mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-25 14:25:23 +00:00
feat: 资产详情添加授权用户列表页 (#1093)
* feat: 资产详情添加授权用户列表页 * feat: 取消console log * perf: 优化一下前端 * feat: 修改授权用户组分隔符 Co-authored-by: Michael Bai <baijiangjie@gmail.com> Co-authored-by: ibuler <ibuler@qq.com>
This commit is contained in:
@@ -109,6 +109,8 @@
|
||||
"Assets": "资产",
|
||||
"Auth": "认证",
|
||||
"AccountList": "账号列表",
|
||||
"PermUserList": "授权用户",
|
||||
"ViewPerm": "查看授权",
|
||||
"AutoGenerateKey": "自动生成",
|
||||
"AutoPush": "自动推送",
|
||||
"BasePlatform": "基础平台",
|
||||
@@ -551,6 +553,7 @@
|
||||
"User": "用户",
|
||||
"UserGroups": "用户组",
|
||||
"PermName":"授权名称",
|
||||
"Permissions": "授权列表",
|
||||
"DatabaseAppPermission": "数据库授权",
|
||||
"RemoteAppPermission": "远程应用授权",
|
||||
"addApplicationToThisPermission": "添加应用",
|
||||
|
@@ -100,6 +100,8 @@
|
||||
"HardwareInfo": "Hardware info",
|
||||
"Hardware": "Hardware",
|
||||
"AccountList": "Account list",
|
||||
"PermUserList": "Authorized user",
|
||||
"ViewPerm": "View permission",
|
||||
"LoginOption": "Login option",
|
||||
"AssetDetail": "Asset detail",
|
||||
"AssetList": "Asset list",
|
||||
@@ -531,6 +533,7 @@
|
||||
"perms": {
|
||||
"": "",
|
||||
"Actions": "Permission",
|
||||
"Permission": "Permissions",
|
||||
"Asset": "Asset",
|
||||
"Basic": "Basic",
|
||||
"Exclude": "Exclude",
|
||||
@@ -541,6 +544,7 @@
|
||||
"SystemUser": "System user",
|
||||
"User": "User",
|
||||
"UserGroups": "UserGroups",
|
||||
"Permissions": "Permissions",
|
||||
"DatabaseAppPermission": "Databases permissions",
|
||||
"RemoteAppPermission": "Remote apps permissions",
|
||||
"KubernetesAppPermission": "Kubernetes permissions",
|
||||
|
60
src/layout/components/GenericListTableDialog/index.vue
Normal file
60
src/layout/components/GenericListTableDialog/index.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<Dialog
|
||||
:title="title"
|
||||
:visible.sync="iVisible"
|
||||
top="1vh"
|
||||
:width="width"
|
||||
:show-cancel="false"
|
||||
:show-confirm="false"
|
||||
>
|
||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dialog from '@/components/Dialog'
|
||||
import { GenericListTable } from '@/layout/components'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
Dialog, GenericListTable
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
tableConfig: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
headerActions: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '60%'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iVisible: {
|
||||
set(val) {
|
||||
this.$emit('update:visible', val)
|
||||
},
|
||||
get() {
|
||||
return this.visible
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -11,3 +11,4 @@ export { default as GenericListTable } from './GenericListTable'
|
||||
export { default as GenericCreateUpdatePage } from './GenericCreateUpdatePage'
|
||||
export { default as GenericCreateUpdateForm } from './GenericCreateUpdateForm'
|
||||
export { default as GenericUpdateFormDialog } from './GenericUpdateFormDialog'
|
||||
export { default as GenericListTableDialog } from './GenericListTableDialog'
|
||||
|
225
src/views/assets/Asset/AssetDetail/PermUser.vue
Normal file
225
src/views/assets/Asset/AssetDetail/PermUser.vue
Normal file
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<PermUserGroupCard v-bind="UserGroupCardConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<GenericListTableDialog
|
||||
:visible.sync="GenericListTableDialogConfig.visible"
|
||||
v-bind="GenericListTableDialogConfig"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ListTable from '@/components/ListTable'
|
||||
import { GenericListTableDialog } from '@/layout/components'
|
||||
import { ChoicesFormatter, DetailFormatter } from '@/components/TableFormatters'
|
||||
import PermUserGroupCard from './components/PermUserGroupCard'
|
||||
|
||||
export default {
|
||||
name: 'PermUserList',
|
||||
components: {
|
||||
ListTable, GenericListTableDialog, PermUserGroupCard
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
tableConfig: {
|
||||
url: `/api/v1/assets/assets/${this.object.id}/perm-users/`,
|
||||
columns: [
|
||||
'name', 'username', 'email', 'phone', 'wechat',
|
||||
'groups_display', 'total_role_display', 'source',
|
||||
'is_valid', 'login_blocked', 'mfa_enabled',
|
||||
'mfa_force_enabled', 'is_expired',
|
||||
'last_login', 'date_joined', 'date_password_last_updated',
|
||||
'comment', 'created_by', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'username', 'actions'],
|
||||
default: [
|
||||
'name', 'username',
|
||||
'source', 'is_valid', 'actions'
|
||||
]
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatterArgs: {
|
||||
route: 'UserDetail'
|
||||
},
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
username: {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
email: {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
source: {
|
||||
width: '120px'
|
||||
},
|
||||
total_role_display: {
|
||||
label: this.$t('users.Role'),
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
mfa_enabled: {
|
||||
label: 'MFA',
|
||||
formatterArgs: {
|
||||
showFalse: false
|
||||
}
|
||||
},
|
||||
mfa_force_enabled: {
|
||||
formatterArgs: {
|
||||
showFalse: false
|
||||
}
|
||||
},
|
||||
is_expired: {
|
||||
formatterArgs: {
|
||||
showFalse: false
|
||||
}
|
||||
},
|
||||
groups_display: {
|
||||
width: '200px',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
hasUpdate: false,
|
||||
hasDelete: false,
|
||||
hasClone: false,
|
||||
extraActions: [
|
||||
{
|
||||
title: vm.$t('assets.ViewPerm'),
|
||||
name: 'view',
|
||||
type: 'primary',
|
||||
callback: function(data) {
|
||||
vm.GenericListTableDialogConfig.visible = true
|
||||
vm.GenericListTableDialogConfig.tableConfig.url = `/api/v1/assets/assets/${vm.object.id}/perm-users/${data.row.id}/permissions/`
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasImport: false,
|
||||
hasExport: false,
|
||||
hasLeftActions: false
|
||||
},
|
||||
UserGroupCardConfig: {
|
||||
icon: 'fa-users',
|
||||
title: this.$t('perms.UserGroups'),
|
||||
url: `/api/v1/assets/assets/${vm.object.id}/perm-user-groups/`,
|
||||
detailRoute: 'UserGroupDetail',
|
||||
buttonTitle: this.$t('assets.ViewPerm'),
|
||||
buttonClickCallback(obj) {
|
||||
vm.GenericListTableDialogConfig.visible = true
|
||||
vm.GenericListTableDialogConfig.tableConfig.url = `/api/v1/assets/assets/${vm.object.id}/perm-user-groups/${obj.id}/permissions/`
|
||||
}
|
||||
},
|
||||
GenericListTableDialogConfig: {
|
||||
title: this.$t('perms.Permissions'),
|
||||
visible: false,
|
||||
width: '60%',
|
||||
tableConfig: {
|
||||
url: '',
|
||||
columns: [
|
||||
'name',
|
||||
'users_amount', 'user_groups_amount', 'assets_amount', 'nodes_amount',
|
||||
'is_valid', 'is_active', 'date_expired', 'comment', 'org_name', 'created_by', 'date_created'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name'],
|
||||
default: [
|
||||
'name', 'is_valid', 'created_by', 'date_created'
|
||||
]
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatterArgs: {
|
||||
route: 'AssetPermissionDetail'
|
||||
},
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
users_amount: {
|
||||
label: this.$t('perms.User'),
|
||||
width: '60px',
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
route: 'AssetPermissionDetail',
|
||||
routeQuery: {
|
||||
activeTab: 'AssetPermissionUser'
|
||||
}
|
||||
}
|
||||
},
|
||||
from_ticket: {
|
||||
width: 100,
|
||||
formatter: ChoicesFormatter,
|
||||
formatterArgs: {
|
||||
showFalse: false
|
||||
}
|
||||
},
|
||||
created_by: {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
user_groups_amount: {
|
||||
label: this.$t('perms.UserGroups'),
|
||||
width: '100px',
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
route: 'AssetPermissionDetail',
|
||||
routeQuery: {
|
||||
activeTab: 'AssetPermissionUser'
|
||||
}
|
||||
}
|
||||
},
|
||||
assets_amount: {
|
||||
label: this.$t('perms.Asset'),
|
||||
width: '60px',
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
route: 'AssetPermissionDetail',
|
||||
routeQuery: {
|
||||
activeTab: 'AssetPermissionAsset'
|
||||
}
|
||||
}
|
||||
},
|
||||
nodes_amount: {
|
||||
label: this.$t('perms.Node'),
|
||||
width: '60px',
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
route: 'AssetPermissionDetail',
|
||||
routeQuery: {
|
||||
activeTab: 'AssetPermissionAsset'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasImport: false,
|
||||
hasExport: false,
|
||||
hasLeftActions: false,
|
||||
hasColumnSetting: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<IBox :fa="icon" :type="type" :title="title" v-bind="$attrs">
|
||||
<table style="width: 100%;table-layout:fixed;" class="CardTable">
|
||||
<tr v-for="obj of iObjects" :key="obj.value" class="item">
|
||||
<td style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">
|
||||
<el-tooltip style="margin: 4px;" effect="dark" :content="obj.label" placement="left">
|
||||
<el-link class="detail" @click="goDetail(obj)">{{ obj.label }}</el-link>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<el-button size="mini" type="primary" style="float: right" @click="buttonClickCallback(obj)">
|
||||
{{ buttonTitle }}
|
||||
</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</IBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import IBox from '@/components/IBox'
|
||||
|
||||
export default {
|
||||
name: 'PermUserGroupCard',
|
||||
components: {
|
||||
IBox
|
||||
},
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'primary'
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
detailRoute: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
buttonTitle: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
buttonClickCallback: {
|
||||
type: Function,
|
||||
default: (obj) => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
objects: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iObjects() {
|
||||
return this.objects
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadObjects()
|
||||
},
|
||||
methods: {
|
||||
async loadObjects() {
|
||||
const data = await this.$axios.get(this.url)
|
||||
data.forEach((v) => {
|
||||
v['label'] = v['name']
|
||||
})
|
||||
this.objects = data
|
||||
},
|
||||
goDetail(obj) {
|
||||
this.$router.push({ name: this.detailRoute, params: { id: obj.id }})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
b, strong {
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
tr td {
|
||||
line-height: 1.42857;
|
||||
padding: 8px;
|
||||
vertical-align: top;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
tr.item {
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
padding: 8px;
|
||||
display: block;
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
.box-margin {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
@@ -11,6 +11,7 @@ import { GenericDetailPage, TabPage } from '@/layout/components'
|
||||
import Detail from './Detail.vue'
|
||||
import Account from './Account.vue'
|
||||
import SystemUserList from './SystemUser.vue'
|
||||
import PermUserList from './PermUser.vue'
|
||||
|
||||
export default {
|
||||
name: 'AssetListDetail',
|
||||
@@ -19,7 +20,8 @@ export default {
|
||||
TabPage,
|
||||
Detail,
|
||||
Account,
|
||||
SystemUserList
|
||||
SystemUserList,
|
||||
PermUserList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -38,6 +40,10 @@ export default {
|
||||
{
|
||||
title: this.$t('assets.AccountList'),
|
||||
name: 'Account'
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.PermUserList'),
|
||||
name: 'PermUserList'
|
||||
}
|
||||
],
|
||||
hasRightSide: true,
|
||||
|
Reference in New Issue
Block a user