@flowgram.ai/free-node-panel-plugin 0.1.0-alpha.2 → 0.1.0-alpha.20
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 +372 -263
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +156 -21
- package/dist/index.d.ts +156 -21
- package/dist/index.js +379 -268
- package/dist/index.js.map +1 -1
- package/package.json +14 -19
package/dist/index.js
CHANGED
|
@@ -36,28 +36,140 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
// src/index.ts
|
|
39
|
-
var
|
|
40
|
-
__export(
|
|
39
|
+
var index_exports = {};
|
|
40
|
+
__export(index_exports, {
|
|
41
41
|
WorkflowNodePanelService: () => WorkflowNodePanelService,
|
|
42
|
+
WorkflowNodePanelUtils: () => WorkflowNodePanelUtils,
|
|
42
43
|
createFreeNodePanelPlugin: () => createFreeNodePanelPlugin
|
|
43
44
|
});
|
|
44
|
-
module.exports = __toCommonJS(
|
|
45
|
+
module.exports = __toCommonJS(index_exports);
|
|
45
46
|
|
|
46
47
|
// src/create-plugin.ts
|
|
47
48
|
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,222 @@ 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.getAllAvailableLines().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 isVertical = fromPort.location === "bottom";
|
|
330
|
+
const toTargetPort = portsData.inputPorts.find((port) => isVertical ? port.location === "top" : true) || portsData.inputPorts[0];
|
|
331
|
+
linesManager.createLine({
|
|
332
|
+
from: fromPort.node.id,
|
|
333
|
+
fromPort: fromPort.portID,
|
|
334
|
+
to: node.id,
|
|
335
|
+
toPort: toTargetPort.portID
|
|
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
|
+
if (fromPort.location === "bottom") {
|
|
365
|
+
adjustedPosition = {
|
|
366
|
+
x: position.x,
|
|
367
|
+
y: position.y
|
|
368
|
+
};
|
|
369
|
+
} else {
|
|
370
|
+
adjustedPosition = {
|
|
371
|
+
x: position.x + size.width / 2,
|
|
372
|
+
y: position.y - size.height / 2
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
} else if (!fromPort && toPort) {
|
|
376
|
+
adjustedPosition = {
|
|
377
|
+
x: position.x - size.width / 2,
|
|
378
|
+
y: position.y - size.height / 2
|
|
379
|
+
};
|
|
380
|
+
} else {
|
|
381
|
+
adjustedPosition = position;
|
|
382
|
+
}
|
|
383
|
+
return dragService.adjustSubNodePosition(nodeType, containerNode, adjustedPosition);
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
// src/utils/index.ts
|
|
387
|
+
var WorkflowNodePanelUtils = {
|
|
388
|
+
adjustNodePosition,
|
|
389
|
+
buildLine,
|
|
390
|
+
getPortBox,
|
|
391
|
+
getSubsequentNodes,
|
|
392
|
+
getContainerNode,
|
|
393
|
+
rectDistance,
|
|
394
|
+
subNodesAutoOffset,
|
|
395
|
+
subPositionOffset,
|
|
396
|
+
updateSubSequentNodesPosition,
|
|
397
|
+
waitNodeRender
|
|
398
|
+
};
|
|
399
|
+
|
|
76
400
|
// src/service.ts
|
|
77
401
|
var WorkflowNodePanelService = class {
|
|
78
402
|
constructor() {
|
|
79
|
-
this.toDispose = new
|
|
403
|
+
this.toDispose = new import_utils4.DisposableCollection();
|
|
80
404
|
this.callNodePanel = async () => void 0;
|
|
81
405
|
}
|
|
82
406
|
/** 销毁 */
|
|
@@ -105,7 +429,7 @@ var WorkflowNodePanelService = class {
|
|
|
105
429
|
position: panelPosition,
|
|
106
430
|
enableMultiAdd,
|
|
107
431
|
panelProps,
|
|
108
|
-
containerNode:
|
|
432
|
+
containerNode: WorkflowNodePanelUtils.getContainerNode({
|
|
109
433
|
fromPort,
|
|
110
434
|
containerNode
|
|
111
435
|
}),
|
|
@@ -124,6 +448,23 @@ var WorkflowNodePanelService = class {
|
|
|
124
448
|
});
|
|
125
449
|
});
|
|
126
450
|
}
|
|
451
|
+
/**
|
|
452
|
+
* 唤起单选面板
|
|
453
|
+
*/
|
|
454
|
+
async singleSelectNodePanel(params) {
|
|
455
|
+
return new Promise((resolve) => {
|
|
456
|
+
this.callNodePanel({
|
|
457
|
+
...params,
|
|
458
|
+
enableMultiAdd: false,
|
|
459
|
+
onSelect: async (panelParams) => {
|
|
460
|
+
resolve(panelParams);
|
|
461
|
+
},
|
|
462
|
+
onClose: () => {
|
|
463
|
+
resolve(void 0);
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
}
|
|
127
468
|
/** 添加节点 */
|
|
128
469
|
async addNode(callParams, panelParams) {
|
|
129
470
|
const {
|
|
@@ -144,7 +485,7 @@ var WorkflowNodePanelService = class {
|
|
|
144
485
|
return;
|
|
145
486
|
}
|
|
146
487
|
const { nodeType, selectEvent, nodeJSON } = panelParams;
|
|
147
|
-
const containerNode =
|
|
488
|
+
const containerNode = WorkflowNodePanelUtils.getContainerNode({
|
|
148
489
|
fromPort,
|
|
149
490
|
containerNode: callParams.containerNode
|
|
150
491
|
});
|
|
@@ -155,14 +496,16 @@ var WorkflowNodePanelService = class {
|
|
|
155
496
|
}
|
|
156
497
|
}
|
|
157
498
|
const selectPosition = this.playgroundConfig.getPosFromMouseEvent(selectEvent);
|
|
158
|
-
const nodePosition = callParams.customPosition ? callParams.customPosition({ nodeType, selectPosition }) :
|
|
499
|
+
const nodePosition = callParams.customPosition ? callParams.customPosition({ nodeType, selectPosition }) : WorkflowNodePanelUtils.adjustNodePosition({
|
|
159
500
|
nodeType,
|
|
160
501
|
position: enableSelectPosition ? selectPosition : panelPosition,
|
|
161
502
|
fromPort,
|
|
162
503
|
toPort,
|
|
163
|
-
containerNode
|
|
504
|
+
containerNode,
|
|
505
|
+
document: this.document,
|
|
506
|
+
dragService: this.dragService
|
|
164
507
|
});
|
|
165
|
-
const node =
|
|
508
|
+
const node = this.document.createWorkflowNodeByType(
|
|
166
509
|
nodeType,
|
|
167
510
|
nodePosition,
|
|
168
511
|
nodeJSON ?? {},
|
|
@@ -172,31 +515,27 @@ var WorkflowNodePanelService = class {
|
|
|
172
515
|
return;
|
|
173
516
|
}
|
|
174
517
|
if (enableAutoOffset && fromPort && toPort) {
|
|
175
|
-
|
|
176
|
-
node,
|
|
177
|
-
fromPort,
|
|
178
|
-
toPort,
|
|
179
|
-
padding: autoOffsetPadding
|
|
180
|
-
});
|
|
181
|
-
const subsequentNodes = this.getSubsequentNodes(toPort.node);
|
|
182
|
-
this.updateSubSequentNodesPosition({
|
|
518
|
+
WorkflowNodePanelUtils.subNodesAutoOffset({
|
|
183
519
|
node,
|
|
184
|
-
subsequentNodes,
|
|
185
520
|
fromPort,
|
|
186
521
|
toPort,
|
|
522
|
+
padding: autoOffsetPadding,
|
|
187
523
|
containerNode,
|
|
188
|
-
|
|
524
|
+
historyService: this.historyService,
|
|
525
|
+
dragService: this.dragService,
|
|
526
|
+
linesManager: this.linesManager
|
|
189
527
|
});
|
|
190
528
|
}
|
|
191
529
|
if (!enableBuildLine && !enableDragNode) {
|
|
192
530
|
return node;
|
|
193
531
|
}
|
|
194
|
-
await
|
|
532
|
+
await WorkflowNodePanelUtils.waitNodeRender();
|
|
195
533
|
if (enableBuildLine) {
|
|
196
|
-
|
|
534
|
+
WorkflowNodePanelUtils.buildLine({
|
|
197
535
|
fromPort,
|
|
198
536
|
node,
|
|
199
|
-
toPort
|
|
537
|
+
toPort,
|
|
538
|
+
linesManager: this.linesManager
|
|
200
539
|
});
|
|
201
540
|
}
|
|
202
541
|
if (enableDragNode) {
|
|
@@ -205,254 +544,24 @@ var WorkflowNodePanelService = class {
|
|
|
205
544
|
}
|
|
206
545
|
return node;
|
|
207
546
|
}
|
|
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
547
|
};
|
|
439
548
|
__decorateClass([
|
|
440
|
-
(0, import_inversify.inject)(
|
|
549
|
+
(0, import_inversify.inject)(import_free_layout_core3.WorkflowDocument)
|
|
441
550
|
], WorkflowNodePanelService.prototype, "document", 2);
|
|
442
551
|
__decorateClass([
|
|
443
|
-
(0, import_inversify.inject)(
|
|
552
|
+
(0, import_inversify.inject)(import_free_layout_core3.WorkflowDragService)
|
|
444
553
|
], WorkflowNodePanelService.prototype, "dragService", 2);
|
|
445
554
|
__decorateClass([
|
|
446
|
-
(0, import_inversify.inject)(
|
|
555
|
+
(0, import_inversify.inject)(import_free_layout_core4.WorkflowSelectService)
|
|
447
556
|
], WorkflowNodePanelService.prototype, "selectService", 2);
|
|
448
557
|
__decorateClass([
|
|
449
|
-
(0, import_inversify.inject)(
|
|
558
|
+
(0, import_inversify.inject)(import_free_layout_core3.WorkflowLinesManager)
|
|
450
559
|
], WorkflowNodePanelService.prototype, "linesManager", 2);
|
|
451
560
|
__decorateClass([
|
|
452
|
-
(0, import_inversify.inject)(
|
|
561
|
+
(0, import_inversify.inject)(import_core2.PlaygroundConfigEntity)
|
|
453
562
|
], WorkflowNodePanelService.prototype, "playgroundConfig", 2);
|
|
454
563
|
__decorateClass([
|
|
455
|
-
(0, import_inversify.inject)(
|
|
564
|
+
(0, import_inversify.inject)(import_free_history_plugin2.HistoryService)
|
|
456
565
|
], WorkflowNodePanelService.prototype, "historyService", 2);
|
|
457
566
|
WorkflowNodePanelService = __decorateClass([
|
|
458
567
|
(0, import_inversify.injectable)()
|
|
@@ -461,13 +570,13 @@ WorkflowNodePanelService = __decorateClass([
|
|
|
461
570
|
// src/layer.tsx
|
|
462
571
|
var import_react = __toESM(require("react"));
|
|
463
572
|
var import_inversify2 = require("inversify");
|
|
573
|
+
var import_utils6 = require("@flowgram.ai/utils");
|
|
574
|
+
var import_free_layout_core5 = require("@flowgram.ai/free-layout-core");
|
|
464
575
|
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
576
|
var WorkflowNodePanelLayer = class extends import_core3.Layer {
|
|
468
577
|
constructor() {
|
|
469
578
|
super();
|
|
470
|
-
this.node =
|
|
579
|
+
this.node = import_utils6.domUtils.createDivWithClass("gedit-playground-layer gedit-node-panel-layer");
|
|
471
580
|
this.node.style.zIndex = "9999";
|
|
472
581
|
this.renderList = /* @__PURE__ */ new Map();
|
|
473
582
|
}
|
|
@@ -485,8 +594,8 @@ var WorkflowNodePanelLayer = class extends import_core3.Layer {
|
|
|
485
594
|
}));
|
|
486
595
|
}
|
|
487
596
|
async call(params) {
|
|
488
|
-
const taskId = (0,
|
|
489
|
-
const {
|
|
597
|
+
const taskId = (0, import_free_layout_core5.nanoid)();
|
|
598
|
+
const { onSelect, onClose, enableMultiAdd = false, panelProps = {} } = params;
|
|
490
599
|
return new Promise((resolve) => {
|
|
491
600
|
const unmount = () => {
|
|
492
601
|
this.renderList.delete(taskId);
|
|
@@ -505,6 +614,7 @@ var WorkflowNodePanelLayer = class extends import_core3.Layer {
|
|
|
505
614
|
};
|
|
506
615
|
const renderProps = {
|
|
507
616
|
...params,
|
|
617
|
+
panelProps,
|
|
508
618
|
onSelect: handleSelect,
|
|
509
619
|
onClose: handleClose
|
|
510
620
|
};
|
|
@@ -536,6 +646,7 @@ var createFreeNodePanelPlugin = (0, import_core4.definePluginCreator)({
|
|
|
536
646
|
// Annotate the CommonJS export names for ESM import in node:
|
|
537
647
|
0 && (module.exports = {
|
|
538
648
|
WorkflowNodePanelService,
|
|
649
|
+
WorkflowNodePanelUtils,
|
|
539
650
|
createFreeNodePanelPlugin
|
|
540
651
|
});
|
|
541
652
|
//# sourceMappingURL=index.js.map
|