From 6be220129fe214eeb56b9e774ef42c65b78bffa8 Mon Sep 17 00:00:00 2001 From: Amy0104 <97265214+Amy0104@users.noreply.github.com> Date: Mon, 31 Jan 2022 12:24:16 +0800 Subject: [PATCH] [Feature][UI Next] Add custom parameters to form (#8271) --- .../form/fields/custom-parameters.ts | 86 +++++++++++++++++++ .../src/components/form/fields/get-field.ts | 61 +++++++++++++ .../src/components/form/fields/index.ts | 21 +++++ .../src/components/form/fields/input.ts | 29 +++++++ .../components/form/fields/monaco-editor.ts | 29 +++++++ .../form/{fields.ts => fields/radio.ts} | 31 +------ .../components/form/get-elements-by-json.ts | 35 ++------ .../src/components/form/types.ts | 5 +- .../src/components/form/use-form.ts | 4 +- 9 files changed, 244 insertions(+), 57 deletions(-) create mode 100644 dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts create mode 100644 dolphinscheduler-ui-next/src/components/form/fields/get-field.ts create mode 100644 dolphinscheduler-ui-next/src/components/form/fields/index.ts create mode 100644 dolphinscheduler-ui-next/src/components/form/fields/input.ts create mode 100644 dolphinscheduler-ui-next/src/components/form/fields/monaco-editor.ts rename dolphinscheduler-ui-next/src/components/form/{fields.ts => fields/radio.ts} (60%) diff --git a/dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts b/dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts new file mode 100644 index 0000000000..a224fd2843 --- /dev/null +++ b/dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { h } from 'vue' +import { NFormItem, NSpace, NButton, NIcon } from 'naive-ui' +import { PlusCircleOutlined, DeleteOutlined } from '@vicons/antd' +import getField from './get-field' +import { formatValidate } from '../utils' +import type { IFieldParams, IJsonItem, FormItemRule } from '../types' + +interface ICustomParameters extends Omit { + rules?: { [key: string]: FormItemRule }[] +} + +export function renderCustomParameters(params: ICustomParameters) { + const { fields, field, children = [], rules = [] } = params + let defaultValue: { [field: string]: any } = {} + let ruleItem: { [key: string]: FormItemRule } = {} + children.forEach((child) => { + defaultValue[child.field] = child.value || null + if (child.validate) ruleItem[child.field] = formatValidate(child.validate) + }) + const getChild = (item: object, i: number) => + children.map((child: IJsonItem) => { + return h( + NFormItem, + { + showLabel: false, + path: `${field}[${i}].${child.field}` + }, + () => getField(child, item) + ) + }) + + const getChildren = () => + fields[field].map((item: object, i: number) => { + return h(NSpace, { ':key': i }, () => [ + ...getChild(item, i), + h( + NButton, + { + tertiary: true, + circle: true, + type: 'error', + onClick: () => { + fields[field].splice(i, 1) + rules.splice(i, 1) + } + }, + () => h(NIcon, { size: 24 }, () => h(DeleteOutlined)) + ) + ]) + }) + + return h(NSpace, null, () => [ + ...getChildren(), + h( + NButton, + { + tertiary: true, + circle: true, + type: 'info', + onClick: () => { + rules.push(ruleItem) + fields[field].push({ ...defaultValue }) + console.log(rules) + } + }, + () => h(NIcon, { size: 24 }, () => h(PlusCircleOutlined)) + ) + ]) +} diff --git a/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts b/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts new file mode 100644 index 0000000000..f0fe77993c --- /dev/null +++ b/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import * as Field from './index' +import type { FormRules } from 'naive-ui' +import type { IJsonItem } from '../types' + +const getField = ( + item: IJsonItem, + fields: { [field: string]: any }, + rules?: FormRules +) => { + const { type, props = {}, field, options, children } = item + // TODO Support other widgets later + if (type === 'radio') { + return Field.renderRadio({ + field, + fields, + props, + options + }) + } + if (type === 'editor') { + return Field.renderEditor({ + field, + fields, + props + }) + } + + if (type === 'custom-parameters') { + const params = { + field, + fields, + children, + props, + rules: [] + } + if (rules) { + params.rules = rules[field] = [] + } + return Field.renderCustomParameters(params) + } + + return Field.renderInput({ field, fields, props }) +} + +export default getField diff --git a/dolphinscheduler-ui-next/src/components/form/fields/index.ts b/dolphinscheduler-ui-next/src/components/form/fields/index.ts new file mode 100644 index 0000000000..5c01ec8717 --- /dev/null +++ b/dolphinscheduler-ui-next/src/components/form/fields/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { renderInput } from './input' +export { renderRadio } from './radio' +export { renderEditor } from './monaco-editor' +export { renderCustomParameters } from './custom-parameters' diff --git a/dolphinscheduler-ui-next/src/components/form/fields/input.ts b/dolphinscheduler-ui-next/src/components/form/fields/input.ts new file mode 100644 index 0000000000..50f38c0417 --- /dev/null +++ b/dolphinscheduler-ui-next/src/components/form/fields/input.ts @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { h } from 'vue' +import { NInput } from 'naive-ui' +import type { IFieldParams } from '../types' + +export function renderInput(params: IFieldParams) { + const { props, fields, field } = params + return h(NInput, { + ...props, + value: fields[field], + onUpdateValue: (value: string) => void (fields[field] = value) + }) +} diff --git a/dolphinscheduler-ui-next/src/components/form/fields/monaco-editor.ts b/dolphinscheduler-ui-next/src/components/form/fields/monaco-editor.ts new file mode 100644 index 0000000000..d51f5f05c2 --- /dev/null +++ b/dolphinscheduler-ui-next/src/components/form/fields/monaco-editor.ts @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { h } from 'vue' +import Editor from '@/components/monaco-editor' +import type { IFieldParams } from '../types' + +export function renderEditor(params: IFieldParams) { + const { props, fields, field } = params + return h(Editor, { + ...props, + value: fields[field], + onUpdateValue: (value: string) => void (fields[field] = value) + }) +} diff --git a/dolphinscheduler-ui-next/src/components/form/fields.ts b/dolphinscheduler-ui-next/src/components/form/fields/radio.ts similarity index 60% rename from dolphinscheduler-ui-next/src/components/form/fields.ts rename to dolphinscheduler-ui-next/src/components/form/fields/radio.ts index e1d5b859b9..821bb89903 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/radio.ts @@ -16,29 +16,16 @@ */ import { h } from 'vue' -import { NInput, NRadio, NRadioGroup, NSpace } from 'naive-ui' -import Editor from '@/components/monaco-editor' -import type { IFieldParams } from './types' +import { NRadio, NRadioGroup, NSpace } from 'naive-ui' +import type { IFieldParams, IOption } from '../types' -// TODO Support other widgets later -// Input -export function renderInput(params: IFieldParams) { - const { props, fields, field } = params - return h(NInput, { - ...props, - value: fields[field], - onUpdateValue: (value) => void (fields[field] = value) - }) -} - -// Radio && RadioGroup export function renderRadio(params: IFieldParams) { const { props, fields, field, options } = params if (!options || options.length === 0) { return h(NRadio, { ...props, value: fields[field], - onUpdateChecked: (checked) => void (fields[field] = checked) + onUpdateChecked: (checked: boolean) => void (fields[field] = checked) }) } return h( @@ -49,17 +36,7 @@ export function renderRadio(params: IFieldParams) { }, () => h(NSpace, null, () => - options.map((option) => h(NRadio, option, () => option.label)) + options.map((option: IOption) => h(NRadio, option, () => option.label)) ) ) } - -// Editor -export function renderEditor(params: IFieldParams) { - const { props, fields, field } = params - return h(Editor, { - ...props, - value: fields[field], - onUpdateValue: (value) => void (fields[field] = value) - }) -} diff --git a/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts b/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts index 48fdef396a..a5911c4db9 100644 --- a/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts +++ b/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -import * as Field from './fields' import { formatValidate } from './utils' +import getField from './fields/get-field' import type { FormRules } from 'naive-ui' import type { IJsonItem } from './types' @@ -28,36 +28,17 @@ export default function getElementByJson( const initialValues: { [field: string]: any } = {} const elements = [] - const getElement = (item: IJsonItem) => { - const { type, props = {}, field, options } = item - // TODO Support other widgets later - if (type === 'radio') { - return Field.renderRadio({ - field, - fields, - props, - options - }) - } - if (type === 'editor') { - return Field.renderEditor({ - field, - fields, - props - }) - } - - return Field.renderInput({ field, fields, props }) - } - for (let item of json) { - fields[item.field] = item.value - initialValues[item.field] = item.value + if (item.value) { + fields[item.field] = item.value + initialValues[item.field] = item.value + } if (item.validate) rules[item.field] = formatValidate(item.validate) elements.push({ label: item.name, - path: item.field, - widget: () => getElement(item) + path: !item.children ? item.field : '', + showLabel: !!item.name, + widget: () => getField(item, fields, rules) }) } diff --git a/dolphinscheduler-ui-next/src/components/form/types.ts b/dolphinscheduler-ui-next/src/components/form/types.ts index 70993cd90e..de2074393c 100644 --- a/dolphinscheduler-ui-next/src/components/form/types.ts +++ b/dolphinscheduler-ui-next/src/components/form/types.ts @@ -24,7 +24,7 @@ import type { SelectOption } from 'naive-ui' -type IType = 'input' | 'radio' | 'editor' +type IType = 'input' | 'radio' | 'editor' | 'custom-parameters' type IOption = SelectOption @@ -42,6 +42,8 @@ interface IFieldParams { props: object fields: { [field: string]: any } options?: IOption[] + rules?: FormRules | { [key: string]: FormRules } + children?: IJsonItem[] } interface IJsonItem { @@ -53,6 +55,7 @@ interface IJsonItem { validate?: FormItemRule value?: any options?: IOption[] + children?: IJsonItem[] } export { diff --git a/dolphinscheduler-ui-next/src/components/form/use-form.ts b/dolphinscheduler-ui-next/src/components/form/use-form.ts index a5e5e8c1b4..8c25ca94d9 100644 --- a/dolphinscheduler-ui-next/src/components/form/use-form.ts +++ b/dolphinscheduler-ui-next/src/components/form/use-form.ts @@ -22,8 +22,8 @@ export function useForm() { formRef: ref() }) - const validate = () => { - state.formRef.validate() + const validate = (...args: []) => { + state.formRef.validate(...args) } const setValues = (initialValues: { [field: string]: any }) => {