@nocobase/client 0.7.0-alpha.23 → 0.7.0-alpha.26

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 (113) hide show
  1. package/esm/collection-manager/interfaces/attachment.js +1 -1
  2. package/esm/collection-manager/interfaces/attachment.js.map +1 -1
  3. package/esm/locale/index.d.ts +48 -0
  4. package/esm/locale/zh_CN.d.ts +48 -0
  5. package/esm/locale/zh_CN.js +51 -2
  6. package/esm/locale/zh_CN.js.map +1 -1
  7. package/esm/schema-component/antd/kanban-v2/Kanban.Card.Designer.js +1 -2
  8. package/esm/schema-component/antd/kanban-v2/Kanban.Card.Designer.js.map +1 -1
  9. package/esm/schema-initializer/utils.js +2 -2
  10. package/esm/schema-initializer/utils.js.map +1 -1
  11. package/esm/workflow/WorkflowCanvas.js +11 -8
  12. package/esm/workflow/WorkflowCanvas.js.map +1 -1
  13. package/esm/workflow/WorkflowLink.js +3 -1
  14. package/esm/workflow/WorkflowLink.js.map +1 -1
  15. package/esm/workflow/WorkflowPage.js +3 -3
  16. package/esm/workflow/WorkflowPage.js.map +1 -1
  17. package/esm/workflow/WorkflowShortcut.js +4 -2
  18. package/esm/workflow/WorkflowShortcut.js.map +1 -1
  19. package/esm/workflow/calculators.js +82 -45
  20. package/esm/workflow/calculators.js.map +1 -1
  21. package/esm/workflow/nodes/calculation.js +5 -3
  22. package/esm/workflow/nodes/calculation.js.map +1 -1
  23. package/esm/workflow/nodes/create.d.ts +0 -5
  24. package/esm/workflow/nodes/create.js +5 -3
  25. package/esm/workflow/nodes/create.js.map +1 -1
  26. package/esm/workflow/nodes/destroy.js +2 -2
  27. package/esm/workflow/nodes/destroy.js.map +1 -1
  28. package/esm/workflow/nodes/index.js +11 -8
  29. package/esm/workflow/nodes/index.js.map +1 -1
  30. package/esm/workflow/nodes/query.js +5 -3
  31. package/esm/workflow/nodes/query.js.map +1 -1
  32. package/esm/workflow/nodes/update.d.ts +0 -5
  33. package/esm/workflow/nodes/update.js +2 -2
  34. package/esm/workflow/nodes/update.js.map +1 -1
  35. package/esm/workflow/schemas/collection.d.ts +0 -5
  36. package/esm/workflow/schemas/collection.js +4 -16
  37. package/esm/workflow/schemas/collection.js.map +1 -1
  38. package/esm/workflow/schemas/executions.d.ts +4 -25
  39. package/esm/workflow/schemas/executions.js +38 -34
  40. package/esm/workflow/schemas/executions.js.map +1 -1
  41. package/esm/workflow/schemas/workflows.js +51 -30
  42. package/esm/workflow/schemas/workflows.js.map +1 -1
  43. package/esm/workflow/triggers/index.js +6 -5
  44. package/esm/workflow/triggers/index.js.map +1 -1
  45. package/esm/workflow/triggers/model.js +12 -10
  46. package/esm/workflow/triggers/model.js.map +1 -1
  47. package/lib/collection-manager/interfaces/attachment.js +1 -1
  48. package/lib/collection-manager/interfaces/attachment.js.map +1 -1
  49. package/lib/locale/index.d.ts +48 -0
  50. package/lib/locale/zh_CN.d.ts +48 -0
  51. package/lib/locale/zh_CN.js +51 -2
  52. package/lib/locale/zh_CN.js.map +1 -1
  53. package/lib/schema-component/antd/kanban-v2/Kanban.Card.Designer.js +1 -2
  54. package/lib/schema-component/antd/kanban-v2/Kanban.Card.Designer.js.map +1 -1
  55. package/lib/schema-initializer/utils.js +2 -2
  56. package/lib/schema-initializer/utils.js.map +1 -1
  57. package/lib/workflow/WorkflowCanvas.js +10 -7
  58. package/lib/workflow/WorkflowCanvas.js.map +1 -1
  59. package/lib/workflow/WorkflowLink.js +3 -1
  60. package/lib/workflow/WorkflowLink.js.map +1 -1
  61. package/lib/workflow/WorkflowPage.js +3 -3
  62. package/lib/workflow/WorkflowPage.js.map +1 -1
  63. package/lib/workflow/WorkflowShortcut.js +4 -2
  64. package/lib/workflow/WorkflowShortcut.js.map +1 -1
  65. package/lib/workflow/calculators.js +79 -42
  66. package/lib/workflow/calculators.js.map +1 -1
  67. package/lib/workflow/nodes/calculation.js +5 -3
  68. package/lib/workflow/nodes/calculation.js.map +1 -1
  69. package/lib/workflow/nodes/create.d.ts +0 -5
  70. package/lib/workflow/nodes/create.js +5 -3
  71. package/lib/workflow/nodes/create.js.map +1 -1
  72. package/lib/workflow/nodes/destroy.js +2 -2
  73. package/lib/workflow/nodes/destroy.js.map +1 -1
  74. package/lib/workflow/nodes/index.js +10 -7
  75. package/lib/workflow/nodes/index.js.map +1 -1
  76. package/lib/workflow/nodes/query.js +5 -3
  77. package/lib/workflow/nodes/query.js.map +1 -1
  78. package/lib/workflow/nodes/update.d.ts +0 -5
  79. package/lib/workflow/nodes/update.js +2 -2
  80. package/lib/workflow/nodes/update.js.map +1 -1
  81. package/lib/workflow/schemas/collection.d.ts +0 -5
  82. package/lib/workflow/schemas/collection.js +4 -16
  83. package/lib/workflow/schemas/collection.js.map +1 -1
  84. package/lib/workflow/schemas/executions.d.ts +4 -25
  85. package/lib/workflow/schemas/executions.js +38 -34
  86. package/lib/workflow/schemas/executions.js.map +1 -1
  87. package/lib/workflow/schemas/workflows.js +51 -30
  88. package/lib/workflow/schemas/workflows.js.map +1 -1
  89. package/lib/workflow/triggers/index.js +5 -4
  90. package/lib/workflow/triggers/index.js.map +1 -1
  91. package/lib/workflow/triggers/model.js +12 -10
  92. package/lib/workflow/triggers/model.js.map +1 -1
  93. package/package.json +3 -3
  94. package/src/collection-manager/interfaces/attachment.ts +1 -1
  95. package/src/locale/zh_CN.ts +63 -2
  96. package/src/schema-component/antd/kanban-v2/Kanban.Card.Designer.tsx +1 -2
  97. package/src/schema-initializer/utils.ts +2 -2
  98. package/src/workflow/WorkflowCanvas.tsx +13 -8
  99. package/src/workflow/WorkflowLink.tsx +3 -1
  100. package/src/workflow/WorkflowPage.tsx +3 -3
  101. package/src/workflow/WorkflowShortcut.tsx +4 -2
  102. package/src/workflow/calculators.tsx +100 -54
  103. package/src/workflow/nodes/calculation.tsx +5 -3
  104. package/src/workflow/nodes/create.tsx +5 -3
  105. package/src/workflow/nodes/destroy.tsx +2 -2
  106. package/src/workflow/nodes/index.tsx +11 -8
  107. package/src/workflow/nodes/query.tsx +5 -3
  108. package/src/workflow/nodes/update.tsx +2 -2
  109. package/src/workflow/schemas/collection.ts +4 -16
  110. package/src/workflow/schemas/executions.ts +38 -34
  111. package/src/workflow/schemas/workflows.ts +31 -30
  112. package/src/workflow/triggers/index.tsx +6 -5
  113. package/src/workflow/triggers/model.tsx +12 -10
