@nocobase/plugin-workflow 0.9.2-alpha.4 → 0.9.4-alpha.1

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 (78) hide show
  1. package/lib/client/CanvasContent.d.ts +4 -0
  2. package/lib/client/CanvasContent.js +49 -0
  3. package/lib/client/ExecutionCanvas.js +110 -44
  4. package/lib/client/WorkflowCanvas.js +35 -18
  5. package/lib/client/components/CollectionFieldset.js +2 -2
  6. package/lib/client/components/FieldsSelect.js +2 -1
  7. package/lib/client/components/NodeDescription.d.ts +2 -0
  8. package/lib/client/components/NodeDescription.js +59 -0
  9. package/lib/client/components/ValueBlock.d.ts +5 -0
  10. package/lib/client/components/ValueBlock.js +110 -0
  11. package/lib/client/index.d.ts +1 -0
  12. package/lib/client/index.js +12 -0
  13. package/lib/client/locale/es-ES.d.ts +130 -0
  14. package/lib/client/locale/es-ES.js +136 -0
  15. package/lib/client/locale/zh-CN.d.ts +35 -6
  16. package/lib/client/locale/zh-CN.js +35 -6
  17. package/lib/client/nodes/aggregate.d.ts +186 -0
  18. package/lib/client/nodes/aggregate.js +349 -0
  19. package/lib/client/nodes/calculation.d.ts +2 -1
  20. package/lib/client/nodes/calculation.js +35 -60
  21. package/lib/client/nodes/condition.d.ts +2 -6
  22. package/lib/client/nodes/condition.js +4 -3
  23. package/lib/client/nodes/create.d.ts +6 -3
  24. package/lib/client/nodes/create.js +16 -7
  25. package/lib/client/nodes/delay.d.ts +1 -0
  26. package/lib/client/nodes/delay.js +1 -0
  27. package/lib/client/nodes/destroy.d.ts +3 -2
  28. package/lib/client/nodes/destroy.js +1 -0
  29. package/lib/client/nodes/index.d.ts +5 -2
  30. package/lib/client/nodes/index.js +96 -105
  31. package/lib/client/nodes/loop.d.ts +29 -0
  32. package/lib/client/nodes/loop.js +165 -0
  33. package/lib/client/nodes/manual/AssigneesSelect.js +8 -6
  34. package/lib/client/nodes/manual/WorkflowTodo.js +1 -8
  35. package/lib/client/nodes/manual/index.d.ts +6 -1
  36. package/lib/client/nodes/manual/index.js +6 -1
  37. package/lib/client/nodes/parallel.d.ts +1 -0
  38. package/lib/client/nodes/parallel.js +2 -1
  39. package/lib/client/nodes/query.d.ts +13 -3
  40. package/lib/client/nodes/query.js +24 -17
  41. package/lib/client/nodes/request.d.ts +1 -0
  42. package/lib/client/nodes/request.js +1 -0
  43. package/lib/client/nodes/update.d.ts +3 -2
  44. package/lib/client/nodes/update.js +1 -0
  45. package/lib/client/schemas/collection.d.ts +2 -2
  46. package/lib/client/schemas/collection.js +5 -5
  47. package/lib/client/style.d.ts +1 -0
  48. package/lib/client/style.js +40 -26
  49. package/lib/client/triggers/collection.d.ts +4 -11
  50. package/lib/client/triggers/collection.js +7 -7
  51. package/lib/client/triggers/index.d.ts +1 -1
  52. package/lib/client/triggers/index.js +5 -3
  53. package/lib/client/triggers/schedule/index.d.ts +3 -1
  54. package/lib/client/triggers/schedule/index.js +6 -4
  55. package/lib/client/variable.d.ts +27 -1
  56. package/lib/client/variable.js +66 -35
  57. package/lib/server/Plugin.d.ts +5 -2
  58. package/lib/server/Plugin.js +2 -14
  59. package/lib/server/Processor.d.ts +3 -0
  60. package/lib/server/Processor.js +34 -8
  61. package/lib/server/actions/workflows.js +2 -2
  62. package/lib/server/collections/workflows.js +2 -1
  63. package/lib/server/functions/index.d.ts +7 -1
  64. package/lib/server/instructions/aggregate.d.ts +9 -0
  65. package/lib/server/instructions/aggregate.js +57 -0
  66. package/lib/server/instructions/calculation.js +6 -7
  67. package/lib/server/instructions/condition.js +1 -1
  68. package/lib/server/instructions/create.js +1 -1
  69. package/lib/server/instructions/destroy.js +1 -1
  70. package/lib/server/instructions/index.d.ts +1 -0
  71. package/lib/server/instructions/index.js +1 -1
  72. package/lib/server/instructions/loop.d.ts +16 -0
  73. package/lib/server/instructions/loop.js +107 -0
  74. package/lib/server/instructions/parallel.js +17 -10
  75. package/lib/server/instructions/query.js +1 -4
  76. package/lib/server/instructions/request.js +1 -1
  77. package/lib/server/instructions/update.js +1 -1
  78. package/package.json +13 -14
