This is an automated email from the ASF dual-hosted git repository.
RosiKyu 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 6019b89c0b3 ui: make "Add Tenant Account" vs "Add User" distinction
clear (#13981)
6019b89c0b3 is described below
commit 6019b89c0b3434b387291f1c14837a3a22f71f80
Author: dahn <[email protected]>
AuthorDate: Thu Nov 12 08:54:06 2026 +0100
ui: make "Add Tenant Account" vs "Add User" distinction clear (#13981)
---
ui/public/locales/en.json | 2 ++
ui/src/config/section/account.js | 13 ++++++++++++-
ui/src/views/iam/AddAccount.vue | 7 +++++++
ui/src/views/iam/AddUser.vue | 27 +++++++++++++++++++++------
4 files changed, 42 insertions(+), 7 deletions(-)
diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index ef1d5e5889f..23e7f41de92 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -269,6 +269,7 @@
"label.add": "Add",
"label.addservices": "Add Services",
"label.add.account": "Add Account",
+"label.add.tenant.account": "Add Tenant Account",
"label.add.acl.rule": "Add rule",
"label.add.acl": "Add ACL",
"label.add.affinity.group": "Add new Affinity Group",
@@ -3328,6 +3329,7 @@
"message.action.vmsnapshot.disk-only.delete": "Please confirm that you want to
delete this Instance Snapshot.",
"message.activate.project": "Are you sure you want to activate this project?",
"message.api.not.available": "API is not available.",
+"message.add.account.warning": "Creating a new account creates a separate
tenant with its own resource limits and isolated resources. Users in different
accounts cannot share Instances or Volumes. Networks can be shared between
accounts when the appropriate permissions are granted. To add a new user to an
existing account instead, use the <b>Add User</b> action in the account's
details view.",
"message.add.custom.action.parameters": "Parameters to be made available while
running the custom action.",
"message.add.egress.rule.failed": "Adding new egress rule failed.",
"message.add.egress.rule.processing": "Adding new egress rule...",
diff --git a/ui/src/config/section/account.js b/ui/src/config/section/account.js
index d04c683817e..32ea5f538e8 100644
--- a/ui/src/config/section/account.js
+++ b/ui/src/config/section/account.js
@@ -104,11 +104,22 @@ export default {
{
api: 'createAccount',
icon: 'plus-outlined',
- label: 'label.add.account',
+ label: 'label.add.tenant.account',
listView: true,
popup: true,
component: shallowRef(defineAsyncComponent(() =>
import('@/views/iam/AddAccount.vue')))
},
+ {
+ api: 'createUser',
+ icon: 'user-add-outlined',
+ label: 'label.add.user',
+ dataView: true,
+ popup: true,
+ show: (record, store) => {
+ return ['Admin', 'DomainAdmin'].includes(store.userInfo.roletype) &&
record.state === 'enabled'
+ },
+ component: shallowRef(defineAsyncComponent(() =>
import('@/views/iam/AddUser.vue')))
+ },
{
api: 'ldapCreateAccount',
icon: 'user-add-outlined',
diff --git a/ui/src/views/iam/AddAccount.vue b/ui/src/views/iam/AddAccount.vue
index a211fd2d8c3..5c0b7e14110 100644
--- a/ui/src/views/iam/AddAccount.vue
+++ b/ui/src/views/iam/AddAccount.vue
@@ -25,6 +25,13 @@
:loading="loading"
layout="vertical"
@finish="handleSubmit">
+ <div style="margin-bottom: 10px">
+ <a-alert type="warning">
+ <template #message>
+ <div v-html="$t('message.add.account.warning')"></div>
+ </template>
+ </a-alert>
+ </div>
<a-form-item ref="roleid" name="roleid">
<template #label>
<tooltip-label :title="$t('label.role')"
:tooltip="apiParams.roleid.description"/>
diff --git a/ui/src/views/iam/AddUser.vue b/ui/src/views/iam/AddUser.vue
index 704c55c4814..c4718c482dc 100644
--- a/ui/src/views/iam/AddUser.vue
+++ b/ui/src/views/iam/AddUser.vue
@@ -185,6 +185,12 @@ export default {
ResourceIcon,
InfiniteScrollSelect
},
+ props: {
+ resource: {
+ type: Object,
+ default: () => {}
+ }
+ },
data () {
this.fetchTimeZone = debounce(this.fetchTimeZone, 800)
return {
@@ -208,6 +214,11 @@ export default {
if (newVal) {
this.form.passwordChangeRequired = false
}
+ },
+ resource (newVal, oldVal) {
+ if (newVal?.id !== oldVal?.id) {
+ this.setAccountContext()
+ }
}
},
computed: {
@@ -247,17 +258,21 @@ export default {
})
},
fetchData () {
- this.account = this.$route.query && this.$route.query.account ?
this.$route.query.account : null
- this.domainid = this.$route.query && this.$route.query.domainid ?
this.$route.query.domainid : null
- // Set initial domain if provided from route
- if (this.domainid) {
- this.form.domainid = this.domainid
- }
+ this.setAccountContext()
this.fetchTimeZone()
if (this.samlAllowed) {
this.fetchIdps()
}
},
+ setAccountContext () {
+ // Only an account resource identifies the target account, other
sections pass e.g. the first listed user
+ const accountResource = this.$route.meta.name === 'account' ?
this.resource : null
+ this.account = this.$route.query?.account || accountResource?.name ||
null
+ this.domainid = this.$route.query?.domainid || accountResource?.domainid
|| null
+ // The form is reused when reopened, so also clear values left from a
previous account
+ this.form.domainid = this.domainid
+ this.form.account = this.account
+ },
handleDomainChange (domainId) {
this.form.domainid = domainId
this.form.account = null