@@ -6,9 +6,12 @@ import { addButtonClass, branchBlockClass, branchClass, nodeBlockClass, nodeCard
6
6
 
7
7
  import {
8
8
  useCollection,
9
+ useCompile,
9
10
  useResourceActionContext
10
11
  } from '..';
11
12
  import { Instruction, instructions, Node } from './nodes';
13
+ import { t } from 'i18next';
14
+ import { useTranslation } from 'react-i18next';
12
15
 
13
16
 
14
17
 
@@ -34,10 +37,11 @@ export function useFlowContext() {
34
37
  }
35
38
 
36
39
  export function WorkflowCanvas() {
40
+ const { t } = useTranslation();
37
41
  const { data, refresh, loading } = useResourceActionContext();
38
42
 
39
43
  if (!data?.data && !loading) {
40
- return <div>加载失败</div>;
44
+ return <div>{t('Load failed')}</div>;
41
45
  }
42
46
 
43
47
  const { nodes = [], ...workflow } = data?.data ?? {};
@@ -56,7 +60,7 @@ export function WorkflowCanvas() {
56
60
  <div className={branchBlockClass}>
57
61
  <Branch entry={entry} />
58
62
  </div>
59
- <div className={cx(nodeCardClass)}>结束</div>
63
+ <div className={cx(nodeCardClass)}>{t('End')}</div>
60
64
  </FlowContext.Provider>
61
65
  );
62
66
  }
@@ -93,6 +97,7 @@ interface AddButtonProps {
93
97
  };
94
98
 
95
99
  export function AddButton({ upstream, branchIndex = null }: AddButtonProps) {
100
+ const compile = useCompile();
96
101
  const { resource } = useCollection();
97
102
  const { data } = useResourceActionContext();
98
103
  const { onNodeAdded } = useFlowContext();
@@ -120,8 +125,8 @@ export function AddButton({ upstream, branchIndex = null }: AddButtonProps) {
120
125
  }
121
126
 
122
127
  const groups = [
123
- { value: 'control', name: '流程控制' },
124
- { value: 'model', name: '数据表操作' },
128
+ { value: 'control', name: '{{t("Control")}}' },
129
+ { value: 'collection', name: '{{t("Collection operations")}}' },
125
130
  ];
126
131
  const instructionList = (Array.from(instructions.getValues()) as Instruction[]);
127
132
 
@@ -130,17 +135,17 @@ export function AddButton({ upstream, branchIndex = null }: AddButtonProps) {
130
135
  <Dropdown trigger={['click']} overlay={
131
136
  <Menu onClick={ev => onCreate(ev)}>
132
137
  {groups.map(group => (
133
- <Menu.ItemGroup key={group.value} title={group.name}>
138
+ <Menu.ItemGroup key={group.value} title={compile(group.name)}>
134
139
  {instructionList.filter(item => item.group === group.value).map(item => item.options
135
140
  ? (
136
- <Menu.SubMenu key={item.type} title={item.title}>
141
+ <Menu.SubMenu key={item.type} title={compile(item.title)}>
137
142
  {item.options.map(option => (
138
- <Menu.Item key={option.key}>{option.label}</Menu.Item>
143
+ <Menu.Item key={option.key}>{compile(option.label)}</Menu.Item>
139
144
  ))}
140
145
  </Menu.SubMenu>
141
146
  )
142
147
  : (
143
- <Menu.Item key={item.type}>{item.title}</Menu.Item>
148
+ <Menu.Item key={item.type}>{compile(item.title)}</Menu.Item>
144
149
  ))}
145
150
  </Menu.ItemGroup>
146
151
  ))}
@@ -1,12 +1,14 @@
1
1
  import React from 'react';
2
+ import { useTranslation } from 'react-i18next';
2
3
  import { Link } from 'react-router-dom';
3
4
  import { useActionContext, useRecord } from '..';
4
5
 
5
6
 
6
7
  export const WorkflowLink = () => {
8
+ const { t } = useTranslation();
7
9
  const { id } = useRecord();
8
10
  const { setVisible } = useActionContext();
9
11
  return (
10
- <Link to={`/admin/plugins/workflows/${id}`} onClick={() => setVisible(false)}>流程配置</Link>
12
+ <Link to={`/admin/plugins/workflows/${id}`} onClick={() => setVisible(false)}>{t('Configure workflow')}</Link>
11
13
  );
12
14
  }
@@ -15,7 +15,7 @@ const workflowCollection = {
15
15
  name: 'title',
16
16
  interface: 'input',
17
17
  uiSchema: {
18
- title: '流程名称',
18
+ title: '{{t("Name")}}',
19
19
  type: 'string',
20
20
  'x-component': 'Input',
21
21
  required: true,
@@ -66,7 +66,7 @@ export const WorkflowPage = () => {
66
66
  name: 'title',
67
67
  interface: 'input',
68
68
  uiSchema: {
69
- title: '节点名称',
69
+ title: '{{t("Name")}}',
70
70
  type: 'string',
71
71
  'x-component': 'Input',
72
72
  },
@@ -76,7 +76,7 @@ export const WorkflowPage = () => {
76
76
  name: 'type',
77
77
  interface: 'select',
78
78
  uiSchema: {
79
- title: '节点类型',
79
+ title: '{{t("Node type")}}',
80
80
  type: 'string',
81
81
  'x-component': 'Select',
82
82
  required: true,
@@ -5,6 +5,7 @@ import { uid } from '@formily/shared';
5
5
  import { PluginManager } from '../plugin-manager';
6
6
  import { ActionContext, SchemaComponent, useActionContext } from '../schema-component';
7
7
  import { WorkflowTable } from './WorkflowTable';
8
+ import { useTranslation } from 'react-i18next';
8
9
 
9
10
  const useCloseAction = () => {
10
11
  const { setVisible } = useActionContext();
@@ -25,7 +26,7 @@ const schema: ISchema = {
25
26
  [uid()]: {
26
27
  'x-component': 'Action.Drawer',
27
28
  type: 'void',
28
- title: '工作流',
29
+ title: '{{t("Workflow")}}',
29
30
  properties: {
30
31
  main: {
31
32
  type: 'void',
@@ -37,12 +38,13 @@ const schema: ISchema = {
37
38
  };
38
39
 
39
40
  export const WorkflowShortcut = () => {
41
+ const { t } = useTranslation();
40
42
  const [visible, setVisible] = useState(false);
41
43
  return (
42
44
  <ActionContext.Provider value={{ visible, setVisible }}>
43
45
  <PluginManager.Toolbar.Item
44
46
  icon={<PartitionOutlined />}
45
- title={'工作流'}
47
+ title={t('Workflow')}
46
48
  onClick={() => {
47
49
  setVisible(true);
48
50
  }}
@@ -1,13 +1,15 @@
1
1
  import React from "react";
2
- import { observer } from "@formily/react";
2
+ import { observer, useForm } from "@formily/react";
3
3
  import { FormItem } from "@formily/antd";
4
- import { Cascader, DatePicker, Input, InputNumber, Select } from "antd";
4
+ import { Button, Cascader, Dropdown, Input, InputNumber, Menu, Select } from "antd";
5
5
  import { css } from "@emotion/css";
6
+ import { PlusOutlined, CloseCircleOutlined } from '@ant-design/icons';
6
7
 
7
8
  import { instructions, useNodeContext } from "./nodes";
8
9
  import { useFlowContext } from "./WorkflowCanvas";
9
10
  import { triggers } from "./triggers";
10
- import { SchemaComponent, useCompile } from "..";
11
+ import { SchemaComponent, useCollectionManager, useCompile } from "..";
12
+ import { useTranslation } from "react-i18next";
11
13
 
12
14
  function NullRender() {
13
15
  return null;
@@ -16,7 +18,7 @@ function NullRender() {
16
18
  export const calculators = [
17
19
  {
18
20
  value: 'boolean',
19
- title: '值比较',
21
+ title: '{{t("Comparison")}}',
20
22
  children: [
21
23
  { value: 'equal', name: '=' },
22
24
  { value: 'notEqual', name: '≠' },
@@ -28,7 +30,7 @@ export const calculators = [
28
30
  },
29
31
  {
30
32
  value: 'number',
31
- title: '算术运算',
33
+ title: '{{t("Arithmetic calculation")}}',
32
34
  children: [
33
35
  { value: 'add', name: '+' },
34
36
  { value: 'minus', name: '-' },
@@ -39,19 +41,19 @@ export const calculators = [
39
41
  },
40
42
  {
41
43
  value: 'string',
42
- title: '字符串',
44
+ title: '{{t("String operation")}}',
43
45
  children: [
44
- { value: 'includes', name: '包含' },
45
- { value: 'notIncludes', name: '不包含' },
46
- { value: 'startsWith', name: '开头是' },
47
- { value: 'notStartsWith', name: '开头不是' },
48
- { value: 'endsWith', name: '结尾是' },
49
- { value: 'notEndsWith', name: '结尾不是' }
46
+ { value: 'includes', name: '{{t("contains")}}' },
47
+ { value: 'notIncludes', name: '{{t("does not contain")}}' },
48
+ { value: 'startsWith', name: '{{t("starts with")}}' },
49
+ { value: 'notStartsWith', name: '{{t("not starts with")}}' },
50
+ { value: 'endsWith', name: '{{t("ends with")}}' },
51
+ { value: 'notEndsWith', name: '{{t("not ends with")}}' }
50
52
  ]
51
53
  },
52
54
  {
53
55
  value: 'date',
54
- title: '日期',
56
+ title: '{{t("Date")}}',
55
57
  children: []
56
58
  }
57
59
  ];
@@ -76,7 +78,7 @@ export const BaseTypeSet = new Set(['boolean', 'number', 'string', 'date']);
76
78
 
77
79
  const ConstantTypes = {
78
80
  string: {
79
- title: '字符串',
81
+ title: '{{t("String")}}',
80
82
  value: 'string',
81
83
  component({ onChange, type, options, value }) {
82
84
  return (
@@ -89,7 +91,7 @@ const ConstantTypes = {
89
91
  default: ''
90
92
  },
91
93
  number: {
92
- title: '数字',
94
+ title: '{{t("Number")}}',
93
95
  value: 'number',
94
96
  component({ onChange, type, options, value }) {
95
97
  return (
@@ -102,7 +104,7 @@ const ConstantTypes = {
102
104
  default: 0
103
105
  },
104
106
  boolean: {
105
- title: '逻辑值',
107
+ title: '{{t("Boolean")}}',
106
108
  value: 'boolean',
107
109
  component({ onChange, type, options, value }) {
108
110
  return (
@@ -126,7 +128,7 @@ const ConstantTypes = {
126
128
 
127
129
  export const VariableTypes = {
128
130
  constant: {
129
- title: '常量',
131
+ title: '{{t("Constant")}}',
130
132
  value: 'constant',
131
133
  options: Object.values(ConstantTypes).map(item => ({
132
134
  value: item.value,
@@ -154,7 +156,7 @@ export const VariableTypes = {
154
156
  }
155
157
  },
156
158
  $jobsMapByNodeId: {
157
- title: '节点数据',
159
+ title: '{{t("Node result")}}',
158
160
  value: '$jobsMapByNodeId',
159
161
  options() {
160
162
  const node = useNodeContext();
@@ -209,7 +211,7 @@ export const VariableTypes = {
209
211
  }
210
212
  },
211
213
  $context: {
212
- title: '触发数据',
214
+ title: '{{t("Trigger context")}}',
213
215
  value: '$context',
214
216
  component() {
215
217
  const { workflow } = useFlowContext();
@@ -251,6 +253,7 @@ export function Operand({
251
253
  onChange,
252
254
  children
253
255
  }: OperandProps) {
256
+ const compile = useCompile();
254
257
  const Types = useVariableTypes();
255
258
 
256
259
  const { type } = operand;
@@ -278,7 +281,7 @@ export function Operand({
278
281
  options={Object.values(Types).map((item: any) => {
279
282
  const options = typeof item.options === 'function' ? item.options() : item.options;
280
283
  return {
281
- label: item.title,
284
+ label: compile(item.title),
282
285
  value: item.value,
283
286
  children: options,
284
287
  disabled: options && !options.length,
@@ -302,6 +305,7 @@ export function Operand({
302
305
  }
303
306
 
304
307
  export function Calculation({ calculator, operands = [], onChange }) {
308
+ const { t } = useTranslation();
305
309
  return (
306
310
  <VariableTypesContext.Provider value={VariableTypes}>
307
311
  <div className={css`
@@ -320,9 +324,9 @@ export function Calculation({ calculator, operands = [], onChange }) {
320
324
  <>
321
325
  <Select value={calculator} onChange={v => onChange({ operands, calculator: v })}>
322
326
  {calculators.map(group => (
323
- <Select.OptGroup key={group.value} label={group.title}>
327
+ <Select.OptGroup key={group.value} label={t(group.title)}>
324
328
  {group.children.map(item => (
325
- <Select.Option key={item.value} value={item.value}>{item.name}</Select.Option>
329
+ <Select.Option key={item.value} value={t(item.value)}>{item.name}</Select.Option>
326
330
  ))}
327
331
  </Select.OptGroup>
328
332
  ))}
@@ -340,7 +344,7 @@ export function Calculation({ calculator, operands = [], onChange }) {
340
344
  export function VariableComponent({ value, onChange, renderSchemaComponent }) {
341
345
  const VTypes = { ...VariableTypes,
342
346
  constant: {
343
- title: '常量',
347
+ title: '{{t("Constant")}}',
344
348
  value: 'constant',
345
349
  options: undefined
346
350
  }
@@ -370,13 +374,21 @@ export function VariableComponent({ value, onChange, renderSchemaComponent }) {
370
374
  }
371
375
 
372
376
  // NOTE: observer for watching useProps
373
- export const CollectionFieldset = observer(({ value, onChange, useProps }: any) => {
374
- const { fields } = useProps();
377
+ export const CollectionFieldset = observer(({ value, onChange }: any) => {
378
+ const { t } = useTranslation();
375
379
  const compile = useCompile();
380
+ const { getCollectionFields } = useCollectionManager();
381
+ const { values: data } = useForm();
382
+ const fields = getCollectionFields(data?.config?.collection)
383
+ .filter(field => (
384
+ !field.hidden
385
+ && (field.uiSchema ? !field.uiSchema['x-read-pretty'] : false)
386
+ ));
376
387
 
377
- const VTypes = { ...VariableTypes,
388
+ const VTypes = {
389
+ ...VariableTypes,
378
390
  constant: {
379
- title: '常量',
391
+ title: '{{t("Constant")}}',
380
392
  value: 'constant',
381
393
  options: undefined
382
394
  }
@@ -395,35 +407,69 @@ export const CollectionFieldset = observer(({ value, onChange, useProps }: any)
395
407
  }
396
408
  `}>
397
409
  {fields.length
398
- ? fields.map(field => {
399
- const operand = typeof value[field.name] === 'string'
400
- ? parseStringValue(value[field.name], VTypes)
401
- : { type: 'constant', value: value[field.name] };
410
+ ? (
411
+ <>
412
+ {fields
413
+ .filter(field => field.name in value)
414
+ .map(field => {
415
+ const operand = typeof value[field.name] === 'string'
416
+ ? parseStringValue(value[field.name], VTypes)
417
+ : { type: 'constant', value: value[field.name] };
402
418
 
403
- return (
404
- <FormItem label={compile(field.uiSchema?.title ?? field.name)} labelAlign="left">
405
- <VariableTypesContext.Provider value={VTypes}>
406
- <Operand
407
- value={operand}
408
- onChange={(next) => {
409
- if (next.type !== operand.type && next.type === 'constant') {
410
- onChange({ ...value, [field.name]: null });
411
- } else {
412
- const { stringify } = VTypes[next.type];
413
- onChange({ ...value, [field.name]: stringify(next) });
419
+ return (
420
+ <FormItem key={field.name} label={compile(field.uiSchema?.title ?? field.name)} labelAlign="left" className={css`
421
+ .ant-formily-item-control-content-component{
422
+ display: flex;
423
+ }
424
+ `}>
425
+ <VariableTypesContext.Provider value={VTypes}>
426
+ <Operand
427
+ value={operand}
428
+ onChange={(next) => {
429
+ if (next.type !== operand.type && next.type === 'constant') {
430
+ onChange({ ...value, [field.name]: null });
431
+ } else {
432
+ const { stringify } = VTypes[next.type];
433
+ onChange({ ...value, [field.name]: stringify(next) });
434
+ }
435
+ }}
436
+ >
437
+ {operand.type === 'constant'
438
+ ? <SchemaComponent schema={{ ...field.uiSchema, name: field.name }} />
439
+ : null
414
440
  }
415
- }}
416
- >
417
- {operand.type === 'constant'
418
- ? <SchemaComponent schema={{ ...field.uiSchema, name: field.name }} />
419
- : null
420
- }
421
- </Operand>
422
- </VariableTypesContext.Provider>
423
- </FormItem>
424
- );
425
- })
426
- : <p>请先选择数据表</p>
441
+ </Operand>
442
+ <Button
443
+ type="link"
444
+ icon={<CloseCircleOutlined />}
445
+ onClick={() => {
446
+ const { [field.name]: _, ...rest } = value;
447
+ onChange(rest);
448
+ }}
449
+ />
450
+ </VariableTypesContext.Provider>
451
+ </FormItem>
452
+ );
453
+ })}
454
+ {Object.keys(value).length < fields.length
455
+ ? (
456
+ <Dropdown overlay={
457
+ <Menu onClick={({ key }) => onChange({ ...value, [key]: null })}>
458
+ {fields
459
+ .filter(field => !(field.name in value))
460
+ .map(field => (
461
+ <Menu.Item key={field.name}>{compile(field.uiSchema?.title ?? field.name)}</Menu.Item>
462
+ ))}
463
+ </Menu>
464
+ }>
465
+ <Button icon={<PlusOutlined />}>{t('Add field')}</Button>
466
+ </Dropdown>
467
+ )
468
+ : null
469
+ }
470
+ </>
471
+ )
472
+ : <p>{t('Select collection')}</p>
427
473
  }
428
474
  </fieldset>
429
475
  );
@@ -1,15 +1,16 @@
1
1
  import { css } from '@emotion/css';
2
2
  import React from 'react';
3
+ import { useTranslation } from 'react-i18next';
3
4
  import { Calculation } from '../calculators';
4
5
 
5
6
  export default {
6
- title: '运算',
7
+ title: '{{t("Calculation")}}',
7
8
  type: 'calculation',
8
9
  group: 'control',
9
10
  fieldset: {
10
11
  'config.calculation': {
11
12
  type: 'object',
12
- title: '配置计算',
13
+ title: '{{t("Configure calculation")}}',
13
14
  name: 'config.calculation',
14
15
  required: true,
15
16
  'x-decorator': 'FormItem',
@@ -27,6 +28,7 @@ export default {
27
28
  }
28
29
  },
29
30
  getter() {
30
- return <div className={css`flex-shrink: 0`}>计算值</div>;
31
+ const { t } = useTranslation();
32
+ return <div className={css`flex-shrink: 0`}>{t('Calculation result')}</div>;
31
33
  }
32
34
  };
@@ -1,5 +1,6 @@
1
1
  import { Select } from 'antd';
2
2
  import React from 'react';
3
+ import { useTranslation } from 'react-i18next';
3
4
  import { useCollectionDataSource, useCollectionManager, useCompile } from '../..';
4
5
  import { BaseTypeSet, CollectionFieldset } from '../calculators';
5
6
  import { collection, values } from '../schemas/collection';
@@ -7,9 +8,9 @@ import { useFlowContext } from '../WorkflowCanvas';
7
8
 
8
9
 
9
10
  export default {
10
- title: '新增数据',
11
+ title: '{{t("Create record")}}',
11
12
  type: 'create',
12
- group: 'model',
13
+ group: 'collection',
13
14
  fieldset: {
14
15
  'config.collection': {
15
16
  ...collection,
@@ -45,6 +46,7 @@ export default {
45
46
  CollectionFieldset
46
47
  },
47
48
  getter({ type, options, onChange }) {
49
+ const { t } = useTranslation();
48
50
  const compile = useCompile();
49
51
  const { collections = [] } = useCollectionManager();
50
52
  const { nodes } = useFlowContext();
@@ -52,7 +54,7 @@ export default {
52
54
  const collection = collections.find(item => item.name === config.collection) ?? { fields: [] };
53
55
 
54
56
  return (
55
- <Select value={options.path} placeholder="选择字段" onChange={path => {
57
+ <Select value={options.path} placeholder={t('Fields')} onChange={path => {
56
58
  onChange({ type, options: { ...options, path } });
57
59
  }}>
58
60
  {collection.fields
@@ -4,9 +4,9 @@ import { VariableComponent } from '../calculators';
4
4
  import { collection, filter } from '../schemas/collection';
5
5
 
6
6
  export default {
7
- title: '删除数据',
7
+ title: '{{t("Delete record")}}',
8
8
  type: 'destroy',
9
- group: 'model',
9
+ group: 'collection',
10
10
  fieldset: {
11
11
  'config.collection': collection,
12
12
  'config.params': {
@@ -4,7 +4,8 @@ import { ISchema, useForm } from '@formily/react';
4
4
  import { Registry } from '@nocobase/utils';
5
5
  import { Button, Modal, Tag } from 'antd';
6
6
  import React, { useContext } from 'react';
7
- import { SchemaComponent, useActionContext, useAPIClient, useCollection, useRequest, useResourceActionContext } from '../..';
7
+ import { useTranslation } from 'react-i18next';
8
+ import { SchemaComponent, useActionContext, useAPIClient, useCollection, useCompile, useRequest, useResourceActionContext } from '../..';
8
9
  import { nodeBlockClass, nodeCardClass, nodeClass, nodeHeaderClass, nodeTitleClass } from '../style';
9
10
  import { AddButton, useFlowContext } from '../WorkflowCanvas';
10
11
 
@@ -109,6 +110,7 @@ export function Node({ data }) {
109
110
  }
110
111
 
111
112
  export function RemoveButton() {
113
+ const { t } = useTranslation();
112
114
  const { resource } = useCollection();
113
115
  const current = useNodeContext();
114
116
  const { nodes, onNodeRemoved } = useFlowContext();
@@ -123,11 +125,11 @@ export function RemoveButton() {
123
125
 
124
126
  const hasBranches = !nodes.find(item => item.upstream === current && item.branchIndex != null);
125
127
  const message = hasBranches
126
- ? '确定删除该节点吗?'
127
- : '节点包含分支,将同时删除其所有分支下的子节点,确定继续?';
128
+ ? t('Are you sure you want to delete it?')
129
+ : t('This node contains branches, deleting will also be preformed to them, are you sure?');
128
130
 
129
131
  Modal.confirm({
130
- title: '删除节点',
132
+ title: t('Delete'),
131
133
  content: message,
132
134
  onOk
133
135
  });
@@ -146,6 +148,7 @@ export function RemoveButton() {
146
148
 
147
149
  export function NodeDefaultView(props) {
148
150
  const { data, children } = props;
151
+ const compile = useCompile();
149
152
  const instruction = instructions.get(data.type);
150
153
 
151
154
  return (
@@ -154,7 +157,7 @@ export function NodeDefaultView(props) {
154
157
  <div className={cx(nodeCardClass)}>
155
158
  <div className={cx(nodeHeaderClass)}>
156
159
  <h4 className={cx(nodeTitleClass)}>
157
- <Tag>{instruction.title}</Tag>
160
+ <Tag>{compile(instruction.title)}</Tag>
158
161
  <strong>{data.title}</strong>
159
162
  <span className="workflow-node-id">#{data.id}</span>
160
163
  </h4>
@@ -169,7 +172,7 @@ export function NodeDefaultView(props) {
169
172
  view: instruction.view,
170
173
  config: {
171
174
  type: 'void',
172
- title: '配置节点',
175
+ title: '{{t("Node configuration")}}',
173
176
  'x-component': 'Action.Link',
174
177
  'x-component-props': {
175
178
  type: 'primary',
@@ -177,7 +180,7 @@ export function NodeDefaultView(props) {
177
180
  properties: {
178
181
  drawer: {
179
182
  type: 'void',
180
- title: '配置节点',
183
+ title: '{{t("Node configuration")}}',
181
184
  'x-component': 'Action.Drawer',
182
185
  'x-decorator': 'Form',
183
186
  'x-decorator-props': {
@@ -192,7 +195,7 @@ export function NodeDefaultView(props) {
192
195
  title: {
193
196
  type: 'string',
194
197
  name: 'title',
195
- title: '节点名称',
198
+ title: '{{t("Name")}}',
196
199
  'x-decorator': 'FormItem',
197
200
  'x-component': 'Input',
198
201
  },
@@ -6,11 +6,12 @@ import { useCollectionDataSource, useCollectionManager, useCompile } from '../..
6
6
  import { useFlowContext } from '../WorkflowCanvas';
7
7
  import { BaseTypeSet, VariableComponent } from '../calculators';
8
8
  import { collection, filter } from '../schemas/collection';
9
+ import { useTranslation } from 'react-i18next';
9
10
 
10
11
  export default {
11
- title: '查询数据',
12
+ title: '{{t("Query record")}}',
12
13
  type: 'query',
13
- group: 'model',
14
+ group: 'collection',
14
15
  fieldset: {
15
16
  'config.collection': collection,
16
17
  'config.multiple': {
@@ -43,6 +44,7 @@ export default {
43
44
  VariableComponent
44
45
  },
45
46
  getter({ type, options, onChange }) {
47
+ const { t } = useTranslation();
46
48
  const compile = useCompile();
47
49
  const { collections = [] } = useCollectionManager();
48
50
  const { nodes } = useFlowContext();
@@ -50,7 +52,7 @@ export default {
50
52
  const collection = collections.find(item => item.name === config.collection) ?? { fields: [] };
51
53
 
52
54
  return (
53
- <Select value={options.path} placeholder="选择字段" onChange={path => {
55
+ <Select value={options.path} placeholder={t('Fields')} onChange={path => {
54
56
  onChange({ type, options: { ...options, path } });
55
57
  }}>
56
58
  {collection.fields
@@ -3,9 +3,9 @@ import { CollectionFieldset, VariableComponent } from '../calculators';
3
3
  import { collection, filter, values } from '../schemas/collection';
4
4
 
5
5
  export default {
6
- title: '更新数据',
6
+ title: '{{t("Update record")}}',
7
7
  type: 'update',
8
- group: 'model',
8
+ group: 'collection',
9
9
  fieldset: {
10
10
  'config.collection': collection,
11
11
  'config.params': {