@nocobase/plugin-workflow 0.9.0-alpha.2 → 0.9.1-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/README.md +9 -0
  2. package/README.zh-CN.md +9 -0
  3. package/lib/client/AddButton.d.ts +1 -1
  4. package/lib/client/AddButton.js +43 -27
  5. package/lib/client/Branch.d.ts +1 -1
  6. package/lib/client/ExecutionCanvas.js +5 -10
  7. package/lib/client/WorkflowCanvas.js +12 -42
  8. package/lib/client/WorkflowProvider.js +10 -1
  9. package/lib/client/components/CollectionBlockInitializer.d.ts +7 -0
  10. package/lib/client/components/CollectionBlockInitializer.js +81 -0
  11. package/lib/client/components/CollectionFieldInitializers.d.ts +2 -0
  12. package/lib/client/components/CollectionFieldInitializers.js +89 -0
  13. package/lib/client/components/CollectionFieldset.js +25 -33
  14. package/lib/client/components/FilterDynamicComponent.d.ts +6 -0
  15. package/lib/client/components/FilterDynamicComponent.js +43 -0
  16. package/lib/client/components/NullRender.d.ts +1 -0
  17. package/lib/client/components/NullRender.js +10 -0
  18. package/lib/client/components/RadioWithTooltip.d.ts +7 -0
  19. package/lib/client/components/RadioWithTooltip.js +94 -0
  20. package/lib/client/constants.d.ts +10 -8
  21. package/lib/client/constants.js +52 -14
  22. package/lib/client/index.d.ts +0 -1
  23. package/lib/client/index.js +1 -10
  24. package/lib/client/locale/en-US.d.ts +18 -18
  25. package/lib/client/locale/en-US.js +19 -19
  26. package/lib/client/locale/zh-CN.d.ts +47 -20
  27. package/lib/client/locale/zh-CN.js +48 -21
  28. package/lib/client/nodes/calculation.d.ts +39 -7
  29. package/lib/client/nodes/calculation.js +165 -19
  30. package/lib/client/nodes/condition.d.ts +67 -4
  31. package/lib/client/nodes/condition.js +283 -31
  32. package/lib/client/nodes/create.d.ts +10 -10
  33. package/lib/client/nodes/create.js +28 -42
  34. package/lib/client/nodes/delay.d.ts +4 -4
  35. package/lib/client/nodes/delay.js +10 -8
  36. package/lib/client/nodes/destroy.d.ts +4 -7
  37. package/lib/client/nodes/destroy.js +4 -5
  38. package/lib/client/nodes/index.d.ts +10 -2
  39. package/lib/client/nodes/index.js +217 -110
  40. package/lib/client/nodes/manual/AssigneesSelect.d.ts +6 -0
  41. package/lib/client/nodes/manual/AssigneesSelect.js +65 -0
  42. package/lib/client/nodes/manual/ModeConfig.d.ts +5 -0
  43. package/lib/client/nodes/manual/ModeConfig.js +160 -0
  44. package/lib/client/nodes/manual/SchemaConfig.d.ts +6 -0
  45. package/lib/client/nodes/manual/SchemaConfig.js +715 -0
  46. package/lib/client/nodes/manual/WorkflowTodo.d.ts +8 -0
  47. package/lib/client/nodes/manual/WorkflowTodo.js +691 -0
  48. package/lib/client/nodes/manual/WorkflowTodoBlockInitializer.d.ts +5 -0
  49. package/lib/client/nodes/manual/WorkflowTodoBlockInitializer.js +75 -0
  50. package/lib/client/nodes/manual/index.d.ts +62 -0
  51. package/lib/client/nodes/manual/index.js +137 -0
  52. package/lib/client/nodes/parallel.d.ts +12 -7
  53. package/lib/client/nodes/parallel.js +32 -39
  54. package/lib/client/nodes/query.d.ts +11 -19
  55. package/lib/client/nodes/query.js +40 -47
  56. package/lib/client/nodes/request.d.ts +77 -42
  57. package/lib/client/nodes/request.js +123 -69
  58. package/lib/client/nodes/update.d.ts +33 -29
  59. package/lib/client/nodes/update.js +14 -7
  60. package/lib/client/schemas/collection.d.ts +0 -3
  61. package/lib/client/schemas/collection.js +2 -7
  62. package/lib/client/schemas/executions.js +1 -1
  63. package/lib/client/schemas/workflows.js +1 -1
  64. package/lib/client/style.js +51 -9
  65. package/lib/client/triggers/collection.d.ts +44 -15
  66. package/lib/client/triggers/collection.js +104 -82
  67. package/lib/client/triggers/index.d.ts +6 -3
  68. package/lib/client/triggers/index.js +167 -74
  69. package/lib/client/triggers/schedule/DateFieldsSelect.js +1 -3
  70. package/lib/client/triggers/schedule/ScheduleConfig.js +15 -17
  71. package/lib/client/triggers/schedule/index.d.ts +7 -6
  72. package/lib/client/triggers/schedule/index.js +39 -81
  73. package/lib/client/utils.d.ts +1 -0
  74. package/lib/client/utils.js +38 -0
  75. package/lib/client/variable.d.ts +21 -0
  76. package/lib/client/variable.js +147 -0
  77. package/lib/server/Plugin.d.ts +3 -3
  78. package/lib/server/Plugin.js +12 -21
  79. package/lib/server/Processor.d.ts +9 -2
  80. package/lib/server/Processor.js +33 -33
  81. package/lib/server/actions/index.js +2 -4
  82. package/lib/server/actions/workflows.d.ts +1 -0
  83. package/lib/server/actions/workflows.js +80 -23
  84. package/lib/server/collections/executions.js +5 -7
  85. package/lib/server/collections/flow_nodes.js +6 -18
  86. package/lib/server/collections/jobs.js +3 -1
  87. package/lib/server/collections/workflows.js +8 -4
  88. package/lib/server/constants.d.ts +9 -3
  89. package/lib/server/constants.js +11 -5
  90. package/lib/server/functions/index.d.ts +4 -0
  91. package/lib/server/functions/index.js +38 -0
  92. package/lib/server/index.d.ts +0 -1
  93. package/lib/server/index.js +0 -14
  94. package/lib/server/instructions/calculation.d.ts +2 -7
  95. package/lib/server/instructions/calculation.js +32 -37
  96. package/lib/server/instructions/condition.d.ts +4 -4
  97. package/lib/server/instructions/condition.js +126 -54
  98. package/lib/server/instructions/index.js +1 -1
  99. package/lib/server/instructions/manual/actions.js +101 -0
  100. package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/jobs.d.ts +2 -0
  101. package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/jobs.js +2 -1
  102. package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/users_jobs.js +10 -10
  103. package/lib/server/instructions/manual/index.d.ts +25 -0
  104. package/lib/server/instructions/manual/index.js +200 -0
  105. package/lib/server/instructions/parallel.js +11 -7
  106. package/lib/server/instructions/request.d.ts +5 -4
  107. package/lib/server/instructions/request.js +60 -79
  108. package/lib/server/migrations/20230221032941-change-request-body-type.d.ts +5 -0
  109. package/lib/server/migrations/20230221032941-change-request-body-type.js +113 -0
  110. package/lib/server/migrations/20230221071831-calculation-expression.d.ts +4 -0
  111. package/lib/server/migrations/20230221071831-calculation-expression.js +143 -0
  112. package/lib/server/migrations/20230221121203-condition-calculation.d.ts +4 -0
  113. package/lib/server/migrations/20230221121203-condition-calculation.js +126 -0
  114. package/lib/server/migrations/20230221162902-jsonb-to-json.d.ts +4 -0
  115. package/lib/server/migrations/20230221162902-jsonb-to-json.js +81 -0
  116. package/lib/server/triggers/schedule.js +11 -3
  117. package/package.json +10 -10
  118. package/lib/client/calculators.d.ts +0 -89
  119. package/lib/client/calculators.js +0 -668
  120. package/lib/client/components/CollectionFieldSelect.d.ts +0 -2
  121. package/lib/client/components/CollectionFieldSelect.js +0 -106
  122. package/lib/client/components/EjsTextArea.d.ts +0 -2
  123. package/lib/client/components/EjsTextArea.js +0 -232
  124. package/lib/server/actions/jobs.d.ts +0 -2
  125. package/lib/server/actions/jobs.js +0 -39
  126. package/lib/server/calculators/index.d.ts +0 -40
  127. package/lib/server/calculators/index.js +0 -187
  128. package/lib/server/extensions/assignees/actions.js +0 -75
  129. package/lib/server/extensions/assignees/index.d.ts +0 -2
  130. package/lib/server/extensions/assignees/index.js +0 -273
  131. package/lib/server/extensions/index.d.ts +0 -3
  132. package/lib/server/extensions/index.js +0 -13
  133. package/lib/server/instructions/prompt.d.ts +0 -19
  134. package/lib/server/instructions/prompt.js +0 -131
  135. /package/lib/server/{extensions/assignees → instructions/manual}/actions.d.ts +0 -0
  136. /package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/users.d.ts +0 -0
  137. /package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/users.js +0 -0
  138. /package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/users_jobs.d.ts +0 -0
