feat(plugin-workflow): support context variables from model trigger (#284)
This commit is contained in:
parent
2f6aeacbd8
commit
d0e524a1a0
@ -40,7 +40,7 @@ export function WorkflowCanvas() {
|
||||
return <div>加载失败</div>;
|
||||
}
|
||||
|
||||
const { nodes = [] } = data?.data ?? {};
|
||||
const { nodes = [], ...workflow } = data?.data ?? {};
|
||||
|
||||
makeNodes(nodes);
|
||||
|
||||
@ -48,6 +48,7 @@ export function WorkflowCanvas() {
|
||||
|
||||
return (
|
||||
<FlowContext.Provider value={{
|
||||
workflow,
|
||||
nodes,
|
||||
onNodeAdded: refresh,
|
||||
onNodeRemoved: refresh
|
||||
|
@ -4,6 +4,7 @@ import { css } from "@emotion/css";
|
||||
|
||||
import { instructions, useNodeContext } from "./nodes";
|
||||
import { useFlowContext } from "./WorkflowCanvas";
|
||||
import { triggers } from "./triggers";
|
||||
|
||||
function NullRender() {
|
||||
return null;
|
||||
@ -68,6 +69,8 @@ export function parseStringValue(value: string, Types) {
|
||||
};
|
||||
}
|
||||
|
||||
export const BaseTypeSet = new Set(['boolean', 'number', 'string', 'date']);
|
||||
|
||||
const ConstantTypes = {
|
||||
string: {
|
||||
title: '字符串',
|
||||
@ -189,7 +192,25 @@ export const VariableTypes = {
|
||||
return `{{${stack.join('.')}}}`;
|
||||
}
|
||||
},
|
||||
// context: ContextSelect,
|
||||
context: {
|
||||
title: '触发数据',
|
||||
value: 'context',
|
||||
component() {
|
||||
const { workflow } = useFlowContext();
|
||||
const trigger = triggers.get(workflow.type);
|
||||
return trigger?.getter ?? NullRender;
|
||||
},
|
||||
parse([prefix, ...path]) {
|
||||
return { path: path.join('.') };
|
||||
},
|
||||
stringify({ options }) {
|
||||
const stack = ['context'];
|
||||
if (options?.path) {
|
||||
stack.push(options.path);
|
||||
}
|
||||
return `{{${stack.join('.')}}}`;
|
||||
}
|
||||
},
|
||||
// calculation: Calculation
|
||||
};
|
||||
|
||||
@ -205,10 +226,15 @@ interface OperandProps {
|
||||
value?: any;
|
||||
options?: any;
|
||||
};
|
||||
onChange(v: any): void
|
||||
onChange(v: any): void;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export function Operand({ onChange, value: operand = { type: 'constant', value: '', options: { type: 'string' } } }: OperandProps) {
|
||||
export function Operand({
|
||||
value: operand = { type: 'constant', value: '', options: { type: 'string' } },
|
||||
onChange,
|
||||
children
|
||||
}: OperandProps) {
|
||||
const Types = useVariableTypes();
|
||||
|
||||
const { type } = operand;
|
||||
@ -226,13 +252,13 @@ export function Operand({ onChange, value: operand = { type: 'constant', value:
|
||||
allowClear={false}
|
||||
value={[type, ...(appendTypeValue ? appendTypeValue(operand) : [])]}
|
||||
options={Object.values(Types).map((item: any) => {
|
||||
const children = typeof item.options === 'function' ? item.options() : item.options;
|
||||
const options = typeof item.options === 'function' ? item.options() : item.options;
|
||||
return {
|
||||
label: item.title,
|
||||
value: item.value,
|
||||
children,
|
||||
disabled: children && !children.length,
|
||||
isLeaf: !children
|
||||
children: options,
|
||||
disabled: options && !options.length,
|
||||
isLeaf: !options
|
||||
};
|
||||
})}
|
||||
onChange={(next: Array<string | number>) => {
|
||||
@ -246,7 +272,7 @@ export function Operand({ onChange, value: operand = { type: 'constant', value:
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<VariableComponent {...operand} onChange={op => onChange({ ...op })} />
|
||||
{children ?? <VariableComponent {...operand} onChange={op => onChange({ ...op })} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ export default {
|
||||
{ label: '分支模式', key: 'branch', value: { rejectOnFalse: false } }
|
||||
],
|
||||
render(data) {
|
||||
const { id, config: { calculation, rejectOnFalse } } = data;
|
||||
const { id, config: { rejectOnFalse } } = data;
|
||||
const { nodes } = useFlowContext();
|
||||
const trueEntry = nodes.find(item => item.upstreamId === id && item.branchIndex === 1);
|
||||
const falseEntry = nodes.find(item => item.upstreamId === id && item.branchIndex === 0);
|
||||
|
@ -8,9 +8,7 @@ import { css } from '@emotion/css';
|
||||
import { useCollectionManager } from '../..';
|
||||
import { useCollectionFilterOptions } from '../../collection-manager/action-hooks';
|
||||
import { useFlowContext } from '../WorkflowCanvas';
|
||||
import { Operand, parseStringValue, VariableTypes, VariableTypesContext } from '../calculators';
|
||||
|
||||
const BaseTypeSet = new Set(['boolean', 'number', 'string', 'date']);
|
||||
import { Operand, parseStringValue, VariableTypes, VariableTypesContext, BaseTypeSet } from '../calculators';
|
||||
|
||||
export default {
|
||||
title: '数据查询',
|
||||
@ -89,10 +87,7 @@ export default {
|
||||
constant: {
|
||||
title: '常量',
|
||||
value: 'constant',
|
||||
options: undefined,
|
||||
component() {
|
||||
return renderSchemaComponent;
|
||||
}
|
||||
options: undefined
|
||||
}
|
||||
};
|
||||
|
||||
@ -112,7 +107,9 @@ export default {
|
||||
onChange(stringify(next));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
>
|
||||
{operand.type === 'constant' ? renderSchemaComponent() : null}
|
||||
</Operand>
|
||||
</VariableTypesContext.Provider>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from "react";
|
||||
import { useForm } from "@formily/react";
|
||||
import { ISchema, useForm } from "@formily/react";
|
||||
import { cx } from "@emotion/css";
|
||||
import { Registry } from "@nocobase/utils";
|
||||
|
||||
import { SchemaComponent, useActionContext, useAPIClient, useRecord, useResourceActionContext } from '../../';
|
||||
import model from './model';
|
||||
@ -30,18 +31,30 @@ function useUpdateConfigAction() {
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
const triggerTypes = {
|
||||
model
|
||||
export interface Trigger {
|
||||
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;
|
||||
getter?(node: any): React.ReactElement;
|
||||
};
|
||||
|
||||
export const triggers = new Registry<Trigger>();
|
||||
|
||||
triggers.register('model', model);
|
||||
|
||||
export const TriggerConfig = () => {
|
||||
const { data } = useResourceActionContext();
|
||||
if (!data) {
|
||||
return null;
|
||||
}
|
||||
const { type, config } = data.data;
|
||||
const { title, fieldset, scope } = triggerTypes[type];
|
||||
const { title, fieldset, scope } = triggers.get(type);
|
||||
return (
|
||||
<div className={cx(nodeCardClass)}>
|
||||
<h4>{title}</h4>
|
||||
|
@ -1,9 +1,15 @@
|
||||
import React from 'react';
|
||||
import { action } from '@formily/reactive';
|
||||
import { t } from 'i18next';
|
||||
import { Select } from 'antd';
|
||||
|
||||
import { useCollectionManager } from '../../collection-manager';
|
||||
import { useFlowContext } from '../WorkflowCanvas';
|
||||
import { BaseTypeSet } from '../calculators';
|
||||
|
||||
export default {
|
||||
title: '数据表事件',
|
||||
type: 'model',
|
||||
fieldset: {
|
||||
collection: {
|
||||
type: 'string',
|
||||
@ -32,5 +38,22 @@ export default {
|
||||
})(collections);
|
||||
}
|
||||
}
|
||||
},
|
||||
getter({ type, options, onChange }) {
|
||||
const { collections = [] } = useCollectionManager();
|
||||
const { workflow } = useFlowContext();
|
||||
const collection = collections.find(item => item.name === workflow.config.collection) ?? { fields: [] };
|
||||
|
||||
return (
|
||||
<Select value={options.path} placeholder="选择字段" onChange={path => {
|
||||
onChange({ type, options: { ...options, path: `data.${path}` } });
|
||||
}}>
|
||||
{collection.fields
|
||||
.filter(field => BaseTypeSet.has(field.uiSchema.type))
|
||||
.map(field => (
|
||||
<Select.Option key={field.name} value={field.name}>{t(field.uiSchema.title)}</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user