@flowgram-vue/document 0.2.0
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/LICENSE +22 -0
- package/dist/index.cjs +3233 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1728 -0
- package/dist/index.js +3199 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
- package/src/datas/flow-node-render-data.ts +227 -0
- package/src/datas/flow-node-transform-data.ts +337 -0
- package/src/datas/flow-node-transition-data.ts +182 -0
- package/src/datas/index.ts +8 -0
- package/src/entities/flow-document-transformer-entity.ts +125 -0
- package/src/entities/flow-node-entity.ts +415 -0
- package/src/entities/flow-renderer-state-entity.ts +127 -0
- package/src/entities/index.ts +8 -0
- package/src/flow-document-config.ts +42 -0
- package/src/flow-document-container-module.ts +33 -0
- package/src/flow-document-contribution.ts +22 -0
- package/src/flow-document-options.ts +79 -0
- package/src/flow-document.ts +766 -0
- package/src/flow-render-tree.ts +236 -0
- package/src/flow-virtual-tree.ts +244 -0
- package/src/index.ts +16 -0
- package/src/layout/horizontal-fixed-layout.ts +198 -0
- package/src/layout/index.ts +7 -0
- package/src/layout/vertical-fixed-layout.ts +198 -0
- package/src/services/flow-drag-service.ts +211 -0
- package/src/services/flow-group-service/flow-group-controller.ts +120 -0
- package/src/services/flow-group-service/flow-group-service.ts +107 -0
- package/src/services/flow-group-service/flow-group-utils.ts +104 -0
- package/src/services/flow-group-service/index.ts +7 -0
- package/src/services/flow-operation-base-service.ts +333 -0
- package/src/services/index.ts +8 -0
- package/src/typings/flow-group.ts +8 -0
- package/src/typings/flow-layout.ts +72 -0
- package/src/typings/flow-node-register.ts +356 -0
- package/src/typings/flow-operation.ts +312 -0
- package/src/typings/flow-transition.ts +104 -0
- package/src/typings/flow.ts +70 -0
- package/src/typings/index.ts +11 -0
- package/src/utils/get-default-spacing.ts +21 -0
- package/src/utils/index.ts +6 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { type IPoint } from '@flowgram-vue/utils';
|
|
7
|
+
import { PaddingSchema } from '@flowgram-vue/utils';
|
|
8
|
+
import { PositionSchema } from '@flowgram-vue/utils';
|
|
9
|
+
import { type EntityDataRegistry, type OriginSchema, type SizeSchema } from '@flowgram-vue/core';
|
|
10
|
+
|
|
11
|
+
import { FlowDocument } from '../flow-document';
|
|
12
|
+
import { type FlowNodeEntity } from '../entities';
|
|
13
|
+
import { type FlowNodeTransformData, type FlowNodeTransitionData } from '../datas';
|
|
14
|
+
import { type FlowTransitionLabel, type FlowTransitionLine } from './flow-transition';
|
|
15
|
+
import { FlowLayout, FlowLayoutDefault } from './flow-layout';
|
|
16
|
+
import {
|
|
17
|
+
FLOW_DEFAULT_HIDDEN_TYPES,
|
|
18
|
+
FlowNodeBaseType,
|
|
19
|
+
type FlowNodeJSON,
|
|
20
|
+
FlowNodeType,
|
|
21
|
+
} from './flow';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 节点渲染相关配置信息,可扩展
|
|
25
|
+
*/
|
|
26
|
+
export interface FlowNodeMeta {
|
|
27
|
+
isStart?: boolean; // 是否为开始节点
|
|
28
|
+
addable?: boolean; // 是否可添加节点
|
|
29
|
+
expandable?: boolean; // 是否可展开
|
|
30
|
+
draggable?: boolean | ((node: FlowNodeEntity) => boolean); // 是否可拖拽
|
|
31
|
+
selectable?: boolean | ((node: FlowNodeEntity, mousePos?: PositionSchema) => boolean); // 是否可被框选
|
|
32
|
+
deleteDisable?: boolean; // 是否禁用删除
|
|
33
|
+
copyDisable?: boolean; // 禁用复制
|
|
34
|
+
addDisable?: boolean; // 禁止添加
|
|
35
|
+
hidden?: boolean; // 是否隐藏
|
|
36
|
+
// maxSize?: SizeSchema // 默认展开后的大小
|
|
37
|
+
size?: SizeSchema; // 默认大小
|
|
38
|
+
autoResizeDisable?: boolean; // 禁用监听节点变化自动调整大小
|
|
39
|
+
/**
|
|
40
|
+
* @deprecated 使用 NodeRegister.getOrigin 代替
|
|
41
|
+
*/
|
|
42
|
+
origin?: OriginSchema; // 原点配置,默认 垂直 { x: 0.5, y: 0 } 水平 { x: 0, y: 0.5 }
|
|
43
|
+
defaultExpanded?: boolean; // 默认是否展开
|
|
44
|
+
defaultCollapsed?: boolean; // 复合节点默认是否收起
|
|
45
|
+
spacing?: number | ((transform: FlowNodeTransformData) => number); // 兄弟节点间,等价于 marginBottom
|
|
46
|
+
padding?: PaddingSchema | ((transform: FlowNodeTransformData) => PaddingSchema); // 节点设置了 padding,则不需要 inlineSpacingPre 和 inlineSpacingAfter
|
|
47
|
+
inlineSpacingPre?: number | ((transform: FlowNodeTransformData) => number); // 父子节点间,等价于 paddingTop 或者 paddingLeft
|
|
48
|
+
inlineSpacingAfter?: number | ((transform: FlowNodeTransformData) => number); // 父子节点间,等价于 paddingBottom 或者 paddingRight
|
|
49
|
+
renderKey?: string; // 节点的渲染组件,可以绑定 react 组件
|
|
50
|
+
isInlineBlocks?: boolean | ((node: FlowNodeEntity) => boolean); // 采用水平布局
|
|
51
|
+
minInlineBlockSpacing?: number | ((node: FlowNodeTransformData) => number); // 最小的 inlineBlock 的间距
|
|
52
|
+
isNodeEnd?: boolean; // 是否标识节点结束
|
|
53
|
+
[key: string]: any;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* spacing default key 值
|
|
58
|
+
*/
|
|
59
|
+
export const DefaultSpacingKey = {
|
|
60
|
+
/**
|
|
61
|
+
* 普通节点间距。垂直 / 水平
|
|
62
|
+
*/
|
|
63
|
+
NODE_SPACING: 'SPACING',
|
|
64
|
+
/**
|
|
65
|
+
* 分支节点间距
|
|
66
|
+
*/
|
|
67
|
+
BRANCH_SPACING: 'BRANCH_SPACING',
|
|
68
|
+
/**
|
|
69
|
+
* 圆弧线条拐角 radius
|
|
70
|
+
*/
|
|
71
|
+
ROUNDED_LINE_RADIUS: 'ROUNDED_LINE_RADIUS',
|
|
72
|
+
/**
|
|
73
|
+
* 圆弧线条 x radius
|
|
74
|
+
*/
|
|
75
|
+
ROUNDED_LINE_X_RADIUS: 'ROUNDED_LINE_X_RADIUS',
|
|
76
|
+
/**
|
|
77
|
+
* 圆弧线条 y radius
|
|
78
|
+
*/
|
|
79
|
+
ROUNDED_LINE_Y_RADIUS: 'ROUNDED_LINE_Y_RADIUS',
|
|
80
|
+
/**
|
|
81
|
+
* dynamicSplit block list 下部留白间距,因为有两个拐弯,所以翻一倍
|
|
82
|
+
*/
|
|
83
|
+
INLINE_BLOCKS_PADDING_BOTTOM: 'INLINE_BLOCKS_PADDING_BOTTOM',
|
|
84
|
+
/**
|
|
85
|
+
* 复合节点距离上个节点的距离
|
|
86
|
+
* 条件分支菱形下边和分支的距离
|
|
87
|
+
*/
|
|
88
|
+
COLLAPSED_SPACING: 'COLLAPSED_SPACING',
|
|
89
|
+
/**
|
|
90
|
+
* width of hover area
|
|
91
|
+
*/
|
|
92
|
+
HOVER_AREA_WIDTH: 'HOVER_AREA_WIDTH',
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* 默认一些间隔参数
|
|
97
|
+
*/
|
|
98
|
+
export const DEFAULT_SPACING = {
|
|
99
|
+
NULL: 0,
|
|
100
|
+
[DefaultSpacingKey.NODE_SPACING]: 32, // 普通节点间距。垂直 / 水平
|
|
101
|
+
[DefaultSpacingKey.BRANCH_SPACING]: 20, // 分支节点间距
|
|
102
|
+
/**
|
|
103
|
+
* @deprecated use 'BRANCH_SPACING' instead
|
|
104
|
+
*/
|
|
105
|
+
MARGIN_RIGHT: 20, // 分支节点右边间距
|
|
106
|
+
INLINE_BLOCK_PADDING_BOTTOM: 16, // block 底部留白
|
|
107
|
+
INLINE_BLOCKS_PADDING_TOP: 30, // block list 上部留白间距
|
|
108
|
+
// JS 浮点数有误差,1046.6 -1006.6 = 39.9999999,会导致 间距/20 < 2 导致布局计算问题,因此需要额外增加 0.1 像素
|
|
109
|
+
[DefaultSpacingKey.INLINE_BLOCKS_PADDING_BOTTOM]: 40.1, // block lit 下部留白间距,因为有两个拐弯,所以翻一倍
|
|
110
|
+
MIN_INLINE_BLOCK_SPACING: 200, // 分支间最小边距 (垂直布局)
|
|
111
|
+
MIN_INLINE_BLOCK_SPACING_HORIZONTAL: 80, // 分支间最小边距 (水平布局)
|
|
112
|
+
[DefaultSpacingKey.COLLAPSED_SPACING]: 12, // 复合节点距离上个节点的距离
|
|
113
|
+
[DefaultSpacingKey.ROUNDED_LINE_RADIUS]: 16, // 圆弧线条拐角 radius
|
|
114
|
+
[DefaultSpacingKey.ROUNDED_LINE_X_RADIUS]: 16, // 圆弧线条 x radius
|
|
115
|
+
[DefaultSpacingKey.ROUNDED_LINE_Y_RADIUS]: 20, // 圆弧线条 y radius
|
|
116
|
+
[DefaultSpacingKey.HOVER_AREA_WIDTH]: 20, // width of hover area
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* 拖拽种类枚举
|
|
121
|
+
* 1. 节点拖拽
|
|
122
|
+
* 2. 分支拖拽
|
|
123
|
+
*/
|
|
124
|
+
export enum DRAGGING_TYPE {
|
|
125
|
+
NODE = 'node',
|
|
126
|
+
BRANCH = 'branch',
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 拖拽分支 Adder、Line 类型
|
|
131
|
+
*/
|
|
132
|
+
export enum LABEL_SIDE_TYPE {
|
|
133
|
+
// 前缀分支
|
|
134
|
+
PRE_BRANCH = 'pre_branch',
|
|
135
|
+
NORMAL_BRANCH = 'normal_branch',
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* 默认节点大小
|
|
140
|
+
*/
|
|
141
|
+
export const DEFAULT_SIZE = {
|
|
142
|
+
width: 280,
|
|
143
|
+
height: 60,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* 默认 meta 配置
|
|
148
|
+
*/
|
|
149
|
+
export const DEFAULT_FLOW_NODE_META: (
|
|
150
|
+
nodeType: FlowNodeType,
|
|
151
|
+
document: FlowDocument
|
|
152
|
+
) => FlowNodeMeta = (nodeType: FlowNodeType, document: FlowDocument) => {
|
|
153
|
+
const hidden = FLOW_DEFAULT_HIDDEN_TYPES.includes(nodeType);
|
|
154
|
+
return {
|
|
155
|
+
isStart: nodeType === 'start',
|
|
156
|
+
hidden,
|
|
157
|
+
defaultExpanded: document.options.allNodesDefaultExpanded,
|
|
158
|
+
size: DEFAULT_SIZE,
|
|
159
|
+
origin: document.layout.getDefaultNodeOrigin(),
|
|
160
|
+
isInlineBlocks: nodeType === FlowNodeBaseType.INLINE_BLOCKS,
|
|
161
|
+
// miniSize: { width: 200, height: 40 },
|
|
162
|
+
spacing: DEFAULT_SPACING.SPACING,
|
|
163
|
+
inlineSpacingPre: 0,
|
|
164
|
+
inlineSpacingAfter: 0,
|
|
165
|
+
expandable: true,
|
|
166
|
+
draggable: true,
|
|
167
|
+
selectable: true,
|
|
168
|
+
renderKey: '',
|
|
169
|
+
minInlineBlockSpacing: () => {
|
|
170
|
+
const isVertical = FlowLayoutDefault.isVertical(document.layout);
|
|
171
|
+
return isVertical
|
|
172
|
+
? DEFAULT_SPACING.MIN_INLINE_BLOCK_SPACING
|
|
173
|
+
: DEFAULT_SPACING.MIN_INLINE_BLOCK_SPACING_HORIZONTAL;
|
|
174
|
+
},
|
|
175
|
+
} as FlowNodeMeta;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* 节点注册
|
|
180
|
+
*/
|
|
181
|
+
export interface FlowNodeRegistry<M extends FlowNodeMeta = FlowNodeMeta> {
|
|
182
|
+
/**
|
|
183
|
+
* 从另外一个注册扩展
|
|
184
|
+
*/
|
|
185
|
+
extend?: string;
|
|
186
|
+
/**
|
|
187
|
+
* 节点类型
|
|
188
|
+
*/
|
|
189
|
+
type: FlowNodeType;
|
|
190
|
+
/**
|
|
191
|
+
* 节点注册的数据,可以理解为 ECS 里的 Component, 这里可以配置自定义数据
|
|
192
|
+
*/
|
|
193
|
+
dataRegistries?: EntityDataRegistry[];
|
|
194
|
+
/**
|
|
195
|
+
* 节点画布相关初始化配置信息,会覆盖 DEFAULT_FLOW_NODE_META
|
|
196
|
+
*/
|
|
197
|
+
meta?: Partial<M>;
|
|
198
|
+
/**
|
|
199
|
+
* 自定义创建节点,可以自定义节点的树形结构
|
|
200
|
+
* 返回新加入的节点,这样才能统计缓存
|
|
201
|
+
*
|
|
202
|
+
* @action 使用该方法,在创建时候将会忽略 json blocks 数据,而是交给适用节点自己处理 json 逻辑
|
|
203
|
+
*/
|
|
204
|
+
onCreate?: (node: FlowNodeEntity, json: FlowNodeJSON) => FlowNodeEntity[] | void;
|
|
205
|
+
/**
|
|
206
|
+
* 添加子 block,一般用于分支的动态添加
|
|
207
|
+
*/
|
|
208
|
+
onBlockChildCreate?: (
|
|
209
|
+
node: FlowNodeEntity,
|
|
210
|
+
json: FlowNodeJSON,
|
|
211
|
+
addedNodes?: FlowNodeEntity[] // 新创建的节点都要存在这里
|
|
212
|
+
) => FlowNodeEntity;
|
|
213
|
+
/**
|
|
214
|
+
* 创建线条
|
|
215
|
+
*/
|
|
216
|
+
getLines?: (transition: FlowNodeTransitionData, layout: FlowLayout) => FlowTransitionLine[];
|
|
217
|
+
/**
|
|
218
|
+
* 创建 label
|
|
219
|
+
*/
|
|
220
|
+
getLabels?: (transition: FlowNodeTransitionData, layout: FlowLayout) => FlowTransitionLabel[];
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* 调整子节点的线条,优先级高于子节点本身的 getLines
|
|
224
|
+
*/
|
|
225
|
+
getChildLines?: (transition: FlowNodeTransitionData, layout: FlowLayout) => FlowTransitionLine[];
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* 调整子节点的 Labels,优先级高于子节点本身的 getLabels
|
|
229
|
+
*/
|
|
230
|
+
getChildLabels?: (
|
|
231
|
+
transition: FlowNodeTransitionData,
|
|
232
|
+
layout: FlowLayout
|
|
233
|
+
) => FlowTransitionLabel[];
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* 自定义输入节点
|
|
237
|
+
*/
|
|
238
|
+
getInputPoint?: (transform: FlowNodeTransformData, layout: FlowLayout) => IPoint;
|
|
239
|
+
/**
|
|
240
|
+
* 自定义输出节点
|
|
241
|
+
*/
|
|
242
|
+
getOutputPoint?: (transform: FlowNodeTransformData, layoutKey: FlowLayout) => IPoint;
|
|
243
|
+
/**
|
|
244
|
+
* 获取当前节点 Position 偏移量,偏移量计算只能使用已经计算完的数据,如上一个节点或者子节点,不然会造成 o(n^2) 复杂度
|
|
245
|
+
*
|
|
246
|
+
* 1. 切记不要用当前节点的 localBounds(相对位置 bbox),因为 delta 计算发生在 localBounds 计算之前
|
|
247
|
+
* 2. 切记不要用 bounds(绝对位置 bbox, 会触发所有父节点绝对位置计算), bounds 只能在最终 render 时候使用
|
|
248
|
+
* 3. 可以用 pre 节点 和 子节点的 localBounds 或者 size 数据,因为子节点是先算的
|
|
249
|
+
* 4. 可以用当前节点的 size (所有子节点的最大 bbox), 这是已经确定下来的
|
|
250
|
+
*/
|
|
251
|
+
getDelta?: (transform: FlowNodeTransformData, layout: FlowLayout) => IPoint | undefined;
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* 动态获取原点,会覆盖 meta.origin
|
|
255
|
+
*/
|
|
256
|
+
getOrigin?(transform: FlowNodeTransformData, layout: FlowLayout): IPoint;
|
|
257
|
+
/**
|
|
258
|
+
* 原点 X 偏移
|
|
259
|
+
* @param transform
|
|
260
|
+
*/
|
|
261
|
+
getOriginDeltaX?: (transform: FlowNodeTransformData, layout: FlowLayout) => number;
|
|
262
|
+
/**
|
|
263
|
+
* 原点 Y 偏移
|
|
264
|
+
* @param transform
|
|
265
|
+
*/
|
|
266
|
+
getOriginDeltaY?: (transform: FlowNodeTransformData, layout: FlowLayout) => number;
|
|
267
|
+
/**
|
|
268
|
+
* 通过 parent 计算当前节点的偏移,规则同 getDelta
|
|
269
|
+
*/
|
|
270
|
+
getChildDelta?: (childBlock: FlowNodeTransformData, layout: FlowLayout) => IPoint | undefined;
|
|
271
|
+
/**
|
|
272
|
+
* 在当前节点布局完成后调用,可以对布局做更精细的调整
|
|
273
|
+
*/
|
|
274
|
+
onAfterUpdateLocalTransform?: (transform: FlowNodeTransformData, layout: FlowLayout) => void;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* 子节点的 registry 覆盖,这里通过 originParent 来查找
|
|
278
|
+
*/
|
|
279
|
+
extendChildRegistries?: FlowNodeRegistry[];
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @deprecated
|
|
283
|
+
* 自定义子节点添加逻辑
|
|
284
|
+
* @param node 节点
|
|
285
|
+
* @param json 添加的节点 JSON
|
|
286
|
+
* @param options 其它配置
|
|
287
|
+
* @returns
|
|
288
|
+
*/
|
|
289
|
+
addChild?: (
|
|
290
|
+
node: FlowNodeEntity,
|
|
291
|
+
json: FlowNodeJSON,
|
|
292
|
+
options?: {
|
|
293
|
+
hidden?: boolean;
|
|
294
|
+
index?: number;
|
|
295
|
+
}
|
|
296
|
+
) => FlowNodeEntity;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* 内部用于继承逻辑判断,不要使用
|
|
300
|
+
*/
|
|
301
|
+
__extends__?: FlowNodeType[];
|
|
302
|
+
/**
|
|
303
|
+
* 扩展注册器
|
|
304
|
+
*/
|
|
305
|
+
[key: string]: any;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export namespace FlowNodeRegistry {
|
|
309
|
+
export function mergeChildRegistries(
|
|
310
|
+
r1: FlowNodeRegistry[] = [],
|
|
311
|
+
r2: FlowNodeRegistry[] = []
|
|
312
|
+
): FlowNodeRegistry[] {
|
|
313
|
+
if (r1.length === 0 || r2.length === 0) {
|
|
314
|
+
return [...r1, ...r2];
|
|
315
|
+
}
|
|
316
|
+
const r1Filter = r1.map((r1Current) => {
|
|
317
|
+
const r2Current = r2.find((n) => n.type === r1Current.type);
|
|
318
|
+
if (r2Current) {
|
|
319
|
+
return merge(r1Current, r2Current, r1Current.type);
|
|
320
|
+
}
|
|
321
|
+
return r1Current;
|
|
322
|
+
});
|
|
323
|
+
const r2Filter = r2.filter((n) => !r1.some((r) => r.type === n.type));
|
|
324
|
+
return [...r1Filter, ...r2Filter];
|
|
325
|
+
}
|
|
326
|
+
export function merge(
|
|
327
|
+
registry1: FlowNodeRegistry,
|
|
328
|
+
registry2: FlowNodeRegistry,
|
|
329
|
+
finalType: FlowNodeType
|
|
330
|
+
): FlowNodeRegistry {
|
|
331
|
+
const extendKeys = registry1.__extends__ ? registry1.__extends__.slice() : [];
|
|
332
|
+
if (registry1.type !== registry2.type) {
|
|
333
|
+
extendKeys.unshift(registry1.type);
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
...registry1,
|
|
337
|
+
...registry2,
|
|
338
|
+
extendChildRegistries: mergeChildRegistries(
|
|
339
|
+
registry1.extendChildRegistries,
|
|
340
|
+
registry2.extendChildRegistries
|
|
341
|
+
),
|
|
342
|
+
meta: { ...registry1.meta, ...registry2.meta },
|
|
343
|
+
extend: undefined,
|
|
344
|
+
type: finalType,
|
|
345
|
+
__extends__: extendKeys,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export function extend(
|
|
350
|
+
registry: FlowNodeRegistry,
|
|
351
|
+
extendRegistries: FlowNodeRegistry[]
|
|
352
|
+
): FlowNodeRegistry {
|
|
353
|
+
if (!extendRegistries.length) return registry;
|
|
354
|
+
return extendRegistries.reduce((res, ext) => merge(res, ext, registry.type), registry);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Event } from '@flowgram-vue/utils';
|
|
7
|
+
import { Disposable } from '@flowgram-vue/utils';
|
|
8
|
+
|
|
9
|
+
import { type FlowNodeEntity } from '../entities/flow-node-entity';
|
|
10
|
+
import { AddNodeData, FlowNodeJSON } from './flow';
|
|
11
|
+
|
|
12
|
+
export enum OperationType {
|
|
13
|
+
addFromNode = 'addFromNode',
|
|
14
|
+
deleteFromNode = 'deleteFromNode',
|
|
15
|
+
addBlock = 'addBlock',
|
|
16
|
+
deleteBlock = 'deleteBlock',
|
|
17
|
+
createGroup = 'createGroup',
|
|
18
|
+
ungroup = 'ungroup',
|
|
19
|
+
moveNodes = 'moveNodes',
|
|
20
|
+
moveBlock = 'moveBlock',
|
|
21
|
+
moveChildNodes = 'moveChildNodes',
|
|
22
|
+
addNodes = 'addNodes',
|
|
23
|
+
deleteNodes = 'deleteNodes',
|
|
24
|
+
addChildNode = 'addChildNode',
|
|
25
|
+
deleteChildNode = 'deleteChildNode',
|
|
26
|
+
addNode = 'addNode',
|
|
27
|
+
deleteNode = 'deleteNode',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface AddOrDeleteFromNodeOperationValue {
|
|
31
|
+
fromId: string;
|
|
32
|
+
data: FlowNodeJSON;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface AddOrDeleteNodeOperationValue {
|
|
36
|
+
fromId: string;
|
|
37
|
+
data: FlowNodeJSON;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface AddFromNodeOperation {
|
|
41
|
+
type: OperationType.addFromNode;
|
|
42
|
+
value: AddOrDeleteFromNodeOperationValue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface DeleteFromNodeOperation {
|
|
46
|
+
type: OperationType.deleteFromNode;
|
|
47
|
+
value: AddOrDeleteFromNodeOperationValue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface AddOrDeleteBlockValue {
|
|
51
|
+
targetId: string;
|
|
52
|
+
index?: number;
|
|
53
|
+
blockData: FlowNodeJSON;
|
|
54
|
+
parentId?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface createOrUngroupValue {
|
|
58
|
+
targetId: string;
|
|
59
|
+
groupId: string;
|
|
60
|
+
nodeIds: string[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface AddBlockOperation {
|
|
64
|
+
type: OperationType.addBlock;
|
|
65
|
+
value: AddOrDeleteBlockValue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface DeleteBlockOperation {
|
|
69
|
+
type: OperationType.deleteBlock;
|
|
70
|
+
value: AddOrDeleteBlockValue;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface CreateGroupOperation {
|
|
74
|
+
type: OperationType.createGroup;
|
|
75
|
+
value: createOrUngroupValue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface UngroupOperation {
|
|
79
|
+
type: OperationType.ungroup;
|
|
80
|
+
value: createOrUngroupValue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface MoveNodesOperationValue {
|
|
84
|
+
fromId: string;
|
|
85
|
+
toId: string;
|
|
86
|
+
nodeIds: string[];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface MoveNodesOperation {
|
|
90
|
+
type: OperationType.moveNodes;
|
|
91
|
+
value: MoveNodesOperationValue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface AddOrDeleteNodesOperationValue {
|
|
95
|
+
fromId: string;
|
|
96
|
+
nodes: FlowNodeJSON[];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface AddNodesOperation {
|
|
100
|
+
type: OperationType.addNodes;
|
|
101
|
+
value: AddOrDeleteNodesOperationValue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface DeleteNodesOperation {
|
|
105
|
+
type: OperationType.deleteNodes;
|
|
106
|
+
value: AddOrDeleteNodesOperationValue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface MoveChildNodesOperationValue {
|
|
110
|
+
nodeIds: string[];
|
|
111
|
+
fromParentId: string;
|
|
112
|
+
fromIndex: number;
|
|
113
|
+
toParentId: string;
|
|
114
|
+
toIndex: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export type MoveBlockOperationValue = {
|
|
118
|
+
nodeId: string;
|
|
119
|
+
fromParentId: string;
|
|
120
|
+
fromIndex: number;
|
|
121
|
+
toParentId: string;
|
|
122
|
+
toIndex: number;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export interface MoveBlockOperation {
|
|
126
|
+
type: OperationType.moveBlock;
|
|
127
|
+
value: MoveBlockOperationValue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface MoveChildNodesOperation {
|
|
131
|
+
type: OperationType.moveChildNodes;
|
|
132
|
+
value: MoveChildNodesOperationValue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface AddChildNodeOperation {
|
|
136
|
+
type: OperationType.addChildNode;
|
|
137
|
+
value: AddOrDeleteChildNodeValue;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface DeleteChildNodeOperation {
|
|
141
|
+
type: OperationType.deleteChildNode;
|
|
142
|
+
value: AddOrDeleteChildNodeValue;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface AddOrDeleteChildNodeValue {
|
|
146
|
+
data: FlowNodeJSON;
|
|
147
|
+
parentId?: string;
|
|
148
|
+
index?: number;
|
|
149
|
+
originParentId?: string;
|
|
150
|
+
hidden?: boolean;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface AddNodeOperation {
|
|
154
|
+
type: OperationType.addNode;
|
|
155
|
+
value: AddOrDeleteNodeValue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface DeleteNodeOperation {
|
|
159
|
+
type: OperationType.deleteNode;
|
|
160
|
+
value: AddOrDeleteNodeValue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface AddOrDeleteNodeValue {
|
|
164
|
+
data: FlowNodeJSON;
|
|
165
|
+
parentId?: string;
|
|
166
|
+
index?: number;
|
|
167
|
+
hidden?: boolean;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export type FlowOperation =
|
|
171
|
+
| AddFromNodeOperation
|
|
172
|
+
| DeleteFromNodeOperation
|
|
173
|
+
| AddBlockOperation
|
|
174
|
+
| DeleteBlockOperation
|
|
175
|
+
| CreateGroupOperation
|
|
176
|
+
| UngroupOperation
|
|
177
|
+
| MoveNodesOperation
|
|
178
|
+
| AddNodesOperation
|
|
179
|
+
| DeleteNodesOperation
|
|
180
|
+
| MoveBlockOperation
|
|
181
|
+
| AddChildNodeOperation
|
|
182
|
+
| DeleteChildNodeOperation
|
|
183
|
+
| MoveChildNodesOperation
|
|
184
|
+
| AddNodeOperation
|
|
185
|
+
| DeleteNodeOperation;
|
|
186
|
+
|
|
187
|
+
export type FlowNodeEntityOrId = string | FlowNodeEntity;
|
|
188
|
+
|
|
189
|
+
// 添加节点时的配置
|
|
190
|
+
export type AddNodeConfig = {
|
|
191
|
+
// 父节点
|
|
192
|
+
parent?: FlowNodeEntityOrId;
|
|
193
|
+
// 是否隐藏
|
|
194
|
+
hidden?: boolean;
|
|
195
|
+
// 插入位置
|
|
196
|
+
index?: number;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 添加block时的配置
|
|
201
|
+
*/
|
|
202
|
+
export interface AddBlockConfig {
|
|
203
|
+
// 父节点,默认去找 $inlineBlocks$
|
|
204
|
+
parent?: FlowNodeEntity;
|
|
205
|
+
// 插入位置,默认最后
|
|
206
|
+
index?: number;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* 移动节点时的配置
|
|
211
|
+
*/
|
|
212
|
+
export interface MoveNodeConfig {
|
|
213
|
+
// 目标父节点,如果不传,默认使用移动节点的父节点
|
|
214
|
+
parent?: FlowNodeEntityOrId;
|
|
215
|
+
// 目标位置, 默认移动到最后
|
|
216
|
+
index?: number;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* 节点添加事件
|
|
221
|
+
*/
|
|
222
|
+
export interface OnNodeAddEvent {
|
|
223
|
+
node: FlowNodeEntity;
|
|
224
|
+
data: AddNodeData;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* 节点移动事件
|
|
229
|
+
*/
|
|
230
|
+
export interface OnNodeMoveEvent {
|
|
231
|
+
node: FlowNodeEntity;
|
|
232
|
+
fromParent: FlowNodeEntity;
|
|
233
|
+
fromIndex: number;
|
|
234
|
+
toParent: FlowNodeEntity;
|
|
235
|
+
toIndex: number;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export interface FlowOperationBaseService extends Disposable {
|
|
239
|
+
/**
|
|
240
|
+
* 执行操作
|
|
241
|
+
* @param operation 可序列化的操作
|
|
242
|
+
* @returns 操作返回
|
|
243
|
+
*/
|
|
244
|
+
apply(operation: FlowOperation): any;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* 添加节点,如果节点已经存在则不会重复创建
|
|
248
|
+
* @param nodeJSON 节点数据
|
|
249
|
+
* @param config 配置
|
|
250
|
+
* @returns 成功添加的节点
|
|
251
|
+
*/
|
|
252
|
+
addNode(nodeJSON: FlowNodeJSON, config?: AddNodeConfig): FlowNodeEntity;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* 基于某一个起始节点往后面添加
|
|
256
|
+
* @param fromNode 起始节点
|
|
257
|
+
* @param nodeJSON 添加的节点JSON
|
|
258
|
+
*/
|
|
259
|
+
addFromNode(fromNode: FlowNodeEntityOrId, nodeJSON: FlowNodeJSON): FlowNodeEntity;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* 删除节点
|
|
263
|
+
* @param node 节点
|
|
264
|
+
* @returns
|
|
265
|
+
*/
|
|
266
|
+
deleteNode(node: FlowNodeEntityOrId): void;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* 批量删除节点
|
|
270
|
+
* @param nodes
|
|
271
|
+
*/
|
|
272
|
+
deleteNodes(nodes: FlowNodeEntityOrId[]): void;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* 添加块(分支)
|
|
276
|
+
* @param target 目标
|
|
277
|
+
* @param blockJSON 块数据
|
|
278
|
+
* @param config 配置
|
|
279
|
+
* @returns
|
|
280
|
+
*/
|
|
281
|
+
addBlock(
|
|
282
|
+
target: FlowNodeEntityOrId,
|
|
283
|
+
blockJSON: FlowNodeJSON,
|
|
284
|
+
config?: AddBlockConfig
|
|
285
|
+
): FlowNodeEntity;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* 移动节点
|
|
289
|
+
* @param node 被移动的节点
|
|
290
|
+
* @param config 移动节点配置
|
|
291
|
+
*/
|
|
292
|
+
moveNode(node: FlowNodeEntityOrId, config?: MoveNodeConfig): void;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* 拖拽节点
|
|
296
|
+
* @param param0
|
|
297
|
+
* @returns
|
|
298
|
+
*/
|
|
299
|
+
dragNodes({ dropNode, nodes }: { dropNode: FlowNodeEntity; nodes: FlowNodeEntity[] }): void;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* 添加节点的回调
|
|
303
|
+
*/
|
|
304
|
+
onNodeAdd: Event<OnNodeAddEvent>;
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* 节点移动的回调
|
|
308
|
+
*/
|
|
309
|
+
onNodeMove: Event<OnNodeMoveEvent>;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export const FlowOperationBaseService = Symbol('FlowOperationBaseService');
|