@@ -11,6 +11,7 @@ exports.RemoveButton = RemoveButton;
11
11
  exports.instructions = void 0;
12
12
  exports.useAvailableUpstreams = useAvailableUpstreams;
13
13
  exports.useNodeContext = useNodeContext;
14
+ exports.useUpstreamScopes = useUpstreamScopes;
14
15
  function _react() {
15
16
  const data = _interopRequireWildcard(require("react"));
16
17
  _react = function _react() {
@@ -53,13 +54,6 @@ function _reactI18next() {
53
54
  };
54
55
  return data;
55
56
  }
56
- function _jsonTemplates() {
57
- const data = _interopRequireDefault(require("json-templates"));
58
- _jsonTemplates = function _jsonTemplates() {
59
- return data;
60
- };
61
- return data;
62
- }
63
57
  function _client() {
64
58
  const data = require("@nocobase/utils/client");
65
59
  _client = function _client() {
@@ -80,42 +74,50 @@ var _FlowContext = require("../FlowContext");
80
74
  var _calculation = _interopRequireDefault(require("./calculation"));
81
75
  var _condition = _interopRequireDefault(require("./condition"));
82
76
  var _parallel = _interopRequireDefault(require("./parallel"));
77
+ var _loop = _interopRequireDefault(require("./loop"));
83
78
  var _delay = _interopRequireDefault(require("./delay"));
84
79
  var _manual = _interopRequireDefault(require("./manual"));
85
80
  var _query = _interopRequireDefault(require("./query"));
86
81
  var _create = _interopRequireDefault(require("./create"));
87
82
  var _update = _interopRequireDefault(require("./update"));
88
83
  var _destroy = _interopRequireDefault(require("./destroy"));
84
+ var _aggregate = _interopRequireDefault(require("./aggregate"));
89
85
  var _constants = require("../constants");
90
86
  var _locale = require("../locale");
91
87
  var _request = _interopRequireDefault(require("./request"));
88
+ var _NodeDescription = require("../components/NodeDescription");
89
+ const _excluded = ["job"];
92
90
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
93
91
  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); }
94
92
  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; }
95
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
96
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
97
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
98
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
99
- function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
100
93
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
101
94
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
102
95
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
103
96
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
104
97
  function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
105
98
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
99
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
100
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
101
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
102
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
103
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
104
+ 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; }
105
+ 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; }
106
106
  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); } }
107
107
  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); }); }; }
108
108
  const instructions = new (_client().Registry)();
109
109
  exports.instructions = instructions;
110
+ instructions.register('calculation', _calculation.default);
110
111
  instructions.register('condition', _condition.default);
111
112
  instructions.register('parallel', _parallel.default);
112
- instructions.register('calculation', _calculation.default);
113
+ instructions.register('loop', _loop.default);
113
114
  instructions.register('delay', _delay.default);
