diff --git a/packages/client/src/workflow/calculators.tsx b/packages/client/src/workflow/calculators.tsx index a98b15069..7b459d6ec 100644 --- a/packages/client/src/workflow/calculators.tsx +++ b/packages/client/src/workflow/calculators.tsx @@ -65,7 +65,7 @@ export function parseStringValue(value: string, Types) { return { type, - options: paths.length ? (Types || VariableTypes)[type].parse(paths) : {} + options: paths.length ? (Types || VariableTypes)[type]?.parse(paths) : {} }; } @@ -252,7 +252,7 @@ export function Operand({ const { type } = operand; - const { component, appendTypeValue } = Types[type]; + const { component, appendTypeValue } = Types[type] || {}; const VariableComponent = typeof component === 'function' ? component(operand) : NullRender; return ( diff --git a/packages/client/src/workflow/nodes/create.tsx b/packages/client/src/workflow/nodes/create.tsx new file mode 100644 index 000000000..1b609266e --- /dev/null +++ b/packages/client/src/workflow/nodes/create.tsx @@ -0,0 +1,156 @@ +import React from 'react'; +import { observer, useForm } from '@formily/react'; +import { action } from '@formily/reactive'; +import { Select } from 'antd'; +import { t } from 'i18next'; +import { css } from '@emotion/css'; + +import { SchemaComponent, useCollectionManager } from '../..'; +import { useCollectionFilterOptions } from '../../collection-manager/action-hooks'; +import { useFlowContext } from '../WorkflowCanvas'; +import { Operand, parseStringValue, VariableTypes, VariableTypesContext, BaseTypeSet } from '../calculators'; +import { FormItem } from '@formily/antd'; + +export default { + title: '新增', + type: 'create', + group: 'model', + fieldset: { + collection: { + type: 'string', + title: '数据表', + name: 'collection', + required: true, + 'x-reactions': ['{{useCollectionDataSource()}}'], + 'x-decorator': 'FormItem', + 'x-component': 'Select', + }, + // multiple: { + // type: 'boolean', + // title: '多条数据', + // name: 'multiple', + // 'x-decorator': 'FormItem', + // 'x-component': 'Checkbox', + // 'x-component-props': { + // disabled: true + // } + // }, + params: { + type: 'object', + name: 'params', + title: '数据', + 'x-decorator': 'FormItem', + properties: { + values: { + type: 'object', + title: '', + name: 'values', + 'x-component': 'DynamicFieldset', + 'x-component-props': { + useProps() { + const { values } = useForm(); + return { fields: useCollectionFilterOptions(values.collection) }; + } + } + } + } + } + }, + view: { + + }, + scope: { + useCollectionDataSource() { + return (field: any) => { + const { collections = [] } = useCollectionManager(); + action.bound((data: any) => { + field.dataSource = data.map(item => ({ + label: t(item.title), + value: item.name + })); + })(collections); + } + } + }, + components: { + // NOTE: observer for watching useProps + DynamicFieldset: observer(({ value, onChange, useProps }: any) => { + const { fields } = useProps(); + + const VTypes = { ...VariableTypes, + constant: { + title: '常量', + value: 'constant', + options: undefined + } + }; + + return ( +
+ {fields.map(field => { + const operand = typeof value[field.name] === 'string' + ? parseStringValue(value[field.name], VTypes) + : { type: 'constant', value: value[field.name] }; + + return ( + + + { + if (next.type !== operand.type && next.type === 'constant') { + onChange({ ...value, [field.name]: null }); + } else { + const { stringify } = VTypes[next.type]; + onChange({ ...value, [field.name]: stringify(next) }); + } + }} + > + {operand.type === 'constant' + ? + : null + } + + + + ); + })} +
+ ); + }) + }, + getter({ type, options, onChange }) { + const { collections = [] } = useCollectionManager(); + const { nodes } = useFlowContext(); + const { config } = nodes.find(n => n.id == options.nodeId); + const collection = collections.find(item => item.name === config.collection) ?? { fields: [] }; + + return ( + + ); + } +}; diff --git a/packages/client/src/workflow/nodes/index.tsx b/packages/client/src/workflow/nodes/index.tsx index e55185d6e..96a65715b 100644 --- a/packages/client/src/workflow/nodes/index.tsx +++ b/packages/client/src/workflow/nodes/index.tsx @@ -12,6 +12,7 @@ import { AddButton, useFlowContext } from '../WorkflowCanvas'; import { nodeClass, nodeCardClass, nodeHeaderClass, nodeTitleClass, nodeBlockClass } from '../style'; import query from './query'; +import create from './create'; import condition from './condition'; import parallel from './parallel'; import calculation from './calculation'; @@ -59,6 +60,7 @@ export interface Instruction { export const instructions = new Registry(); instructions.register('query', query); +instructions.register('create', create); instructions.register('condition', condition); instructions.register('parallel', parallel); instructions.register('calculation', calculation); @@ -159,54 +161,58 @@ export function NodeDefaultView(props) { type: 'void', properties: { view: instruction.view, - config: { - type: 'void', - title: '配置节点', - 'x-component': 'Action.Link', - 'x-component-props': { - type: 'primary', - }, - properties: { - drawer: { + ...(Object.keys(instruction.fieldset).length + ? { + config: { type: 'void', title: '配置节点', - 'x-component': 'Action.Drawer', - 'x-decorator': 'Form', - 'x-decorator-props': { - useValues(options) { - const node = useNodeContext(); - return useRequest(() => { - return Promise.resolve({ data: node.config }); - }, options); - } + 'x-component': 'Action.Link', + 'x-component-props': { + type: 'primary', }, properties: { - ...instruction.fieldset, - actions: { + drawer: { type: 'void', - 'x-component': 'Action.Drawer.Footer', - properties: { - cancel: { - title: '{{t("Cancel")}}', - 'x-component': 'Action', - 'x-component-props': { - useAction: '{{ cm.useCancelAction }}', - }, - }, - submit: { - title: '{{t("Submit")}}', - 'x-component': 'Action', - 'x-component-props': { - type: 'primary', - useAction: useUpdateConfigAction, - }, - }, + title: '配置节点', + 'x-component': 'Action.Drawer', + 'x-decorator': 'Form', + 'x-decorator-props': { + useValues(options) { + const node = useNodeContext(); + return useRequest(() => { + return Promise.resolve({ data: node.config }); + }, options); + } }, - } as ISchema + properties: { + ...instruction.fieldset, + actions: { + type: 'void', + 'x-component': 'Action.Drawer.Footer', + properties: { + cancel: { + title: '{{t("Cancel")}}', + 'x-component': 'Action', + 'x-component-props': { + useAction: '{{ cm.useCancelAction }}', + }, + }, + submit: { + title: '{{t("Submit")}}', + 'x-component': 'Action', + 'x-component-props': { + type: 'primary', + useAction: useUpdateConfigAction, + }, + }, + }, + } as ISchema + } + } } } } - } + : {}) } }} /> diff --git a/packages/client/src/workflow/nodes/query.tsx b/packages/client/src/workflow/nodes/query.tsx index 4e16e45a9..027cdd9dd 100644 --- a/packages/client/src/workflow/nodes/query.tsx +++ b/packages/client/src/workflow/nodes/query.tsx @@ -11,7 +11,7 @@ import { useFlowContext } from '../WorkflowCanvas'; import { Operand, parseStringValue, VariableTypes, VariableTypesContext, BaseTypeSet } from '../calculators'; export default { - title: '数据查询', + title: '查询', type: 'query', group: 'model', fieldset: { diff --git a/packages/client/src/workflow/triggers/model.tsx b/packages/client/src/workflow/triggers/model.tsx index 7536b553c..dae142814 100644 --- a/packages/client/src/workflow/triggers/model.tsx +++ b/packages/client/src/workflow/triggers/model.tsx @@ -72,11 +72,15 @@ export default { const collection = collections.find(item => item.name === workflow.config.collection) ?? { fields: [] }; return ( - { + onChange({ type, options: { ...options, path: `data.${path}` } }); + }} + > {collection.fields - .filter(field => BaseTypeSet.has(field.uiSchema.type)) + .filter(field => BaseTypeSet.has(field?.uiSchema?.type)) .map(field => ( {t(field.uiSchema.title)} ))}