blob: fd3408b244f21e4695291c246bbd6abfbe93b3d1 [file] [log] [blame]
// 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>