114
115
  instructions.register('manual', _manual.default);
115
116
  instructions.register('query', _query.default);
116
117
  instructions.register('create', _create.default);
117
118
  instructions.register('update', _update.default);
118
119
  instructions.register('destroy', _destroy.default);
120
+ instructions.register('aggregate', _aggregate.default);
119
121
  instructions.register('request', _request.default);
120
122
  function useUpdateAction() {
121
123
  const form = (0, _react2().useForm)();
@@ -162,6 +164,18 @@ function useAvailableUpstreams(node) {
162
164
  }
163
165
  return stack;
164
166
  }
167
+ function useUpstreamScopes(node) {
168
+ const stack = [];
169
+ if (!node) {
170
+ return [];
171
+ }
172
+ for (let current = node; current; current = current.upstream) {
173
+ if (current.upstream && current.branchIndex != null) {
174
+ stack.push(current.upstream);
175
+ }
176
+ }
177
+ return stack;
178
+ }
165
179
  function Node({
166
180
  data
167
181
  }) {
@@ -229,7 +243,7 @@ function RemoveButton() {
229
243
  if (node === current) {
230
244
  return false;
231
245
  }
232
- const template = (0, _jsonTemplates().default)(node.config);
246
+ const template = (0, _client().parse)(node.config);
233
247
  const refs = template.parameters.filter(({
234
248
  key
235
249
  }) => key.startsWith(`$jobsMapByNodeId.${current.id}.`) || key === `$jobsMapByNodeId.${current.id}`);
@@ -262,106 +276,76 @@ function RemoveButton() {
262
276
  className: "workflow-node-remove-button"
263
277
  });
264
278
  }
