@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.
Files changed (34) hide show
  1. package/dist/client/components/DrawerDescription.d.ts +2 -0
  2. package/dist/client/components/ExecutionStatusSelect.d.ts +4 -0
  3. package/dist/client/components/StatusIcon.d.ts +2 -0
  4. package/dist/client/constants.d.ts +1 -0
  5. package/dist/client/index.js +2268 -319
  6. package/dist/client/nodes/create.d.ts +1 -0
  7. package/dist/client/nodes/query.d.ts +136 -2
  8. package/dist/client/schemas/collection.d.ts +112 -0
  9. package/dist/client/schemas/executions.d.ts +17 -2
  10. package/dist/client/style.d.ts +2 -0
  11. package/dist/client/triggers/collection.d.ts +2 -0
  12. package/dist/client/triggers/form.d.ts +50 -0
  13. package/dist/client/triggers/index.d.ts +1 -0
  14. package/dist/client/triggers/schedule/index.d.ts +2 -1
  15. package/dist/locale/zh-CN.d.ts +33 -0
  16. package/dist/locale/zh-CN.js +33 -0
  17. package/dist/node_modules/cron-parser/package.json +1 -1
  18. package/dist/node_modules/lru-cache/package.json +1 -1
  19. package/dist/server/Plugin.js +10 -2
  20. package/dist/server/Processor.js +6 -5
  21. package/dist/server/actions/executions.d.ts +2 -0
  22. package/dist/server/actions/executions.js +22 -0
  23. package/dist/server/actions/index.js +4 -1
  24. package/dist/server/actions/workflows.d.ts +1 -0
  25. package/dist/server/actions/workflows.js +19 -3
  26. package/dist/server/collections/workflows.js +5 -0
  27. package/dist/server/instructions/query.js +12 -1
  28. package/dist/server/migrations/20230809113132-workflow-options.d.ts +4 -0
  29. package/dist/server/migrations/20230809113132-workflow-options.js +34 -0
  30. package/dist/server/triggers/form.d.ts +11 -0
  31. package/dist/server/triggers/form.js +89 -0
  32. package/dist/server/triggers/index.js +2 -1
  33. package/package.json +2 -2
  34. package/dist/client/components/NodeDescription.d.ts +0 -2
@@ -48,20 +48,21 @@ class Processor {
48
48
  });
49
49
  }
50
50
  async getTransaction() {
51
- if (!this.execution.useTransaction) {
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({ transaction });
61
+ execution.workflow = await execution.getWorkflow();
63
62
  }
64
- const nodes = await execution.workflow.getNodes({ transaction });
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,2 @@
1
+ import { Context } from '@nocobase/actions';
2
+ export declare function destroy(context: Context, next: any): Promise<void>;
@@ -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 options = processor.getParsedValue(params, node);
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,4 @@
1
+ import { Migration } from '@nocobase/server';
2
+ export default class extends Migration {
3
+ up(): Promise<void>;
4
+ }
@@ -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.2",
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": "a95e9e2666f0318c955113a4735bc005a2c9a767"
43
+ "gitHead": "215dc3b2437c501ca903b56cc378ab5e81c8a11c"
44
44
  }
@@ -1,2 +0,0 @@
1
- import React from 'react';
2
- export declare function NodeDescription(props: any): React.JSX.Element;