Skip to content

Commit 4b6e4ef

Browse files
authored
feat(free-layout): workflow onContentChange add LINE_DATA_CHANGE event, workflow-line-entity remove isDefaultLine (bytedance#660)
* feat(free-layout): workflow onContentChange add LINE_DATA_CHANGE event * refactor(free-layout): workflow-line-entity remove isDefaultLine * chore(demo): demo-nextjs-antd add build:prod * fix(free-layout): workflow-drag-service lineData update * feat(free-history-plugin): add change-line-data to history * � This is a combination of 2 commits. � This is the 1st commit message: feat(free-history-plugin): add change-line-data to history � The commit message bytedance#2 will be skipped: � feat(free-history-plugin): add change-line-data to history * fix: history lint
1 parent c91f70c commit 4b6e4ef

File tree

21 files changed

+355
-24
lines changed

21 files changed

+355
-24
lines changed

apps/demo-nextjs-antd/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
],
1919
"scripts": {
2020
"dev": "next dev",
21-
"build": "next build",
21+
"build": "exit 0",
22+
"build:prod": "next build",
2223
"start": "next start",
2324
"lint": "eslint ./src --cache",
2425
"lint:fix": "eslint ./src --fix"

packages/canvas-engine/free-layout-core/__tests__/mocks/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export const baseJSON: WorkflowJSON = {
6666
{
6767
sourceNodeID: 'start_0',
6868
targetNodeID: 'condition_0',
69+
data: { a: 33 },
6970
},
7071
{
7172
sourceNodeID: 'condition_0',
@@ -112,6 +113,7 @@ export const nestJSON: WorkflowJSON = {
112113
{
113114
sourceNodeID: 'break_0',
114115
targetNodeID: 'variable_0',
116+
data: { a: 33 },
115117
},
116118
],
117119
},

packages/canvas-engine/free-layout-core/__tests__/workflow-document.test.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55

66
import { vi } from 'vitest';
77
import { interfaces } from 'inversify';
8-
import { FlowNodeTransformData } from '@flowgram.ai/document';
9-
import { FlowNodeRegistry } from '@flowgram.ai/document';
10-
import { FlowNodeBaseType } from '@flowgram.ai/document';
8+
import { FlowNodeBaseType, FlowNodeRegistry, FlowNodeTransformData } from '@flowgram.ai/document';
119
import { PlaygroundConfigEntity } from '@flowgram.ai/core';
1210

1311
import {
@@ -20,7 +18,7 @@ import {
2018
WorkflowNodeJSON,
2119
WorkflowSubCanvas,
2220
} from '../src';
23-
import { createWorkflowContainer, baseJSON, nestJSON, createSubCanvasNodes } from './mocks';
21+
import { baseJSON, createSubCanvasNodes, createWorkflowContainer, nestJSON } from './mocks';
2422

2523
let container: interfaces.Container;
2624
let document: WorkflowDocument;
@@ -551,4 +549,23 @@ describe('workflow-document with nestedJSON & subCanvas', () => {
551549
document.dispose();
552550
expect(() => document.toJSON()).toThrowError(/disposed/);
553551
});
552+
it('lineData change trigger onContentChange', () => {
553+
document.fromJSON(baseJSON);
554+
let contentChangeEvent: WorkflowContentChangeEvent;
555+
document.onContentChange((e) => {
556+
contentChangeEvent = e;
557+
});
558+
const line = document.linesManager.getLine({
559+
from: 'start_0',
560+
to: 'condition_0',
561+
})!;
562+
line.lineData = { b: 33 };
563+
expect(document.toJSON().edges[0].data).toEqual({ b: 33 });
564+
expect(contentChangeEvent!.type).toEqual(WorkflowContentChangeType.LINE_DATA_CHANGE);
565+
expect(contentChangeEvent!.toJSON()).toEqual({
566+
sourceNodeID: 'start_0',
567+
targetNodeID: 'condition_0',
568+
data: { b: 33 },
569+
});
570+
});
554571
});

packages/canvas-engine/free-layout-core/__tests__/workflow-lines-manager.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,5 +240,23 @@ describe('workflow-lines-manager', () => {
240240
// 选中状态应该优先于流动状态
241241
expect(linesManager.getLineColor(line!)).toBe('#00ff00');
242242
});
243+
it('line data change', () => {
244+
const line = linesManager.createLine({
245+
from: 'start_0',
246+
to: 'end_0',
247+
data: { a: 1 },
248+
})!;
249+
expect(line.toJSON()).toEqual({
250+
sourceNodeID: 'start_0',
251+
targetNodeID: 'end_0',
252+
data: { a: 1 },
253+
});
254+
line.lineData = { a: 2 };
255+
expect(line.toJSON()).toEqual({
256+
sourceNodeID: 'start_0',
257+
targetNodeID: 'end_0',
258+
data: { a: 2 },
259+
});
260+
});
243261
});
244262
});

