@nocobase/plugin-workflow-manual 1.0.0-alpha.2 → 1.0.0-alpha.3

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 (88) hide show
  1. package/dist/client/WorkflowTodo.d.ts +8 -0
  2. package/dist/client/WorkflowTodoBlockInitializer.d.ts +8 -0
  3. package/dist/client/index.d.ts +8 -0
  4. package/dist/client/index.js +9 -0
  5. package/dist/client/instruction/AssigneesSelect.d.ts +8 -0
  6. package/dist/client/instruction/FormBlockInitializer.d.ts +8 -0
  7. package/dist/client/instruction/FormBlockProvider.d.ts +8 -0
  8. package/dist/client/instruction/ModeConfig.d.ts +8 -0
  9. package/dist/client/instruction/SchemaConfig.d.ts +8 -0
  10. package/dist/client/instruction/createManualFormBlockUISchema.d.ts +8 -0
  11. package/dist/client/instruction/forms/create.d.ts +8 -0
  12. package/dist/client/instruction/forms/custom.d.ts +8 -0
  13. package/dist/client/instruction/forms/update.d.ts +8 -0
  14. package/dist/client/instruction/index.d.ts +8 -0
  15. package/dist/client/instruction/utils.d.ts +8 -0
  16. package/dist/externalVersion.js +18 -9
  17. package/dist/index.d.ts +8 -0
  18. package/dist/index.js +9 -0
  19. package/dist/locale/index.d.ts +8 -0
  20. package/dist/locale/index.js +9 -0
  21. package/dist/server/ManualInstruction.d.ts +8 -0
  22. package/dist/server/ManualInstruction.js +9 -0
  23. package/dist/server/Plugin.d.ts +8 -0
  24. package/dist/server/Plugin.js +9 -0
  25. package/dist/server/actions.d.ts +8 -0
  26. package/dist/server/actions.js +9 -0
  27. package/dist/server/collections/1-users_jobs.d.ts +8 -0
  28. package/dist/server/collections/1-users_jobs.js +9 -0
  29. package/dist/server/collections/2-jobs.d.ts +8 -0
  30. package/dist/server/collections/2-jobs.js +9 -0
  31. package/dist/server/collections/3-users.d.ts +8 -0
  32. package/dist/server/collections/3-users.js +9 -0
  33. package/dist/server/forms/create.d.ts +8 -0
  34. package/dist/server/forms/create.js +9 -0
  35. package/dist/server/forms/index.d.ts +8 -0
  36. package/dist/server/forms/index.js +9 -0
  37. package/dist/server/forms/update.d.ts +8 -0
  38. package/dist/server/forms/update.js +9 -0
  39. package/dist/server/index.d.ts +8 -0
  40. package/dist/server/index.js +9 -0
  41. package/dist/server/migrations/20240325213145-fix-schema.d.ts +8 -0
  42. package/dist/server/migrations/20240325213145-fix-schema.js +9 -0
  43. package/package.json +2 -2
  44. package/src/client/WorkflowTodo.tsx +0 -647
  45. package/src/client/WorkflowTodoBlockInitializer.tsx +0 -32
  46. package/src/client/__e2e__/assignees.test.ts +0 -0
  47. package/src/client/__e2e__/createRecordForm.test.ts +0 -2287
  48. package/src/client/__e2e__/customFormBlocks.test.ts +0 -1933
  49. package/src/client/__e2e__/datablocks.test.ts +0 -1208
  50. package/src/client/__e2e__/updateRecordForm.test.ts +0 -2338
  51. package/src/client/__e2e__/workflowTodo.test.ts +0 -242
  52. package/src/client/index.ts +0 -51
  53. package/src/client/instruction/AssigneesSelect.tsx +0 -39
  54. package/src/client/instruction/FormBlockInitializer.tsx +0 -79
  55. package/src/client/instruction/FormBlockProvider.tsx +0 -92
  56. package/src/client/instruction/ModeConfig.tsx +0 -85
  57. package/src/client/instruction/SchemaConfig.tsx +0 -659
  58. package/src/client/instruction/createManualFormBlockUISchema.ts +0 -5
  59. package/src/client/instruction/forms/create.tsx +0 -123
  60. package/src/client/instruction/forms/custom.tsx +0 -439
  61. package/src/client/instruction/forms/update.tsx +0 -167
  62. package/src/client/instruction/index.tsx +0 -160
  63. package/src/client/instruction/utils.ts +0 -19
  64. package/src/index.ts +0 -2
  65. package/src/locale/en-US.json +0 -30
  66. package/src/locale/index.ts +0 -14
  67. package/src/locale/ko_KR.json +0 -32
  68. package/src/locale/zh-CN.json +0 -32
  69. package/src/server/ManualInstruction.ts +0 -157
  70. package/src/server/Plugin.ts +0 -43
  71. package/src/server/__tests__/assignees.test.ts +0 -153
  72. package/src/server/__tests__/collections/categories.ts +0 -15
  73. package/src/server/__tests__/collections/comments.ts +0 -24
  74. package/src/server/__tests__/collections/posts.ts +0 -40
  75. package/src/server/__tests__/collections/replies.ts +0 -9
  76. package/src/server/__tests__/collections/tags.ts +0 -15
  77. package/src/server/__tests__/data-source.test.ts +0 -223
  78. package/src/server/__tests__/form.test.ts +0 -637
  79. package/src/server/__tests__/mode.test.ts +0 -561
  80. package/src/server/actions.ts +0 -103
  81. package/src/server/collections/1-users_jobs.ts +0 -52
  82. package/src/server/collections/2-jobs.ts +0 -19
  83. package/src/server/collections/3-users.ts +0 -17
  84. package/src/server/forms/create.ts +0 -30
  85. package/src/server/forms/index.ts +0 -13
  86. package/src/server/forms/update.ts +0 -30
  87. package/src/server/index.ts +0 -1
  88. package/src/server/migrations/20240325213145-fix-schema.ts +0 -82
