@coding-flow/flow-design 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -183
- package/dist/components/design-editor/node-components/strategy/operator-load.js +39 -17
- package/dist/components/design-panel/manager/form.js +2 -1
- package/dist/script-components/components/action/components/add-audit.js +22 -10
- package/dist/script-components/components/action/components/delegate.js +22 -10
- package/dist/script-components/components/action/components/max-operator-count.d.ts +15 -0
- package/dist/script-components/components/action/components/max-operator-count.js +16 -0
- package/dist/script-components/components/action/components/transfer.js +22 -10
- package/dist/script-components/components/sub-process/index.js +12 -1
- package/dist/script-components/components/sub-process/presenters/sub-process-presenter.d.ts +4 -0
- package/dist/script-components/components/sub-process/presenters/sub-process-presenter.js +5 -1
- package/dist/script-components/components/sub-process/typings/index.d.ts +4 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/uuid.d.ts +7 -0
- package/dist/utils/uuid.js +16 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# @coding-flow/flow-
|
|
1
|
+
# @coding-flow/flow-design
|
|
2
2
|
|
|
3
|
-
Flow Engine
|
|
3
|
+
Flow Engine 流程设计器组件库,提供可视化流程设计、节点配置、属性面板、脚本配置等功能。
|
|
4
4
|
|
|
5
5
|
## 简介
|
|
6
6
|
|
|
7
|
-
`flow-
|
|
7
|
+
`flow-design` 是 Flow Engine 的流程设计器组件库,提供:
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
- 节点配置面板(
|
|
9
|
+
- 流程设计器(基于 @flowgram.ai 的可视化流程设计)
|
|
10
|
+
- 节点配置面板(19 种节点类型配置)
|
|
11
11
|
- 属性面板(节点属性编辑)
|
|
12
12
|
- 脚本配置器(Groovy 脚本编辑)
|
|
13
13
|
- 变量选择器
|
|
@@ -15,7 +15,7 @@ Flow Engine PC 端流程设计器组件库,提供节点配置、属性面板
|
|
|
15
15
|
|
|
16
16
|
### 依赖关系
|
|
17
17
|
|
|
18
|
-
- **依赖**: `@coding-flow/flow-core
|
|
18
|
+
- **依赖**: `@coding-flow/flow-core`、`@coding-flow/flow-types`、`@coding-flow/flow-icons`、`@coding-flow/flow-pc-ui`、`@flowgram.ai/fixed-layout-editor`、`@coding-script/script-engine`
|
|
19
19
|
|
|
20
20
|
## Setup
|
|
21
21
|
|
|
@@ -33,182 +33,6 @@ pnpm install
|
|
|
33
33
|
pnpm run build
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
监听模式构建:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
pnpm run dev
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## 核心功能
|
|
43
|
-
|
|
44
|
-
### 流程设计器
|
|
45
|
-
|
|
46
|
-
可视化流程设计器,支持:
|
|
47
|
-
|
|
48
|
-
- 节点拖拽添加
|
|
49
|
-
- 节点连线
|
|
50
|
-
- 节点配置
|
|
51
|
-
- 流程预览
|
|
52
|
-
- 流程校验
|
|
53
|
-
- 流程导入/导出
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
import { WorkflowDesigner } from '@coding-flow/flow-pc-design';
|
|
57
|
-
|
|
58
|
-
<WorkflowDesigner
|
|
59
|
-
workflow={workflow}
|
|
60
|
-
onChange={handleWorkflowChange}
|
|
61
|
-
onValidate={handleValidate}
|
|
62
|
-
/>
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 节点配置
|
|
66
|
-
|
|
67
|
-
支持 15 种节点类型的配置:
|
|
68
|
-
|
|
69
|
-
**基础节点 (9 种)**:
|
|
70
|
-
- `StartNode` - 开始节点
|
|
71
|
-
- `EndNode` - 结束节点
|
|
72
|
-
- `ApprovalNode` - 审批节点
|
|
73
|
-
- `HandleNode` - 办理节点
|
|
74
|
-
- `NotifyNode` - 通知节点
|
|
75
|
-
- `RouterNode` - 路由节点
|
|
76
|
-
- `SubProcessNode` - 子流程节点
|
|
77
|
-
- `DelayNode` - 延迟节点
|
|
78
|
-
- `TriggerNode` - 触发节点
|
|
79
|
-
|
|
80
|
-
**块节点 (3 种)**:
|
|
81
|
-
- `ConditionNode` - 条件节点
|
|
82
|
-
- `ParallelNode` - 并行节点
|
|
83
|
-
- `InclusiveNode` - 包容节点
|
|
84
|
-
|
|
85
|
-
**分支节点 (3 种)**:
|
|
86
|
-
- `ConditionBranchNode` - 条件分支
|
|
87
|
-
- `ParallelBranchNode` - 并行分支
|
|
88
|
-
- `InclusiveBranchNode` - 包容分支
|
|
89
|
-
|
|
90
|
-
### 属性面板
|
|
91
|
-
|
|
92
|
-
节点属性编辑:
|
|
93
|
-
|
|
94
|
-
- 基本信息配置
|
|
95
|
-
- 审批人配置
|
|
96
|
-
- 表单权限配置
|
|
97
|
-
- 通知配置
|
|
98
|
-
- 超时策略配置
|
|
99
|
-
|
|
100
|
-
### 脚本配置器
|
|
101
|
-
|
|
102
|
-
Groovy 脚本编辑支持:
|
|
103
|
-
|
|
104
|
-
- 语法高亮
|
|
105
|
-
- 代码补全
|
|
106
|
-
- 语法检查
|
|
107
|
-
- 变量提示
|
|
108
|
-
- TypeScript/Groovy 转换
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
import { ScriptEditor } from '@coding-flow/flow-pc-design';
|
|
112
|
-
|
|
113
|
-
<ScriptEditor
|
|
114
|
-
value={script}
|
|
115
|
-
onChange={handleScriptChange}
|
|
116
|
-
scriptType="CONDITION"
|
|
117
|
-
variables={availableVariables}
|
|
118
|
-
/>
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### 变量选择器
|
|
122
|
-
|
|
123
|
-
流程变量选择:
|
|
124
|
-
|
|
125
|
-
- 表单字段变量
|
|
126
|
-
- 流程实例变量
|
|
127
|
-
- 系统内置变量
|
|
128
|
-
- 自定义变量
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
import { VariablePicker } from '@coding-flow/flow-pc-design';
|
|
132
|
-
|
|
133
|
-
<VariablePicker
|
|
134
|
-
variables={variables}
|
|
135
|
-
onSelect={handleVariableSelect}
|
|
136
|
-
filterTypes={['FORM_FIELD', 'INSTANCE']}
|
|
137
|
-
/>
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### 策略配置
|
|
141
|
-
|
|
142
|
-
节点策略配置:
|
|
143
|
-
|
|
144
|
-
- 多人审批策略(会签/或签)
|
|
145
|
-
- 超时策略
|
|
146
|
-
- 通知策略
|
|
147
|
-
- 权限策略
|
|
148
|
-
|
|
149
|
-
## 模块结构
|
|
150
|
-
|
|
151
|
-
```
|
|
152
|
-
flow-pc-design/
|
|
153
|
-
├── src/
|
|
154
|
-
│ ├── designer/ # 流程设计器
|
|
155
|
-
│ ├── node-config/ # 节点配置组件
|
|
156
|
-
│ ├── property-panel/ # 属性面板
|
|
157
|
-
│ ├── script/ # 脚本编辑器
|
|
158
|
-
│ ├── variable/ # 变量选择器
|
|
159
|
-
│ ├── strategy/ # 策略配置
|
|
160
|
-
│ ├── components/ # 公共组件
|
|
161
|
-
│ └── index.ts # 统一导出
|
|
162
|
-
└── README.md
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## 使用示例
|
|
166
|
-
|
|
167
|
-
### 流程设计器
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
import { WorkflowDesigner } from '@coding-flow/flow-pc-design';
|
|
171
|
-
import type { Workflow } from '@coding-flow/flow-types';
|
|
172
|
-
|
|
173
|
-
const MyWorkflowDesigner = () => {
|
|
174
|
-
const [workflow, setWorkflow] = useState<Workflow>({ ... });
|
|
175
|
-
|
|
176
|
-
return (
|
|
177
|
-
<WorkflowDesigner
|
|
178
|
-
workflow={workflow}
|
|
179
|
-
onChange={setWorkflow}
|
|
180
|
-
onSave={handleSave}
|
|
181
|
-
onPreview={handlePreview}
|
|
182
|
-
/>
|
|
183
|
-
);
|
|
184
|
-
};
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### 脚本编辑器
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
import { ScriptEditor } from '@coding-flow/flow-pc-design';
|
|
191
|
-
import type { ScriptType } from '@coding-flow/flow-pc-design';
|
|
192
|
-
|
|
193
|
-
const MyScriptEditor = () => {
|
|
194
|
-
const [script, setScript] = useState('');
|
|
195
|
-
|
|
196
|
-
return (
|
|
197
|
-
<ScriptEditor
|
|
198
|
-
value={script}
|
|
199
|
-
onChange={setScript}
|
|
200
|
-
scriptType="CONDITION"
|
|
201
|
-
variables={variables}
|
|
202
|
-
onInsertVariable={(variable) => {
|
|
203
|
-
setScript(prev => prev + variable);
|
|
204
|
-
}}
|
|
205
|
-
/>
|
|
206
|
-
);
|
|
207
|
-
};
|
|
208
|
-
```
|
|
209
|
-
|
|
210
36
|
## Learn more
|
|
211
37
|
|
|
212
|
-
- [
|
|
213
|
-
- [Flow Engine Docs](https://github.com/codingapi/flow-engine) - 完整文档
|
|
214
|
-
- [CLAUDE.md](../../CLAUDE.md) - 开发指南
|
|
38
|
+
- [Flow Engine Docs](https://github.com/codingapi/flow-engine) - 完整文档
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import react from "react";
|
|
3
3
|
import { Button, Form, Select, Space } from "antd";
|
|
4
4
|
import { Field } from "@flowgram.ai/fixed-layout-editor";
|
|
@@ -6,6 +6,7 @@ import { EditOutlined } from "@ant-design/icons";
|
|
|
6
6
|
import { GroovyScriptPreview } from "../../../../script-components/components/groovy-script-preview.js";
|
|
7
7
|
import { OperatorLoadConfigModal } from "../../../../script-components/modal/operator-load-config-modal.js";
|
|
8
8
|
import { GroovyScriptLoader } from "../../../../script-components/components/groovy-script-loader.js";
|
|
9
|
+
import { MaxOperatorCountInput } from "../../../../script-components/components/action/components/max-operator-count.js";
|
|
9
10
|
import { FieldTip } from "../../../field-tip/index.js";
|
|
10
11
|
const SELECT_TYPE_OPTIONS = [
|
|
11
12
|
{
|
|
@@ -102,23 +103,44 @@ const OperatorLoadStrategy = ()=>{
|
|
|
102
103
|
name: "OperatorLoadStrategy.selectType",
|
|
103
104
|
render: ({ field: { value: selectType } })=>{
|
|
104
105
|
const isRangeMode = 'INITIATOR_SELECT' === selectType || 'APPROVER_SELECT' === selectType;
|
|
105
|
-
return /*#__PURE__*/
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
106
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
107
|
+
children: [
|
|
108
|
+
/*#__PURE__*/ jsx(Form.Item, {
|
|
109
|
+
label: /*#__PURE__*/ jsx(FieldTip, {
|
|
110
|
+
label: isRangeMode ? "设定人员范围" : "当前操作人",
|
|
111
|
+
description: isRangeMode ? "设定可选人员范围,留空表示不限范围(可选任意人)。" : "通过脚本设定该节点的操作人。"
|
|
112
|
+
}),
|
|
113
|
+
name: [
|
|
114
|
+
"OperatorLoadStrategy",
|
|
115
|
+
"script"
|
|
116
|
+
],
|
|
117
|
+
children: /*#__PURE__*/ jsx(Field, {
|
|
118
|
+
name: "OperatorLoadStrategy.script",
|
|
119
|
+
render: ({ field: { value, onChange } })=>/*#__PURE__*/ jsx(GroovyScriptLoader, {
|
|
120
|
+
content: OperatorLoadScriptContent,
|
|
121
|
+
value: value,
|
|
122
|
+
onChange: onChange
|
|
123
|
+
})
|
|
120
124
|
})
|
|
121
|
-
|
|
125
|
+
}),
|
|
126
|
+
isRangeMode && /*#__PURE__*/ jsx(Form.Item, {
|
|
127
|
+
label: /*#__PURE__*/ jsx(FieldTip, {
|
|
128
|
+
label: "最大可选人数",
|
|
129
|
+
description: "限制发起人/审批人可选人数的最大值,-1 表示不限制;固定为 1 时即为单选。"
|
|
130
|
+
}),
|
|
131
|
+
name: [
|
|
132
|
+
"OperatorLoadStrategy",
|
|
133
|
+
"maxOperatorCount"
|
|
134
|
+
],
|
|
135
|
+
children: /*#__PURE__*/ jsx(Field, {
|
|
136
|
+
name: "OperatorLoadStrategy.maxOperatorCount",
|
|
137
|
+
render: ({ field: { value, onChange } })=>/*#__PURE__*/ jsx(MaxOperatorCountInput, {
|
|
138
|
+
value: value,
|
|
139
|
+
onChange: onChange
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
]
|
|
122
144
|
});
|
|
123
145
|
}
|
|
124
146
|
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { generateUUID } from "../../../utils/uuid.js";
|
|
1
2
|
class WorkflowFormManager {
|
|
2
3
|
form;
|
|
3
4
|
formList;
|
|
@@ -45,7 +46,7 @@ class WorkflowFormManager {
|
|
|
45
46
|
} else list.push(field);
|
|
46
47
|
if (!exist) list.push({
|
|
47
48
|
...values,
|
|
48
|
-
id:
|
|
49
|
+
id: generateUUID()
|
|
49
50
|
});
|
|
50
51
|
const mainCode = this.form.code;
|
|
51
52
|
if (code === mainCode) return {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import "react";
|
|
3
3
|
import { Col, Form, Row } from "antd";
|
|
4
4
|
import { OperatorLoadPluginView } from "../../../../plugins/view/operator-load-view.js";
|
|
5
|
+
import { MaxOperatorCountInput } from "./max-operator-count.js";
|
|
5
6
|
const AddAuditInput = (props)=>{
|
|
6
7
|
const script = props.value || '';
|
|
7
8
|
const handleChange = (value)=>{
|
|
@@ -12,15 +13,26 @@ const AddAuditInput = (props)=>{
|
|
|
12
13
|
onChange: handleChange
|
|
13
14
|
});
|
|
14
15
|
};
|
|
15
|
-
const AddAuditActionForm = (props)=>/*#__PURE__*/
|
|
16
|
-
children:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
const AddAuditActionForm = (props)=>/*#__PURE__*/ jsxs(Row, {
|
|
17
|
+
children: [
|
|
18
|
+
/*#__PURE__*/ jsx(Col, {
|
|
19
|
+
span: 24,
|
|
20
|
+
children: /*#__PURE__*/ jsx(Form.Item, {
|
|
21
|
+
name: "maxOperatorCount",
|
|
22
|
+
label: "最大可选人数",
|
|
23
|
+
help: "限制加签时可选人数的最大值,-1 表示不限制;固定为 1 时即为单选",
|
|
24
|
+
children: /*#__PURE__*/ jsx(MaxOperatorCountInput, {})
|
|
25
|
+
})
|
|
26
|
+
}),
|
|
27
|
+
/*#__PURE__*/ jsx(Col, {
|
|
28
|
+
span: 24,
|
|
29
|
+
children: /*#__PURE__*/ jsx(Form.Item, {
|
|
30
|
+
name: "script",
|
|
31
|
+
label: "加签人员范围",
|
|
32
|
+
help: "加签人员范围为空时,即为全部人员",
|
|
33
|
+
children: /*#__PURE__*/ jsx(AddAuditInput, {})
|
|
34
|
+
})
|
|
23
35
|
})
|
|
24
|
-
|
|
36
|
+
]
|
|
25
37
|
});
|
|
26
38
|
export { AddAuditActionForm };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import "react";
|
|
3
3
|
import { OperatorLoadPluginView } from "../../../../plugins/view/operator-load-view.js";
|
|
4
|
+
import { MaxOperatorCountInput } from "./max-operator-count.js";
|
|
4
5
|
import { Col, Form, Row } from "antd";
|
|
5
6
|
const DelegateInput = (props)=>{
|
|
6
7
|
const script = props.value || '';
|
|
@@ -12,15 +13,26 @@ const DelegateInput = (props)=>{
|
|
|
12
13
|
onChange: handleChange
|
|
13
14
|
});
|
|
14
15
|
};
|
|
15
|
-
const DelegateActionForm = (props)=>/*#__PURE__*/
|
|
16
|
-
children:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
const DelegateActionForm = (props)=>/*#__PURE__*/ jsxs(Row, {
|
|
17
|
+
children: [
|
|
18
|
+
/*#__PURE__*/ jsx(Col, {
|
|
19
|
+
span: 24,
|
|
20
|
+
children: /*#__PURE__*/ jsx(Form.Item, {
|
|
21
|
+
name: "maxOperatorCount",
|
|
22
|
+
label: "最大可选人数",
|
|
23
|
+
help: "限制委派时可选人数的最大值,-1 表示不限制;固定为 1 时即为单选",
|
|
24
|
+
children: /*#__PURE__*/ jsx(MaxOperatorCountInput, {})
|
|
25
|
+
})
|
|
26
|
+
}),
|
|
27
|
+
/*#__PURE__*/ jsx(Col, {
|
|
28
|
+
span: 24,
|
|
29
|
+
children: /*#__PURE__*/ jsx(Form.Item, {
|
|
30
|
+
name: "script",
|
|
31
|
+
label: "委派人员范围",
|
|
32
|
+
help: "委派人员范围为空时,即为全部人员",
|
|
33
|
+
children: /*#__PURE__*/ jsx(DelegateInput, {})
|
|
34
|
+
})
|
|
23
35
|
})
|
|
24
|
-
|
|
36
|
+
]
|
|
25
37
|
});
|
|
26
38
|
export { DelegateActionForm };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* 最大可选人数的默认值,-1 表示不限制
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_MAX_OPERATOR_COUNT = -1;
|
|
6
|
+
interface MaxOperatorCountInputProps {
|
|
7
|
+
value?: number;
|
|
8
|
+
onChange?: (value: number) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 最大可选人数输入框
|
|
12
|
+
* 为空时按 -1(不限制)处理
|
|
13
|
+
*/
|
|
14
|
+
export declare const MaxOperatorCountInput: React.FC<MaxOperatorCountInputProps>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
|
+
import { InputNumber } from "antd";
|
|
4
|
+
const DEFAULT_MAX_OPERATOR_COUNT = -1;
|
|
5
|
+
const MaxOperatorCountInput = (props)=>/*#__PURE__*/ jsx(InputNumber, {
|
|
6
|
+
style: {
|
|
7
|
+
width: '100%'
|
|
8
|
+
},
|
|
9
|
+
min: -1,
|
|
10
|
+
placeholder: "-1 表示不限制",
|
|
11
|
+
value: props.value ?? DEFAULT_MAX_OPERATOR_COUNT,
|
|
12
|
+
onChange: (val)=>{
|
|
13
|
+
props.onChange?.(val ?? DEFAULT_MAX_OPERATOR_COUNT);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
export { DEFAULT_MAX_OPERATOR_COUNT, MaxOperatorCountInput };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import "react";
|
|
3
3
|
import { OperatorLoadPluginView } from "../../../../plugins/view/operator-load-view.js";
|
|
4
|
+
import { MaxOperatorCountInput } from "./max-operator-count.js";
|
|
4
5
|
import { Col, Form, Row } from "antd";
|
|
5
6
|
const TransferInput = (props)=>{
|
|
6
7
|
const script = props.value || '';
|
|
@@ -12,15 +13,26 @@ const TransferInput = (props)=>{
|
|
|
12
13
|
onChange: handleChange
|
|
13
14
|
});
|
|
14
15
|
};
|
|
15
|
-
const TransferActionForm = (props)=>/*#__PURE__*/
|
|
16
|
-
children:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
const TransferActionForm = (props)=>/*#__PURE__*/ jsxs(Row, {
|
|
17
|
+
children: [
|
|
18
|
+
/*#__PURE__*/ jsx(Col, {
|
|
19
|
+
span: 24,
|
|
20
|
+
children: /*#__PURE__*/ jsx(Form.Item, {
|
|
21
|
+
name: "maxOperatorCount",
|
|
22
|
+
label: "最大可选人数",
|
|
23
|
+
help: "限制转办时可选人数的最大值,-1 表示不限制;固定为 1 时即为单选",
|
|
24
|
+
children: /*#__PURE__*/ jsx(MaxOperatorCountInput, {})
|
|
25
|
+
})
|
|
26
|
+
}),
|
|
27
|
+
/*#__PURE__*/ jsx(Col, {
|
|
28
|
+
span: 24,
|
|
29
|
+
children: /*#__PURE__*/ jsx(Form.Item, {
|
|
30
|
+
name: "script",
|
|
31
|
+
label: "转办人员范围",
|
|
32
|
+
help: "转办人员范围为空时,即为全部人员",
|
|
33
|
+
children: /*#__PURE__*/ jsx(TransferInput, {})
|
|
34
|
+
})
|
|
23
35
|
})
|
|
24
|
-
|
|
36
|
+
]
|
|
25
37
|
});
|
|
26
38
|
export { TransferActionForm };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import react from "react";
|
|
3
|
-
import { Button, Card, Form, Select, Space } from "antd";
|
|
3
|
+
import { Button, Card, Form, Input, Select, Space } from "antd";
|
|
4
4
|
import { useTargetWorkflowPresenter } from "./hooks/use-target-workflow-presenter.js";
|
|
5
5
|
import { SubProcessOperatorPluginView } from "../../../plugins/view/sub-process-opreator-view.js";
|
|
6
6
|
import { FormDataView } from "../form-data/index.js";
|
|
@@ -94,6 +94,17 @@ const SubProcessConfigItem = ({ form, index, removable, remove })=>{
|
|
|
94
94
|
children: /*#__PURE__*/ jsx(FormDataView, {
|
|
95
95
|
form: state.form
|
|
96
96
|
})
|
|
97
|
+
}),
|
|
98
|
+
/*#__PURE__*/ jsx(Form.Item, {
|
|
99
|
+
name: [
|
|
100
|
+
index,
|
|
101
|
+
"workTitle"
|
|
102
|
+
],
|
|
103
|
+
label: "子流程标题",
|
|
104
|
+
tooltip: "不填写时子流程使用流程定义标题;填写后该实例以自定义标题展示(issue #197)",
|
|
105
|
+
children: /*#__PURE__*/ jsx(Input, {
|
|
106
|
+
placeholder: "不填则使用流程定义标题"
|
|
107
|
+
})
|
|
97
108
|
})
|
|
98
109
|
]
|
|
99
110
|
});
|
|
@@ -19,6 +19,10 @@ export declare class SubProcessPresenter {
|
|
|
19
19
|
updateScript(values: SubProcessFormValues): void;
|
|
20
20
|
private toFormData;
|
|
21
21
|
private toScript;
|
|
22
|
+
/**
|
|
23
|
+
* 转义 Groovy 字符串字面量中的单引号,防止用户输入破坏脚本。
|
|
24
|
+
*/
|
|
25
|
+
private escapeSingleQuotes;
|
|
22
26
|
private isRecord;
|
|
23
27
|
private isSubProcessConfig;
|
|
24
28
|
}
|
|
@@ -48,6 +48,7 @@ class SubProcessPresenter {
|
|
|
48
48
|
const meta = JSON.stringify(values);
|
|
49
49
|
const requests = values.processes.map((config)=>{
|
|
50
50
|
const formData = this.toFormData(config);
|
|
51
|
+
if (config.workTitle) return `request.toCreateRequest('${config.workId}', ${config.operatorId}, '${config.actionId}', '${formData}', '${this.escapeSingleQuotes(config.workTitle)}')`;
|
|
51
52
|
return `request.toCreateRequest('${config.workId}', ${config.operatorId}, '${config.actionId}', '${formData}')`;
|
|
52
53
|
}).join(',\n ');
|
|
53
54
|
return `
|
|
@@ -59,9 +60,12 @@ class SubProcessPresenter {
|
|
|
59
60
|
];
|
|
60
61
|
}`;
|
|
61
62
|
}
|
|
63
|
+
escapeSingleQuotes(value) {
|
|
64
|
+
return value.replace(/'/g, "\\'");
|
|
65
|
+
}
|
|
62
66
|
isRecord(value) {
|
|
63
67
|
return 'object' == typeof value && null !== value;
|
|
64
68
|
}
|
|
65
|
-
isSubProcessConfig = (value)=>this.isRecord(value) && (void 0 === value.workId || 'string' == typeof value.workId) && (void 0 === value.actionId || 'string' == typeof value.actionId) && (void 0 === value.operatorId || 'string' == typeof value.operatorId || 'number' == typeof value.operatorId) && (void 0 === value.formData || 'string' == typeof value.formData);
|
|
69
|
+
isSubProcessConfig = (value)=>this.isRecord(value) && (void 0 === value.workId || 'string' == typeof value.workId) && (void 0 === value.actionId || 'string' == typeof value.actionId) && (void 0 === value.operatorId || 'string' == typeof value.operatorId || 'number' == typeof value.operatorId) && (void 0 === value.formData || 'string' == typeof value.formData) && (void 0 === value.workTitle || 'string' == typeof value.workTitle);
|
|
66
70
|
}
|
|
67
71
|
export { SubProcessPresenter };
|
|
@@ -11,6 +11,10 @@ export interface SubProcessConfig {
|
|
|
11
11
|
actionId?: string;
|
|
12
12
|
operatorId?: string | number;
|
|
13
13
|
formData?: string;
|
|
14
|
+
/**
|
|
15
|
+
* 子流程标题;不填则子流程回落流程定义标题(issue #197)
|
|
16
|
+
*/
|
|
17
|
+
workTitle?: string;
|
|
14
18
|
}
|
|
15
19
|
export interface SubProcessFormValues {
|
|
16
20
|
processes: SubProcessConfig[];
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const generateUUID = ()=>{
|
|
2
|
+
if ("u" > typeof crypto && 'function' == typeof crypto.randomUUID) return crypto.randomUUID();
|
|
3
|
+
if ("u" > typeof crypto && 'function' == typeof crypto.getRandomValues) {
|
|
4
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
5
|
+
bytes[6] = 0x0f & bytes[6] | 0x40;
|
|
6
|
+
bytes[8] = 0x3f & bytes[8] | 0x80;
|
|
7
|
+
const hex = Array.from(bytes, (b)=>b.toString(16).padStart(2, '0')).join('');
|
|
8
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
9
|
+
}
|
|
10
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c)=>{
|
|
11
|
+
const r = 16 * Math.random() | 0;
|
|
12
|
+
const v = 'x' === c ? r : 0x3 & r | 0x8;
|
|
13
|
+
return v.toString(16);
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
export { generateUUID };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coding-flow/flow-design",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "flow-engine design components ",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -54,16 +54,16 @@
|
|
|
54
54
|
"nanoid": "^5.1.6",
|
|
55
55
|
"react-redux": "^9.2.0",
|
|
56
56
|
"styled-components": "^5.3.11",
|
|
57
|
-
"@coding-flow/flow-core": "0.1.
|
|
58
|
-
"@coding-flow/flow-
|
|
59
|
-
"@coding-flow/flow-
|
|
60
|
-
"@coding-flow/flow-
|
|
57
|
+
"@coding-flow/flow-core": "0.1.5",
|
|
58
|
+
"@coding-flow/flow-pc-ui": "0.1.5",
|
|
59
|
+
"@coding-flow/flow-types": "0.1.5",
|
|
60
|
+
"@coding-flow/flow-icons": "0.1.5"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/lodash-es": "^4.17.12",
|
|
64
64
|
"@types/styled-components": "^5.1.36",
|
|
65
|
-
"@coding-flow/flow-core": "0.1.
|
|
66
|
-
"@coding-flow/flow-types": "0.1.
|
|
65
|
+
"@coding-flow/flow-core": "0.1.5",
|
|
66
|
+
"@coding-flow/flow-types": "0.1.5"
|
|
67
67
|
},
|
|
68
68
|
"scripts": {
|
|
69
69
|
"build": "rslib build",
|