@nocobase/plugin-workflow-manual 0.17.0-alpha.4

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 (84) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +9 -0
  3. package/README.zh-CN.md +9 -0
  4. package/client.d.ts +2 -0
  5. package/client.js +1 -0
  6. package/dist/client/WorkflowTodo.d.ts +5 -0
  7. package/dist/client/WorkflowTodoBlockInitializer.d.ts +2 -0
  8. package/dist/client/index.d.ts +6 -0
  9. package/dist/client/index.js +13 -0
  10. package/dist/client/instruction/AssigneesSelect.d.ts +6 -0
  11. package/dist/client/instruction/DetailsBlockProvider.d.ts +2 -0
  12. package/dist/client/instruction/FormBlockInitializer.d.ts +2 -0
  13. package/dist/client/instruction/FormBlockProvider.d.ts +2 -0
  14. package/dist/client/instruction/ModeConfig.d.ts +5 -0
  15. package/dist/client/instruction/SchemaConfig.d.ts +49 -0
  16. package/dist/client/instruction/forms/create.d.ts +3 -0
  17. package/dist/client/instruction/forms/custom.d.ts +5 -0
  18. package/dist/client/instruction/forms/update.d.ts +3 -0
  19. package/dist/client/instruction/index.d.ts +83 -0
  20. package/dist/client/instruction/utils.d.ts +1 -0
  21. package/dist/externalVersion.js +18 -0
  22. package/dist/index.d.ts +2 -0
  23. package/dist/index.js +39 -0
  24. package/dist/locale/en-US.json +30 -0
  25. package/dist/locale/index.d.ts +3 -0
  26. package/dist/locale/index.js +39 -0
  27. package/dist/locale/zh-CN.json +30 -0
  28. package/dist/server/ManualInstruction.d.ts +28 -0
  29. package/dist/server/ManualInstruction.js +150 -0
  30. package/dist/server/Plugin.d.ts +6 -0
  31. package/dist/server/Plugin.js +73 -0
  32. package/dist/server/actions.d.ts +2 -0
  33. package/dist/server/actions.js +94 -0
  34. package/dist/server/collecions/jobs.d.ts +19 -0
  35. package/dist/server/collecions/jobs.js +39 -0
  36. package/dist/server/collecions/users.d.ts +15 -0
  37. package/dist/server/collecions/users.js +37 -0
  38. package/dist/server/collecions/users_jobs.d.ts +3 -0
  39. package/dist/server/collecions/users_jobs.js +70 -0
  40. package/dist/server/forms/create.d.ts +5 -0
  41. package/dist/server/forms/create.js +41 -0
  42. package/dist/server/forms/index.d.ts +6 -0
  43. package/dist/server/forms/index.js +38 -0
  44. package/dist/server/forms/update.d.ts +6 -0
  45. package/dist/server/forms/update.js +41 -0
  46. package/dist/server/index.d.ts +1 -0
  47. package/dist/server/index.js +33 -0
  48. package/package.json +33 -0
  49. package/server.d.ts +2 -0
  50. package/server.js +1 -0
  51. package/src/client/WorkflowTodo.tsx +618 -0
  52. package/src/client/WorkflowTodoBlockInitializer.tsx +30 -0
  53. package/src/client/index.ts +44 -0
  54. package/src/client/instruction/AssigneesSelect.tsx +39 -0
  55. package/src/client/instruction/DetailsBlockProvider.tsx +85 -0
  56. package/src/client/instruction/FormBlockInitializer.tsx +72 -0
  57. package/src/client/instruction/FormBlockProvider.tsx +84 -0
  58. package/src/client/instruction/ModeConfig.tsx +85 -0
  59. package/src/client/instruction/SchemaConfig.tsx +538 -0
  60. package/src/client/instruction/forms/create.tsx +112 -0
  61. package/src/client/instruction/forms/custom.tsx +403 -0
  62. package/src/client/instruction/forms/update.tsx +150 -0
  63. package/src/client/instruction/index.tsx +157 -0
  64. package/src/client/instruction/utils.ts +19 -0
  65. package/src/index.ts +2 -0
  66. package/src/locale/en-US.json +30 -0
  67. package/src/locale/index.ts +12 -0
  68. package/src/locale/zh-CN.json +30 -0
  69. package/src/server/ManualInstruction.ts +151 -0
  70. package/src/server/Plugin.ts +48 -0
  71. package/src/server/__tests__/collections/categories.ts +15 -0
  72. package/src/server/__tests__/collections/comments.ts +24 -0
  73. package/src/server/__tests__/collections/posts.ts +40 -0
  74. package/src/server/__tests__/collections/replies.ts +9 -0
  75. package/src/server/__tests__/collections/tags.ts +15 -0
  76. package/src/server/__tests__/instruction.test.ts +1154 -0
  77. package/src/server/actions.ts +100 -0
  78. package/src/server/collecions/jobs.ts +17 -0
  79. package/src/server/collecions/users.ts +15 -0
  80. package/src/server/collecions/users_jobs.ts +50 -0
  81. package/src/server/forms/create.ts +23 -0
  82. package/src/server/forms/index.ts +13 -0
  83. package/src/server/forms/update.ts +23 -0
  84. package/src/server/index.ts +1 -0
