@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.
Files changed (133) hide show
  1. package/lib/client/AddButton.js +13 -4
  2. package/lib/client/Branch.js +4 -2
  3. package/lib/client/CanvasContent.js +6 -4
  4. package/lib/client/ExecutionCanvas.js +18 -7
  5. package/lib/client/ExecutionPage.js +4 -2
  6. package/lib/client/WorkflowCanvas.js +16 -6
  7. package/lib/client/WorkflowPage.js +4 -2
  8. package/lib/client/WorkflowProvider.js +2 -2
  9. package/lib/client/components/CollectionBlockInitializer.js +3 -3
  10. package/lib/client/components/CollectionFieldset.js +7 -1
  11. package/lib/client/components/FieldsSelect.js +4 -1
  12. package/lib/client/components/NodeDescription.js +36 -22
  13. package/lib/client/index.js +3 -3
  14. package/lib/client/locale/zh-CN.d.ts +5 -1
  15. package/lib/client/locale/zh-CN.js +6 -2
  16. package/lib/client/nodes/aggregate.d.ts +6 -1
  17. package/lib/client/nodes/aggregate.js +4 -3
  18. package/lib/client/nodes/calculation.d.ts +5 -3
  19. package/lib/client/nodes/calculation.js +6 -5
  20. package/lib/client/nodes/condition.d.ts +1 -7
  21. package/lib/client/nodes/condition.js +12 -23
  22. package/lib/client/nodes/create.d.ts +2 -4
  23. package/lib/client/nodes/create.js +1 -3
  24. package/lib/client/nodes/index.d.ts +1 -2
  25. package/lib/client/nodes/index.js +24 -24
  26. package/lib/client/nodes/loop.js +19 -28
  27. package/lib/client/nodes/manual/FormBlockInitializer.js +6 -5
  28. package/lib/client/nodes/manual/SchemaConfig.d.ts +1 -2
  29. package/lib/client/nodes/manual/SchemaConfig.js +175 -21
  30. package/lib/client/nodes/manual/WorkflowTodo.js +39 -46
  31. package/lib/client/nodes/manual/forms/create.js +8 -1
  32. package/lib/client/nodes/manual/forms/custom.js +11 -4
  33. package/lib/client/nodes/manual/forms/update.js +8 -1
  34. package/lib/client/nodes/manual/index.d.ts +6 -1
  35. package/lib/client/nodes/manual/index.js +5 -4
  36. package/lib/client/nodes/parallel.js +7 -4
  37. package/lib/client/nodes/query.d.ts +2 -5
  38. package/lib/client/nodes/query.js +1 -3
  39. package/lib/client/nodes/sql.d.ts +26 -0
  40. package/lib/client/{triggers/schedule/DateFieldsSelect.js → nodes/sql.js} +37 -46
  41. package/lib/client/schemas/collection.d.ts +2 -3
  42. package/lib/client/schemas/collection.js +8 -7
  43. package/lib/client/style.d.ts +18 -13
  44. package/lib/client/style.js +312 -289
  45. package/lib/client/triggers/collection.d.ts +9 -10
  46. package/lib/client/triggers/collection.js +4 -0
  47. package/lib/client/triggers/index.d.ts +2 -3
  48. package/lib/client/triggers/index.js +10 -5
  49. package/lib/client/triggers/schedule/OnField.js +35 -23
  50. package/lib/client/triggers/schedule/ScheduleConfig.js +7 -7
  51. package/lib/client/triggers/schedule/index.d.ts +0 -1
  52. package/lib/client/triggers/schedule/index.js +31 -19
  53. package/lib/client/variable.d.ts +29 -11
  54. package/lib/client/variable.js +39 -24
  55. package/lib/server/Plugin.d.ts +1 -3
  56. package/lib/server/Plugin.js +10 -6
  57. package/lib/server/Processor.d.ts +1 -1
  58. package/lib/server/Processor.js +2 -2
  59. package/lib/server/instructions/create.d.ts +1 -1
  60. package/lib/server/instructions/create.js +13 -13
  61. package/lib/server/instructions/index.js +1 -1
  62. package/lib/server/instructions/manual/actions.js +19 -7
  63. package/lib/server/instructions/manual/forms/create.js +7 -1
  64. package/lib/server/instructions/manual/forms/update.js +7 -1
  65. package/lib/server/instructions/query.js +8 -1
  66. package/lib/server/instructions/request.d.ts +1 -1
  67. package/lib/server/instructions/request.js +4 -2
  68. package/lib/server/instructions/sql.d.ts +12 -0
  69. package/lib/server/instructions/sql.js +34 -0
  70. package/lib/server/migrations/20230710115902-manual-action-values.d.ts +4 -0
  71. package/lib/server/migrations/20230710115902-manual-action-values.js +97 -0
  72. package/lib/server/triggers/collection.js +13 -11
  73. package/lib/server/utils.d.ts +2 -0
  74. package/lib/server/utils.js +21 -0
  75. package/package.json +12 -11
  76. package/src/client/AddButton.tsx +17 -5
  77. package/src/client/Branch.tsx +4 -2
  78. package/src/client/CanvasContent.tsx +6 -4
  79. package/src/client/ExecutionCanvas.tsx +11 -13
  80. package/src/client/ExecutionPage.tsx +3 -2
  81. package/src/client/WorkflowCanvas.tsx +14 -13
  82. package/src/client/WorkflowPage.tsx +3 -2
  83. package/src/client/WorkflowProvider.tsx +2 -2
  84. package/src/client/components/CollectionBlockInitializer.tsx +3 -3
  85. package/src/client/components/CollectionFieldset.tsx +5 -3
  86. package/src/client/components/FieldsSelect.tsx +5 -1
  87. package/src/client/components/NodeDescription.tsx +30 -23
  88. package/src/client/index.tsx +3 -3
  89. package/src/client/locale/zh-CN.ts +8 -2
  90. package/src/client/nodes/aggregate.tsx +4 -4
  91. package/src/client/nodes/calculation.tsx +4 -5
  92. package/src/client/nodes/condition.tsx +7 -34
  93. package/src/client/nodes/create.tsx +0 -1
  94. package/src/client/nodes/index.tsx +21 -25
  95. package/src/client/nodes/loop.tsx +16 -31
  96. package/src/client/nodes/manual/FormBlockInitializer.tsx +6 -5
  97. package/src/client/nodes/manual/SchemaConfig.tsx +162 -18
  98. package/src/client/nodes/manual/WorkflowTodo.tsx +43 -47
  99. package/src/client/nodes/manual/forms/create.tsx +5 -1
  100. package/src/client/nodes/manual/forms/custom.tsx +7 -3
  101. package/src/client/nodes/manual/forms/update.tsx +5 -1
  102. package/src/client/nodes/manual/index.tsx +5 -5
  103. package/src/client/nodes/parallel.tsx +6 -5
  104. package/src/client/nodes/query.tsx +0 -1
  105. package/src/client/nodes/sql.tsx +37 -0
  106. package/src/client/schemas/collection.ts +6 -6
  107. package/src/client/style.tsx +324 -289
  108. package/src/client/triggers/collection.tsx +4 -0
  109. package/src/client/triggers/index.tsx +14 -10
  110. package/src/client/triggers/schedule/OnField.tsx +29 -15
  111. package/src/client/triggers/schedule/ScheduleConfig.tsx +21 -19
  112. package/src/client/triggers/schedule/index.tsx +25 -19
  113. package/src/client/variable.tsx +48 -26
  114. package/src/server/Plugin.ts +13 -9
  115. package/src/server/Processor.ts +2 -2
  116. package/src/server/__tests__/collections/categories.ts +4 -0
  117. package/src/server/__tests__/instructions/manual.test.ts +391 -72
  118. package/src/server/__tests__/instructions/request.test.ts +30 -0
  119. package/src/server/__tests__/instructions/sql.test.ts +162 -0
  120. package/src/server/__tests__/triggers/collection.test.ts +35 -0
  121. package/src/server/instructions/create.ts +13 -11
  122. package/src/server/instructions/index.ts +1 -0
  123. package/src/server/instructions/manual/actions.ts +16 -4
  124. package/src/server/instructions/manual/forms/create.ts +2 -1
  125. package/src/server/instructions/manual/forms/update.ts +3 -2
  126. package/src/server/instructions/query.ts +12 -1
  127. package/src/server/instructions/request.ts +2 -1
  128. package/src/server/instructions/sql.ts +25 -0
  129. package/src/server/migrations/20230710115902-manual-action-values.ts +78 -0
  130. package/src/server/triggers/collection.ts +15 -11
  131. package/src/server/utils.ts +17 -0
  132. package/lib/client/triggers/schedule/DateFieldsSelect.d.ts +0 -2
  133. 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, message, Modal, Switch } from 'antd';
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 { workflowVersionDropdownClass } from './style';
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
- Modal.confirm({
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
- <Breadcrumb.Item>
146
- <Link to={`/admin/settings/workflow/workflows`}>{lang('Workflow')}</Link>
147
- </Breadcrumb.Item>
148
- <Breadcrumb.Item>
149
- <strong>{workflow.title}</strong>
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 { workflowPageClass } from './style';
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 resovledCollection = getCollection(collection);
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: resovledCollection.name,
24
- title: resovledCollection.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
- Variable,
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 = () => true, ...others } = props;
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 { css, cx } from '@nocobase/client';
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
- export function NodeDescription(props) {
7
- const { instruction } = props;
8
- const className = css`
9
- margin-bottom: 1.5em;
10
- padding: 1em;
11
- background: #f6f6f6;
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
- > *:last-child {
14
- margin-bottom: 0;
15
- }
13
+ > *:last-child {
14
+ margin-bottom: 0;
15
+ }
16
16
 
17
- dl {
18
- display: flex;
17
+ dl {
18
+ display: flex;
19
19
 
20
- dt {
21
- &:after {
22
- content: ':';
23
- margin-right: 0.5em;
20
+ dt {
21
+ color: ${token.colorText};
22
+ &:after {
23
+ content: ':';
24
+ margin-right: 0.5em;
25
+ }
24
26
  }
25
27
  }
26
- }
27
28
 
28
- p {
29
- color: rgba(0, 0, 0, 0.45);
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(className, props.className)}>
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}
@@ -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 }, options) {
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 { branchBlockClass, nodeSubtreeClass } from '../style';
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
- className={css`
443
- position: relative;
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
  )}
@@ -38,7 +38,6 @@ export default {
38
38
  },
39
39
  components: {
40
40
  CollectionFieldset,
41
- FieldsSelect,
42
41
  },
43
42
  useVariables({ id, title, config }, options) {
44
43
  const compile = useCompile();
@@ -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, Modal, Tag, message } from 'antd';
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 { nodeBlockClass, nodeCardClass, nodeClass, nodeJobButtonClass, nodeMetaClass } from '../style';
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
- Modal.error({
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
- Modal.confirm({
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,