@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.
- package/README.md +9 -0
- package/README.zh-CN.md +9 -0
- package/lib/client/AddButton.d.ts +1 -1
- package/lib/client/AddButton.js +43 -27
- package/lib/client/Branch.d.ts +1 -1
- package/lib/client/ExecutionCanvas.js +5 -10
- package/lib/client/WorkflowCanvas.js +12 -42
- package/lib/client/WorkflowProvider.js +10 -1
- package/lib/client/components/CollectionBlockInitializer.d.ts +7 -0
- package/lib/client/components/CollectionBlockInitializer.js +81 -0
- package/lib/client/components/CollectionFieldInitializers.d.ts +2 -0
- package/lib/client/components/CollectionFieldInitializers.js +89 -0
- package/lib/client/components/CollectionFieldset.js +25 -33
- package/lib/client/components/FilterDynamicComponent.d.ts +6 -0
- package/lib/client/components/FilterDynamicComponent.js +43 -0
- package/lib/client/components/NullRender.d.ts +1 -0
- package/lib/client/components/NullRender.js +10 -0
- package/lib/client/components/RadioWithTooltip.d.ts +7 -0
- package/lib/client/components/RadioWithTooltip.js +94 -0
- package/lib/client/constants.d.ts +10 -8
- package/lib/client/constants.js +52 -14
- package/lib/client/index.d.ts +0 -1
- package/lib/client/index.js +1 -10
- package/lib/client/locale/en-US.d.ts +18 -18
- package/lib/client/locale/en-US.js +19 -19
- package/lib/client/locale/zh-CN.d.ts +47 -20
- package/lib/client/locale/zh-CN.js +48 -21
- package/lib/client/nodes/calculation.d.ts +39 -7
- package/lib/client/nodes/calculation.js +165 -19
- package/lib/client/nodes/condition.d.ts +67 -4
- package/lib/client/nodes/condition.js +283 -31
- package/lib/client/nodes/create.d.ts +10 -10
- package/lib/client/nodes/create.js +28 -42
- package/lib/client/nodes/delay.d.ts +4 -4
- package/lib/client/nodes/delay.js +10 -8
- package/lib/client/nodes/destroy.d.ts +4 -7
- package/lib/client/nodes/destroy.js +4 -5
- package/lib/client/nodes/index.d.ts +10 -2
- package/lib/client/nodes/index.js +217 -110
- package/lib/client/nodes/manual/AssigneesSelect.d.ts +6 -0
- package/lib/client/nodes/manual/AssigneesSelect.js +65 -0
- package/lib/client/nodes/manual/ModeConfig.d.ts +5 -0
- package/lib/client/nodes/manual/ModeConfig.js +160 -0
- package/lib/client/nodes/manual/SchemaConfig.d.ts +6 -0
- package/lib/client/nodes/manual/SchemaConfig.js +715 -0
- package/lib/client/nodes/manual/WorkflowTodo.d.ts +8 -0
- package/lib/client/nodes/manual/WorkflowTodo.js +691 -0
- package/lib/client/nodes/manual/WorkflowTodoBlockInitializer.d.ts +5 -0
- package/lib/client/nodes/manual/WorkflowTodoBlockInitializer.js +75 -0
- package/lib/client/nodes/manual/index.d.ts +62 -0
- package/lib/client/nodes/manual/index.js +137 -0
- package/lib/client/nodes/parallel.d.ts +12 -7
- package/lib/client/nodes/parallel.js +32 -39
- package/lib/client/nodes/query.d.ts +11 -19
- package/lib/client/nodes/query.js +40 -47
- package/lib/client/nodes/request.d.ts +77 -42
- package/lib/client/nodes/request.js +123 -69
- package/lib/client/nodes/update.d.ts +33 -29
- package/lib/client/nodes/update.js +14 -7
- package/lib/client/schemas/collection.d.ts +0 -3
- package/lib/client/schemas/collection.js +2 -7
- package/lib/client/schemas/executions.js +1 -1
- package/lib/client/schemas/workflows.js +1 -1
- package/lib/client/style.js +51 -9
- package/lib/client/triggers/collection.d.ts +44 -15
- package/lib/client/triggers/collection.js +104 -82
- package/lib/client/triggers/index.d.ts +6 -3
- package/lib/client/triggers/index.js +167 -74
- package/lib/client/triggers/schedule/DateFieldsSelect.js +1 -3
- package/lib/client/triggers/schedule/ScheduleConfig.js +15 -17
- package/lib/client/triggers/schedule/index.d.ts +7 -6
- package/lib/client/triggers/schedule/index.js +39 -81
- package/lib/client/utils.d.ts +1 -0
- package/lib/client/utils.js +38 -0
- package/lib/client/variable.d.ts +21 -0
- package/lib/client/variable.js +147 -0
- package/lib/server/Plugin.d.ts +3 -3
- package/lib/server/Plugin.js +12 -21
- package/lib/server/Processor.d.ts +9 -2
- package/lib/server/Processor.js +33 -33
- package/lib/server/actions/index.js +2 -4
- package/lib/server/actions/workflows.d.ts +1 -0
- package/lib/server/actions/workflows.js +80 -23
- package/lib/server/collections/executions.js +5 -7
- package/lib/server/collections/flow_nodes.js +6 -18
- package/lib/server/collections/jobs.js +3 -1
- package/lib/server/collections/workflows.js +8 -4
- package/lib/server/constants.d.ts +9 -3
- package/lib/server/constants.js +11 -5
- package/lib/server/functions/index.d.ts +4 -0
- package/lib/server/functions/index.js +38 -0
- package/lib/server/index.d.ts +0 -1
- package/lib/server/index.js +0 -14
- package/lib/server/instructions/calculation.d.ts +2 -7
- package/lib/server/instructions/calculation.js +32 -37
- package/lib/server/instructions/condition.d.ts +4 -4
- package/lib/server/instructions/condition.js +126 -54
- package/lib/server/instructions/index.js +1 -1
- package/lib/server/instructions/manual/actions.js +101 -0
- package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/jobs.d.ts +2 -0
- package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/jobs.js +2 -1
- package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/users_jobs.js +10 -10
- package/lib/server/instructions/manual/index.d.ts +25 -0
- package/lib/server/instructions/manual/index.js +200 -0
- package/lib/server/instructions/parallel.js +11 -7
- package/lib/server/instructions/request.d.ts +5 -4
- package/lib/server/instructions/request.js +60 -79
- package/lib/server/migrations/20230221032941-change-request-body-type.d.ts +5 -0
- package/lib/server/migrations/20230221032941-change-request-body-type.js +113 -0
- package/lib/server/migrations/20230221071831-calculation-expression.d.ts +4 -0
- package/lib/server/migrations/20230221071831-calculation-expression.js +143 -0
- package/lib/server/migrations/20230221121203-condition-calculation.d.ts +4 -0
- package/lib/server/migrations/20230221121203-condition-calculation.js +126 -0
- package/lib/server/migrations/20230221162902-jsonb-to-json.d.ts +4 -0
- package/lib/server/migrations/20230221162902-jsonb-to-json.js +81 -0
- package/lib/server/triggers/schedule.js +11 -3
- package/package.json +10 -10
- package/lib/client/calculators.d.ts +0 -89
- package/lib/client/calculators.js +0 -668
- package/lib/client/components/CollectionFieldSelect.d.ts +0 -2
- package/lib/client/components/CollectionFieldSelect.js +0 -106
- package/lib/client/components/EjsTextArea.d.ts +0 -2
- package/lib/client/components/EjsTextArea.js +0 -232
- package/lib/server/actions/jobs.d.ts +0 -2
- package/lib/server/actions/jobs.js +0 -39
- package/lib/server/calculators/index.d.ts +0 -40
- package/lib/server/calculators/index.js +0 -187
- package/lib/server/extensions/assignees/actions.js +0 -75
- package/lib/server/extensions/assignees/index.d.ts +0 -2
- package/lib/server/extensions/assignees/index.js +0 -273
- package/lib/server/extensions/index.d.ts +0 -3
- package/lib/server/extensions/index.js +0 -13
- package/lib/server/instructions/prompt.d.ts +0 -19
- package/lib/server/instructions/prompt.js +0 -131
- /package/lib/server/{extensions/assignees → instructions/manual}/actions.d.ts +0 -0
- /package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/users.d.ts +0 -0
- /package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/users.js +0 -0
- /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
|
-
|
|
8
|
+
function _utils() {
|
|
9
|
+
const data = require("@nocobase/utils");
|
|
9
10
|
|
|
10
|
-
|
|
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
|
-
|
|
21
|
+
_evaluators = function _evaluators() {
|
|
22
|
+
return data;
|
|
23
|
+
};
|
|
13
24
|
|
|
14
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
53
|
-
group = calculation.group;
|
|
54
|
-
let result;
|
|
38
|
+
exports.calculators = calculators;
|
|
55
39
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
44
|
+
function notEqual(a, b) {
|
|
45
|
+
return a !== b;
|
|
46
|
+
}
|
|
63
47
|
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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.
|
|
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', '
|
|
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
|
+
}
|
package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/jobs.d.ts
RENAMED
|
@@ -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
|
};
|
package/lib/server/{extensions/assignees/collections → instructions/manual/collecions}/users_jobs.js
RENAMED
|
@@ -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
|
|
23
|
+
return previous.status >= _constants.JOB_STATUS.PENDING;
|
|
24
24
|
},
|
|
25
25
|
|
|
26
26
|
getStatus(result) {
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
68
|
-
|
|
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
|
-
|
|
15
|
-
|
|
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
|
}
|