@burdenoff/fluidgrids-fe-sdk 2026.801.1 → 2026.801.2
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/{WorkflowBuilder-IGQYC2UR.js → WorkflowBuilder-R3PBZQOF.js} +5 -5
- package/dist/{WorkflowBuilder-IGQYC2UR.js.map → WorkflowBuilder-R3PBZQOF.js.map} +1 -1
- package/dist/WorkflowsList-F5QRVKAW.js +10 -0
- package/dist/{WorkflowsList-S2MGY2UT.js.map → WorkflowsList-F5QRVKAW.js.map} +1 -1
- package/dist/{blocks-K5JPCH3D.js → blocks-QKAWYAOT.js} +4 -4
- package/dist/{blocks-K5JPCH3D.js.map → blocks-QKAWYAOT.js.map} +1 -1
- package/dist/{chunk-JIZFSX6X.js → chunk-3VY2DAPD.js} +3 -3
- package/dist/{chunk-JIZFSX6X.js.map → chunk-3VY2DAPD.js.map} +1 -1
- package/dist/{chunk-2XMPJHCW.js → chunk-KOXWDM2E.js} +696 -245
- package/dist/chunk-KOXWDM2E.js.map +1 -0
- package/dist/{chunk-KU64CCSV.js → chunk-WSBRI47P.js} +38 -5
- package/dist/chunk-WSBRI47P.js.map +1 -0
- package/dist/{chunk-IVKT244I.js → chunk-XBMHUJYN.js} +180 -39
- package/dist/chunk-XBMHUJYN.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +8 -8
- package/package.json +1 -1
- package/dist/WorkflowsList-S2MGY2UT.js +0 -10
- package/dist/chunk-2XMPJHCW.js.map +0 -1
- package/dist/chunk-IVKT244I.js.map +0 -1
- package/dist/chunk-KU64CCSV.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Dialog as Dialog$1, DialogContent as DialogContent$1, DialogHeader as DialogHeader$1, DialogTitle as DialogTitle$1, DialogDescription as DialogDescription$1, Input as Input$1, DialogFooter } from './chunk-MRVS73S2.js';
|
|
2
2
|
import { Badge as Badge$1, Button } from './chunk-DBOMRIP5.js';
|
|
3
|
-
import { refetchStoreNodes, registerWorkflowNodeTypes, ensureNodeConfigsLoaded, onNodeTypesUpdate, NODE_TYPES, getNodeMetadata, AVAILABLE_NODES, useInsertNode, NODE_TYPE_DRAG_DATA_FORMAT, NODE_OPERATION_DRAG_DATA_FORMAT, useSaveWorkflow, STICKY_NOTE_TYPE, useNodeExecution, getNodeDetail,
|
|
3
|
+
import { refetchStoreNodes, registerWorkflowNodeTypes, ensureNodeConfigsLoaded, onNodeTypesUpdate, NODE_TYPES, getNodeMetadata, AVAILABLE_NODES, useInsertNode, NODE_TYPE_DRAG_DATA_FORMAT, NODE_OPERATION_DRAG_DATA_FORMAT, useSaveWorkflow, STICKY_NOTE_TYPE, useNodeExecution, getNodeDetail, mergeStickyNotes, buildStickyNode, ConnectionSelector, nodeAccent, NODES_METADATA, isNodeConfigsInitialized, NODE_CONFIGS, NODES, NodePropertyPanel, resolveInputHandles } from './chunk-XBMHUJYN.js';
|
|
4
4
|
import { createGlobalStoreClient, setGlobalStoreClient, resetGlobalStoreClient, getGlobalStoreClient } from './chunk-BQXHJIER.js';
|
|
5
5
|
import { BrowseWorkflowTemplatesDocument, InstallWorkflowNodeDocument, InstallPurchasedNodeDocument, GetMyNodeInstallationsDocument, BrowseWorkflowNodesDocument, UninstallWorkflowNodeDocument, CreateStoreOrderDocument } from './chunk-PNOA7CQV.js';
|
|
6
6
|
import { useLazyWorkflowDefinition, useCreateWorkflow, useWorkflowVersions, useRestoreWorkflowVersion, useActivateWorkflow, useDeleteWorkflow, useDeactivateWorkflow } from './chunk-NMS2QUXG.js';
|
|
7
|
-
import { useFlowStore } from './chunk-
|
|
7
|
+
import { useFlowStore } from './chunk-WSBRI47P.js';
|
|
8
8
|
import { SdkPermissionButton, FLUIDGRIDS_PERMISSIONS } from './chunk-UIY2HBWA.js';
|
|
9
9
|
import { cn } from './chunk-3ZYUGTIT.js';
|
|
10
10
|
import { throwIfResultError, NodeSchemaIntrospectionDocument, EventRegistrationsDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument } from './chunk-XEYNX7YJ.js';
|
|
@@ -2868,6 +2868,57 @@ var UninstallNodeDialog = ({
|
|
|
2868
2868
|
] })
|
|
2869
2869
|
] }) });
|
|
2870
2870
|
};
|
|
2871
|
+
|
|
2872
|
+
// src/builder/hooks/attach-node-helpers.ts
|
|
2873
|
+
var ATTACH_GAP_X = 120;
|
|
2874
|
+
var DEFAULT_NODE_WIDTH = 288;
|
|
2875
|
+
function computeAttachPosition(source) {
|
|
2876
|
+
if (!source) return void 0;
|
|
2877
|
+
const width = source.measured?.width ?? DEFAULT_NODE_WIDTH;
|
|
2878
|
+
return {
|
|
2879
|
+
x: source.position.x + width + ATTACH_GAP_X,
|
|
2880
|
+
y: source.position.y
|
|
2881
|
+
};
|
|
2882
|
+
}
|
|
2883
|
+
function firstInputHandleId(data) {
|
|
2884
|
+
return resolveInputHandles(data)[0]?.id ?? "target";
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2887
|
+
// src/builder/hooks/use-attach-store-node.ts
|
|
2888
|
+
function useAddNodeFromStore() {
|
|
2889
|
+
const { getNode } = useReactFlow();
|
|
2890
|
+
const insertNode = useInsertNode();
|
|
2891
|
+
return useCallback(
|
|
2892
|
+
(nodeType, operationName) => {
|
|
2893
|
+
const store = useFlowStore.getState();
|
|
2894
|
+
const pending = store.workflow.pendingConnection;
|
|
2895
|
+
if (!pending) {
|
|
2896
|
+
insertNode(nodeType, void 0, operationName);
|
|
2897
|
+
return { attached: false };
|
|
2898
|
+
}
|
|
2899
|
+
const source = getNode(pending.nodeId);
|
|
2900
|
+
const created = insertNode(
|
|
2901
|
+
nodeType,
|
|
2902
|
+
computeAttachPosition(source),
|
|
2903
|
+
operationName
|
|
2904
|
+
);
|
|
2905
|
+
if (created?.id && source) {
|
|
2906
|
+
store.actions.edges.onConnect({
|
|
2907
|
+
source: pending.nodeId,
|
|
2908
|
+
sourceHandle: pending.handleId,
|
|
2909
|
+
target: created.id,
|
|
2910
|
+
targetHandle: firstInputHandleId(
|
|
2911
|
+
created.data
|
|
2912
|
+
)
|
|
2913
|
+
});
|
|
2914
|
+
}
|
|
2915
|
+
store.actions.pendingConnection.clear();
|
|
2916
|
+
store.actions.sidebar.setActivePanel("none");
|
|
2917
|
+
return { attached: true };
|
|
2918
|
+
},
|
|
2919
|
+
[getNode, insertNode]
|
|
2920
|
+
);
|
|
2921
|
+
}
|
|
2871
2922
|
function isTriggerOperation(op) {
|
|
2872
2923
|
return op.role === "trigger" || !!op.delivery || op.type === "subscription";
|
|
2873
2924
|
}
|
|
@@ -2879,6 +2930,9 @@ function userSelectableOperations(ops) {
|
|
|
2879
2930
|
function StoreNodeOperations({ nodeType }) {
|
|
2880
2931
|
const [, bump] = useState(0);
|
|
2881
2932
|
useEffect(() => onNodeTypesUpdate(() => bump((n) => n + 1)), []);
|
|
2933
|
+
const pendingConnection = useFlowStore((s) => s.workflow.pendingConnection);
|
|
2934
|
+
const addNodeFromStore = useAddNodeFromStore();
|
|
2935
|
+
const attachMode = !!pendingConnection;
|
|
2882
2936
|
const config = nodeType ? NODE_CONFIGS.find((c) => c.type === nodeType) : void 0;
|
|
2883
2937
|
const operations = userSelectableOperations(
|
|
2884
2938
|
config?.operations
|
|
@@ -2893,6 +2947,13 @@ function StoreNodeOperations({ nodeType }) {
|
|
|
2893
2947
|
},
|
|
2894
2948
|
[nodeType]
|
|
2895
2949
|
);
|
|
2950
|
+
const handleClick = useCallback(
|
|
2951
|
+
(opName) => {
|
|
2952
|
+
if (!nodeType) return;
|
|
2953
|
+
addNodeFromStore(nodeType, opName);
|
|
2954
|
+
},
|
|
2955
|
+
[nodeType, addNodeFromStore]
|
|
2956
|
+
);
|
|
2896
2957
|
if (!nodeType) return null;
|
|
2897
2958
|
if (operations.length === 0) {
|
|
2898
2959
|
return /* @__PURE__ */ jsx("div", { className: "px-3 pt-3 pb-1", children: /* @__PURE__ */ jsxs(
|
|
@@ -2900,12 +2961,14 @@ function StoreNodeOperations({ nodeType }) {
|
|
|
2900
2961
|
{
|
|
2901
2962
|
draggable: true,
|
|
2902
2963
|
onDragStart: (e) => handleDragStart(e),
|
|
2903
|
-
|
|
2964
|
+
onClick: () => handleClick(),
|
|
2965
|
+
title: attachMode ? "Click to attach to the selected output" : "Click to add, or drag onto the canvas",
|
|
2904
2966
|
className: "w-full flex items-center gap-2.5 px-2 py-2 rounded-md hover:bg-muted/60 transition-colors text-left group",
|
|
2905
|
-
style: { cursor: "grab" },
|
|
2967
|
+
style: { cursor: attachMode ? "pointer" : "grab" },
|
|
2968
|
+
"data-testid": "store-op-add-to-canvas",
|
|
2906
2969
|
children: [
|
|
2907
2970
|
/* @__PURE__ */ jsx("div", { className: "size-7 shrink-0 rounded-md bg-muted flex items-center justify-center", children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:plus", className: "size-3.5 text-primary" }) }),
|
|
2908
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm font-medium text-foreground group-hover:text-primary transition-colors", children: "Add to canvas" }),
|
|
2971
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm font-medium text-foreground group-hover:text-primary transition-colors", children: attachMode ? "Attach to canvas" : "Add to canvas" }),
|
|
2909
2972
|
/* @__PURE__ */ jsx(
|
|
2910
2973
|
Icon,
|
|
2911
2974
|
{
|
|
@@ -2918,17 +2981,22 @@ function StoreNodeOperations({ nodeType }) {
|
|
|
2918
2981
|
) });
|
|
2919
2982
|
}
|
|
2920
2983
|
return /* @__PURE__ */ jsxs("div", { className: "px-3 pt-3 pb-1", children: [
|
|
2921
|
-
/* @__PURE__ */ jsx("p", { className: "px-1 pb-2 text-xs font-medium text-muted-foreground", children: "Operations \u2014
|
|
2984
|
+
/* @__PURE__ */ jsx("p", { className: "px-1 pb-2 text-xs font-medium text-muted-foreground", children: attachMode ? "Operations \u2014 click one to attach it" : "Operations \u2014 click to add, or drag onto the canvas" }),
|
|
2922
2985
|
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: operations.map((op) => {
|
|
2923
2986
|
const isTrigger = isTriggerOperation(op);
|
|
2987
|
+
const attachBlocked = attachMode && isTrigger;
|
|
2924
2988
|
return /* @__PURE__ */ jsxs(
|
|
2925
2989
|
"button",
|
|
2926
2990
|
{
|
|
2927
2991
|
draggable: true,
|
|
2928
2992
|
onDragStart: (e) => handleDragStart(e, op.name),
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2993
|
+
onClick: attachBlocked ? void 0 : () => handleClick(op.name),
|
|
2994
|
+
title: attachBlocked ? "Triggers start a flow \u2014 they can't be attached to an output" : attachMode ? `${op.name} \u2014 click to attach to the selected output` : `${op.name} \u2014 click to add, or drag onto the canvas`,
|
|
2995
|
+
className: `w-full flex items-center gap-2.5 px-2 py-2 rounded-md transition-colors text-left group ${attachBlocked ? "opacity-45" : "hover:bg-muted/60"}`,
|
|
2996
|
+
style: {
|
|
2997
|
+
cursor: attachBlocked ? "not-allowed" : attachMode ? "pointer" : "grab"
|
|
2998
|
+
},
|
|
2999
|
+
"data-testid": `store-op-${op.name}`,
|
|
2932
3000
|
children: [
|
|
2933
3001
|
/* @__PURE__ */ jsx("div", { className: "size-7 shrink-0 rounded-md bg-muted flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
2934
3002
|
Icon,
|
|
@@ -3345,6 +3413,65 @@ function StoreNodeDetail({ node, onBack }) {
|
|
|
3345
3413
|
)
|
|
3346
3414
|
] });
|
|
3347
3415
|
}
|
|
3416
|
+
function AttachModeBanner() {
|
|
3417
|
+
const pendingConnection = useFlowStore((s) => s.workflow.pendingConnection);
|
|
3418
|
+
const nodes = useFlowStore((s) => s.workflow.nodes);
|
|
3419
|
+
const clearPending = useFlowStore((s) => s.actions.pendingConnection.clear);
|
|
3420
|
+
if (!pendingConnection) return null;
|
|
3421
|
+
const source = nodes.find((n) => n.id === pendingConnection.nodeId);
|
|
3422
|
+
const data = source?.data;
|
|
3423
|
+
const sourceTitle = typeof data?.label === "string" && data.label || getNodeDetail(source?.type).title || pendingConnection.nodeId;
|
|
3424
|
+
const handleLabel = pendingConnection.handleId === "source" || pendingConnection.handleId === "output" ? void 0 : pendingConnection.handleId;
|
|
3425
|
+
return /* @__PURE__ */ jsx(
|
|
3426
|
+
"div",
|
|
3427
|
+
{
|
|
3428
|
+
className: "mx-3 mt-3 shrink-0 rounded-lg border px-3 py-2",
|
|
3429
|
+
style: {
|
|
3430
|
+
borderColor: "var(--color-status-info-border)",
|
|
3431
|
+
background: "var(--color-status-info-bgSubtle)"
|
|
3432
|
+
},
|
|
3433
|
+
"data-testid": "store-attach-banner",
|
|
3434
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3435
|
+
/* @__PURE__ */ jsx(
|
|
3436
|
+
Icon,
|
|
3437
|
+
{
|
|
3438
|
+
icon: "mynaui:git-branch",
|
|
3439
|
+
className: "size-4 shrink-0",
|
|
3440
|
+
style: { color: "var(--color-status-info-text)" }
|
|
3441
|
+
}
|
|
3442
|
+
),
|
|
3443
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
3444
|
+
/* @__PURE__ */ jsxs(
|
|
3445
|
+
"p",
|
|
3446
|
+
{
|
|
3447
|
+
className: "text-xs font-semibold leading-tight",
|
|
3448
|
+
style: { color: "var(--color-status-info-text)" },
|
|
3449
|
+
children: [
|
|
3450
|
+
"Attaching after \u201C",
|
|
3451
|
+
sourceTitle,
|
|
3452
|
+
"\u201D",
|
|
3453
|
+
handleLabel ? ` \u2192 ${handleLabel}` : ""
|
|
3454
|
+
]
|
|
3455
|
+
}
|
|
3456
|
+
),
|
|
3457
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "Click an operation below to add & connect it." })
|
|
3458
|
+
] }),
|
|
3459
|
+
/* @__PURE__ */ jsx(
|
|
3460
|
+
"button",
|
|
3461
|
+
{
|
|
3462
|
+
type: "button",
|
|
3463
|
+
"aria-label": "Cancel attach",
|
|
3464
|
+
title: "Cancel attach",
|
|
3465
|
+
onClick: clearPending,
|
|
3466
|
+
className: "shrink-0 rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
3467
|
+
"data-testid": "store-attach-cancel",
|
|
3468
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:close", className: "size-3.5" })
|
|
3469
|
+
}
|
|
3470
|
+
)
|
|
3471
|
+
] })
|
|
3472
|
+
}
|
|
3473
|
+
);
|
|
3474
|
+
}
|
|
3348
3475
|
function StoreBrowsePanel() {
|
|
3349
3476
|
const [view, setView] = useState({ type: "categories" });
|
|
3350
3477
|
const [globalSearch, setGlobalSearch] = useState("");
|
|
@@ -3370,6 +3497,7 @@ function StoreBrowsePanel() {
|
|
|
3370
3497
|
});
|
|
3371
3498
|
}, []);
|
|
3372
3499
|
return /* @__PURE__ */ jsxs(SidebarPanelWrapper, { children: [
|
|
3500
|
+
/* @__PURE__ */ jsx(AttachModeBanner, {}),
|
|
3373
3501
|
view.type === "categories" && /* @__PURE__ */ jsxs("div", { className: "px-4 pt-4 pb-2 shrink-0 flex items-center gap-2", children: [
|
|
3374
3502
|
/* @__PURE__ */ jsx("div", { className: "size-7 flex items-center justify-center rounded-lg bg-primary", children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:store", className: "size-4 text-white" }) }),
|
|
3375
3503
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -4075,7 +4203,7 @@ function DesktopSidebarFragment({
|
|
|
4075
4203
|
if (nodes) {
|
|
4076
4204
|
const requiredNodeTypes = [];
|
|
4077
4205
|
try {
|
|
4078
|
-
const { NODE_CONFIGS: NODE_CONFIGS3, ensureNodeConfigsLoaded: ensureNodeConfigsLoaded2 } = await import('./blocks-
|
|
4206
|
+
const { NODE_CONFIGS: NODE_CONFIGS3, ensureNodeConfigsLoaded: ensureNodeConfigsLoaded2 } = await import('./blocks-QKAWYAOT.js');
|
|
4079
4207
|
await ensureNodeConfigsLoaded2().catch(() => {
|
|
4080
4208
|
});
|
|
4081
4209
|
const workflowNodeTypes = [
|
|
@@ -12629,6 +12757,8 @@ function useWebhookRegistration(workflowKey, triggerNodeId, enabled = true) {
|
|
|
12629
12757
|
refetch: fetchData
|
|
12630
12758
|
};
|
|
12631
12759
|
}
|
|
12760
|
+
|
|
12761
|
+
// src/builder/components/ndv/use-node-config.ts
|
|
12632
12762
|
function coerceNumber(type, raw) {
|
|
12633
12763
|
if (raw.trim() === "") return void 0;
|
|
12634
12764
|
const n = type === "integer" ? parseInt(raw, 10) : parseFloat(raw);
|
|
@@ -12673,66 +12803,32 @@ function nodeSubtitle(node) {
|
|
|
12673
12803
|
const data = asRecord(node?.data);
|
|
12674
12804
|
return typeof data?.operation_name === "string" ? data.operation_name : void 0;
|
|
12675
12805
|
}
|
|
12676
|
-
|
|
12677
|
-
function NodeDetailView() {
|
|
12678
|
-
const ndv = useFlowStore((s) => s.workflow.ndv);
|
|
12806
|
+
function useNodeConfig(target, options) {
|
|
12679
12807
|
const nodes = useFlowStore((s) => s.workflow.nodes);
|
|
12680
12808
|
const edges = useFlowStore((s) => s.workflow.edges);
|
|
12681
|
-
const
|
|
12682
|
-
const
|
|
12683
|
-
(s) => s.actions.sidebar.showNodePropertiesOf
|
|
12684
|
-
);
|
|
12685
|
-
const open = !!ndv;
|
|
12809
|
+
const workflowKey = useFlowStore((s) => s.workflow.workflowKey);
|
|
12810
|
+
const nodeId = target?.nodeId;
|
|
12686
12811
|
const node = useMemo(
|
|
12687
|
-
() =>
|
|
12688
|
-
[
|
|
12812
|
+
() => nodeId ? nodes.find((n) => n.id === nodeId) : void 0,
|
|
12813
|
+
[nodeId, nodes]
|
|
12689
12814
|
);
|
|
12690
12815
|
const incoming = useMemo(
|
|
12691
|
-
() =>
|
|
12692
|
-
[edges,
|
|
12816
|
+
() => nodeId ? edges.filter((e) => e.target === nodeId) : [],
|
|
12817
|
+
[edges, nodeId]
|
|
12693
12818
|
);
|
|
12694
12819
|
const sourceIds = useMemo(() => incoming.map((e) => e.source), [incoming]);
|
|
12695
12820
|
const sourceKey = sourceIds.join(",");
|
|
12696
12821
|
const [selectedSource, setSelectedSource] = useState();
|
|
12697
|
-
const [tab, setTab] = useState("parameters");
|
|
12698
|
-
const [outputView, setOutputView] = useState("schema");
|
|
12699
12822
|
const [dragField, setDragField] = useState(null);
|
|
12700
12823
|
const [modeByField, setModeByField] = useState({});
|
|
12701
|
-
const panesRef = useRef(null);
|
|
12702
|
-
const dragCleanupRef = useRef(null);
|
|
12703
|
-
const [leftPct, setLeftPct] = useState(30);
|
|
12704
|
-
const [rightPct, setRightPct] = useState(30);
|
|
12705
|
-
const startDrag = (which) => (e) => {
|
|
12706
|
-
e.preventDefault();
|
|
12707
|
-
const el = panesRef.current;
|
|
12708
|
-
if (!el) return;
|
|
12709
|
-
const rect = el.getBoundingClientRect();
|
|
12710
|
-
const onMove = (ev) => {
|
|
12711
|
-
const pct = (ev.clientX - rect.left) / rect.width * 100;
|
|
12712
|
-
if (which === "left") setLeftPct(Math.min(55, Math.max(15, pct)));
|
|
12713
|
-
else setRightPct(Math.min(55, Math.max(15, 100 - pct)));
|
|
12714
|
-
};
|
|
12715
|
-
const cleanup = () => {
|
|
12716
|
-
window.removeEventListener("mousemove", onMove);
|
|
12717
|
-
window.removeEventListener("mouseup", cleanup);
|
|
12718
|
-
dragCleanupRef.current = null;
|
|
12719
|
-
};
|
|
12720
|
-
dragCleanupRef.current = cleanup;
|
|
12721
|
-
window.addEventListener("mousemove", onMove);
|
|
12722
|
-
window.addEventListener("mouseup", cleanup);
|
|
12723
|
-
};
|
|
12724
|
-
useEffect(() => () => dragCleanupRef.current?.(), []);
|
|
12725
12824
|
useEffect(() => {
|
|
12726
12825
|
setSelectedSource(
|
|
12727
12826
|
(prev) => prev && sourceIds.includes(prev) ? prev : sourceIds[0]
|
|
12728
12827
|
);
|
|
12729
|
-
}, [
|
|
12730
|
-
useEffect(() => {
|
|
12731
|
-
if (open) setTab("parameters");
|
|
12732
|
-
}, [open, ndv?.nodeId]);
|
|
12828
|
+
}, [nodeId, sourceKey, sourceIds]);
|
|
12733
12829
|
useEffect(() => {
|
|
12734
12830
|
setModeByField({});
|
|
12735
|
-
}, [
|
|
12831
|
+
}, [nodeId, selectedSource]);
|
|
12736
12832
|
const sourceNode = useMemo(
|
|
12737
12833
|
() => nodes.find((n) => n.id === selectedSource),
|
|
12738
12834
|
[nodes, selectedSource]
|
|
@@ -12762,11 +12858,10 @@ function NodeDetailView() {
|
|
|
12762
12858
|
() => !!asRecord(currentOp?.output_fields)?.webhookUrl,
|
|
12763
12859
|
[currentOp]
|
|
12764
12860
|
);
|
|
12765
|
-
const workflowKey = useFlowStore((s) => s.workflow.workflowKey);
|
|
12766
12861
|
const { webhookUrl, loading: webhookUrlLoading } = useWebhookRegistration(
|
|
12767
12862
|
workflowKey || void 0,
|
|
12768
12863
|
node?.id,
|
|
12769
|
-
isWebhookTrigger &&
|
|
12864
|
+
isWebhookTrigger && (options?.webhookEnabled ?? true)
|
|
12770
12865
|
);
|
|
12771
12866
|
const pickerFields = useMemo(() => flattenFields(inputFields), [inputFields]);
|
|
12772
12867
|
const mapping = currentEdge?.mapping?.definition ?? {};
|
|
@@ -12799,10 +12894,10 @@ function NodeDetailView() {
|
|
|
12799
12894
|
return fromList(args?.credentials, "id");
|
|
12800
12895
|
}, [node]);
|
|
12801
12896
|
const handleConnectionsChange = (connections) => {
|
|
12802
|
-
if (!
|
|
12897
|
+
if (!nodeId) return;
|
|
12803
12898
|
const store = useFlowStore.getState();
|
|
12804
12899
|
const next = store.workflow.nodes.map((n) => {
|
|
12805
|
-
if (n.id !==
|
|
12900
|
+
if (n.id !== nodeId) return n;
|
|
12806
12901
|
const data = { ...asRecord(n.data) ?? {} };
|
|
12807
12902
|
const args = { ...asRecord(data.args) ?? {} };
|
|
12808
12903
|
delete args.credentials;
|
|
@@ -12828,19 +12923,19 @@ function NodeDetailView() {
|
|
|
12828
12923
|
...e,
|
|
12829
12924
|
mapping: {
|
|
12830
12925
|
definition: def,
|
|
12831
|
-
comment: e.mapping?.comment ?? `Map ${selectedSource} \u2192 ${
|
|
12926
|
+
comment: e.mapping?.comment ?? `Map ${selectedSource} \u2192 ${nodeId ?? ""}`
|
|
12832
12927
|
}
|
|
12833
12928
|
};
|
|
12834
12929
|
});
|
|
12835
12930
|
store.actions.edges.setEdges(next);
|
|
12836
12931
|
};
|
|
12837
12932
|
const clearMappingFromAllIncoming = (field) => {
|
|
12838
|
-
if (!
|
|
12933
|
+
if (!nodeId) return;
|
|
12839
12934
|
const store = useFlowStore.getState();
|
|
12840
12935
|
const fresh = store.workflow.edges;
|
|
12841
12936
|
let changed = false;
|
|
12842
12937
|
const next = fresh.map((e) => {
|
|
12843
|
-
if (e.target !==
|
|
12938
|
+
if (e.target !== nodeId || !e.mapping?.definition) return e;
|
|
12844
12939
|
if (!(field in e.mapping.definition)) return e;
|
|
12845
12940
|
const def = { ...e.mapping.definition };
|
|
12846
12941
|
delete def[field];
|
|
@@ -12850,10 +12945,10 @@ function NodeDetailView() {
|
|
|
12850
12945
|
if (changed) store.actions.edges.setEdges(next);
|
|
12851
12946
|
};
|
|
12852
12947
|
const writeFixed = (field, value) => {
|
|
12853
|
-
if (!
|
|
12948
|
+
if (!nodeId) return;
|
|
12854
12949
|
const store = useFlowStore.getState();
|
|
12855
12950
|
const next = store.workflow.nodes.map((n) => {
|
|
12856
|
-
if (n.id !==
|
|
12951
|
+
if (n.id !== nodeId) return n;
|
|
12857
12952
|
const data = { ...asRecord(n.data) ?? {} };
|
|
12858
12953
|
const args = { ...asRecord(data.args) ?? {} };
|
|
12859
12954
|
const state = { ...asRecord(args.state) ?? {} };
|
|
@@ -12887,6 +12982,279 @@ function NodeDetailView() {
|
|
|
12887
12982
|
setModeByField((m) => ({ ...m, [field]: "expression" }));
|
|
12888
12983
|
}
|
|
12889
12984
|
};
|
|
12985
|
+
return {
|
|
12986
|
+
node,
|
|
12987
|
+
nodes,
|
|
12988
|
+
incoming,
|
|
12989
|
+
sourceIds,
|
|
12990
|
+
selectedSource,
|
|
12991
|
+
setSelectedSource,
|
|
12992
|
+
currentEdge,
|
|
12993
|
+
currentOp,
|
|
12994
|
+
params,
|
|
12995
|
+
argsState,
|
|
12996
|
+
mapping,
|
|
12997
|
+
inputFields,
|
|
12998
|
+
outputFields,
|
|
12999
|
+
pickerFields,
|
|
13000
|
+
connectionAdapters,
|
|
13001
|
+
selectedConnections,
|
|
13002
|
+
isWebhookTrigger,
|
|
13003
|
+
webhookUrl,
|
|
13004
|
+
webhookUrlLoading,
|
|
13005
|
+
modeByField,
|
|
13006
|
+
dragField,
|
|
13007
|
+
setDragField,
|
|
13008
|
+
writeFixed,
|
|
13009
|
+
writeMapping,
|
|
13010
|
+
handleConnectionsChange,
|
|
13011
|
+
toggleMode,
|
|
13012
|
+
handleDropOnParam
|
|
13013
|
+
};
|
|
13014
|
+
}
|
|
13015
|
+
var SECTION_LABEL2 = "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground";
|
|
13016
|
+
function NodeParamsForm({
|
|
13017
|
+
config,
|
|
13018
|
+
nodeType,
|
|
13019
|
+
testIdPrefix = "ndv"
|
|
13020
|
+
}) {
|
|
13021
|
+
const {
|
|
13022
|
+
params,
|
|
13023
|
+
argsState,
|
|
13024
|
+
mapping,
|
|
13025
|
+
pickerFields,
|
|
13026
|
+
connectionAdapters,
|
|
13027
|
+
selectedConnections,
|
|
13028
|
+
isWebhookTrigger,
|
|
13029
|
+
webhookUrl,
|
|
13030
|
+
webhookUrlLoading,
|
|
13031
|
+
currentEdge,
|
|
13032
|
+
modeByField,
|
|
13033
|
+
dragField,
|
|
13034
|
+
setDragField,
|
|
13035
|
+
writeFixed,
|
|
13036
|
+
writeMapping,
|
|
13037
|
+
handleConnectionsChange,
|
|
13038
|
+
toggleMode,
|
|
13039
|
+
handleDropOnParam
|
|
13040
|
+
} = config;
|
|
13041
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13042
|
+
isWebhookTrigger && /* @__PURE__ */ jsx(WebhookUrlField, { webhookUrl, loading: webhookUrlLoading }),
|
|
13043
|
+
connectionAdapters.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-2", "data-testid": `${testIdPrefix}-connections`, children: [
|
|
13044
|
+
/* @__PURE__ */ jsx("div", { className: SECTION_LABEL2, children: "Connections" }),
|
|
13045
|
+
/* @__PURE__ */ jsx(
|
|
13046
|
+
ConnectionSelector,
|
|
13047
|
+
{
|
|
13048
|
+
adapters: connectionAdapters,
|
|
13049
|
+
selectedConnections,
|
|
13050
|
+
onChange: handleConnectionsChange,
|
|
13051
|
+
compact: true
|
|
13052
|
+
}
|
|
13053
|
+
)
|
|
13054
|
+
] }),
|
|
13055
|
+
!currentEdge && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-dashed border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground", children: "No upstream node connected \u2014 set fixed values below, or connect a node to map fields with expressions." }),
|
|
13056
|
+
params.length === 0 ? /* @__PURE__ */ jsx("div", { className: "py-6 text-center text-xs text-muted-foreground", children: "This operation has no input parameters." }) : params.map((p) => {
|
|
13057
|
+
if (p.type === "condition") {
|
|
13058
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
13059
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground", children: p.name === "conditionTree" ? "Conditions" : p.name }),
|
|
13060
|
+
/* @__PURE__ */ jsx(
|
|
13061
|
+
ConditionTreeBuilder,
|
|
13062
|
+
{
|
|
13063
|
+
value: argsState[p.name],
|
|
13064
|
+
fields: pickerFields,
|
|
13065
|
+
onChange: (tree) => writeFixed(p.name, tree)
|
|
13066
|
+
}
|
|
13067
|
+
),
|
|
13068
|
+
p.description && /* @__PURE__ */ jsx("span", { className: "text-[11px] leading-snug text-muted-foreground", children: p.description })
|
|
13069
|
+
] }, p.name);
|
|
13070
|
+
}
|
|
13071
|
+
if (p.type === "switch-rules") {
|
|
13072
|
+
const rules = Array.isArray(argsState[p.name]) ? argsState[p.name] : [];
|
|
13073
|
+
const fallbackHandle = typeof argsState.fallbackHandle === "string" ? argsState.fallbackHandle : "default";
|
|
13074
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
13075
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground", children: "Routing rules" }),
|
|
13076
|
+
/* @__PURE__ */ jsx(
|
|
13077
|
+
SwitchRulesEditor,
|
|
13078
|
+
{
|
|
13079
|
+
rules,
|
|
13080
|
+
fallbackHandle,
|
|
13081
|
+
fields: pickerFields,
|
|
13082
|
+
onChange: (next) => {
|
|
13083
|
+
writeFixed(p.name, next.rules);
|
|
13084
|
+
writeFixed("cases", casesFromRules(next.rules));
|
|
13085
|
+
writeFixed("fallbackHandle", next.fallbackHandle);
|
|
13086
|
+
}
|
|
13087
|
+
}
|
|
13088
|
+
)
|
|
13089
|
+
] }, p.name);
|
|
13090
|
+
}
|
|
13091
|
+
const mode = modeByField[p.name] ?? (mapping[p.name] !== void 0 ? "expression" : "fixed");
|
|
13092
|
+
const exprValue = mapping[p.name] ?? "";
|
|
13093
|
+
const fixedValue = argsState[p.name];
|
|
13094
|
+
const isCodeParam = p.type === "code" || nodeType === "internal:code" && p.name === "code";
|
|
13095
|
+
const highlight = dragField === p.name;
|
|
13096
|
+
const inputCx = cn$1(
|
|
13097
|
+
"w-full rounded-md border bg-background px-2.5 py-1.5 text-sm outline-none transition-colors disabled:opacity-50",
|
|
13098
|
+
highlight ? "border-primary ring-1 ring-primary" : "border-input focus:border-primary"
|
|
13099
|
+
);
|
|
13100
|
+
return /* @__PURE__ */ jsxs(
|
|
13101
|
+
"div",
|
|
13102
|
+
{
|
|
13103
|
+
className: "flex flex-col gap-1.5",
|
|
13104
|
+
onDragOver: (e) => e.preventDefault(),
|
|
13105
|
+
onDragEnter: () => setDragField(p.name),
|
|
13106
|
+
onDragLeave: () => setDragField((f) => f === p.name ? null : f),
|
|
13107
|
+
onDrop: handleDropOnParam(p.name),
|
|
13108
|
+
children: [
|
|
13109
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
13110
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground", children: p.name }),
|
|
13111
|
+
p.required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" }),
|
|
13112
|
+
/* @__PURE__ */ jsx("span", { className: "ml-auto text-[10px] uppercase tracking-wide text-muted-foreground", children: p.type }),
|
|
13113
|
+
/* @__PURE__ */ jsx(
|
|
13114
|
+
"button",
|
|
13115
|
+
{
|
|
13116
|
+
type: "button",
|
|
13117
|
+
onClick: () => toggleMode(p.name, mode),
|
|
13118
|
+
title: mode === "expression" ? "Switch to a fixed value" : "Switch to an expression",
|
|
13119
|
+
"data-testid": `${testIdPrefix}-mode-${p.name}`,
|
|
13120
|
+
className: cn$1(
|
|
13121
|
+
"ml-1 rounded p-0.5 hover:text-foreground",
|
|
13122
|
+
mode === "expression" ? "text-primary" : "text-muted-foreground"
|
|
13123
|
+
),
|
|
13124
|
+
children: /* @__PURE__ */ jsx(
|
|
13125
|
+
Icon,
|
|
13126
|
+
{
|
|
13127
|
+
icon: mode === "expression" ? "mdi:variable" : "mdi:form-textbox",
|
|
13128
|
+
className: "size-3.5"
|
|
13129
|
+
}
|
|
13130
|
+
)
|
|
13131
|
+
}
|
|
13132
|
+
)
|
|
13133
|
+
] }),
|
|
13134
|
+
mode === "expression" ? /* @__PURE__ */ jsx(
|
|
13135
|
+
"input",
|
|
13136
|
+
{
|
|
13137
|
+
type: "text",
|
|
13138
|
+
value: exprValue,
|
|
13139
|
+
placeholder: currentEdge ? "Drop a field or type ${output.\u2026}" : "Connect an upstream node to use expressions",
|
|
13140
|
+
disabled: !currentEdge,
|
|
13141
|
+
onChange: (e) => writeMapping(p.name, e.target.value),
|
|
13142
|
+
"data-testid": `${testIdPrefix}-param-${p.name}`,
|
|
13143
|
+
className: cn$1(inputCx, "font-mono text-primary")
|
|
13144
|
+
}
|
|
13145
|
+
) : isCodeParam ? /* @__PURE__ */ jsx(
|
|
13146
|
+
CodeEditorField,
|
|
13147
|
+
{
|
|
13148
|
+
value: typeof fixedValue === "string" ? fixedValue : "",
|
|
13149
|
+
language: normalizeCodeLanguage(
|
|
13150
|
+
argsState.runtime ?? params.find((f) => f.name === "runtime")?.defaultValue
|
|
13151
|
+
),
|
|
13152
|
+
placeholder: typeof p.defaultValue === "string" ? p.defaultValue : p.description,
|
|
13153
|
+
onChange: (v) => writeFixed(p.name, v),
|
|
13154
|
+
"data-testid": `${testIdPrefix}-param-${p.name}`
|
|
13155
|
+
}
|
|
13156
|
+
) : p.type === "boolean" ? /* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
|
|
13157
|
+
/* @__PURE__ */ jsx(
|
|
13158
|
+
"input",
|
|
13159
|
+
{
|
|
13160
|
+
type: "checkbox",
|
|
13161
|
+
checked: fixedValue === true,
|
|
13162
|
+
onChange: (e) => writeFixed(p.name, e.target.checked),
|
|
13163
|
+
"data-testid": `${testIdPrefix}-param-${p.name}`,
|
|
13164
|
+
className: "size-4"
|
|
13165
|
+
}
|
|
13166
|
+
),
|
|
13167
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: fixedValue === void 0 ? "Not set (default)" : fixedValue === true ? "true" : "false" })
|
|
13168
|
+
] }) : p.options && p.options.length > 0 ? /* @__PURE__ */ jsxs(
|
|
13169
|
+
"select",
|
|
13170
|
+
{
|
|
13171
|
+
value: typeof fixedValue === "string" ? fixedValue : "",
|
|
13172
|
+
onChange: (e) => writeFixed(p.name, e.target.value),
|
|
13173
|
+
"data-testid": `${testIdPrefix}-param-${p.name}`,
|
|
13174
|
+
className: inputCx,
|
|
13175
|
+
children: [
|
|
13176
|
+
/* @__PURE__ */ jsx("option", { value: "", children: p.defaultValue !== void 0 ? `Default (${String(p.defaultValue)})` : "Select\u2026" }),
|
|
13177
|
+
p.options.map((o) => /* @__PURE__ */ jsx("option", { value: o, children: o }, o))
|
|
13178
|
+
]
|
|
13179
|
+
}
|
|
13180
|
+
) : p.type === "integer" || p.type === "number" ? /* @__PURE__ */ jsx(
|
|
13181
|
+
"input",
|
|
13182
|
+
{
|
|
13183
|
+
type: "number",
|
|
13184
|
+
step: p.type === "integer" ? "1" : "any",
|
|
13185
|
+
value: typeof fixedValue === "number" ? String(fixedValue) : "",
|
|
13186
|
+
placeholder: p.defaultValue !== void 0 ? `Default: ${String(p.defaultValue)}` : "Enter a number",
|
|
13187
|
+
onChange: (e) => writeFixed(p.name, coerceNumber(p.type, e.target.value)),
|
|
13188
|
+
"data-testid": `${testIdPrefix}-param-${p.name}`,
|
|
13189
|
+
className: inputCx
|
|
13190
|
+
}
|
|
13191
|
+
) : /* @__PURE__ */ jsx(
|
|
13192
|
+
"input",
|
|
13193
|
+
{
|
|
13194
|
+
type: "text",
|
|
13195
|
+
value: fixedValue === void 0 || fixedValue === null ? "" : String(fixedValue),
|
|
13196
|
+
placeholder: p.defaultValue !== void 0 ? `Default: ${String(p.defaultValue)}` : "Enter a value",
|
|
13197
|
+
onChange: (e) => writeFixed(p.name, e.target.value),
|
|
13198
|
+
"data-testid": `${testIdPrefix}-param-${p.name}`,
|
|
13199
|
+
className: inputCx
|
|
13200
|
+
}
|
|
13201
|
+
),
|
|
13202
|
+
p.description && /* @__PURE__ */ jsx("span", { className: "text-[11px] leading-snug text-muted-foreground", children: p.description })
|
|
13203
|
+
]
|
|
13204
|
+
},
|
|
13205
|
+
p.name
|
|
13206
|
+
);
|
|
13207
|
+
})
|
|
13208
|
+
] });
|
|
13209
|
+
}
|
|
13210
|
+
var SECTION_LABEL3 = "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground";
|
|
13211
|
+
function NodeDetailView() {
|
|
13212
|
+
const ndv = useFlowStore((s) => s.workflow.ndv);
|
|
13213
|
+
const closeNdv = useFlowStore((s) => s.actions.ndv.close);
|
|
13214
|
+
const showNodePropertiesOf = useFlowStore(
|
|
13215
|
+
(s) => s.actions.sidebar.showNodePropertiesOf
|
|
13216
|
+
);
|
|
13217
|
+
const open = !!ndv;
|
|
13218
|
+
const config = useNodeConfig(ndv ?? null, { webhookEnabled: open });
|
|
13219
|
+
const {
|
|
13220
|
+
node,
|
|
13221
|
+
nodes,
|
|
13222
|
+
sourceIds,
|
|
13223
|
+
selectedSource,
|
|
13224
|
+
setSelectedSource,
|
|
13225
|
+
currentOp,
|
|
13226
|
+
inputFields,
|
|
13227
|
+
outputFields
|
|
13228
|
+
} = config;
|
|
13229
|
+
const [tab, setTab] = useState("parameters");
|
|
13230
|
+
const [outputView, setOutputView] = useState("schema");
|
|
13231
|
+
const panesRef = useRef(null);
|
|
13232
|
+
const dragCleanupRef = useRef(null);
|
|
13233
|
+
const [leftPct, setLeftPct] = useState(30);
|
|
13234
|
+
const [rightPct, setRightPct] = useState(30);
|
|
13235
|
+
const startDrag = (which) => (e) => {
|
|
13236
|
+
e.preventDefault();
|
|
13237
|
+
const el = panesRef.current;
|
|
13238
|
+
if (!el) return;
|
|
13239
|
+
const rect = el.getBoundingClientRect();
|
|
13240
|
+
const onMove = (ev) => {
|
|
13241
|
+
const pct = (ev.clientX - rect.left) / rect.width * 100;
|
|
13242
|
+
if (which === "left") setLeftPct(Math.min(55, Math.max(15, pct)));
|
|
13243
|
+
else setRightPct(Math.min(55, Math.max(15, 100 - pct)));
|
|
13244
|
+
};
|
|
13245
|
+
const cleanup = () => {
|
|
13246
|
+
window.removeEventListener("mousemove", onMove);
|
|
13247
|
+
window.removeEventListener("mouseup", cleanup);
|
|
13248
|
+
dragCleanupRef.current = null;
|
|
13249
|
+
};
|
|
13250
|
+
dragCleanupRef.current = cleanup;
|
|
13251
|
+
window.addEventListener("mousemove", onMove);
|
|
13252
|
+
window.addEventListener("mouseup", cleanup);
|
|
13253
|
+
};
|
|
13254
|
+
useEffect(() => () => dragCleanupRef.current?.(), []);
|
|
13255
|
+
useEffect(() => {
|
|
13256
|
+
if (open) setTab("parameters");
|
|
13257
|
+
}, [open, ndv?.nodeId]);
|
|
12890
13258
|
const openClassicPanel = () => {
|
|
12891
13259
|
if (!ndv) return;
|
|
12892
13260
|
showNodePropertiesOf({
|
|
@@ -12944,7 +13312,7 @@ function NodeDetailView() {
|
|
|
12944
13312
|
className: "flex min-h-0 min-w-[180px] flex-col bg-card/40",
|
|
12945
13313
|
children: [
|
|
12946
13314
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-2.5", children: [
|
|
12947
|
-
/* @__PURE__ */ jsx("span", { className:
|
|
13315
|
+
/* @__PURE__ */ jsx("span", { className: SECTION_LABEL3, children: "Input" }),
|
|
12948
13316
|
sourceIds.length > 0 && /* @__PURE__ */ jsx(
|
|
12949
13317
|
"select",
|
|
12950
13318
|
{
|
|
@@ -12997,188 +13365,19 @@ function NodeDetailView() {
|
|
|
12997
13365
|
}
|
|
12998
13366
|
)
|
|
12999
13367
|
] }),
|
|
13000
|
-
tab === "parameters" ? /* @__PURE__ */
|
|
13368
|
+
tab === "parameters" ? /* @__PURE__ */ jsx(
|
|
13001
13369
|
"div",
|
|
13002
13370
|
{
|
|
13003
13371
|
className: "min-h-0 flex-1 space-y-4 overflow-auto p-4",
|
|
13004
13372
|
"data-testid": "ndv-params",
|
|
13005
|
-
children:
|
|
13006
|
-
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
connectionAdapters.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-2", "data-testid": "ndv-connections", children: [
|
|
13014
|
-
/* @__PURE__ */ jsx("div", { className: SECTION_LABEL2, children: "Connections" }),
|
|
13015
|
-
/* @__PURE__ */ jsx(
|
|
13016
|
-
ConnectionSelector,
|
|
13017
|
-
{
|
|
13018
|
-
adapters: connectionAdapters,
|
|
13019
|
-
selectedConnections,
|
|
13020
|
-
onChange: handleConnectionsChange,
|
|
13021
|
-
compact: true
|
|
13022
|
-
}
|
|
13023
|
-
)
|
|
13024
|
-
] }),
|
|
13025
|
-
!currentEdge && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-dashed border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground", children: "No upstream node connected \u2014 set fixed values below, or connect a node to map fields with expressions." }),
|
|
13026
|
-
params.length === 0 ? /* @__PURE__ */ jsx("div", { className: "py-6 text-center text-xs text-muted-foreground", children: "This operation has no input parameters." }) : params.map((p) => {
|
|
13027
|
-
if (p.type === "condition") {
|
|
13028
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
13029
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground", children: p.name === "conditionTree" ? "Conditions" : p.name }),
|
|
13030
|
-
/* @__PURE__ */ jsx(
|
|
13031
|
-
ConditionTreeBuilder,
|
|
13032
|
-
{
|
|
13033
|
-
value: argsState[p.name],
|
|
13034
|
-
fields: pickerFields,
|
|
13035
|
-
onChange: (tree) => writeFixed(p.name, tree)
|
|
13036
|
-
}
|
|
13037
|
-
),
|
|
13038
|
-
p.description && /* @__PURE__ */ jsx("span", { className: "text-[11px] leading-snug text-muted-foreground", children: p.description })
|
|
13039
|
-
] }, p.name);
|
|
13040
|
-
}
|
|
13041
|
-
if (p.type === "switch-rules") {
|
|
13042
|
-
const rules = Array.isArray(argsState[p.name]) ? argsState[p.name] : [];
|
|
13043
|
-
const fallbackHandle = typeof argsState.fallbackHandle === "string" ? argsState.fallbackHandle : "default";
|
|
13044
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
13045
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground", children: "Routing rules" }),
|
|
13046
|
-
/* @__PURE__ */ jsx(
|
|
13047
|
-
SwitchRulesEditor,
|
|
13048
|
-
{
|
|
13049
|
-
rules,
|
|
13050
|
-
fallbackHandle,
|
|
13051
|
-
fields: pickerFields,
|
|
13052
|
-
onChange: (next) => {
|
|
13053
|
-
writeFixed(p.name, next.rules);
|
|
13054
|
-
writeFixed("cases", casesFromRules(next.rules));
|
|
13055
|
-
writeFixed("fallbackHandle", next.fallbackHandle);
|
|
13056
|
-
}
|
|
13057
|
-
}
|
|
13058
|
-
)
|
|
13059
|
-
] }, p.name);
|
|
13060
|
-
}
|
|
13061
|
-
const mode = modeByField[p.name] ?? (mapping[p.name] !== void 0 ? "expression" : "fixed");
|
|
13062
|
-
const exprValue = mapping[p.name] ?? "";
|
|
13063
|
-
const fixedValue = argsState[p.name];
|
|
13064
|
-
const isCodeParam = p.type === "code" || node?.type === "internal:code" && p.name === "code";
|
|
13065
|
-
const highlight = dragField === p.name;
|
|
13066
|
-
const inputCx = cn$1(
|
|
13067
|
-
"w-full rounded-md border bg-background px-2.5 py-1.5 text-sm outline-none transition-colors disabled:opacity-50",
|
|
13068
|
-
highlight ? "border-primary ring-1 ring-primary" : "border-input focus:border-primary"
|
|
13069
|
-
);
|
|
13070
|
-
return /* @__PURE__ */ jsxs(
|
|
13071
|
-
"div",
|
|
13072
|
-
{
|
|
13073
|
-
className: "flex flex-col gap-1.5",
|
|
13074
|
-
onDragOver: (e) => e.preventDefault(),
|
|
13075
|
-
onDragEnter: () => setDragField(p.name),
|
|
13076
|
-
onDragLeave: () => setDragField((f) => f === p.name ? null : f),
|
|
13077
|
-
onDrop: handleDropOnParam(p.name),
|
|
13078
|
-
children: [
|
|
13079
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
13080
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground", children: p.name }),
|
|
13081
|
-
p.required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" }),
|
|
13082
|
-
/* @__PURE__ */ jsx("span", { className: "ml-auto text-[10px] uppercase tracking-wide text-muted-foreground", children: p.type }),
|
|
13083
|
-
/* @__PURE__ */ jsx(
|
|
13084
|
-
"button",
|
|
13085
|
-
{
|
|
13086
|
-
type: "button",
|
|
13087
|
-
onClick: () => toggleMode(p.name, mode),
|
|
13088
|
-
title: mode === "expression" ? "Switch to a fixed value" : "Switch to an expression",
|
|
13089
|
-
"data-testid": `ndv-mode-${p.name}`,
|
|
13090
|
-
className: cn$1(
|
|
13091
|
-
"ml-1 rounded p-0.5 hover:text-foreground",
|
|
13092
|
-
mode === "expression" ? "text-primary" : "text-muted-foreground"
|
|
13093
|
-
),
|
|
13094
|
-
children: /* @__PURE__ */ jsx(
|
|
13095
|
-
Icon,
|
|
13096
|
-
{
|
|
13097
|
-
icon: mode === "expression" ? "mdi:variable" : "mdi:form-textbox",
|
|
13098
|
-
className: "size-3.5"
|
|
13099
|
-
}
|
|
13100
|
-
)
|
|
13101
|
-
}
|
|
13102
|
-
)
|
|
13103
|
-
] }),
|
|
13104
|
-
mode === "expression" ? /* @__PURE__ */ jsx(
|
|
13105
|
-
"input",
|
|
13106
|
-
{
|
|
13107
|
-
type: "text",
|
|
13108
|
-
value: exprValue,
|
|
13109
|
-
placeholder: currentEdge ? "Drop a field or type ${output.\u2026}" : "Connect an upstream node to use expressions",
|
|
13110
|
-
disabled: !currentEdge,
|
|
13111
|
-
onChange: (e) => writeMapping(p.name, e.target.value),
|
|
13112
|
-
"data-testid": `ndv-param-${p.name}`,
|
|
13113
|
-
className: cn$1(inputCx, "font-mono text-primary")
|
|
13114
|
-
}
|
|
13115
|
-
) : isCodeParam ? /* @__PURE__ */ jsx(
|
|
13116
|
-
CodeEditorField,
|
|
13117
|
-
{
|
|
13118
|
-
value: typeof fixedValue === "string" ? fixedValue : "",
|
|
13119
|
-
language: normalizeCodeLanguage(
|
|
13120
|
-
argsState.runtime ?? params.find((f) => f.name === "runtime")?.defaultValue
|
|
13121
|
-
),
|
|
13122
|
-
placeholder: typeof p.defaultValue === "string" ? p.defaultValue : p.description,
|
|
13123
|
-
onChange: (v) => writeFixed(p.name, v),
|
|
13124
|
-
"data-testid": `ndv-param-${p.name}`
|
|
13125
|
-
}
|
|
13126
|
-
) : p.type === "boolean" ? /* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
|
|
13127
|
-
/* @__PURE__ */ jsx(
|
|
13128
|
-
"input",
|
|
13129
|
-
{
|
|
13130
|
-
type: "checkbox",
|
|
13131
|
-
checked: fixedValue === true,
|
|
13132
|
-
onChange: (e) => writeFixed(p.name, e.target.checked),
|
|
13133
|
-
"data-testid": `ndv-param-${p.name}`,
|
|
13134
|
-
className: "size-4"
|
|
13135
|
-
}
|
|
13136
|
-
),
|
|
13137
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: fixedValue === void 0 ? "Not set (default)" : fixedValue === true ? "true" : "false" })
|
|
13138
|
-
] }) : p.options && p.options.length > 0 ? /* @__PURE__ */ jsxs(
|
|
13139
|
-
"select",
|
|
13140
|
-
{
|
|
13141
|
-
value: typeof fixedValue === "string" ? fixedValue : "",
|
|
13142
|
-
onChange: (e) => writeFixed(p.name, e.target.value),
|
|
13143
|
-
"data-testid": `ndv-param-${p.name}`,
|
|
13144
|
-
className: inputCx,
|
|
13145
|
-
children: [
|
|
13146
|
-
/* @__PURE__ */ jsx("option", { value: "", children: p.defaultValue !== void 0 ? `Default (${String(p.defaultValue)})` : "Select\u2026" }),
|
|
13147
|
-
p.options.map((o) => /* @__PURE__ */ jsx("option", { value: o, children: o }, o))
|
|
13148
|
-
]
|
|
13149
|
-
}
|
|
13150
|
-
) : p.type === "integer" || p.type === "number" ? /* @__PURE__ */ jsx(
|
|
13151
|
-
"input",
|
|
13152
|
-
{
|
|
13153
|
-
type: "number",
|
|
13154
|
-
step: p.type === "integer" ? "1" : "any",
|
|
13155
|
-
value: typeof fixedValue === "number" ? String(fixedValue) : "",
|
|
13156
|
-
placeholder: p.defaultValue !== void 0 ? `Default: ${String(p.defaultValue)}` : "Enter a number",
|
|
13157
|
-
onChange: (e) => writeFixed(
|
|
13158
|
-
p.name,
|
|
13159
|
-
coerceNumber(p.type, e.target.value)
|
|
13160
|
-
),
|
|
13161
|
-
"data-testid": `ndv-param-${p.name}`,
|
|
13162
|
-
className: inputCx
|
|
13163
|
-
}
|
|
13164
|
-
) : /* @__PURE__ */ jsx(
|
|
13165
|
-
"input",
|
|
13166
|
-
{
|
|
13167
|
-
type: "text",
|
|
13168
|
-
value: fixedValue === void 0 || fixedValue === null ? "" : String(fixedValue),
|
|
13169
|
-
placeholder: p.defaultValue !== void 0 ? `Default: ${String(p.defaultValue)}` : "Enter a value",
|
|
13170
|
-
onChange: (e) => writeFixed(p.name, e.target.value),
|
|
13171
|
-
"data-testid": `ndv-param-${p.name}`,
|
|
13172
|
-
className: inputCx
|
|
13173
|
-
}
|
|
13174
|
-
),
|
|
13175
|
-
p.description && /* @__PURE__ */ jsx("span", { className: "text-[11px] leading-snug text-muted-foreground", children: p.description })
|
|
13176
|
-
]
|
|
13177
|
-
},
|
|
13178
|
-
p.name
|
|
13179
|
-
);
|
|
13180
|
-
})
|
|
13181
|
-
]
|
|
13373
|
+
children: /* @__PURE__ */ jsx(
|
|
13374
|
+
NodeParamsForm,
|
|
13375
|
+
{
|
|
13376
|
+
config,
|
|
13377
|
+
nodeType: node?.type,
|
|
13378
|
+
testIdPrefix: "ndv"
|
|
13379
|
+
}
|
|
13380
|
+
)
|
|
13182
13381
|
}
|
|
13183
13382
|
) : /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto p-4 text-xs text-muted-foreground", children: "No additional settings for this node." })
|
|
13184
13383
|
] }),
|
|
@@ -13190,7 +13389,7 @@ function NodeDetailView() {
|
|
|
13190
13389
|
className: "flex min-h-0 min-w-[180px] flex-col bg-card/40",
|
|
13191
13390
|
children: [
|
|
13192
13391
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-2.5", children: [
|
|
13193
|
-
/* @__PURE__ */ jsx("span", { className:
|
|
13392
|
+
/* @__PURE__ */ jsx("span", { className: SECTION_LABEL3, children: "Output" }),
|
|
13194
13393
|
outputFields.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
13195
13394
|
/* @__PURE__ */ jsx(
|
|
13196
13395
|
ToggleChip,
|
|
@@ -13292,6 +13491,255 @@ function EmptyState({
|
|
|
13292
13491
|
/* @__PURE__ */ jsx("div", { className: "max-w-[14rem] text-xs text-muted-foreground", children: hint })
|
|
13293
13492
|
] });
|
|
13294
13493
|
}
|
|
13494
|
+
var PANEL_WIDTH = 380;
|
|
13495
|
+
var PANEL_EST_HEIGHT = 480;
|
|
13496
|
+
var MAPPER_WIDTH = 260;
|
|
13497
|
+
var VIEWPORT_MARGIN = 12;
|
|
13498
|
+
function clampToViewport(pos) {
|
|
13499
|
+
const maxX = window.innerWidth - PANEL_WIDTH - VIEWPORT_MARGIN;
|
|
13500
|
+
const maxY = window.innerHeight - PANEL_EST_HEIGHT - VIEWPORT_MARGIN;
|
|
13501
|
+
return {
|
|
13502
|
+
x: Math.min(
|
|
13503
|
+
Math.max(VIEWPORT_MARGIN, pos.x),
|
|
13504
|
+
Math.max(VIEWPORT_MARGIN, maxX)
|
|
13505
|
+
),
|
|
13506
|
+
y: Math.min(
|
|
13507
|
+
Math.max(VIEWPORT_MARGIN, pos.y),
|
|
13508
|
+
Math.max(VIEWPORT_MARGIN, maxY)
|
|
13509
|
+
)
|
|
13510
|
+
};
|
|
13511
|
+
}
|
|
13512
|
+
function QuickConfigPanel() {
|
|
13513
|
+
const quickConfig = useFlowStore((s) => s.workflow.quickConfig);
|
|
13514
|
+
if (!quickConfig) return null;
|
|
13515
|
+
return (
|
|
13516
|
+
// Remount per node so panel position/flyout state reset naturally.
|
|
13517
|
+
/* @__PURE__ */ jsx(
|
|
13518
|
+
QuickConfigPanelInner,
|
|
13519
|
+
{
|
|
13520
|
+
nodeId: quickConfig.nodeId,
|
|
13521
|
+
type: quickConfig.type,
|
|
13522
|
+
anchor: quickConfig.anchor
|
|
13523
|
+
},
|
|
13524
|
+
quickConfig.nodeId
|
|
13525
|
+
)
|
|
13526
|
+
);
|
|
13527
|
+
}
|
|
13528
|
+
function QuickConfigPanelInner({
|
|
13529
|
+
nodeId,
|
|
13530
|
+
type,
|
|
13531
|
+
anchor
|
|
13532
|
+
}) {
|
|
13533
|
+
const close = useFlowStore((s) => s.actions.quickConfig.close);
|
|
13534
|
+
const openNdv = useFlowStore((s) => s.actions.ndv.open);
|
|
13535
|
+
const config = useNodeConfig({ nodeId});
|
|
13536
|
+
const {
|
|
13537
|
+
node,
|
|
13538
|
+
nodes,
|
|
13539
|
+
sourceIds,
|
|
13540
|
+
selectedSource,
|
|
13541
|
+
setSelectedSource,
|
|
13542
|
+
inputFields
|
|
13543
|
+
} = config;
|
|
13544
|
+
const [pos, setPos] = useState(
|
|
13545
|
+
() => clampToViewport(
|
|
13546
|
+
anchor ?? {
|
|
13547
|
+
x: window.innerWidth / 2 - PANEL_WIDTH / 2,
|
|
13548
|
+
y: window.innerHeight / 4
|
|
13549
|
+
}
|
|
13550
|
+
)
|
|
13551
|
+
);
|
|
13552
|
+
const [showMapper, setShowMapper] = useState(false);
|
|
13553
|
+
const dragStateRef = useRef(null);
|
|
13554
|
+
const handleHeaderPointerDown = useCallback(
|
|
13555
|
+
(e) => {
|
|
13556
|
+
if (e.target.closest("button")) return;
|
|
13557
|
+
dragStateRef.current = {
|
|
13558
|
+
startX: e.clientX,
|
|
13559
|
+
startY: e.clientY,
|
|
13560
|
+
baseX: pos.x,
|
|
13561
|
+
baseY: pos.y
|
|
13562
|
+
};
|
|
13563
|
+
const onMove = (ev) => {
|
|
13564
|
+
const s = dragStateRef.current;
|
|
13565
|
+
if (!s) return;
|
|
13566
|
+
setPos(
|
|
13567
|
+
clampToViewport({
|
|
13568
|
+
x: s.baseX + (ev.clientX - s.startX),
|
|
13569
|
+
y: s.baseY + (ev.clientY - s.startY)
|
|
13570
|
+
})
|
|
13571
|
+
);
|
|
13572
|
+
};
|
|
13573
|
+
const onUp = () => {
|
|
13574
|
+
dragStateRef.current = null;
|
|
13575
|
+
window.removeEventListener("pointermove", onMove);
|
|
13576
|
+
window.removeEventListener("pointerup", onUp);
|
|
13577
|
+
};
|
|
13578
|
+
window.addEventListener("pointermove", onMove);
|
|
13579
|
+
window.addEventListener("pointerup", onUp);
|
|
13580
|
+
},
|
|
13581
|
+
[pos.x, pos.y]
|
|
13582
|
+
);
|
|
13583
|
+
useEffect(() => {
|
|
13584
|
+
const onKey = (e) => {
|
|
13585
|
+
if (e.key === "Escape") close();
|
|
13586
|
+
};
|
|
13587
|
+
window.addEventListener("keydown", onKey);
|
|
13588
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
13589
|
+
}, [close]);
|
|
13590
|
+
useEffect(() => {
|
|
13591
|
+
if (!nodes.some((n) => n.id === nodeId)) close();
|
|
13592
|
+
}, [nodes, nodeId, close]);
|
|
13593
|
+
if (!node) return null;
|
|
13594
|
+
const meta = getNodeDetail(node.type);
|
|
13595
|
+
const accent = nodeAccent(node.type || meta.title);
|
|
13596
|
+
const subtitle = nodeSubtitle(node);
|
|
13597
|
+
const expandToNdv = () => {
|
|
13598
|
+
openNdv({ nodeId, type });
|
|
13599
|
+
};
|
|
13600
|
+
return /* @__PURE__ */ jsxs(
|
|
13601
|
+
"div",
|
|
13602
|
+
{
|
|
13603
|
+
className: "fixed",
|
|
13604
|
+
style: { left: pos.x, top: pos.y, zIndex: 300, width: PANEL_WIDTH },
|
|
13605
|
+
"data-testid": "quick-config-panel",
|
|
13606
|
+
children: [
|
|
13607
|
+
showMapper && /* @__PURE__ */ jsxs(
|
|
13608
|
+
"div",
|
|
13609
|
+
{
|
|
13610
|
+
className: "absolute overflow-hidden rounded-xl border border-border bg-card shadow-xl",
|
|
13611
|
+
style: {
|
|
13612
|
+
right: "100%",
|
|
13613
|
+
marginRight: 10,
|
|
13614
|
+
top: 0,
|
|
13615
|
+
width: MAPPER_WIDTH,
|
|
13616
|
+
maxHeight: "min(60vh, 480px)",
|
|
13617
|
+
display: "flex",
|
|
13618
|
+
flexDirection: "column"
|
|
13619
|
+
},
|
|
13620
|
+
"data-testid": "quick-config-mapper",
|
|
13621
|
+
children: [
|
|
13622
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b border-border px-3 py-2", children: [
|
|
13623
|
+
/* @__PURE__ */ jsx(
|
|
13624
|
+
Icon,
|
|
13625
|
+
{
|
|
13626
|
+
icon: "mdi:tray-arrow-down",
|
|
13627
|
+
className: "size-3.5 text-muted-foreground"
|
|
13628
|
+
}
|
|
13629
|
+
),
|
|
13630
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground", children: "Input" }),
|
|
13631
|
+
sourceIds.length > 0 && /* @__PURE__ */ jsx(
|
|
13632
|
+
"select",
|
|
13633
|
+
{
|
|
13634
|
+
className: "ml-auto max-w-[55%] truncate rounded-md border border-input bg-background px-1.5 py-0.5 text-[11px] text-foreground outline-none focus:border-primary",
|
|
13635
|
+
value: selectedSource ?? "",
|
|
13636
|
+
onChange: (e) => setSelectedSource(e.target.value),
|
|
13637
|
+
"data-testid": "qc-source-selector",
|
|
13638
|
+
children: sourceIds.map((sid) => {
|
|
13639
|
+
const sn = nodes.find((n) => n.id === sid);
|
|
13640
|
+
return /* @__PURE__ */ jsx("option", { value: sid, children: nodeTitle(sn) }, sid);
|
|
13641
|
+
})
|
|
13642
|
+
}
|
|
13643
|
+
)
|
|
13644
|
+
] }),
|
|
13645
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto px-2 py-2", children: inputFields.length > 0 ? /* @__PURE__ */ jsx(FieldTree, { fields: inputFields, draggable: true }) : /* @__PURE__ */ jsx("p", { className: "px-2 py-4 text-center text-xs text-muted-foreground", children: sourceIds.length === 0 ? "Connect an upstream node to map its fields." : "The selected source has no declared output fields." }) }),
|
|
13646
|
+
/* @__PURE__ */ jsx("p", { className: "shrink-0 border-t border-border px-3 py-1.5 text-[10px] leading-snug text-muted-foreground", children: "Drag a field onto a parameter to map it." })
|
|
13647
|
+
]
|
|
13648
|
+
}
|
|
13649
|
+
),
|
|
13650
|
+
/* @__PURE__ */ jsxs(
|
|
13651
|
+
"div",
|
|
13652
|
+
{
|
|
13653
|
+
className: "flex flex-col overflow-hidden rounded-xl border border-border bg-card shadow-2xl animate-in fade-in zoom-in-95 duration-150",
|
|
13654
|
+
style: {
|
|
13655
|
+
maxHeight: "min(70vh, 560px)",
|
|
13656
|
+
borderTop: `3px solid ${accent}`
|
|
13657
|
+
},
|
|
13658
|
+
children: [
|
|
13659
|
+
/* @__PURE__ */ jsxs(
|
|
13660
|
+
"div",
|
|
13661
|
+
{
|
|
13662
|
+
className: "flex shrink-0 cursor-move items-center gap-2.5 border-b border-border px-3 py-2.5 select-none",
|
|
13663
|
+
onPointerDown: handleHeaderPointerDown,
|
|
13664
|
+
children: [
|
|
13665
|
+
/* @__PURE__ */ jsx(
|
|
13666
|
+
"div",
|
|
13667
|
+
{
|
|
13668
|
+
className: "flex size-7 shrink-0 items-center justify-center rounded-lg",
|
|
13669
|
+
style: {
|
|
13670
|
+
backgroundColor: `color-mix(in srgb, ${accent} 13%, transparent)`,
|
|
13671
|
+
color: accent,
|
|
13672
|
+
border: `1px solid color-mix(in srgb, ${accent} 26%, transparent)`
|
|
13673
|
+
},
|
|
13674
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: meta.icon, className: "size-4" })
|
|
13675
|
+
}
|
|
13676
|
+
),
|
|
13677
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
13678
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-sm font-semibold leading-tight text-foreground", children: nodeTitle(node) }),
|
|
13679
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "truncate font-mono text-[11px] leading-tight text-muted-foreground", children: subtitle })
|
|
13680
|
+
] }),
|
|
13681
|
+
/* @__PURE__ */ jsx(
|
|
13682
|
+
"button",
|
|
13683
|
+
{
|
|
13684
|
+
type: "button",
|
|
13685
|
+
title: showMapper ? "Hide input data" : "Map data from input",
|
|
13686
|
+
"aria-label": "Toggle input mapper",
|
|
13687
|
+
onClick: () => setShowMapper((v) => !v),
|
|
13688
|
+
className: `rounded-md p-1.5 transition-colors hover:bg-muted ${showMapper ? "text-primary" : "text-muted-foreground"} hover:text-foreground`,
|
|
13689
|
+
"data-testid": "qc-toggle-mapper",
|
|
13690
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:tray-arrow-down", className: "size-4" })
|
|
13691
|
+
}
|
|
13692
|
+
),
|
|
13693
|
+
/* @__PURE__ */ jsx(
|
|
13694
|
+
"button",
|
|
13695
|
+
{
|
|
13696
|
+
type: "button",
|
|
13697
|
+
title: "Open full editor",
|
|
13698
|
+
"aria-label": "Open full editor",
|
|
13699
|
+
onClick: expandToNdv,
|
|
13700
|
+
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
13701
|
+
"data-testid": "qc-expand",
|
|
13702
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:arrow-expand", className: "size-4" })
|
|
13703
|
+
}
|
|
13704
|
+
),
|
|
13705
|
+
/* @__PURE__ */ jsx(
|
|
13706
|
+
"button",
|
|
13707
|
+
{
|
|
13708
|
+
type: "button",
|
|
13709
|
+
title: "Close",
|
|
13710
|
+
"aria-label": "Close",
|
|
13711
|
+
onClick: close,
|
|
13712
|
+
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
13713
|
+
"data-testid": "qc-close",
|
|
13714
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:close", className: "size-4" })
|
|
13715
|
+
}
|
|
13716
|
+
)
|
|
13717
|
+
]
|
|
13718
|
+
}
|
|
13719
|
+
),
|
|
13720
|
+
/* @__PURE__ */ jsx(
|
|
13721
|
+
"div",
|
|
13722
|
+
{
|
|
13723
|
+
className: "min-h-0 flex-1 space-y-4 overflow-auto p-3",
|
|
13724
|
+
"data-testid": "qc-params",
|
|
13725
|
+
children: /* @__PURE__ */ jsx(
|
|
13726
|
+
NodeParamsForm,
|
|
13727
|
+
{
|
|
13728
|
+
config,
|
|
13729
|
+
nodeType: node.type,
|
|
13730
|
+
testIdPrefix: "qc"
|
|
13731
|
+
}
|
|
13732
|
+
)
|
|
13733
|
+
}
|
|
13734
|
+
),
|
|
13735
|
+
/* @__PURE__ */ jsx("p", { className: "shrink-0 border-t border-border px-3 py-1.5 text-[10px] leading-snug text-muted-foreground", children: "Changes apply instantly \xB7 double-click the node for the full editor" })
|
|
13736
|
+
]
|
|
13737
|
+
}
|
|
13738
|
+
)
|
|
13739
|
+
]
|
|
13740
|
+
}
|
|
13741
|
+
);
|
|
13742
|
+
}
|
|
13295
13743
|
var STATUS_STYLES = {
|
|
13296
13744
|
DRAFT: { label: "Draft", variant: "secondary" },
|
|
13297
13745
|
ACTIVE: { label: "Active", variant: "default" },
|
|
@@ -13786,6 +14234,7 @@ var FlowBuilder = ({ readOnly = false }) => {
|
|
|
13786
14234
|
];
|
|
13787
14235
|
})
|
|
13788
14236
|
);
|
|
14237
|
+
const closeQuickConfig = useFlowStore((s) => s.actions.quickConfig.close);
|
|
13789
14238
|
const [nodeTypesVersion, setNodeTypesVersion] = useState(0);
|
|
13790
14239
|
useEffect(() => {
|
|
13791
14240
|
return onNodeTypesUpdate(() => setNodeTypesVersion((v) => v + 1));
|
|
@@ -14040,6 +14489,7 @@ var FlowBuilder = ({ readOnly = false }) => {
|
|
|
14040
14489
|
onNodeDragStop: (_, node) => {
|
|
14041
14490
|
autoAdjustNode(node);
|
|
14042
14491
|
},
|
|
14492
|
+
onPaneClick: closeQuickConfig,
|
|
14043
14493
|
onNodesDelete,
|
|
14044
14494
|
isValidConnection,
|
|
14045
14495
|
nodesDraggable: !isReadOnly,
|
|
@@ -14072,6 +14522,7 @@ var FlowBuilder = ({ readOnly = false }) => {
|
|
|
14072
14522
|
/* @__PURE__ */ jsx(ChatPanel, {}),
|
|
14073
14523
|
/* @__PURE__ */ jsx(LogsPanel, {}),
|
|
14074
14524
|
/* @__PURE__ */ jsx(NodeDetailView, {}),
|
|
14525
|
+
/* @__PURE__ */ jsx(QuickConfigPanel, {}),
|
|
14075
14526
|
/* @__PURE__ */ jsx(
|
|
14076
14527
|
"div",
|
|
14077
14528
|
{
|
|
@@ -14310,7 +14761,7 @@ function WorkflowItem({
|
|
|
14310
14761
|
};
|
|
14311
14762
|
const requiredNodeTypes = [];
|
|
14312
14763
|
try {
|
|
14313
|
-
const { NODE_CONFIGS: NODE_CONFIGS3, ensureNodeConfigsLoaded: ensureNodeConfigsLoaded2 } = await import('./blocks-
|
|
14764
|
+
const { NODE_CONFIGS: NODE_CONFIGS3, ensureNodeConfigsLoaded: ensureNodeConfigsLoaded2 } = await import('./blocks-QKAWYAOT.js');
|
|
14314
14765
|
await ensureNodeConfigsLoaded2().catch(() => {
|
|
14315
14766
|
});
|
|
14316
14767
|
const workflowNodeTypes = [
|
|
@@ -14608,5 +15059,5 @@ function WorkflowBuilder() {
|
|
|
14608
15059
|
}
|
|
14609
15060
|
|
|
14610
15061
|
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, FlowBuilderPage, FluidGridsProvider, TemplateCard, WorkflowBuilder, useFluidGridsContext, useImportWorkflowTemplate, useWorkflowTemplates };
|
|
14611
|
-
//# sourceMappingURL=chunk-
|
|
14612
|
-
//# sourceMappingURL=chunk-
|
|
15062
|
+
//# sourceMappingURL=chunk-KOXWDM2E.js.map
|
|
15063
|
+
//# sourceMappingURL=chunk-KOXWDM2E.js.map
|