blob: 9e319620a86ba13f9d28fce8834133302c620592 [file] [log] [blame]
<!--
Licensed 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 class="app-container">
<div class="filter-container">
<el-input :placeholder="$t('tenant.searchTenant')" v-model="listQuery.tenant" style="width: 200px;" @keyup.enter.native="handleFilter"/>
<el-button type="primary" icon="el-icon-search" @click="handleFilter"/>
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">{{ $t('tenant.newTenant') }}</el-button>
</div>
<el-row :gutter="24">
<el-col :xs="{span: 24}" :sm="{span: 24}" :md="{span: 24}" :lg="{span: 24}" :xl="{span: 24}">
<el-table
v-loading="listLoading"
:key="tableKey"
:data="list"
border
fit
highlight-current-row
style="width: 100%;">
<el-table-column :label="$t('tenant.name')" min-width="50px" align="center">
<template slot-scope="scope">
<router-link :to="'/management/tenants/tenantInfo/' + scope.row.tenant + '?tab=namespaces'" class="link-type">
<span>{{ scope.row.tenant }}</span>
</router-link>
</template>
</el-table-column>
<el-table-column :label="$t('namespace.namespaceNumber')" align="center" min-width="100px">
<template slot-scope="scope">
<router-link :to="'/management/tenants/tenantInfo/' + scope.row.tenant + '?tab=namespaces'" class="link-type">
<span>{{ scope.row.namespace }}</span>
</router-link>
</template>
</el-table-column>
<el-table-column :label="$t('tenant.allowedClustersLabel')" align="center" min-width="100px">
<template slot-scope="scope">
<span
v-for="tag in scope.row.allowedClusters"
:key="tag"
class="list-el-tag">
<router-link :to="'/management/clusters/' + tag + '/cluster?tab=brokers'" class="link-type">
{{ tag }}
</router-link>
</span>
</template>
</el-table-column>
<el-table-column :label="$t('tenant.adminRolesLabel')" align="center" min-width="100px">
<template slot-scope="scope">
<el-tag
v-for="tag in scope.row.adminRoles"
:key="tag"
effect="dark"
class="list-el-tag">
{{ tag }}
</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('table.actions')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<router-link :to="'/management/tenants/tenantInfo/' + scope.row.tenant">
<el-button type="primary" size="mini">{{ $t('table.edit') }}</el-button>
</router-link>
<el-button size="mini" type="danger" @click="handleDelete(scope.row)">{{ $t('table.delete') }}</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="30%">
<el-form ref="form" :rules="rules" :model="form" label-position="top">
<el-form-item v-if="dialogStatus==='create'" :label="$t('table.tenant')" prop="tenant">
<el-input v-model="form.tenant" :placeholder="$t('tenant.selectTenantMessage')"/>
</el-form-item>
<el-form-item v-if="dialogStatus==='create'" :label="$t('tenant.allowedClustersLabel')" prop="clusters">
<el-select v-model="form.clusters" :placeholder="$t('cluster.selectClusterMessage')" multiple style="width:100%">
<el-option v-for="item in clusterListOptions" :label="item.label" :value="item.value" :key="item.value" />
</el-select>
</el-form-item>
<el-form-item v-if="dialogStatus==='create'" :label="$t('tenant.adminRolesLabel')" prop="roles">
<el-tag
v-for="tag in form.dynamicRoles"
:key="tag"
:disable-transitions="false"
closable
@close="handleClose(tag)">
{{ tag }}
</el-tag>
<el-input
v-if="inputVisible"
ref="saveTagInput"
v-model="inputValue"
size="small"
class="input-new-tag"
@keyup.enter.native="handleInputConfirm"/>
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Role</el-button>
</el-form-item>
<el-form-item v-if="dialogStatus==='delete'">
<h4>{{ deleteTenantMessage }}</h4>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleOptions()">{{ $t('table.confirm') }}</el-button>
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
import {
putTenant,
fetchTenants,
deleteTenant
} from '@/api/tenants'
import { fetchClusters } from '@/api/clusters'
import { validateEmpty } from '@/utils/validate'
const defaultForm = {
cluster: ''
}
export default {
name: 'Tenants',
data() {
return {
postForm: Object.assign({}, defaultForm),
clusterListOptions: [],
tableKey: 0,
list: null,
localList: [],
searchList: [],
total: 0,
listLoading: true,
listQuery: {
tenant: '',
page: 1,
limit: 10
},
form: {
tenant: '',
clusters: [],
dynamicRoles: []
},
dialogFormVisible: false,
dialogStatus: '',
textMap: {
create: this.$i18n.t('tenant.newTenant'),
delete: this.$i18n.t('tenant.deleteTenant')
},
rules: {
tenant: [{ required: true, message: this.$i18n.t('tenant.tenantIsRequired'), trigger: 'blur' }],
clusters: [{ required: true, message: this.$i18n.t('tenant.clusterIsRequired'), trigger: 'blur' }]
},
inputVisible: false,
inputValue: '',
deleteTenantMessage: this.$i18n.t('tenant.deleteTenantMessage')
}
},
created() {
this.getTenants()
},
methods: {
getTenants() {
if (this.localList.length > 0) {
setTimeout(() => {
this.localPaging()
}, 0)
} else {
this.listLoading = true
fetchTenants().then(response => {
for (var i = 0; i < response.data.total; i++) {
let allowedClusters = ''
let adminRoles = ''
if (response.data.data[i]['allowedClusters'].length > 0) {
allowedClusters = response.data.data[i]['allowedClusters']
}
if (response.data.data[i]['adminRoles'].length > 0) {
adminRoles = response.data.data[i]['adminRoles']
}
let adminRolesArray = []
if (adminRoles !== '') {
adminRolesArray = adminRoles.split(',')
}
let allowedClustersArray = []
if (allowedClusters !== '') {
allowedClustersArray = allowedClusters.split(',')
}
this.localList.push({
'tenant': response.data.data[i]['tenant'],
'namespace': response.data.data[i]['namespaces'],
'allowedClusters': allowedClustersArray,
'adminRoles': adminRolesArray
})
}
this.total = response.data.total
this.listQuery.page = response.data.pageNum
this.listQuery.limit = response.data.pageSize
this.list = this.localList.slice((this.listQuery.page - 1) * this.listQuery.limit, this.listQuery.limit * this.listQuery.page)
// this.localPaging()
// Just to simulate the time of the request
setTimeout(() => {
this.listLoading = false
}, 1.5 * 1000)
})
}
},
localPaging() {
this.listLoading = true
if (!validateEmpty(this.listQuery.tenant)) {
this.searchList = []
for (var i = 0; i < this.localList.length; i++) {
if (this.localList[i]['tenant'].indexOf(this.listQuery.tenant) !== -1) {
this.searchList.push(this.localList[i])
}
}
this.total = this.searchList.length
this.list = this.searchList.slice((this.listQuery.page - 1) * this.listQuery.limit, this.listQuery.limit * this.listQuery.page)
} else {
this.total = this.localList.length
this.list = this.localList.slice((this.listQuery.page - 1) * this.listQuery.limit, this.listQuery.limit * this.listQuery.page)
}
this.listLoading = false
},
handleFilter() {
this.getTenants()
},
resetForm() {
this.form = {
tenant: '',
adminRoles: '',
allowedClusters: '',
clusters: []
}
},
handleOptions() {
this.$refs['form'].validate((valid) => {
if (valid) {
switch (this.dialogStatus) {
case 'create':
this.createData()
break
case 'delete':
this.deleteData()
break
}
}
})
},
handleCreate() {
this.resetForm()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.form.clusters = []
this.clusterListOptions = []
this.form.dynamicRoles = []
fetchClusters(this.listQuery).then(response => {
for (var i = 0; i < response.data.data.length; i++) {
this.clusterListOptions.push({ 'value': response.data.data[i].cluster, 'label': response.data.data[i].cluster })
}
})
this.$nextTick(() => {
this.$refs['form'].clearValidate()
})
},
createData() {
this.$refs['form'].validate((valid) => {
if (valid) {
const data = {
allowedClusters: this.form.clusters,
adminRoles: this.form.dynamicRoles
}
putTenant(this.form.tenant, data).then((response) => {
this.form.adminRoles = 'empty'
this.form.allowedClusters = 'empty'
this.localList = []
this.getTenants()
this.dialogFormVisible = false
this.$notify({
title: 'success',
message: this.$i18n.t('tenant.createTenantSuccessNotification'),
type: 'success',
duration: 2000
})
})
}
})
},
handleDelete(row) {
this.dialogStatus = 'delete'
this.dialogFormVisible = true
this.form.tenant = row.tenant
},
deleteData() {
deleteTenant(this.form.tenant).then((response) => {
this.$notify({
title: 'success',
message: this.$i18n.t('tenant.deleteTenantSuccessNotification'),
type: 'success',
duration: 2000
})
this.dialogFormVisible = false
this.localList = []
this.getTenants()
})
},
handleClose(tag) {
this.form.dynamicRoles.splice(this.form.dynamicRoles.indexOf(tag), 1)
},
showInput() {
this.inputVisible = true
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus()
})
},
handleInputConfirm() {
const inputValue = this.inputValue
if (inputValue) {
if (this.form.dynamicRoles.indexOf(this.inputValue) >= 0) {
this.$notify({
title: 'error',
message: this.$i18n.t('tenant.roleAlreadyExists'),
type: 'error',
duration: 2000
})
return
}
this.form.dynamicRoles.push(inputValue)
}
this.inputVisible = false
this.inputValue = ''
}
}
}
</script>
<style>
.list-el-tag {
margin-left: 2px;
margin-right: 2px;
}
.el-form {
margin-left: 0% !important;
margin-right: 0% !important;
}
</style>