This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.19 by this push:
new b6937b6a51a UI: Allow accounts of the `User` type to add other
accounts or users to projects through UI (#9927)
b6937b6a51a is described below
commit b6937b6a51aadebb00a68dd65b17b924c6681a41
Author: Bernardo De Marco Gonçalves <[email protected]>
AuthorDate: Thu Nov 28 14:33:46 2024 -0300
UI: Allow accounts of the `User` type to add other accounts or users to
projects through UI (#9927)
---
ui/src/views/project/AddAccountOrUserToProject.vue | 95 ++++++++++++++--------
1 file changed, 60 insertions(+), 35 deletions(-)
diff --git a/ui/src/views/project/AddAccountOrUserToProject.vue
b/ui/src/views/project/AddAccountOrUserToProject.vue
index d85dc785729..bb5fb0884c6 100644
--- a/ui/src/views/project/AddAccountOrUserToProject.vue
+++ b/ui/src/views/project/AddAccountOrUserToProject.vue
@@ -31,27 +31,23 @@
<template #label>
<tooltip-label :title="$t('label.account')"
:tooltip="apiParams.addAccountToProject.account.description"/>
</template>
- <a-select
- show-search
+ <a-auto-complete
v-model:value="form.account"
:placeholder="apiParams.addAccountToProject.account.description"
- v-focus="true"
- :filterOption="false"
- @search="fetchAccounts"
- >
- <template v-if="load.accounts" #notFoundContent>
- <a-spin size="small" />
- </template>
- <template v-if="!load.accounts">
- <a-select-option v-for="account in accounts"
:key="account.name" :value="account.name">
- <span v-if="account.icon">
- <resource-icon :image="account.icon.base64image"
size="1x" style="margin-right: 5px"/>
- </span>
- <block-outlined v-else style="margin-right: 5px" />
- {{ account.name }}
- </a-select-option>
- </template>
- </a-select>
+ :filterOption="filterOption"
+ :options="accounts"
+ >
+ <template v-if="load.accounts" #notFoundContent>
+ <a-spin size="small" />
+ </template>
+ <template v-if="!load.accounts" #option="account">
+ <span v-if="account.icon">
+ <resource-icon :image="account.icon.base64image" size="1x"
style="margin-right: 5px"/>
+ </span>
+ <block-outlined v-else style="margin-right: 5px" />
+ {{ account.name }}
+ </template>
+ </a-auto-complete>
</a-form-item>
<a-form-item name="email" ref="email">
<template #label>
@@ -121,27 +117,23 @@
<template #label>
<tooltip-label :title="$t('label.name')"
:tooltip="apiParams.addUserToProject.username.description"/>
</template>
- <a-select
- show-search
+ <a-auto-complete
v-model:value="form.username"
:placeholder="apiParams.addUserToProject.username.description"
- v-focus="true"
- :filterOption="false"
- @search="fetchUsers"
+ :filterOption="filterOption"
+ :options="users"
>
<template v-if="load.users" #notFoundContent>
<a-spin size="small" />
</template>
- <template v-if="!load.users">
- <a-select-option v-for="user in users" :key="user.username"
:value="user.username">
- <span v-if="user.icon">
- <resource-icon :image="user.icon.base64image" size="1x"
style="margin-right: 5px"/>
- </span>
- <block-outlined v-else style="margin-right: 5px" />
- {{ user.firstname + ' ' + user.lastname + " (" +
user.username + ")" }}
- </a-select-option>
+ <template v-if="!load.users" #option="user">
+ <span v-if="user.icon">
+ <resource-icon :image="user.icon.base64image" size="1x"
style="margin-right: 5px"/>
+ </span>
+ <block-outlined v-else style="margin-right: 5px" />
+ {{ user.firstName + ' ' + user.lastName + " (" +
user.username + ")" }}
</template>
- </a-select>
+ </a-auto-complete>
</a-form-item>
<a-form-item name="email" ref="email">
<template #label>
@@ -254,6 +246,11 @@ export default {
this.fetchProjectRoles()
}
},
+ filterOption (input, option) {
+ return (
+ option.value.toUpperCase().indexOf(input.toUpperCase()) >= 0
+ )
+ },
fetchUsers (keyword) {
this.load.users = true
const params = { listall: true, showicon: true }
@@ -261,13 +258,28 @@ export default {
params.keyword = keyword
}
api('listUsers', params).then(response => {
- this.users = response.listusersresponse.user ?
response.listusersresponse.user : []
+ this.users = this.parseUsers(response?.listusersresponse?.user)
}).catch(error => {
this.$notifyError(error)
}).finally(() => {
this.load.users = false
})
},
+ parseUsers (users) {
+ if (!users) {
+ return []
+ }
+
+ return users.map(user => {
+ return {
+ value: user.username,
+ username: user.username,
+ firstName: user.firstname,
+ lastName: user.lastname,
+ icon: user.icon
+ }
+ })
+ },
fetchAccounts (keyword) {
this.load.accounts = true
const params = { domainid: this.resource.domainid, showicon: true }
@@ -275,13 +287,26 @@ export default {
params.keyword = keyword
}
api('listAccounts', params).then(response => {
- this.accounts = response.listaccountsresponse.account || []
+ this.accounts =
this.parseAccounts(response?.listaccountsresponse?.account)
}).catch(error => {
this.$notifyError(error)
}).finally(() => {
this.load.accounts = false
})
},
+ parseAccounts (accounts) {
+ if (!accounts) {
+ return []
+ }
+
+ return accounts.map(account => {
+ return {
+ value: account.name,
+ name: account.name,
+ icon: account.icon
+ }
+ })
+ },
fetchProjectRoles () {
this.load.projectRoles = true
api('listProjectRoles', {