@@ -3,88 +3,160 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.calculators = void 0;
7
7
 
8
- var _calculators = _interopRequireWildcard(require("../calculators"));
8
+ function _utils() {
9
+ const data = require("@nocobase/utils");
9
10
 
10
- var _constants = require("../constants");
11
+ _utils = function _utils() {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
17
+
18
+ function _evaluators() {
19
+ const data = _interopRequireDefault(require("@nocobase/evaluators"));
11
20
 
12
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
+ _evaluators = function _evaluators() {
22
+ return data;
23
+ };
13
24
 
14
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
+ return data;
26
+ }
27
+
28
+ var _constants = require("../constants");
29
+
30
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
31
 
16
32
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
17
33
 
18
34
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
19
35
 
20
- // @calculation: {
21
- // not: false,
22
- // group: {
23
- // type: 'and',
24
- // calculations: [
25
- // {
26
- // calculator: 'time.equal',
27
- // operands: [{ value: '{{$context.time}}' }, { value: '{{$fn.now}}' }]
28
- // },
29
- // {
30
- // calculator: 'value.equal',
31
- // operands: [{ value: '{{$jobsMapByNodeId.213}}' }, { value: 1 }]
32
- // },
33
- // {
34
- // group: {
35
- // type: 'or',
36
- // calculations: [
37
- // {
38
- // calculator: 'value.equal',
39
- // operands: [{ value: '{{$jobsMapByNodeId.213}}' }, { value: 1 }]
40
- // }
41
- // ]
42
- // }
43
- // }
44
- // ]
45
- // }
46
- // }
47
- function logicCalculate(calculation, input, processor) {
48
- if (!calculation) {
49
- return true;
50
- }
36
+ const calculators = new (_utils().Registry)(); // built-in functions
51
37
 
52
- const not = calculation.not,
53
- group = calculation.group;
54
- let result;
38
+ exports.calculators = calculators;
55
39
 
56
- if (group) {
57
- const method = group.type === 'and' ? 'every' : 'some';
58
- result = group.calculations[method](item => logicCalculate(item, input, processor));
59
- } else {
60
- const args = calculation.operands.map(operand => (0, _calculators.calculate)(operand, input, processor));
40
+ function equal(a, b) {
41
+ return a === b;
42
+ }
61
43
 
62
- const fn = _calculators.default.get(calculation.calculator);
44
+ function notEqual(a, b) {
45
+ return a !== b;
46
+ }
63
47
 
64
- if (!fn) {
65
- throw new Error(`no calculator function registered for "${calculation.calculator}"`);
66
- }
48
+ function gt(a, b) {
49
+ return a > b;
50
+ }
51
+
52
+ function gte(a, b) {
53
+ return a >= b;
54
+ }
55
+
56
+ function lt(a, b) {
57
+ return a < b;
58
+ }
59
+
60
+ function lte(a, b) {
61
+ return a <= b;
62
+ }
63
+
64
+ calculators.register('equal', equal);
65
+ calculators.register('notEqual', notEqual);
66
+ calculators.register('gt', gt);
67
+ calculators.register('gte', gte);
68
+ calculators.register('lt', lt);
69
+ calculators.register('lte', lte);
70
+ calculators.register('===', equal);
71
+ calculators.register('!==', notEqual);
72
+ calculators.register('>', gt);
73
+ calculators.register('>=', gte);
74
+ calculators.register('<', lt);
75
+ calculators.register('<=', lte);
76
+
77
+ function includes(a, b) {
78
+ return a.includes(b);
79
+ }
67
80
 
68
- result = fn(...args);
81
+ function notIncludes(a, b) {
82
+ return !a.includes(b);
83
+ }
84
+
85
+ function startsWith(a, b) {
86
+ return a.startsWith(b);
87
+ }
88
+
89
+ function notStartsWith(a, b) {
90
+ return !a.startsWith(b);
91
+ }
92
+
93
+ function endsWith(a, b) {
94
+ return a.endsWith(b);
95
+ }
96
+
97
+ function notEndsWith(a, b) {
98
+ return !a.endsWith(b);
99
+ }
100
+
101
+ calculators.register('includes', includes);
102
+ calculators.register('notIncludes', notIncludes);
103
+ calculators.register('startsWith', startsWith);
104
+ calculators.register('notStartsWith', notStartsWith);
105
+ calculators.register('endsWith', endsWith);
106
+ calculators.register('notEndsWith', notEndsWith);
107
+
108
+ function calculate(calculation = {}) {
109
+ var _calculation$operands;
110
+
111
+ let fn;
112
+
113
+ if (!(calculation.calculator && (fn = calculators.get(calculation.calculator)))) {
114
+ throw new Error(`no calculator function registered for "${calculation.calculator}"`);
115
+ }
116
+
117
+ return Boolean(fn(...((_calculation$operands = calculation.operands) !== null && _calculation$operands !== void 0 ? _calculation$operands : [])));
118
+ }
119
+
120
+ function logicCalculate(calculation) {
121
+ if (!calculation) {
122
+ return true;
123
+ }
124
+
125
+ if (typeof calculation['group'] === 'object') {
126
+ var _calculation$group$ca;
127
+
128
+ const method = calculation['group'].type === 'and' ? 'every' : 'some';
129
+ return ((_calculation$group$ca = calculation['group'].calculations) !== null && _calculation$group$ca !== void 0 ? _calculation$group$ca : [])[method](item => logicCalculate(item));
69
130
  }
70
131
 
71
- return not ? !result : result;
132
+ return calculate(calculation);
72
133
  }
73
134
 
74
135
  var _default = {
75
136
  run(node, prevJob, processor) {
76
137
  return _asyncToGenerator(function* () {
77
- // TODO(optimize): loading of jobs could be reduced and turned into incrementally in processor
78
- // const jobs = await processor.getJobs();
79
138
  const _ref = node.config || {},
139
+ engine = _ref.engine,
80
140
  calculation = _ref.calculation,
141
+ expression = _ref.expression,
81
142
  rejectOnFalse = _ref.rejectOnFalse;
82
143
 
83
- const result = logicCalculate(processor.getParsedValue(calculation), prevJob, processor);
144
+ const evaluator = _evaluators().default.get(engine);
145
+
146
+ let result = true;
147
+
148
+ try {
149
+ result = evaluator ? evaluator(expression, processor.getScope()) : logicCalculate(processor.getParsedValue(calculation));
150
+ } catch (e) {
151
+ return {
152
+ result: e.toString(),
153
+ status: _constants.JOB_STATUS.ERROR
154
+ };
155
+ }
84
156
 
85
157
  if (!result && rejectOnFalse) {
86
158
  return {
87
- status: _constants.JOB_STATUS.REJECTED,
159
+ status: _constants.JOB_STATUS.FAILED,
88
160
  result
89
161
  };
90
162
  }
@@ -47,7 +47,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
47
47
 
48
48
  function _default(plugin, more = {}) {
49
49
  const instructions = plugin.instructions;
50
- const natives = ['calculation', 'condition', 'parallel', 'delay', 'prompt', 'query', 'create', 'update', 'destroy', 'request'].reduce((result, key) => Object.assign(result, {
50
+ const natives = ['calculation', 'condition', 'parallel', 'delay', 'manual', 'query', 'create', 'update', 'destroy', 'request'].reduce((result, key) => Object.assign(result, {
51
51
  [key]: (0, _utils().requireModule)(_path().default.isAbsolute(key) ? key : _path().default.join(__dirname, key))
52
52
  }), {});
53
53
 
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.submit = submit;
7
+
8
+ function _actions() {
9
+ const data = require("@nocobase/actions");
10
+
11
+ _actions = function _actions() {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
17
+
18
+ var _constants = require("../../constants");
19
+
20
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
21
+
22
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
23
+
24
+ function submit(_x, _x2) {
25
+ return _submit.apply(this, arguments);
26
+ }
27
+
28
+ function _submit() {
29
+ _submit = _asyncToGenerator(function* (context, next) {
30
+ const repository = _actions().utils.getRepositoryFromParams(context);
31
+
32
+ const _context$action$param = context.action.params,
33
+ filterByTk = _context$action$param.filterByTk,
34
+ values = _context$action$param.values;
35
+ const currentUser = context.state.currentUser;
36
+
37
+ if (!currentUser) {
38
+ return context.throw(401);
39
+ }
40
+
41
+ const plugin = context.app.pm.get('workflow');
42
+ const userJob = yield context.db.sequelize.transaction( /*#__PURE__*/function () {
43
+ var _ref = _asyncToGenerator(function* (transaction) {
44
+ var _instance$node$config2;
45
+
46
+ const instance = yield repository.findOne({
47
+ filterByTk,
48
+ // filter: {
49
+ // userId: currentUser?.id
50
+ // },
51
+ appends: ['job', 'node', 'execution', 'workflow'],
52
+ context,
53
+ transaction
54
+ });
55
+
56
+ if (!instance) {
57
+ return context.throw(404);
58
+ }
59
+
60
+ const _instance$node$config = instance.node.config.actions,
61
+ actions = _instance$node$config === void 0 ? [] : _instance$node$config; // NOTE: validate status
62
+
63
+ if (instance.status !== _constants.JOB_STATUS.PENDING || instance.job.status !== _constants.JOB_STATUS.PENDING || instance.execution.status !== _constants.EXECUTION_STATUS.STARTED || !instance.workflow.enabled || !actions.includes(values.status)) {
64
+ return context.throw(400);
65
+ }
66
+
67
+ instance.execution.workflow = instance.workflow;
68
+ const processor = plugin.createProcessor(instance.execution, {
69
+ transaction
70
+ });
71
+ yield processor.prepare();
72
+ const assignees = processor.getParsedValue((_instance$node$config2 = instance.node.config.assignees) !== null && _instance$node$config2 !== void 0 ? _instance$node$config2 : []);
73
+
74
+ if (!assignees.includes(currentUser.id) || instance.userId !== currentUser.id) {
75
+ return context.throw(403);
76
+ } // NOTE: validate assignee
77
+
78
+
79
+ yield instance.update({
80
+ status: values.status,
81
+ result: values.result
82
+ }, {
83
+ transaction
84
+ });
85
+ return instance;
86
+ });
87
+
88
+ return function (_x3) {
89
+ return _ref.apply(this, arguments);
90
+ };
91
+ }()); // await transaction.commit();
92
+
93
+ context.body = userJob;
94
+ context.status = 202;
95
+ yield next();
96
+ userJob.job.latestUserJob = userJob; // NOTE: resume the process and no `await` for quick returning
97
+
98
+ plugin.resume(userJob.job);
99
+ });
100
+ return _submit.apply(this, arguments);
101
+ }
@@ -6,11 +6,13 @@ declare const _default: {
6
6
  through: string;
7
7
  target?: undefined;
8
8
  foreignKey?: undefined;
9
+ onDelete?: undefined;
9
10
  } | {
10
11
  type: string;
11
12
  name: string;
12
13
  target: string;
13
14
  foreignKey: string;
15
+ onDelete: string;
14
16
  through?: undefined;
15
17
  })[];
16
18
  };
@@ -14,7 +14,8 @@ var _default = {
14
14
  type: 'hasMany',
15
15
  name: 'usersJobs',
16
16
  target: 'users_jobs',
17
- foreignKey: 'jobId'
17
+ foreignKey: 'jobId',
18
+ onDelete: 'CASCADE'
18
19
  }]
19
20
  };
20
21
  exports.default = _default;
@@ -5,26 +5,26 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _default = {
8
+ namespace: 'workflow',
8
9
  name: 'users_jobs',
10
+ duplicator: 'optional',
9
11
  fields: [{
10
12
  type: 'bigInt',
11
13
  name: 'id',
12
14
  primaryKey: true,
13
15
  autoIncrement: true
14
- }, {
15
- type: 'bigInt',
16
- name: 'userId',
17
- primaryKey: false
18
- }, {
19
- type: 'bigInt',
20
- name: 'jobId',
21
- primaryKey: false
22
16
  }, {
23
17
  type: 'belongsTo',
24
- name: 'job'
18
+ name: 'job',
19
+ target: 'jobs',
20
+ foreignKey: 'jobId',
21
+ primaryKey: false
25
22
  }, {
26
23
  type: 'belongsTo',
27
- name: 'user'
24
+ name: 'user',
25
+ target: 'users',
26
+ foreignKey: 'userId',
27
+ primaryKey: false
28
28
  }, {
29
29
  type: 'belongsTo',
30
30
  name: 'execution'
@@ -0,0 +1,25 @@
1
+ import Plugin from '../..';
2
+ import { Instruction } from '..';
3
+ export interface ManualConfig {
4
+ schema: {
5
+ collection: {
6
+ name: string;
7
+ fields: any[];
8
+ };
9
+ blocks: {
10
+ [key: string]: any;
11
+ };
12
+ actions: {
13
+ [key: string]: any;
14
+ };
15
+ };
16
+ actions: number[];
17
+ assignees?: number[];
18
+ mode?: number;
19
+ }
20
+ export default class implements Instruction {
21
+ protected plugin: Plugin;
22
+ constructor(plugin: Plugin);
23
+ run(node: any, prevJob: any, processor: any): Promise<any>;
24
+ resume(node: any, job: any, processor: any): Promise<any>;
25
+ }
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ function _actions() {
9
+ const data = _interopRequireDefault(require("@nocobase/actions"));
10
+
11
+ _actions = function _actions() {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
17
+
18
+ var _constants = require("../../constants");
19
+
20
+ var _jobs = _interopRequireDefault(require("./collecions/jobs"));
21
+
22
+ var _users = _interopRequireDefault(require("./collecions/users"));
23
+
24
+ var _users_jobs = _interopRequireDefault(require("./collecions/users_jobs"));
25
+
26
+ var _actions2 = require("./actions");
27
+
28
+ const _excluded = ["mode"];
29
+
30
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
+
32
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
33
+
34
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
35
+
36
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
37
+
38
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
39
+
40
+ const MULTIPLE_ASSIGNED_MODE = {
41
+ SINGLE: Symbol('single'),
42
+ ALL: Symbol('all'),
43
+ ANY: Symbol('any'),
44
+ ALL_PERCENTAGE: Symbol('all percentage'),
45
+ ANY_PERCENTAGE: Symbol('any percentage')
46
+ };
47
+ const Modes = {
48
+ [MULTIPLE_ASSIGNED_MODE.SINGLE]: {
49
+ getStatus(distribution, assignees) {
50
+ const done = distribution.find(item => item.status !== _constants.JOB_STATUS.PENDING && item.count > 0);
51
+ return done ? done.status : null;
52
+ }
53
+
54
+ },
55
+ [MULTIPLE_ASSIGNED_MODE.ALL]: {
56
+ getStatus(distribution, assignees) {
57
+ const resolved = distribution.find(item => item.status === _constants.JOB_STATUS.RESOLVED);
58
+
59
+ if (resolved && resolved.count === assignees.length) {
60
+ return _constants.JOB_STATUS.RESOLVED;
61
+ }
62
+
63
+ const rejected = distribution.find(item => item.status < _constants.JOB_STATUS.PENDING);
64
+
65
+ if (rejected && rejected.count) {
66
+ return rejected.status;
67
+ }
68
+
69
+ return null;
70
+ }
71
+
72
+ },
73
+ [MULTIPLE_ASSIGNED_MODE.ANY]: {
74
+ getStatus(distribution, assignees) {
75
+ const resolved = distribution.find(item => item.status === _constants.JOB_STATUS.RESOLVED);
76
+
77
+ if (resolved && resolved.count) {
78
+ return _constants.JOB_STATUS.RESOLVED;
79
+ }
80
+
81
+ const rejectedCount = distribution.reduce((count, item) => item.status < _constants.JOB_STATUS.PENDING ? count + item.count : count, 0); // NOTE: all failures are considered as rejected for now
82
+
83
+ if (rejectedCount === assignees.length) {
84
+ return _constants.JOB_STATUS.REJECTED;
85
+ }
86
+
87
+ return null;
88
+ }
89
+
90
+ }
91
+ };
92
+
93
+ function getMode(mode) {
94
+ switch (true) {
95
+ case mode === 1:
96
+ return Modes[MULTIPLE_ASSIGNED_MODE.ALL];
97
+
98
+ case mode === -1:
99
+ return Modes[MULTIPLE_ASSIGNED_MODE.ANY];
100
+
101
+ case mode > 0:
102
+ return Modes[MULTIPLE_ASSIGNED_MODE.ALL_PERCENTAGE];
103
+
104
+ case mode < 0:
105
+ return Modes[MULTIPLE_ASSIGNED_MODE.ANY_PERCENTAGE];
106
+
107
+ default:
108
+ return Modes[MULTIPLE_ASSIGNED_MODE.SINGLE];
109
+ }
110
+ }
111
+
112
+ class _default {
113
+ constructor(plugin) {
114
+ this.plugin = void 0;
115
+ this.plugin = plugin;
116
+ plugin.db.collection(_users_jobs.default);
117
+ plugin.db.extendCollection(_users.default);
118
+ plugin.db.extendCollection(_jobs.default);
119
+ plugin.app.resource({
120
+ name: 'users_jobs',
121
+ actions: {
122
+ list: {
123
+ filter: {
124
+ $or: [{
125
+ 'workflow.enabled': true
126
+ }, {
127
+ 'workflow.enabled': false,
128
+ status: {
129
+ $ne: _constants.JOB_STATUS.PENDING
130
+ }
131
+ }]
132
+ },
133
+ handler: _actions().default.list
134
+ },
135
+ submit: _actions2.submit
136
+ }
137
+ });
138
+ }
139
+
140
+ run(node, prevJob, processor) {
141
+ return _asyncToGenerator(function* () {
142
+ var _prevJob$id;
143
+
144
+ const _node$config = node.config,
145
+ mode = _node$config.mode,
146
+ config = _objectWithoutProperties(_node$config, _excluded);
147
+
148
+ const assignees = [...new Set(processor.getParsedValue(config.assignees) || [])];
149
+ const job = yield processor.saveJob({
150
+ status: _constants.JOB_STATUS.PENDING,
151
+ result: mode ? [] : null,
152
+ nodeId: node.id,
153
+ upstreamId: (_prevJob$id = prevJob === null || prevJob === void 0 ? void 0 : prevJob.id) !== null && _prevJob$id !== void 0 ? _prevJob$id : null
154
+ }); // NOTE: batch create users jobs
155
+
156
+ const UserJobModel = processor.options.plugin.db.getModel('users_jobs');
157
+ yield UserJobModel.bulkCreate(assignees.map(userId => ({
158
+ userId,
159
+ jobId: job.id,
160
+ nodeId: node.id,
161
+ executionId: job.executionId,
162
+ workflowId: node.workflowId,
163
+ status: _constants.JOB_STATUS.PENDING
164
+ })), {
165
+ transaction: processor.transaction
166
+ });
167
+ return job;
168
+ })();
169
+ }
170
+
171
+ resume(node, job, processor) {
172
+ return _asyncToGenerator(function* () {
173
+ var _job$latestUserJob$re, _job$latestUserJob, _getMode$getStatus;
174
+
175
+ // NOTE: check all users jobs related if all done then continue as parallel
176
+ const _node$config2 = node.config,
177
+ _node$config2$assigne = _node$config2.assignees,
178
+ assignees = _node$config2$assigne === void 0 ? [] : _node$config2$assigne,
179
+ mode = _node$config2.mode;
180
+ const UserJobModel = processor.options.plugin.db.getModel('users_jobs');
181
+ const distribution = yield UserJobModel.count({
182
+ where: {
183
+ jobId: job.id
184
+ },
185
+ group: ['status']
186
+ });
187
+ const submitted = distribution.reduce((count, item) => item.status !== _constants.JOB_STATUS.PENDING ? count + item.count : count, 0);
188
+ const result = mode ? (submitted || 0) / assignees.length : (_job$latestUserJob$re = (_job$latestUserJob = job.latestUserJob) === null || _job$latestUserJob === void 0 ? void 0 : _job$latestUserJob.result) !== null && _job$latestUserJob$re !== void 0 ? _job$latestUserJob$re : job.result;
189
+ job.set({
190
+ status: job.status || ((_getMode$getStatus = getMode(mode).getStatus(distribution, assignees)) !== null && _getMode$getStatus !== void 0 ? _getMode$getStatus : _constants.JOB_STATUS.PENDING),
191
+ result
192
+ });
193
+ return job;
194
+ })();
195
+ }
196
+
197
+ }
198
+
199
+ exports.default = _default;
200
+ ;
@@ -20,12 +20,14 @@ exports.PARALLEL_MODE = PARALLEL_MODE;
20
20
  const Modes = {
21
21
  [PARALLEL_MODE.ALL]: {
22
22
  next(previous) {
23
- return previous.status !== _constants.JOB_STATUS.REJECTED;
23
+ return previous.status >= _constants.JOB_STATUS.PENDING;
24
24
  },
25
25
 
26
26
  getStatus(result) {
27
- if (result.some(status => status != null && status === _constants.JOB_STATUS.REJECTED)) {
28
- return _constants.JOB_STATUS.REJECTED;
27
+ const failedStatus = result.find(status => status != null && status < _constants.JOB_STATUS.PENDING);
28
+
29
+ if (typeof failedStatus !== 'undefined') {
30
+ return failedStatus;
29
31
  }
30
32
 
31
33
  if (result.every(status => status != null && status === _constants.JOB_STATUS.RESOLVED)) {
@@ -38,7 +40,7 @@ const Modes = {
38
40
  },
39
41
  [PARALLEL_MODE.ANY]: {
40
42
  next(previous) {
41
- return previous.status !== _constants.JOB_STATUS.RESOLVED;
43
+ return previous.status <= _constants.JOB_STATUS.PENDING;
42
44
  },
43
45
 
44
46
  getStatus(result) {
@@ -50,7 +52,7 @@ const Modes = {
50
52
  return _constants.JOB_STATUS.PENDING;
51
53
  }
52
54
 
53
- return _constants.JOB_STATUS.REJECTED;
55
+ return _constants.JOB_STATUS.FAILED;
54
56
  }
55
57
 
56
58
  },
@@ -64,8 +66,10 @@ const Modes = {
64
66
  return _constants.JOB_STATUS.RESOLVED;
65
67
  }
66
68
 
67
- if (result.some(status => status != null && status === _constants.JOB_STATUS.REJECTED)) {
68
- return _constants.JOB_STATUS.REJECTED;
69
+ const failedStatus = result.find(status => status != null && status < _constants.JOB_STATUS.PENDING);
70
+
71
+ if (typeof failedStatus !== 'undefined') {
72
+ return failedStatus;
69
73
  }
70
74
 
71
75
  return _constants.JOB_STATUS.PENDING;
@@ -1,17 +1,18 @@
1
1
  import { AxiosRequestConfig } from 'axios';
2
2
  import { Instruction } from './index';
3
+ import Processor from '../Processor';
4
+ import FlowNodeModel from '../models/FlowNode';
3
5
  export interface Header {
4
6
  name: string;
5
7
  value: string;
6
8
  }
7
- export declare type RequestConfig = Pick<AxiosRequestConfig, 'url' | 'method' | 'data' | 'timeout'> & {
9
+ export declare type RequestConfig = Pick<AxiosRequestConfig, 'url' | 'method' | 'params' | 'data' | 'timeout'> & {
8
10
  headers: Array<Header>;
9
11
  ignoreFail: boolean;
10
12
  };
11
13
  export default class implements Instruction {
12
14
  plugin: any;
13
15
  constructor(plugin: any);
14
- request: (node: any, job: any, processor: any) => Promise<any>;
15
- run(node: any, input: any, processor: any): Promise<any>;
16
- resume(node: any, job: any, processor: any): Promise<any>;
16
+ run(node: FlowNodeModel, input: any, processor: Processor): Promise<any>;
17
+ resume(node: FlowNodeModel, job: any, processor: Processor): Promise<any>;
17
18
  }