@@ -0,0 +1,100 @@
1
+ import { Context, utils } from '@nocobase/actions';
2
+ import WorkflowPlugin, { EXECUTION_STATUS, JOB_STATUS } from '@nocobase/plugin-workflow';
3
+
4
+ import ManualInstruction from './ManualInstruction';
5
+
6
+ export async function submit(context: Context, next) {
7
+ const repository = utils.getRepositoryFromParams(context);
8
+ const { filterByTk, values } = context.action.params;
9
+ const { currentUser } = context.state;
10
+
11
+ if (!currentUser) {
12
+ return context.throw(401);
13
+ }
14
+
15
+ const plugin: WorkflowPlugin = context.app.pm.get('workflow') as WorkflowPlugin;
16
+ const instruction = plugin.instructions.get('manual') as ManualInstruction;
17
+
18
+ const userJob = await repository.findOne({
19
+ filterByTk,
20
+ // filter: {
21
+ // userId: currentUser?.id
22
+ // },
23
+ appends: ['job', 'node', 'execution', 'workflow'],
24
+ context,
25
+ });
26
+
27
+ if (!userJob) {
28
+ return context.throw(404);
29
+ }
30
+
31
+ const { forms = {} } = userJob.node.config;
32
+ const [formKey] = Object.keys(values.result ?? {}).filter((key) => key !== '_');
33
+ const actionKey = values.result?._;
34
+
35
+ const actionItem = forms[formKey]?.actions?.find((item) => item.key === actionKey);
36
+ // NOTE: validate status
37
+ if (
38
+ userJob.status !== JOB_STATUS.PENDING ||
39
+ userJob.job.status !== JOB_STATUS.PENDING ||
40
+ userJob.execution.status !== EXECUTION_STATUS.STARTED ||
41
+ !userJob.workflow.enabled ||
42
+ !actionKey ||
43
+ actionItem?.status == null
44
+ ) {
45
+ return context.throw(400);
46
+ }
47
+
48
+ userJob.execution.workflow = userJob.workflow;
49
+ const processor = plugin.createProcessor(userJob.execution);
50
+ await processor.prepare();
51
+
52
+ // NOTE: validate assignee
53
+ const assignees = processor.getParsedValue(userJob.node.config.assignees ?? [], userJob.nodeId);
54
+ if (!assignees.includes(currentUser.id) || userJob.userId !== currentUser.id) {
55
+ return context.throw(403);
56
+ }
57
+ const presetValues = processor.getParsedValue(actionItem.values ?? {}, userJob.nodeId, {
58
+ // @deprecated
59
+ currentUser: currentUser.toJSON(),
60
+ // @deprecated
61
+ currentRecord: values.result[formKey],
62
+ // @deprecated
63
+ currentTime: new Date(),
64
+ $user: currentUser.toJSON(),
65
+ $nForm: values.result[formKey],
66
+ $nDate: {
67
+ now: new Date(),
68
+ },
69
+ });
70
+
71
+ userJob.set({
72
+ status: actionItem.status,
73
+ result:
74
+ actionItem.status > JOB_STATUS.PENDING
75
+ ? { [formKey]: Object.assign(values.result[formKey], presetValues), _: actionKey }
76
+ : Object.assign(userJob.result ?? {}, values.result),
77
+ });
78
+
79
+ const handler = instruction.formTypes.get(forms[formKey].type);
80
+ if (handler && userJob.status) {
81
+ await handler.call(instruction, userJob, forms[formKey], processor);
82
+ }
83
+
84
+ await userJob.save({ transaction: processor.transaction });
85
+
86
+ await processor.exit();
87
+
88
+ context.body = userJob;
89
+ context.status = 202;
90
+
91
+ await next();
92
+
93
+ userJob.job.execution = userJob.execution;
94
+ userJob.job.latestUserJob = userJob;
95
+
96
+ // NOTE: resume the process and no `await` for quick returning
97
+ processor.logger.info(`manual node (${userJob.nodeId}) action trigger execution (${userJob.execution.id}) to resume`);
98
+
99
+ plugin.resume(userJob.job);
100
+ }
@@ -0,0 +1,17 @@
1
+ export default {
2
+ name: 'jobs',
3
+ fields: [
4
+ {
5
+ type: 'belongsToMany',
6
+ name: 'users',
7
+ through: 'users_jobs',
8
+ },
9
+ {
10
+ type: 'hasMany',
11
+ name: 'usersJobs',
12
+ target: 'users_jobs',
13
+ foreignKey: 'jobId',
14
+ onDelete: 'CASCADE',
15
+ },
16
+ ],
17
+ };
@@ -0,0 +1,15 @@
1
+ export default {
2
+ name: 'users',
3
+ fields: [
4
+ {
5
+ type: 'belongsToMany',
6
+ name: 'jobs',
7
+ through: 'users_jobs',
8
+ },
9
+ {
10
+ type: 'hasMany',
11
+ name: 'usersJobs',
12
+ target: 'users_jobs',
13
+ },
14
+ ],
15
+ };
@@ -0,0 +1,50 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+
3
+ export default {
4
+ namespace: 'workflow.executionLogs',
5
+ name: 'users_jobs',
6
+ duplicator: 'optional',
7
+ fields: [
8
+ {
9
+ type: 'bigInt',
10
+ name: 'id',
11
+ primaryKey: true,
12
+ autoIncrement: true,
13
+ },
14
+ {
15
+ type: 'belongsTo',
16
+ name: 'job',
17
+ target: 'jobs',
18
+ foreignKey: 'jobId',
19
+ primaryKey: false,
20
+ },
21
+ {
22
+ type: 'belongsTo',
23
+ name: 'user',
24
+ target: 'users',
25
+ foreignKey: 'userId',
26
+ primaryKey: false,
27
+ },
28
+ {
29
+ type: 'belongsTo',
30
+ name: 'execution',
31
+ },
32
+ {
33
+ type: 'belongsTo',
34
+ name: 'node',
35
+ target: 'flow_nodes',
36
+ },
37
+ {
38
+ type: 'belongsTo',
39
+ name: 'workflow',
40
+ },
41
+ {
42
+ type: 'integer',
43
+ name: 'status',
44
+ },
45
+ {
46
+ type: 'jsonb',
47
+ name: 'result',
48
+ },
49
+ ],
50
+ } as CollectionOptions;
@@ -0,0 +1,23 @@
1
+ import { Processor } from '@nocobase/plugin-workflow';
2
+ import ManualInstruction from '../ManualInstruction';
3
+
4
+ export default async function (this: ManualInstruction, instance, { collection }, processor: Processor) {
5
+ const repo = this.plugin.db.getRepository(collection);
6
+ if (!repo) {
7
+ throw new Error(`collection ${collection} for create data on manual node not found`);
8
+ }
9
+
10
+ const { _, ...form } = instance.result;
11
+ const [values] = Object.values(form);
12
+ await repo.create({
13
+ values: {
14
+ ...((values as { [key: string]: any }) ?? {}),
15
+ createdBy: instance.userId,
16
+ updatedBy: instance.userId,
17
+ },
18
+ context: {
19
+ executionId: processor.execution.id,
20
+ },
21
+ transaction: processor.transaction,
22
+ });
23
+ }
@@ -0,0 +1,13 @@
1
+ import { Processor } from '@nocobase/plugin-workflow';
2
+
3
+ import ManualInstruction from '../ManualInstruction';
4
+
5
+ import create from './create';
6
+ import update from './update';
7
+
8
+ export type FormHandler = (this: ManualInstruction, instance, formConfig, processor: Processor) => Promise<void>;
9
+
10
+ export default function ({ formTypes }) {
11
+ formTypes.register('create', create);
12
+ formTypes.register('update', update);
13
+ }
@@ -0,0 +1,23 @@
1
+ import { Processor } from '@nocobase/plugin-workflow';
2
+ import ManualInstruction from '../ManualInstruction';
3
+
4
+ export default async function (this: ManualInstruction, instance, { collection, filter = {} }, processor: Processor) {
5
+ const repo = this.plugin.db.getRepository(collection);
6
+ if (!repo) {
7
+ throw new Error(`collection ${collection} for update data on manual node not found`);
8
+ }
9
+
10
+ const { _, ...form } = instance.result;
11
+ const [values] = Object.values(form);
12
+ await repo.update({
13
+ filter: processor.getParsedValue(filter, instance.nodeId),
14
+ values: {
15
+ ...((values as { [key: string]: any }) ?? {}),
16
+ updatedBy: instance.userId,
17
+ },
18
+ context: {
19
+ executionId: processor.execution.id,
20
+ },
21
+ transaction: processor.transaction,
22
+ });
23
+ }
@@ -0,0 +1 @@
1
+ export { default } from './Plugin';