This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new 3291a62fc12 Allow locking and unlocking users via UI (#8337)
3291a62fc12 is described below

commit 3291a62fc128ae1e726f8684b43f12f970934511
Author: Fabricio Duarte <[email protected]>
AuthorDate: Tue Feb 13 06:30:32 2024 -0300

    Allow locking and unlocking users via UI (#8337)
---
 ui/public/locales/en.json     |  3 +++
 ui/public/locales/pt_BR.json  |  3 +++
 ui/src/config/section/user.js | 16 +++++++++++++++-
 ui/src/views/AutogenView.vue  | 36 +++++++++++++++++++++---------------
 4 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index 71da3c6d0aa..86dd0ba38ad 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -142,6 +142,7 @@
 "label.action.iso.permission": "Update ISO permissions",
 "label.action.iso.share": "Update ISO sharing",
 "label.action.lock.account": "Lock Account",
+"label.action.lock.user": "Lock User",
 "label.action.manage.cluster": "Manage cluster",
 "label.action.migrate.router": "Migrate router",
 "label.action.migrate.systemvm": "Migrate System VM",
@@ -2966,6 +2967,8 @@
 "message.loading.delete.tungsten.router.table": "Removing Router Table...",
 "message.loading.delete.tungsten.tag": "Removing Tag...",
 "message.lock.account": "Please confirm that you want to lock this Account. By 
locking the Account, all Users for this Account will no longer be able to 
manage their cloud resources. Existing resources can still be accessed.",
+"message.lock.user": "Please confirm that you want to lock the User 
\"{user}\". By locking this User, they will no longer be able to manage their 
cloud resources. Existing resources can still be accessed.",
+"message.lock.user.success": "Successfully locked User \"{user}\"",
 "message.login.failed": "Login Failed",
 "message.migrate.instance.host.auto.assign": "Host for the Instance will be 
automatically chosen based on the suitability within the same cluster",
 "message.migrate.instance.to.host": "Please confirm that you want to migrate 
this Instance to another host. When migration is between hosts of different 
clusters volume(s) of the Instance may get migrated to suitable storage pools.",
diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json
index c36a5c762a7..24e70c8c219 100644
--- a/ui/public/locales/pt_BR.json
+++ b/ui/public/locales/pt_BR.json
@@ -120,6 +120,7 @@
 "label.action.iso.permission": "Atualizar permiss\u00f5es da ISO",
 "label.action.iso.share": "Atualizar compartilhamento da ISO",
 "label.action.lock.account": "Bloquear conta",
+"label.action.lock.user": "Bloquear usu\u00e1rio",
 "label.action.manage.cluster": "Vincular cluster",
 "label.action.migrate.router": "Migrar roteador",
 "label.action.migrate.systemvm": "Migrar VM de sistema",
@@ -2224,6 +2225,8 @@
 "message.listnsp.not.return.providerid": "erro: A API 
listNetworkServiceProviders n\u00e3o retorna o ID do provedor virtualRouter",
 "message.load.host.failed": "Falha ao carregar os hosts",
 "message.lock.account": "Confirme se voc\u00ea deseja bloquear esta conta. 
Bloqueando a conta, todos os usu\u00e1rios desta conta n\u00e3o estar\u00e3o 
mais habilitados a gerenciar os recursos na nuvem. Os recursos existentes 
(cloud server) ainda poder\u00e3o ser acessados.",
+"message.lock.user": "Confirme se voc\u00ea deseja bloquear o usu\u00e1rio 
\"{user}\". Bloqueando este usu\u00e1rio, o mesmo n\u00e3o estar\u00e1 mais 
habilitado a gerenciar os recursos na nuvem. Os recursos existentes (cloud 
server) ainda poder\u00e3o ser acessados.",
+"message.lock.user.success": "Usu\u00e1rio \"{user}\" bloqueado com sucesso",
 "message.login.failed": "Falha no login",
 "message.memory.usage.info.hypervisor.additionals": "Os dados apresentados 
podem n\u00e3o refletir o real uso de mem\u00f3ria se a VM n\u00e3o possuir as 
ferramentas adicionais do virtualizador instaladas",
 "message.memory.usage.info.negative.value": "Se n\u00e3o for poss\u00edvel 
obter do hypervisor o uso de mem\u00f3ria da VM, ser\u00e3o desabilitadas as 
linhas de mem\u00f3ria livre do gr\u00e1fico de dados brutos e de uso de 
mem\u00f3ria no gr\u00e1fico de percentual",
diff --git a/ui/src/config/section/user.js b/ui/src/config/section/user.js
index eef9ea3f939..90a9822333e 100644
--- a/ui/src/config/section/user.js
+++ b/ui/src/config/section/user.js
@@ -81,7 +81,7 @@ export default {
       show: (record, store) => {
         return ['Admin', 'DomainAdmin'].includes(store.userInfo.roletype) && 
!record.isdefault &&
           !(record.domain === 'ROOT' && record.account === 'admin' && 
record.accounttype === 1) &&
-          record.state === 'disabled'
+          ['disabled', 'locked'].includes(record.state)
       }
     },
     {
@@ -96,6 +96,20 @@ export default {
           record.state === 'enabled'
       }
     },
+    {
+      api: 'lockUser',
+      icon: 'LockOutlined',
+      label: 'label.action.lock.user',
+      message: (record) => ['message.lock.user', { user: record.username }],
+      successMessage: (record) => ['message.lock.user.success', { user: 
record.username }],
+      dataView: true,
+      popup: true,
+      show: (record, store) => {
+        return ['Admin', 'DomainAdmin'].includes(store.userInfo.roletype) && 
!record.isdefault &&
+          !(record.domain === 'ROOT' && record.account === 'admin' && 
record.accounttype === 1) &&
+          record.state === 'enabled'
+      }
+    },
     {
       api: 'authorizeSamlSso',
       icon: 'form-outlined',
diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue
index bf1c42d4c05..2404bc0b6d4 100644
--- a/ui/src/views/AutogenView.vue
+++ b/ui/src/views/AutogenView.vue
@@ -183,20 +183,20 @@
                 <template #message>
                   <exclamation-circle-outlined style="color: red; fontSize: 
30px; display: inline-flex" />
                   <span style="padding-left: 5px" 
v-html="`<b>${selectedRowKeys.length} ` + $t('label.items.selected') + `. 
</b>`" />
-                  <span v-html="$t(currentAction.message)" />
+                  <span v-html="currentAction.message" />
                 </template>
               </a-alert>
               <a-alert v-else type="warning">
                 <template #message>
                   <span v-if="selectedRowKeys.length > 0" 
v-html="`<b>${selectedRowKeys.length} ` + $t('label.items.selected') + `. 
</b>`" />
-                  <span v-html="$t(currentAction.message)" />
+                  <span v-html="currentAction.message" />
                 </template>
               </a-alert>
             </div>
             <div v-else>
               <a-alert type="warning">
                 <template #message>
-                  <span v-html="$t(currentAction.message)" />
+                  <span v-html="currentAction.message" />
                 </template>
               </a-alert>
             </div>
@@ -1145,13 +1145,11 @@ export default {
       this.currentAction.paramFields = []
       this.currentAction.paramFilters = []
       if ('message' in action) {
-        var message = action.message
         if (typeof action.message === 'function') {
-          message = action.message(action.resource)
+          action.message = action.message(action.resource)
         }
-        action.message = message
+        action.message = Array.isArray(action.message) ? 
this.$t(...action.message) : this.$t(action.message)
       }
-
       this.getArgs(action, isGroupAction, paramFields)
       this.getFilters(action, isGroupAction, paramFields)
       this.getFirstIndexFocus()
@@ -1480,18 +1478,26 @@ export default {
                   this.selectedItems.filter(item => item === resource)
                 }
               }
-              var message = action.successMessage ? 
this.$t(action.successMessage) : this.$t(action.label) +
-                (resourceName ? ' - ' + resourceName : '')
-              var duration = 2
-              if (action.additionalMessage) {
-                message = message + ' - ' + this.$t(action.successMessage)
-                duration = 5
-              }
               if (this.selectedItems.length === 0) {
+                let message = ''
+                let messageDuration = 2
+                if ('successMessage' in action) {
+                  message = action.successMessage
+                  if (typeof action.successMessage === 'function') {
+                    message = action.successMessage(action.resource)
+                  }
+                  message = Array.isArray(message) ? this.$t(...message) : 
this.$t(message)
+                } else {
+                  message = this.$t(action.label) + (resourceName ? ' - ' + 
resourceName : '')
+                }
+                if ('additionalMessage' in action) {
+                  message = `${message} - ${this.$t(action.additionalMessage)}`
+                  messageDuration = 5
+                }
                 this.$message.success({
                   content: message,
                   key: action.label + resourceName,
-                  duration: duration
+                  duration: messageDuration
                 })
               }
               break

Reply via email to