[Improvement][UI] Set the `required` to be reactive in the task modal. (#12225)

This commit is contained in:
Amy0104 2022-09-30 14:15:40 +08:00 committed by GitHub
parent aacabc6ec7
commit 64a23cdca2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 57 additions and 36 deletions

View File

@ -17,12 +17,19 @@
import { defineComponent, h, unref, renderSlot } from 'vue' import { defineComponent, h, unref, renderSlot } from 'vue'
import { useFormItem } from 'naive-ui/es/_mixins' import { useFormItem } from 'naive-ui/es/_mixins'
import { NFormItemGi, NSpace, NButton, NGrid, NGridItem } from 'naive-ui' import {
NFormItemGi,
NSpace,
NButton,
NGrid,
NGridItem,
FormItemRule
} from 'naive-ui'
import { isFunction } from 'lodash' import { isFunction } from 'lodash'
import { PlusOutlined, DeleteOutlined } from '@vicons/antd' import { PlusOutlined, DeleteOutlined } from '@vicons/antd'
import getField from './get-field' import getField from './get-field'
import { formatValidate } from '../utils' import { formatValidate } from '../utils'
import type { IJsonItem, FormItemRule } from '../types' import type { IJsonItem, IFormItemRule } from '../types'
const CustomParameters = defineComponent({ const CustomParameters = defineComponent({
name: 'CustomParameters', name: 'CustomParameters',
@ -66,11 +73,11 @@ const CustomParameters = defineComponent({
const getDefaultValue = (children: IJsonItem[]) => { const getDefaultValue = (children: IJsonItem[]) => {
const defaultValue: { [field: string]: any } = {} const defaultValue: { [field: string]: any } = {}
const ruleItem: { [key: string]: FormItemRule[] | FormItemRule } = {} const ruleItem: { [key: string]: IFormItemRule[] | IFormItemRule } = {}
const loop = ( const loop = (
children: IJsonItem[], children: IJsonItem[],
parent: { [field: string]: any }, parent: { [field: string]: any },
ruleParent: { [key: string]: FormItemRule[] | FormItemRule } ruleParent: { [key: string]: IFormItemRule[] | IFormItemRule }
) => { ) => {
children.forEach((child) => { children.forEach((child) => {
const mergedChild = isFunction(child) ? child() : child const mergedChild = isFunction(child) ? child() : child
@ -102,7 +109,7 @@ const getDefaultValue = (children: IJsonItem[]) => {
export function renderCustomParameters( export function renderCustomParameters(
item: IJsonItem, item: IJsonItem,
fields: { [field: string]: any }, fields: { [field: string]: any },
rules: { [key: string]: FormItemRule | FormItemRule[] }[] rules: { [key: string]: IFormItemRule | IFormItemRule[] }[]
) { ) {
const mergedItem = isFunction(item) ? item() : item const mergedItem = isFunction(item) ? item() : item
const { field, children = [] } = mergedItem const { field, children = [] } = mergedItem
@ -119,7 +126,7 @@ export function renderCustomParameters(
label: mergedChild.name, label: mergedChild.name,
span: unref(mergedChild.span), span: unref(mergedChild.span),
class: mergedChild.class, class: mergedChild.class,
rule: mergedChild.rule rule: mergedChild.rule as FormItemRule
}, },
() => getField(mergedChild, item) () => getField(mergedChild, item)
) )

View File

@ -16,8 +16,7 @@
*/ */
import * as Field from './index' import * as Field from './index'
import { camelCase, upperFirst, isFunction } from 'lodash' import { camelCase, upperFirst, isFunction } from 'lodash'
import type { FormRules, FormItemRule } from 'naive-ui' import type { IJsonItem, IFormRules, IFormItemRule } from '../types'
import type { IJsonItem } from '../types'
const TYPES = [ const TYPES = [
'input', 'input',
@ -37,7 +36,7 @@ const TYPES = [
const getField = ( const getField = (
item: IJsonItem, item: IJsonItem,
fields: { [field: string]: any }, fields: { [field: string]: any },
rules?: FormRules rules?: IFormRules
) => { ) => {
const { type = 'input', widget, field } = isFunction(item) ? item() : item const { type = 'input', widget, field } = isFunction(item) ? item() : item
if (!TYPES.includes(type)) return null if (!TYPES.includes(type)) return null
@ -47,7 +46,7 @@ const getField = (
} }
// TODO Support other widgets later // TODO Support other widgets later
if (type === 'custom-parameters') { if (type === 'custom-parameters') {
let fieldRules: { [key: string]: FormItemRule }[] = [] let fieldRules: { [key: string]: IFormItemRule }[] = []
if (rules && !rules[field]) fieldRules = rules[field] = [] if (rules && !rules[field]) fieldRules = rules[field] = []
// @ts-ignore // @ts-ignore
return Field[renderTypeName](item, fields, fieldRules) return Field[renderTypeName](item, fields, fieldRules)

View File

@ -20,7 +20,7 @@ import { useFormItem } from 'naive-ui/es/_mixins'
import { NFormItemGi, NSpace, NButton, NGrid, NGridItem } from 'naive-ui' import { NFormItemGi, NSpace, NButton, NGrid, NGridItem } from 'naive-ui'
import { PlusOutlined, DeleteOutlined } from '@vicons/antd' import { PlusOutlined, DeleteOutlined } from '@vicons/antd'
import { isFunction } from 'lodash' import { isFunction } from 'lodash'
import type { IJsonItem, FormItemRule } from '../types' import type { IJsonItem, IFormItemRule } from '../types'
import getField from '@/components/form/fields/get-field' import getField from '@/components/form/fields/get-field'
import { formatValidate } from '@/components/form/utils' import { formatValidate } from '@/components/form/utils'
@ -65,10 +65,9 @@ const MultiCondition = defineComponent({
export function renderMultiCondition( export function renderMultiCondition(
item: IJsonItem, item: IJsonItem,
fields: { [field: string]: any }, fields: { [field: string]: any }
unused: { [key: string]: FormItemRule }[]
) { ) {
const ruleItem: { [key: string]: FormItemRule } = {} const ruleItem: { [key: string]: IFormItemRule } = {}
// the fields is the data of the task definition. // the fields is the data of the task definition.
// the item is the options of this component in the form. // the item is the options of this component in the form.

View File

@ -19,14 +19,13 @@ import { toRef, Ref } from 'vue'
import { formatValidate } from './utils' import { formatValidate } from './utils'
import getField from './fields/get-field' import getField from './fields/get-field'
import { omit, isFunction } from 'lodash' import { omit, isFunction } from 'lodash'
import type { FormRules } from 'naive-ui' import type { IFormItem, IJsonItem, IFormRules } from './types'
import type { IFormItem, IJsonItem } from './types'
export default function getElementByJson( export default function getElementByJson(
json: IJsonItem[], json: IJsonItem[],
fields: { [field: string]: any } fields: { [field: string]: any }
) { ) {
const rules: FormRules = {} const rules: IFormRules = {}
const initialValues: { [field: string]: any } = {} const initialValues: { [field: string]: any } = {}
const elements: IFormItem[] = [] const elements: IFormItem[] = []
for (const item of json) { for (const item of json) {

View File

@ -16,7 +16,7 @@
*/ */
import { defineComponent, PropType, toRefs, h, unref } from 'vue' import { defineComponent, PropType, toRefs, h, unref } from 'vue'
import { NSpin, NGrid, NForm, NFormItemGi } from 'naive-ui' import { NSpin, NGrid, NForm, NFormItemGi, FormRules } from 'naive-ui'
import { useForm } from './use-form' import { useForm } from './use-form'
import type { GridProps, IMeta } from './types' import type { GridProps, IMeta } from './types'
@ -50,7 +50,7 @@ const Form = defineComponent({
const { elements = [], ...restFormProps } = meta const { elements = [], ...restFormProps } = meta
return ( return (
<NSpin show={loading}> <NSpin show={loading}>
<NForm {...restFormProps} ref='formRef'> <NForm {...restFormProps} rules={meta.rules as FormRules} ref='formRef'>
<NGrid {...layout}> <NGrid {...layout}>
{elements.map((element) => { {elements.map((element) => {
const { span = 24, path, widget, ...formItemProps } = element const { span = 24, path, widget, ...formItemProps } = element

View File

@ -45,18 +45,29 @@ interface IFormItem {
class?: string class?: string
} }
interface IMeta extends Omit<FormProps, 'model'> { interface IMeta extends Omit<FormProps, 'model' | 'rules'> {
elements?: IFormItem[] elements?: IFormItem[]
model: object model: object
rules: IFormRules
} }
interface IFormItemRule extends Omit<FormItemRule, 'required'> {
required?: boolean | Ref<boolean>
}
type IFormRules =
| {
[path: string]: IFormItemRule | IFormItemRule[]
}
| FormRules
interface IJsonItemParams { interface IJsonItemParams {
field: string field: string
name?: string name?: string
props?: any props?: any
title?: string title?: string
type?: IType type?: IType
validate?: FormItemRule validate?: IFormItemRule
value?: any value?: any
options?: IOption[] | Ref<IOption[]> options?: IOption[] | Ref<IOption[]>
children?: IJsonItem[] children?: IJsonItem[]
@ -65,7 +76,7 @@ interface IJsonItemParams {
widget?: any widget?: any
class?: string class?: string
path?: string path?: string
rule?: FormItemRule rule?: IFormItemRule
} }
type IJsonItemFn = (i?: number) => IJsonItemParams type IJsonItemFn = (i?: number) => IJsonItemParams
@ -81,5 +92,7 @@ export {
FormRules, FormRules,
IFormItem, IFormItem,
GridProps, GridProps,
IJsonItemParams IJsonItemParams,
IFormItemRule,
IFormRules
} }

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import type { FormRules, FormItemRule } from './types' import type { FormRules, IFormItemRule } from './types'
export function formatLabel(label?: string): string { export function formatLabel(label?: string): string {
if (!label) return '' if (!label) return ''
@ -23,11 +23,11 @@ export function formatLabel(label?: string): string {
} }
export function formatValidate( export function formatValidate(
validate?: FormItemRule | FormRules validate?: IFormItemRule | FormRules
): FormItemRule { ): IFormItemRule {
if (!validate) return {} if (!validate) return {}
if (Array.isArray(validate)) { if (Array.isArray(validate)) {
validate.forEach((item: FormItemRule) => { validate.forEach((item: IFormItemRule) => {
if (!item?.message) delete item.message if (!item?.message) delete item.message
return item return item
}) })

View File

@ -24,7 +24,7 @@ import type { IJsonItem, IResource } from '../types'
export function useResources( export function useResources(
span: number | Ref<number> = 24, span: number | Ref<number> = 24,
required = false, required: boolean | Ref<boolean> = false,
limit: number | Ref<number> = -1 limit: number | Ref<number> = -1
): IJsonItem { ): IJsonItem {
const { t } = useI18n() const { t } = useI18n()

View File

@ -31,7 +31,7 @@ import { useDetail } from './use-detail'
import Modal from '@/components/modal' import Modal from '@/components/modal'
import Form from '@/components/form' import Form from '@/components/form'
import getElementByJson from '@/components/form/get-elements-by-json' import getElementByJson from '@/components/form/get-elements-by-json'
import type { IRecord, FormRules, IFormItem } from './types' import type { IRecord, IFormRules, IFormItem } from './types'
import type { PropType, Ref } from 'vue' import type { PropType, Ref } from 'vue'
interface IElements extends Omit<Ref, 'value'> { interface IElements extends Omit<Ref, 'value'> {
@ -55,7 +55,7 @@ const DetailModal = defineComponent({
setup(props, ctx) { setup(props, ctx) {
const { t } = useI18n() const { t } = useI18n()
const rules = ref<FormRules>({}) const rules = ref<IFormRules>({})
const elements = ref<IFormItem[]>([]) as IElements const elements = ref<IFormItem[]>([]) as IElements
const { const {

View File

@ -17,8 +17,12 @@
import type { IPluginId } from '@/service/modules/ui-plugins/types' import type { IPluginId } from '@/service/modules/ui-plugins/types'
import type { TableColumns } from 'naive-ui/es/data-table/src/interface' import type { TableColumns } from 'naive-ui/es/data-table/src/interface'
import type { IMeta, IJsonItem, IFormItem } from '@/components/form/types' import type {
import type { FormRules } from 'naive-ui' IMeta,
IJsonItem,
IFormItem,
IFormRules
} from '@/components/form/types'
interface IRecord { interface IRecord {
alertPluginName?: string alertPluginName?: string
@ -47,5 +51,5 @@ export {
IMeta, IMeta,
IFormItem, IFormItem,
TableColumns, TableColumns,
FormRules IFormRules
} }

View File

@ -24,7 +24,7 @@ import {
import type { import type {
IPluginId, IPluginId,
IPlugin, IPlugin,
FormRules, IFormRules,
IMeta, IMeta,
IJsonItem, IJsonItem,
IRecord IRecord
@ -60,13 +60,13 @@ export function useForm() {
pluginDefineId: { pluginDefineId: {
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
required: true, required: true,
validator(validte, value) { validator(unused: any, value: number) {
if (!value && value !== 0) { if (!value && value !== 0) {
return new Error(t('security.alarm_instance.select_plugin_tips')) return new Error(t('security.alarm_instance.select_plugin_tips'))
} }
} }
} }
} as FormRules } as IFormRules
} as IMeta } as IMeta
const getUiPluginsByType = async () => { const getUiPluginsByType = async () => {