@@ -1,242 +0,0 @@
1
- import { faker } from '@faker-js/faker';
2
- import {
3
- CollectionTriggerNode,
4
- ManualNode,
5
- apiCreateWorkflow,
6
- apiDeleteWorkflow,
7
- apiGetWorkflow,
8
- apiUpdateWorkflowTrigger,
9
- appendJsonCollectionName,
10
- generalWithNoRelationalFields,
11
- apiGetDataSourceCount,
12
- } from '@nocobase/plugin-workflow-test/e2e';
13
- import { expect, test } from '@nocobase/test/e2e';
14
- import { dayjs } from '@nocobase/utils';
15
-
16
- test('filter task node', async ({ page, mockPage, mockCollections, mockRecords }) => {
17
- //数据表后缀标识
18
- const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
19
- const manualNodeAppendText = 'b' + dayjs().format('HHmmss').toString();
20
-
21
- // 创建触发器节点数据表
22
- const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
23
- const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
24
- const triggerNodeFieldName = 'orgname';
25
- const triggerNodeFieldDisplayName = '公司名称(单行文本)';
26
- await mockCollections(
27
- appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
28
- .collections,
29
- );
30
- // 创建Manual节点数据表
31
- const manualNodeCollectionDisplayName = `自动>组织[普通表]${manualNodeAppendText}`;
32
- const manualNodeCollectionName = `tt_amt_org${manualNodeAppendText}`;
33
- const manualNodeFieldName = 'orgname';
34
- const manualNodeFieldDisplayName = '公司名称(单行文本)';
35
- await mockCollections(
36
- appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), manualNodeAppendText)
37
- .collections,
38
- );
39
- //添加工作流
40
- const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
41
- const workflowData = {
42
- current: true,
43
- options: { deleteExecutionOnStatus: [] },
44
- title: workFlowName,
45
- type: 'collection',
46
- enabled: true,
47
- };
48
- const workflow = await apiCreateWorkflow(workflowData);
49
- const workflowObj = JSON.parse(JSON.stringify(workflow));
50
- const workflowId = workflowObj.id;
51
- //配置工作流触发器
52
- const triggerNodeData = {
53
- config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
54
- };
55
- const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
56
- const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
57
- //配置Manual节点
58
- await page.goto(`admin/workflow/workflows/${workflowId}`);
59
- await page.waitForLoadState('networkidle');
60
- const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
61
- await collectionTriggerNode.addNodeButton.click();
62
- await page.getByRole('button', { name: 'manual', exact: true }).click();
63
- const manualNodeName = 'Manual' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
64
- await page.getByLabel('Manual-Manual', { exact: true }).getByRole('textbox').fill(manualNodeName);
65
- const manualNode = new ManualNode(page, manualNodeName);
66
- const manualNodeId = await manualNode.node.locator('.workflow-node-id').innerText();
67
- await manualNode.nodeConfigure.click();
68
- await manualNode.assigneesDropDown.click();
69
- await page.getByRole('option', { name: 'Super Admin' }).click();
70
- await manualNode.configureUserInterfaceButton.click();
71
- await manualNode.addBlockButton.hover();
72
- await manualNode.createRecordFormMenu.hover();
73
- const dataSourcesCount = await apiGetDataSourceCount();
74
- if (dataSourcesCount > 1) {
75
- await page.getByRole('menuitem', { name: 'Main right' }).hover();
76
- }
77
- await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
78
- await page.mouse.move(300, 0, { steps: 100 });
79
- await page
80
- .locator(`button[aria-label^="schema-initializer-Grid-form:configureFields-${manualNodeCollectionName}"]`)
81
- .hover();
82
- await page.getByLabel(`designer-schema-settings-CardItem-CreateFormDesigner-${manualNodeCollectionName}`).hover();
83
- await page.getByRole('menuitem', { name: 'Edit block title' }).click();
84
- const blockTitle = 'Create record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
85
- await page.getByLabel('Edit block title').getByRole('textbox').fill(blockTitle);
86
- await page.getByRole('button', { name: 'OK', exact: true }).click();
87
- await page
88
- .locator(`button[aria-label^="schema-initializer-Grid-form:configureFields-${manualNodeCollectionName}"]`)
89
- .hover();
90
- await page.getByRole('menuitem', { name: manualNodeFieldDisplayName }).getByRole('switch').click();
91
- await page.mouse.move(300, 0, { steps: 100 });
92
- await page.mouse.click(300, 0);
93
- await manualNode.submitButton.click();
94
- await page.waitForLoadState('networkidle');
95
-
96
- // 2、测试步骤:添加数据触发工作流
97
- const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
98
- const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
99
- { orgname: triggerNodeCollectionRecordOne },
100
- ]);
101
- await page.waitForTimeout(1000);
102
- // 3、预期结果:工作流成功触发,待办弹窗表单中显示数据
103
- const getWorkflow = await apiGetWorkflow(workflowId);
104
- const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
105
- const getWorkflowExecuted = getWorkflowObj.executed;
106
- expect(getWorkflowExecuted).toBe(1);
107
-
108
- const newPage = mockPage();
109
- await newPage.goto();
110
- await page.waitForLoadState('networkidle');
111
- await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
112
- await page.getByRole('menuitem', { name: 'check-square Workflow todos' }).click();
113
- await page.mouse.move(300, 0, { steps: 100 });
114
- await page.waitForTimeout(300);
115
- await page.getByLabel('action-Filter.Action-Filter-filter-users_jobs-workflow-todo').click();
116
- await page.getByText('Add condition', { exact: true }).click();
117
- await page.getByTestId('select-filter-field').click();
118
- await page.getByRole('menuitemcheckbox', { name: 'Task right' }).click();
119
- await page.getByRole('menuitemcheckbox', { name: 'Title' }).click();
120
- await page.getByRole('textbox').fill(manualNodeName);
121
- await page.getByRole('button', { name: 'Submit' }).click();
122
-
123
- // 3、预期结果:列表中出现筛选的工作流
124
- await expect(page.getByText(manualNodeName)).toBeAttached();
125
-
126
- // 4、后置处理:删除工作流
127
- await apiDeleteWorkflow(workflowId);
128
- });
129
-
130
- test('filter workflow name', async ({ page, mockPage, mockCollections, mockRecords }) => {
131
- //数据表后缀标识
132
- const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
133
- const manualNodeAppendText = 'b' + dayjs().format('HHmmss').toString();
134
-
135
- // 创建触发器节点数据表
136
- const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
137
- const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
138
- const triggerNodeFieldName = 'orgname';
139
- const triggerNodeFieldDisplayName = '公司名称(单行文本)';
140
- await mockCollections(
141
- appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
142
- .collections,
143
- );
144
- // 创建Manual节点数据表
145
- const manualNodeCollectionDisplayName = `自动>组织[普通表]${manualNodeAppendText}`;
146
- const manualNodeCollectionName = `tt_amt_org${manualNodeAppendText}`;
147
- const manualNodeFieldName = 'orgname';
148
- const manualNodeFieldDisplayName = '公司名称(单行文本)';
149
- await mockCollections(
150
- appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), manualNodeAppendText)
151
- .collections,
152
- );
153
- //添加工作流
154
- const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
155
- const workflowData = {
156
- current: true,
157
- options: { deleteExecutionOnStatus: [] },
158
- title: workFlowName,
159
- type: 'collection',
160
- enabled: true,
161
- };
162
- const workflow = await apiCreateWorkflow(workflowData);
163
- const workflowObj = JSON.parse(JSON.stringify(workflow));
164
- const workflowId = workflowObj.id;
165
- //配置工作流触发器
166
- const triggerNodeData = {
167
- config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
168
- };
169
- const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
170
- const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
171
- //配置Manual节点
172
- await page.goto(`admin/workflow/workflows/${workflowId}`);
173
- await page.waitForLoadState('networkidle');
174
- const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
175
- await collectionTriggerNode.addNodeButton.click();
176
- await page.getByRole('button', { name: 'manual', exact: true }).click();
177
- const manualNodeName = 'Manual' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
178
- await page.getByLabel('Manual-Manual', { exact: true }).getByRole('textbox').fill(manualNodeName);
179
- const manualNode = new ManualNode(page, manualNodeName);
180
- const manualNodeId = await manualNode.node.locator('.workflow-node-id').innerText();
181
- await manualNode.nodeConfigure.click();
182
- await manualNode.assigneesDropDown.click();
183
- await page.getByRole('option', { name: 'Super Admin' }).click();
184
- await manualNode.configureUserInterfaceButton.click();
185
- await manualNode.addBlockButton.hover();
186
- await manualNode.createRecordFormMenu.hover();
187
- const dataSourcesCount = await apiGetDataSourceCount();
188
- if (dataSourcesCount > 1) {
189
- await page.getByRole('menuitem', { name: 'Main right' }).hover();
190
- }
191
- await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
192
- await page.mouse.move(300, 0, { steps: 100 });
193
- await page
194
- .locator(`button[aria-label^="schema-initializer-Grid-form:configureFields-${manualNodeCollectionName}"]`)
195
- .hover();
196
- await page.getByLabel(`designer-schema-settings-CardItem-CreateFormDesigner-${manualNodeCollectionName}`).hover();
197
- await page.getByRole('menuitem', { name: 'Edit block title' }).click();
198
- const blockTitle = 'Create record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
199
- await page.getByLabel('Edit block title').getByRole('textbox').fill(blockTitle);
200
- await page.getByRole('button', { name: 'OK', exact: true }).click();
201
- await page
202
- .locator(`button[aria-label^="schema-initializer-Grid-form:configureFields-${manualNodeCollectionName}"]`)
203
- .hover();
204
- await page.getByRole('menuitem', { name: manualNodeFieldDisplayName }).getByRole('switch').click();
205
- await page.mouse.move(300, 0, { steps: 100 });
206
- await page.mouse.click(300, 0);
207
- await manualNode.submitButton.click();
208
- await page.waitForLoadState('networkidle');
209
-
210
- // 2、测试步骤:添加数据触发工作流
211
- const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
212
- const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
213
- { orgname: triggerNodeCollectionRecordOne },
214
- ]);
215
- await page.waitForTimeout(1000);
216
- // 3、预期结果:工作流成功触发,待办弹窗表单中显示数据
217
- const getWorkflow = await apiGetWorkflow(workflowId);
218
- const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
219
- const getWorkflowExecuted = getWorkflowObj.executed;
220
- expect(getWorkflowExecuted).toBe(1);
221
-
222
- const newPage = mockPage();
223
- await newPage.goto();
224
- await page.waitForLoadState('networkidle');
225
- await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
226
- await page.getByRole('menuitem', { name: 'check-square Workflow todos' }).click();
227
- await page.mouse.move(300, 0, { steps: 100 });
228
- await page.waitForTimeout(300);
229
- await page.getByLabel('action-Filter.Action-Filter-filter-users_jobs-workflow-todo').click();
230
- await page.getByText('Add condition', { exact: true }).click();
231
- await page.getByTestId('select-filter-field').click();
232
- await page.getByRole('menuitemcheckbox', { name: 'Workflow right' }).click();
233
- await page.getByRole('menuitemcheckbox', { name: 'Name' }).click();
234
- await page.getByRole('textbox').fill(workFlowName);
235
- await page.getByRole('button', { name: 'Submit' }).click();
236
-
237
- // 3、预期结果:列表中出现筛选的工作流
238
- await expect(page.getByText(manualNodeName)).toBeAttached();
239
-
240
- // 4、后置处理:删除工作流
241
- await apiDeleteWorkflow(workflowId);
242
- });
@@ -1,51 +0,0 @@
1
- import { Plugin } from '@nocobase/client';
2
- import WorkflowPlugin from '@nocobase/plugin-workflow/client';
3
-
4
- import Manual from './instruction';
5
-
6
- import { NAMESPACE } from '../locale';
7
- import { WorkflowTodo } from './WorkflowTodo';
8
- import { WorkflowTodoBlockInitializer } from './WorkflowTodoBlockInitializer';
9
- import {
10
- addActionButton,
11
- addActionButton_deprecated,
12
- addBlockButton,
13
- addBlockButton_deprecated,
14
- } from './instruction/SchemaConfig';
15
- import { addCustomFormField, addCustomFormField_deprecated } from './instruction/forms/custom';
16
-
17
- export default class extends Plugin {
18
- async afterAdd() {
19
- // await this.app.pm.add()
20
- }
21
-
22
- // You can get and modify the app instance here
23
- async load() {
24
- this.addComponents();
25
-
26
- // this.app.addProvider(Provider);
27
- const workflow = this.app.pm.get('workflow') as WorkflowPlugin;
28
- workflow.registerInstruction('manual', Manual);
29
-
30
- this.app.schemaInitializerManager.add(addBlockButton_deprecated);
31
- this.app.schemaInitializerManager.add(addBlockButton);
32
- this.app.schemaInitializerManager.add(addActionButton_deprecated);
33
- this.app.schemaInitializerManager.add(addActionButton);
34
- this.app.schemaInitializerManager.add(addCustomFormField_deprecated);
35
- this.app.schemaInitializerManager.add(addCustomFormField);
36
-
37
- const blockInitializers = this.app.schemaInitializerManager.get('page:addBlock');
38
- blockInitializers.add('otherBlocks.workflowTodos', {
39
- title: `{{t("Workflow todos", { ns: "${NAMESPACE}" })}}`,
40
- Component: 'WorkflowTodoBlockInitializer',
41
- icon: 'CheckSquareOutlined',
42
- });
43
- }
44
-
45
- addComponents() {
46
- this.app.addComponents({
47
- WorkflowTodo,
48
- WorkflowTodoBlockInitializer,
49
- });
50
- }
51
- }
@@ -1,39 +0,0 @@
1
- import React from 'react';
2
- import { RemoteSelect, Variable } from '@nocobase/client';
3
- import { useWorkflowVariableOptions } from '@nocobase/plugin-workflow/client';
4
-
5
- function isUserKeyField(field) {
6
- if (field.isForeignKey) {
7
- return field.target === 'users';
8
- }
9
- return field.collectionName === 'users' && field.name === 'id';
10
- }
11
-
12
- export function AssigneesSelect({ multiple = false, value = [], onChange }) {
13
- const scope = useWorkflowVariableOptions({ types: [isUserKeyField] });
14
-
15
- return (
16
- <Variable.Input
17
- scope={scope}
18
- value={value[0]}
19
- onChange={(next) => {
20
- onChange([next]);
21
- }}
22
- >
23
- <RemoteSelect
24
- fieldNames={{
25
- label: 'nickname',
26
- value: 'id',
27
- }}
28
- service={{
29
- resource: 'users',
30
- }}
31
- manual={false}
32
- value={value[0]}
33
- onChange={(v) => {
34
- onChange(v != null ? [v] : []);
35
- }}
36
- />
37
- </Variable.Input>
38
- );
39
- }
@@ -1,79 +0,0 @@
1
- import React from 'react';
2
-
3
- import {
4
- CollectionProvider_deprecated,
5
- SchemaInitializerItem,
6
- SchemaInitializerItemType,
7
- useRecordCollectionDataSourceItems,
8
- useSchemaInitializer,
9
- useSchemaInitializerItem,
10
- useSchemaTemplateManager,
11
- } from '@nocobase/client';
12
-
13
- import { JOB_STATUS, traverseSchema } from '@nocobase/plugin-workflow/client';
14
-
15
- import { NAMESPACE } from '../../locale';
16
- import { createManualFormBlockUISchema } from './createManualFormBlockUISchema';
17
-
18
- function InternalFormBlockInitializer({ schema, ...others }) {
19
- const { getTemplateSchemaByMode } = useSchemaTemplateManager();
20
- const { insert } = useSchemaInitializer();
21
- const items = useRecordCollectionDataSourceItems('FormItem') as SchemaInitializerItemType[];
22
- async function onConfirm({ item }) {
23
- const template = item.template ? await getTemplateSchemaByMode(item) : null;
24
- const result = createManualFormBlockUISchema({
25
- actionInitializers: 'workflowManual:form:configureActions',
26
- actions: {
27
- resolve: {
28
- type: 'void',
29
- title: `{{t("Continue the process", { ns: "${NAMESPACE}" })}}`,
30
- 'x-decorator': 'ManualActionStatusProvider',
31
- 'x-decorator-props': {
32
- value: JOB_STATUS.RESOLVED,
33
- },
34
- 'x-component': 'Action',
35
- 'x-component-props': {
36
- type: 'primary',
37
- useAction: '{{ useSubmit }}',
38
- },
39
- 'x-designer': 'ManualActionDesigner',
40
- 'x-designer-props': {},
41
- },
42
- },
43
- ...schema,
44
- template,
45
- });
46
- delete result['x-acl-action-props'];
47
- delete result['x-acl-action'];
48
- const [formKey] = Object.keys(result.properties);
49
- //获取actionBar的schemakey
50
- const actionKey =
51
- Object.entries(result.properties[formKey].properties).find(([key, f]) => f['x-component'] === 'ActionBar')?.[0] ||
52
- 'actions';
53
- result.properties[formKey].properties[actionKey]['x-decorator'] = 'ActionBarProvider';
54
- result.properties[formKey].properties[actionKey]['x-component-props'].style = {
55
- marginTop: '1.5em',
56
- flexWrap: 'wrap',
57
- };
58
- traverseSchema(result, (node) => {
59
- if (node['x-uid']) {
60
- delete node['x-uid'];
61
- }
62
- });
63
- insert(result);
64
- }
65
-
66
- return <SchemaInitializerItem {...others} onClick={onConfirm} items={items} />;
67
- }
68
-
69
- export function FormBlockInitializer() {
70
- const itemConfig = useSchemaInitializerItem();
71
- return (
72
- <CollectionProvider_deprecated
73
- dataSource={itemConfig.schema?.dataSource}
74
- collection={itemConfig.schema?.collection}
75
- >
76
- <InternalFormBlockInitializer {...itemConfig} />
77
- </CollectionProvider_deprecated>
78
- );
79
- }
@@ -1,92 +0,0 @@
1
- import { createForm } from '@formily/core';
2
- import { useField, useFieldSchema } from '@formily/react';
3
- import {
4
- BlockRequestContext_deprecated,
5
- CollectionManagerProvider,
6
- CollectionProvider_deprecated,
7
- DEFAULT_DATA_SOURCE_KEY,
8
- FormActiveFieldsProvider,
9
- FormBlockContext,
10
- FormV2,
11
- RecordProvider,
12
- useAPIClient,
13
- useAssociationNames,
14
- useBlockRequestContext,
15
- useDataSourceHeaders,
16
- useDesignable,
17
- useRecord,
18
- } from '@nocobase/client';
19
- import React, { useMemo, useRef } from 'react';
20
-
21
- export function FormBlockProvider(props) {
22
- const userJob = useRecord();
23
- const fieldSchema = useFieldSchema();
24
- const field = useField();
25
- const formBlockRef = useRef(null);
26
- const dataSource = props.dataSource || DEFAULT_DATA_SOURCE_KEY;
27
-
28
- const { getAssociationAppends } = useAssociationNames(dataSource);
29
- const { appends, updateAssociationValues } = getAssociationAppends();
30
- const [formKey] = Object.keys(fieldSchema.toJSON().properties ?? {});
31
- const values = userJob?.result?.[formKey];
32
-
33
- const { findComponent } = useDesignable();
34
-
35
- const form = useMemo(
36
- () =>
37
- createForm({
38
- initialValues: values,
39
- }),
40
- [values],
41
- );
42
-
43
- const params = useMemo(() => {
44
- return {
45
- appends,
46
- ...props.params,
47
- };
48
- }, [appends, props.params]);
49
- const service = useMemo(() => {
50
- return {
51
- loading: false,
52
- data: {
53
- data: values,
54
- },
55
- };
56
- }, [values]);
57
- const api = useAPIClient();
58
- const headers = useDataSourceHeaders(dataSource);
59
-
60
- const resource = api.resource(props.collection, undefined, headers);
61
- const __parent = useBlockRequestContext();
62
-
63
- const formBlockValue = useMemo(() => {
64
- return {
65
- params,
66
- form,
67
- field,
68
- service,
69
- updateAssociationValues,
70
- formBlockRef,
71
- };
72
- }, [field, form, params, service, updateAssociationValues]);
73
-
74
- return !userJob.status || values ? (
75
- <CollectionManagerProvider dataSource={dataSource}>
76
- <CollectionProvider_deprecated collection={props.collection}>
77
- <RecordProvider record={values} parent={null}>
78
- <FormActiveFieldsProvider name="form">
79
- <BlockRequestContext_deprecated.Provider
80
- value={{ block: 'form', props, field, service, resource, __parent }}
81
- >
82
- <FormBlockContext.Provider value={formBlockValue}>
83
- <FormV2.Templates style={{ marginBottom: 18 }} form={form} />
84
- <div ref={formBlockRef}>{props.children}</div>
85
- </FormBlockContext.Provider>
86
- </BlockRequestContext_deprecated.Provider>
87
- </FormActiveFieldsProvider>
88
- </RecordProvider>
89
- </CollectionProvider_deprecated>
90
- </CollectionManagerProvider>
91
- ) : null;
92
- }
@@ -1,85 +0,0 @@
1
- import { QuestionCircleOutlined } from '@ant-design/icons';
2
- import { FormLayout } from '@formily/antd-v5';
3
- import { Form, Radio, Tooltip } from 'antd';
4
- import React from 'react';
5
-
6
- import { css, FormItem } from '@nocobase/client';
7
- import { useLang } from '../../locale';
8
-
9
- function parseMode(v) {
10
- if (!v) {
11
- return 'single';
12
- }
13
- if (v >= 1) {
14
- return 'all';
15
- }
16
- if (v <= -1) {
17
- return 'any';
18
- }
19
-
20
- const dir = Math.sign(v);
21
- if (dir > 0) {
22
- return '';
23
- }
24
- }
25
-
26
- export function ModeConfig({ value, onChange }) {
27
- const mode = parseMode(value);
28
- const negotiationFieldset = (
29
- <fieldset>
30
- <FormLayout layout="vertical">
31
- <FormItem label={useLang('Negotiation')}>
32
- <Radio.Group value={value} onChange={onChange}>
33
- <Radio value={1}>
34
- <Tooltip title={useLang('Everyone should pass')} placement="bottom">
35
- <span>{useLang('All pass')}</span>
36
- <QuestionCircleOutlined style={{ color: '#999' }} />
37
- </Tooltip>
38
- </Radio>
39
- <Radio value={-1}>
40
- <Tooltip title={useLang('Anyone pass')} placement="bottom">
41
- <span>{useLang('Any pass')}</span>
42
- <QuestionCircleOutlined style={{ color: '#999' }} />
43
- </Tooltip>
44
- </Radio>
45
- </Radio.Group>
46
- </FormItem>
47
- </FormLayout>
48
- </fieldset>
49
- );
50
- return (
51
- <fieldset
52
- className={css`
53
- .ant-radio-group {
54
- .anticon {
55
- margin-left: 0.5em;
56
- }
57
- }
58
- `}
59
- >
60
- <Form.Item>
61
- <Radio.Group
62
- value={Boolean(value)}
63
- onChange={({ target: { value: v } }) => {
64
- console.log(v);
65
- onChange(Number(v));
66
- }}
67
- >
68
- <Radio value={true}>
69
- <Tooltip title={useLang('Each user has own task')} placement="bottom">
70
- <span>{useLang('Separately')}</span>
71
- <QuestionCircleOutlined style={{ color: '#999' }} />
72
- </Tooltip>
73
- </Radio>
74
- <Radio value={false}>
75
- <Tooltip title={useLang('Everyone shares one task')} placement="bottom">
76
- <span>{useLang('Collaboratively')}</span>
77
- <QuestionCircleOutlined style={{ color: '#999' }} />
78
- </Tooltip>
79
- </Radio>
80
- </Radio.Group>
81
- </Form.Item>
82
- {value ? negotiationFieldset : null}
83
- </fieldset>
84
- );
85
- }