feat(plugin-workflow): add all crud nodes for workflow (#293)
This commit is contained in:
parent
28da6a5f82
commit
10dedd87e6
@ -1,4 +1,4 @@
|
|||||||
export * from './useCollection';
|
export * from './useCollection';
|
||||||
export * from './useCollectionField';
|
export * from './useCollectionField';
|
||||||
export * from './useCollectionManager';
|
export * from './useCollectionManager';
|
||||||
|
export * from './useCollectionDataSource';
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
import { action } from '@formily/reactive';
|
||||||
|
|
||||||
|
import { useCollectionManager } from ".";
|
||||||
|
import { useCompile } from "../../schema-component";
|
||||||
|
|
||||||
|
export function useCollectionDataSource() {
|
||||||
|
return (field: any) => {
|
||||||
|
const compile = useCompile();
|
||||||
|
const { collections = [] } = useCollectionManager();
|
||||||
|
action.bound((data: any) => {
|
||||||
|
field.dataSource = data.map(item => ({
|
||||||
|
label: compile(item.title),
|
||||||
|
value: item.name
|
||||||
|
}));
|
||||||
|
})(collections);
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@ const useDef = (options) => {
|
|||||||
|
|
||||||
export const Filter: any = observer((props: any) => {
|
export const Filter: any = observer((props: any) => {
|
||||||
const { useDataSource = useDef } = props;
|
const { useDataSource = useDef } = props;
|
||||||
const { options, dynamicComponent } = useProps(props);
|
const { options, dynamicComponent, className } = useProps(props);
|
||||||
const field = useField<ObjectFieldModel>();
|
const field = useField<ObjectFieldModel>();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
useDataSource({
|
useDataSource({
|
||||||
@ -25,7 +25,7 @@ export const Filter: any = observer((props: any) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={className}>
|
||||||
<FilterContext.Provider
|
<FilterContext.Provider
|
||||||
value={{ field, fieldSchema, dynamicComponent, options: options || field.dataSource || [] }}
|
value={{ field, fieldSchema, dynamicComponent, options: options || field.dataSource || [] }}
|
||||||
>
|
>
|
||||||
|
@ -97,7 +97,7 @@ export const InputRecordPicker: React.FC<any> = (props) => {
|
|||||||
open={false}
|
open={false}
|
||||||
/>
|
/>
|
||||||
<RecordPickerContext.Provider value={{ multiple, onChange, selectedRows, setSelectedRows }}>
|
<RecordPickerContext.Provider value={{ multiple, onChange, selectedRows, setSelectedRows }}>
|
||||||
<CollectionProvider name={collectionField.target}>
|
<CollectionProvider name={collectionField?.target}>
|
||||||
<ActionContext.Provider value={{ openMode: 'drawer', visible, setVisible }}>
|
<ActionContext.Provider value={{ openMode: 'drawer', visible, setVisible }}>
|
||||||
<FormProvider>
|
<FormProvider>
|
||||||
<SchemaComponentOptions scope={{ useTableSelectorProps, usePickActionProps }}>
|
<SchemaComponentOptions scope={{ useTableSelectorProps, usePickActionProps }}>
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { observer } from "@formily/react";
|
||||||
|
import { FormItem } from "@formily/antd";
|
||||||
import { Cascader, DatePicker, Input, InputNumber, Select } from "antd";
|
import { Cascader, DatePicker, Input, InputNumber, Select } from "antd";
|
||||||
import { css } from "@emotion/css";
|
import { css } from "@emotion/css";
|
||||||
|
|
||||||
import { instructions, useNodeContext } from "./nodes";
|
import { instructions, useNodeContext } from "./nodes";
|
||||||
import { useFlowContext } from "./WorkflowCanvas";
|
import { useFlowContext } from "./WorkflowCanvas";
|
||||||
import { triggers } from "./triggers";
|
import { triggers } from "./triggers";
|
||||||
|
import { SchemaComponent, useCompile } from "..";
|
||||||
|
|
||||||
function NullRender() {
|
function NullRender() {
|
||||||
return null;
|
return null;
|
||||||
@ -325,3 +328,101 @@ export function Calculation({ calculator, operands = [], onChange }) {
|
|||||||
</VariableTypesContext.Provider>
|
</VariableTypesContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function VariableComponent({ value, onChange, renderSchemaComponent }) {
|
||||||
|
const VTypes = { ...VariableTypes,
|
||||||
|
constant: {
|
||||||
|
title: '常量',
|
||||||
|
value: 'constant',
|
||||||
|
options: undefined
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const operand = typeof value === 'string'
|
||||||
|
? parseStringValue(value, VTypes)
|
||||||
|
: { type: 'constant', value };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<VariableTypesContext.Provider value={VTypes}>
|
||||||
|
<Operand
|
||||||
|
value={operand}
|
||||||
|
onChange={(next) => {
|
||||||
|
if (next.type !== operand.type && next.type === 'constant') {
|
||||||
|
onChange(null);
|
||||||
|
} else {
|
||||||
|
const { stringify } = VTypes[next.type];
|
||||||
|
onChange(stringify(next));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{operand.type === 'constant' ? renderSchemaComponent() : null}
|
||||||
|
</Operand>
|
||||||
|
</VariableTypesContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: observer for watching useProps
|
||||||
|
export const CollectionFieldset = observer(({ value, onChange, useProps }: any) => {
|
||||||
|
const { fields } = useProps();
|
||||||
|
const compile = useCompile();
|
||||||
|
|
||||||
|
const VTypes = { ...VariableTypes,
|
||||||
|
constant: {
|
||||||
|
title: '常量',
|
||||||
|
value: 'constant',
|
||||||
|
options: undefined
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<fieldset className={css`
|
||||||
|
margin-top: .5em;
|
||||||
|
|
||||||
|
.ant-formily-item{
|
||||||
|
.ant-formily-item-label{
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-select,
|
||||||
|
.ant-cascader-picker,
|
||||||
|
.ant-picker,
|
||||||
|
.ant-input-number,
|
||||||
|
.ant-input-affix-wrapper{
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`}>
|
||||||
|
{fields.length
|
||||||
|
? fields.map(field => {
|
||||||
|
const operand = typeof value[field.name] === 'string'
|
||||||
|
? parseStringValue(value[field.name], VTypes)
|
||||||
|
: { type: 'constant', value: value[field.name] };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormItem label={compile(field.title)}>
|
||||||
|
<VariableTypesContext.Provider value={VTypes}>
|
||||||
|
<Operand
|
||||||
|
value={operand}
|
||||||
|
onChange={(next) => {
|
||||||
|
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'
|
||||||
|
? <SchemaComponent schema={field.schema} />
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</Operand>
|
||||||
|
</VariableTypesContext.Provider>
|
||||||
|
</FormItem>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
: <p>请先选择数据表</p>
|
||||||
|
}
|
||||||
|
</fieldset>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
@ -1,30 +1,17 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer, useForm } from '@formily/react';
|
|
||||||
import { action } from '@formily/reactive';
|
|
||||||
import { Select } from 'antd';
|
import { Select } from 'antd';
|
||||||
import { t } from 'i18next';
|
|
||||||
import { css } from '@emotion/css';
|
|
||||||
|
|
||||||
import { SchemaComponent, useCollectionManager } from '../..';
|
import { useCollectionDataSource, useCollectionManager, useCompile } from '../..';
|
||||||
import { useCollectionFilterOptions } from '../../collection-manager/action-hooks';
|
|
||||||
import { useFlowContext } from '../WorkflowCanvas';
|
import { useFlowContext } from '../WorkflowCanvas';
|
||||||
import { Operand, parseStringValue, VariableTypes, VariableTypesContext, BaseTypeSet } from '../calculators';
|
import { collection, values } from '../schemas/collection';
|
||||||
import { FormItem } from '@formily/antd';
|
import { BaseTypeSet, CollectionFieldset } from '../calculators';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: '新增',
|
title: '新增数据',
|
||||||
type: 'create',
|
type: 'create',
|
||||||
group: 'model',
|
group: 'model',
|
||||||
fieldset: {
|
fieldset: {
|
||||||
collection: {
|
collection,
|
||||||
type: 'string',
|
|
||||||
title: '数据表',
|
|
||||||
name: 'collection',
|
|
||||||
required: true,
|
|
||||||
'x-reactions': ['{{useCollectionDataSource()}}'],
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Select',
|
|
||||||
},
|
|
||||||
// multiple: {
|
// multiple: {
|
||||||
// type: 'boolean',
|
// type: 'boolean',
|
||||||
// title: '多条数据',
|
// title: '多条数据',
|
||||||
@ -38,21 +25,10 @@ export default {
|
|||||||
params: {
|
params: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
name: 'params',
|
name: 'params',
|
||||||
title: '数据',
|
title: '',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
properties: {
|
properties: {
|
||||||
values: {
|
values
|
||||||
type: 'object',
|
|
||||||
title: '',
|
|
||||||
name: 'values',
|
|
||||||
'x-component': 'DynamicFieldset',
|
|
||||||
'x-component-props': {
|
|
||||||
useProps() {
|
|
||||||
const { values } = useForm();
|
|
||||||
return { fields: useCollectionFilterOptions(values.collection) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -60,82 +36,13 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
scope: {
|
scope: {
|
||||||
useCollectionDataSource() {
|
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: {
|
components: {
|
||||||
// NOTE: observer for watching useProps
|
CollectionFieldset
|
||||||
DynamicFieldset: observer(({ value, onChange, useProps }: any) => {
|
|
||||||
const { fields } = useProps();
|
|
||||||
|
|
||||||
const VTypes = { ...VariableTypes,
|
|
||||||
constant: {
|
|
||||||
title: '常量',
|
|
||||||
value: 'constant',
|
|
||||||
options: undefined
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<fieldset className={css`
|
|
||||||
margin-top: .5em;
|
|
||||||
|
|
||||||
.ant-formily-item{
|
|
||||||
.ant-formily-item-label{
|
|
||||||
line-height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-select,
|
|
||||||
.ant-cascader-picker,
|
|
||||||
.ant-picker,
|
|
||||||
.ant-input-number,
|
|
||||||
.ant-input-affix-wrapper{
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`}>
|
|
||||||
{fields.map(field => {
|
|
||||||
const operand = typeof value[field.name] === 'string'
|
|
||||||
? parseStringValue(value[field.name], VTypes)
|
|
||||||
: { type: 'constant', value: value[field.name] };
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormItem label={field.title}>
|
|
||||||
<VariableTypesContext.Provider value={VTypes}>
|
|
||||||
<Operand
|
|
||||||
value={operand}
|
|
||||||
onChange={(next) => {
|
|
||||||
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'
|
|
||||||
? <SchemaComponent schema={field.schema} />
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
</Operand>
|
|
||||||
</VariableTypesContext.Provider>
|
|
||||||
</FormItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</fieldset>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
getter({ type, options, onChange }) {
|
getter({ type, options, onChange }) {
|
||||||
|
const compile = useCompile();
|
||||||
const { collections = [] } = useCollectionManager();
|
const { collections = [] } = useCollectionManager();
|
||||||
const { nodes } = useFlowContext();
|
const { nodes } = useFlowContext();
|
||||||
const { config } = nodes.find(n => n.id == options.nodeId);
|
const { config } = nodes.find(n => n.id == options.nodeId);
|
||||||
@ -148,7 +55,7 @@ export default {
|
|||||||
{collection.fields
|
{collection.fields
|
||||||
.filter(field => BaseTypeSet.has(field.uiSchema.type))
|
.filter(field => BaseTypeSet.has(field.uiSchema.type))
|
||||||
.map(field => (
|
.map(field => (
|
||||||
<Select.Option key={field.name} value={field.name}>{t(field.uiSchema.title)}</Select.Option>
|
<Select.Option key={field.name} value={field.name}>{compile(field.uiSchema.title)}</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
);
|
);
|
||||||
|
31
packages/client/src/workflow/nodes/destroy.tsx
Normal file
31
packages/client/src/workflow/nodes/destroy.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { useCollectionDataSource } from '../..';
|
||||||
|
|
||||||
|
import { VariableComponent } from '../calculators';
|
||||||
|
import { collection, filter } from '../schemas/collection';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: '删除数据',
|
||||||
|
type: 'destroy',
|
||||||
|
group: 'model',
|
||||||
|
fieldset: {
|
||||||
|
collection,
|
||||||
|
params: {
|
||||||
|
type: 'object',
|
||||||
|
name: 'params',
|
||||||
|
title: '',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
properties: {
|
||||||
|
filter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
view: {
|
||||||
|
|
||||||
|
},
|
||||||
|
scope: {
|
||||||
|
useCollectionDataSource
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
VariableComponent
|
||||||
|
}
|
||||||
|
};
|
@ -13,11 +13,38 @@ import { nodeClass, nodeCardClass, nodeHeaderClass, nodeTitleClass, nodeBlockCla
|
|||||||
|
|
||||||
import query from './query';
|
import query from './query';
|
||||||
import create from './create';
|
import create from './create';
|
||||||
|
import update from './update';
|
||||||
|
import destroy from './destroy';
|
||||||
import condition from './condition';
|
import condition from './condition';
|
||||||
import parallel from './parallel';
|
import parallel from './parallel';
|
||||||
import calculation from './calculation';
|
import calculation from './calculation';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export interface Instruction {
|
||||||
|
title: string;
|
||||||
|
type: string;
|
||||||
|
group: string;
|
||||||
|
options?: { label: string; value: any; key: string }[];
|
||||||
|
fieldset: { [key: string]: ISchema };
|
||||||
|
view?: ISchema;
|
||||||
|
scope?: { [key: string]: any };
|
||||||
|
components?: { [key: string]: any };
|
||||||
|
render?(props): React.ReactElement;
|
||||||
|
endding?: boolean;
|
||||||
|
getter?(node: any): React.ReactElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const instructions = new Registry<Instruction>();
|
||||||
|
|
||||||
|
instructions.register('query', query);
|
||||||
|
instructions.register('create', create);
|
||||||
|
instructions.register('update', update);
|
||||||
|
instructions.register('destroy', destroy);
|
||||||
|
instructions.register('condition', condition);
|
||||||
|
instructions.register('parallel', parallel);
|
||||||
|
instructions.register('calculation', calculation);
|
||||||
|
|
||||||
function useUpdateConfigAction() {
|
function useUpdateConfigAction() {
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
@ -41,30 +68,6 @@ function useUpdateConfigAction() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface Instruction {
|
|
||||||
title: string;
|
|
||||||
type: string;
|
|
||||||
group: string;
|
|
||||||
options?: { label: string; value: any; key: string }[];
|
|
||||||
fieldset: { [key: string]: ISchema };
|
|
||||||
view?: ISchema;
|
|
||||||
scope?: { [key: string]: any };
|
|
||||||
components?: { [key: string]: any };
|
|
||||||
render?(props): React.ReactElement;
|
|
||||||
endding?: boolean;
|
|
||||||
getter?(node: any): React.ReactElement;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const instructions = new Registry<Instruction>();
|
|
||||||
|
|
||||||
instructions.register('query', query);
|
|
||||||
instructions.register('create', create);
|
|
||||||
instructions.register('condition', condition);
|
|
||||||
instructions.register('parallel', parallel);
|
|
||||||
instructions.register('calculation', calculation);
|
|
||||||
|
|
||||||
const NodeContext = React.createContext(null);
|
const NodeContext = React.createContext(null);
|
||||||
|
|
||||||
export function useNodeContext() {
|
export function useNodeContext() {
|
||||||
|
@ -1,29 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useForm } from '@formily/react';
|
|
||||||
import { action } from '@formily/reactive';
|
|
||||||
import { Select } from 'antd';
|
import { Select } from 'antd';
|
||||||
import { t } from 'i18next';
|
|
||||||
import { css } from '@emotion/css';
|
|
||||||
|
|
||||||
import { useCollectionManager } from '../..';
|
import { useCollectionDataSource, useCollectionManager, useCompile } from '../..';
|
||||||
import { useCollectionFilterOptions } from '../../collection-manager/action-hooks';
|
|
||||||
import { useFlowContext } from '../WorkflowCanvas';
|
import { useFlowContext } from '../WorkflowCanvas';
|
||||||
import { Operand, parseStringValue, VariableTypes, VariableTypesContext, BaseTypeSet } from '../calculators';
|
import { BaseTypeSet, VariableComponent } from '../calculators';
|
||||||
|
import { collection, filter } from '../schemas/collection';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: '查询',
|
title: '查询数据',
|
||||||
type: 'query',
|
type: 'query',
|
||||||
group: 'model',
|
group: 'model',
|
||||||
fieldset: {
|
fieldset: {
|
||||||
collection: {
|
collection,
|
||||||
type: 'string',
|
|
||||||
title: '数据表',
|
|
||||||
name: 'collection',
|
|
||||||
required: true,
|
|
||||||
'x-reactions': ['{{useCollectionDataSource()}}'],
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Select',
|
|
||||||
},
|
|
||||||
multiple: {
|
multiple: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
title: '多条数据',
|
title: '多条数据',
|
||||||
@ -37,31 +26,10 @@ export default {
|
|||||||
params: {
|
params: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
name: 'params',
|
name: 'params',
|
||||||
title: '查询参数',
|
title: '',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
properties: {
|
properties: {
|
||||||
filter: {
|
filter
|
||||||
type: 'object',
|
|
||||||
title: '筛选条件',
|
|
||||||
name: 'filter',
|
|
||||||
'x-decorator': 'div',
|
|
||||||
'x-decorator-props': {
|
|
||||||
className: css`
|
|
||||||
.ant-select{
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
},
|
|
||||||
'x-component': 'Filter',
|
|
||||||
'x-component-props': {
|
|
||||||
useProps() {
|
|
||||||
const { values } = useForm();
|
|
||||||
const options = useCollectionFilterOptions(values.collection);
|
|
||||||
return { options };
|
|
||||||
},
|
|
||||||
dynamicComponent: 'VariableComponent'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -69,52 +37,13 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
scope: {
|
scope: {
|
||||||
useCollectionDataSource() {
|
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: {
|
components: {
|
||||||
VariableComponent({ value, onChange, renderSchemaComponent }) {
|
VariableComponent
|
||||||
const VTypes = { ...VariableTypes,
|
|
||||||
constant: {
|
|
||||||
title: '常量',
|
|
||||||
value: 'constant',
|
|
||||||
options: undefined
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const operand = typeof value === 'string'
|
|
||||||
? parseStringValue(value, VTypes)
|
|
||||||
: { type: 'constant', value };
|
|
||||||
|
|
||||||
return (
|
|
||||||
<VariableTypesContext.Provider value={VTypes}>
|
|
||||||
<Operand
|
|
||||||
value={operand}
|
|
||||||
onChange={(next) => {
|
|
||||||
if (next.type !== operand.type && next.type === 'constant') {
|
|
||||||
onChange(null);
|
|
||||||
} else {
|
|
||||||
const { stringify } = VTypes[next.type];
|
|
||||||
onChange(stringify(next));
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{operand.type === 'constant' ? renderSchemaComponent() : null}
|
|
||||||
</Operand>
|
|
||||||
</VariableTypesContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
getter({ type, options, onChange }) {
|
getter({ type, options, onChange }) {
|
||||||
|
const compile = useCompile();
|
||||||
const { collections = [] } = useCollectionManager();
|
const { collections = [] } = useCollectionManager();
|
||||||
const { nodes } = useFlowContext();
|
const { nodes } = useFlowContext();
|
||||||
const { config } = nodes.find(n => n.id == options.nodeId);
|
const { config } = nodes.find(n => n.id == options.nodeId);
|
||||||
@ -127,7 +56,7 @@ export default {
|
|||||||
{collection.fields
|
{collection.fields
|
||||||
.filter(field => BaseTypeSet.has(field.uiSchema.type))
|
.filter(field => BaseTypeSet.has(field.uiSchema.type))
|
||||||
.map(field => (
|
.map(field => (
|
||||||
<Select.Option key={field.name} value={field.name}>{t(field.uiSchema.title)}</Select.Option>
|
<Select.Option key={field.name} value={field.name}>{compile(field.uiSchema.title)}</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
);
|
);
|
||||||
|
32
packages/client/src/workflow/nodes/update.tsx
Normal file
32
packages/client/src/workflow/nodes/update.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { useCollectionDataSource } from '../..';
|
||||||
|
import { CollectionFieldset, VariableComponent } from '../calculators';
|
||||||
|
import { collection, filter, values } from '../schemas/collection';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: '更新数据',
|
||||||
|
type: 'update',
|
||||||
|
group: 'model',
|
||||||
|
fieldset: {
|
||||||
|
collection,
|
||||||
|
params: {
|
||||||
|
type: 'object',
|
||||||
|
name: 'params',
|
||||||
|
title: '',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
properties: {
|
||||||
|
filter,
|
||||||
|
values
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
view: {
|
||||||
|
|
||||||
|
},
|
||||||
|
scope: {
|
||||||
|
useCollectionDataSource
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
VariableComponent,
|
||||||
|
CollectionFieldset
|
||||||
|
}
|
||||||
|
};
|
64
packages/client/src/workflow/schemas/collection.ts
Normal file
64
packages/client/src/workflow/schemas/collection.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { css } from "@emotion/css";
|
||||||
|
import { useForm } from "@formily/react";
|
||||||
|
import { useCollectionFilterOptions } from "../../collection-manager/action-hooks";
|
||||||
|
|
||||||
|
export const collection = {
|
||||||
|
type: 'string',
|
||||||
|
title: '数据表',
|
||||||
|
name: 'collection',
|
||||||
|
required: true,
|
||||||
|
'x-reactions': ['{{useCollectionDataSource()}}'],
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Select',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const values = {
|
||||||
|
type: 'object',
|
||||||
|
title: '数据内容',
|
||||||
|
name: 'values',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-decorator-props': {
|
||||||
|
labelAlign: 'left',
|
||||||
|
className: css`
|
||||||
|
flex-direction: column;
|
||||||
|
`
|
||||||
|
},
|
||||||
|
'x-component': 'CollectionFieldset',
|
||||||
|
'x-component-props': {
|
||||||
|
useProps() {
|
||||||
|
const { values: form } = useForm();
|
||||||
|
const fields = useCollectionFilterOptions(form.collection);
|
||||||
|
return { fields };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const filter = {
|
||||||
|
type: 'object',
|
||||||
|
title: '筛选条件',
|
||||||
|
name: 'filter',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-decorator-props': {
|
||||||
|
labelAlign: 'left',
|
||||||
|
className: css`
|
||||||
|
flex-direction: column;
|
||||||
|
`
|
||||||
|
},
|
||||||
|
'x-component': 'Filter',
|
||||||
|
'x-component-props': {
|
||||||
|
useProps() {
|
||||||
|
const { values } = useForm();
|
||||||
|
const options = useCollectionFilterOptions(values.collection);
|
||||||
|
return {
|
||||||
|
options,
|
||||||
|
className: css`
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
padding: .5em 1em;
|
||||||
|
border: 1px dashed #ddd;
|
||||||
|
`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
dynamicComponent: 'VariableComponent'
|
||||||
|
}
|
||||||
|
};
|
@ -1,27 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { action } from '@formily/reactive';
|
|
||||||
import { t } from 'i18next';
|
|
||||||
import { Select } from 'antd';
|
import { Select } from 'antd';
|
||||||
|
|
||||||
import { useCollectionManager } from '../../collection-manager';
|
import { useCollectionDataSource, useCollectionManager } from '../../collection-manager';
|
||||||
|
import { useCompile } from '../../schema-component';
|
||||||
|
|
||||||
import { useFlowContext } from '../WorkflowCanvas';
|
import { useFlowContext } from '../WorkflowCanvas';
|
||||||
import { BaseTypeSet } from '../calculators';
|
import { BaseTypeSet } from '../calculators';
|
||||||
import { useForm } from '@formily/react';
|
import { collection, filter } from '../schemas/collection';
|
||||||
import { useCollectionFilterOptions } from '../../collection-manager/action-hooks';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: '数据表事件',
|
title: '数据表事件',
|
||||||
type: 'model',
|
type: 'model',
|
||||||
fieldset: {
|
fieldset: {
|
||||||
collection: {
|
collection,
|
||||||
type: 'string',
|
|
||||||
title: '数据表',
|
|
||||||
name: 'collection',
|
|
||||||
required: true,
|
|
||||||
'x-reactions': ['{{useAsyncDataSource()}}'],
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Select',
|
|
||||||
},
|
|
||||||
mode: {
|
mode: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
title: '触发时机',
|
title: '触发时机',
|
||||||
@ -38,35 +29,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
type: 'object',
|
...filter,
|
||||||
title: '满足条件',
|
title: '满足条件'
|
||||||
description: 'not supported by server yet',
|
|
||||||
name: 'filter',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Filter',
|
|
||||||
'x-component-props': {
|
|
||||||
useProps() {
|
|
||||||
const { values } = useForm();
|
|
||||||
const options = useCollectionFilterOptions(values.collection);
|
|
||||||
return { options };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scope: {
|
scope: {
|
||||||
useAsyncDataSource() {
|
useCollectionDataSource
|
||||||
return (field: any) => {
|
|
||||||
const { collections = [] } = useCollectionManager();
|
|
||||||
action.bound((data: any) => {
|
|
||||||
field.dataSource = data.map(item => ({
|
|
||||||
label: t(item.title),
|
|
||||||
value: item.name
|
|
||||||
}));
|
|
||||||
})(collections);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
getter({ type, options, onChange }) {
|
getter({ type, options, onChange }) {
|
||||||
|
const compile = useCompile();
|
||||||
const { collections = [] } = useCollectionManager();
|
const { collections = [] } = useCollectionManager();
|
||||||
const { workflow } = useFlowContext();
|
const { workflow } = useFlowContext();
|
||||||
const collection = collections.find(item => item.name === workflow.config.collection) ?? { fields: [] };
|
const collection = collections.find(item => item.name === workflow.config.collection) ?? { fields: [] };
|
||||||
@ -82,7 +53,7 @@ export default {
|
|||||||
{collection.fields
|
{collection.fields
|
||||||
.filter(field => BaseTypeSet.has(field?.uiSchema?.type))
|
.filter(field => BaseTypeSet.has(field?.uiSchema?.type))
|
||||||
.map(field => (
|
.map(field => (
|
||||||
<Select.Option key={field.name} value={field.name}>{t(field.uiSchema.title)}</Select.Option>
|
<Select.Option key={field.name} value={field.name}>{compile(field.uiSchema.title)}</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user