mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-24 20:47:17 +00:00
perf: Add pam template
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :md="16" :sm="24">
|
||||
<el-col :md="16" :sm="24" class="resource-activity">
|
||||
<IBox :title="title" class="block" v-bind="$attrs">
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
|
@@ -1,25 +1,37 @@
|
||||
<template>
|
||||
<DataActions
|
||||
v-if="hasLeftActions && iActions.length > 0"
|
||||
:actions="iActions"
|
||||
class="header-action"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
<div>
|
||||
<DataActions
|
||||
v-if="hasLeftActions && iActions.length > 0"
|
||||
:actions="iActions"
|
||||
class="header-action"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
|
||||
<Drawer v-if="showDrawer" @close-drawer="handleCloseDrawer">
|
||||
<component :is="dynamicTemplateComponent" />
|
||||
</Drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import i18n from '@/i18n/i18n'
|
||||
import DataActions from '@/components/DataActions/index.vue'
|
||||
import { createSourceIdCache } from '@/api/common'
|
||||
import { cleanActions } from './utils'
|
||||
import { createSourceIdCache } from '@/api/common'
|
||||
import { getErrorResponseMsg } from '@/utils/common'
|
||||
|
||||
import i18n from '@/i18n/i18n'
|
||||
import Drawer from '@/components/Drawer/index.vue'
|
||||
import DataActions from '@/components/DataActions/index.vue'
|
||||
import AccountTemplateCreate from '@/views/accounts/AccountTemplate/AccountTemplateCreateUpdate.vue'
|
||||
|
||||
const defaultTrue = { type: [Boolean, Function, String], default: true }
|
||||
const defaultFalse = { type: [Boolean, Function, String], default: false }
|
||||
|
||||
export default {
|
||||
name: 'LeftSide',
|
||||
components: {
|
||||
DataActions
|
||||
Drawer,
|
||||
DataActions,
|
||||
AccountTemplateCreate
|
||||
},
|
||||
props: {
|
||||
hasLeftActions: defaultTrue,
|
||||
@@ -90,6 +102,8 @@ export default {
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
showDrawer: false,
|
||||
dynamicTemplateComponent: null,
|
||||
defaultMoreActions: [
|
||||
{
|
||||
title: this.$t('DeleteSelected'),
|
||||
@@ -194,6 +208,7 @@ export default {
|
||||
methods: {
|
||||
handleCreate() {
|
||||
let route
|
||||
|
||||
if (typeof this.createRoute === 'string') {
|
||||
route = { name: this.createRoute }
|
||||
route.name = this.createRoute
|
||||
@@ -202,14 +217,27 @@ export default {
|
||||
} else if (typeof this.createRoute === 'object') {
|
||||
route = this.createRoute
|
||||
}
|
||||
|
||||
this.$log.debug('handle create')
|
||||
|
||||
if (this.createInNewPage) {
|
||||
const { href } = this.$router.resolve(route)
|
||||
window.open(href, '_blank')
|
||||
} else {
|
||||
if (route.isPam) {
|
||||
this.showDrawer = true
|
||||
this.dynamicTemplateComponent = route.name
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.$router.push(route)
|
||||
}
|
||||
},
|
||||
handleCloseDrawer() {
|
||||
this.showDrawer = false
|
||||
this.dynamicTemplateComponent = null
|
||||
},
|
||||
defaultBulkDeleteCallback({ selectedRows, reloadTable }) {
|
||||
const msg = this.$t('DeleteWarningMsg') + ' ' + selectedRows.length + ' ' + this.$t('Rows') + ' ?'
|
||||
const title = this.$tc('Info')
|
||||
@@ -248,3 +276,17 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep .ibox {
|
||||
height: 100% !important;
|
||||
margin: unset !important;
|
||||
border: unset !important;
|
||||
|
||||
.el-card__body {
|
||||
padding-top: unset !important;
|
||||
padding-bottom: unset !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -106,6 +106,8 @@ export default {
|
||||
goDetail() {
|
||||
const detailRoute = this.getDetailRoute()
|
||||
|
||||
console.log('%c DEBUG[ detailRoute ]-97:', 'font-size:13px; background:pink; color:#7B68EE;', detailRoute)
|
||||
|
||||
if (this.formatterArgs.openInNewPage) {
|
||||
this.linkClicked = this.formatterArgs.removeColorOnClick
|
||||
const { href } = this.$router.resolve(detailRoute)
|
||||
|
@@ -132,6 +132,7 @@ export default {
|
||||
|
||||
::v-deep > div {
|
||||
margin-bottom: 50px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -67,57 +67,57 @@ export default [
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'account-template',
|
||||
component: empty,
|
||||
redirect: {
|
||||
name: 'AccountTemplateList'
|
||||
},
|
||||
meta: {
|
||||
title: i18n.t('AccountTemplate'),
|
||||
app: 'accounts',
|
||||
icon: 'template',
|
||||
permissions: ['accounts.view_accounttemplate']
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'AccountTemplateList',
|
||||
component: () => import('@/views/accounts/AccountTemplate/AccountTemplateList'),
|
||||
meta: {
|
||||
menuTitle: i18n.t('MenuAccountTemplates'),
|
||||
title: i18n.t('AccountTemplateList'),
|
||||
permissions: ['accounts.view_accounttemplate']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: () => import('@/views/accounts/AccountTemplate/AccountTemplateCreateUpdate.vue'),
|
||||
name: 'AccountTemplateCreate',
|
||||
meta: {
|
||||
title: i18n.t('CreateAccountTemplate'),
|
||||
action: 'create'
|
||||
},
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id/update',
|
||||
component: () => import('@/views/accounts/AccountTemplate/AccountTemplateCreateUpdate.vue'),
|
||||
name: 'AccountTemplateUpdate',
|
||||
meta: {
|
||||
title: i18n.t('UpdateAccountTemplate'),
|
||||
action: 'update'
|
||||
},
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
component: () => import('@/views/accounts/AccountTemplate/AccountTemplateDetail/index.vue'),
|
||||
name: 'AccountTemplateDetail',
|
||||
meta: { title: i18n.t('AccountTemplate') },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
// {
|
||||
// path: 'account-template',
|
||||
// component: empty,
|
||||
// redirect: {
|
||||
// name: 'AccountTemplateList'
|
||||
// },
|
||||
// meta: {
|
||||
// title: i18n.t('AccountTemplate'),
|
||||
// app: 'accounts',
|
||||
// icon: 'template',
|
||||
// permissions: ['accounts.view_accounttemplate']
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: '',
|
||||
// name: 'AccountTemplateList',
|
||||
// component: () => import('@/views/accounts/AccountTemplate/AccountTemplateList'),
|
||||
// meta: {
|
||||
// menuTitle: i18n.t('MenuAccountTemplates'),
|
||||
// title: i18n.t('AccountTemplateList'),
|
||||
// permissions: ['accounts.view_accounttemplate']
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: 'create',
|
||||
// component: () => import('@/views/accounts/AccountTemplate/AccountTemplateCreateUpdate.vue'),
|
||||
// name: 'AccountTemplateCreate',
|
||||
// meta: {
|
||||
// title: i18n.t('CreateAccountTemplate'),
|
||||
// action: 'create'
|
||||
// },
|
||||
// hidden: true
|
||||
// },
|
||||
// {
|
||||
// path: ':id/update',
|
||||
// component: () => import('@/views/accounts/AccountTemplate/AccountTemplateCreateUpdate.vue'),
|
||||
// name: 'AccountTemplateUpdate',
|
||||
// meta: {
|
||||
// title: i18n.t('UpdateAccountTemplate'),
|
||||
// action: 'update'
|
||||
// },
|
||||
// hidden: true
|
||||
// },
|
||||
// {
|
||||
// path: ':id',
|
||||
// component: () => import('@/views/accounts/AccountTemplate/AccountTemplateDetail/index.vue'),
|
||||
// name: 'AccountTemplateDetail',
|
||||
// meta: { title: i18n.t('AccountTemplate') },
|
||||
// hidden: true
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
|
@@ -8,10 +8,10 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :md="15" :sm="24">
|
||||
<el-col :md="15" :sm="24" class="generic-list-table">
|
||||
<GenericListTable ref="listTable" :header-actions="headerActions" :table-config="tableConfig" />
|
||||
</el-col>
|
||||
<el-col :md="9" :sm="24">
|
||||
<el-col :md="9" :sm="24" class="quick-actions">
|
||||
<QuickActions :actions="quickActions" type="primary" />
|
||||
</el-col>
|
||||
<ViewSecret
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :md="15" :sm="24">
|
||||
<el-col :md="15" :sm="24" class="auto-detail-card">
|
||||
<AutoDetailCard :fields="detailFields" :object="object" :url="url" />
|
||||
</el-col>
|
||||
<el-col :md="9" :sm="24">
|
||||
<el-col :md="9" :sm="24" class="quick-actions">
|
||||
<QuickActions :actions="quickActions" type="primary" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
174
src/views/pam/Account/AccountTemplate.vue
Normal file
174
src/views/pam/Account/AccountTemplate.vue
Normal file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<div>
|
||||
<GenericListPage :header-actions="headerActions" :table-config="tableConfig" />
|
||||
<ViewSecret
|
||||
v-if="showViewSecretDialog"
|
||||
:account="account"
|
||||
:show-password-record="false"
|
||||
:url="secretUrl"
|
||||
type="template"
|
||||
:visible.sync="showViewSecretDialog"
|
||||
/>
|
||||
|
||||
<Drawer v-if="showTableUpdateDrawer" :title="drawerTitle" @close-drawer="showTableUpdateDrawer = !showTableUpdateDrawer">
|
||||
<component :is="currentTemplate" />
|
||||
</Drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
import { ActionsFormatter } from '@/components/Table/TableFormatters'
|
||||
|
||||
import Drawer from '@/components/Drawer/index.vue'
|
||||
import ViewSecret from '@/components/Apps/AccountListTable/ViewSecret'
|
||||
import AccountTemplateDetail from '@/views/accounts/AccountTemplate/AccountTemplateDetail/index.vue'
|
||||
import AccountTemplateUpdate from '@/views/accounts/AccountTemplate/AccountTemplateCreateUpdate.vue'
|
||||
|
||||
export default {
|
||||
name: 'AccountTemplateList',
|
||||
components: {
|
||||
Drawer,
|
||||
ViewSecret,
|
||||
GenericListPage,
|
||||
AccountTemplateUpdate,
|
||||
AccountTemplateDetail
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
showViewSecretDialog: false,
|
||||
showTableUpdateDrawer: false,
|
||||
currentTemplate: null,
|
||||
drawerTitle: '',
|
||||
account: {},
|
||||
secretUrl: '',
|
||||
tableConfig: {
|
||||
url: '/api/v1/accounts/account-templates/',
|
||||
columns: null,
|
||||
columnsExclude: ['spec_info', 'password_rules', 'push_params'],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'username', 'secret_type', 'has_secret', 'privileged', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatter: (row) => {
|
||||
return (
|
||||
<span style={{ color: '#1c84c6', cursor: 'pointer' }} onClick={() => {
|
||||
this.$route.params.id = row.id
|
||||
|
||||
this.currentTemplate = 'AccountTemplateDetail'
|
||||
this.showTableUpdateDrawer = true
|
||||
this.drawerTitle = this.$t('AccountTemplate')
|
||||
}}>
|
||||
{row.name}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
},
|
||||
privileged: {
|
||||
width: '120px',
|
||||
formatterArgs: {
|
||||
showText: false,
|
||||
showFalse: false
|
||||
}
|
||||
},
|
||||
has_secret: {
|
||||
formatterArgs: {
|
||||
showFalse: false,
|
||||
showText: false
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
formatter: ActionsFormatter,
|
||||
formatterArgs: {
|
||||
hasUpdate: true,
|
||||
hasDelete: true,
|
||||
hasClone: this.hasClone,
|
||||
moreActionsTitle: this.$t('More'),
|
||||
extraActions: [
|
||||
{
|
||||
name: 'View',
|
||||
title: this.$t('View'),
|
||||
can: this.$hasPerm('accounts.view_accounttemplatesecret'),
|
||||
type: 'primary',
|
||||
callback: ({ row }) => {
|
||||
vm.secretUrl = `/api/v1/accounts/account-template-secrets/${row.id}/`
|
||||
vm.account = row
|
||||
vm.showViewSecretDialog = false
|
||||
setTimeout(() => {
|
||||
vm.showViewSecretDialog = true
|
||||
})
|
||||
}
|
||||
}
|
||||
],
|
||||
onUpdate: ({ row }) => {
|
||||
this.$route.params.id = row.id
|
||||
|
||||
this.currentTemplate = 'AccountTemplateUpdate'
|
||||
this.drawerTitle = this.$t('UpdateAccountTemplate')
|
||||
this.showTableUpdateDrawer = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasRefresh: true,
|
||||
hasExport: this.$hasPerm('accounts.view_accounttemplatesecret'),
|
||||
hasMoreActions: false,
|
||||
hasLabelSearch: true,
|
||||
exportOptions: {
|
||||
url: '/api/v1/accounts/account-template-secrets/',
|
||||
mfaVerifyRequired: true,
|
||||
tips: this.$t('AccountExportTips')
|
||||
},
|
||||
createRoute: () => {
|
||||
return {
|
||||
name: 'AccountTemplateCreate',
|
||||
isPam: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page ::v-deep .page-heading {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::v-deep .ibox {
|
||||
height: 100%;
|
||||
|
||||
.el-card__body {
|
||||
height: 100%;
|
||||
padding-bottom: unset;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.auto-detail-card,
|
||||
.quick-actions,
|
||||
.generic-list-table,
|
||||
.resource-activity {
|
||||
width: 100% !important;
|
||||
|
||||
.ibox {
|
||||
border: 1px solid #EBEEF5 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.quick-actions {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
@@ -33,6 +33,12 @@ export default {
|
||||
title: this.$t('Asset'),
|
||||
icon: 'fa-inbox',
|
||||
component: () => import('@/views/pam/Account/AssetList.vue')
|
||||
},
|
||||
{
|
||||
name: 'AccountTemplateList',
|
||||
title: this.$t('AccountTemplate'),
|
||||
icon: 'fa-copy',
|
||||
component: () => import('@/views/pam/Account/AccountTemplate.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -46,4 +52,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user