@nocobase/plugin-workflow 0.11.0-alpha.1 → 0.11.1-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client/AddButton.js +13 -4
- package/lib/client/Branch.js +4 -2
- package/lib/client/CanvasContent.js +6 -4
- package/lib/client/ExecutionCanvas.js +18 -7
- package/lib/client/ExecutionPage.js +4 -2
- package/lib/client/WorkflowCanvas.js +16 -6
- package/lib/client/WorkflowPage.js +4 -2
- package/lib/client/WorkflowProvider.js +2 -2
- package/lib/client/components/CollectionBlockInitializer.js +3 -3
- package/lib/client/components/CollectionFieldset.js +7 -1
- package/lib/client/components/FieldsSelect.js +4 -1
- package/lib/client/components/NodeDescription.js +36 -22
- package/lib/client/index.js +3 -3
- package/lib/client/locale/zh-CN.d.ts +5 -1
- package/lib/client/locale/zh-CN.js +6 -2
- package/lib/client/nodes/aggregate.d.ts +6 -1
- package/lib/client/nodes/aggregate.js +4 -3
- package/lib/client/nodes/calculation.d.ts +5 -3
- package/lib/client/nodes/calculation.js +6 -5
- package/lib/client/nodes/condition.d.ts +1 -7
- package/lib/client/nodes/condition.js +12 -23
- package/lib/client/nodes/create.d.ts +2 -4
- package/lib/client/nodes/create.js +1 -3
- package/lib/client/nodes/index.d.ts +1 -2
- package/lib/client/nodes/index.js +24 -24
- package/lib/client/nodes/loop.js +19 -28
- package/lib/client/nodes/manual/FormBlockInitializer.js +6 -5
- package/lib/client/nodes/manual/SchemaConfig.d.ts +1 -2
- package/lib/client/nodes/manual/SchemaConfig.js +175 -21
- package/lib/client/nodes/manual/WorkflowTodo.js +39 -46
- package/lib/client/nodes/manual/forms/create.js +8 -1
- package/lib/client/nodes/manual/forms/custom.js +11 -4
- package/lib/client/nodes/manual/forms/update.js +8 -1
- package/lib/client/nodes/manual/index.d.ts +6 -1
- package/lib/client/nodes/manual/index.js +5 -4
- package/lib/client/nodes/parallel.js +7 -4
- package/lib/client/nodes/query.d.ts +2 -5
- package/lib/client/nodes/query.js +1 -3
- package/lib/client/nodes/sql.d.ts +26 -0
- package/lib/client/{triggers/schedule/DateFieldsSelect.js → nodes/sql.js} +37 -46
- package/lib/client/schemas/collection.d.ts +2 -3
- package/lib/client/schemas/collection.js +8 -7
- package/lib/client/style.d.ts +18 -13
- package/lib/client/style.js +312 -289
- package/lib/client/triggers/collection.d.ts +9 -10
- package/lib/client/triggers/collection.js +4 -0
- package/lib/client/triggers/index.d.ts +2 -3
- package/lib/client/triggers/index.js +10 -5
- package/lib/client/triggers/schedule/OnField.js +35 -23
- package/lib/client/triggers/schedule/ScheduleConfig.js +7 -7
- package/lib/client/triggers/schedule/index.d.ts +0 -1
- package/lib/client/triggers/schedule/index.js +31 -19
- package/lib/client/variable.d.ts +29 -11
- package/lib/client/variable.js +39 -24
- package/lib/server/Plugin.d.ts +1 -3
- package/lib/server/Plugin.js +10 -6
- package/lib/server/Processor.d.ts +1 -1
- package/lib/server/Processor.js +2 -2
- package/lib/server/instructions/create.d.ts +1 -1
- package/lib/server/instructions/create.js +13 -13
- package/lib/server/instructions/index.js +1 -1
- package/lib/server/instructions/manual/actions.js +19 -7
- package/lib/server/instructions/manual/forms/create.js +7 -1
- package/lib/server/instructions/manual/forms/update.js +7 -1
- package/lib/server/instructions/query.js +8 -1
- package/lib/server/instructions/request.d.ts +1 -1
- package/lib/server/instructions/request.js +4 -2
- package/lib/server/instructions/sql.d.ts +12 -0
- package/lib/server/instructions/sql.js +34 -0
- package/lib/server/migrations/20230710115902-manual-action-values.d.ts +4 -0
- package/lib/server/migrations/20230710115902-manual-action-values.js +97 -0
- package/lib/server/triggers/collection.js +13 -11
- package/lib/server/utils.d.ts +2 -0
- package/lib/server/utils.js +21 -0
- package/package.json +12 -11
- package/src/client/AddButton.tsx +17 -5
- package/src/client/Branch.tsx +4 -2
- package/src/client/CanvasContent.tsx +6 -4
- package/src/client/ExecutionCanvas.tsx +11 -13
- package/src/client/ExecutionPage.tsx +3 -2
- package/src/client/WorkflowCanvas.tsx +14 -13
- package/src/client/WorkflowPage.tsx +3 -2
- package/src/client/WorkflowProvider.tsx +2 -2
- package/src/client/components/CollectionBlockInitializer.tsx +3 -3
- package/src/client/components/CollectionFieldset.tsx +5 -3
- package/src/client/components/FieldsSelect.tsx +5 -1
- package/src/client/components/NodeDescription.tsx +30 -23
- package/src/client/index.tsx +3 -3
- package/src/client/locale/zh-CN.ts +8 -2
- package/src/client/nodes/aggregate.tsx +4 -4
- package/src/client/nodes/calculation.tsx +4 -5
- package/src/client/nodes/condition.tsx +7 -34
- package/src/client/nodes/create.tsx +0 -1
- package/src/client/nodes/index.tsx +21 -25
- package/src/client/nodes/loop.tsx +16 -31
- package/src/client/nodes/manual/FormBlockInitializer.tsx +6 -5
- package/src/client/nodes/manual/SchemaConfig.tsx +162 -18
- package/src/client/nodes/manual/WorkflowTodo.tsx +43 -47
- package/src/client/nodes/manual/forms/create.tsx +5 -1
- package/src/client/nodes/manual/forms/custom.tsx +7 -3
- package/src/client/nodes/manual/forms/update.tsx +5 -1
- package/src/client/nodes/manual/index.tsx +5 -5
- package/src/client/nodes/parallel.tsx +6 -5
- package/src/client/nodes/query.tsx +0 -1
- package/src/client/nodes/sql.tsx +37 -0
- package/src/client/schemas/collection.ts +6 -6
- package/src/client/style.tsx +324 -289
- package/src/client/triggers/collection.tsx +4 -0
- package/src/client/triggers/index.tsx +14 -10
- package/src/client/triggers/schedule/OnField.tsx +29 -15
- package/src/client/triggers/schedule/ScheduleConfig.tsx +21 -19
- package/src/client/triggers/schedule/index.tsx +25 -19
- package/src/client/variable.tsx +48 -26
- package/src/server/Plugin.ts +13 -9
- package/src/server/Processor.ts +2 -2
- package/src/server/__tests__/collections/categories.ts +4 -0
- package/src/server/__tests__/instructions/manual.test.ts +391 -72
- package/src/server/__tests__/instructions/request.test.ts +30 -0
- package/src/server/__tests__/instructions/sql.test.ts +162 -0
- package/src/server/__tests__/triggers/collection.test.ts +35 -0
- package/src/server/instructions/create.ts +13 -11
- package/src/server/instructions/index.ts +1 -0
- package/src/server/instructions/manual/actions.ts +16 -4
- package/src/server/instructions/manual/forms/create.ts +2 -1
- package/src/server/instructions/manual/forms/update.ts +3 -2
- package/src/server/instructions/query.ts +12 -1
- package/src/server/instructions/request.ts +2 -1
- package/src/server/instructions/sql.ts +25 -0
- package/src/server/migrations/20230710115902-manual-action-values.ts +78 -0
- package/src/server/triggers/collection.ts +15 -11
- package/src/server/utils.ts +17 -0
- package/lib/client/triggers/schedule/DateFieldsSelect.d.ts +0 -2
- package/src/client/triggers/schedule/DateFieldsSelect.tsx +0 -28
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { DownOutlined, EllipsisOutlined, RightOutlined } from '@ant-design/icons';
|
|
2
2
|
import {
|
|
3
3
|
ActionContextProvider,
|
|
4
|
-
cx,
|
|
5
4
|
ResourceActionProvider,
|
|
6
5
|
SchemaComponent,
|
|
6
|
+
cx,
|
|
7
7
|
useDocumentTitle,
|
|
8
8
|
useResourceActionContext,
|
|
9
9
|
useResourceContext,
|
|
10
10
|
} from '@nocobase/client';
|
|
11
|
-
import { Breadcrumb, Button, Dropdown,
|
|
11
|
+
import { App, Breadcrumb, Button, Dropdown, Switch, message } from 'antd';
|
|
12
12
|
import classnames from 'classnames';
|
|
13
13
|
import React, { useEffect, useState } from 'react';
|
|
14
14
|
import { useTranslation } from 'react-i18next';
|
|
@@ -18,7 +18,7 @@ import { ExecutionLink } from './ExecutionLink';
|
|
|
18
18
|
import { FlowContext, useFlowContext } from './FlowContext';
|
|
19
19
|
import { lang } from './locale';
|
|
20
20
|
import { executionSchema } from './schemas/executions';
|
|
21
|
-
import
|
|
21
|
+
import useStyles from './style';
|
|
22
22
|
import { linkNodes } from './utils';
|
|
23
23
|
|
|
24
24
|
function ExecutionResourceProvider({ request, filter = {}, ...others }) {
|
|
@@ -47,6 +47,9 @@ export function WorkflowCanvas() {
|
|
|
47
47
|
const { resource } = useResourceContext();
|
|
48
48
|
const { setTitle } = useDocumentTitle();
|
|
49
49
|
const [visible, setVisible] = useState(false);
|
|
50
|
+
const { styles } = useStyles();
|
|
51
|
+
const { modal } = App.useApp();
|
|
52
|
+
|
|
50
53
|
useEffect(() => {
|
|
51
54
|
const { title } = data?.data ?? {};
|
|
52
55
|
setTitle?.(`${lang('Workflow')}${title ? `: ${title}` : ''}`);
|
|
@@ -95,7 +98,7 @@ export function WorkflowCanvas() {
|
|
|
95
98
|
const content = workflow.current
|
|
96
99
|
? lang('Delete a main version will cause all other revisions to be deleted too.')
|
|
97
100
|
: '';
|
|
98
|
-
|
|
101
|
+
modal.confirm({
|
|
99
102
|
title: t('Are you sure you want to delete it?'),
|
|
100
103
|
content,
|
|
101
104
|
async onOk() {
|
|
@@ -141,14 +144,12 @@ export function WorkflowCanvas() {
|
|
|
141
144
|
>
|
|
142
145
|
<div className="workflow-toolbar">
|
|
143
146
|
<header>
|
|
144
|
-
<Breadcrumb
|
|
145
|
-
|
|
146
|
-
<Link to={`/admin/settings/workflow/workflows`}>{lang('Workflow')}</Link>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
</Breadcrumb.Item>
|
|
151
|
-
</Breadcrumb>
|
|
147
|
+
<Breadcrumb
|
|
148
|
+
items={[
|
|
149
|
+
{ title: <Link to={`/admin/settings/workflow/workflows`}>{lang('Workflow')}</Link> },
|
|
150
|
+
{ title: <strong>{workflow.title}</strong> },
|
|
151
|
+
]}
|
|
152
|
+
/>
|
|
152
153
|
</header>
|
|
153
154
|
<aside>
|
|
154
155
|
<div className="workflow-versions">
|
|
@@ -157,7 +158,7 @@ export function WorkflowCanvas() {
|
|
|
157
158
|
menu={{
|
|
158
159
|
onClick: onSwitchVersion,
|
|
159
160
|
defaultSelectedKeys: [`${workflow.id}`],
|
|
160
|
-
className: cx(workflowVersionDropdownClass),
|
|
161
|
+
className: cx(styles.workflowVersionDropdownClass),
|
|
161
162
|
items: revisions
|
|
162
163
|
.sort((a, b) => b.id - a.id)
|
|
163
164
|
.map((item, index) => ({
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { cx, SchemaComponent } from '@nocobase/client';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { useParams } from 'react-router-dom';
|
|
4
|
-
import
|
|
4
|
+
import useStyles from './style';
|
|
5
5
|
import { WorkflowCanvas } from './WorkflowCanvas';
|
|
6
6
|
|
|
7
7
|
export const WorkflowPage = () => {
|
|
8
8
|
const params = useParams<any>();
|
|
9
|
+
const { styles } = useStyles();
|
|
9
10
|
|
|
10
11
|
return (
|
|
11
|
-
<div className={cx(workflowPageClass)}>
|
|
12
|
+
<div className={cx(styles.workflowPageClass)}>
|
|
12
13
|
<SchemaComponent
|
|
13
14
|
schema={{
|
|
14
15
|
type: 'void',
|
|
@@ -6,15 +6,15 @@ import {
|
|
|
6
6
|
} from '@nocobase/client';
|
|
7
7
|
import { Card } from 'antd';
|
|
8
8
|
import React, { useContext } from 'react';
|
|
9
|
-
import OpenDrawer from './components/OpenDrawer';
|
|
10
9
|
import { ExecutionLink } from './ExecutionLink';
|
|
11
10
|
import { ExecutionResourceProvider } from './ExecutionResourceProvider';
|
|
11
|
+
import { WorkflowLink } from './WorkflowLink';
|
|
12
|
+
import OpenDrawer from './components/OpenDrawer';
|
|
12
13
|
import expressionField from './interfaces/expression';
|
|
13
14
|
import { lang } from './locale';
|
|
14
15
|
import { instructions } from './nodes';
|
|
15
16
|
import { workflowSchema } from './schemas/workflows';
|
|
16
17
|
import { triggers } from './triggers';
|
|
17
|
-
import { WorkflowLink } from './WorkflowLink';
|
|
18
18
|
|
|
19
19
|
// registerField(expressionField.group, 'expression', expressionField);
|
|
20
20
|
|
|
@@ -14,14 +14,14 @@ function InnerCollectionBlockInitializer({ insert, collection, dataSource, ...pr
|
|
|
14
14
|
const { getTemplateSchemaByMode } = useSchemaTemplateManager();
|
|
15
15
|
const { getCollection } = useCollectionManager();
|
|
16
16
|
const items = useRecordCollectionDataSourceItems('FormItem') as SchemaInitializerItemOptions[];
|
|
17
|
-
const
|
|
17
|
+
const resolvedCollection = getCollection(collection);
|
|
18
18
|
|
|
19
19
|
async function onConfirm({ item }) {
|
|
20
20
|
const template = item.template ? await getTemplateSchemaByMode(item) : null;
|
|
21
21
|
const result = {
|
|
22
22
|
type: 'void',
|
|
23
|
-
name:
|
|
24
|
-
title:
|
|
23
|
+
name: resolvedCollection.name,
|
|
24
|
+
title: resolvedCollection.title,
|
|
25
25
|
'x-decorator': 'DetailsBlockProvider',
|
|
26
26
|
'x-decorator-props': {
|
|
27
27
|
collection,
|
|
@@ -3,11 +3,12 @@ import { observer, useField, useForm } from '@formily/react';
|
|
|
3
3
|
import {
|
|
4
4
|
CollectionField,
|
|
5
5
|
CollectionProvider,
|
|
6
|
-
css,
|
|
7
6
|
SchemaComponent,
|
|
7
|
+
Variable,
|
|
8
|
+
css,
|
|
8
9
|
useCollectionManager,
|
|
9
10
|
useCompile,
|
|
10
|
-
|
|
11
|
+
useToken,
|
|
11
12
|
} from '@nocobase/client';
|
|
12
13
|
import { Button, Dropdown, Form, Input, MenuProps } from 'antd';
|
|
13
14
|
import React, { useMemo } from 'react';
|
|
@@ -42,6 +43,7 @@ export function useCollectionUIFields(collection) {
|
|
|
42
43
|
// NOTE: observer for watching useProps
|
|
43
44
|
const CollectionFieldSet = observer(
|
|
44
45
|
({ value, disabled, onChange, filter }: any) => {
|
|
46
|
+
const { token } = useToken();
|
|
45
47
|
const { t } = useTranslation();
|
|
46
48
|
const compile = useCompile();
|
|
47
49
|
const form = useForm();
|
|
@@ -147,7 +149,7 @@ const CollectionFieldSet = observer(
|
|
|
147
149
|
) : null}
|
|
148
150
|
</CollectionProvider>
|
|
149
151
|
) : (
|
|
150
|
-
<p>{lang('Please select collection first')}</p>
|
|
152
|
+
<p style={{ color: token.colorText }}>{lang('Please select collection first')}</p>
|
|
151
153
|
)}
|
|
152
154
|
</fieldset>
|
|
153
155
|
);
|
|
@@ -4,9 +4,13 @@ import React from 'react';
|
|
|
4
4
|
|
|
5
5
|
import { useCollectionManager, useCompile } from '@nocobase/client';
|
|
6
6
|
|
|
7
|
+
function defaultFilter() {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
|
|
7
11
|
export const FieldsSelect = observer(
|
|
8
12
|
(props: any) => {
|
|
9
|
-
const { filter =
|
|
13
|
+
const { filter = defaultFilter, ...others } = props;
|
|
10
14
|
const compile = useCompile();
|
|
11
15
|
const { getCollectionFields } = useCollectionManager();
|
|
12
16
|
const { values } = useForm();
|
|
@@ -1,41 +1,48 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createStyles, cx } from '@nocobase/client';
|
|
2
2
|
import { Tag } from 'antd';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { lang } from '../locale';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
const useStyles = createStyles(({ css, token }) => {
|
|
7
|
+
return {
|
|
8
|
+
container: css`
|
|
9
|
+
margin-bottom: 1.5em;
|
|
10
|
+
padding: 1em;
|
|
11
|
+
background-color: ${token.colorFillAlter};
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
> *:last-child {
|
|
14
|
+
margin-bottom: 0;
|
|
15
|
+
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
dl {
|
|
18
|
+
display: flex;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
dt {
|
|
21
|
+
color: ${token.colorText};
|
|
22
|
+
&:after {
|
|
23
|
+
content: ':';
|
|
24
|
+
margin-right: 0.5em;
|
|
25
|
+
}
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
|
-
}
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
p {
|
|
30
|
+
color: ${token.colorTextDescription};
|
|
31
|
+
}
|
|
32
|
+
`,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export function NodeDescription(props) {
|
|
37
|
+
const { instruction } = props;
|
|
38
|
+
const { styles } = useStyles();
|
|
32
39
|
|
|
33
40
|
return (
|
|
34
|
-
<div className={cx(
|
|
41
|
+
<div className={cx(styles.container, props.className)}>
|
|
35
42
|
<dl>
|
|
36
43
|
<dt>{lang('Node type')}</dt>
|
|
37
44
|
<dd>
|
|
38
|
-
<Tag>{instruction.title}</Tag>
|
|
45
|
+
<Tag style={{ background: 'none' }}>{instruction.title}</Tag>
|
|
39
46
|
</dd>
|
|
40
47
|
</dl>
|
|
41
48
|
{instruction.description ? <p>{instruction.description}</p> : null}
|
package/src/client/index.tsx
CHANGED
|
@@ -6,12 +6,12 @@ export { useWorkflowVariableOptions } from './variable';
|
|
|
6
6
|
|
|
7
7
|
import { Plugin, useCollectionDataSource } from '@nocobase/client';
|
|
8
8
|
import React from 'react';
|
|
9
|
-
import { DynamicExpression } from './components/DynamicExpression';
|
|
10
9
|
import { ExecutionPage } from './ExecutionPage';
|
|
11
|
-
import { WorkflowTodo } from './nodes/manual/WorkflowTodo';
|
|
12
|
-
import { WorkflowTodoBlockInitializer } from './nodes/manual/WorkflowTodoBlockInitializer';
|
|
13
10
|
import { WorkflowPage } from './WorkflowPage';
|
|
14
11
|
import { WorkflowProvider } from './WorkflowProvider';
|
|
12
|
+
import { DynamicExpression } from './components/DynamicExpression';
|
|
13
|
+
import { WorkflowTodo } from './nodes/manual/WorkflowTodo';
|
|
14
|
+
import { WorkflowTodoBlockInitializer } from './nodes/manual/WorkflowTodoBlockInitializer';
|
|
15
15
|
|
|
16
16
|
export class WorkflowPlugin extends Plugin {
|
|
17
17
|
async load() {
|
|
@@ -28,8 +28,8 @@ export default {
|
|
|
28
28
|
'只有被选中的某个字段发生变动时才会触发。如果不选择,则表示任何字段变动时都会触发。新增或删除数据时,任意字段都被认为发生变动。',
|
|
29
29
|
'Only triggers when match conditions': '满足以下条件才触发',
|
|
30
30
|
'Preload associations': '预加载关联数据',
|
|
31
|
-
'Please select the associated fields that need to be accessed in subsequent nodes':
|
|
32
|
-
'
|
|
31
|
+
'Please select the associated fields that need to be accessed in subsequent nodes. With more than two levels of to-many associations may cause performance issue, please use with caution.':
|
|
32
|
+
'请选中需要在后续节点中被访问的关系字段。超过两层的对多关联可能会导致性能问题,请谨慎使用。',
|
|
33
33
|
'Schedule event': '定时任务',
|
|
34
34
|
'Trigger mode': '触发模式',
|
|
35
35
|
'Based on certain date': '自定义时间',
|
|
@@ -90,6 +90,8 @@ export default {
|
|
|
90
90
|
Manual: '人工处理',
|
|
91
91
|
'Could be used for manually submitting data, and determine whether to continue or exit. Workflow will generate a todo item for assigned user when it reaches a manual node, and continue processing after user submits the form.':
|
|
92
92
|
'可用于人工提交数据,并决定是否继续或退出流程。工作流在执行到人工节点时会为被指派的用户生成待办事项,直到用户提交对应表单后继续处理该流程。',
|
|
93
|
+
'Values preset in this form will override user submitted ones when continue or reject.':
|
|
94
|
+
'表单中预设的字段值会在用户提交继续或拒绝时覆盖相应字段的值。',
|
|
93
95
|
'Extended types': '扩展类型',
|
|
94
96
|
'Node type': '节点类型',
|
|
95
97
|
Calculation: '运算',
|
|
@@ -239,4 +241,8 @@ export default {
|
|
|
239
241
|
'Dynamic expression': '动态表达式',
|
|
240
242
|
'An expression for calculation in each rows': '每行数据计算规则不同时使用',
|
|
241
243
|
Unconfigured: '未配置',
|
|
244
|
+
|
|
245
|
+
'SQL action': 'SQL 操作',
|
|
246
|
+
'Execute a SQL statement in database': '在数据库中执行一个 SQL 语句',
|
|
247
|
+
'Usage of SQL query result is not supported yet.': 'SQL 执行的结果暂不支持使用。'
|
|
242
248
|
};
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { collection, filter } from '../schemas/collection';
|
|
14
14
|
import { NAMESPACE, lang } from '../locale';
|
|
15
15
|
import { FilterDynamicComponent } from '../components/FilterDynamicComponent';
|
|
16
|
-
import { BaseTypeSets, nodesOptions, triggerOptions, useWorkflowVariableOptions } from '../variable';
|
|
16
|
+
import { BaseTypeSets, defaultFieldNames, nodesOptions, triggerOptions, useWorkflowVariableOptions } from '../variable';
|
|
17
17
|
import { FieldsSelect } from '../components/FieldsSelect';
|
|
18
18
|
import { ValueBlock } from '../components/ValueBlock';
|
|
19
19
|
import { useNodeContext } from '.';
|
|
@@ -299,7 +299,7 @@ export default {
|
|
|
299
299
|
ValueBlock,
|
|
300
300
|
AssociatedConfig,
|
|
301
301
|
},
|
|
302
|
-
useVariables({ id, title }, { types }) {
|
|
302
|
+
useVariables({ id, title }, { types, fieldNames = defaultFieldNames }) {
|
|
303
303
|
if (
|
|
304
304
|
types &&
|
|
305
305
|
!types.some((type) => type in BaseTypeSets || Object.values(BaseTypeSets).some((set) => set.has(type)))
|
|
@@ -307,8 +307,8 @@ export default {
|
|
|
307
307
|
return null;
|
|
308
308
|
}
|
|
309
309
|
return {
|
|
310
|
-
value: `${id}`,
|
|
311
|
-
label: title,
|
|
310
|
+
[fieldNames.value]: `${id}`,
|
|
311
|
+
[fieldNames.label]: title,
|
|
312
312
|
};
|
|
313
313
|
},
|
|
314
314
|
useInitializers(node): SchemaInitializerItemOptions | null {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FormItem, FormLayout } from '@formily/antd-v5';
|
|
2
|
-
import { SchemaInitializerItemOptions, Variable, css, useCollectionManager } from '@nocobase/client';
|
|
2
|
+
import { SchemaInitializerItemOptions, Variable, css, defaultFieldNames, useCollectionManager } from '@nocobase/client';
|
|
3
3
|
import { Evaluator, evaluators, getOptions } from '@nocobase/evaluators/client';
|
|
4
4
|
import { parse } from '@nocobase/utils/client';
|
|
5
5
|
import { Radio } from 'antd';
|
|
@@ -192,8 +192,7 @@ export default {
|
|
|
192
192
|
RadioWithTooltip,
|
|
193
193
|
DynamicConfig,
|
|
194
194
|
},
|
|
195
|
-
useVariables({ id, title },
|
|
196
|
-
const { types } = options ?? {};
|
|
195
|
+
useVariables({ id, title }, { types, fieldNames = defaultFieldNames }) {
|
|
197
196
|
if (
|
|
198
197
|
types &&
|
|
199
198
|
!types.some((type) => type in BaseTypeSets || Object.values(BaseTypeSets).some((set) => set.has(type)))
|
|
@@ -201,8 +200,8 @@ export default {
|
|
|
201
200
|
return null;
|
|
202
201
|
}
|
|
203
202
|
return {
|
|
204
|
-
value: id
|
|
205
|
-
label: title,
|
|
203
|
+
[fieldNames.value]: `${id}`,
|
|
204
|
+
[fieldNames.label]: title,
|
|
206
205
|
};
|
|
207
206
|
},
|
|
208
207
|
useInitializers(node): SchemaInitializerItemOptions {
|
|
@@ -5,14 +5,13 @@ import { Registry } from '@nocobase/utils/client';
|
|
|
5
5
|
import { Button, Select } from 'antd';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import { Trans, useTranslation } from 'react-i18next';
|
|
8
|
-
import { cloneDeep } from 'lodash';
|
|
9
8
|
import { NodeDefaultView } from '.';
|
|
10
9
|
import { Branch } from '../Branch';
|
|
11
10
|
import { RadioWithTooltip, RadioWithTooltipOption } from '../components/RadioWithTooltip';
|
|
12
11
|
import { renderEngineReference } from '../components/renderEngineReference';
|
|
13
12
|
import { useFlowContext } from '../FlowContext';
|
|
14
13
|
import { lang, NAMESPACE } from '../locale';
|
|
15
|
-
import
|
|
14
|
+
import useStyles from '../style';
|
|
16
15
|
import { useWorkflowVariableOptions } from '../variable';
|
|
17
16
|
|
|
18
17
|
interface Calculator {
|
|
@@ -413,6 +412,7 @@ export default {
|
|
|
413
412
|
component: function Component({ data }) {
|
|
414
413
|
const { t } = useTranslation();
|
|
415
414
|
const { nodes } = useFlowContext();
|
|
415
|
+
const { styles } = useStyles();
|
|
416
416
|
const {
|
|
417
417
|
id,
|
|
418
418
|
config: { rejectOnFalse },
|
|
@@ -422,10 +422,10 @@ export default {
|
|
|
422
422
|
return (
|
|
423
423
|
<NodeDefaultView data={data}>
|
|
424
424
|
{rejectOnFalse ? null : (
|
|
425
|
-
<div className={cx(nodeSubtreeClass)}>
|
|
425
|
+
<div className={cx(styles.nodeSubtreeClass)}>
|
|
426
426
|
<div
|
|
427
427
|
className={cx(
|
|
428
|
-
branchBlockClass,
|
|
428
|
+
styles.branchBlockClass,
|
|
429
429
|
css`
|
|
430
430
|
> * > .workflow-branch-lines {
|
|
431
431
|
> button {
|
|
@@ -438,36 +438,9 @@ export default {
|
|
|
438
438
|
<Branch from={data} entry={falseEntry} branchIndex={0} />
|
|
439
439
|
<Branch from={data} entry={trueEntry} branchIndex={1} />
|
|
440
440
|
</div>
|
|
441
|
-
<div
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
height: 2em;
|
|
445
|
-
overflow: visible;
|
|
446
|
-
|
|
447
|
-
> span {
|
|
448
|
-
position: absolute;
|
|
449
|
-
top: calc(1.5em - 1px);
|
|
450
|
-
line-height: 1em;
|
|
451
|
-
color: #999;
|
|
452
|
-
background-color: var(--nb-box-bg);
|
|
453
|
-
padding: 1px;
|
|
454
|
-
}
|
|
455
|
-
`}
|
|
456
|
-
>
|
|
457
|
-
<span
|
|
458
|
-
className={css`
|
|
459
|
-
right: 4em;
|
|
460
|
-
`}
|
|
461
|
-
>
|
|
462
|
-
{t('No')}
|
|
463
|
-
</span>
|
|
464
|
-
<span
|
|
465
|
-
className={css`
|
|
466
|
-
left: 4em;
|
|
467
|
-
`}
|
|
468
|
-
>
|
|
469
|
-
{t('Yes')}
|
|
470
|
-
</span>
|
|
441
|
+
<div className={styles.conditionClass}>
|
|
442
|
+
<span style={{ right: '4em' }}>{t('No')}</span>
|
|
443
|
+
<span style={{ left: '4em' }}>{t('Yes')}</span>
|
|
471
444
|
</div>
|
|
472
445
|
</div>
|
|
473
446
|
)}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
useResourceActionContext,
|
|
14
14
|
} from '@nocobase/client';
|
|
15
15
|
import { Registry, parse, str2moment } from '@nocobase/utils/client';
|
|
16
|
-
import { Alert, Button, Dropdown, Input,
|
|
16
|
+
import { Alert, App, Button, Dropdown, Input, Tag, message } from 'antd';
|
|
17
17
|
import React, { useContext, useState } from 'react';
|
|
18
18
|
import { useTranslation } from 'react-i18next';
|
|
19
19
|
import { AddButton } from '../AddButton';
|
|
@@ -21,7 +21,7 @@ import { useFlowContext } from '../FlowContext';
|
|
|
21
21
|
import { NodeDescription } from '../components/NodeDescription';
|
|
22
22
|
import { JobStatusOptionsMap } from '../constants';
|
|
23
23
|
import { NAMESPACE, lang } from '../locale';
|
|
24
|
-
import
|
|
24
|
+
import useStyles from '../style';
|
|
25
25
|
import { VariableOption, VariableOptions } from '../variable';
|
|
26
26
|
import aggregate from './aggregate';
|
|
27
27
|
import calculation from './calculation';
|
|
@@ -35,6 +35,7 @@ import parallel from './parallel';
|
|
|
35
35
|
import query from './query';
|
|
36
36
|
import request from './request';
|
|
37
37
|
import update from './update';
|
|
38
|
+
import sql from './sql';
|
|
38
39
|
|
|
39
40
|
export interface Instruction {
|
|
40
41
|
title: string;
|
|
@@ -71,6 +72,7 @@ instructions.register('destroy', destroy);
|
|
|
71
72
|
instructions.register('aggregate', aggregate);
|
|
72
73
|
|
|
73
74
|
instructions.register('request', request);
|
|
75
|
+
instructions.register('sql', sql);
|
|
74
76
|
|
|
75
77
|
function useUpdateAction() {
|
|
76
78
|
const form = useForm();
|
|
@@ -132,11 +134,12 @@ export function useUpstreamScopes(node) {
|
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
export function Node({ data }) {
|
|
137
|
+
const { styles } = useStyles();
|
|
135
138
|
const { component: Component = NodeDefaultView, endding } = instructions.get(data.type);
|
|
136
139
|
|
|
137
140
|
return (
|
|
138
141
|
<NodeContext.Provider value={data}>
|
|
139
|
-
<div className={cx(nodeBlockClass)}>
|
|
142
|
+
<div className={cx(styles.nodeBlockClass)}>
|
|
140
143
|
<Component data={data} />
|
|
141
144
|
{!endding ? (
|
|
142
145
|
<AddButton upstream={data} />
|
|
@@ -172,6 +175,8 @@ export function RemoveButton() {
|
|
|
172
175
|
const api = useAPIClient();
|
|
173
176
|
const { workflow, nodes, refresh } = useFlowContext() ?? {};
|
|
174
177
|
const current = useNodeContext();
|
|
178
|
+
const { modal } = App.useApp();
|
|
179
|
+
|
|
175
180
|
if (!workflow) {
|
|
176
181
|
return null;
|
|
177
182
|
}
|
|
@@ -198,7 +203,7 @@ export function RemoveButton() {
|
|
|
198
203
|
});
|
|
199
204
|
|
|
200
205
|
if (usingNodes.length) {
|
|
201
|
-
|
|
206
|
+
modal.error({
|
|
202
207
|
title: lang('Can not delete'),
|
|
203
208
|
content: lang(
|
|
204
209
|
'The result of this node has been referenced by other nodes ({{nodes}}), please remove the usage before deleting.',
|
|
@@ -213,7 +218,7 @@ export function RemoveButton() {
|
|
|
213
218
|
? t('Are you sure you want to delete it?')
|
|
214
219
|
: lang('This node contains branches, deleting will also be preformed to them, are you sure?');
|
|
215
220
|
|
|
216
|
-
|
|
221
|
+
modal.confirm({
|
|
217
222
|
title: t('Delete'),
|
|
218
223
|
content: message,
|
|
219
224
|
onOk,
|
|
@@ -232,10 +237,11 @@ export function RemoveButton() {
|
|
|
232
237
|
}
|
|
233
238
|
|
|
234
239
|
function InnerJobButton({ job, ...props }) {
|
|
240
|
+
const { styles } = useStyles();
|
|
235
241
|
const { icon, color } = JobStatusOptionsMap[job.status];
|
|
236
242
|
|
|
237
243
|
return (
|
|
238
|
-
<Button {...props} shape="circle" className={cx(nodeJobButtonClass, props.className)}>
|
|
244
|
+
<Button {...props} shape="circle" size="small" className={cx(styles.nodeJobButtonClass, props.className)}>
|
|
239
245
|
<Tag color={color}>{icon}</Tag>
|
|
240
246
|
</Button>
|
|
241
247
|
);
|
|
@@ -244,6 +250,8 @@ function InnerJobButton({ job, ...props }) {
|
|
|
244
250
|
export function JobButton() {
|
|
245
251
|
const { execution, setViewJob } = useFlowContext();
|
|
246
252
|
const { jobs } = useNodeContext() ?? {};
|
|
253
|
+
const { styles } = useStyles();
|
|
254
|
+
|
|
247
255
|
if (!execution) {
|
|
248
256
|
return null;
|
|
249
257
|
}
|
|
@@ -252,7 +260,7 @@ export function JobButton() {
|
|
|
252
260
|
return (
|
|
253
261
|
<span
|
|
254
262
|
className={cx(
|
|
255
|
-
nodeJobButtonClass,
|
|
263
|
+
styles.nodeJobButtonClass,
|
|
256
264
|
css`
|
|
257
265
|
border: 2px solid #d9d9d9;
|
|
258
266
|
border-radius: 50%;
|
|
@@ -279,6 +287,7 @@ export function JobButton() {
|
|
|
279
287
|
<div
|
|
280
288
|
className={css`
|
|
281
289
|
display: flex;
|
|
290
|
+
align-items: center;
|
|
282
291
|
gap: 0.5em;
|
|
283
292
|
|
|
284
293
|
time {
|
|
@@ -287,7 +296,7 @@ export function JobButton() {
|
|
|
287
296
|
}
|
|
288
297
|
`}
|
|
289
298
|
>
|
|
290
|
-
<span className={cx(nodeJobButtonClass, 'inner')}>
|
|
299
|
+
<span className={cx(styles.nodeJobButtonClass, 'inner')}>
|
|
291
300
|
<Tag color={color}>{icon}</Tag>
|
|
292
301
|
</span>
|
|
293
302
|
<time>{str2moment(job.updatedAt).format('YYYY-MM-DD HH:mm:ss')}</time>
|
|
@@ -310,6 +319,7 @@ export function NodeDefaultView(props) {
|
|
|
310
319
|
const compile = useCompile();
|
|
311
320
|
const api = useAPIClient();
|
|
312
321
|
const { workflow, refresh } = useFlowContext() ?? {};
|
|
322
|
+
const { styles } = useStyles();
|
|
313
323
|
|
|
314
324
|
const instruction = instructions.get(data.type);
|
|
315
325
|
const detailText = workflow.executed ? '{{t("View")}}' : '{{t("Configure")}}';
|
|
@@ -349,9 +359,9 @@ export function NodeDefaultView(props) {
|
|
|
349
359
|
}
|
|
350
360
|
|
|
351
361
|
return (
|
|
352
|
-
<div className={cx(nodeClass, `workflow-node-type-${data.type}`)}>
|
|
353
|
-
<div className={cx(nodeCardClass, { configuring: editingConfig })} onClick={onOpenDrawer}>
|
|
354
|
-
<div className={cx(nodeMetaClass, 'workflow-node-meta')}>
|
|
362
|
+
<div className={cx(styles.nodeClass, `workflow-node-type-${data.type}`)}>
|
|
363
|
+
<div className={cx(styles.nodeCardClass, { configuring: editingConfig })} onClick={onOpenDrawer}>
|
|
364
|
+
<div className={cx(styles.nodeMetaClass, 'workflow-node-meta')}>
|
|
355
365
|
<Tag>{typeTitle}</Tag>
|
|
356
366
|
<span className="workflow-node-id">{data.id}</span>
|
|
357
367
|
</div>
|
|
@@ -435,20 +445,6 @@ export function NodeDefaultView(props) {
|
|
|
435
445
|
.ant-cascader-picker,
|
|
436
446
|
.ant-picker,
|
|
437
447
|
.ant-input-number,
|
|
438
|
-
.ant-input-affix-wrapper {
|
|
439
|
-
&:not(.full-width) {
|
|
440
|
-
width: auto;
|
|
441
|
-
min-width: 6em;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
.ant-input-affix-wrapper {
|
|
445
|
-
&:not(.full-width) {
|
|
446
|
-
.ant-input {
|
|
447
|
-
width: auto;
|
|
448
|
-
min-width: 6em;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
448
|
`,
|
|
453
449
|
},
|
|
454
450
|
properties: instruction.fieldset,
|