@bian-womp/spark-workbench 0.2.74 → 0.2.75
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/lib/cjs/index.cjs +256 -46
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts +0 -3
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/cjs/src/index.d.ts +1 -0
- package/lib/cjs/src/index.d.ts.map +1 -1
- package/lib/cjs/src/misc/KeyboardShortcutToast.d.ts +16 -0
- package/lib/cjs/src/misc/KeyboardShortcutToast.d.ts.map +1 -0
- package/lib/cjs/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.d.ts +3 -11
- package/lib/cjs/src/misc/context/WorkbenchContext.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/cjs/src/misc/context-menu/ContextMenuHandlers.d.ts +5 -0
- package/lib/cjs/src/misc/context-menu/ContextMenuHandlers.d.ts.map +1 -1
- package/lib/cjs/src/misc/context-menu/ContextMenuHelpers.d.ts +1 -1
- package/lib/cjs/src/misc/context-menu/ContextMenuHelpers.d.ts.map +1 -1
- package/lib/cjs/src/misc/context-menu/DefaultContextMenu.d.ts.map +1 -1
- package/lib/cjs/src/misc/context-menu/NodeContextMenu.d.ts.map +1 -1
- package/lib/cjs/src/misc/context-menu/SelectionContextMenu.d.ts.map +1 -1
- package/lib/cjs/src/misc/load.d.ts.map +1 -1
- package/lib/cjs/src/misc/viewport-utils.d.ts +9 -0
- package/lib/cjs/src/misc/viewport-utils.d.ts.map +1 -0
- package/lib/cjs/src/runtime/IGraphRunner.d.ts +13 -1
- package/lib/cjs/src/runtime/IGraphRunner.d.ts.map +1 -1
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts +5 -0
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/lib/esm/index.js +255 -47
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/InMemoryWorkbench.d.ts +0 -3
- package/lib/esm/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/esm/src/index.d.ts +1 -0
- package/lib/esm/src/index.d.ts.map +1 -1
- package/lib/esm/src/misc/KeyboardShortcutToast.d.ts +16 -0
- package/lib/esm/src/misc/KeyboardShortcutToast.d.ts.map +1 -0
- package/lib/esm/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.d.ts +3 -11
- package/lib/esm/src/misc/context/WorkbenchContext.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/esm/src/misc/context-menu/ContextMenuHandlers.d.ts +5 -0
- package/lib/esm/src/misc/context-menu/ContextMenuHandlers.d.ts.map +1 -1
- package/lib/esm/src/misc/context-menu/ContextMenuHelpers.d.ts +1 -1
- package/lib/esm/src/misc/context-menu/ContextMenuHelpers.d.ts.map +1 -1
- package/lib/esm/src/misc/context-menu/DefaultContextMenu.d.ts.map +1 -1
- package/lib/esm/src/misc/context-menu/NodeContextMenu.d.ts.map +1 -1
- package/lib/esm/src/misc/context-menu/SelectionContextMenu.d.ts.map +1 -1
- package/lib/esm/src/misc/load.d.ts.map +1 -1
- package/lib/esm/src/misc/viewport-utils.d.ts +9 -0
- package/lib/esm/src/misc/viewport-utils.d.ts.map +1 -0
- package/lib/esm/src/runtime/IGraphRunner.d.ts +13 -1
- package/lib/esm/src/runtime/IGraphRunner.d.ts.map +1 -1
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts +5 -0
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/esm/index.js
CHANGED
|
@@ -6,7 +6,6 @@ import React, { useCallback, useState, useRef, useEffect, useMemo, createContext
|
|
|
6
6
|
import cx from 'classnames';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import { XCircleIcon, WarningCircleIcon, CopyIcon, TrashIcon, XIcon, ArrowClockwiseIcon, ClockClockwiseIcon, StopIcon, PlayIcon, PlugsConnectedIcon, WifiHighIcon, WifiSlashIcon, PlayPauseIcon, LightningIcon, TreeStructureIcon, CornersOutIcon, DownloadIcon, UploadIcon, BugBeetleIcon, ListBulletsIcon } from '@phosphor-icons/react';
|
|
9
|
-
import isEqual from 'lodash/isEqual';
|
|
10
9
|
|
|
11
10
|
class DefaultUIExtensionRegistry {
|
|
12
11
|
constructor() {
|
|
@@ -321,12 +320,13 @@ class InMemoryWorkbench extends AbstractWorkbench {
|
|
|
321
320
|
// Clear selection
|
|
322
321
|
this.setSelection({ nodes: [], edges: [] }, options);
|
|
323
322
|
}
|
|
324
|
-
setViewport(viewport
|
|
323
|
+
setViewport(viewport) {
|
|
324
|
+
if (lod.isEqual(this.viewport, viewport))
|
|
325
|
+
return;
|
|
325
326
|
this.viewport = { ...viewport };
|
|
326
327
|
this.emit("graphUiChanged", {
|
|
327
328
|
def: this.def,
|
|
328
329
|
change: { type: "viewport" },
|
|
329
|
-
...options,
|
|
330
330
|
});
|
|
331
331
|
}
|
|
332
332
|
getViewport() {
|
|
@@ -969,6 +969,24 @@ class LocalGraphRunner extends AbstractGraphRunner {
|
|
|
969
969
|
}
|
|
970
970
|
}
|
|
971
971
|
|
|
972
|
+
function isValidViewport(viewport) {
|
|
973
|
+
return (viewport !== null &&
|
|
974
|
+
typeof viewport === "object" &&
|
|
975
|
+
"x" in viewport &&
|
|
976
|
+
"y" in viewport &&
|
|
977
|
+
"zoom" in viewport &&
|
|
978
|
+
typeof viewport.x === "number" &&
|
|
979
|
+
typeof viewport.y === "number" &&
|
|
980
|
+
typeof viewport.zoom === "number");
|
|
981
|
+
}
|
|
982
|
+
function excludeViewportFromUIState(uiState) {
|
|
983
|
+
if (!uiState) {
|
|
984
|
+
return {};
|
|
985
|
+
}
|
|
986
|
+
const { viewport: _ignoredViewport, ...rest } = uiState;
|
|
987
|
+
return rest;
|
|
988
|
+
}
|
|
989
|
+
|
|
972
990
|
// Counter for generating readable runner IDs
|
|
973
991
|
let remoteRunnerCounter = 0;
|
|
974
992
|
class RemoteGraphRunner extends AbstractGraphRunner {
|
|
@@ -1140,9 +1158,26 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
1140
1158
|
this.clientPromise = (async () => {
|
|
1141
1159
|
// Build client config from backend config
|
|
1142
1160
|
const clientConfig = this.buildClientConfig(backend);
|
|
1143
|
-
//
|
|
1161
|
+
// Wrap custom event handler to intercept flow-viewport events and emit viewport event
|
|
1162
|
+
const wrappedOnCustomEvent = (event) => {
|
|
1163
|
+
const msg = event?.message;
|
|
1164
|
+
if (msg &&
|
|
1165
|
+
typeof msg === "object" &&
|
|
1166
|
+
"type" in msg &&
|
|
1167
|
+
msg.type === "flow-viewport") {
|
|
1168
|
+
const viewport = msg.payload?.viewport;
|
|
1169
|
+
if (isValidViewport(viewport)) {
|
|
1170
|
+
this.emit("viewport", { viewport });
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
// Call original handler if provided
|
|
1174
|
+
if (backend.onCustomEvent) {
|
|
1175
|
+
backend.onCustomEvent(event);
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
// Create client with wrapped custom event handler
|
|
1144
1179
|
const client = new RuntimeApiClient(clientConfig, {
|
|
1145
|
-
onCustomEvent:
|
|
1180
|
+
onCustomEvent: wrappedOnCustomEvent,
|
|
1146
1181
|
runnerId: this.runnerId,
|
|
1147
1182
|
});
|
|
1148
1183
|
// Setup event subscriptions
|
|
@@ -1417,6 +1452,20 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
1417
1452
|
const client = await this.ensureClient();
|
|
1418
1453
|
await client.copyOutputs(fromNodeId, toNodeId, options);
|
|
1419
1454
|
}
|
|
1455
|
+
async setViewport(viewport) {
|
|
1456
|
+
const client = await this.ensureClient();
|
|
1457
|
+
const transport = client.transport;
|
|
1458
|
+
if (transport && transport.send) {
|
|
1459
|
+
transport.send({
|
|
1460
|
+
seq: Date.now(),
|
|
1461
|
+
ts: Date.now(),
|
|
1462
|
+
message: {
|
|
1463
|
+
type: "SetViewport",
|
|
1464
|
+
payload: { viewport },
|
|
1465
|
+
},
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1420
1469
|
triggerExternal(nodeId, event, options) {
|
|
1421
1470
|
// If engine exists, call directly; otherwise ensure client (fire-and-forget)
|
|
1422
1471
|
if (this.engine) {
|
|
@@ -2434,7 +2483,8 @@ function isSnapshotPayload(parsed) {
|
|
|
2434
2483
|
async function download(wb, runner) {
|
|
2435
2484
|
try {
|
|
2436
2485
|
const def = wb.export();
|
|
2437
|
-
const
|
|
2486
|
+
const fullUiState = wb.getUIState();
|
|
2487
|
+
const uiState = excludeViewportFromUIState(fullUiState);
|
|
2438
2488
|
const runtimeState = wb.getRuntimeState();
|
|
2439
2489
|
let snapshot;
|
|
2440
2490
|
if (runner.isRunning()) {
|
|
@@ -2444,7 +2494,7 @@ async function download(wb, runner) {
|
|
|
2444
2494
|
def,
|
|
2445
2495
|
extData: {
|
|
2446
2496
|
...(fullSnapshot.extData || {}),
|
|
2447
|
-
ui: uiState,
|
|
2497
|
+
ui: Object.keys(uiState || {}).length > 0 ? uiState : undefined,
|
|
2448
2498
|
runtime: runtimeState || undefined,
|
|
2449
2499
|
},
|
|
2450
2500
|
};
|
|
@@ -2456,7 +2506,10 @@ async function download(wb, runner) {
|
|
|
2456
2506
|
inputs,
|
|
2457
2507
|
outputs: {},
|
|
2458
2508
|
environment: {},
|
|
2459
|
-
extData: {
|
|
2509
|
+
extData: {
|
|
2510
|
+
ui: Object.keys(uiState || {}).length > 0 ? uiState : undefined,
|
|
2511
|
+
runtime: runtimeState || undefined,
|
|
2512
|
+
},
|
|
2460
2513
|
};
|
|
2461
2514
|
}
|
|
2462
2515
|
downloadJSON(snapshot, `spark-snapshot-${generateTimestamp()}.json`);
|
|
@@ -2480,7 +2533,8 @@ async function upload(parsed, wb, runner) {
|
|
|
2480
2533
|
}
|
|
2481
2534
|
await wb.load(def);
|
|
2482
2535
|
if (extData.ui && typeof extData.ui === "object") {
|
|
2483
|
-
|
|
2536
|
+
const uiWithoutViewport = excludeViewportFromUIState(extData.ui);
|
|
2537
|
+
wb.setUIState(uiWithoutViewport);
|
|
2484
2538
|
}
|
|
2485
2539
|
if (extData.runtime && typeof extData.runtime === "object") {
|
|
2486
2540
|
wb.setRuntimeState(extData.runtime);
|
|
@@ -2727,11 +2781,12 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2727
2781
|
}
|
|
2728
2782
|
// Save cleaned metadata to workbench state
|
|
2729
2783
|
wb.setRuntimeState(metadata);
|
|
2730
|
-
|
|
2731
|
-
const
|
|
2732
|
-
// Save both runtime and UI state to extData (merge to preserve both)
|
|
2784
|
+
const fullUiState = wb.getUIState();
|
|
2785
|
+
const uiWithoutViewport = excludeViewportFromUIState(fullUiState);
|
|
2733
2786
|
await runner.setExtData?.({
|
|
2734
|
-
...(
|
|
2787
|
+
...(Object.keys(uiWithoutViewport || {}).length > 0
|
|
2788
|
+
? { ui: uiWithoutViewport }
|
|
2789
|
+
: {}),
|
|
2735
2790
|
runtime: metadata,
|
|
2736
2791
|
});
|
|
2737
2792
|
}
|
|
@@ -3165,6 +3220,16 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3165
3220
|
}
|
|
3166
3221
|
});
|
|
3167
3222
|
const offWbGraphUiChanged = wb.on("graphUiChanged", async (event) => {
|
|
3223
|
+
// Handle viewport changes separately (send via SetViewport command, not commit)
|
|
3224
|
+
if (event.change?.type === "viewport") {
|
|
3225
|
+
const viewport = wb.getViewport();
|
|
3226
|
+
if (viewport && runner.setViewport) {
|
|
3227
|
+
runner.setViewport(viewport).catch((err) => {
|
|
3228
|
+
console.warn("[WorkbenchContext] Failed to send viewport update:", err);
|
|
3229
|
+
});
|
|
3230
|
+
}
|
|
3231
|
+
return;
|
|
3232
|
+
}
|
|
3168
3233
|
// Only commit if commit flag is true (e.g., drag end, not during dragging)
|
|
3169
3234
|
if (event.commit) {
|
|
3170
3235
|
// Build detailed reason from change type
|
|
@@ -3180,9 +3245,6 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3180
3245
|
else if (changeType === "selection") {
|
|
3181
3246
|
reason = "selection";
|
|
3182
3247
|
}
|
|
3183
|
-
else if (changeType === "viewport") {
|
|
3184
|
-
reason = "viewport";
|
|
3185
|
-
}
|
|
3186
3248
|
}
|
|
3187
3249
|
await saveUiRuntimeMetadata();
|
|
3188
3250
|
const history = await runner
|
|
@@ -3214,7 +3276,12 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3214
3276
|
console.error("Failed to handle registry changed event");
|
|
3215
3277
|
}
|
|
3216
3278
|
});
|
|
3217
|
-
|
|
3279
|
+
const offFlowViewport = runner.on("viewport", (event) => {
|
|
3280
|
+
const viewport = event.viewport;
|
|
3281
|
+
if (isValidViewport(viewport)) {
|
|
3282
|
+
wb.setViewport(viewport);
|
|
3283
|
+
}
|
|
3284
|
+
});
|
|
3218
3285
|
const offRunnerTransport = runner.on("transport", (t) => {
|
|
3219
3286
|
if (t.state === "disconnected") {
|
|
3220
3287
|
console.info("[WorkbenchContext] Transport disconnected, resetting node status");
|
|
@@ -3254,6 +3321,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3254
3321
|
offWbSelectionChanged();
|
|
3255
3322
|
offRunnerRegistry();
|
|
3256
3323
|
offRunnerTransport();
|
|
3324
|
+
offFlowViewport();
|
|
3257
3325
|
};
|
|
3258
3326
|
}, [runner, wb, setRegistry]);
|
|
3259
3327
|
const isRunning = useCallback(() => runner.isRunning(), [runner]);
|
|
@@ -3612,6 +3680,47 @@ function createNodeCopyHandler(wb, runner, nodeId, getDefaultNodeSize, onCopyRes
|
|
|
3612
3680
|
* Creates base selection context menu handlers.
|
|
3613
3681
|
*/
|
|
3614
3682
|
function createSelectionContextMenuHandlers(wb, onClose, getDefaultNodeSize, onCopyResult, runner) {
|
|
3683
|
+
const onDuplicate = runner
|
|
3684
|
+
? () => {
|
|
3685
|
+
const selection = wb.getSelection();
|
|
3686
|
+
if (selection.nodes.length === 0) {
|
|
3687
|
+
onClose();
|
|
3688
|
+
return;
|
|
3689
|
+
}
|
|
3690
|
+
const def = wb.export();
|
|
3691
|
+
const positions = wb.getPositions();
|
|
3692
|
+
const newNodes = [];
|
|
3693
|
+
// Duplicate each selected node
|
|
3694
|
+
for (const nodeId of selection.nodes) {
|
|
3695
|
+
const n = def.nodes.find((n) => n.nodeId === nodeId);
|
|
3696
|
+
if (!n)
|
|
3697
|
+
continue;
|
|
3698
|
+
const pos = positions[nodeId] || { x: 0, y: 0 };
|
|
3699
|
+
// Get inputs without bindings (literal values only)
|
|
3700
|
+
const allInputs = runner.getInputs(def)[nodeId] || {};
|
|
3701
|
+
const inboundHandles = new Set(def.edges
|
|
3702
|
+
.filter((e) => e.target.nodeId === nodeId)
|
|
3703
|
+
.map((e) => e.target.handle));
|
|
3704
|
+
const inputsWithoutBindings = Object.fromEntries(Object.entries(allInputs).filter(([handle]) => !inboundHandles.has(handle)));
|
|
3705
|
+
const newNodeId = wb.addNode({
|
|
3706
|
+
typeId: n.typeId,
|
|
3707
|
+
params: n.params,
|
|
3708
|
+
position: { x: pos.x + 24, y: pos.y + 24 },
|
|
3709
|
+
resolvedHandles: n.resolvedHandles,
|
|
3710
|
+
}, {
|
|
3711
|
+
inputs: inputsWithoutBindings,
|
|
3712
|
+
copyOutputsFrom: nodeId,
|
|
3713
|
+
dry: true,
|
|
3714
|
+
});
|
|
3715
|
+
newNodes.push(newNodeId);
|
|
3716
|
+
}
|
|
3717
|
+
// Select all newly duplicated nodes
|
|
3718
|
+
if (newNodes.length > 0) {
|
|
3719
|
+
wb.setSelection({ nodes: newNodes, edges: [] }, { commit: true, reason: "duplicate-selection" });
|
|
3720
|
+
}
|
|
3721
|
+
onClose();
|
|
3722
|
+
}
|
|
3723
|
+
: undefined;
|
|
3615
3724
|
return {
|
|
3616
3725
|
onCopy: runner
|
|
3617
3726
|
? createCopyHandler(wb, runner, getDefaultNodeSize, onCopyResult)
|
|
@@ -3623,13 +3732,14 @@ function createSelectionContextMenuHandlers(wb, onClose, getDefaultNodeSize, onC
|
|
|
3623
3732
|
wb.deleteSelection({ commit: true, reason: "delete-selection" });
|
|
3624
3733
|
onClose();
|
|
3625
3734
|
},
|
|
3735
|
+
onDuplicate,
|
|
3626
3736
|
onClose,
|
|
3627
3737
|
};
|
|
3628
3738
|
}
|
|
3629
3739
|
/**
|
|
3630
3740
|
* Creates base default context menu handlers.
|
|
3631
3741
|
*/
|
|
3632
|
-
function createDefaultContextMenuHandlers(onAddNode, onClose, onPaste, runner, getCopiedData, clearCopiedData, history) {
|
|
3742
|
+
function createDefaultContextMenuHandlers(onAddNode, onClose, onPaste, runner, getCopiedData, clearCopiedData, history, wb) {
|
|
3633
3743
|
// Wrap paste handler to clear storage after paste
|
|
3634
3744
|
const wrappedOnPaste = onPaste && getCopiedData && clearCopiedData
|
|
3635
3745
|
? (position) => {
|
|
@@ -3640,12 +3750,22 @@ function createDefaultContextMenuHandlers(onAddNode, onClose, onPaste, runner, g
|
|
|
3640
3750
|
const hasPasteData = getCopiedData ? () => !!getCopiedData() : undefined;
|
|
3641
3751
|
const canUndo = history ? history.undoCount > 0 : undefined;
|
|
3642
3752
|
const canRedo = history ? history.redoCount > 0 : undefined;
|
|
3753
|
+
const onSelectAll = wb
|
|
3754
|
+
? () => {
|
|
3755
|
+
const def = wb.export();
|
|
3756
|
+
const allNodeIds = def.nodes.map((n) => n.nodeId);
|
|
3757
|
+
const allEdgeIds = def.edges.map((e) => e.id);
|
|
3758
|
+
wb.setSelection({ nodes: allNodeIds, edges: allEdgeIds }, { commit: true, reason: "select-all" });
|
|
3759
|
+
onClose();
|
|
3760
|
+
}
|
|
3761
|
+
: undefined;
|
|
3643
3762
|
return {
|
|
3644
3763
|
onAddNode,
|
|
3645
3764
|
onPaste: wrappedOnPaste,
|
|
3646
3765
|
hasPasteData,
|
|
3647
3766
|
onUndo: runner ? () => runner.undo().then(() => onClose()) : undefined,
|
|
3648
3767
|
onRedo: runner ? () => runner.redo().then(() => onClose()) : undefined,
|
|
3768
|
+
onSelectAll,
|
|
3649
3769
|
canUndo,
|
|
3650
3770
|
canRedo,
|
|
3651
3771
|
onClose,
|
|
@@ -4185,6 +4305,7 @@ function DefaultContextMenu({ open, clientPos, handlers, registry, nodeIds, enab
|
|
|
4185
4305
|
undo: "⌘/Ctrl + Z",
|
|
4186
4306
|
redo: "⌘/Ctrl + Shift + Z",
|
|
4187
4307
|
paste: "⌘/Ctrl + V",
|
|
4308
|
+
selectAll: "⌘/Ctrl + A",
|
|
4188
4309
|
}, }) {
|
|
4189
4310
|
const rf = useReactFlow();
|
|
4190
4311
|
const [query, setQuery] = useState("");
|
|
@@ -4287,7 +4408,7 @@ function DefaultContextMenu({ open, clientPos, handlers, registry, nodeIds, enab
|
|
|
4287
4408
|
return (jsxs("div", { ref: ref, tabIndex: -1, className: "fixed z-[1000] bg-white border border-gray-300 rounded-lg shadow-lg p-1 min-w-[180px] text-sm text-gray-700 select-none", style: { left: x, top: y }, onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), onWheel: (e) => e.stopPropagation(), onContextMenu: (e) => {
|
|
4288
4409
|
e.preventDefault();
|
|
4289
4410
|
e.stopPropagation();
|
|
4290
|
-
}, children: [hasPasteData && handlers.onPaste && (jsx(ContextMenuButton, { label: "Paste", onClick: handlePaste, shortcut: keyboardShortcuts.paste, enableKeyboardShortcuts: enableKeyboardShortcuts })), (handlers.onUndo || handlers.onRedo) && (jsxs(Fragment, { children: [hasPasteData && handlers.onPaste && (jsx("div", { className: "h-px bg-gray-200 my-1" })), handlers.onUndo && (jsx(ContextMenuButton, { label: "Undo", onClick: handlers.onUndo, disabled: !canUndo, shortcut: keyboardShortcuts.undo, enableKeyboardShortcuts: enableKeyboardShortcuts })), handlers.onRedo && (jsx(ContextMenuButton, { label: "Redo", onClick: handlers.onRedo, disabled: !canRedo, shortcut: keyboardShortcuts.redo, enableKeyboardShortcuts: enableKeyboardShortcuts }))] })), hasPasteData &&
|
|
4411
|
+
}, children: [hasPasteData && handlers.onPaste && (jsx(ContextMenuButton, { label: "Paste", onClick: handlePaste, shortcut: keyboardShortcuts.paste, enableKeyboardShortcuts: enableKeyboardShortcuts })), (handlers.onUndo || handlers.onRedo || handlers.onSelectAll) && (jsxs(Fragment, { children: [hasPasteData && handlers.onPaste && (jsx("div", { className: "h-px bg-gray-200 my-1" })), handlers.onSelectAll && (jsx(ContextMenuButton, { label: "Select All", onClick: handlers.onSelectAll, shortcut: keyboardShortcuts.selectAll, enableKeyboardShortcuts: enableKeyboardShortcuts })), handlers.onSelectAll && (handlers.onUndo || handlers.onRedo) && (jsx("div", { className: "h-px bg-gray-200 my-1" })), handlers.onUndo && (jsx(ContextMenuButton, { label: "Undo", onClick: handlers.onUndo, disabled: !canUndo, shortcut: keyboardShortcuts.undo, enableKeyboardShortcuts: enableKeyboardShortcuts })), handlers.onRedo && (jsx(ContextMenuButton, { label: "Redo", onClick: handlers.onRedo, disabled: !canRedo, shortcut: keyboardShortcuts.redo, enableKeyboardShortcuts: enableKeyboardShortcuts })), (handlers.onUndo || handlers.onRedo) && (jsx("div", { className: "h-px bg-gray-200 my-1" }))] })), hasPasteData &&
|
|
4291
4412
|
handlers.onPaste &&
|
|
4292
4413
|
!handlers.onUndo &&
|
|
4293
4414
|
!handlers.onRedo && jsx("div", { className: "h-px bg-gray-200 my-1" }), jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Add Node", " ", jsxs("span", { className: "text-gray-500 font-normal", children: ["(", totalCount, ")"] })] }), jsx("div", { className: "px-2 pb-1", children: jsx("input", { ref: inputRef, type: "text", value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Filter nodes...", className: "w-full border border-gray-300 rounded px-2 py-1 text-sm outline-none focus:border-gray-400 select-text", onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), onWheel: (e) => e.stopPropagation() }) }), jsx("div", { className: "max-h-60 overflow-auto", children: totalCount > 0 ? (renderTree(root)) : (jsx("div", { className: "px-3 py-2 text-gray-400", children: "No matches" })) })] }));
|
|
@@ -4295,7 +4416,8 @@ function DefaultContextMenu({ open, clientPos, handlers, registry, nodeIds, enab
|
|
|
4295
4416
|
|
|
4296
4417
|
function NodeContextMenu({ open, clientPos, nodeId, handlers, canRunPull, bakeableOutputs, enableKeyboardShortcuts = true, keyboardShortcuts = {
|
|
4297
4418
|
copy: "⌘/Ctrl + C",
|
|
4298
|
-
duplicate: "⌘/Ctrl +
|
|
4419
|
+
duplicate: "⌘/Ctrl + E",
|
|
4420
|
+
duplicateWithEdges: "⌘/Ctrl + Shift + E",
|
|
4299
4421
|
delete: "Delete",
|
|
4300
4422
|
}, }) {
|
|
4301
4423
|
const ref = useRef(null);
|
|
@@ -4335,11 +4457,12 @@ function NodeContextMenu({ open, clientPos, nodeId, handlers, canRunPull, bakeab
|
|
|
4335
4457
|
return (jsxs("div", { ref: ref, tabIndex: -1, className: "fixed z-[1000] bg-white border border-gray-300 rounded-lg shadow-lg p-1 min-w-[180px] text-sm text-gray-700 select-none", style: { left: x, top: y }, onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), onWheel: (e) => e.stopPropagation(), onContextMenu: (e) => {
|
|
4336
4458
|
e.preventDefault();
|
|
4337
4459
|
e.stopPropagation();
|
|
4338
|
-
}, children: [jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Node (", nodeId, ")"] }), jsx(ContextMenuButton, { label: "Delete", onClick: handlers.onDelete, shortcut: keyboardShortcuts.delete, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx(ContextMenuButton, { label: "Duplicate", onClick: handlers.onDuplicate, shortcut: keyboardShortcuts.duplicate, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx(
|
|
4460
|
+
}, children: [jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Node (", nodeId, ")"] }), jsx(ContextMenuButton, { label: "Delete", onClick: handlers.onDelete, shortcut: keyboardShortcuts.delete, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx(ContextMenuButton, { label: "Duplicate", onClick: handlers.onDuplicate, shortcut: keyboardShortcuts.duplicate, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx(ContextMenuButton, { label: "Duplicate with edges", onClick: handlers.onDuplicateWithEdges, shortcut: keyboardShortcuts.duplicateWithEdges, enableKeyboardShortcuts: enableKeyboardShortcuts }), canRunPull && (jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onRunPull, children: "Run (pull)" })), jsx("div", { className: "h-px bg-gray-200 my-1" }), jsx(ContextMenuButton, { label: "Copy", onClick: handlers.onCopy, shortcut: keyboardShortcuts.copy, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onCopyId, children: "Copy Node ID" }), bakeableOutputs.length > 0 && (jsxs(Fragment, { children: [jsx("div", { className: "h-px bg-gray-200 my-1" }), jsx("div", { className: "px-2 py-1 font-semibold text-gray-700", children: "Bake" }), bakeableOutputs.map((h) => (jsxs("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: () => handlers.onBake(h), children: ["Bake: ", h] }, h)))] }))] }));
|
|
4339
4461
|
}
|
|
4340
4462
|
|
|
4341
4463
|
function SelectionContextMenu({ open, clientPos, handlers, enableKeyboardShortcuts = true, keyboardShortcuts = {
|
|
4342
4464
|
copy: "⌘/Ctrl + C",
|
|
4465
|
+
duplicate: "⌘/Ctrl + E",
|
|
4343
4466
|
delete: "Delete",
|
|
4344
4467
|
}, }) {
|
|
4345
4468
|
const ref = useRef(null);
|
|
@@ -4379,7 +4502,45 @@ function SelectionContextMenu({ open, clientPos, handlers, enableKeyboardShortcu
|
|
|
4379
4502
|
return (jsxs("div", { ref: ref, tabIndex: -1, className: "fixed z-[1000] bg-white border border-gray-300 rounded-lg shadow-lg p-1 min-w-[180px] text-sm text-gray-700 select-none", style: { left: x, top: y }, onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), onWheel: (e) => e.stopPropagation(), onContextMenu: (e) => {
|
|
4380
4503
|
e.preventDefault();
|
|
4381
4504
|
e.stopPropagation();
|
|
4382
|
-
}, children: [jsx("div", { className: "px-2 py-1 font-semibold text-gray-700", children: "Selection" }), jsx(ContextMenuButton, { label: "Copy", onClick: handlers.onCopy, shortcut: keyboardShortcuts.copy, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx(ContextMenuButton, { label: "Delete", onClick: handlers.onDelete, shortcut: keyboardShortcuts.delete, enableKeyboardShortcuts: enableKeyboardShortcuts })] }));
|
|
4505
|
+
}, children: [jsx("div", { className: "px-2 py-1 font-semibold text-gray-700", children: "Selection" }), jsx(ContextMenuButton, { label: "Copy", onClick: handlers.onCopy, shortcut: keyboardShortcuts.copy, enableKeyboardShortcuts: enableKeyboardShortcuts }), handlers.onDuplicate && (jsx(ContextMenuButton, { label: "Duplicate", onClick: handlers.onDuplicate, shortcut: keyboardShortcuts.duplicate, enableKeyboardShortcuts: enableKeyboardShortcuts })), jsx(ContextMenuButton, { label: "Delete", onClick: handlers.onDelete, shortcut: keyboardShortcuts.delete, enableKeyboardShortcuts: enableKeyboardShortcuts })] }));
|
|
4506
|
+
}
|
|
4507
|
+
|
|
4508
|
+
function KeyboardShortcutToast({ message, duration = 1000, onClose, }) {
|
|
4509
|
+
const [isVisible, setIsVisible] = useState(true);
|
|
4510
|
+
const onCloseRef = useRef(onClose);
|
|
4511
|
+
const fadeOutTimerRef = useRef(null);
|
|
4512
|
+
// Keep onClose ref up to date
|
|
4513
|
+
useEffect(() => {
|
|
4514
|
+
onCloseRef.current = onClose;
|
|
4515
|
+
}, [onClose]);
|
|
4516
|
+
useEffect(() => {
|
|
4517
|
+
const timer = setTimeout(() => {
|
|
4518
|
+
setIsVisible(false);
|
|
4519
|
+
// Wait for fade-out animation before calling onClose
|
|
4520
|
+
fadeOutTimerRef.current = setTimeout(() => {
|
|
4521
|
+
onCloseRef.current();
|
|
4522
|
+
}, 300);
|
|
4523
|
+
}, duration);
|
|
4524
|
+
return () => {
|
|
4525
|
+
clearTimeout(timer);
|
|
4526
|
+
if (fadeOutTimerRef.current) {
|
|
4527
|
+
clearTimeout(fadeOutTimerRef.current);
|
|
4528
|
+
}
|
|
4529
|
+
};
|
|
4530
|
+
}, [duration]);
|
|
4531
|
+
return (jsx("div", { className: `fixed top-4 left-1/2 -translate-x-1/2 z-[2000] pointer-events-none transition-opacity duration-300 ${isVisible ? "opacity-100" : "opacity-0"}`, children: jsx("div", { className: "bg-white border border-gray-300 rounded-lg shadow-lg px-2 py-1 text-sm text-gray-700 font-medium whitespace-nowrap", children: message }) }));
|
|
4532
|
+
}
|
|
4533
|
+
// Hook to manage toast state
|
|
4534
|
+
function useKeyboardShortcutToast() {
|
|
4535
|
+
const [toast, setToast] = useState(null);
|
|
4536
|
+
const showToast = (message) => {
|
|
4537
|
+
const id = Date.now();
|
|
4538
|
+
setToast({ message, id });
|
|
4539
|
+
};
|
|
4540
|
+
const hideToast = () => {
|
|
4541
|
+
setToast(null);
|
|
4542
|
+
};
|
|
4543
|
+
return { toast, showToast, hideToast };
|
|
4383
4544
|
}
|
|
4384
4545
|
|
|
4385
4546
|
const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, getDefaultNodeSize }, ref) => {
|
|
@@ -4424,7 +4585,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4424
4585
|
inputConnected: n.data.inputConnected,
|
|
4425
4586
|
},
|
|
4426
4587
|
});
|
|
4427
|
-
return isEqual(pick(a), pick(b));
|
|
4588
|
+
return lod.isEqual(pick(a), pick(b));
|
|
4428
4589
|
};
|
|
4429
4590
|
const isSameEdge = (a, b) => {
|
|
4430
4591
|
const pick = (e) => ({
|
|
@@ -4438,7 +4599,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4438
4599
|
label: e.label,
|
|
4439
4600
|
type: e.type,
|
|
4440
4601
|
});
|
|
4441
|
-
return isEqual(pick(a), pick(b));
|
|
4602
|
+
return lod.isEqual(pick(a), pick(b));
|
|
4442
4603
|
};
|
|
4443
4604
|
// Expose imperative API
|
|
4444
4605
|
const rfInstanceRef = useRef(null);
|
|
@@ -4754,7 +4915,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4754
4915
|
return;
|
|
4755
4916
|
wb.pasteCopiedData(data, position, { commit: true, reason: "paste" });
|
|
4756
4917
|
onCloseMenu();
|
|
4757
|
-
}, runner, () => storage.get(), () => storage.set(null), historyState);
|
|
4918
|
+
}, runner, () => storage.get(), () => storage.set(null), historyState, wb);
|
|
4758
4919
|
if (overrides?.getDefaultContextMenuHandlers) {
|
|
4759
4920
|
return overrides.getDefaultContextMenuHandlers(wb, baseHandlers);
|
|
4760
4921
|
}
|
|
@@ -4819,9 +4980,13 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4819
4980
|
redo: "⌘/Ctrl + Shift + Z",
|
|
4820
4981
|
copy: "⌘/Ctrl + C",
|
|
4821
4982
|
paste: "⌘/Ctrl + V",
|
|
4822
|
-
duplicate: "⌘/Ctrl +
|
|
4983
|
+
duplicate: "⌘/Ctrl + E",
|
|
4984
|
+
duplicateWithEdges: "⌘/Ctrl + Shift + E",
|
|
4985
|
+
selectAll: "⌘/Ctrl + A",
|
|
4823
4986
|
delete: "Delete",
|
|
4824
4987
|
};
|
|
4988
|
+
// Toast notification for keyboard shortcuts
|
|
4989
|
+
const { toast, showToast, hideToast } = useKeyboardShortcutToast();
|
|
4825
4990
|
// Keyboard shortcut handler
|
|
4826
4991
|
useEffect(() => {
|
|
4827
4992
|
if (!enableKeyboardShortcuts)
|
|
@@ -4847,6 +5012,8 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4847
5012
|
defaultContextMenuHandlers.onUndo &&
|
|
4848
5013
|
defaultContextMenuHandlers.canUndo) {
|
|
4849
5014
|
if (defaultContextMenuHandlers.canUndo) {
|
|
5015
|
+
const modKeyLabel = isMac ? "⌘" : "Ctrl";
|
|
5016
|
+
showToast(`Undo (${modKeyLabel} + Z)`);
|
|
4850
5017
|
defaultContextMenuHandlers.onUndo();
|
|
4851
5018
|
}
|
|
4852
5019
|
}
|
|
@@ -4860,6 +5027,8 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4860
5027
|
defaultContextMenuHandlers.onRedo &&
|
|
4861
5028
|
defaultContextMenuHandlers.canRedo) {
|
|
4862
5029
|
if (defaultContextMenuHandlers.canRedo) {
|
|
5030
|
+
const modKeyLabel = isMac ? "⌘" : "Ctrl";
|
|
5031
|
+
showToast(`Redo (${modKeyLabel} + Shift + Z)`);
|
|
4863
5032
|
defaultContextMenuHandlers.onRedo();
|
|
4864
5033
|
}
|
|
4865
5034
|
}
|
|
@@ -4870,6 +5039,8 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4870
5039
|
const selection = wb.getSelection();
|
|
4871
5040
|
if (selection.nodes.length > 0 || selection.edges.length > 0) {
|
|
4872
5041
|
e.preventDefault();
|
|
5042
|
+
const modKeyLabel = isMac ? "⌘" : "Ctrl";
|
|
5043
|
+
showToast(`Copy (${modKeyLabel} + C)`);
|
|
4873
5044
|
// If single node selected, use node context menu handler; otherwise use selection handler
|
|
4874
5045
|
if (selection.nodes.length === 1 && nodeContextMenuHandlers?.onCopy) {
|
|
4875
5046
|
nodeContextMenuHandlers.onCopy();
|
|
@@ -4880,14 +5051,37 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4880
5051
|
}
|
|
4881
5052
|
return;
|
|
4882
5053
|
}
|
|
4883
|
-
// Duplicate: Cmd/Ctrl +
|
|
4884
|
-
if (modKey && key === "
|
|
5054
|
+
// Duplicate: Cmd/Ctrl + E
|
|
5055
|
+
if (modKey && key === "e" && !e.shiftKey && !e.altKey) {
|
|
4885
5056
|
const selection = wb.getSelection();
|
|
4886
5057
|
if (selection.nodes.length === 1 &&
|
|
4887
5058
|
nodeContextMenuHandlers?.onDuplicate) {
|
|
5059
|
+
// Single node selected - use node context menu handler
|
|
4888
5060
|
e.preventDefault();
|
|
5061
|
+
const modKeyLabel = isMac ? "⌘" : "Ctrl";
|
|
5062
|
+
showToast(`Duplicate (${modKeyLabel} + E)`);
|
|
4889
5063
|
nodeContextMenuHandlers.onDuplicate();
|
|
4890
5064
|
}
|
|
5065
|
+
else if (selection.nodes.length > 1 &&
|
|
5066
|
+
selectionContextMenuHandlers.onDuplicate) {
|
|
5067
|
+
// Multiple nodes selected - use selection context menu handler
|
|
5068
|
+
e.preventDefault();
|
|
5069
|
+
const modKeyLabel = isMac ? "⌘" : "Ctrl";
|
|
5070
|
+
showToast(`Duplicate (${modKeyLabel} + E)`);
|
|
5071
|
+
selectionContextMenuHandlers.onDuplicate();
|
|
5072
|
+
}
|
|
5073
|
+
return;
|
|
5074
|
+
}
|
|
5075
|
+
// Duplicate with edges: Cmd/Ctrl + Shift + E
|
|
5076
|
+
if (modKey && key === "e" && e.shiftKey && !e.altKey) {
|
|
5077
|
+
const selection = wb.getSelection();
|
|
5078
|
+
if (selection.nodes.length === 1 &&
|
|
5079
|
+
nodeContextMenuHandlers?.onDuplicateWithEdges) {
|
|
5080
|
+
e.preventDefault();
|
|
5081
|
+
const modKeyLabel = isMac ? "⌘" : "Ctrl";
|
|
5082
|
+
showToast(`Duplicate with edges (${modKeyLabel} + Shift + E)`);
|
|
5083
|
+
nodeContextMenuHandlers.onDuplicateWithEdges();
|
|
5084
|
+
}
|
|
4891
5085
|
return;
|
|
4892
5086
|
}
|
|
4893
5087
|
// Paste: Cmd/Ctrl + V
|
|
@@ -4898,6 +5092,8 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4898
5092
|
defaultContextMenuHandlers.hasPasteData() &&
|
|
4899
5093
|
"onPaste" in defaultContextMenuHandlers &&
|
|
4900
5094
|
defaultContextMenuHandlers.onPaste) {
|
|
5095
|
+
const modKeyLabel = isMac ? "⌘" : "Ctrl";
|
|
5096
|
+
showToast(`Paste (${modKeyLabel} + V)`);
|
|
4901
5097
|
const center = rfInstanceRef.current?.screenToFlowPosition({
|
|
4902
5098
|
x: window.innerWidth / 2,
|
|
4903
5099
|
y: window.innerHeight / 2,
|
|
@@ -4906,6 +5102,16 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4906
5102
|
}
|
|
4907
5103
|
return;
|
|
4908
5104
|
}
|
|
5105
|
+
// Select All: Cmd/Ctrl + A
|
|
5106
|
+
if (modKey && key === "a" && !e.shiftKey && !e.altKey) {
|
|
5107
|
+
e.preventDefault();
|
|
5108
|
+
if (defaultContextMenuHandlers.onSelectAll) {
|
|
5109
|
+
const modKeyLabel = isMac ? "⌘" : "Ctrl";
|
|
5110
|
+
showToast(`Select All (${modKeyLabel} + A)`);
|
|
5111
|
+
defaultContextMenuHandlers.onSelectAll();
|
|
5112
|
+
}
|
|
5113
|
+
return;
|
|
5114
|
+
}
|
|
4909
5115
|
// Note: Delete/Backspace is handled by ReactFlow's deleteKeyCode prop
|
|
4910
5116
|
// which triggers onNodesDelete/onEdgesDelete, so we don't need to handle it here
|
|
4911
5117
|
};
|
|
@@ -4921,6 +5127,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4921
5127
|
selectionContextMenuHandlers,
|
|
4922
5128
|
nodeContextMenuHandlers,
|
|
4923
5129
|
rfInstanceRef,
|
|
5130
|
+
showToast,
|
|
4924
5131
|
]);
|
|
4925
5132
|
// Get custom renderers from UI extension registry (reactive to uiVersion changes)
|
|
4926
5133
|
const { BackgroundRenderer, MinimapRenderer, ControlsRenderer, DefaultContextMenuRenderer, NodeContextMenuRenderer, connectionLineRenderer, } = useMemo(() => {
|
|
@@ -4936,7 +5143,8 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4936
5143
|
const onMoveEnd = useCallback(() => {
|
|
4937
5144
|
if (rfInstanceRef.current) {
|
|
4938
5145
|
const viewport = rfInstanceRef.current.getViewport();
|
|
4939
|
-
|
|
5146
|
+
const viewportData = lod.pick(viewport, ["x", "y", "zoom"]);
|
|
5147
|
+
wb.setViewport(viewportData);
|
|
4940
5148
|
}
|
|
4941
5149
|
}, [wb]);
|
|
4942
5150
|
const viewportRef = useRef(null);
|
|
@@ -4957,24 +5165,24 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
4957
5165
|
});
|
|
4958
5166
|
}
|
|
4959
5167
|
});
|
|
4960
|
-
return (
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
? { enableKeyboardShortcuts, keyboardShortcuts }
|
|
4973
|
-
: {}) })) : (jsx(DefaultContextMenu, { open: menuOpen, clientPos: menuPos, handlers: defaultContextMenuHandlers, registry: registry, nodeIds: nodeIds, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })), !!nodeAtMenu &&
|
|
4974
|
-
nodeContextMenuHandlers &&
|
|
4975
|
-
(NodeContextMenuRenderer ? (jsx(NodeContextMenuRenderer, { open: nodeMenuOpen, clientPos: nodeMenuPos, nodeId: nodeAtMenu, handlers: nodeContextMenuHandlers, canRunPull: canRunPull, bakeableOutputs: bakeableOutputs, ...(enableKeyboardShortcuts !== false
|
|
5168
|
+
return (jsxs("div", { className: "w-full h-full", onContextMenu: onContextMenu, children: [jsx(ReactFlowProvider, { children: jsxs(ReactFlow, { nodes: throttled.nodes, edges: throttled.edges, nodeTypes: nodeTypes, connectionLineComponent: connectionLineRenderer, selectionOnDrag: true, onInit: (inst) => {
|
|
5169
|
+
rfInstanceRef.current = inst;
|
|
5170
|
+
const savedViewport = wb.getViewport();
|
|
5171
|
+
if (savedViewport) {
|
|
5172
|
+
viewportRef.current = savedViewport;
|
|
5173
|
+
inst.setViewport({
|
|
5174
|
+
x: savedViewport.x,
|
|
5175
|
+
y: savedViewport.y,
|
|
5176
|
+
zoom: savedViewport.zoom,
|
|
5177
|
+
});
|
|
5178
|
+
}
|
|
5179
|
+
}, onConnect: onConnect, onEdgesChange: onEdgesChange, onEdgesDelete: onEdgesDelete, onNodesDelete: onNodesDelete, onNodesChange: onNodesChange, onMoveEnd: onMoveEnd, deleteKeyCode: ["Backspace", "Delete"], proOptions: { hideAttribution: true }, noDragClassName: "wb-nodrag", noWheelClassName: "wb-nowheel", noPanClassName: "wb-nopan", fitView: true, children: [BackgroundRenderer ? (jsx(BackgroundRenderer, {})) : (jsx(Background, { id: "workbench-canvas-background", variant: BackgroundVariant.Dots, gap: 12, size: 1 })), MinimapRenderer ? jsx(MinimapRenderer, {}) : jsx(MiniMap, {}), ControlsRenderer ? jsx(ControlsRenderer, {}) : jsx(Controls, {}), DefaultContextMenuRenderer ? (jsx(DefaultContextMenuRenderer, { open: menuOpen, clientPos: menuPos, handlers: defaultContextMenuHandlers, registry: registry, nodeIds: nodeIds, ...(enableKeyboardShortcuts !== false
|
|
4976
5180
|
? { enableKeyboardShortcuts, keyboardShortcuts }
|
|
4977
|
-
: {}) })) : (jsx(
|
|
5181
|
+
: {}) })) : (jsx(DefaultContextMenu, { open: menuOpen, clientPos: menuPos, handlers: defaultContextMenuHandlers, registry: registry, nodeIds: nodeIds, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })), !!nodeAtMenu &&
|
|
5182
|
+
nodeContextMenuHandlers &&
|
|
5183
|
+
(NodeContextMenuRenderer ? (jsx(NodeContextMenuRenderer, { open: nodeMenuOpen, clientPos: nodeMenuPos, nodeId: nodeAtMenu, handlers: nodeContextMenuHandlers, canRunPull: canRunPull, bakeableOutputs: bakeableOutputs, ...(enableKeyboardShortcuts !== false
|
|
5184
|
+
? { enableKeyboardShortcuts, keyboardShortcuts }
|
|
5185
|
+
: {}) })) : (jsx(NodeContextMenu, { open: nodeMenuOpen, clientPos: nodeMenuPos, nodeId: nodeAtMenu, handlers: nodeContextMenuHandlers, canRunPull: canRunPull, bakeableOutputs: bakeableOutputs, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts }))), selectionMenuOpen && selectionMenuPos && (jsx(SelectionContextMenu, { open: selectionMenuOpen, clientPos: selectionMenuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts }))] }) }), toast && (jsx(KeyboardShortcutToast, { message: toast.message, onClose: hideToast }, toast.id))] }));
|
|
4978
5186
|
});
|
|
4979
5187
|
|
|
4980
5188
|
function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, example, onExampleChange, engine, onEngineChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, overrides, onInit, onChange, }) {
|
|
@@ -5511,5 +5719,5 @@ function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, bac
|
|
|
5511
5719
|
return (jsx(WorkbenchProvider, { wb: wb, runner: runner, registry: registry, setRegistry: setRegistry, overrides: overrides, uiVersion: uiVersion, children: jsx(WorkbenchStudioCanvas, { setRegistry: setRegistry, autoScroll: autoScroll, onAutoScrollChange: onAutoScrollChange, example: example, onExampleChange: onExampleChange, engine: engine, onEngineChange: onEngineChange, backendKind: backendKind, onBackendKindChange: onBackendKindChangeWithDispose, httpBaseUrl: httpBaseUrl, onHttpBaseUrlChange: onHttpBaseUrlChange, wsUrl: wsUrl, onWsUrlChange: onWsUrlChange, debug: debug, onDebugChange: onDebugChange, showValues: showValues, onShowValuesChange: onShowValuesChange, hideWorkbench: hideWorkbench, onHideWorkbenchChange: onHideWorkbenchChange, overrides: overrides, onInit: onInit, onChange: onChange }) }));
|
|
5512
5720
|
}
|
|
5513
5721
|
|
|
5514
|
-
export { AbstractWorkbench, CLIWorkbench, DefaultNode, DefaultNodeContent, DefaultNodeHeader, DefaultUIExtensionRegistry, InMemoryWorkbench, Inspector, LocalGraphRunner, NodeHandles, RemoteGraphRunner, WorkbenchCanvas, WorkbenchContext, WorkbenchProvider, WorkbenchStudio, computeEffectiveHandles, countVisibleHandles, createCopyHandler, createDefaultContextMenuHandlers, createHandleBounds, createHandleLayout, createNodeContextMenuHandlers, createNodeCopyHandler, createSelectionContextMenuHandlers, download, estimateNodeSize, formatDataUrlAsLabel, formatDeclaredTypeSignature, getBakeableOutputs, getHandleBoundsX, getHandleBoundsY, getHandleClassName, getHandleLayoutY, getNodeBorderClassNames, layoutNode, preformatValueForDisplay, prettyHandle, resolveOutputDisplay, summarizeDeep, toReactFlow, upload, useQueryParamBoolean, useQueryParamString, useThrottledValue, useWorkbenchBridge, useWorkbenchContext, useWorkbenchGraphTick, useWorkbenchGraphUiTick, useWorkbenchVersionTick };
|
|
5722
|
+
export { AbstractWorkbench, CLIWorkbench, DefaultNode, DefaultNodeContent, DefaultNodeHeader, DefaultUIExtensionRegistry, InMemoryWorkbench, Inspector, LocalGraphRunner, NodeHandles, RemoteGraphRunner, WorkbenchCanvas, WorkbenchContext, WorkbenchProvider, WorkbenchStudio, computeEffectiveHandles, countVisibleHandles, createCopyHandler, createDefaultContextMenuHandlers, createHandleBounds, createHandleLayout, createNodeContextMenuHandlers, createNodeCopyHandler, createSelectionContextMenuHandlers, download, estimateNodeSize, excludeViewportFromUIState, formatDataUrlAsLabel, formatDeclaredTypeSignature, getBakeableOutputs, getHandleBoundsX, getHandleBoundsY, getHandleClassName, getHandleLayoutY, getNodeBorderClassNames, isValidViewport, layoutNode, preformatValueForDisplay, prettyHandle, resolveOutputDisplay, summarizeDeep, toReactFlow, upload, useQueryParamBoolean, useQueryParamString, useThrottledValue, useWorkbenchBridge, useWorkbenchContext, useWorkbenchGraphTick, useWorkbenchGraphUiTick, useWorkbenchVersionTick };
|
|
5515
5723
|
//# sourceMappingURL=index.js.map
|