@flowgram.ai/free-node-panel-plugin 0.1.0-alpha.2 → 0.1.0-alpha.21

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/esm/index.js CHANGED
@@ -10,27 +10,135 @@ var __decorateClass = (decorators, target, key, kind) => {
10
10
  };
11
11
 
12
12
  // src/create-plugin.ts
13
- import {
14
- definePluginCreator
15
- } from "@flowgram.ai/core";
13
+ import { definePluginCreator } from "@flowgram.ai/core";
16
14
 
17
15
  // src/service.ts
18
16
  import { inject, injectable } from "inversify";
19
- import { delay, DisposableCollection, Rectangle } from "@flowgram.ai/utils";
17
+ import { DisposableCollection } from "@flowgram.ai/utils";
20
18
  import {
21
19
  WorkflowDocument,
22
20
  WorkflowDragService,
23
- WorkflowLinesManager,
24
- WorkflowNodePortsData
21
+ WorkflowLinesManager as WorkflowLinesManager2
25
22
  } from "@flowgram.ai/free-layout-core";
26
23
  import { WorkflowSelectService } from "@flowgram.ai/free-layout-core";
27
- import { FreeOperationType, HistoryService } from "@flowgram.ai/free-history-plugin";
28
- import { FlowNodeTransformData } from "@flowgram.ai/document";
29
- import { FlowNodeBaseType } from "@flowgram.ai/document";
24
+ import { HistoryService as HistoryService2 } from "@flowgram.ai/free-history-plugin";
30
25
  import { PlaygroundConfigEntity } from "@flowgram.ai/core";
26
+
27
+ // src/utils/wait-node-render.ts
28
+ import { delay } from "@flowgram.ai/free-layout-core";
29
+ var waitNodeRender = async () => {
30
+ await delay(20);
31
+ };
32
+
33
+ // src/utils/update-sub-nodes-position.ts
34
+ import { FreeOperationType } from "@flowgram.ai/free-history-plugin";
31
35
  import { TransformData } from "@flowgram.ai/core";
32
36
 
