mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
381 lines
12 KiB
Vue
381 lines
12 KiB
Vue
// 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 #bodyCell="{ column, record }">
|
|
<template v-if="column.key === 'user'">
|
|
<span v-if="record.userid">{{ record.username }}</span>
|
|
</template>
|
|
<template v-if="column.key === 'projectrole'">
|
|
<span v-if="record.projectroleid">{{ getProjectRole(record) }}</span>
|
|
</template>
|
|
<template v-if="column.key === 'actions'">
|
|
<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>
|
|
</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 { getAPI, postAPI } 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 = [
|
|
{
|
|
key: 'account',
|
|
title: this.$t('label.account'),
|
|
dataIndex: 'account'
|
|
},
|
|
{
|
|
key: 'role',
|
|
title: this.$t('label.roletype'),
|
|
dataIndex: 'role'
|
|
},
|
|
{
|
|
key: 'actions',
|
|
title: this.$t('label.actions'),
|
|
dataIndex: 'actions'
|
|
}
|
|
]
|
|
if (this.isProjectRolesSupported()) {
|
|
this.columns.splice(1, 0, {
|
|
key: 'user',
|
|
title: this.$t('label.user'),
|
|
dataIndex: 'userid'
|
|
})
|
|
this.columns.splice(this.columns.length - 1, 0, {
|
|
key: 'projectrole',
|
|
title: this.$t('label.project.role'),
|
|
dataIndex: 'projectroleid'
|
|
})
|
|
}
|
|
this.page = 1
|
|
this.pageSize = 10
|
|
this.itemCount = 0
|
|
this.fetchData()
|
|
},
|
|
inject: ['parentFetchData'],
|
|
methods: {
|
|
fetchData () {
|
|
const params = {}
|
|
params.projectId = this.resource.id
|
|
params.page = this.page
|
|
params.pageSize = this.pageSize
|
|
this.updateProjectApi = this.$store.getters.apis.updateProject
|
|
if (!this.resource.id) return
|
|
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
|
|
getAPI('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
|
|
getAPI('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
|
|
getAPI('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) {
|
|
postAPI('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) {
|
|
postAPI(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>
|