@nocobase/plugin-workflow 0.12.0-alpha.2 → 0.12.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.
- package/dist/client/components/DrawerDescription.d.ts +2 -0
- package/dist/client/components/ExecutionStatusSelect.d.ts +4 -0
- package/dist/client/components/StatusIcon.d.ts +2 -0
- package/dist/client/constants.d.ts +1 -0
- package/dist/client/index.js +2268 -319
- package/dist/client/nodes/create.d.ts +1 -0
- package/dist/client/nodes/query.d.ts +136 -2
- package/dist/client/schemas/collection.d.ts +112 -0
- package/dist/client/schemas/executions.d.ts +17 -2
- package/dist/client/style.d.ts +2 -0
- package/dist/client/triggers/collection.d.ts +2 -0
- package/dist/client/triggers/form.d.ts +50 -0
- package/dist/client/triggers/index.d.ts +1 -0
- package/dist/client/triggers/schedule/index.d.ts +2 -1
- package/dist/locale/zh-CN.d.ts +33 -0
- package/dist/locale/zh-CN.js +33 -0
- package/dist/node_modules/cron-parser/package.json +1 -1
- package/dist/node_modules/lru-cache/package.json +1 -1
- package/dist/server/Plugin.js +10 -2
- package/dist/server/Processor.js +6 -5
- package/dist/server/actions/executions.d.ts +2 -0
- package/dist/server/actions/executions.js +22 -0
- package/dist/server/actions/index.js +4 -1
- package/dist/server/actions/workflows.d.ts +1 -0
- package/dist/server/actions/workflows.js +19 -3
- package/dist/server/collections/workflows.js +5 -0
- package/dist/server/instructions/query.js +12 -1
- package/dist/server/migrations/20230809113132-workflow-options.d.ts +4 -0
- package/dist/server/migrations/20230809113132-workflow-options.js +34 -0
- package/dist/server/triggers/form.d.ts +11 -0
- package/dist/server/triggers/form.js +89 -0
- package/dist/server/triggers/index.js +2 -1
- package/package.json +2 -2
- package/dist/client/components/NodeDescription.d.ts +0 -2
package/dist/server/Processor.js
CHANGED
|
@@ -48,20 +48,21 @@ class Processor {
|
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
async getTransaction() {
|
|
51
|
-
|
|
51
|
+
var _a;
|
|
52
|
+
if (!((_a = this.execution.workflow.options) == null ? void 0 : _a.useTransaction)) {
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
55
|
const { options } = this;
|
|
55
56
|
return options.transaction && !options.transaction.finished ? options.transaction : await options.plugin.db.sequelize.transaction();
|
|
56
57
|
}
|
|
57
58
|
async prepare() {
|
|
58
|
-
const transaction = await this.getTransaction();
|
|
59
|
-
this.transaction = transaction;
|
|
60
59
|
const { execution } = this;
|
|
61
60
|
if (!execution.workflow) {
|
|
62
|
-
execution.workflow = await execution.getWorkflow(
|
|
61
|
+
execution.workflow = await execution.getWorkflow();
|
|
63
62
|
}
|
|
64
|
-
const
|
|
63
|
+
const transaction = await this.getTransaction();
|
|
64
|
+
this.transaction = transaction;
|
|
65
|
+
const nodes = await execution.workflow.getNodes();
|
|
65
66
|
this.makeNodes(nodes);
|
|
66
67
|
const jobs = await execution.getJobs({
|
|
67
68
|
order: [["id", "ASC"]],
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var actions = require('@nocobase/actions');
|
|
4
|
+
var database = require('@nocobase/database');
|
|
5
|
+
var constants = require('../constants');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var actions__default = /*#__PURE__*/_interopDefault(actions);
|
|
10
|
+
|
|
11
|
+
async function destroy(context, next) {
|
|
12
|
+
context.action.mergeParams({
|
|
13
|
+
filter: {
|
|
14
|
+
status: {
|
|
15
|
+
[database.Op.ne]: constants.EXECUTION_STATUS.STARTED
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
await actions__default.default.destroy(context, next);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
exports.destroy = destroy;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var workflows = require('./workflows');
|
|
4
4
|
var nodes = require('./nodes');
|
|
5
|
+
var executions = require('./executions');
|
|
5
6
|
|
|
6
7
|
function _interopNamespace(e) {
|
|
7
8
|
if (e && e.__esModule) return e;
|
|
@@ -23,6 +24,7 @@ function _interopNamespace(e) {
|
|
|
23
24
|
|
|
24
25
|
var workflows__namespace = /*#__PURE__*/_interopNamespace(workflows);
|
|
25
26
|
var nodes__namespace = /*#__PURE__*/_interopNamespace(nodes);
|
|
27
|
+
var executions__namespace = /*#__PURE__*/_interopNamespace(executions);
|
|
26
28
|
|
|
27
29
|
function make(name, mod) {
|
|
28
30
|
return Object.keys(mod).reduce(
|
|
@@ -42,7 +44,8 @@ function actions_default({ app }) {
|
|
|
42
44
|
}),
|
|
43
45
|
...make("flow_nodes", {
|
|
44
46
|
update: nodes__namespace.update
|
|
45
|
-
})
|
|
47
|
+
}),
|
|
48
|
+
...make("executions", executions__namespace)
|
|
46
49
|
});
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -2,3 +2,4 @@ import { Context } from '@nocobase/actions';
|
|
|
2
2
|
export declare function update(context: Context, next: any): Promise<void>;
|
|
3
3
|
export declare function destroy(context: Context, next: any): Promise<void>;
|
|
4
4
|
export declare function revision(context: Context, next: any): Promise<void>;
|
|
5
|
+
export declare function sync(context: Context, next: any): Promise<void>;
|
|
@@ -11,7 +11,7 @@ async function update(context, next) {
|
|
|
11
11
|
const repository = actions.utils.getRepositoryFromParams(context);
|
|
12
12
|
const { filterByTk, values } = context.action.params;
|
|
13
13
|
context.action.mergeParams({
|
|
14
|
-
whitelist: ["title", "description", "enabled", "config"]
|
|
14
|
+
whitelist: ["title", "description", "enabled", "config", "options"]
|
|
15
15
|
});
|
|
16
16
|
if (Object.keys(values).includes("config")) {
|
|
17
17
|
const workflow = await repository.findById(filterByTk);
|
|
@@ -94,7 +94,7 @@ function migrateConfig(config, oldToNew) {
|
|
|
94
94
|
async function revision(context, next) {
|
|
95
95
|
const { db } = context;
|
|
96
96
|
const repository = actions.utils.getRepositoryFromParams(context);
|
|
97
|
-
const { filterByTk, filter = {} } = context.action.params;
|
|
97
|
+
const { filterByTk, filter = {}, values = {} } = context.action.params;
|
|
98
98
|
context.body = await db.sequelize.transaction(async (transaction) => {
|
|
99
99
|
const origin = await repository.findOne({
|
|
100
100
|
filterByTk,
|
|
@@ -107,7 +107,7 @@ async function revision(context, next) {
|
|
|
107
107
|
key: filter.key,
|
|
108
108
|
title: origin.title,
|
|
109
109
|
allExecuted: origin.allExecuted
|
|
110
|
-
} :
|
|
110
|
+
} : values;
|
|
111
111
|
const instance = await repository.create({
|
|
112
112
|
values: {
|
|
113
113
|
title: `${origin.title} copy`,
|
|
@@ -160,7 +160,23 @@ async function revision(context, next) {
|
|
|
160
160
|
});
|
|
161
161
|
await next();
|
|
162
162
|
}
|
|
163
|
+
async function sync(context, next) {
|
|
164
|
+
const plugin = context.app.getPlugin("workflow");
|
|
165
|
+
const repository = actions.utils.getRepositoryFromParams(context);
|
|
166
|
+
const { filterByTk, filter = {} } = context.action.params;
|
|
167
|
+
const workflows = await repository.find({
|
|
168
|
+
filterByTk,
|
|
169
|
+
filter
|
|
170
|
+
});
|
|
171
|
+
workflows.forEach((workflow) => {
|
|
172
|
+
plugin.toggle(workflow, false);
|
|
173
|
+
plugin.toggle(workflow);
|
|
174
|
+
});
|
|
175
|
+
context.status = 204;
|
|
176
|
+
await next();
|
|
177
|
+
}
|
|
163
178
|
|
|
164
179
|
exports.destroy = destroy;
|
|
165
180
|
exports.revision = revision;
|
|
181
|
+
exports.sync = sync;
|
|
166
182
|
exports.update = update;
|
|
@@ -75,6 +75,11 @@ function workflows_default() {
|
|
|
75
75
|
// NOTE: no constraints needed here because tricky self-referencing
|
|
76
76
|
constraints: false,
|
|
77
77
|
onDelete: "NO ACTION"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: "jsonb",
|
|
81
|
+
name: "options",
|
|
82
|
+
defaultValue: {}
|
|
78
83
|
}
|
|
79
84
|
],
|
|
80
85
|
// NOTE: use unique index for avoiding deadlock in mysql when setCurrent
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var actions = require('@nocobase/actions');
|
|
3
4
|
var constants = require('../constants');
|
|
4
5
|
var utils = require('../utils');
|
|
5
6
|
|
|
@@ -7,7 +8,12 @@ var query_default = {
|
|
|
7
8
|
async run(node, input, processor) {
|
|
8
9
|
const { collection, multiple, params = {}, failOnEmpty = false } = node.config;
|
|
9
10
|
const repo = node.constructor.database.getRepository(collection);
|
|
10
|
-
const
|
|
11
|
+
const {
|
|
12
|
+
page = actions.DEFAULT_PAGE,
|
|
13
|
+
pageSize = actions.DEFAULT_PER_PAGE,
|
|
14
|
+
sort = [],
|
|
15
|
+
...options
|
|
16
|
+
} = processor.getParsedValue(params, node);
|
|
11
17
|
const appends = options.appends ? Array.from(
|
|
12
18
|
options.appends.reduce((set, field) => {
|
|
13
19
|
set.add(field.split(".")[0]);
|
|
@@ -17,6 +23,11 @@ var query_default = {
|
|
|
17
23
|
) : options.appends;
|
|
18
24
|
const result = await (multiple ? repo.find : repo.findOne).call(repo, {
|
|
19
25
|
...options,
|
|
26
|
+
...actions.utils.pageArgsToLimitArgs(page, pageSize),
|
|
27
|
+
sort: sort.filter((item) => item.field).map((item) => {
|
|
28
|
+
var _a;
|
|
29
|
+
return `${((_a = item.direction) == null ? void 0 : _a.toLowerCase()) === "desc" ? "-" : ""}${item.field}`;
|
|
30
|
+
}),
|
|
20
31
|
appends,
|
|
21
32
|
transaction: processor.transaction
|
|
22
33
|
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var server = require('@nocobase/server');
|
|
4
|
+
|
|
5
|
+
class workflow_options_default extends server.Migration {
|
|
6
|
+
async up() {
|
|
7
|
+
const match = await this.app.version.satisfies("<0.11.0-alpha.2");
|
|
8
|
+
if (!match) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const { db } = this.context;
|
|
12
|
+
const WorkflowRepo = db.getRepository("flow_nodes");
|
|
13
|
+
await db.sequelize.transaction(async (transaction) => {
|
|
14
|
+
const workflows = await WorkflowRepo.find({
|
|
15
|
+
transaction
|
|
16
|
+
});
|
|
17
|
+
await workflows.reduce(
|
|
18
|
+
(promise, workflow) => promise.then(() => {
|
|
19
|
+
workflow.set("options", {
|
|
20
|
+
useTransaction: workflow.get("useTransaction")
|
|
21
|
+
});
|
|
22
|
+
workflow.changed("options", true);
|
|
23
|
+
return workflow.save({
|
|
24
|
+
silent: true,
|
|
25
|
+
transaction
|
|
26
|
+
});
|
|
27
|
+
}),
|
|
28
|
+
Promise.resolve()
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = workflow_options_default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Trigger } from '.';
|
|
2
|
+
import Plugin from '..';
|
|
3
|
+
import { WorkflowModel } from '../types';
|
|
4
|
+
export default class FormTrigger extends Trigger {
|
|
5
|
+
constructor(plugin: Plugin);
|
|
6
|
+
triggerAction: (context: any, next: any) => Promise<any>;
|
|
7
|
+
middleware: (context: any, next: any) => Promise<void>;
|
|
8
|
+
trigger(context: any): Promise<void>;
|
|
9
|
+
on(workflow: WorkflowModel): void;
|
|
10
|
+
off(workflow: WorkflowModel): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lodash = require('lodash');
|
|
4
|
+
var _ = require('.');
|
|
5
|
+
var database = require('@nocobase/database');
|
|
6
|
+
|
|
7
|
+
class FormTrigger extends _.Trigger {
|
|
8
|
+
constructor(plugin) {
|
|
9
|
+
super(plugin);
|
|
10
|
+
plugin.app.resourcer.use(this.middleware);
|
|
11
|
+
plugin.app.actions({
|
|
12
|
+
["workflows:trigger"]: this.triggerAction
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
triggerAction = async (context, next) => {
|
|
16
|
+
const { triggerWorkflows } = context.action.params;
|
|
17
|
+
if (!triggerWorkflows) {
|
|
18
|
+
return context.throw(400);
|
|
19
|
+
}
|
|
20
|
+
context.status = 202;
|
|
21
|
+
await next();
|
|
22
|
+
this.trigger(context);
|
|
23
|
+
};
|
|
24
|
+
middleware = async (context, next) => {
|
|
25
|
+
await next();
|
|
26
|
+
const { resourceName, actionName } = context.action;
|
|
27
|
+
if (resourceName === "workflows" && actionName === "trigger" || !["create", "update"].includes(actionName)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this.trigger(context);
|
|
31
|
+
};
|
|
32
|
+
async trigger(context) {
|
|
33
|
+
const { triggerWorkflows, values } = context.action.params;
|
|
34
|
+
if (!triggerWorkflows) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const triggers = triggerWorkflows.split(",").map((trigger) => trigger.split("!"));
|
|
38
|
+
const workflowRepo = this.plugin.db.getRepository("workflows");
|
|
39
|
+
const workflows = await workflowRepo.find({
|
|
40
|
+
filter: {
|
|
41
|
+
key: triggers.map((trigger) => trigger[0]),
|
|
42
|
+
current: true,
|
|
43
|
+
type: "form",
|
|
44
|
+
enabled: true
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
workflows.forEach((workflow) => {
|
|
48
|
+
var _a;
|
|
49
|
+
const trigger = triggers.find((trigger2) => trigger2[0] == workflow.key);
|
|
50
|
+
if ((_a = context.body) == null ? void 0 : _a.data) {
|
|
51
|
+
const { data } = context.body;
|
|
52
|
+
(Array.isArray(data) ? data : [data]).forEach(async (row) => {
|
|
53
|
+
let payload = row;
|
|
54
|
+
if (trigger[1]) {
|
|
55
|
+
const paths = trigger[1].split(".");
|
|
56
|
+
for await (const field of paths) {
|
|
57
|
+
if (payload.get(field)) {
|
|
58
|
+
payload = payload.get(field);
|
|
59
|
+
} else {
|
|
60
|
+
const association = database.modelAssociationByKey(payload, field);
|
|
61
|
+
payload = await payload[association.accessors.get]();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const { collection, appends = [] } = workflow.config;
|
|
66
|
+
const model = payload.constructor;
|
|
67
|
+
if (collection !== model.collection.name) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (appends.length) {
|
|
71
|
+
payload = await model.collection.repository.findOne({
|
|
72
|
+
filterByTk: payload.get(model.primaryKeyAttribute),
|
|
73
|
+
appends
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
this.plugin.trigger(workflow, { data: payload });
|
|
77
|
+
});
|
|
78
|
+
} else {
|
|
79
|
+
this.plugin.trigger(workflow, { data: trigger[1] ? lodash.get(values, trigger[1]) : values });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
on(workflow) {
|
|
84
|
+
}
|
|
85
|
+
off(workflow) {
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = FormTrigger;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var path = require('path');
|
|
6
5
|
var utils = require('@nocobase/utils');
|
|
6
|
+
var path = require('path');
|
|
7
7
|
|
|
8
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
9
|
|
|
@@ -17,6 +17,7 @@ class Trigger {
|
|
|
17
17
|
function triggers_default(plugin, more = {}) {
|
|
18
18
|
const { triggers } = plugin;
|
|
19
19
|
triggers.register("collection", new (utils.requireModule(path__default.default.join(__dirname, "collection")))(plugin));
|
|
20
|
+
triggers.register("form", new (utils.requireModule(path__default.default.join(__dirname, "form")))(plugin));
|
|
20
21
|
triggers.register("schedule", new (utils.requireModule(path__default.default.join(__dirname, "schedule")))(plugin));
|
|
21
22
|
for (const [name, TClass] of Object.entries(more)) {
|
|
22
23
|
triggers.register(name, new TClass(plugin));
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"displayName.zh-CN": "工作流",
|
|
5
5
|
"description": "A powerful workflow plugin designed to support business process management and automation.",
|
|
6
6
|
"description.zh-CN": "工作流插件,为业务流程管理和自动化提供支持。",
|
|
7
|
-
"version": "0.12.0-alpha.
|
|
7
|
+
"version": "0.12.0-alpha.4",
|
|
8
8
|
"license": "AGPL-3.0",
|
|
9
9
|
"main": "./dist/server/index.js",
|
|
10
10
|
"devDependencies": {
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"@nocobase/test": "0.x",
|
|
41
41
|
"@nocobase/utils": "0.x"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "215dc3b2437c501ca903b56cc378ab5e81c8a11c"
|
|
44
44
|
}
|