33
- // src/utils.ts
37
+ // src/utils/get-port-box.ts
38
+ import { Rectangle } from "@flowgram.ai/utils";
39
+ import { FlowNodeTransformData } from "@flowgram.ai/document";
40
+
41
+ // src/utils/is-container.ts
42
+ var isContainer = (node) => node?.getNodeMeta().isContainer ?? false;
43
+
44
+ // src/utils/get-port-box.ts
45
+ var getPortBox = (port, offset = { x: 0, y: 0 }) => {
46
+ const node = port.node;
47
+ if (isContainer(node)) {
48
+ const { point } = port;
49
+ if (port.portType === "input") {
50
+ return new Rectangle(point.x + offset.x, point.y - 50 + offset.y, 300, 100);
51
+ }
52
+ return new Rectangle(point.x - 300, point.y - 50, 300, 100);
53
+ }
54
+ const box = node.getData(FlowNodeTransformData).bounds;
55
+ return box;
56
+ };
57
+
58
+ // src/utils/update-sub-nodes-position.ts
59
+ var updateSubSequentNodesPosition = (params) => {
60
+ const {
61
+ node,
62
+ subsequentNodes,
63
+ fromPort,
64
+ toPort,
65
+ containerNode,
66
+ offset,
67
+ historyService,
68
+ dragService
69
+ } = params;
70
+ if (!offset || !toPort) {
71
+ return;
72
+ }
73
+ const subsequentNodesPositions = subsequentNodes.map((node2) => {
74
+ const nodeTrans2 = node2.getData(TransformData);
75
+ return {
76
+ x: nodeTrans2.position.x,
77
+ y: nodeTrans2.position.y
78
+ };
79
+ });
80
+ historyService.pushOperation({
81
+ type: FreeOperationType.dragNodes,
82
+ value: {
83
+ ids: subsequentNodes.map((node2) => node2.id),
84
+ value: subsequentNodesPositions.map((position) => ({
85
+ x: position.x + offset.x,
86
+ y: position.y + offset.y
87
+ })),
88
+ oldValue: subsequentNodesPositions
89
+ }
90
+ });
91
+ const fromBox = getPortBox(fromPort);
92
+ const toBox = getPortBox(toPort, offset);
93
+ const nodeTrans = node.getData(TransformData);
94
+ let nodePos = {
95
+ x: (fromBox.center.x + toBox.center.x) / 2,
96
+ y: (fromBox.y + toBox.y) / 2
97
+ };
98
+ if (containerNode) {
99
+ nodePos = dragService.adjustSubNodePosition(
100
+ node.flowNodeType,
101
+ containerNode,
102
+ nodePos
103
+ );
104
+ }
105
+ historyService.pushOperation({
106
+ type: FreeOperationType.dragNodes,
107
+ value: {
108
+ ids: [node.id],
109
+ value: [nodePos],
110
+ oldValue: [
111
+ {
112
+ x: nodeTrans.position.x,
113
+ y: nodeTrans.position.y
114
+ }
115
+ ]
116
+ }
117
+ });
118
+ };
119
+
120
+ // src/utils/sub-position-offset.ts
121
+ import { Rectangle as Rectangle3 } from "@flowgram.ai/utils";
122
+ import { FlowNodeTransformData as FlowNodeTransformData2 } from "@flowgram.ai/document";
123
+
124
+ // src/utils/rect-distance.ts
125
+ import { Rectangle as Rectangle2 } from "@flowgram.ai/utils";
126
+ var rectDistance = (rectA, rectB) => {
127
+ const distanceX = Math.abs(Math.min(rectA.right, rectB.right) - Math.max(rectA.left, rectB.left));
128
+ const distanceY = Math.abs(Math.min(rectA.bottom, rectB.bottom) - Math.max(rectA.top, rectB.top));
129
+ if (Rectangle2.intersects(rectA, rectB)) {
130
+ return {
131
+ x: -distanceX,
132
+ y: -distanceY
133
+ };
134
+ }
135
+ return {
136
+ x: distanceX,
137
+ y: distanceY
138
+ };
139
+ };
140
+
141
+ // src/utils/greater-or-less.ts
34
142
  var isGreaterThan = (a, b) => {
35
143
  if (a === void 0 || b === void 0) {
36
144
  return false;
@@ -46,6 +154,220 @@ var isLessThan = (a, b) => {
46
154
  return b - a > EPSILON;
47
155
  };
48
156
 
157
+ // src/utils/sub-position-offset.ts
158
+ var subPositionOffset = (params) => {
159
+ const { node, fromPort, toPort, padding } = params;
160
+ const fromBox = getPortBox(fromPort);
161
+ const toBox = getPortBox(toPort);
162
+ const nodeTrans = node.getData(FlowNodeTransformData2);
163
+ const nodeSize = node.getNodeMeta()?.size ?? {
164
+ width: nodeTrans.bounds.width,
165
+ height: nodeTrans.bounds.height
166
+ };
167
+ const minDistance = {
168
+ x: nodeSize.width + padding.x,
169
+ y: nodeSize.height + padding.y
170
+ };
171
+ const boxDistance = rectDistance(fromBox, toBox);
172
+ const neededOffset = {
173
+ x: isGreaterThan(boxDistance.x, minDistance.x) ? 0 : minDistance.x - boxDistance.x,
174
+ y: isGreaterThan(boxDistance.y, minDistance.y) ? 0 : minDistance.y - boxDistance.y
175
+ };
176
+ if (neededOffset.x === 0 || neededOffset.y === 0) {
177
+ return;
178
+ }
179
+ const intersection = {
180
+ // 这里没有写反,Rectangle内置的算法是反的
181
+ vertical: Rectangle3.intersects(fromBox, toBox, "horizontal"),
182
+ horizontal: Rectangle3.intersects(fromBox, toBox, "vertical")
183
+ };
184
+ let offsetX = 0;
185
+ let offsetY = 0;
186
+ if (!intersection.horizontal) {
187
+ if (isGreaterThan(toBox.center.y, fromBox.center.y)) {
188
+ offsetY = neededOffset.y;
189
+ } else if (isLessThan(toBox.center.y, fromBox.center.y)) {
190
+ offsetY = -neededOffset.y;
191
+ }
192
+ }
193
+ if (!intersection.vertical) {
194
+ if (isGreaterThan(toBox.center.x, fromBox.center.x)) {
195
+ offsetX = neededOffset.x;
196
+ } else if (isLessThan(toBox.center.x, fromBox.center.x)) {
197
+ offsetX = -neededOffset.x;
198
+ }
199
+ }
200
+ return {
201
+ x: offsetX,
202
+ y: offsetY
203
+ };
204
+ };
205
+
206
+ // src/utils/get-sub-nodes.ts
207
+ var getSubsequentNodes = (params) => {
208
+ const { node, linesManager } = params;
209
+ if (isContainer(node)) {
210
+ return [];
211
+ }
212
+ const brothers = node.parent?.blocks ?? [];
213
+ const linkedBrothers = /* @__PURE__ */ new Set();
214
+ const linesMap = /* @__PURE__ */ new Map();
215
+ linesManager.getAllAvailableLines().forEach((line) => {
216
+ if (!linesMap.has(line.from.id)) {
217
+ linesMap.set(line.from.id, []);
218
+ }
219
+ if (!line.to?.id || isContainer(line.to)) {
220
+ return;
221
+ }
222
+ linesMap.get(line.from.id)?.push(line.to.id);
223
+ });
224
+ const bfs = (nodeId) => {
225
+ if (linkedBrothers.has(nodeId)) {
226
+ return;
227
+ }
228
+ linkedBrothers.add(nodeId);
229
+ const nextNodes = linesMap.get(nodeId) ?? [];
230
+ nextNodes.forEach(bfs);
231
+ };
232
+ bfs(node.id);
233
+ const subsequentNodes = brothers.filter((node2) => linkedBrothers.has(node2.id));
234
+ return subsequentNodes;
235
+ };
236
+
237
+ // src/utils/sub-nodes-auto-offset.ts
238
+ var subNodesAutoOffset = (params) => {
239
+ const {
240
+ node,
241
+ fromPort,
242
+ toPort,
243
+ linesManager,
244
+ historyService,
245
+ dragService,
246
+ containerNode,
247
+ padding = {
248
+ x: 100,
249
+ y: 100
250
+ }
251
+ } = params;
252
+ const subOffset = subPositionOffset({
253
+ node,
254
+ fromPort,
255
+ toPort,
256
+ padding
257
+ });
258
+ const subsequentNodes = getSubsequentNodes({
259
+ node: toPort.node,
260
+ linesManager
261
+ });
262
+ updateSubSequentNodesPosition({
263
+ node,
264
+ subsequentNodes,
265
+ fromPort,
266
+ toPort,
267
+ containerNode,
268
+ offset: subOffset,
269
+ historyService,
270
+ dragService
271
+ });
272
+ };
273
+
274
+ // src/utils/get-container-node.ts
275
+ var getContainerNode = (params) => {
276
+ const { fromPort, containerNode } = params;
277
+ if (containerNode) {
278
+ return containerNode;
279
+ }
280
+ const fromNode = fromPort?.node;
281
+ const fromContainer = fromNode?.parent;
282
+ if (isContainer(fromNode)) {
283
+ return fromNode;
284
+ }
285
+ return fromContainer;
286
+ };
287
+
288
+ // src/utils/build-line.ts
289
+ import {
290
+ WorkflowNodePortsData
291
+ } from "@flowgram.ai/free-layout-core";
292
+ var buildLine = (params) => {
293
+ const { fromPort, node, toPort, linesManager } = params;
294
+ const portsData = node.getData(WorkflowNodePortsData);
295
+ if (!portsData) {
296
+ return;
297
+ }
298
+ const shouldBuildFromLine = portsData.inputPorts?.length > 0;
299
+ if (fromPort && shouldBuildFromLine) {
300
+ const isVertical = fromPort.location === "bottom";
301
+ const toTargetPort = portsData.inputPorts.find((port) => isVertical ? port.location === "top" : true) || portsData.inputPorts[0];
302
+ linesManager.createLine({
303
+ from: fromPort.node.id,
304
+ fromPort: fromPort.portID,
305
+ to: node.id,
306
+ toPort: toTargetPort.portID
307
+ });
308
+ }
309
+ const shouldBuildToLine = portsData.outputPorts?.length > 0;
310
+ if (toPort && shouldBuildToLine) {
311
+ const fromTargetPort = portsData.outputPorts[0];
312
+ linesManager.createLine({
313
+ from: node.id,
314
+ fromPort: fromTargetPort.portID,
315
+ to: toPort.node.id,
316
+ toPort: toPort.portID
317
+ });
318
+ }
319
+ };
320
+
321
+ // src/utils/adjust-node-position.ts
322
+ var adjustNodePosition = (params) => {
323
+ const { nodeType, position, fromPort, toPort, containerNode, document, dragService } = params;
324
+ const register = document.getNodeRegistry(nodeType);
325
+ const size = register?.meta?.size;
326
+ let adjustedPosition = position;
327
+ if (!size) {
328
+ adjustedPosition = position;
329
+ } else if (fromPort && toPort) {
330
+ adjustedPosition = {
331
+ x: position.x,
332
+ y: position.y - size.height / 2
333
+ };
334
+ } else if (fromPort && !toPort) {
335
+ if (fromPort.location === "bottom") {
336
+ adjustedPosition = {
337
+ x: position.x,
338
+ y: position.y
339
+ };
340
+ } else {
341
+ adjustedPosition = {
342
+ x: position.x + size.width / 2,
343
+ y: position.y - size.height / 2
344
+ };
345
+ }
346
+ } else if (!fromPort && toPort) {
347
+ adjustedPosition = {
348
+ x: position.x - size.width / 2,
349
+ y: position.y - size.height / 2
350
+ };
351
+ } else {
352
+ adjustedPosition = position;
353
+ }
354
+ return dragService.adjustSubNodePosition(nodeType, containerNode, adjustedPosition);
355
+ };
356
+
357
+ // src/utils/index.ts
358
+ var WorkflowNodePanelUtils = {
359
+ adjustNodePosition,
360
+ buildLine,
361
+ getPortBox,
362
+ getSubsequentNodes,
363
+ getContainerNode,
364
+ rectDistance,
365
+ subNodesAutoOffset,
366
+ subPositionOffset,
367
+ updateSubSequentNodesPosition,
368
+ waitNodeRender
369
+ };
370
+
49
371
  // src/service.ts
50
372
  var WorkflowNodePanelService = class {
51
373
  constructor() {
@@ -78,7 +400,7 @@ var WorkflowNodePanelService = class {
78
400
  position: panelPosition,
79
401
  enableMultiAdd,
80
402
  panelProps,
81
- containerNode: this.getContainerNode({
403
+ containerNode: WorkflowNodePanelUtils.getContainerNode({
82
404
  fromPort,
83
405
  containerNode
84
406
  }),
@@ -97,6 +419,23 @@ var WorkflowNodePanelService = class {
97
419
  });
98
420
  });
99
421
  }
422
+ /**
423
+ * 唤起单选面板
424
+ */
425
+ async singleSelectNodePanel(params) {
426
+ return new Promise((resolve) => {
427
+ this.callNodePanel({
428
+ ...params,
429
+ enableMultiAdd: false,
430
+ onSelect: async (panelParams) => {
431
+ resolve(panelParams);
432
+ },
433
+ onClose: () => {
434
+ resolve(void 0);
435
+ }
436
+ });
437
+ });
438
+ }
100
439
  /** 添加节点 */
101
440
  async addNode(callParams, panelParams) {
102
441
  const {
@@ -117,7 +456,7 @@ var WorkflowNodePanelService = class {
117
456
  return;
118
457
  }
119
458
  const { nodeType, selectEvent, nodeJSON } = panelParams;
120
- const containerNode = this.getContainerNode({
459
+ const containerNode = WorkflowNodePanelUtils.getContainerNode({
121
460
  fromPort,
122
461
  containerNode: callParams.containerNode
123
462
  });
@@ -128,14 +467,16 @@ var WorkflowNodePanelService = class {
128
467
  }
129
468
  }
130
469
  const selectPosition = this.playgroundConfig.getPosFromMouseEvent(selectEvent);
131
- const nodePosition = callParams.customPosition ? callParams.customPosition({ nodeType, selectPosition }) : this.adjustNodePosition({
470
+ const nodePosition = callParams.customPosition ? callParams.customPosition({ nodeType, selectPosition }) : WorkflowNodePanelUtils.adjustNodePosition({
132
471
  nodeType,
133
472
  position: enableSelectPosition ? selectPosition : panelPosition,
134
473
  fromPort,
135
474
  toPort,
136
- containerNode
475
+ containerNode,
476
+ document: this.document,
477
+ dragService: this.dragService
137
478
  });
138
- const node = await this.document.createWorkflowNodeByType(
479
+ const node = this.document.createWorkflowNodeByType(
139
480
  nodeType,
140
481
  nodePosition,
141
482
  nodeJSON ?? {},
@@ -145,31 +486,27 @@ var WorkflowNodePanelService = class {
145
486
  return;
146
487
  }
147
488
  if (enableAutoOffset && fromPort && toPort) {
148
- const subOffset = this.subPositionOffset({
489
+ WorkflowNodePanelUtils.subNodesAutoOffset({
149
490
  node,
150
491
  fromPort,
151
492
  toPort,
152
- padding: autoOffsetPadding
153
- });
154
- const subsequentNodes = this.getSubsequentNodes(toPort.node);
155
- this.updateSubSequentNodesPosition({
156
- node,
157
- subsequentNodes,
158
- fromPort,
159
- toPort,
493
+ padding: autoOffsetPadding,
160
494
  containerNode,
161
- offset: subOffset
495
+ historyService: this.historyService,
496
+ dragService: this.dragService,
497
+ linesManager: this.linesManager
162
498
  });
163
499
  }
164
500
  if (!enableBuildLine && !enableDragNode) {
165
501
  return node;
166
502
  }
167
- await delay(20);
503
+ await WorkflowNodePanelUtils.waitNodeRender();
168
504
  if (enableBuildLine) {
169
- this.buildLine({
505
+ WorkflowNodePanelUtils.buildLine({
170
506
  fromPort,
171
507
  node,
172
- toPort
508
+ toPort,
509
+ linesManager: this.linesManager
173
510
  });
174
511
  }
175
512
  if (enableDragNode) {
@@ -178,236 +515,6 @@ var WorkflowNodePanelService = class {
178
515
  }
179
516
  return node;
180
517
  }
181
- /** 建立连线 */
182
- buildLine(params) {
183
- const { fromPort, node, toPort } = params;
184
- const portsData = node.getData(WorkflowNodePortsData);
185
- if (!portsData) {
186
- return;
187
- }
188
- const shouldBuildFromLine = portsData.inputPorts?.length > 0;
189
- if (fromPort && shouldBuildFromLine) {
190
- const toTargetPort = portsData.inputPorts[0];
191
- const isSingleInput = portsData.inputPorts.length === 1;
192
- this.linesManager.createLine({
193
- from: fromPort.node.id,
194
- fromPort: fromPort.portID,
195
- to: node.id,
196
- toPort: isSingleInput ? void 0 : toTargetPort.id
197
- });
198
- }
199
- const shouldBuildToLine = portsData.outputPorts?.length > 0;
200
- if (toPort && shouldBuildToLine) {
201
- const fromTargetPort = portsData.outputPorts[0];
202
- this.linesManager.createLine({
203
- from: node.id,
204
- fromPort: fromTargetPort.portID,
205
- to: toPort.node.id,
206
- toPort: toPort.portID
207
- });
208
- }
209
- }
210
- /** 调整节点坐标 */
211
- adjustNodePosition(params) {
212
- const { nodeType, position, fromPort, toPort, containerNode } = params;
213
- const register = this.document.getNodeRegistry(nodeType);
214
- const size = register?.meta?.size;
215
- let adjustedPosition = position;
216
- if (!size) {
217
- adjustedPosition = position;
218
- } else if (fromPort && toPort) {
219
- adjustedPosition = {
220
- x: position.x,
221
- y: position.y - size.height / 2
222
- };
223
- } else if (fromPort && !toPort) {
224
- adjustedPosition = {
225
- x: position.x + size.width / 2,
226
- y: position.y - size.height / 2
227
- };
228
- } else if (!fromPort && toPort) {
229
- adjustedPosition = {
230
- x: position.x - size.width / 2,
231
- y: position.y - size.height / 2
232
- };
233
- } else {
234
- adjustedPosition = position;
235
- }
236
- return this.dragService.adjustSubNodePosition(nodeType, containerNode, adjustedPosition);
237
- }
238
- getContainerNode(params) {
239
- const { fromPort, containerNode } = params;
240
- if (containerNode) {
241
- return containerNode;
242
- }
243
- const fromNode = fromPort?.node;
244
- const fromContainer = fromNode?.parent;
245
- if (fromNode?.flowNodeType === FlowNodeBaseType.SUB_CANVAS) {
246
- return fromNode;
247
- }
248
- return fromContainer;
249
- }
250
- /** 获取端口矩形 */
251
- getPortBox(port, offset = { x: 0, y: 0 }) {
252
- const node = port.node;
253
- if (node.flowNodeType === FlowNodeBaseType.SUB_CANVAS) {
254
- const { point } = port;
255
- if (port.portType === "input") {
256
- return new Rectangle(point.x + offset.x, point.y - 50 + offset.y, 300, 100);
257
- }
258
- return new Rectangle(point.x - 300, point.y - 50, 300, 100);
259
- }
260
- const box = node.getData(FlowNodeTransformData).bounds;
261
- return box;
262
- }
263
- /** 后续节点位置偏移 */
264
- subPositionOffset(params) {
265
- const { node, fromPort, toPort, padding } = params;
266
- const fromBox = this.getPortBox(fromPort);
267
- const toBox = this.getPortBox(toPort);
268
- const nodeTrans = node.getData(FlowNodeTransformData);
269
- const nodeSize = node.getNodeMeta()?.size ?? {
270
- width: nodeTrans.bounds.width,
271
- height: nodeTrans.bounds.height
272
- };
273
- const minDistance = {
274
- x: nodeSize.width + padding.x,
275
- y: nodeSize.height + padding.y
276
- };
277
- const boxDistance = this.rectDistance(fromBox, toBox);
278
- const neededOffset = {
279
- x: isGreaterThan(boxDistance.x, minDistance.x) ? 0 : minDistance.x - boxDistance.x,
280
- y: isGreaterThan(boxDistance.y, minDistance.y) ? 0 : minDistance.y - boxDistance.y
281
- };
282
- if (neededOffset.x === 0 || neededOffset.y === 0) {
283
- return;
284
- }
285
- const intersection = {
286
- // 这里没有写反,Rectangle内置的算法是反的
287
- vertical: Rectangle.intersects(fromBox, toBox, "horizontal"),
288
- horizontal: Rectangle.intersects(fromBox, toBox, "vertical")
289
- };
290
- let offsetX = 0;
291
- let offsetY = 0;
292
- if (!intersection.horizontal) {
293
- if (isGreaterThan(toBox.center.y, fromBox.center.y)) {
294
- offsetY = neededOffset.y;
295
- } else if (isLessThan(toBox.center.y, fromBox.center.y)) {
296
- offsetY = -neededOffset.y;
297
- }
298
- }
299
- if (!intersection.vertical) {
300
- if (isGreaterThan(toBox.center.x, fromBox.center.x)) {
301
- offsetX = neededOffset.x;
302
- } else if (isLessThan(toBox.center.x, fromBox.center.x)) {
303
- offsetX = -neededOffset.x;
304
- }
305
- }
306
- return {
307
- x: offsetX,
308
- y: offsetY
309
- };
310
- }
311
- /** 矩形间距 */
312
- rectDistance(rectA, rectB) {
313
- const distanceX = Math.abs(
314
- Math.min(rectA.right, rectB.right) - Math.max(rectA.left, rectB.left)
315
- );
316
- const distanceY = Math.abs(
317
- Math.min(rectA.bottom, rectB.bottom) - Math.max(rectA.top, rectB.top)
318
- );
319
- if (Rectangle.intersects(rectA, rectB)) {
320
- return {
321
- x: -distanceX,
322
- y: -distanceY
323
- };
324
- }
325
- return {
326
- x: distanceX,
327
- y: distanceY
328
- };
329
- }
330
- /** 获取后续节点 */
331
- getSubsequentNodes(node) {
332
- if (node.flowNodeType === FlowNodeBaseType.SUB_CANVAS) {
333
- return [];
334
- }
335
- const brothers = node.parent?.collapsedChildren ?? [];
336
- const linkedBrothers = /* @__PURE__ */ new Set();
337
- const linesMap = /* @__PURE__ */ new Map();
338
- this.linesManager.getAllLines().forEach((line) => {
339
- if (!linesMap.has(line.from.id)) {
340
- linesMap.set(line.from.id, []);
341
- }
342
- if (!line.to?.id || line.to.flowNodeType === FlowNodeBaseType.SUB_CANVAS) {
343
- return;
344
- }
345
- linesMap.get(line.from.id)?.push(line.to.id);
346
- });
347
- const bfs = (nodeId) => {
348
- if (linkedBrothers.has(nodeId)) {
349
- return;
350
- }
351
- linkedBrothers.add(nodeId);
352
- const nextNodes = linesMap.get(nodeId) ?? [];
353
- nextNodes.forEach(bfs);
354
- };
355
- bfs(node.id);
356
- const subsequentNodes = brothers.filter((node2) => linkedBrothers.has(node2.id));
357
- return subsequentNodes;
358
- }
359
- /** 更新后续节点位置 */
360
- updateSubSequentNodesPosition(params) {
361
- const { node, subsequentNodes, fromPort, toPort, containerNode, offset } = params;
362
- if (!offset || !toPort) {
363
- return;
364
- }
365
- const subsequentNodesPositions = subsequentNodes.map((node2) => {
366
- const nodeTrans2 = node2.getData(TransformData);
367
- return {
368
- x: nodeTrans2.position.x,
369
- y: nodeTrans2.position.y
370
- };
371
- });
372
- this.historyService.pushOperation({
373
- type: FreeOperationType.dragNodes,
374
- value: {
375
- ids: subsequentNodes.map((node2) => node2.id),
376
- value: subsequentNodesPositions.map((position) => ({
377
- x: position.x + offset.x,
378
- y: position.y + offset.y
379
- })),
380
- oldValue: subsequentNodesPositions
381
- }
382
- });
383
- const fromBox = this.getPortBox(fromPort);
384
- const toBox = this.getPortBox(toPort, offset);
385
- const nodeTrans = node.getData(TransformData);
386
- let nodePos = {
387
- x: (fromBox.center.x + toBox.center.x) / 2,
388
- y: (fromBox.y + toBox.y) / 2
389
- };
390
- if (containerNode) {
391
- nodePos = this.dragService.adjustSubNodePosition(
392
- node.flowNodeType,
393
- containerNode,
394
- nodePos
395
- );
396
- }
397
- this.historyService.pushOperation({
398
- type: FreeOperationType.dragNodes,
399
- value: {
400
- ids: [node.id],
401
- value: [nodePos],
402
- oldValue: [
403
- {
404
- x: nodeTrans.position.x,
405
- y: nodeTrans.position.y
406
- }
407
- ]
408
- }
409
- });
410
- }
411
518
  };
412
519
  __decorateClass([
413
520
  inject(WorkflowDocument)
@@ -419,13 +526,13 @@ __decorateClass([
419
526
  inject(WorkflowSelectService)
420
527
  ], WorkflowNodePanelService.prototype, "selectService", 2);
421
528
  __decorateClass([
422
- inject(WorkflowLinesManager)
529
+ inject(WorkflowLinesManager2)
423
530
  ], WorkflowNodePanelService.prototype, "linesManager", 2);
424
531
  __decorateClass([
425
532
  inject(PlaygroundConfigEntity)
426
533
  ], WorkflowNodePanelService.prototype, "playgroundConfig", 2);
427
534
  __decorateClass([
428
- inject(HistoryService)
535
+ inject(HistoryService2)
429
536
  ], WorkflowNodePanelService.prototype, "historyService", 2);
430
537
  WorkflowNodePanelService = __decorateClass([
431
538
  injectable()
@@ -434,9 +541,9 @@ WorkflowNodePanelService = __decorateClass([
434
541
  // src/layer.tsx
435
542
  import React from "react";
436
543
  import { inject as inject2 } from "inversify";
437
- import { Layer } from "@flowgram.ai/core";
438
- import { nanoid } from "@flowgram.ai/free-layout-core";
439
544
  import { domUtils } from "@flowgram.ai/utils";
545
+ import { nanoid } from "@flowgram.ai/free-layout-core";
546
+ import { Layer } from "@flowgram.ai/core";
440
547
  var WorkflowNodePanelLayer = class extends Layer {
441
548
  constructor() {
442
549
  super();
@@ -459,7 +566,7 @@ var WorkflowNodePanelLayer = class extends Layer {
459
566
  }
460
567
  async call(params) {
461
568
  const taskId = nanoid();
462
- const { enableMultiAdd, onSelect, onClose } = params;
569
+ const { onSelect, onClose, enableMultiAdd = false, panelProps = {} } = params;
463
570
  return new Promise((resolve) => {
464
571
  const unmount = () => {
465
572
  this.renderList.delete(taskId);
@@ -478,6 +585,7 @@ var WorkflowNodePanelLayer = class extends Layer {
478
585
  };
479
586
  const renderProps = {
480
587
  ...params,
588
+ panelProps,
481
589
  onSelect: handleSelect,
482
590
  onClose: handleClose
483
591
  };
@@ -508,6 +616,7 @@ var createFreeNodePanelPlugin = definePluginCreator({
508
616
  });
509
617
  export {
510
618
  WorkflowNodePanelService,
619
+ WorkflowNodePanelUtils,
511
620
  createFreeNodePanelPlugin
512
621
  };
513
622
  //# sourceMappingURL=index.js.map