@flowgram-vue/free-layout-core 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.
Files changed (68) hide show
  1. package/LICENSE +22 -0
  2. package/dist/index.cjs +0 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +0 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/typings.cjs +46 -0
  8. package/dist/typings.cjs.map +1 -0
  9. package/dist/typings.d.ts +1 -0
  10. package/dist/typings.js +40 -0
  11. package/dist/typings.js.map +1 -0
  12. package/package.json +78 -0
  13. package/src/composables/index.ts +24 -0
  14. package/src/composables/typings.ts +97 -0
  15. package/src/composables/use-current-dom-node.ts +18 -0
  16. package/src/composables/use-current-entity.ts +15 -0
  17. package/src/composables/use-node-render-context.ts +18 -0
  18. package/src/composables/use-node-render.ts +192 -0
  19. package/src/composables/use-playground-readonly-state.ts +25 -0
  20. package/src/composables/use-workflow-document.ts +12 -0
  21. package/src/constants.ts +17 -0
  22. package/src/entities/index.ts +8 -0
  23. package/src/entities/workflow-line-entity.ts +640 -0
  24. package/src/entities/workflow-node-entity.ts +17 -0
  25. package/src/entities/workflow-port-entity.ts +340 -0
  26. package/src/entity-datas/index.ts +8 -0
  27. package/src/entity-datas/workflow-line-render-data.ts +136 -0
  28. package/src/entity-datas/workflow-node-lines-data.ts +166 -0
  29. package/src/entity-datas/workflow-node-ports-data.ts +253 -0
  30. package/src/env.d.ts +10 -0
  31. package/src/index.ts +18 -0
  32. package/src/layout/free-layout.ts +166 -0
  33. package/src/layout/index.ts +6 -0
  34. package/src/service/index.ts +10 -0
  35. package/src/service/workflow-drag-service.ts +969 -0
  36. package/src/service/workflow-hover-service.ts +106 -0
  37. package/src/service/workflow-operation-base-service.ts +118 -0
  38. package/src/service/workflow-reset-layout-service.ts +87 -0
  39. package/src/service/workflow-select-service.ts +128 -0
  40. package/src/typings/index.ts +19 -0
  41. package/src/typings/workflow-drag.ts +51 -0
  42. package/src/typings/workflow-edge.ts +15 -0
  43. package/src/typings/workflow-json.ts +64 -0
  44. package/src/typings/workflow-line.ts +71 -0
  45. package/src/typings/workflow-node.ts +52 -0
  46. package/src/typings/workflow-operation.ts +40 -0
  47. package/src/typings/workflow-registry.ts +34 -0
  48. package/src/typings/workflow-sub-canvas.ts +15 -0
  49. package/src/utils/build-group-json.ts +47 -0
  50. package/src/utils/compose.ts +6 -0
  51. package/src/utils/fit-view.ts +21 -0
  52. package/src/utils/flow-node-form-data.ts +45 -0
  53. package/src/utils/get-anti-overlap-position.ts +44 -0
  54. package/src/utils/get-line-center.ts +22 -0
  55. package/src/utils/get-url-params.ts +50 -0
  56. package/src/utils/index.ts +29 -0
  57. package/src/utils/layout-to-positions.ts +65 -0
  58. package/src/utils/location-config-to-point.ts +40 -0
  59. package/src/utils/nanoid.ts +10 -0
  60. package/src/utils/statics.ts +27 -0
  61. package/src/vue/index.ts +6 -0
  62. package/src/vue/node-render-provider.vue +16 -0
  63. package/src/workflow-commands.ts +14 -0
  64. package/src/workflow-document-container-module.ts +50 -0
  65. package/src/workflow-document-contribution.ts +31 -0
  66. package/src/workflow-document-option.ts +148 -0
  67. package/src/workflow-document.ts +873 -0
  68. package/src/workflow-lines-manager.ts +596 -0
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { inject, injectable } from 'inversify';
7
+ import { Emitter, type PositionSchema } from '@flowgram-vue/utils';
8
+ import { EntityManager } from '@flowgram-vue/core';
9
+
10
+ import {
11
+ type WorkflowLineEntity,
12
+ type WorkflowNodeEntity,
13
+ type WorkflowPortEntity,
14
+ } from '../entities';
15
+
16
+ /**
17
+ * 可 Hover 的节点 类型
18
+ */
19
+ export type WorkflowEntityHoverable = WorkflowNodeEntity | WorkflowLineEntity | WorkflowPortEntity;
20
+
21
+ export interface HoverPosition {
22
+ position: PositionSchema;
23
+ target?: HTMLElement;
24
+ }
25
+
26
+ /** @deprecated */
27
+ export type WorkfloEntityHoverable = WorkflowEntityHoverable;
28
+ /**
29
+ * hover 状态管理
30
+ */
31
+ @injectable()
32
+ export class WorkflowHoverService {
33
+ @inject(EntityManager) protected entityManager: EntityManager;
34
+
35
+ protected onHoveredChangeEmitter = new Emitter<string>();
36
+
37
+ protected onUpdateHoverPositionEmitter = new Emitter<HoverPosition>();
38
+
39
+ readonly onHoveredChange = this.onHoveredChangeEmitter.event;
40
+
41
+ readonly onUpdateHoverPosition = this.onUpdateHoverPositionEmitter.event;
42
+
43
+ // 当前鼠标 hover 位置
44
+ hoveredPos: PositionSchema = { x: 0, y: 0 };
45
+
46
+ /**
47
+ * 当前 hovered 的 节点或者线条或者点
48
+ * 1: nodeId / lineId (节点 / 线条)
49
+ * 2: nodeId:portKey (节点连接点)
50
+ */
51
+ hoveredKey = '';
52
+
53
+ /**
54
+ * 更新 hover 的内容
55
+ * @param hoveredKey hovered key
56
+ */
57
+ updateHoveredKey(hoveredKey: string): void {
58
+ if (this.hoveredKey !== hoveredKey) {
59
+ this.hoveredKey = hoveredKey;
60
+ this.onHoveredChangeEmitter.fire(hoveredKey);
61
+ }
62
+ }
63
+
64
+ updateHoverPosition(position: PositionSchema, target?: HTMLElement): void {
65
+ this.hoveredPos = position;
66
+ this.onUpdateHoverPositionEmitter.fire({
67
+ position,
68
+ target,
69
+ });
70
+ }
71
+
72
+ /**
73
+ * 清空 hover 内容
74
+ */
75
+ clearHovered(): void {
76
+ this.updateHoveredKey('');
77
+ }
78
+
79
+ /**
80
+ * 判断是否 hover
81
+ * @param nodeId hoveredKey
82
+ * @returns 是否 hover
83
+ */
84
+ isHovered(nodeId: string): boolean {
85
+ return nodeId === this.hoveredKey;
86
+ }
87
+
88
+ isSomeHovered(): boolean {
89
+ return !!this.hoveredKey;
90
+ }
91
+
92
+ /**
93
+ * 获取被 hover 的节点或线条
94
+ * @deprecated use 'someHovered' instead
95
+ */
96
+ get hoveredNode(): WorkflowEntityHoverable | undefined {
97
+ return this.entityManager.getEntityById(this.hoveredKey);
98
+ }
99
+
100
+ /**
101
+ * 获取被 hover 的节点或线条
102
+ */
103
+ get someHovered(): WorkflowEntityHoverable | undefined {
104
+ return this.entityManager.getEntityById(this.hoveredKey);
105
+ }
106
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { inject } from 'inversify';
7
+ import { IPoint, Emitter } from '@flowgram-vue/utils';
8
+ import { FlowNodeEntityOrId, FlowOperationBaseServiceImpl } from '@flowgram-vue/document';
9
+ import { TransformData } from '@flowgram-vue/core';
10
+
11
+ import { WorkflowLinesManager } from '../workflow-lines-manager';
12
+ import { WorkflowDocument } from '../workflow-document';
13
+ import {
14
+ NodePostionUpdateEvent,
15
+ WorkflowOperationBaseService,
16
+ } from '../typings/workflow-operation';
17
+ import { WorkflowJSON } from '../typings';
18
+ import { WorkflowNodeEntity, WorkflowLineEntity } from '../entities';
19
+
20
+ export class WorkflowOperationBaseServiceImpl
21
+ extends FlowOperationBaseServiceImpl
22
+ implements WorkflowOperationBaseService
23
+ {
24
+ @inject(WorkflowDocument)
25
+ protected declare document: WorkflowDocument;
26
+
27
+ @inject(WorkflowLinesManager) linesManager: WorkflowLinesManager;
28
+
29
+ private onNodePostionUpdateEmitter = new Emitter<NodePostionUpdateEvent>();
30
+
31
+ public readonly onNodePostionUpdate = this.onNodePostionUpdateEmitter.event;
32
+
33
+ updateNodePosition(nodeOrId: FlowNodeEntityOrId, position: IPoint): void {
34
+ const node = this.toNodeEntity(nodeOrId);
35
+
36
+ if (!node) {
37
+ return;
38
+ }
39
+
40
+ const transformData = node.getData(TransformData);
41
+ const oldPosition = {
42
+ x: transformData.position.x,
43
+ y: transformData.position.y,
44
+ };
45
+ transformData.update({
46
+ position,
47
+ });
48
+
49
+ this.onNodePostionUpdateEmitter.fire({
50
+ node,
51
+ oldPosition,
52
+ newPosition: position,
53
+ });
54
+ }
55
+
56
+ fromJSON(json: WorkflowJSON) {
57
+ if (this.document.disposed) return;
58
+ const workflowJSON: WorkflowJSON = {
59
+ nodes: json.nodes ?? [],
60
+ edges: json.edges ?? [],
61
+ };
62
+
63
+ const oldNodes = this.document.getAllNodes();
64
+ const oldEdges = this.linesManager.getAllLines();
65
+ const oldPositionMap = new Map<string, IPoint>(
66
+ oldNodes.map((node) => [
67
+ node.id,
68
+ {
69
+ x: node.transform.transform.position.x,
70
+ y: node.transform.transform.position.y,
71
+ },
72
+ ])
73
+ );
74
+
75
+ const newNodes: WorkflowNodeEntity[] = [];
76
+ const newEdges: WorkflowLineEntity[] = [];
77
+
78
+ // 逐层渲染
79
+ this.document.batchAddFromJSON(workflowJSON, {
80
+ onNodeCreated: (node) => newNodes.push(node),
81
+ onEdgeCreated: (edge) => newEdges.push(edge),
82
+ });
83
+
84
+ const newEdgeIDSet = new Set<string>(newEdges.map((edge) => edge.id));
85
+ oldEdges.forEach((edge) => {
86
+ // 清空旧线条
87
+ if (!newEdgeIDSet.has(edge.id)) {
88
+ edge.dispose();
89
+ return;
90
+ }
91
+ });
92
+
93
+ const newNodeIDSet = new Set<string>(newNodes.map((node) => node.id));
94
+ oldNodes.forEach((node) => {
95
+ // 清空旧节点
96
+ if (!newNodeIDSet.has(node.id)) {
97
+ node.dispose();
98
+ return;
99
+ }
100
+ // 记录现有节点位置变更
101
+ const oldPosition = oldPositionMap.get(node.id);
102
+ const newPosition = {
103
+ x: node.transform.transform.position.x,
104
+ y: node.transform.transform.position.y,
105
+ };
106
+ if (oldPosition && (oldPosition.x !== newPosition.x || oldPosition.y !== newPosition.y)) {
107
+ this.onNodePostionUpdateEmitter.fire({
108
+ node,
109
+ oldPosition,
110
+ newPosition,
111
+ });
112
+ }
113
+ });
114
+
115
+ // 批量触发画布更新
116
+ this.document.fireRender();
117
+ }
118
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { inject, injectable, postConstruct } from 'inversify';
7
+ import { PlaygroundConfigEntity } from '@flowgram-vue/core';
8
+ import { EntityManager } from '@flowgram-vue/core';
9
+ import { DisposableCollection, Emitter, type IPoint } from '@flowgram-vue/utils';
10
+
11
+ import { WorkflowDocument } from '../workflow-document';
12
+ import { layoutToPositions } from '../utils/layout-to-positions';
13
+ import { fitView } from '../utils';
14
+ import { WorkflowNodeEntity } from '../entities';
15
+
16
+ export type PositionMap = Record<string, IPoint>;
17
+
18
+ /**
19
+ * 重置布局服务
20
+ */
21
+ @injectable()
22
+ export class WorkflowResetLayoutService {
23
+ @inject(PlaygroundConfigEntity)
24
+ private _config: PlaygroundConfigEntity;
25
+
26
+ @inject(WorkflowDocument)
27
+ private _document: WorkflowDocument;
28
+
29
+ @inject(EntityManager)
30
+ private _entityManager: EntityManager;
31
+
32
+ private _resetLayoutEmitter = new Emitter<{
33
+ nodeIds: string[];
34
+ positionMap: PositionMap;
35
+ oldPositionMap: PositionMap;
36
+ }>();
37
+
38
+ /**
39
+ * reset layout事件
40
+ */
41
+ readonly onResetLayout = this._resetLayoutEmitter.event;
42
+
43
+ private _toDispose = new DisposableCollection();
44
+
45
+ /**
46
+ * 初始化
47
+ */
48
+ @postConstruct()
49
+ init() {
50
+ this._toDispose.push(this._resetLayoutEmitter);
51
+ }
52
+
53
+ /**
54
+ * 触发重置布局
55
+ * @param nodeIds 节点id
56
+ * @param positionMap 新布局数据
57
+ * @param oldPositionMap 老布局数据
58
+ */
59
+ fireResetLayout(nodeIds: string[], positionMap: PositionMap, oldPositionMap: PositionMap) {
60
+ this._resetLayoutEmitter.fire({
61
+ nodeIds,
62
+ positionMap,
63
+ oldPositionMap,
64
+ });
65
+ }
66
+
67
+ /**
68
+ * 根据数据重新布局
69
+ * @param positionMap
70
+ * @returns
71
+ */
72
+ async layoutToPositions(nodeIds: string[], positionMap: PositionMap) {
73
+ const nodes = nodeIds
74
+ .map(id => this._entityManager.getEntityById(id))
75
+ .filter(Boolean) as WorkflowNodeEntity[];
76
+ const positions = await layoutToPositions(nodes, positionMap);
77
+ fitView(this._document, this._config, true);
78
+ return positions;
79
+ }
80
+
81
+ /**
82
+ * 销毁
83
+ */
84
+ dispose() {
85
+ this._toDispose.dispose();
86
+ }
87
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { inject, injectable } from 'inversify';
7
+ import {
8
+ type Entity,
9
+ Playground,
10
+ SelectionService,
11
+ TransformData,
12
+ type PlaygroundConfigRevealOpts,
13
+ } from '@flowgram-vue/core';
14
+ import { type Event, Rectangle, SizeSchema } from '@flowgram-vue/utils';
15
+
16
+ import { delay } from '../utils';
17
+ import { WorkflowNodeEntity } from '../entities';
18
+ import { type WorkfloEntityHoverable } from './workflow-hover-service';
19
+
20
+ @injectable()
21
+ export class WorkflowSelectService {
22
+ @inject(SelectionService) protected selectionService: SelectionService;
23
+
24
+ @inject(Playground) protected playground: Playground;
25
+
26
+ get onSelectionChanged(): Event<void> {
27
+ return this.selectionService.onSelectionChanged;
28
+ }
29
+
30
+ get selection(): Entity[] {
31
+ return this.selectionService.selection;
32
+ }
33
+
34
+ set selection(entities: Entity[]) {
35
+ this.selectionService.selection = entities;
36
+ }
37
+
38
+ /**
39
+ * 当前激活的节点只能有一个
40
+ */
41
+ get activatedNode(): WorkflowNodeEntity | undefined {
42
+ const { selectedNodes } = this;
43
+ if (selectedNodes.length !== 1) {
44
+ return undefined;
45
+ }
46
+ return selectedNodes[0];
47
+ }
48
+
49
+ isSelected(id: string): boolean {
50
+ return this.selectionService.selection.some(s => s.id === id);
51
+ }
52
+
53
+ isActivated(id: string): boolean {
54
+ return this.activatedNode?.id === id;
55
+ }
56
+
57
+ /**
58
+ * 选中的节点
59
+ */
60
+ get selectedNodes(): WorkflowNodeEntity[] {
61
+ return this.selectionService.selection.filter(
62
+ n => n instanceof WorkflowNodeEntity,
63
+ ) as WorkflowNodeEntity[];
64
+ }
65
+
66
+ /**
67
+ * 选中
68
+ * @param node
69
+ */
70
+ selectNode(node: WorkflowNodeEntity): void {
71
+ this.selectionService.selection = [node];
72
+ }
73
+
74
+ toggleSelect(node: WorkflowNodeEntity): void {
75
+ if (this.selectionService.selection.includes(node)) {
76
+ this.selectionService.selection = this.selectionService.selection.filter(n => n !== node);
77
+ } else {
78
+ this.selectionService.selection = this.selectionService.selection.concat(node);
79
+ }
80
+ }
81
+
82
+ select(node: WorkfloEntityHoverable): void {
83
+ this.selectionService.selection = [node];
84
+ }
85
+
86
+ clear(): void {
87
+ this.selectionService.selection = [];
88
+ }
89
+
90
+ /**
91
+ * 选中并滚动到节点
92
+ * @param node
93
+ */
94
+ async selectNodeAndScrollToView(node: WorkflowNodeEntity, fitView?: boolean): Promise<void> {
95
+ this.selectNodeAndFocus(node);
96
+ const DELAY_TIME = 30;
97
+ // 等待节点渲染完成(一般用于刚添加的节点)
98
+ await delay(DELAY_TIME);
99
+
100
+ const scrollConfig: PlaygroundConfigRevealOpts = {
101
+ entities: [node],
102
+ };
103
+
104
+ if (fitView) {
105
+ const bounds = Rectangle.enlarge([node.getData<TransformData>(TransformData).bounds]).pad(
106
+ 30,
107
+ 30,
108
+ ); // 留出 30 像素的边界
109
+
110
+ const viewport = this.playground.config.getViewport(false);
111
+
112
+ const zoom = SizeSchema.fixSize(bounds, viewport);
113
+
114
+ scrollConfig.zoom = zoom;
115
+ scrollConfig.scrollToCenter = true;
116
+ scrollConfig.easing = true;
117
+ }
118
+
119
+ return this.playground.config.scrollToView(scrollConfig);
120
+ }
121
+
122
+ selectNodeAndFocus(node: WorkflowNodeEntity): void {
123
+ // 新添加的节点需要被选中
124
+ this.select(node);
125
+ // 拖进来需要让画布聚焦, 才能使用快捷键删除
126
+ this.playground.node.focus();
127
+ }
128
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './workflow-json';
7
+ export * from './workflow-edge';
8
+ export * from './workflow-node';
9
+ export * from './workflow-registry';
10
+ export * from './workflow-line';
11
+ export * from './workflow-sub-canvas';
12
+ export * from './workflow-operation';
13
+ export * from './workflow-drag';
14
+
15
+ export const URLParams = Symbol('');
16
+
17
+ export interface URLParams {
18
+ [key: string]: string;
19
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { type PositionSchema } from '@flowgram-vue/utils';
7
+ import { type FlowNodeEntity } from '@flowgram-vue/document';
8
+ import { PlaygroundDrag, type PlaygroundDragEvent } from '@flowgram-vue/core';
9
+
10
+ import { type WorkflowLineEntity, type WorkflowPortEntity } from '../entities';
11
+
12
+ export interface LineEventProps {
13
+ type: 'onDrag' | 'onDragEnd';
14
+ onDragNodeId?: string;
15
+ event?: MouseEvent;
16
+ }
17
+
18
+ interface INodesDragEvent {
19
+ type: string;
20
+ nodes: FlowNodeEntity[];
21
+ startPositions: PositionSchema[];
22
+ dragEvent: PlaygroundDragEvent;
23
+ triggerEvent: MouseEvent | TouchEvent;
24
+ dragger: PlaygroundDrag;
25
+ }
26
+
27
+ export interface NodesDragStartEvent extends INodesDragEvent {
28
+ type: 'onDragStart';
29
+ }
30
+
31
+ export interface NodesDragEndEvent extends INodesDragEvent {
32
+ type: 'onDragEnd';
33
+ }
34
+
35
+ export interface NodesDraggingEvent extends INodesDragEvent {
36
+ type: 'onDragging';
37
+ positions: PositionSchema[];
38
+ }
39
+
40
+ export type NodesDragEvent = NodesDragStartEvent | NodesDraggingEvent | NodesDragEndEvent;
41
+
42
+ export type onDragLineEndParams = {
43
+ fromPort?: WorkflowPortEntity;
44
+ toPort?: WorkflowPortEntity;
45
+ mousePos: PositionSchema;
46
+ line?: WorkflowLineEntity;
47
+ originLine?: WorkflowLineEntity;
48
+ event: PlaygroundDragEvent;
49
+ };
50
+
51
+ export type OnDragLineEnd = (params: onDragLineEndParams) => Promise<void>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ /**
7
+ * 边数据
8
+ */
9
+ export interface WorkflowEdgeJSON {
10
+ sourceNodeID: string;
11
+ targetNodeID: string;
12
+ sourcePortID?: string | number;
13
+ targetPortID?: string | number;
14
+ data?: any;
15
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { type WorkflowLineEntity, type WorkflowNodeEntity } from '../entities';
7
+ import { type WorkflowNodeJSON } from './workflow-node';
8
+ import { type WorkflowEdgeJSON } from './workflow-edge';
9
+
10
+ export interface WorkflowJSON {
11
+ nodes: WorkflowNodeJSON[];
12
+ edges: WorkflowEdgeJSON[];
13
+ }
14
+
15
+ export enum WorkflowContentChangeType {
16
+ /**
17
+ * 添加节点
18
+ */
19
+ ADD_NODE = 'ADD_NODE',
20
+ /**
21
+ * 删除节点
22
+ */
23
+ DELETE_NODE = 'DELETE_NODE',
24
+ /**
25
+ * 移动节点
26
+ */
27
+ MOVE_NODE = 'MOVE_NODE',
28
+ /**
29
+ * 节点数据更新 (表单引擎数据 或者 extInfo 数据)
30
+ */
31
+ NODE_DATA_CHANGE = 'NODE_DATA_CHANGE',
32
+ /**
33
+ * 添加线条
34
+ */
35
+ ADD_LINE = 'ADD_LINE',
36
+ /**
37
+ * 删除线条
38
+ */
39
+ DELETE_LINE = 'DELETE_LINE',
40
+ /**
41
+ * 线条数据修改
42
+ */
43
+ LINE_DATA_CHANGE = 'LINE_DATA_CHANGE',
44
+ /**
45
+ * 节点Meta信息变更
46
+ */
47
+ META_CHANGE = 'META_CHANGE',
48
+ }
49
+
50
+ export interface WorkflowContentChangeEvent {
51
+ type: WorkflowContentChangeType;
52
+ /**
53
+ * 当前触发的元素的json数据,toJSON 需要主动触发
54
+ */
55
+ toJSON: () => any;
56
+ /**
57
+ * oldValue
58
+ */
59
+ oldValue?: any;
60
+ /*
61
+ * 当前的事件的 entity
62
+ */
63
+ entity: WorkflowNodeEntity | WorkflowLineEntity;
64
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { Rectangle, IPoint } from '@flowgram-vue/utils';
7
+
8
+ import { type WorkflowLineEntity } from '../entities';
9
+
10
+ export enum LineType {
11
+ BEZIER, // 贝塞尔曲线
12
+ LINE_CHART, // 折叠线
13
+ STRAIGHT, // 直线
14
+ }
15
+
16
+ export type LineRenderType = LineType | string;
17
+
18
+ export type LinePointLocation = 'left' | 'top' | 'right' | 'bottom';
19
+
20
+ export interface LinePoint {
21
+ x: number;
22
+ y: number;
23
+ location: LinePointLocation;
24
+ }
25
+
26
+ export interface LinePosition {
27
+ from: LinePoint;
28
+ to: LinePoint;
29
+ }
30
+
31
+ export interface LineColor {
32
+ hidden: string;
33
+ default: string;
34
+ drawing: string;
35
+ hovered: string;
36
+ selected: string;
37
+ error: string;
38
+ flowing: string;
39
+ }
40
+
41
+ export enum LineColors {
42
+ HIDDEN = 'var(--g-workflow-line-color-hidden,transparent)', // 隐藏线条
43
+ DEFUALT = 'var(--g-workflow-line-color-default,#4d53e8)',
44
+ DRAWING = 'var(--g-workflow-line-color-drawing, #5DD6E3)', // '#b5bbf8', // '#9197F1',
45
+ HOVER = 'var(--g-workflow-line-color-hover,#37d0ff)',
46
+ SELECTED = 'var(--g-workflow-line-color-selected,#37d0ff)',
47
+ ERROR = 'var(--g-workflow-line-color-error,red)',
48
+ FLOWING = 'var(--g-workflow-line-color-flowing,#4d53e8)', // 流动线条,默认使用主题色
49
+ }
50
+
51
+ export interface LineCenterPoint {
52
+ x: number;
53
+ y: number;
54
+ labelX: number; // Relative to where the line begins
55
+ labelY: number; // Relative to where the line begins
56
+ }
57
+
58
+ export interface WorkflowLineRenderContribution {
59
+ entity: WorkflowLineEntity;
60
+ path: string;
61
+ center?: LineCenterPoint;
62
+ bounds: Rectangle;
63
+ update: (params: { fromPos: LinePoint; toPos: LinePoint }) => void;
64
+ calcDistance: (pos: IPoint) => number;
65
+ }
66
+
67
+ export type WorkflowLineRenderContributionFactory = (new (
68
+ entity: WorkflowLineEntity
69
+ ) => WorkflowLineRenderContribution) & {
70
+ type: LineRenderType;
71
+ };