packages/canvas-engine/free-layout-core/src/entities/workflow-line-entity.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import { isEqual } from 'lodash-es';
7-
import { domUtils, type IPoint, Rectangle } from '@flowgram.ai/utils';
7+
import { domUtils, type IPoint, Rectangle, Emitter } from '@flowgram.ai/utils';
88
import { Entity, type EntityOpts } from '@flowgram.ai/core';
99

1010
import { type WorkflowLinesManager } from '../workflow-lines-manager';
@@ -25,6 +25,7 @@ export interface WorkflowLinePortInfo {
2525
to?: string; // 后置节点 id
2626
fromPort?: string | number; // 连线的 port 位置
2727
toPort?: string | number; // 连线的 port 位置
28+
data?: any;
2829
}
2930

3031
export interface WorkflowLineEntityOpts extends EntityOpts, WorkflowLinePortInfo {
@@ -35,7 +36,6 @@ export interface WorkflowLineEntityOpts extends EntityOpts, WorkflowLinePortInfo
3536

3637
export interface WorkflowLineInfo extends WorkflowLinePortInfo {
3738
drawingTo?: IPoint; // 正在画中的元素
38-
isDefaultLine?: boolean; // 是否为默认的线
3939
}
4040

4141
export interface WorkflowLineUIState {
@@ -64,10 +64,14 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
6464
return `${from}_${fromPort || ''}-${to || ''}_${toPort || ''}`;
6565
}
6666

67+
private _onLineDataChangeEmitter = new Emitter<{ oldValue: any; newValue: any }>();
68+
6769
readonly document: WorkflowDocument;
6870

6971
readonly linesManager: WorkflowLinesManager;
7072

73+
readonly onLineDataChange = this._onLineDataChangeEmitter.event;
74+
7175
private _from: WorkflowNodeEntity;
7276

7377
private _to?: WorkflowNodeEntity;
@@ -121,9 +125,13 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
121125
* 更新线条扩展数据
122126
* @param data
123127
*/
124-
set lineData(data: any) {
125-
this._lineData = data;
126-
this.fireChange();
128+
set lineData(newValue: any) {
129+
const oldValue = this._lineData;
130+
if (!isEqual(oldValue, newValue)) {
131+
this._lineData = newValue;
132+
this._onLineDataChangeEmitter.fire({ oldValue, newValue });
133+
this.fireChange();
134+
}
127135
}
128136

129137
public stackIndex = 0;
@@ -153,6 +161,7 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
153161
drawingTo: opts.drawingTo,
154162
fromPort: opts.fromPort,
155163
toPort: opts.toPort,
164+
data: opts.data,
156165
});
157166
if (opts.drawingTo) {
158167
this.isDrawing = true;
@@ -165,6 +174,7 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
165174
this.fromPort?.validate();
166175
this.toPort?.validate();
167176
});
177+
this.toDispose.push(this._onLineDataChangeEmitter);
168178
// this.onDispose(() => {
169179
// this._infoDispose.dispose();
170180
// });
@@ -248,7 +258,6 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
248258
const { node, portID } = toPort;
249259
this._to = node;
250260
this.info.drawingTo = undefined;
251-
this.info.isDefaultLine = false;
252261
this.info.to = node.id;
253262
this.info.toPort = portID;
254263
} else {
@@ -277,7 +286,6 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
277286
}
278287
if (!oldDrawingTo || pos.x !== oldDrawingTo.x || pos.y !== oldDrawingTo.y) {
279288
this.info.to = undefined;
280-
this.info.isDefaultLine = false;
281289
this.info.drawingTo = pos;
282290
this.fireChange();
283291
}
@@ -392,6 +400,7 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
392400
this.info = info;
393401
this._from = this.document.getNode(info.from)!;
394402
this._to = info.to ? this.document.getNode(info.to) : undefined;
403+
this._lineData = info.data;
395404
this.fireChange();
396405
}
397406
}

