| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| <template> |
| <div> |
| <a-row :gutter="12"> |
| <a-col :md="24" :lg="24"> |
| <a-table |
| size="small" |
| :loading="loading.table" |
| :columns="columns" |
| :dataSource="dataSource" |
| :pagination="false" |
| :rowKey="rowItem => rowItem.userid ? rowItem.userid : (rowItem.accountid || rowItem.account)"> |
| <template #user="{ record }"> |
| <span v-if="record.userid">{{ record.username }}</span> |
| </template> |
| <template #projectrole="{ record }"> |
| <span v-if="record.projectroleid">{{ getProjectRole(record) }}</span> |
| </template> |
| <template #action="{ record }"> |
| <div> |
| <span v-if="imProjectAdmin && dataSource.length > 1" class="account-button-action"> |
| <tooltip-button |
| tooltipPlacement="top" |
| :tooltip="record.userid ? $t('label.make.user.project.owner') : $t('label.make.project.owner')" |
| v-if="record.role !== owner" |
| type="default" |
| icon="arrow-up-outlined" |
| size="small" |
| @onClick="promoteAccount(record)" /> |
| <tooltip-button |
| tooltipPlacement="top" |
| :tooltip="record.userid ? $t('label.demote.project.owner.user') : $t('label.demote.project.owner')" |
| v-if="updateProjectApi.params.filter(x => x.name === 'swapowner').length > 0 && record.role === owner" |
| type="default" |
| icon="arrow-down-outlined" |
| size="small" |
| @onClick="demoteAccount(record)" /> |
| <tooltip-button |
| tooltipPlacement="top" |
| :tooltip="record.userid ? $t('label.remove.project.user') : $t('label.remove.project.account')" |
| type="primary" |
| :danger="true" |
| icon="delete-outlined" |
| size="small" |
| :disabled="!('deleteAccountFromProject' in $store.getters.apis)" |
| @onClick="onShowConfirmDelete(record)" /> |
| </span> |
| </div> |
| </template> |
| </a-table> |
| <a-pagination |
| class="row-element" |
| size="small" |
| :current="page" |
| :pageSize="pageSize" |
| :total="itemCount" |
| :showTotal="total => `${$t('label.total')} ${total} ${$t('label.items')}`" |
| :pageSizeOptions="['10', '20', '40', '80', '100']" |
| @change="changePage" |
| @showSizeChange="changePageSize" |
| showSizeChanger> |
| <template #buildOptionText="props"> |
| <span>{{ props.value }} / {{ $t('label.page') }}</span> |
| </template> |
| </a-pagination> |
| </a-col> |
| </a-row> |
| </div> |
| </template> |
| |
| <script> |
| import { api } from '@/api' |
| import TooltipButton from '@/components/widgets/TooltipButton' |
| |
| export default { |
| name: 'AccountsTab', |
| components: { |
| TooltipButton |
| }, |
| props: { |
| resource: { |
| type: Object, |
| required: true |
| } |
| }, |
| data () { |
| return { |
| columns: [], |
| dataSource: [], |
| imProjectAdmin: false, |
| loading: { |
| user: false, |
| projectAccount: false, |
| roles: false, |
| table: false |
| }, |
| page: 1, |
| pageSize: 10, |
| itemCount: 0, |
| users: [], |
| projectRoles: [], |
| owner: 'Admin', |
| role: 'Regular' |
| } |
| }, |
| created () { |
| this.columns = [ |
| { |
| title: this.$t('label.account'), |
| dataIndex: 'account', |
| slots: { customRender: 'account' } |
| }, |
| { |
| title: this.$t('label.roletype'), |
| dataIndex: 'role', |
| slots: { customRender: 'role' } |
| }, |
| { |
| title: this.$t('label.action'), |
| dataIndex: 'action', |
| slots: { customRender: 'action' } |
| } |
| ] |
| if (this.isProjectRolesSupported()) { |
| this.columns.splice(1, 0, { |
| title: this.$t('label.user'), |
| dataIndex: 'userid', |
| slots: { customRender: 'user' } |
| }) |
| this.columns.splice(this.columns.length - 1, 0, { |
| title: this.$t('label.project.role'), |
| dataIndex: 'projectroleid', |
| slots: { customRender: 'projectrole' } |
| }) |
| } |
| this.page = 1 |
| this.pageSize = 10 |
| this.itemCount = 0 |
| this.fetchData() |
| }, |
| inject: ['parentFetchData'], |
| watch: { |
| resource: { |
| deep: true, |
| handler (newItem) { |
| if (!newItem || !newItem.id) { |
| return |
| } |
| this.fetchData() |
| } |
| } |
| }, |
| methods: { |
| fetchData () { |
| const params = {} |
| params.projectId = this.resource.id |
| params.page = this.page |
| params.pageSize = this.pageSize |
| this.updateProjectApi = this.$store.getters.apis.updateProject |
| this.fetchUsers() |
| this.fetchProjectAccounts(params) |
| if (this.isProjectRolesSupported()) { |
| this.fetchProjectRoles() |
| } |
| }, |
| changePage (page, pageSize) { |
| this.page = page |
| this.pageSize = pageSize |
| this.fetchData() |
| }, |
| changePageSize (currentPage, pageSize) { |
| this.page = 0 |
| this.pageSize = pageSize |
| this.fetchData() |
| }, |
| isLoggedInUserProjectAdmin (user) { |
| if (['Admin', 'DomainAdmin'].includes(this.$store.getters.userInfo.roletype)) { |
| return true |
| } |
| // If I'm the logged in user Or if I'm the logged in account And I'm the owner |
| if (((user.userid && user.userid === this.$store.getters.userInfo.id) || |
| user.account === this.$store.getters.userInfo.account) && |
| user.role === this.owner) { |
| return true |
| } |
| return false |
| }, |
| isProjectRolesSupported () { |
| return ('listProjectRoles' in this.$store.getters.apis) |
| }, |
| getProjectRole (record) { |
| const projectRole = this.projectRoles.filter(role => role.id === record.projectroleid) |
| return projectRole[0].name || projectRole[0].id || null |
| }, |
| fetchUsers () { |
| this.loading.user = true |
| api('listUsers', { listall: true }).then(response => { |
| this.users = response.listusersresponse.user || [] |
| }).catch(error => { |
| this.$notifyError(error) |
| }).finally(() => { |
| this.loading.user = false |
| }) |
| }, |
| fetchProjectRoles () { |
| this.loading.roles = true |
| api('listProjectRoles', { projectId: this.resource.id }).then(response => { |
| this.projectRoles = response.listprojectrolesresponse.projectrole || [] |
| }).catch(error => { |
| this.$notifyError(error) |
| }).finally(() => { |
| this.loading.roles = false |
| }) |
| }, |
| fetchProjectAccounts (params) { |
| this.loading.projectAccount = true |
| api('listProjectAccounts', params).then(json => { |
| const listProjectAccount = json.listprojectaccountsresponse.projectaccount |
| const itemCount = json.listprojectaccountsresponse.count |
| if (!listProjectAccount || listProjectAccount.length === 0) { |
| this.dataSource = [] |
| return |
| } |
| for (const projectAccount of listProjectAccount) { |
| this.imProjectAdmin = this.isLoggedInUserProjectAdmin(projectAccount) |
| if (this.imProjectAdmin) { |
| break |
| } |
| } |
| |
| this.itemCount = itemCount |
| this.dataSource = listProjectAccount |
| }).catch(error => { |
| this.$notifyError(error) |
| }).finally(() => { |
| this.loading.projectAccount = false |
| }) |
| }, |
| onMakeProjectOwner (record) { |
| const title = this.$t('label.make.project.owner') |
| const loading = this.$message.loading(title + `${this.$t('label.in.progress.for')} ` + record.account, 0) |
| const params = {} |
| params.id = this.resource.id |
| params.account = record.account |
| this.updateProject(record, params, title, loading) |
| }, |
| promoteAccount (record) { |
| var title = this.$t('label.make.project.owner') |
| const loading = this.$message.loading(title + `${this.$t('label.in.progress.for')} ` + record.account, 0) |
| const params = {} |
| |
| params.id = this.resource.id |
| if (record.userid) { |
| params.userid = record.userid |
| // params.accountid = (record.user && record.user[0].accountid) || record.accountid |
| title = this.$t('label.make.user.project.owner') |
| } else { |
| params.account = record.account |
| } |
| params.roletype = this.owner |
| params.swapowner = false |
| this.updateProject(record, params, title, loading) |
| }, |
| demoteAccount (record) { |
| var title = this.$t('label.demote.project.owner') |
| const loading = this.$message.loading(title + `${this.$t('label.in.progress.for')} ` + record.account, 0) |
| const params = {} |
| if (record.userid) { |
| params.userid = record.userid |
| // params.accountid = (record.user && record.user[0].accountid) || record.accountid |
| title = this.$t('label.demote.project.owner.user') |
| } else { |
| params.account = record.account |
| } |
| |
| params.id = this.resource.id |
| params.roletype = 'Regular' |
| params.swapowner = false |
| this.updateProject(record, params, title, loading) |
| }, |
| updateProject (record, params, title, loading) { |
| api('updateProject', params).then(json => { |
| const hasJobId = this.checkForAddAsyncJob(json, title, record.account) |
| if (hasJobId) { |
| this.fetchData() |
| } |
| }).catch(error => { |
| this.$notifyError(error) |
| }).finally(() => { |
| setTimeout(loading, 1000) |
| this.parentFetchData() |
| }) |
| }, |
| onShowConfirmDelete (record) { |
| const self = this |
| const title = `${this.$t('label.deleteconfirm')} ${this.$t('label.account')}` |
| |
| this.$confirm({ |
| title, |
| okText: this.$t('label.ok'), |
| okType: 'danger', |
| cancelText: this.$t('label.cancel'), |
| onOk () { |
| self.removeAccount(record) |
| } |
| }) |
| }, |
| removeAccount (record) { |
| const title = this.$t('label.remove.project.account') |
| const loading = this.$message.loading(title + `${this.$t('label.in.progress.for')} ` + record.account, 0) |
| const params = {} |
| params.projectid = this.resource.id |
| if (record.userid) { |
| params.userid = record.userid |
| this.deleteOperation('deleteUserFromProject', params, record, title, loading) |
| } else { |
| params.account = record.account |
| this.deleteOperation('deleteAccountFromProject', params, record, title, loading) |
| } |
| }, |
| deleteOperation (apiName, params, record, title, loading) { |
| api(apiName, params).then(json => { |
| const hasJobId = this.checkForAddAsyncJob(json, title, record.account) |
| if (hasJobId) { |
| this.fetchData() |
| } |
| }).catch(error => { |
| this.$notifyError(error) |
| }).finally(() => { |
| setTimeout(loading, 1000) |
| }) |
| }, |
| checkForAddAsyncJob (json, title, description) { |
| let hasJobId = false |
| |
| for (const obj in json) { |
| if (obj.includes('response')) { |
| for (const res in json[obj]) { |
| if (res === 'jobid') { |
| hasJobId = true |
| const jobId = json[obj][res] |
| this.$pollJob({ |
| jobId, |
| title, |
| description, |
| showLoading: false |
| }) |
| } |
| } |
| } |
| } |
| |
| return hasJobId |
| } |
| } |
| } |
| </script> |
| |
| <style scoped> |
| :deep(.ant-table-fixed-right) { |
| z-index: 5; |
| } |
| |
| .row-element { |
| margin-top: 10px; |
| margin-bottom: 10px; |
| } |
| |
| .account-button-action button { |
| margin-right: 5px; |
| } |
| </style> |