mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-13 05:39:06 +00:00
perf: stash json
This commit is contained in:
@@ -12,8 +12,8 @@
|
|||||||
<slot />
|
<slot />
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<slot name="footer">
|
<slot name="footer">
|
||||||
<el-button v-if="showCancel" @click="onCancel">{{ cancelTitle }}</el-button>
|
<el-button v-if="showCancel && showButtons" @click="onCancel">{{ cancelTitle }}</el-button>
|
||||||
<el-button v-if="showConfirm" :loading="loadingStatus" type="primary" @click="onConfirm">
|
<el-button v-if="showConfirm && showButtons" :loading="loadingStatus" type="primary" @click="onConfirm">
|
||||||
{{ confirmTitle }}
|
{{ confirmTitle }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -29,16 +29,6 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'Title'
|
default: 'Title'
|
||||||
},
|
},
|
||||||
showCancel: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
cancelTitle: {
|
|
||||||
type: String,
|
|
||||||
default() {
|
|
||||||
return this.$t('common.Cancel')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
top: {
|
top: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '3vh'
|
default: '3vh'
|
||||||
@@ -51,16 +41,30 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
loadingStatus: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
confirmTitle: {
|
confirmTitle: {
|
||||||
type: String,
|
type: String,
|
||||||
default() {
|
default() {
|
||||||
return this.$t('common.Confirm')
|
return this.$t('common.Confirm')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
showCancel: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
cancelTitle: {
|
||||||
|
type: String,
|
||||||
|
default() {
|
||||||
|
return this.$t('common.Cancel')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showButtons: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
loadingStatus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
maxWidth: {
|
maxWidth: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '1200px'
|
default: '1200px'
|
||||||
|
@@ -1,16 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div v-if="!loading">
|
||||||
<TagInput v-if="Array.isArray(value)" :value="value" @input="handleInput" />
|
<TagInput v-if="type === 'array'" :value="value" @input="handleInput" />
|
||||||
|
<Select2 v-else-if="type === 'select'" :value="value" v-bind="attr.el" @change="handleInput" @input="handleInput" />
|
||||||
|
<Switcher v-else-if="type === 'bool'" :value="value" @change="handleInput" />
|
||||||
<el-input v-else :value="value" @input="handleInput" />
|
<el-input v-else :value="value" @input="handleInput" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import TagInput from '@/components/FormFields/TagInput.vue'
|
import TagInput from '@/components/FormFields/TagInput.vue'
|
||||||
|
import Select2 from '@/components/FormFields/Select2.vue'
|
||||||
|
import Switcher from '@/components/FormFields/Switcher.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ValueField',
|
name: 'ValueField',
|
||||||
components: { TagInput },
|
components: { Switcher, TagInput, Select2 },
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: [String, Number, Boolean, Array, Object],
|
type: [String, Number, Boolean, Array, Object],
|
||||||
@@ -18,11 +22,44 @@ export default {
|
|||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: 'exact'
|
||||||
|
},
|
||||||
|
attr: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
loading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
type() {
|
||||||
|
const attrType = this.attr.type
|
||||||
|
if (attrType === 'm2m') {
|
||||||
|
return 'select'
|
||||||
|
} else if (attrType === 'bool') {
|
||||||
|
return 'bool'
|
||||||
|
} else if (attrType === 'select') {
|
||||||
|
return 'select'
|
||||||
|
}
|
||||||
|
if (this.match in ['in', 'ip_in']) {
|
||||||
|
return 'array'
|
||||||
|
} else {
|
||||||
|
return 'string'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
attr: {
|
||||||
|
handler() {
|
||||||
|
this.loading = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<span v-if="attr.type === 'bool'">
|
||||||
|
<i v-if="value" class="fa fa-check text-primary" />
|
||||||
|
<i v-else class="fa fa-times text-danger" />
|
||||||
|
</span>
|
||||||
|
<span v-else :title="value">{{ value }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BaseFormatter from '@/components/TableFormatters/base.vue'
|
||||||
|
import { setUrlParam } from '@/utils/common'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ValueFormatter',
|
||||||
|
extends: BaseFormatter,
|
||||||
|
props: {
|
||||||
|
formatterArgsDefault: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
attrs: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const formatterArgs = Object.assign(this.formatterArgsDefault, this.col.formatterArgs)
|
||||||
|
return {
|
||||||
|
formatterArgs: formatterArgs,
|
||||||
|
loading: true,
|
||||||
|
value: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
attr() {
|
||||||
|
return this.formatterArgs.attrs.find(attr => attr.name === this.row.name) || {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
cellValue: {
|
||||||
|
handler(val) {
|
||||||
|
this.getValue()
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getValue()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getValue() {
|
||||||
|
if (this.attr.type === 'm2m') {
|
||||||
|
const url = setUrlParam(this.attr.el.url, 'ids', this.cellValue.join(','))
|
||||||
|
const data = await this.$axios.get(url)
|
||||||
|
if (data.length > 0) {
|
||||||
|
const displayField = this.attr.el.displayField || 'name'
|
||||||
|
this.value = data.map(item => item[displayField]).join(', ')
|
||||||
|
}
|
||||||
|
} else if (this.attr.type === 'select') {
|
||||||
|
this.value = this.attr.el.options
|
||||||
|
.filter(item => this.cellValue.includes(item.value))
|
||||||
|
.map(item => item.label).join(',')
|
||||||
|
} else {
|
||||||
|
this.value = this.cellValue
|
||||||
|
}
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@@ -14,7 +14,7 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Dialog v-if="visible" :show-cancel="false" :show-confirm="false" :visible.sync="visible" title="选择属性">
|
<Dialog v-if="visible" :show-buttons="false" :visible.sync="visible" title="选择属性">
|
||||||
<DataForm class="attr-form" v-bind="formConfig" @submit="onAttrDialogConfirm" />
|
<DataForm class="attr-form" v-bind="formConfig" @submit="onAttrDialogConfirm" />
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -25,6 +25,7 @@ import Select2 from '../Select2.vue'
|
|||||||
import DataTable from '@/components/DataTable/index.vue'
|
import DataTable from '@/components/DataTable/index.vue'
|
||||||
import Dialog from '@/components/Dialog/index.vue'
|
import Dialog from '@/components/Dialog/index.vue'
|
||||||
import DataForm from '@/components/DataForm/index.vue'
|
import DataForm from '@/components/DataForm/index.vue'
|
||||||
|
import ValueFormatter from './ValueFormatter.vue'
|
||||||
import ValueField from './ValueField.vue'
|
import ValueField from './ValueField.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -61,14 +62,24 @@ export default {
|
|||||||
{ label: this.$t('common.Startswith'), value: 'startswith' },
|
{ label: this.$t('common.Startswith'), value: 'startswith' },
|
||||||
{ label: this.$t('common.Endswith'), value: 'endswith' },
|
{ label: this.$t('common.Endswith'), value: 'endswith' },
|
||||||
{ label: this.$t('common.Regex'), value: 'regex' },
|
{ label: this.$t('common.Regex'), value: 'regex' },
|
||||||
{ label: this.$t('common.IPMatch'), value: 'ip_in' }
|
{ label: this.$t('common.BelongTo'), value: 'm2m' },
|
||||||
|
{ label: this.$t('common.IPMatch'), value: 'ip_in' },
|
||||||
|
{ label: this.$t('common.GreatEqualThan'), value: 'gte' },
|
||||||
|
{ label: this.$t('common.LessEqualThan'), value: 'lte' }
|
||||||
]
|
]
|
||||||
const attrRelOptions = [
|
|
||||||
{ label: this.$t('common.RelAnd'), value: 'and' },
|
const strMatchValues = ['exact', 'not', 'in', 'contains', 'startswith', 'endswith', 'regex']
|
||||||
{ label: this.$t('common.RelOr'), value: 'or' },
|
const typeMatchMapper = {
|
||||||
{ label: this.$t('common.RelNot'), value: 'not' }
|
str: strMatchValues,
|
||||||
]
|
bool: ['exact', 'not'],
|
||||||
const attrNameOptions = this.attrs.map(attr => ({ label: attr.label, value: attr.name }))
|
m2m: ['m2m'],
|
||||||
|
ip: strMatchValues + ['ip_in'],
|
||||||
|
int: strMatchValues + ['gte', 'lte'],
|
||||||
|
select: ['in']
|
||||||
|
}
|
||||||
|
attrMatchOptions.forEach((option) => {
|
||||||
|
option.hidden = !typeMatchMapper[this.attrs[0].type || 'str'].includes(option.value)
|
||||||
|
})
|
||||||
const tableFormatter = (colName) => {
|
const tableFormatter = (colName) => {
|
||||||
return (row, col, cellValue) => {
|
return (row, col, cellValue) => {
|
||||||
const value = cellValue
|
const value = cellValue
|
||||||
@@ -77,8 +88,6 @@ export default {
|
|||||||
return this.attrs.find(attr => attr.name === value)?.label || value
|
return this.attrs.find(attr => attr.name === value)?.label || value
|
||||||
case 'match':
|
case 'match':
|
||||||
return attrMatchOptions.find(opt => opt.value === value).label || value
|
return attrMatchOptions.find(opt => opt.value === value).label || value
|
||||||
case 'rel':
|
|
||||||
return attrRelOptions.find(opt => opt.value === value)?.label || value
|
|
||||||
case 'value':
|
case 'value':
|
||||||
return Array.isArray(value) ? value.join(', ') : value
|
return Array.isArray(value) ? value.join(', ') : value
|
||||||
default:
|
default:
|
||||||
@@ -98,8 +107,7 @@ export default {
|
|||||||
columns: [
|
columns: [
|
||||||
{ prop: 'name', label: this.$t('common.AttrName'), formatter: tableFormatter('name') },
|
{ prop: 'name', label: this.$t('common.AttrName'), formatter: tableFormatter('name') },
|
||||||
{ prop: 'match', label: this.$t('common.Match'), formatter: tableFormatter('match') },
|
{ prop: 'match', label: this.$t('common.Match'), formatter: tableFormatter('match') },
|
||||||
{ prop: 'value', label: this.$t('common.AttrValue'), formatter: tableFormatter('value') },
|
{ prop: 'value', label: this.$t('common.AttrValue'), formatter: ValueFormatter, formatterArgs: { attrs: this.attrs }},
|
||||||
{ prop: 'rel', label: this.$t('common.Relation'), formatter: tableFormatter('rel') },
|
|
||||||
{ prop: 'action', label: this.$t('common.Action'), formatter: (row, col, cellValue, index) => {
|
{ prop: 'action', label: this.$t('common.Action'), formatter: (row, col, cellValue, index) => {
|
||||||
return (
|
return (
|
||||||
<div className='input-button'>
|
<div className='input-button'>
|
||||||
@@ -126,46 +134,48 @@ export default {
|
|||||||
},
|
},
|
||||||
formConfig: {
|
formConfig: {
|
||||||
// 为了方便更新,避免去取 fields 的索引
|
// 为了方便更新,避免去取 fields 的索引
|
||||||
attrNameOptions: attrNameOptions,
|
|
||||||
hasSaveContinue: false,
|
hasSaveContinue: false,
|
||||||
editRowIndex: -1,
|
editRowIndex: -1,
|
||||||
form: {},
|
form: {},
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
id: 'name',
|
id: 'name',
|
||||||
label: '属性',
|
label: this.$t('common.AttrName'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
options: attrNameOptions
|
options: this.attrs.map(attr => ({ label: attr.label, value: attr.name })),
|
||||||
|
on: {
|
||||||
|
change: ([val], updateForm) => {
|
||||||
|
const attr = this.attrs.find(attr => attr.name === val)
|
||||||
|
if (!attr) return
|
||||||
|
this.formConfig.fields[2].el.attr = attr
|
||||||
|
const attrType = attr.type || 'str'
|
||||||
|
const matchSupports = typeMatchMapper[attrType]
|
||||||
|
attrMatchOptions.forEach((option) => {
|
||||||
|
option.hidden = !matchSupports.includes(option.value)
|
||||||
|
})
|
||||||
|
setTimeout(() => updateForm({ match: matchSupports[0] }), 0.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'match',
|
id: 'match',
|
||||||
label: '匹配方式',
|
label: this.$t('common.Match'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
options: attrMatchOptions,
|
options: attrMatchOptions,
|
||||||
on: {
|
on: {
|
||||||
change: ([value], updateForm) => {
|
change: ([value], updateForm) => {
|
||||||
this.formConfig.fields[2].el.match = value
|
this.formConfig.fields[2].el.match = value
|
||||||
if (['in', 'ip_in'].includes(value)) {
|
|
||||||
updateForm({ value: [] })
|
|
||||||
} else {
|
|
||||||
updateForm({ value: '' })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'value',
|
id: 'value',
|
||||||
label: '值',
|
label: this.$t('common.AttrValue'),
|
||||||
component: ValueField,
|
component: ValueField,
|
||||||
el: {
|
el: {
|
||||||
match: 'exact'
|
match: attrMatchOptions[0].value,
|
||||||
|
attr: this.attrs[0]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'rel',
|
|
||||||
label: '关系',
|
|
||||||
type: 'radio-group',
|
|
||||||
options: attrRelOptions
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -209,9 +219,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setAttrNameOptionUsed() {
|
setAttrNameOptionUsed() {
|
||||||
const options = this.formConfig.attrNameOptions
|
const options = this.formConfig.fields[0].options
|
||||||
const used = this.tableConfig.totalData.map(attr => attr.name)
|
const used = this.tableConfig.totalData.map(attr => attr.name)
|
||||||
console.log('Used: ', used)
|
|
||||||
options.forEach(opt => {
|
options.forEach(opt => {
|
||||||
if (used.includes(opt.value)) {
|
if (used.includes(opt.value)) {
|
||||||
opt.disabled = true
|
opt.disabled = true
|
||||||
@@ -219,11 +228,11 @@ export default {
|
|||||||
delete opt.disabled
|
delete opt.disabled
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log('Options: ', options)
|
|
||||||
},
|
},
|
||||||
handleAttrEdit({ row, index }) {
|
handleAttrEdit({ row, index }) {
|
||||||
return () => {
|
return () => {
|
||||||
this.formConfig.editRowIndex = index
|
this.formConfig.editRowIndex = index
|
||||||
|
this.formConfig.fields[2].el.attr = this.attrs.find(attr => attr.name === row.name)
|
||||||
this.formConfig.form = Object.assign({ index }, row)
|
this.formConfig.form = Object.assign({ index }, row)
|
||||||
this.setAttrNameOptionUsed()
|
this.setAttrNameOptionUsed()
|
||||||
this.visible = true
|
this.visible = true
|
||||||
@@ -236,6 +245,7 @@ export default {
|
|||||||
},
|
},
|
||||||
handleAttrAdd() {
|
handleAttrAdd() {
|
||||||
this.formConfig.form = this.getDefaultAttrForm()
|
this.formConfig.form = this.getDefaultAttrForm()
|
||||||
|
this.formConfig.fields[2].el.attr = this.attrs.find(attr => attr.name === this.formConfig.form.name)
|
||||||
this.setAttrNameOptionUsed()
|
this.setAttrNameOptionUsed()
|
||||||
this.visible = true
|
this.visible = true
|
||||||
},
|
},
|
||||||
|
@@ -456,6 +456,11 @@
|
|||||||
"ReLoginErr": "登录时长已超过 5 分钟,请重新登录"
|
"ReLoginErr": "登录时长已超过 5 分钟,请重新登录"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
|
"GreatEqualThan": "大于等于",
|
||||||
|
"LessEqualThan": "小于等于",
|
||||||
|
"BelongTo": "所属",
|
||||||
|
"Email": "邮箱",
|
||||||
|
"IsActive": "激活",
|
||||||
"All": "所有",
|
"All": "所有",
|
||||||
"Spec": "指定",
|
"Spec": "指定",
|
||||||
"SelectByAttr": "属性筛选",
|
"SelectByAttr": "属性筛选",
|
||||||
|
@@ -140,6 +140,23 @@ export const assetFieldsMeta = (vm) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const assetJSONSelectMeta = (vm) => {
|
export const assetJSONSelectMeta = (vm) => {
|
||||||
|
const categories = []
|
||||||
|
const types = []
|
||||||
|
const protocols = []
|
||||||
|
vm.$axios.get('/api/v1/assets/categories/').then((res) => {
|
||||||
|
const _types = []
|
||||||
|
const _protocols = []
|
||||||
|
for (const category of res) {
|
||||||
|
categories.push({ value: category.value, label: category.label })
|
||||||
|
_types.push(...category.types.map(item => ({ value: item.value, label: item.label })))
|
||||||
|
for (const type of category.types) {
|
||||||
|
_protocols.push(...type.constraints.protocols?.map(item => ({ value: item.name, label: item.name.toUpperCase() })))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
types.push(..._.uniqBy(_types, 'value'))
|
||||||
|
protocols.push(..._.uniqBy(_protocols, 'value'))
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
component: JSONManyToManySelect,
|
component: JSONManyToManySelect,
|
||||||
el: {
|
el: {
|
||||||
@@ -160,7 +177,63 @@ export const assetJSONSelectMeta = (vm) => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'address',
|
name: 'address',
|
||||||
label: vm.$t('assets.Address')
|
label: vm.$t('assets.Address'),
|
||||||
|
type: 'ip'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'nodes',
|
||||||
|
label: vm.$t('assets.Node'),
|
||||||
|
type: 'm2m',
|
||||||
|
el: {
|
||||||
|
url: '/api/v1/assets/nodes/',
|
||||||
|
ajax: {
|
||||||
|
transformOption: (item) => {
|
||||||
|
return { label: item.full_value, value: item.id }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'platform',
|
||||||
|
label: vm.$t('assets.Platform'),
|
||||||
|
type: 'm2m',
|
||||||
|
el: {
|
||||||
|
multiple: false,
|
||||||
|
url: '/api/v1/assets/platforms/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
label: vm.$t('assets.Category'),
|
||||||
|
type: 'select',
|
||||||
|
el: {
|
||||||
|
options: categories
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'type',
|
||||||
|
label: vm.$t('assets.Type'),
|
||||||
|
type: 'select',
|
||||||
|
el: {
|
||||||
|
options: types
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'protocols',
|
||||||
|
label: vm.$t('assets.Protocols'),
|
||||||
|
type: 'select',
|
||||||
|
el: {
|
||||||
|
options: protocols
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'labels',
|
||||||
|
label: vm.$t('assets.Label'),
|
||||||
|
type: 'm2m',
|
||||||
|
el: {
|
||||||
|
multiple: true,
|
||||||
|
url: '/api/v1/assets/labels/'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -176,6 +176,7 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initDefaultChoice()
|
this.initDefaultChoice()
|
||||||
|
this.$emit('input', this.value)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initDefaultChoice() {
|
initDefaultChoice() {
|
||||||
|
@@ -22,6 +22,55 @@ export const userJSONSelectMeta = (vm) => {
|
|||||||
{
|
{
|
||||||
name: 'username',
|
name: 'username',
|
||||||
label: vm.$t('common.Username')
|
label: vm.$t('common.Username')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'email',
|
||||||
|
label: vm.$t('common.Email')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'comment',
|
||||||
|
label: vm.$t('common.Comment')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'is_active',
|
||||||
|
label: vm.$t('common.IsActive'),
|
||||||
|
type: 'bool'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'system_roles',
|
||||||
|
label: vm.$t('users.SystemRoles'),
|
||||||
|
type: 'm2m',
|
||||||
|
el: {
|
||||||
|
url: '/api/v1/rbac/system-roles/?fields_size=mini',
|
||||||
|
ajax: {
|
||||||
|
transformOption: (item) => {
|
||||||
|
return { label: item.display_name, value: item.id }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
displayField: 'display_name'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'org_roles',
|
||||||
|
label: vm.$t('users.OrgRoles'),
|
||||||
|
type: 'm2m',
|
||||||
|
el: {
|
||||||
|
url: '/api/v1/rbac/org-roles/',
|
||||||
|
ajax: {
|
||||||
|
transformOption: (item) => {
|
||||||
|
return { label: item.display_name, value: item.id }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
displayField: 'display_name'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'groups',
|
||||||
|
label: vm.$t('users.UserGroups'),
|
||||||
|
type: 'm2m',
|
||||||
|
el: {
|
||||||
|
url: '/api/v1/users/groups/?fields_size=mini'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user