mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-25 06:19:51 +00:00
perf: Add pam template
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-row :gutter="20">
|
<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">
|
<IBox :title="title" class="block" v-bind="$attrs">
|
||||||
<el-timeline>
|
<el-timeline>
|
||||||
<el-timeline-item
|
<el-timeline-item
|
||||||
|
@@ -1,25 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<DataActions
|
<div>
|
||||||
v-if="hasLeftActions && iActions.length > 0"
|
<DataActions
|
||||||
:actions="iActions"
|
v-if="hasLeftActions && iActions.length > 0"
|
||||||
class="header-action"
|
:actions="iActions"
|
||||||
v-bind="$attrs"
|
class="header-action"
|
||||||
/>
|
v-bind="$attrs"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Drawer v-if="showDrawer" @close-drawer="handleCloseDrawer">
|
||||||
|
<component :is="dynamicTemplateComponent" />
|
||||||
|
</Drawer>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import i18n from '@/i18n/i18n'
|
|
||||||
import DataActions from '@/components/DataActions/index.vue'
|
|
||||||
import { createSourceIdCache } from '@/api/common'
|
|
||||||
import { cleanActions } from './utils'
|
import { cleanActions } from './utils'
|
||||||
|
import { createSourceIdCache } from '@/api/common'
|
||||||
import { getErrorResponseMsg } from '@/utils/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 defaultTrue = { type: [Boolean, Function, String], default: true }
|
||||||
const defaultFalse = { type: [Boolean, Function, String], default: false }
|
const defaultFalse = { type: [Boolean, Function, String], default: false }
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LeftSide',
|
name: 'LeftSide',
|
||||||
components: {
|
components: {
|
||||||
DataActions
|
Drawer,
|
||||||
|
DataActions,
|
||||||
|
AccountTemplateCreate
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
hasLeftActions: defaultTrue,
|
hasLeftActions: defaultTrue,
|
||||||
@@ -90,6 +102,8 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
const vm = this
|
const vm = this
|
||||||
return {
|
return {
|
||||||
|
showDrawer: false,
|
||||||
|
dynamicTemplateComponent: null,
|
||||||
defaultMoreActions: [
|
defaultMoreActions: [
|
||||||
{
|
{
|
||||||
title: this.$t('DeleteSelected'),
|
title: this.$t('DeleteSelected'),
|
||||||
@@ -194,6 +208,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
handleCreate() {
|
handleCreate() {
|
||||||
let route
|
let route
|
||||||
|
|
||||||
if (typeof this.createRoute === 'string') {
|
if (typeof this.createRoute === 'string') {
|
||||||
route = { name: this.createRoute }
|
route = { name: this.createRoute }
|
||||||
route.name = this.createRoute
|
route.name = this.createRoute
|
||||||
@@ -202,14 +217,27 @@ export default {
|
|||||||
} else if (typeof this.createRoute === 'object') {
|
} else if (typeof this.createRoute === 'object') {
|
||||||
route = this.createRoute
|
route = this.createRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$log.debug('handle create')
|
this.$log.debug('handle create')
|
||||||
|
|
||||||
if (this.createInNewPage) {
|
if (this.createInNewPage) {
|
||||||
const { href } = this.$router.resolve(route)
|
const { href } = this.$router.resolve(route)
|
||||||
window.open(href, '_blank')
|
window.open(href, '_blank')
|
||||||
} else {
|
} else {
|
||||||
|
if (route.isPam) {
|
||||||
|
this.showDrawer = true
|
||||||
|
this.dynamicTemplateComponent = route.name
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.$router.push(route)
|
this.$router.push(route)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
handleCloseDrawer() {
|
||||||
|
this.showDrawer = false
|
||||||
|
this.dynamicTemplateComponent = null
|
||||||
|
},
|
||||||
defaultBulkDeleteCallback({ selectedRows, reloadTable }) {
|
defaultBulkDeleteCallback({ selectedRows, reloadTable }) {
|
||||||
const msg = this.$t('DeleteWarningMsg') + ' ' + selectedRows.length + ' ' + this.$t('Rows') + ' ?'
|
const msg = this.$t('DeleteWarningMsg') + ' ' + selectedRows.length + ' ' + this.$t('Rows') + ' ?'
|
||||||
const title = this.$tc('Info')
|
const title = this.$tc('Info')
|
||||||
@@ -248,3 +276,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</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() {
|
goDetail() {
|
||||||
const detailRoute = this.getDetailRoute()
|
const detailRoute = this.getDetailRoute()
|
||||||
|
|
||||||
|
console.log('%c DEBUG[ detailRoute ]-97:', 'font-size:13px; background:pink; color:#7B68EE;', detailRoute)
|
||||||
|
|
||||||
if (this.formatterArgs.openInNewPage) {
|
if (this.formatterArgs.openInNewPage) {
|
||||||
this.linkClicked = this.formatterArgs.removeColorOnClick
|
this.linkClicked = this.formatterArgs.removeColorOnClick
|
||||||
const { href } = this.$router.resolve(detailRoute)
|
const { href } = this.$router.resolve(detailRoute)
|
||||||
|
@@ -132,6 +132,7 @@ export default {
|
|||||||
|
|
||||||
::v-deep > div {
|
::v-deep > div {
|
||||||
margin-bottom: 50px;
|
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-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="20">
|
<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" />
|
<GenericListTable ref="listTable" :header-actions="headerActions" :table-config="tableConfig" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :md="9" :sm="24">
|
<el-col :md="9" :sm="24" class="quick-actions">
|
||||||
<QuickActions :actions="quickActions" type="primary" />
|
<QuickActions :actions="quickActions" type="primary" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<ViewSecret
|
<ViewSecret
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-row :gutter="20">
|
<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" />
|
<AutoDetailCard :fields="detailFields" :object="object" :url="url" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :md="9" :sm="24">
|
<el-col :md="9" :sm="24" class="quick-actions">
|
||||||
<QuickActions :actions="quickActions" type="primary" />
|
<QuickActions :actions="quickActions" type="primary" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</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'),
|
title: this.$t('Asset'),
|
||||||
icon: 'fa-inbox',
|
icon: 'fa-inbox',
|
||||||
component: () => import('@/views/pam/Account/AssetList.vue')
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
Reference in New Issue
Block a user