@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,659 +0,0 @@
1
- import { FormLayout } from '@formily/antd-v5';
2
- import { createForm } from '@formily/core';
3
- import { FormProvider, ISchema, Schema, useFieldSchema, useForm } from '@formily/react';
4
- import { Alert, Button, Modal, Space, message } from 'antd';
5
- import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
6
- import { useTranslation } from 'react-i18next';
7
-
8
- import {
9
- Action,
10
- ActionContextProvider,
11
- CompatibleSchemaInitializer,
12
- DefaultValueProvider,
13
- FormActiveFieldsProvider,
14
- GeneralSchemaDesigner,
15
- InitializerWithSwitch,
16
- SchemaComponent,
17
- SchemaComponentContext,
18
- SchemaInitializerItem,
19
- SchemaInitializerItemType,
20
- SchemaSettingsDivider,
21
- SchemaSettingsItem,
22
- SchemaSettingsRemove,
23
- VariableScopeProvider,
24
- css,
25
- gridRowColWrap,
26
- useDataSourceManager,
27
- useFormActiveFields,
28
- useFormBlockContext,
29
- usePlugin,
30
- useSchemaInitializer,
31
- useSchemaInitializerItem,
32
- useSchemaOptionsContext,
33
- } from '@nocobase/client';
34
- import WorkflowPlugin, {
35
- DetailsBlockProvider,
36
- JOB_STATUS,
37
- SimpleDesigner,
38
- useAvailableUpstreams,
39
- useFlowContext,
40
- useNodeContext,
41
- useTrigger,
42
- useWorkflowVariableOptions,
43
- } from '@nocobase/plugin-workflow/client';
44
- import { Registry, lodash } from '@nocobase/utils/client';
45
-
46
- import { NAMESPACE, usePluginTranslation } from '../../locale';
47
- import { FormBlockProvider } from './FormBlockProvider';
48
- import createRecordForm from './forms/create';
49
- import customRecordForm from './forms/custom';
50
- import updateRecordForm from './forms/update';
51
-
52
- type ValueOf<T> = T[keyof T];
53
-
54
- export type FormType = {
55
- type: 'create' | 'update' | 'custom';
56
- title: string;
57
- actions: ValueOf<typeof JOB_STATUS>[];
58
- collection:
59
- | string
60
- | {
61
- name: string;
62
- fields: any[];
63
- [key: string]: any;
64
- };
65
- };
66
-
67
- export type ManualFormType = {
68
- title: string;
69
- config: {
70
- useInitializer: ({ allCollections }?: { allCollections: any[] }) => SchemaInitializerItemType;
71
- initializers?: {
72
- [key: string]: React.FC;
73
- };
74
- components?: {
75
- [key: string]: React.FC;
76
- };
77
- parseFormOptions(root: ISchema): { [key: string]: FormType };
78
- };
79
- block: {
80
- scope?: {
81
- [key: string]: () => any;
82
- };
83
- components?: {
84
- [key: string]: React.FC;
85
- };
86
- };
87
- validate?: (config: any) => string | null;
88
- };
89
-
90
- export const manualFormTypes = new Registry<ManualFormType>();
91
-
92
- manualFormTypes.register('custom', customRecordForm);
93
- manualFormTypes.register('create', createRecordForm);
94
- manualFormTypes.register('update', updateRecordForm);
95
-
96
- function useTriggerInitializers(): SchemaInitializerItemType | null {
97
- const { workflow } = useFlowContext();
98
- const trigger = useTrigger();
99
- return trigger.useInitializers ? trigger.useInitializers(workflow.config) : null;
100
- }
101
-
102
- const blockTypeNames = {
103
- customForm: customRecordForm.title,
104
- record: `{{t("Data record", { ns: "${NAMESPACE}" })}}`,
105
- };
106
-
107
- /**
108
- * @deprecated
109
- * use `addBlockButton` instead
110
- */
111
- export const addBlockButton_deprecated = new CompatibleSchemaInitializer({
112
- name: 'AddBlockButton',
113
- wrap: gridRowColWrap,
114
- title: '{{t("Add block")}}',
115
- items: [
116
- {
117
- type: 'itemGroup',
118
- name: 'dataBlocks',
119
- title: '{{t("Data blocks")}}',
120
- hideIfNoChildren: true,
121
- useChildren() {
122
- const workflowPlugin = usePlugin(WorkflowPlugin);
123
- const current = useNodeContext();
124
- const nodes = useAvailableUpstreams(current);
125
- const triggerInitializers = [useTriggerInitializers()].filter(Boolean);
126
- const nodeBlockInitializers = nodes
127
- .map((node) => {
128
- const instruction = workflowPlugin.instructions.get(node.type);
129
- return instruction?.useInitializers?.(node);
130
- })
131
- .filter(Boolean);
132
- const dataBlockInitializers: any = [
133
- ...triggerInitializers,
134
- ...(nodeBlockInitializers.length
135
- ? [
136
- {
137
- name: 'nodes',
138
- type: 'subMenu',
139
- title: `{{t("Node result", { ns: "workflow" })}}`,
140
- children: nodeBlockInitializers,
141
- },
142
- ]
143
- : []),
144
- ].filter(Boolean);
145
- return dataBlockInitializers;
146
- },
147
- },
148
- {
149
- type: 'itemGroup',
150
- name: 'form',
151
- title: '{{t("Form")}}',
152
- useChildren() {
153
- const dm = useDataSourceManager();
154
- const allCollections = dm.getAllCollections();
155
- return Array.from(manualFormTypes.getValues()).map((item: ManualFormType) => {
156
- const { useInitializer: getInitializer } = item.config;
157
- return getInitializer({ allCollections });
158
- });
159
- },
160
- },
161
- {
162
- type: 'itemGroup',
163
- name: 'otherBlocks',
164
- title: '{{t("Other blocks")}}',
165
- children: [
166
- {
167
- name: 'markdown',
168
- title: '{{t("Markdown")}}',
169
- Component: 'MarkdownBlockInitializer',
170
- },
171
- ],
172
- },
173
- ],
174
- });
175
-
176
- export const addBlockButton = new CompatibleSchemaInitializer(
177
- {
178
- name: 'workflowManual:popup:configureUserInterface:addBlock',
179
- wrap: gridRowColWrap,
180
- title: '{{t("Add block")}}',
181
- items: [
182
- {
183
- type: 'itemGroup',
184
- name: 'dataBlocks',
185
- title: '{{t("Data blocks")}}',
186
- hideIfNoChildren: true,
187
- useChildren() {
188
- const workflowPlugin = usePlugin(WorkflowPlugin);
189
- const current = useNodeContext();
190
- const nodes = useAvailableUpstreams(current);
191
- const triggerInitializers = [useTriggerInitializers()].filter(Boolean);
192
- const nodeBlockInitializers = nodes
193
- .map((node) => {
194
- const instruction = workflowPlugin.instructions.get(node.type);
195
- return instruction?.useInitializers?.(node);
196
- })
197
- .filter(Boolean);
198
- const dataBlockInitializers: any = [
199
- ...triggerInitializers,
200
- ...(nodeBlockInitializers.length
201
- ? [
202
- {
203
- name: 'nodes',
204
- type: 'subMenu',
205
- title: `{{t("Node result", { ns: "${NAMESPACE}" })}}`,
206
- children: nodeBlockInitializers,
207
- },
208
- ]
209
- : []),
210
- ].filter(Boolean);
211
- return dataBlockInitializers;
212
- },
213
- },
214
- {
215
- type: 'itemGroup',
216
- name: 'form',
217
- title: '{{t("Form")}}',
218
- useChildren() {
219
- const dm = useDataSourceManager();
220
- const allCollections = dm.getAllCollections();
221
- return Array.from(manualFormTypes.getValues()).map((item: ManualFormType) => {
222
- const { useInitializer: getInitializer } = item.config;
223
- return getInitializer({ allCollections });
224
- });
225
- },
226
- },
227
- {
228
- type: 'itemGroup',
229
- name: 'otherBlocks',
230
- title: '{{t("Other blocks")}}',
231
- children: [
232
- {
233
- name: 'markdown',
234
- title: '{{t("Markdown")}}',
235
- Component: 'MarkdownBlockInitializer',
236
- },
237
- ],
238
- },
239
- ],
240
- },
241
- addBlockButton_deprecated,
242
- );
243
-
244
- function AssignedFieldValues() {
245
- const ctx = useContext(SchemaComponentContext);
246
- const { t: coreT } = useTranslation();
247
- const { t } = usePluginTranslation();
248
- const fieldSchema = useFieldSchema();
249
- const scope = useWorkflowVariableOptions();
250
- const [open, setOpen] = useState(false);
251
- const [initialSchema, setInitialSchema] = useState(
252
- fieldSchema?.['x-action-settings']?.assignedValues?.schema ?? {
253
- type: 'void',
254
- 'x-component': 'Grid',
255
- 'x-initializer': 'assignFieldValuesForm:configureFields',
256
- properties: {},
257
- },
258
- );
259
- const [schema, setSchema] = useState<Schema>(null);
260
- const { components } = useSchemaOptionsContext();
261
- useEffect(() => {
262
- setSchema(
263
- new Schema({
264
- properties: {
265
- grid: initialSchema,
266
- },
267
- }),
268
- );
269
- }, [initialSchema]);
270
- const form = useMemo(() => {
271
- const initialValues = fieldSchema?.['x-action-settings']?.assignedValues?.values;
272
- return createForm({
273
- initialValues: lodash.cloneDeep(initialValues),
274
- values: lodash.cloneDeep(initialValues),
275
- });
276
- }, [fieldSchema]);
277
- const upLevelActiveFields = useFormActiveFields();
278
-
279
- const title = coreT('Assign field values');
280
-
281
- function onCancel() {
282
- setOpen(false);
283
- }
284
-
285
- function onSubmit() {
286
- if (!fieldSchema['x-action-settings']) {
287
- fieldSchema['x-action-settings'] = {};
288
- }
289
- if (!fieldSchema['x-action-settings'].assignedValues) {
290
- fieldSchema['x-action-settings'].assignedValues = {};
291
- }
292
- fieldSchema['x-action-settings'].assignedValues.schema = initialSchema;
293
- fieldSchema['x-action-settings'].assignedValues.values = form.values;
294
- setOpen(false);
295
- setTimeout(() => {
296
- ctx.refresh?.();
297
- }, 300);
298
- }
299
-
300
- return (
301
- <>
302
- <SchemaSettingsItem title={title} onClick={() => setOpen(true)}>
303
- {title}
304
- </SchemaSettingsItem>
305
- <Modal
306
- width={'50%'}
307
- title={title}
308
- open={open}
309
- onCancel={onCancel}
310
- footer={
311
- <Space>
312
- <Button onClick={onCancel}>{t('Cancel')}</Button>
313
- <Button type="primary" onClick={onSubmit}>
314
- {t('Submit')}
315
- </Button>
316
- </Space>
317
- }
318
- >
319
- <DefaultValueProvider isAllowToSetDefaultValue={() => false}>
320
- <VariableScopeProvider scope={scope}>
321
- <FormActiveFieldsProvider name="form" getActiveFieldsName={upLevelActiveFields?.getActiveFieldsName}>
322
- <FormProvider form={form}>
323
- <FormLayout layout={'vertical'}>
324
- <Alert
325
- message={t('Values preset in this form will override user submitted ones when continue or reject.')}
326
- />
327
- <br />
328
- {open && schema && (
329
- <SchemaComponentContext.Provider
330
- value={{
331
- ...ctx,
332
- refresh() {
333
- setInitialSchema(lodash.get(schema.toJSON(), 'properties.grid'));
334
- },
335
- }}
336
- >
337
- <SchemaComponent schema={schema} components={components} />
338
- </SchemaComponentContext.Provider>
339
- )}
340
- </FormLayout>
341
- </FormProvider>
342
- </FormActiveFieldsProvider>
343
- </VariableScopeProvider>
344
- </DefaultValueProvider>
345
- </Modal>
346
- </>
347
- );
348
- }
349
-
350
- function ManualActionDesigner(props) {
351
- return (
352
- <GeneralSchemaDesigner {...props} disableInitializer>
353
- <Action.Designer.ButtonEditor />
354
- <AssignedFieldValues />
355
- <SchemaSettingsDivider />
356
- <SchemaSettingsRemove
357
- removeParentsIfNoChildren
358
- breakRemoveOn={{
359
- 'x-component': 'ActionBar',
360
- }}
361
- />
362
- </GeneralSchemaDesigner>
363
- );
364
- }
365
-
366
- function ContinueInitializer() {
367
- const itemConfig = useSchemaInitializerItem();
368
- const { action, actionProps, ...others } = itemConfig;
369
- const { insert } = useSchemaInitializer();
370
- return (
371
- <SchemaInitializerItem
372
- {...others}
373
- onClick={() => {
374
- insert({
375
- type: 'void',
376
- title: others.title,
377
- 'x-decorator': 'ManualActionStatusProvider',
378
- 'x-decorator-props': {
379
- value: action,
380
- },
381
- 'x-component': 'Action',
382
- 'x-component-props': {
383
- ...actionProps,
384
- useAction: '{{ useSubmit }}',
385
- },
386
- 'x-designer': 'ManualActionDesigner',
387
- 'x-action-settings': {},
388
- });
389
- }}
390
- />
391
- );
392
- }
393
-
394
- function ActionInitializer() {
395
- const itemConfig = useSchemaInitializerItem();
396
- const { action, actionProps, ...others } = itemConfig;
397
- return (
398
- <InitializerWithSwitch
399
- {...others}
400
- item={itemConfig}
401
- schema={{
402
- type: 'void',
403
- title: others.title,
404
- 'x-decorator': 'ManualActionStatusProvider',
405
- 'x-decorator-props': {
406
- value: action,
407
- },
408
- 'x-component': 'Action',
409
- 'x-component-props': {
410
- ...actionProps,
411
- useAction: '{{ useSubmit }}',
412
- },
413
- 'x-designer': 'Action.Designer',
414
- 'x-action': `${action}`,
415
- }}
416
- type="x-action"
417
- />
418
- );
419
- }
420
-
421
- /**
422
- * @deprecated
423
- * use `addActionButton` instead
424
- */
425
- export const addActionButton_deprecated = new CompatibleSchemaInitializer({
426
- name: 'AddActionButton',
427
- title: '{{t("Configure actions")}}',
428
- items: [
429
- {
430
- name: 'jobStatusResolved',
431
- title: `{{t("Continue the process", { ns: "${NAMESPACE}" })}}`,
432
- Component: ContinueInitializer,
433
- action: JOB_STATUS.RESOLVED,
434
- actionProps: {
435
- type: 'primary',
436
- },
437
- },
438
- {
439
- name: 'jobStatusRejected',
440
- title: `{{t("Terminate the process", { ns: "${NAMESPACE}" })}}`,
441
- Component: ActionInitializer,
442
- action: JOB_STATUS.REJECTED,
443
- actionProps: {
444
- danger: true,
445
- },
446
- },
447
- {
448
- name: 'jobStatusPending',
449
- title: `{{t("Save temporarily", { ns: "${NAMESPACE}" })}}`,
450
- Component: ActionInitializer,
451
- action: JOB_STATUS.PENDING,
452
- },
453
- ],
454
- });
455
-
456
- export const addActionButton = new CompatibleSchemaInitializer(
457
- {
458
- name: 'workflowManual:form:configureActions',
459
- title: '{{t("Configure actions")}}',
460
- items: [
461
- {
462
- name: 'jobStatusResolved',
463
- title: `{{t("Continue the process", { ns: "${NAMESPACE}" })}}`,
464
- Component: ContinueInitializer,
465
- action: JOB_STATUS.RESOLVED,
466
- actionProps: {
467
- type: 'primary',
468
- },
469
- },
470
- {
471
- name: 'jobStatusRejected',
472
- title: `{{t("Terminate the process", { ns: "${NAMESPACE}" })}}`,
473
- Component: ActionInitializer,
474
- action: JOB_STATUS.REJECTED,
475
- actionProps: {
476
- danger: true,
477
- },
478
- },
479
- {
480
- name: 'jobStatusPending',
481
- title: `{{t("Save temporarily", { ns: "${NAMESPACE}" })}}`,
482
- Component: ActionInitializer,
483
- action: JOB_STATUS.PENDING,
484
- },
485
- ],
486
- },
487
- addActionButton_deprecated,
488
- );
489
-
490
- // NOTE: fake useAction for ui configuration
491
- function useSubmit() {
492
- // const { values, submit, id: formId } = useForm();
493
- // const formSchema = useFieldSchema();
494
- return {
495
- run() {},
496
- };
497
- }
498
-
499
- export function SchemaConfig({ value, onChange }) {
500
- const workflowPlugin = usePlugin(WorkflowPlugin);
501
- const ctx = useContext(SchemaComponentContext);
502
- const node = useNodeContext();
503
- const nodes = useAvailableUpstreams(node);
504
- const form = useForm();
505
- const { workflow } = useFlowContext();
506
-
507
- const nodeComponents = {};
508
- nodes.forEach((item) => {
509
- const instruction = workflowPlugin.instructions.get(item.type);
510
- Object.assign(nodeComponents, instruction.components);
511
- });
512
-
513
- const schema = useMemo(
514
- () =>
515
- new Schema({
516
- properties: {
517
- drawer: {
518
- type: 'void',
519
- title: `{{t("User interface", { ns: "${NAMESPACE}" })}}`,
520
- 'x-decorator': 'Form',
521
- 'x-component': 'Action.Drawer',
522
- 'x-component-props': {
523
- className: css`
524
- .ant-drawer-body {
525
- background: var(--nb-box-bg);
526
- }
527
- `,
528
- },
529
- properties: {
530
- tabs: {
531
- type: 'void',
532
- 'x-component': 'Tabs',
533
- 'x-component-props': {},
534
- 'x-initializer': 'popup:addTab',
535
- 'x-initializer-props': {
536
- gridInitializer: 'workflowManual:popup:configureUserInterface:addBlock',
537
- },
538
- properties: value ?? {
539
- tab1: {
540
- type: 'void',
541
- title: `{{t("Manual", { ns: "${NAMESPACE}" })}}`,
542
- 'x-component': 'Tabs.TabPane',
543
- 'x-designer': 'Tabs.Designer',
544
- properties: {
545
- grid: {
546
- type: 'void',
547
- 'x-component': 'Grid',
548
- 'x-initializer': 'workflowManual:popup:configureUserInterface:addBlock',
549
- properties: {},
550
- },
551
- },
552
- },
553
- },
554
- },
555
- },
556
- },
557
- },
558
- }),
559
- [],
560
- );
561
-
562
- const refresh = useCallback(
563
- function refresh() {
564
- // ctx.refresh?.();
565
- const { tabs } = lodash.get(schema.toJSON(), 'properties.drawer.properties') as { tabs: ISchema };
566
- const forms = Array.from(manualFormTypes.getValues()).reduce(
567
- (result, item: ManualFormType) => Object.assign(result, item.config.parseFormOptions(tabs)),
568
- {},
569
- );
570
- form.setValuesIn('forms', forms);
571
-
572
- onChange(tabs.properties);
573
- },
574
- [form, onChange, schema],
575
- );
576
-
577
- return (
578
- <SchemaComponentContext.Provider
579
- value={{
580
- ...ctx,
581
- designable: !workflow.executed,
582
- refresh,
583
- }}
584
- >
585
- <SchemaComponent
586
- schema={schema}
587
- components={{
588
- ...nodeComponents,
589
- // @ts-ignore
590
- ...Array.from(manualFormTypes.getValues()).reduce(
591
- (result, item: ManualFormType) => Object.assign(result, item.config.components),
592
- {},
593
- ),
594
- FormBlockProvider,
595
- DetailsBlockProvider,
596
- // NOTE: fake provider component
597
- ManualActionStatusProvider(props) {
598
- return props.children;
599
- },
600
- ActionBarProvider(props) {
601
- return props.children;
602
- },
603
- SimpleDesigner,
604
- ManualActionDesigner,
605
- }}
606
- scope={{
607
- useSubmit,
608
- useDetailsBlockProps: useFormBlockContext,
609
- }}
610
- />
611
- </SchemaComponentContext.Provider>
612
- );
613
- }
614
-
615
- function validateForms(forms: Record<string, any> = {}) {
616
- for (const form of Object.values(forms)) {
617
- const formType = manualFormTypes.get(form.type);
618
- if (typeof formType.validate === 'function') {
619
- const msg = formType.validate(form);
620
- if (msg) {
621
- return msg;
622
- }
623
- }
624
- }
625
- }
626
-
627
- export function SchemaConfigButton(props) {
628
- const { workflow } = useFlowContext();
629
- const [visible, setVisible] = useState(false);
630
- const { values } = useForm();
631
- const { t } = usePluginTranslation();
632
- const onSetVisible = useCallback(
633
- (v) => {
634
- if (!v) {
635
- const msg = validateForms(values.forms);
636
- if (msg) {
637
- message.error({
638
- // eslint-disable-next-line react-hooks/rules-of-hooks
639
- title: t('Validation failed'),
640
- content: t(msg),
641
- });
642
- return;
643
- }
644
- }
645
- setVisible(v);
646
- },
647
- [values.forms],
648
- );
649
- return (
650
- <>
651
- <Button type="primary" onClick={() => setVisible(true)} disabled={false}>
652
- {t(workflow.executed ? 'View user interface' : 'Configure user interface')}
653
- </Button>
654
- <ActionContextProvider value={{ visible, setVisible: onSetVisible, formValueChanged: false }}>
655
- {props.children}
656
- </ActionContextProvider>
657
- </>
658
- );
659
- }
@@ -1,5 +0,0 @@
1
- import { createFormBlockSchema } from '@nocobase/client';
2
-
3
- export function createManualFormBlockUISchema(options) {
4
- return createFormBlockSchema(options);
5
- }