@nocobase/plugin-workflow-delay 1.0.0-alpha.2 → 1.0.0-alpha.3
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/DelayInstruction.d.ts +8 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.js +9 -0
- package/dist/externalVersion.js +12 -3
- package/dist/index.d.ts +8 -0
- package/dist/index.js +9 -0
- package/dist/locale/index.d.ts +8 -0
- package/dist/locale/index.js +9 -0
- package/dist/server/DelayInstruction.d.ts +8 -0
- package/dist/server/DelayInstruction.js +9 -0
- package/dist/server/Plugin.d.ts +8 -0
- package/dist/server/Plugin.js +9 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.js +9 -0
- package/package.json +2 -2
- package/src/client/DelayInstruction.tsx +0 -90
- package/src/client/index.ts +0 -18
- package/src/index.ts +0 -2
- package/src/locale/en-US.json +0 -9
- package/src/locale/es-ES.json +0 -8
- package/src/locale/fr-FR.json +0 -8
- package/src/locale/index.ts +0 -12
- package/src/locale/ko_KR.json +0 -10
- package/src/locale/pt-BR.json +0 -8
- package/src/locale/zh-CN.json +0 -9
- package/src/server/DelayInstruction.ts +0 -110
- package/src/server/Plugin.ts +0 -11
- package/src/server/__tests__/instruction.test.ts +0 -183
- package/src/server/index.ts +0 -1
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
1
9
|
import React from 'react';
|
|
2
10
|
import { Instruction } from '@nocobase/plugin-workflow/client';
|
|
3
11
|
declare function Duration({ value, onChange }: {
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
1
9
|
import { Plugin } from '@nocobase/client';
|
|
2
10
|
export default class extends Plugin {
|
|
3
11
|
afterAdd(): Promise<void>;
|
package/dist/client/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
(function(e,t){typeof exports=="object"&&typeof module!="undefined"?t(exports,require("@nocobase/client"),require("react/jsx-runtime"),require("antd"),require("@nocobase/plugin-workflow/client"),require("react-i18next")):typeof define=="function"&&define.amd?define(["exports","@nocobase/client","react/jsx-runtime","antd","@nocobase/plugin-workflow/client","react-i18next"],t):(e=typeof globalThis!="undefined"?globalThis:e||self,t(e["@nocobase/plugin-workflow-delay"]={},e["@nocobase/client"],e.jsxRuntime,e.antd,e["@nocobase/plugin-workflow"]))})(this,function(e,t,n,f,s){"use strict";var v=Object.defineProperty;var h=(e,t,n)=>t in e?v(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var r=(e,t,n)=>(h(e,typeof t!="symbol"?t+"":t,n),n);var m=(e,t,n)=>new Promise((f,s)=>{var a=o=>{try{c(n.next(o))}catch(d){s(d)}},w=o=>{try{c(n.throw(o))}catch(d){s(d)}},c=o=>o.done?f(o.value):Promise.resolve(o.value).then(a,w);c((n=n.apply(e,t)).next())});const a="workflow-delay",w=[{value:1e3,label:`{{t('Seconds', { ns: "workflow" })}}`},{value:6e4,label:`{{t('Minutes', { ns: "workflow" })}}`},{value:36e5,label:`{{t('Hours', { ns: "workflow" })}}`},{value:864e5,label:`{{t('Days', { ns: "workflow" })}}`},{value:6048e5,label:`{{t('Weeks', { ns: "workflow" })}}`}];function c(u){return w.slice().reverse().find(i=>!(u%i.value))}function o({value:u=6e4,onChange:i}){const b=t.useCompile(),p=c(u),y=Math.round(u/p.value);return n.jsxs("fieldset",{className:t.css`
|
|
2
11
|
display: flex;
|
|
3
12
|
gap: 0.5em;
|
package/dist/externalVersion.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
module.exports = {
|
|
2
11
|
"react": "18.2.0",
|
|
3
12
|
"antd": "5.12.8",
|
|
4
|
-
"@nocobase/client": "1.0.0-alpha.
|
|
5
|
-
"@nocobase/plugin-workflow": "1.0.0-alpha.
|
|
13
|
+
"@nocobase/client": "1.0.0-alpha.3",
|
|
14
|
+
"@nocobase/plugin-workflow": "1.0.0-alpha.3",
|
|
6
15
|
"react-i18next": "11.18.6",
|
|
7
|
-
"@nocobase/server": "1.0.0-alpha.
|
|
16
|
+
"@nocobase/server": "1.0.0-alpha.3"
|
|
8
17
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
1
9
|
export * from './server';
|
|
2
10
|
export { default } from './server';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
var __create = Object.create;
|
|
2
11
|
var __defProp = Object.defineProperty;
|
|
3
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
package/dist/locale/index.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
1
9
|
export declare const NAMESPACE = "workflow-delay";
|
|
2
10
|
export declare function useLang(key: string, options?: {}): string;
|
|
3
11
|
export declare function usePluginTranslation(options: any): import("react-i18next").UseTranslationResponse<"workflow-delay", undefined>;
|
package/dist/locale/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
1
9
|
/// <reference types="node" />
|
|
2
10
|
import WorkflowPlugin, { Processor, Instruction } from '@nocobase/plugin-workflow';
|
|
3
11
|
export default class extends Instruction {
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
package/dist/server/Plugin.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
1
9
|
import { Plugin } from '@nocobase/server';
|
|
2
10
|
export default class extends Plugin {
|
|
3
11
|
load(): Promise<void>;
|
package/dist/server/Plugin.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
var __create = Object.create;
|
|
2
11
|
var __defProp = Object.defineProperty;
|
|
3
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
1
9
|
export { default } from './Plugin';
|
package/dist/server/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
var __create = Object.create;
|
|
2
11
|
var __defProp = Object.defineProperty;
|
|
3
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"displayName.zh-CN": "工作流:延时节点",
|
|
5
5
|
"description": "Could be used in workflow parallel branch for waiting other branches.",
|
|
6
6
|
"description.zh-CN": "可用于工作流并行分支中等待其他分支执行完成。",
|
|
7
|
-
"version": "1.0.0-alpha.
|
|
7
|
+
"version": "1.0.0-alpha.3",
|
|
8
8
|
"license": "AGPL-3.0",
|
|
9
9
|
"main": "./dist/server/index.js",
|
|
10
10
|
"homepage": "https://docs.nocobase.com/handbook/workflow-delay",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"@nocobase/server": "1.x",
|
|
22
22
|
"@nocobase/test": "1.x"
|
|
23
23
|
},
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "7ccb137c7616cba5d238f87368239640e1d9ace1",
|
|
25
25
|
"keywords": [
|
|
26
26
|
"Workflow"
|
|
27
27
|
]
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { InputNumber, Select } from 'antd';
|
|
3
|
-
import { css, useCompile, usePlugin } from '@nocobase/client';
|
|
4
|
-
import WorkflowPlugin, { Instruction, JOB_STATUS } from '@nocobase/plugin-workflow/client';
|
|
5
|
-
|
|
6
|
-
import { NAMESPACE } from '../locale';
|
|
7
|
-
|
|
8
|
-
const UnitOptions = [
|
|
9
|
-
{ value: 1_000, label: `{{t('Seconds', { ns: "workflow" })}}` },
|
|
10
|
-
{ value: 60_000, label: `{{t('Minutes', { ns: "workflow" })}}` },
|
|
11
|
-
{ value: 3600_000, label: `{{t('Hours', { ns: "workflow" })}}` },
|
|
12
|
-
{ value: 86400_000, label: `{{t('Days', { ns: "workflow" })}}` },
|
|
13
|
-
{ value: 604800_000, label: `{{t('Weeks', { ns: "workflow" })}}` },
|
|
14
|
-
];
|
|
15
|
-
|
|
16
|
-
function getNumberOption(v) {
|
|
17
|
-
return UnitOptions.slice()
|
|
18
|
-
.reverse()
|
|
19
|
-
.find((item) => !(v % item.value));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function Duration({ value = 60000, onChange }) {
|
|
23
|
-
const compile = useCompile();
|
|
24
|
-
const option = getNumberOption(value);
|
|
25
|
-
const quantity = Math.round(value / option.value);
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<fieldset
|
|
29
|
-
className={css`
|
|
30
|
-
display: flex;
|
|
31
|
-
gap: 0.5em;
|
|
32
|
-
`}
|
|
33
|
-
>
|
|
34
|
-
<InputNumber
|
|
35
|
-
min={1}
|
|
36
|
-
value={quantity}
|
|
37
|
-
onChange={(v) => onChange(Math.round(v * option.value))}
|
|
38
|
-
className="auto-width"
|
|
39
|
-
/>
|
|
40
|
-
<Select
|
|
41
|
-
// @ts-ignore
|
|
42
|
-
role="button"
|
|
43
|
-
data-testid="select-time-unit"
|
|
44
|
-
popupMatchSelectWidth={false}
|
|
45
|
-
value={option.value}
|
|
46
|
-
onChange={(unit) => onChange(Math.round(quantity * unit))}
|
|
47
|
-
className="auto-width"
|
|
48
|
-
options={UnitOptions.map((item) => ({
|
|
49
|
-
value: item.value,
|
|
50
|
-
label: compile(item.label),
|
|
51
|
-
}))}
|
|
52
|
-
/>
|
|
53
|
-
</fieldset>
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export default class extends Instruction {
|
|
58
|
-
title = `{{t("Delay", { ns: "${NAMESPACE}" })}}`;
|
|
59
|
-
type = 'delay';
|
|
60
|
-
group = 'control';
|
|
61
|
-
description = `{{t("Delay a period of time and then continue or exit the process. Can be used to set wait or timeout times in parallel branches.", { ns: "${NAMESPACE}" })}}`;
|
|
62
|
-
fieldset = {
|
|
63
|
-
duration: {
|
|
64
|
-
type: 'number',
|
|
65
|
-
title: `{{t("Duration", { ns: "${NAMESPACE}" })}}`,
|
|
66
|
-
'x-decorator': 'FormItem',
|
|
67
|
-
'x-component': 'Duration',
|
|
68
|
-
default: 60000,
|
|
69
|
-
required: true,
|
|
70
|
-
},
|
|
71
|
-
endStatus: {
|
|
72
|
-
type: 'number',
|
|
73
|
-
title: `{{t("End status", { ns: "${NAMESPACE}" })}}`,
|
|
74
|
-
'x-decorator': 'FormItem',
|
|
75
|
-
'x-component': 'Radio.Group',
|
|
76
|
-
enum: [
|
|
77
|
-
{ label: `{{t("Succeed and continue", { ns: "${NAMESPACE}" })}}`, value: JOB_STATUS.RESOLVED },
|
|
78
|
-
{ label: `{{t("Fail and exit", { ns: "${NAMESPACE}" })}}`, value: JOB_STATUS.FAILED },
|
|
79
|
-
],
|
|
80
|
-
required: true,
|
|
81
|
-
default: JOB_STATUS.RESOLVED,
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
components = {
|
|
85
|
-
Duration,
|
|
86
|
-
};
|
|
87
|
-
isAvailable({ engine, workflow, upstream, branchIndex }) {
|
|
88
|
-
return !engine.isWorkflowSync(workflow);
|
|
89
|
-
}
|
|
90
|
-
}
|
package/src/client/index.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Plugin } from '@nocobase/client';
|
|
2
|
-
import WorkflowPlugin from '@nocobase/plugin-workflow/client';
|
|
3
|
-
|
|
4
|
-
import DelayInstruction from './DelayInstruction';
|
|
5
|
-
|
|
6
|
-
export default class extends Plugin {
|
|
7
|
-
async afterAdd() {
|
|
8
|
-
// await this.app.pm.add()
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async beforeLoad() {}
|
|
12
|
-
|
|
13
|
-
// You can get and modify the app instance here
|
|
14
|
-
async load() {
|
|
15
|
-
const workflow = this.app.pm.get('workflow') as WorkflowPlugin;
|
|
16
|
-
workflow.registerInstruction('delay', DelayInstruction);
|
|
17
|
-
}
|
|
18
|
-
}
|
package/src/index.ts
DELETED
package/src/locale/en-US.json
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"Delay": "Delay",
|
|
3
|
-
"Delay a period of time and then continue or exit the process. Can be used to set wait or timeout times in parallel branches.": "Delay a period of time and then continue or exit the process. Can be used to set wait or timeout times in parallel branches.",
|
|
4
|
-
"Duration": "Duration",
|
|
5
|
-
"End status": "End status",
|
|
6
|
-
"Select status": "Select status",
|
|
7
|
-
"Succeed and continue": "Succeed and continue",
|
|
8
|
-
"Fail and exit": "Fail and exit"
|
|
9
|
-
}
|
package/src/locale/es-ES.json
DELETED
package/src/locale/fr-FR.json
DELETED
package/src/locale/index.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { useTranslation } from 'react-i18next';
|
|
2
|
-
|
|
3
|
-
export const NAMESPACE = 'workflow-delay';
|
|
4
|
-
|
|
5
|
-
export function useLang(key: string, options = {}) {
|
|
6
|
-
const { t } = usePluginTranslation(options);
|
|
7
|
-
return t(key);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function usePluginTranslation(options) {
|
|
11
|
-
return useTranslation(NAMESPACE, options);
|
|
12
|
-
}
|
package/src/locale/ko_KR.json
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"Delay": "지연",
|
|
3
|
-
"Delay a period of time and then continue or exit the process. Can be used to set wait or timeout times in parallel branches.":
|
|
4
|
-
"일정 시간 동안 지연한 다음 프로세스를 계속하거나 종료합니다. 병렬 분기에서 대기 또는 타임아웃 시간을 설정하는 데 사용할 수 있습니다.",
|
|
5
|
-
"Duration": "기간",
|
|
6
|
-
"End Status": "종료 상태",
|
|
7
|
-
"Select status": "상태 선택",
|
|
8
|
-
"Succeed and continue": "성공하고 계속",
|
|
9
|
-
"Fail and exit": "실패하고 종료"
|
|
10
|
-
}
|
package/src/locale/pt-BR.json
DELETED
package/src/locale/zh-CN.json
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"Delay": "延时",
|
|
3
|
-
"Delay a period of time and then continue or exit the process. Can be used to set wait or timeout times in parallel branches.": "延时一段时间,然后继续或退出流程。可以用于并行分支中等待其他分支或设置超时时间。",
|
|
4
|
-
"Duration": "时长",
|
|
5
|
-
"End status": "到时状态",
|
|
6
|
-
"Select status": "选择状态",
|
|
7
|
-
"Succeed and continue": "通过并继续",
|
|
8
|
-
"Fail and exit": "失败并退出"
|
|
9
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import WorkflowPlugin, {
|
|
2
|
-
Processor,
|
|
3
|
-
Instruction,
|
|
4
|
-
JOB_STATUS,
|
|
5
|
-
JobModel,
|
|
6
|
-
EXECUTION_STATUS,
|
|
7
|
-
} from '@nocobase/plugin-workflow';
|
|
8
|
-
|
|
9
|
-
type ValueOf<T> = T[keyof T];
|
|
10
|
-
|
|
11
|
-
interface DelayConfig {
|
|
12
|
-
endStatus: ValueOf<typeof JOB_STATUS>;
|
|
13
|
-
duration: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export default class extends Instruction {
|
|
17
|
-
timers: Map<number, NodeJS.Timeout> = new Map();
|
|
18
|
-
|
|
19
|
-
constructor(public workflow: WorkflowPlugin) {
|
|
20
|
-
super(workflow);
|
|
21
|
-
|
|
22
|
-
workflow.app.on('afterStart', this.load);
|
|
23
|
-
workflow.app.on('beforeStop', this.unload);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
load = async () => {
|
|
27
|
-
const { model } = this.workflow.app.db.getCollection('jobs');
|
|
28
|
-
const jobs = (await model.findAll({
|
|
29
|
-
where: {
|
|
30
|
-
status: JOB_STATUS.PENDING,
|
|
31
|
-
},
|
|
32
|
-
include: [
|
|
33
|
-
{
|
|
34
|
-
association: 'execution',
|
|
35
|
-
attributes: [],
|
|
36
|
-
where: {
|
|
37
|
-
status: EXECUTION_STATUS.STARTED,
|
|
38
|
-
},
|
|
39
|
-
required: true,
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
association: 'node',
|
|
43
|
-
attributes: ['config'],
|
|
44
|
-
where: {
|
|
45
|
-
type: 'delay',
|
|
46
|
-
},
|
|
47
|
-
required: true,
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
})) as JobModel[];
|
|
51
|
-
|
|
52
|
-
jobs.forEach((job) => {
|
|
53
|
-
this.schedule(job);
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
unload = () => {
|
|
58
|
-
for (const timer of this.timers.values()) {
|
|
59
|
-
clearTimeout(timer);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
this.timers = new Map();
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
schedule(job) {
|
|
66
|
-
const now = new Date();
|
|
67
|
-
const createdAt = Date.parse(job.createdAt);
|
|
68
|
-
const delay = createdAt + job.node.config.duration - now.getTime();
|
|
69
|
-
if (delay > 0) {
|
|
70
|
-
const trigger = this.trigger.bind(this, job);
|
|
71
|
-
this.timers.set(job.id, setTimeout(trigger, delay));
|
|
72
|
-
} else {
|
|
73
|
-
this.trigger(job);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async trigger(job) {
|
|
78
|
-
if (!job.execution) {
|
|
79
|
-
job.execution = await job.getExecution();
|
|
80
|
-
}
|
|
81
|
-
if (job.execution.status === EXECUTION_STATUS.STARTED) {
|
|
82
|
-
this.workflow.resume(job);
|
|
83
|
-
}
|
|
84
|
-
if (this.timers.get(job.id)) {
|
|
85
|
-
this.timers.delete(job.id);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async run(node, prevJob, processor: Processor) {
|
|
90
|
-
const job = await processor.saveJob({
|
|
91
|
-
status: JOB_STATUS.PENDING,
|
|
92
|
-
result: null,
|
|
93
|
-
nodeId: node.id,
|
|
94
|
-
nodeKey: node.key,
|
|
95
|
-
upstreamId: prevJob?.id ?? null,
|
|
96
|
-
});
|
|
97
|
-
job.node = node;
|
|
98
|
-
|
|
99
|
-
// add to schedule
|
|
100
|
-
this.schedule(job);
|
|
101
|
-
|
|
102
|
-
return processor.exit();
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async resume(node, prevJob, processor: Processor) {
|
|
106
|
-
const { endStatus } = node.config as DelayConfig;
|
|
107
|
-
prevJob.set('status', endStatus);
|
|
108
|
-
return prevJob;
|
|
109
|
-
}
|
|
110
|
-
}
|
package/src/server/Plugin.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Plugin } from '@nocobase/server';
|
|
2
|
-
import WorkflowPlugin from '@nocobase/plugin-workflow';
|
|
3
|
-
|
|
4
|
-
import DelayInstruction from './DelayInstruction';
|
|
5
|
-
|
|
6
|
-
export default class extends Plugin {
|
|
7
|
-
async load() {
|
|
8
|
-
const workflowPlugin = this.app.getPlugin<WorkflowPlugin>(WorkflowPlugin);
|
|
9
|
-
workflowPlugin.registerInstruction('delay', DelayInstruction);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import Database from '@nocobase/database';
|
|
2
|
-
import { EXECUTION_STATUS, JOB_STATUS } from '@nocobase/plugin-workflow';
|
|
3
|
-
import { getApp, sleep } from '@nocobase/plugin-workflow-test';
|
|
4
|
-
import { Application } from '@nocobase/server';
|
|
5
|
-
|
|
6
|
-
describe('workflow > instructions > delay', () => {
|
|
7
|
-
let app: Application;
|
|
8
|
-
let db: Database;
|
|
9
|
-
let PostRepo;
|
|
10
|
-
let WorkflowModel;
|
|
11
|
-
let workflow;
|
|
12
|
-
let plugin;
|
|
13
|
-
|
|
14
|
-
beforeEach(async () => {
|
|
15
|
-
app = await getApp({
|
|
16
|
-
plugins: ['workflow-delay'],
|
|
17
|
-
});
|
|
18
|
-
plugin = app.pm.get('workflow');
|
|
19
|
-
|
|
20
|
-
db = app.db;
|
|
21
|
-
WorkflowModel = db.getCollection('workflows').model;
|
|
22
|
-
PostRepo = db.getCollection('posts').repository;
|
|
23
|
-
|
|
24
|
-
workflow = await WorkflowModel.create({
|
|
25
|
-
enabled: true,
|
|
26
|
-
type: 'collection',
|
|
27
|
-
config: {
|
|
28
|
-
mode: 1,
|
|
29
|
-
collection: 'posts',
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
afterEach(() => app.destroy());
|
|
35
|
-
|
|
36
|
-
describe('runtime', () => {
|
|
37
|
-
it('delay to resolved', async () => {
|
|
38
|
-
const n1 = await workflow.createNode({
|
|
39
|
-
type: 'delay',
|
|
40
|
-
config: {
|
|
41
|
-
duration: 2000,
|
|
42
|
-
endStatus: JOB_STATUS.RESOLVED,
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
47
|
-
|
|
48
|
-
await sleep(500);
|
|
49
|
-
|
|
50
|
-
const [e1] = await workflow.getExecutions();
|
|
51
|
-
expect(e1.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
52
|
-
const [j1] = await e1.getJobs();
|
|
53
|
-
expect(j1.status).toBe(JOB_STATUS.PENDING);
|
|
54
|
-
|
|
55
|
-
await sleep(2000);
|
|
56
|
-
|
|
57
|
-
const [e2] = await workflow.getExecutions();
|
|
58
|
-
expect(e2.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
59
|
-
const [j2] = await e2.getJobs();
|
|
60
|
-
expect(j2.status).toBe(JOB_STATUS.RESOLVED);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('delay to reject', async () => {
|
|
64
|
-
const n1 = await workflow.createNode({
|
|
65
|
-
type: 'delay',
|
|
66
|
-
config: {
|
|
67
|
-
duration: 2000,
|
|
68
|
-
endStatus: JOB_STATUS.FAILED,
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
73
|
-
|
|
74
|
-
await sleep(500);
|
|
75
|
-
|
|
76
|
-
const [e1] = await workflow.getExecutions();
|
|
77
|
-
expect(e1.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
78
|
-
const [j1] = await e1.getJobs();
|
|
79
|
-
expect(j1.status).toBe(JOB_STATUS.PENDING);
|
|
80
|
-
|
|
81
|
-
await sleep(2000);
|
|
82
|
-
|
|
83
|
-
const [e2] = await workflow.getExecutions();
|
|
84
|
-
expect(e2.status).toEqual(EXECUTION_STATUS.FAILED);
|
|
85
|
-
const [j2] = await e2.getJobs();
|
|
86
|
-
expect(j2.status).toBe(JOB_STATUS.FAILED);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('delay to resolve and downstream node error', async () => {
|
|
90
|
-
const n1 = await workflow.createNode({
|
|
91
|
-
type: 'delay',
|
|
92
|
-
config: {
|
|
93
|
-
duration: 2000,
|
|
94
|
-
endStatus: JOB_STATUS.RESOLVED,
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
const n2 = await workflow.createNode({
|
|
98
|
-
type: 'create',
|
|
99
|
-
config: {
|
|
100
|
-
collection: 'notExistsTable',
|
|
101
|
-
params: {
|
|
102
|
-
values: {},
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
upstreamId: n1.id,
|
|
106
|
-
});
|
|
107
|
-
await n1.setDownstream(n2);
|
|
108
|
-
|
|
109
|
-
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
110
|
-
|
|
111
|
-
await sleep(500);
|
|
112
|
-
|
|
113
|
-
const [e1] = await workflow.getExecutions();
|
|
114
|
-
expect(e1.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
115
|
-
const [j1] = await e1.getJobs();
|
|
116
|
-
expect(j1.status).toBe(JOB_STATUS.PENDING);
|
|
117
|
-
|
|
118
|
-
await sleep(2000);
|
|
119
|
-
|
|
120
|
-
const [e2] = await workflow.getExecutions();
|
|
121
|
-
expect(e2.status).toEqual(EXECUTION_STATUS.ERROR);
|
|
122
|
-
const [j2, j3] = await e2.getJobs({ order: [['id', 'ASC']] });
|
|
123
|
-
expect(j2.status).toBe(JOB_STATUS.RESOLVED);
|
|
124
|
-
expect(j3.status).toBe(JOB_STATUS.ERROR);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
describe('app lifecycle', () => {
|
|
129
|
-
beforeEach(async () => {
|
|
130
|
-
await workflow.createNode({
|
|
131
|
-
type: 'delay',
|
|
132
|
-
config: {
|
|
133
|
-
duration: 2000,
|
|
134
|
-
endStatus: JOB_STATUS.RESOLVED,
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('restart app should trigger delayed job', async () => {
|
|
140
|
-
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
141
|
-
|
|
142
|
-
await sleep(500);
|
|
143
|
-
|
|
144
|
-
const [e1] = await workflow.getExecutions();
|
|
145
|
-
expect(e1.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
146
|
-
const [j1] = await e1.getJobs();
|
|
147
|
-
expect(j1.status).toBe(JOB_STATUS.PENDING);
|
|
148
|
-
|
|
149
|
-
await app.stop();
|
|
150
|
-
await sleep(500);
|
|
151
|
-
|
|
152
|
-
await app.start();
|
|
153
|
-
await sleep(2000);
|
|
154
|
-
|
|
155
|
-
const [e2] = await workflow.getExecutions();
|
|
156
|
-
expect(e2.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
157
|
-
const [j2] = await e2.getJobs();
|
|
158
|
-
expect(j2.status).toBe(JOB_STATUS.RESOLVED);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('restart app should trigger missed delayed job', async () => {
|
|
162
|
-
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
163
|
-
|
|
164
|
-
await sleep(500);
|
|
165
|
-
|
|
166
|
-
const [e1] = await workflow.getExecutions();
|
|
167
|
-
expect(e1.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
168
|
-
const [j1] = await e1.getJobs();
|
|
169
|
-
expect(j1.status).toBe(JOB_STATUS.PENDING);
|
|
170
|
-
|
|
171
|
-
await app.stop();
|
|
172
|
-
await sleep(2000);
|
|
173
|
-
|
|
174
|
-
await app.start();
|
|
175
|
-
await sleep(1000);
|
|
176
|
-
|
|
177
|
-
const [e2] = await workflow.getExecutions();
|
|
178
|
-
expect(e2.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
179
|
-
const [j2] = await e2.getJobs();
|
|
180
|
-
expect(j2.status).toBe(JOB_STATUS.RESOLVED);
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
});
|
package/src/server/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Plugin';
|