mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-17 15:52:32 +00:00
perf: 优化 nest fields 支持是否隐藏
This commit is contained in:
@@ -85,6 +85,10 @@ export class FormFieldGenerator {
|
|||||||
field.el = { ...field.el, ...fieldMeta }
|
field.el = { ...field.el, ...fieldMeta }
|
||||||
field.el.fields = this.generateNestFields(field, fieldMeta, fieldRemoteMeta)
|
field.el.fields = this.generateNestFields(field, fieldMeta, fieldRemoteMeta)
|
||||||
field.el.errors = {}
|
field.el.errors = {}
|
||||||
|
field.hidden = () => {
|
||||||
|
const hidden = fieldMeta['hiddenFields'] || (() => field.el.fields.length === 0)
|
||||||
|
return hidden(fieldMeta, fieldRemoteMeta, field.el.fields)
|
||||||
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
type = 'input'
|
type = 'input'
|
||||||
|
@@ -1,98 +0,0 @@
|
|||||||
<template>
|
|
||||||
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
|
||||||
import AssetSelect from '@/components/AssetSelect/index'
|
|
||||||
export default {
|
|
||||||
name: 'CommandFilterCreateUpdate',
|
|
||||||
components: { GenericCreateUpdatePage },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
initial: {
|
|
||||||
|
|
||||||
},
|
|
||||||
fields: [
|
|
||||||
[this.$t('common.Basic'), ['name']],
|
|
||||||
[this.$t('common.Correlation'), ['users', 'user_groups', 'nodes', 'assets', 'applications', 'system_users']],
|
|
||||||
[this.$t('common.Other'), ['is_active', 'comment']]
|
|
||||||
],
|
|
||||||
fieldsMeta: {
|
|
||||||
users: {
|
|
||||||
el: {
|
|
||||||
value: [],
|
|
||||||
ajax: {
|
|
||||||
url: '/api/v1/users/users/?fields_size=mini',
|
|
||||||
transformOption: (item) => {
|
|
||||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
user_groups: {
|
|
||||||
el: {
|
|
||||||
value: [],
|
|
||||||
url: '/api/v1/users/groups/'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
nodes: {
|
|
||||||
el: {
|
|
||||||
value: [],
|
|
||||||
ajax: {
|
|
||||||
url: '/api/v1/assets/nodes/',
|
|
||||||
transformOption: (item) => {
|
|
||||||
return { label: item.full_value, value: item.id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
assets: {
|
|
||||||
type: 'assetSelect',
|
|
||||||
component: AssetSelect,
|
|
||||||
label: this.$t('perms.Asset'),
|
|
||||||
rules: [{
|
|
||||||
required: false
|
|
||||||
}],
|
|
||||||
el: {
|
|
||||||
value: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
applications: {
|
|
||||||
label: this.$t('assets.Applications'),
|
|
||||||
el: {
|
|
||||||
value: [],
|
|
||||||
ajax: {
|
|
||||||
url: `/api/v1/applications/applications/?category__in=db,cloud`,
|
|
||||||
transformOption: (item) => {
|
|
||||||
return { label: item.name + ' (' + item.type_display + ')', value: item.id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
system_users: {
|
|
||||||
el: {
|
|
||||||
value: [],
|
|
||||||
ajax: {
|
|
||||||
url: `/api/v1/assets/system-users/?protocol__in=ssh,telnet,mysql,postgresql,mariadb,oracle,sqlserver,k8s,redis,mongodb,clickhouse`,
|
|
||||||
transformOption: (item) => {
|
|
||||||
if (this.$route.query.type === 'k8s') {
|
|
||||||
return { label: item.name, value: item.id }
|
|
||||||
}
|
|
||||||
const username = item.username || '*'
|
|
||||||
return { label: item.name + '(' + username + ')', value: item.id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
url: '/api/v1/assets/cmd-filters/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang='less' scoped>
|
|
||||||
|
|
||||||
</style>
|
|
@@ -1,122 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :md="14" :sm="24">
|
|
||||||
<AutoDetailCard :url="url" :object="object" />
|
|
||||||
</el-col>
|
|
||||||
<el-col :md="10" :sm="24">
|
|
||||||
<RelationCard ref="users" v-bind="userRelationConfig" />
|
|
||||||
<RelationCard ref="userGroups" type="info" v-bind="userGroupsRelationConfig" class="card-margin" />
|
|
||||||
<RelationCard ref="applications" type="warning" v-bind="applicationsRelationConfig" class="card-margin" />
|
|
||||||
<RelationCard ref="systemUsers" type="danger" v-bind="systemUserRelationConfig" class="card-margin" />
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import AutoDetailCard from '@/components/DetailCard/auto'
|
|
||||||
import RelationCard from '@/components/RelationCard'
|
|
||||||
export default {
|
|
||||||
name: 'Detail',
|
|
||||||
components: {
|
|
||||||
AutoDetailCard,
|
|
||||||
RelationCard
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
object: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
const disabled = !this.$hasPerm('assets.change_commandfilter')
|
|
||||||
const defaultTransformOption = (item, filed) => {
|
|
||||||
const currentFiled = item[filed] ? item[filed] : filed === 'username' ? '*' : ''
|
|
||||||
return { label: item.name + '(' + currentFiled + ')', value: item.id }
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
userRelationConfig: {
|
|
||||||
disabled,
|
|
||||||
icon: 'fa-user',
|
|
||||||
title: this.$t('common.User'),
|
|
||||||
objectsAjax: {
|
|
||||||
url: '/api/v1/users/users/?fields_size=mini',
|
|
||||||
transformOption: (item) => defaultTransformOption(item, 'username')
|
|
||||||
},
|
|
||||||
hasObjectsId: this.object.users,
|
|
||||||
performAdd: item => this.performAddHandle(item, 'users'),
|
|
||||||
performDelete: item => this.performDeleteHandle(item, 'users')
|
|
||||||
},
|
|
||||||
userGroupsRelationConfig: {
|
|
||||||
disabled,
|
|
||||||
icon: 'fa-users',
|
|
||||||
title: this.$t('users.UserGroups'),
|
|
||||||
objectsAjax: {
|
|
||||||
url: '/api/v1/users/groups/'
|
|
||||||
},
|
|
||||||
hasObjectsId: this.object.user_groups,
|
|
||||||
performAdd: item => this.performAddHandle(item, 'user_groups'),
|
|
||||||
performDelete: item => this.performDeleteHandle(item, 'user_groups')
|
|
||||||
},
|
|
||||||
applicationsRelationConfig: {
|
|
||||||
disabled,
|
|
||||||
icon: 'fa-th',
|
|
||||||
title: this.$t('assets.Applications'),
|
|
||||||
objectsAjax: {
|
|
||||||
url: `/api/v1/applications/applications/?category__in=db,cloud`,
|
|
||||||
transformOption: (item) => defaultTransformOption(item, 'type_display')
|
|
||||||
},
|
|
||||||
hasObjectsId: this.object.applications,
|
|
||||||
performAdd: item => this.performAddHandle(item, 'applications'),
|
|
||||||
performDelete: item => this.performDeleteHandle(item, 'applications')
|
|
||||||
},
|
|
||||||
systemUserRelationConfig: {
|
|
||||||
disabled,
|
|
||||||
icon: 'fa-info-circle',
|
|
||||||
title: this.$t('assets.SystemUser'),
|
|
||||||
objectsAjax: {
|
|
||||||
url: `/api/v1/assets/system-users/?protocol__in=ssh,telnet,mysql,postgresql,mariadb,oracle,sqlserver,k8s,redis,mongodb,clickhouse`,
|
|
||||||
transformOption: (item) => defaultTransformOption(item, 'username')
|
|
||||||
},
|
|
||||||
hasObjectsId: this.object.system_users,
|
|
||||||
performAdd: item => this.performAddHandle(item, 'system_users'),
|
|
||||||
performDelete: item => this.performDeleteHandle(item, 'system_users')
|
|
||||||
},
|
|
||||||
url: '/api/v1/assets/cmd-filters/'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
performAddHandle(item, updateField) {
|
|
||||||
const newDatas = []
|
|
||||||
const updateFieldRef = _.camelCase(updateField)
|
|
||||||
const options = this.$refs[updateFieldRef].iHasObjects
|
|
||||||
const relationUrl = `/api/v1/assets/cmd-filters/${this.object.id}/`
|
|
||||||
options.forEach(v => newDatas.push(v.value))
|
|
||||||
item.forEach(v => newDatas.push(v.value))
|
|
||||||
|
|
||||||
return this.$axios.patch(relationUrl, { [updateField]: newDatas })
|
|
||||||
},
|
|
||||||
performDeleteHandle(item, updateField) {
|
|
||||||
const newDatas = []
|
|
||||||
const itemId = item?.value || ''
|
|
||||||
const updateFieldRef = _.camelCase(updateField)
|
|
||||||
const options = this.$refs[updateFieldRef].iHasObjects
|
|
||||||
const relationUrl = `/api/v1/assets/cmd-filters/${this.object.id}/`
|
|
||||||
options.forEach(v => {
|
|
||||||
if (v.value !== itemId) {
|
|
||||||
newDatas.push(v.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return this.$axios.patch(relationUrl, { [updateField]: newDatas })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang='less' scoped>
|
|
||||||
.card-margin {
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,74 +0,0 @@
|
|||||||
<template>
|
|
||||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import GenericListTable from '@/layout/components/GenericListTable'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Rules',
|
|
||||||
components: {
|
|
||||||
GenericListTable
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
object: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
tableConfig: {
|
|
||||||
url: `/api/v1/assets/cmd-filters/${this.object.id}/rules/`,
|
|
||||||
permissions: {
|
|
||||||
resource: 'commandfilterrule'
|
|
||||||
},
|
|
||||||
columns: ['type', 'content', 'ignore_case', 'action', 'priority', 'pattern', 'comment', 'actions'],
|
|
||||||
columnsMeta: {
|
|
||||||
type: {
|
|
||||||
width: '100px'
|
|
||||||
},
|
|
||||||
ignore_case: {
|
|
||||||
width: '100px',
|
|
||||||
formatterArgs: {
|
|
||||||
showFalse: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
priority: {
|
|
||||||
width: '70px'
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
width: '90px'
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
formatterArgs: {
|
|
||||||
hasClone: false,
|
|
||||||
updateRoute: {
|
|
||||||
name: 'CommandFilterRulesUpdate',
|
|
||||||
query: {
|
|
||||||
filter: this.object.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
headerActions: {
|
|
||||||
hasSearch: true,
|
|
||||||
hasBulkDelete: false,
|
|
||||||
hasMoreActions: false,
|
|
||||||
createRoute: {
|
|
||||||
name: 'CommandFilterRulesCreate',
|
|
||||||
query: {
|
|
||||||
filter: this.object.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang='less' scoped>
|
|
||||||
|
|
||||||
</style>
|
|
@@ -1,100 +0,0 @@
|
|||||||
<template>
|
|
||||||
<GenericCreateUpdatePage
|
|
||||||
:fields="fields"
|
|
||||||
:initial="initial"
|
|
||||||
:fields-meta="fieldsMeta"
|
|
||||||
:url="url"
|
|
||||||
:has-detail-in-msg="false"
|
|
||||||
:get-next-route="getNextRoute"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
|
||||||
import Select2 from '@/components/FormFields/Select2'
|
|
||||||
import rules from '@/components/DataForm/rules'
|
|
||||||
export default {
|
|
||||||
name: 'RulesCreateUpdate',
|
|
||||||
components: { GenericCreateUpdatePage },
|
|
||||||
data() {
|
|
||||||
const filterId = this.$route.query.filter || '00000000-0000-0000-0000-000000000000'
|
|
||||||
const regexPlaceholder = 'rm.*|reboot|shutdown'
|
|
||||||
const commandPlaceholder = 'rm\rreboot'
|
|
||||||
const commandHelpText = this.$t('assets.CommandFilterRuleContentHelpText')
|
|
||||||
const vm = this
|
|
||||||
return {
|
|
||||||
initial: {
|
|
||||||
filter: filterId,
|
|
||||||
type: 'regex',
|
|
||||||
action: 0
|
|
||||||
},
|
|
||||||
fields: [
|
|
||||||
[this.$t('common.Basic'), ['filter', 'type', 'content', 'ignore_case', 'priority', 'action', 'reviewers', 'comment']]
|
|
||||||
],
|
|
||||||
fieldsMeta: {
|
|
||||||
filter: {
|
|
||||||
component: Select2,
|
|
||||||
el: {
|
|
||||||
ajax: {
|
|
||||||
url: '/api/v1/assets/cmd-filters/'
|
|
||||||
},
|
|
||||||
disabled: true,
|
|
||||||
multiple: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
on: {
|
|
||||||
change: ([val]) => {
|
|
||||||
if (val === 'command') {
|
|
||||||
vm.fieldsMeta.content.el.placeholder = commandPlaceholder
|
|
||||||
vm.fieldsMeta.content.helpText = commandHelpText
|
|
||||||
} else {
|
|
||||||
vm.fieldsMeta.content.el.placeholder = regexPlaceholder
|
|
||||||
vm.fieldsMeta.content.helpText = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content: {
|
|
||||||
type: 'input',
|
|
||||||
el: {
|
|
||||||
type: 'textarea',
|
|
||||||
placeholder: 'rm.*|reboot|shutdown',
|
|
||||||
rows: 4
|
|
||||||
},
|
|
||||||
helpText: ''
|
|
||||||
},
|
|
||||||
reviewers: {
|
|
||||||
hidden: (item) => item.action !== 2,
|
|
||||||
rules: [rules.RequiredChange],
|
|
||||||
el: {
|
|
||||||
value: [],
|
|
||||||
ajax: {
|
|
||||||
url: '/api/v1/users/users/?fields_size=mini',
|
|
||||||
transformOption: (item) => {
|
|
||||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getNextRoute(res, method) {
|
|
||||||
return {
|
|
||||||
name: 'CommandFilterDetail',
|
|
||||||
params: {
|
|
||||||
id: res.filter
|
|
||||||
},
|
|
||||||
query: {
|
|
||||||
activeTable: 'rules'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
url: `/api/v1/assets/cmd-filters/${filterId}/rules/`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang='less' scoped>
|
|
||||||
|
|
||||||
</style>
|
|
@@ -1,45 +0,0 @@
|
|||||||
<template>
|
|
||||||
<GenericDetailPage :object.sync="TaskDetail" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
|
|
||||||
<keep-alive>
|
|
||||||
<component :is="config.activeMenu" :object="TaskDetail" />
|
|
||||||
</keep-alive>
|
|
||||||
</GenericDetailPage>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { GenericDetailPage, TabPage } from '@/layout/components'
|
|
||||||
import Detail from './Detail.vue'
|
|
||||||
import Rules from './Rules.vue'
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
GenericDetailPage,
|
|
||||||
TabPage,
|
|
||||||
Detail,
|
|
||||||
Rules
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
TaskDetail: {},
|
|
||||||
config: {
|
|
||||||
activeMenu: 'Detail',
|
|
||||||
submenu: [
|
|
||||||
{
|
|
||||||
title: this.$t('assets.CommandFilterDetail'),
|
|
||||||
name: 'Detail'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.$t('assets.CommandFilterRules'),
|
|
||||||
name: 'rules',
|
|
||||||
hidden: () => !this.$hasPerm('assets.view_commandfilterrule')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
hasRightSide: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
@@ -1,97 +0,0 @@
|
|||||||
<template>
|
|
||||||
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" :help-message="title" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { GenericListPage } from '@/layout/components'
|
|
||||||
import { DetailFormatter } from '@/components/TableFormatters'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
GenericListPage
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
tableConfig: {
|
|
||||||
url: '/api/v1/assets/cmd-filters/',
|
|
||||||
permissions: {
|
|
||||||
app: 'assets',
|
|
||||||
resource: 'commandfilter'
|
|
||||||
},
|
|
||||||
columns: [
|
|
||||||
'name', 'rules', 'users', 'user_groups', 'assets', 'applications', 'system_users', 'is_active',
|
|
||||||
'created_by', 'date_created', 'comment', 'org_name', 'actions'
|
|
||||||
],
|
|
||||||
columnsShow: {
|
|
||||||
min: ['name', 'actions'],
|
|
||||||
default: ['name', 'rules', 'comment', 'actions']
|
|
||||||
},
|
|
||||||
columnsMeta: {
|
|
||||||
rules: {
|
|
||||||
label: this.$t('assets.Rules'),
|
|
||||||
formatter: DetailFormatter,
|
|
||||||
formatterArgs: {
|
|
||||||
getTitle: ({ cellValue }) => {
|
|
||||||
return cellValue.length
|
|
||||||
},
|
|
||||||
routeQuery: {
|
|
||||||
activeTab: 'rules'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
date_created: {
|
|
||||||
label: this.$t('users.DateJoined')
|
|
||||||
},
|
|
||||||
users: {
|
|
||||||
formatter: function(row, col, cell) {
|
|
||||||
return cell.length
|
|
||||||
}
|
|
||||||
},
|
|
||||||
user_groups: {
|
|
||||||
formatter: function(row, col, cell) {
|
|
||||||
return cell.length
|
|
||||||
}
|
|
||||||
},
|
|
||||||
assets: {
|
|
||||||
formatter: function(row, col, cell) {
|
|
||||||
return cell.length
|
|
||||||
}
|
|
||||||
},
|
|
||||||
applications: {
|
|
||||||
formatter: function(row, col, cell) {
|
|
||||||
return cell.length
|
|
||||||
}
|
|
||||||
},
|
|
||||||
system_users: {
|
|
||||||
label: this.$t('assets.SystemUsers'),
|
|
||||||
formatter: DetailFormatter,
|
|
||||||
formatterArgs: {
|
|
||||||
route: 'CommandFilterDetail',
|
|
||||||
getTitle: ({ cellValue }) => {
|
|
||||||
return cellValue.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
headerActions: {
|
|
||||||
hasRightActions: true,
|
|
||||||
hasExport: false,
|
|
||||||
hasImport: false,
|
|
||||||
hasRefresh: true,
|
|
||||||
hasSearch: true,
|
|
||||||
createRoute: 'CommandFilterCreate'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
title() {
|
|
||||||
return this.$t('assets.CommandFilterHelpMessage')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
</style>
|
|
@@ -66,7 +66,8 @@ export default {
|
|||||||
key: this.$t('assets.Type'),
|
key: this.$t('assets.Type'),
|
||||||
value: `${this.object.category?.label}/${this.object.type?.label}`
|
value: `${this.object.category?.label}/${this.object.type?.label}`
|
||||||
},
|
},
|
||||||
'su_method', 'comment'
|
'su_method', 'date_created', 'date_updated',
|
||||||
|
'created_by', 'updated_by', 'comment'
|
||||||
],
|
],
|
||||||
|
|
||||||
protocolChoices: null,
|
protocolChoices: null,
|
||||||
|
Reference in New Issue
Block a user