279
+ function InnerJobButton(_ref2) {
280
+ let job = _ref2.job,
281
+ props = _objectWithoutProperties(_ref2, _excluded);
282
+ const _JobStatusOptionsMap$ = _constants.JobStatusOptionsMap[job.status],
283
+ icon = _JobStatusOptionsMap$.icon,
284
+ color = _JobStatusOptionsMap$.color;
285
+ return _react().default.createElement(_antd().Button, _objectSpread(_objectSpread({}, props), {}, {
286
+ shape: "circle",
287
+ className: _style.nodeJobButtonClass
288
+ }), _react().default.createElement(_antd().Tag, {
289
+ color: color
290
+ }, icon));
291
+ }
265
292
  function JobButton() {
266
293
  var _useNodeContext;
267
- const compile = (0, _client2().useCompile)();
268
294
  const _useFlowContext3 = (0, _FlowContext.useFlowContext)(),
269
- execution = _useFlowContext3.execution;
270
- const _ref2 = (_useNodeContext = useNodeContext()) !== null && _useNodeContext !== void 0 ? _useNodeContext : {},
271
- id = _ref2.id,
272
- type = _ref2.type,
273
- title = _ref2.title,
274
- job = _ref2.job;
295
+ execution = _useFlowContext3.execution,
296
+ setViewJob = _useFlowContext3.setViewJob;
297
+ const _ref3 = (_useNodeContext = useNodeContext()) !== null && _useNodeContext !== void 0 ? _useNodeContext : {},
298
+ jobs = _ref3.jobs;
275
299
  if (!execution) {
276
300
  return null;
277
301
  }
278
- if (!job) {
302
+ if (!jobs.length) {
279
303
  return _react().default.createElement("span", {
280
- className: (0, _css().cx)('workflow-node-job-button', (0, _css().css)`
304
+ className: (0, _css().cx)(_style.nodeJobButtonClass, (0, _css().css)`
281
305
  border: 2px solid #d9d9d9;
282
306
  border-radius: 50%;
283
307
  cursor: not-allowed;
284
308
  `)
285
309
  });
286
310
  }
287
- const instruction = instructions.get(type);
288
- const _JobStatusOptionsMap$ = _constants.JobStatusOptionsMap[job.status],
289
- value = _JobStatusOptionsMap$.value,
290
- icon = _JobStatusOptionsMap$.icon,
291
- color = _JobStatusOptionsMap$.color;
292
- return _react().default.createElement(_client2().SchemaComponent, {
293
- schema: {
294
- type: 'void',
295
- properties: {
296
- [`${job.id}-button`]: {
297
- type: 'void',
298
- 'x-component': 'Action',
299
- 'x-component-props': {
300
- title: _react().default.createElement(_antd().Tag, {
301
- color: color
302
- }, icon),
303
- shape: 'circle',
304
- className: ['workflow-node-job-button', (0, _css().css)`
305
- .ant-tag {
306
- padding: 0;
307
- width: 100%;
308
- line-height: 18px;
309
- margin-right: 0;
310
- border-radius: 50%;
311
+ function onOpenJob({
312
+ key
313
+ }) {
314
+ const job = jobs.find(item => item.id == key);
315
+ setViewJob(job);
316
+ }
317
+ return jobs.length > 1 ? _react().default.createElement(_antd().Dropdown, {
318
+ menu: {
319
+ items: jobs.map(job => {
320
+ const _JobStatusOptionsMap$2 = _constants.JobStatusOptionsMap[job.status],
321
+ icon = _JobStatusOptionsMap$2.icon,
322
+ color = _JobStatusOptionsMap$2.color;
323
+ return {
324
+ key: job.id,
325
+ label: _react().default.createElement("div", {
326
+ className: (0, _css().css)`
327
+ display: flex;
328
+ gap: 0.5em;
329
+
330
+ time {
331
+ color: #999;
332
+ font-size: 0.8em;
311
333
  }
312
- `]
313
- },
314
- properties: {
315
- [`${job.id}-modal`]: {
316
- type: 'void',
317
- 'x-decorator': 'Form',
318
- 'x-decorator-props': {
319
- initialValue: job
320
- },
321
- 'x-component': 'Action.Modal',
322
- title: _react().default.createElement("div", {
323
- className: (0, _css().cx)(_style.nodeTitleClass)
324
- }, _react().default.createElement(_antd().Tag, null, compile(instruction.title)), _react().default.createElement("strong", null, title), _react().default.createElement("span", {
325
- className: "workflow-node-id"
326
- }, "#", id)),
327
- properties: {
328
- status: {
329
- type: 'number',
330
- title: `{{t("Status", { ns: "${_locale.NAMESPACE}" })}}`,
331
- 'x-decorator': 'FormItem',
332
- 'x-component': 'Select',
333
- enum: _constants.JobStatusOptions,
334
- 'x-read-pretty': true
335
- },
336
- updatedAt: {
337
- type: 'string',
338
- title: `{{t("Executed at", { ns: "${_locale.NAMESPACE}" })}}`,
339
- 'x-decorator': 'FormItem',
340
- 'x-component': 'DatePicker',
341
- 'x-component-props': {
342
- showTime: true
343
- },
344
- 'x-read-pretty': true
345
- },
346
- result: {
347
- type: 'object',
348
- title: `{{t("Node result", { ns: "${_locale.NAMESPACE}" })}}`,
349
- 'x-decorator': 'FormItem',
350
- 'x-component': 'Input.JSON',
351
- 'x-component-props': {
352
- className: (0, _css().css)`
353
- padding: 1em;
354
- background-color: #eee;
355
- `
356
- },
357
- 'x-read-pretty': true
358
- }
359
- }
360
- }
361
- }
362
- }
363
- }
334
+ `
335
+ }, _react().default.createElement("span", {
336
+ className: _style.nodeJobButtonClass
337
+ }, _react().default.createElement(_antd().Tag, {
338
+ color: color
339
+ }, icon)), _react().default.createElement("time", null, (0, _client().str2moment)(job.updatedAt).format('YYYY-MM-DD HH:mm:ss')))
340
+ };
341
+ }),
342
+ onClick: onOpenJob
364
343
  }
344
+ }, _react().default.createElement(InnerJobButton, {
345
+ job: jobs[jobs.length - 1]
346
+ })) : _react().default.createElement(InnerJobButton, {
347
+ job: jobs[0],
348
+ onClick: () => setViewJob(jobs[0])
365
349
  });
366
350
  }
367
351
  function NodeDefaultView(props) {
@@ -370,9 +354,9 @@ function NodeDefaultView(props) {
370
354
  children = props.children;
371
355
  const compile = (0, _client2().useCompile)();
372
356
  const api = (0, _client2().useAPIClient)();
373
- const _ref3 = (_useFlowContext4 = (0, _FlowContext.useFlowContext)()) !== null && _useFlowContext4 !== void 0 ? _useFlowContext4 : {},
374
- workflow = _ref3.workflow,
375
- refresh = _ref3.refresh;
357
+ const _ref4 = (_useFlowContext4 = (0, _FlowContext.useFlowContext)()) !== null && _useFlowContext4 !== void 0 ? _useFlowContext4 : {},
358
+ workflow = _ref4.workflow,
359
+ refresh = _ref4.refresh;
376
360
  const instruction = instructions.get(data.type);
377
361
  const detailText = workflow.executed ? '{{t("View")}}' : '{{t("Configure")}}';
378
362
  const typeTitle = compile(instruction.title);
@@ -411,7 +395,7 @@ function NodeDefaultView(props) {
411
395
  return;
412
396
  }
413
397
  const whiteSet = new Set(['workflow-node-meta', 'workflow-node-config-button', 'ant-input-disabled']);
414
- for (let el = ev.target; el && el !== ev.currentTarget; el = el.parentNode) {
398
+ for (let el = ev.target; el && el !== ev.currentTarget && el !== document.documentElement; el = el.parentNode) {
415
399
  if (Array.from(el.classList).some(name => whiteSet.has(name))) {
416
400
  setEditingConfig(true);
417
401
  ev.stopPropagation();
@@ -460,7 +444,7 @@ function NodeDefaultView(props) {
460
444
  },
461
445
  [`${instruction.type}_${data.id}`]: {
462
446
  type: 'void',
463
- title: instruction.title,
447
+ title: data.title,
464
448
  'x-component': 'Action.Drawer',
465
449
  'x-decorator': 'Form',
466
450
  'x-decorator-props': {
@@ -490,6 +474,14 @@ function NodeDefaultView(props) {
490
474
  `
491
475
  }
492
476
  }
477
+ } : instruction.description ? {
478
+ description: {
479
+ type: 'void',
480
+ 'x-component': _NodeDescription.NodeDescription,
481
+ 'x-component-props': {
482
+ instruction
483
+ }
484
+ }
493
485
  } : {}), {}, {
494
486
  fieldset: {
495
487
  type: 'void',
@@ -506,7 +498,6 @@ function NodeDefaultView(props) {
506
498
  min-width: 6em;
507
499
  }
508
500
  }
509
-
510
501
  .ant-input-affix-wrapper {
511
502
  &:not(.full-width) {
512
503
  .ant-input {
@@ -0,0 +1,29 @@
1
+ import { useWorkflowVariableOptions, VariableOption } from '../variable';
2
+ declare const _default: {
3
+ title: string;
4
+ type: string;
5
+ group: string;
6
+ description: string;
7
+ fieldset: {
8
+ target: {
9
+ type: string;
10
+ title: string;
11
+ description: string;
12
+ 'x-decorator': string;
13
+ 'x-component': string;
14
+ 'x-component-props': {
15
+ scope: string;
16
+ useTypedConstant: string[];
17
+ };
18
+ required: boolean;
19
+ };
20
+ };
21
+ view: {};
22
+ render: (data: any) => JSX.Element;
23
+ scope: {
24
+ useWorkflowVariableOptions: typeof useWorkflowVariableOptions;
25
+ };
26
+ components: {};
27
+ useScopeVariables(node: any, options: any): VariableOption[];
28
+ };
29
+ export default _default;
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ function _react() {
8
+ const data = _interopRequireDefault(require("react"));
9
+ _react = function _react() {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
14
+ function _icons() {
15
+ const data = require("@ant-design/icons");
16
+ _icons = function _icons() {
17
+ return data;
18
+ };
19
+ return data;
20
+ }
21
+ function _css() {
22
+ const data = require("@emotion/css");
23
+ _css = function _css() {
24
+ return data;
25
+ };
26
+ return data;
27
+ }
28
+ function _client() {
29
+ const data = require("@nocobase/client");
30
+ _client = function _client() {
31
+ return data;
32
+ };
33
+ return data;
34
+ }
35
+ var _ = require(".");
36
+ var _FlowContext = require("../FlowContext");
37
+ var _locale = require("../locale");
38
+ var _variable = require("../variable");
39
+ var _style = require("../style");
40
+ var _Branch = require("../Branch");
41
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
42
+ function findOption(options, paths) {
43
+ let current = options;
44
+ for (let i = 0; i < paths.length; i++) {
45
+ const path = paths[i];
46
+ const option = current.find(item => item.value === path);
47
+ if (!option) {
48
+ return null;
49
+ }
50
+ if (option.children) {
51
+ current = option.children;
52
+ }
53
+ }
54
+ return current;
55
+ }
56
+ var _default = {
57
+ title: `{{t("Loop", { ns: "${_locale.NAMESPACE}" })}}`,
58
+ type: 'loop',
59
+ group: 'control',
60
+ description: `{{t("By using a loop node, you can perform the same operation on multiple sets of data. The source of these sets can be either multiple records from a query node or multiple associated records of a single record. Loop node can also be used for iterating a certain number of times or for looping through each character in a string. However, excessive looping may cause performance issues, so use with caution.", { ns: "${_locale.NAMESPACE}" })}}`,
61
+ fieldset: {
62
+ target: {
63
+ type: 'string',
64
+ title: `{{t("Loop target", { ns: "${_locale.NAMESPACE}" })}}`,
65
+ description: `{{t("A single number will be treated as a loop count, a single string will be treated as an array of characters, and other non-array values will be converted to arrays. The loop node ends when the loop count is reached, or when the array loop is completed. You can also add condition nodes to the loop to terminate it.", { ns: "${_locale.NAMESPACE}" })}}`,
66
+ 'x-decorator': 'FormItem',
67
+ 'x-component': 'Variable.Input',
68
+ 'x-component-props': {
69
+ scope: '{{useWorkflowVariableOptions}}',
70
+ useTypedConstant: ['string', 'number', 'null']
71
+ },
72
+ required: true
73
+ }
74
+ },
75
+ view: {},
76
+ render: function Renderer(data) {
77
+ var _entry$branchIndex;
78
+ const _useFlowContext = (0, _FlowContext.useFlowContext)(),
79
+ nodes = _useFlowContext.nodes;
80
+ const entry = nodes.find(node => node.upstreamId === data.id && node.branchIndex != null);
81
+ return _react().default.createElement(_.NodeDefaultView, {
82
+ data: data
83
+ }, _react().default.createElement("div", {
84
+ className: (0, _css().cx)(_style.nodeSubtreeClass)
85
+ }, _react().default.createElement("div", {
86
+ className: (0, _css().cx)(_style.branchBlockClass, (0, _css().css)`
87
+ padding-left: 20em;
88
+ `)
89
+ }, _react().default.createElement(_Branch.Branch, {
90
+ from: data,
91
+ entry: entry,
92
+ branchIndex: (_entry$branchIndex = entry === null || entry === void 0 ? void 0 : entry.branchIndex) !== null && _entry$branchIndex !== void 0 ? _entry$branchIndex : 0
93
+ }), _react().default.createElement("div", {
94
+ className: (0, _css().cx)(_style.branchClass)
95
+ }, _react().default.createElement("div", {
96
+ className: "workflow-branch-lines"
97
+ }), _react().default.createElement("div", {
98
+ className: (0, _css().cx)(_style.addButtonClass, (0, _css().css)`
99
+ display: flex;
100
+ justify-content: center;
101
+ align-items: center;
102
+ position: absolute;
103
+ top: 50%;
104
+ transform: translateY(-50%);
105
+ width: 2em;
106
+ height: 6em;
107
+ `)
108
+ }, _react().default.createElement(_icons().ArrowUpOutlined, {
109
+ className: (0, _css().css)`
110
+ background-color: #f0f2f5;
111
+ `
112
+ })))), _react().default.createElement("div", {
113
+ className: (0, _css().css)`
114
+ position: relative;
115
+ height: 2em;
116
+ `
117
+ })));
118
+ },
119
+ scope: {
120
+ useWorkflowVariableOptions: _variable.useWorkflowVariableOptions
121
+ },
122
+ components: {},
123
+ useScopeVariables(node, options) {
124
+ const compile = (0, _client().useCompile)();
125
+ const target = node.config.target;
126
+ if (!target) {
127
+ return null;
128
+ }
129
+ // const { workflow } = useFlowContext();
130
+ // const current = useNodeContext();
131
+ // const upstreams = useAvailableUpstreams(current);
132
+ // find target data model by path described in `config.target`
133
+ // 1. get options from $context/$jobsMapByNodeId
134
+ // 2. route to sub-options and use as loop target options
135
+ const targetOption = {
136
+ key: 'item',
137
+ value: 'item',
138
+ label: (0, _locale.lang)('Loop target')
139
+ };
140
+ if (typeof target === 'string' && target.startsWith('{{') && target.endsWith('}}')) {
141
+ const paths = target.slice(2, -2).split('.').map(path => path.trim());
142
+ const targetOptions = [_variable.nodesOptions, _variable.triggerOptions].map(item => {
143
+ const opts = typeof item.useOptions === 'function' ? item.useOptions(options).filter(Boolean) : null;
144
+ return {
145
+ label: compile(item.title),
146
+ value: item.value,
147
+ key: item.value,
148
+ children: compile(opts),
149
+ disabled: opts && !opts.length
150
+ };
151
+ });
152
+ targetOption.children = findOption(targetOptions, paths);
153
+ }
154
+ return [targetOption, {
155
+ key: 'index',
156
+ value: 'index',
157
+ label: (0, _locale.lang)('Loop index')
158
+ }, {
159
+ key: 'length',
160
+ value: 'length',
161
+ label: (0, _locale.lang)('Loop length')
162
+ }];
163
+ }
164
+ };
165
+ exports.default = _default;
@@ -25,12 +25,14 @@ function AssigneesSelect({
25
25
  value = [],
26
26
  onChange: _onChange
27
27
  }) {
28
- const scope = (0, _variable.useWorkflowVariableOptions)([{
29
- type: 'reference',
30
- options: {
31
- collection: 'users'
32
- }
33
- }]);
28
+ const scope = (0, _variable.useWorkflowVariableOptions)({
29
+ types: [{
30
+ type: 'reference',
31
+ options: {
32
+ collection: 'users'
33
+ }
34
+ }]
35
+ });
34
36
  return _react().default.createElement(_client().Variable.Input, {
35
37
  scope: scope,
36
38
  value: value[0],
@@ -25,13 +25,6 @@ function _antd() {
25
25
  };
26
26
  return data;
27
27
  }
28
- function _jsonTemplates() {
29
- const data = _interopRequireDefault(require("json-templates"));
30
- _jsonTemplates = function _jsonTemplates() {
31
- return data;
32
- };
33
- return data;
34
- }
35
28
  function _css() {
36
29
  const data = require("@emotion/css");
37
30
  _css = function _css() {
@@ -468,7 +461,7 @@ function useFlowRecordFromBlock(opts) {
468
461
  dataSource = _useFieldSchema['x-context-datasource'];
469
462
  const _useFlowContext = (0, _FlowContext.useFlowContext)(),
470
463
  execution = _useFlowContext.execution;
471
- const result = (0, _jsonTemplates().default)(dataSource)({
464
+ const result = (0, _client2().parse)(dataSource)({
472
465
  $context: execution === null || execution === void 0 ? void 0 : execution.context,
473
466
  $jobsMapByNodeId: ((_execution$jobs = execution === null || execution === void 0 ? void 0 : execution.jobs) !== null && _execution$jobs !== void 0 ? _execution$jobs : []).reduce((map, job) => Object.assign(map, {
474
467
  [job.nodeId]: job.result
@@ -7,6 +7,7 @@ declare const _default: {
7
7
  title: string;
8
8
  type: string;
9
9
  group: string;
10
+ description: string;
10
11
  fieldset: {
11
12
  assignees: {
12
13
  type: string;
@@ -58,7 +59,11 @@ declare const _default: {
58
59
  ModeConfig: typeof ModeConfig;
59
60
  AssigneesSelect: typeof AssigneesSelect;
60
61
  };
61
- getOptions(config: any, types: any): {
62
+ useVariables({ config }: {
63
+ config: any;
64
+ }, { types }: {
65
+ types: any;
66
+ }): {
62
67
  key: string;
63
68
  value: string;
64
69
  label: any;
@@ -40,6 +40,7 @@ var _default = {
40
40
  title: `{{t("Manual", { ns: "${_locale.NAMESPACE}" })}}`,
41
41
  type: 'manual',
42
42
  group: 'manual',
43
+ description: `{{t("Could be used for manually submitting data, and determine whether to continue or exit. Workflow will generate a todo item for assigned user when it reaches a manual node, and continue processing after user submits the form.", { ns: "${_locale.NAMESPACE}" })}}`,
43
44
  fieldset: {
44
45
  assignees: {
45
46
  type: 'array',
@@ -93,7 +94,11 @@ var _default = {
93
94
  ModeConfig: _ModeConfig.ModeConfig,
94
95
  AssigneesSelect: _AssigneesSelect.AssigneesSelect
95
96
  },
96
- getOptions(config, types) {
97
+ useVariables({
98
+ config
99
+ }, {
100
+ types
101
+ }) {
97
102
  var _config$forms;
98
103
  const formKeys = Object.keys((_config$forms = config.forms) !== null && _config$forms !== void 0 ? _config$forms : {});
99
104
  if (!formKeys.length) {
@@ -3,6 +3,7 @@ declare const _default: {
3
3
  title: string;
4
4
  type: string;
5
5
  group: string;
6
+ description: string;
6
7
  fieldset: {
7
8
  mode: {
8
9
  type: string;
@@ -50,6 +50,7 @@ var _default = {
50
50
  title: `{{t("Parallel branch", { ns: "${_locale.NAMESPACE}" })}}`,
51
51
  type: 'parallel',
52
52
  group: 'control',
53
+ description: `{{t("Run multiple branch processes in parallel.", { ns: "${_locale.NAMESPACE}" })}}`,
53
54
  fieldset: {
54
55
  mode: {
55
56
  type: 'string',
@@ -68,7 +69,7 @@ var _default = {
68
69
  }, {
69
70
  value: 'race',
70
71
  label: `{{t('Any succeeded or failed', { ns: "${_locale.NAMESPACE}" })}}`,
71
- tooltip: `{{t('Continue after any branch succeeded, or exit after any branch failed', { ns: "${_locale.NAMESPACE}" })}}`
72
+ tooltip: `{{t('Continue after any branch succeeded, or exit after any branch failed.', { ns: "${_locale.NAMESPACE}" })}}`
72
73
  }]
73
74
  },
74
75
  default: 'all'