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