mirror of
https://github.com/jumpserver/lina.git
synced 2025-11-09 19:31:26 +00:00
162 lines
4.9 KiB
JavaScript
162 lines
4.9 KiB
JavaScript
import Vue from 'vue'
|
|
import Select2 from '@/components/FormFields/Select2'
|
|
import NestedField from '@/components/AutoDataForm/components/NestedField'
|
|
import rules from '@/components/DataForm/rules'
|
|
import { assignIfNot } from '@/utils/common'
|
|
|
|
export class FormFieldGenerator {
|
|
constructor() {
|
|
this.groups = []
|
|
}
|
|
generateFieldByType(type, field, fieldMeta, fieldRemoteMeta) {
|
|
switch (type) {
|
|
case 'choice':
|
|
type = 'radio-group'
|
|
if (!fieldRemoteMeta.read_only) {
|
|
field.options = fieldRemoteMeta.choices.map(v => {
|
|
return { label: v.display_name, value: v.value }
|
|
})
|
|
}
|
|
break
|
|
case 'multiple choice':
|
|
field.el.choices = fieldRemoteMeta['choices']
|
|
break
|
|
case 'datetime':
|
|
type = 'date-picker'
|
|
field.el = {
|
|
type: 'datetime'
|
|
}
|
|
break
|
|
case 'field':
|
|
type = ''
|
|
field.component = Select2
|
|
if (fieldRemoteMeta.required) {
|
|
field.el.clearable = false
|
|
}
|
|
break
|
|
case 'string':
|
|
type = 'input'
|
|
if (!fieldRemoteMeta['max_length']) {
|
|
field.el.type = 'textarea'
|
|
field.el.rows = 3
|
|
}
|
|
if (fieldRemoteMeta['write_only']) {
|
|
field.el.type = 'password'
|
|
}
|
|
break
|
|
case 'boolean':
|
|
type = 'checkbox'
|
|
break
|
|
case 'nested object':
|
|
type = 'nestedField'
|
|
field.component = NestedField
|
|
field.label = ''
|
|
field.labelWidth = 0
|
|
field.el.fields = this.generateNestFields(field, fieldMeta, fieldRemoteMeta)
|
|
field.el.errors = {}
|
|
Vue.$log.debug('All fields in generate: ', field.el.allFields)
|
|
break
|
|
default:
|
|
type = 'input'
|
|
break
|
|
}
|
|
if (type === 'radio-group') {
|
|
if (!fieldRemoteMeta.read_only) {
|
|
const options = fieldRemoteMeta.choices.map(v => {
|
|
return { label: v.display_name, value: v.value }
|
|
})
|
|
if (options.length > 4) {
|
|
type = 'select'
|
|
field.el.filterable = true
|
|
}
|
|
}
|
|
}
|
|
field.type = type
|
|
return field
|
|
}
|
|
generateNestFields(field, fieldMeta, fieldRemoteMeta) {
|
|
const fields = []
|
|
const nestedFields = fieldMeta.fields || []
|
|
const nestedFieldsMeta = fieldMeta.fieldsMeta || {}
|
|
const nestedFieldsRemoteMeta = fieldRemoteMeta.children || {}
|
|
for (const name of nestedFields) {
|
|
const f = this.generateField(name, nestedFieldsMeta, nestedFieldsRemoteMeta)
|
|
fields.push(f)
|
|
}
|
|
Vue.$log.debug('NestFields: ', fields)
|
|
return fields
|
|
}
|
|
generateFieldByName(name, field) {
|
|
switch (name) {
|
|
case 'email':
|
|
field.el.type = 'email'
|
|
break
|
|
case 'password':
|
|
field.el.type = 'password'
|
|
break
|
|
case 'comment':
|
|
field.el.type = 'textarea'
|
|
break
|
|
}
|
|
return field
|
|
}
|
|
generateFieldByOther(field, fieldMeta, fieldRemoteMeta) {
|
|
const filedRules = field.rules || []
|
|
if (fieldRemoteMeta.required) {
|
|
if (field.type === 'input') {
|
|
filedRules.push(rules.Required)
|
|
} else {
|
|
filedRules.push(rules.RequiredChange)
|
|
}
|
|
}
|
|
field.rules = filedRules
|
|
return field
|
|
}
|
|
generateField(name, fieldsMeta, remoteFieldsMeta) {
|
|
let field = { id: name, prop: name, el: {}, attrs: {}, rules: [] }
|
|
const remoteFieldMeta = remoteFieldsMeta[name] || {}
|
|
const fieldMeta = fieldsMeta[name] || {}
|
|
field.label = remoteFieldMeta.label
|
|
field.helpText = remoteFieldMeta.help_text
|
|
field = this.generateFieldByType(remoteFieldMeta.type, field, fieldMeta, remoteFieldMeta)
|
|
field = this.generateFieldByName(name, field)
|
|
field = this.generateFieldByOther(field, fieldMeta, remoteFieldMeta)
|
|
const el = assignIfNot(fieldMeta.el || {}, field.el)
|
|
const rules = fieldMeta.rules || field.rules
|
|
field = Object.assign(field, fieldMeta)
|
|
field.el = el
|
|
field.rules = rules
|
|
_.set(field, 'attrs.error', '')
|
|
// Vue.$log.debug('Generate field: ', name, field)
|
|
return field
|
|
}
|
|
generateFieldGroup(field, fieldsMeta, remoteFieldsMeta) {
|
|
const [groupTitle, fields] = field
|
|
this.groups.push({
|
|
id: groupTitle,
|
|
title: groupTitle,
|
|
name: fields[0],
|
|
fields: fields
|
|
})
|
|
return this.generateFields(fields, fieldsMeta, remoteFieldsMeta)
|
|
}
|
|
generateFields(_fields, fieldsMeta, remoteFieldsMeta) {
|
|
let fields = []
|
|
for (let field of _fields) {
|
|
if (field instanceof Array) {
|
|
const items = this.generateFieldGroup(field, fieldsMeta, remoteFieldsMeta)
|
|
fields = [...fields, ...items]
|
|
} else if (typeof field === 'string') {
|
|
field = this.generateField(field, fieldsMeta, remoteFieldsMeta)
|
|
fields.push(field)
|
|
} else if (field instanceof Object) {
|
|
if (this.errors) {
|
|
this.errors[field.prop] = ''
|
|
}
|
|
fields.push(field)
|
|
}
|
|
}
|
|
return fields
|
|
}
|
|
}
|