packages/canvas-engine/free-layout-core/src/service/workflow-drag-service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ export class WorkflowDragService {
610610
from: fromPort.node.id,
611611
fromPort: fromPort.portID,
612612
drawingTo: config.getPosFromMouseEvent(event),
613+
data: originLine?.lineData,
613614
});
614615
if (!line) {
615616
return;
@@ -708,6 +709,7 @@ export class WorkflowDragService {
708709
fromPort: fromPort.portID,
709710
to: toPort.node.id,
710711
toPort: toPort.portID,
712+
data: originLine?.lineData,
711713
}
712714
: undefined;
713715
// Step2: 检测 reset

packages/canvas-engine/free-layout-core/src/typings/workflow-json.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export enum WorkflowContentChangeType {
3737
* 删除线条
3838
*/
3939
DELETE_LINE = 'DELETE_LINE',
40+
/**
41+
* 线条数据修改
42+
*/
43+
LINE_DATA_CHANGE = 'LINE_DATA_CHANGE',
4044
/**
4145
* 节点Meta信息变更
4246
*/
@@ -49,6 +53,10 @@ export interface WorkflowContentChangeEvent {
4953
* 当前触发的元素的json数据,toJSON 需要主动触发
5054
*/
5155
toJSON: () => any;
56+
/**
57+
* oldValue
58+
*/
59+
oldValue?: any;
5260
/*
5361
* 当前的事件的 entity
5462
*/

packages/canvas-engine/free-layout-core/src/workflow-document.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,7 @@ export class WorkflowDocument extends FlowDocument {
775775
fromPort: json.sourcePortID,
776776
to: json.targetNodeID,
777777
toPort: json.targetPortID,
778+
data: json.data,
778779
};
779780
if (!parentId) {
780781
return this.linesManager.createLine(lineInfo);

packages/canvas-engine/free-layout-core/src/workflow-lines-manager.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ export class WorkflowLinesManager {
138138
);
139139
}
140140

141+
getLineById(id: string): WorkflowLineEntity | undefined {
142+
return this.entityManager.getEntityById<WorkflowLineEntity>(id);
143+
}
144+
141145
replaceLine(
142146
oldPortInfo: WorkflowLinePortInfo,
143147
newPortInfo: WorkflowLinePortInfo
@@ -155,7 +159,7 @@ export class WorkflowLinesManager {
155159
key?: string; // 自定义 key
156160
} & WorkflowLinePortInfo
157161
): WorkflowLineEntity | undefined {
158-
const { from, to, drawingTo, fromPort, toPort } = options;
162+
const { from, to, drawingTo, fromPort, toPort, data } = options;
159163
const available = Boolean(from && to);
160164
const key = options.key || WorkflowLineEntity.portInfoToLineId(options);
161165
let line = this.entityManager.getEntityById<WorkflowLineEntity>(key)!;
@@ -190,6 +194,7 @@ export class WorkflowLinesManager {
190194
toPort,
191195
to,
192196
drawingTo,
197+
data,
193198
});
194199

195200
this.registerData(line);
@@ -212,6 +217,14 @@ export class WorkflowLinesManager {
212217
});
213218
}
214219
});
220+
line.onLineDataChange(({ oldValue }) => {
221+
this.onAvailableLinesChangeEmitter.fire({
222+
type: WorkflowContentChangeType.LINE_DATA_CHANGE,
223+
toJSON: () => line.toJSON(),
224+
oldValue,
225+
entity: line,
226+
});
227+
});
215228
// 是否为有效的线条
216229
if (available) {
217230
this.onAvailableLinesChangeEmitter.fire({

0 commit comments

Comments
 (0)