@burdenoff/fluidgrids-fe-sdk 2026.1105.2 → 2026.1105.4
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/README.md +42 -3
- package/dist/ExecutionDetailPage-OOHJQR2L.js +30 -0
- package/dist/ExecutionsListPage-6HS5VQOV.js +24 -0
- package/dist/WorkflowBuilder-PICIS7FI.js +35 -0
- package/dist/WorkflowsList-SD5XQC4Q.js +23 -0
- package/dist/{agentTools-5N3ZEZDW.js → agentTools-UH4LU6LA.js} +9 -7
- package/dist/{chunk-6ZK4MRVA.js → chunk-43GSC5Y6.js} +1 -1
- package/dist/{chunk-CH3YUGWR.js → chunk-4XAXF5VP.js} +4 -4
- package/dist/{chunk-6IS7EXIY.js → chunk-5GG2FEKW.js} +2 -2
- package/dist/{chunk-64JN2TVX.js → chunk-5Z4F24QT.js} +10 -39
- package/dist/chunk-6VIG44VF.js +32 -0
- package/dist/{chunk-QFC6E3WD.js → chunk-ASYYYJG2.js} +4 -4
- package/dist/{chunk-OXXXUAWM.js → chunk-CTKWMPQQ.js} +1 -1
- package/dist/{chunk-QFGZXWTM.js → chunk-EIMTOK6E.js} +3 -3
- package/dist/{chunk-AMXJLVZN.js → chunk-EXJW7EKR.js} +2 -2
- package/dist/{chunk-O7CJJNW6.js → chunk-GBJWPSLJ.js} +70 -5
- package/dist/{chunk-X25NCWG2.js → chunk-GBQC5WDH.js} +16 -8
- package/dist/{chunk-3XUWPDKJ.js → chunk-GPABUQTD.js} +650 -636
- package/dist/{chunk-3QCRKKTI.js → chunk-HSTP2RX3.js} +267 -2149
- package/dist/{chunk-US5QSLPV.js → chunk-JKLZ6YZ3.js} +22 -11
- package/dist/{chunk-GKFMK7FF.js → chunk-JRLBPR5U.js} +3 -3
- package/dist/{chunk-IL343FKX.js → chunk-KHS2DZHH.js} +1 -1
- package/dist/{chunk-SALZ3LQB.js → chunk-KJT5TAOE.js} +3 -3
- package/dist/{chunk-AASHQI77.js → chunk-KZCNJAMK.js} +2 -1
- package/dist/{chunk-TNFBRXU7.js → chunk-LLCVVRCE.js} +9 -8
- package/dist/{chunk-5CFCFA6O.js → chunk-M72SMQOS.js} +8 -7
- package/dist/{chunk-TCIBTMJI.js → chunk-NZMUKAXG.js} +3 -69
- package/dist/{chunk-2KUZBEWW.js → chunk-OLRIWGYM.js} +8 -7
- package/dist/{chunk-62CCBMDC.js → chunk-OTOQFZFO.js} +40 -39
- package/dist/{chunk-EYQ7GJRW.js → chunk-PASKZCII.js} +3 -3
- package/dist/{chunk-3IXU7WUC.js → chunk-PDODDDHY.js} +1 -1
- package/dist/chunk-SDZEAIIE.js +9 -0
- package/dist/chunk-TGWDFLEX.js +1932 -0
- package/dist/{chunk-AU7LACOY.js → chunk-TYI2XOSI.js} +1 -1
- package/dist/{chunk-L2N6DDOI.js → chunk-U7UNWR3D.js} +2 -2
- package/dist/{chunk-HK76ZUAK.js → chunk-UIS7KGHW.js} +4 -4
- package/dist/{chunk-QPLFALVV.js → chunk-UWCD7JUU.js} +8 -7
- package/dist/{chunk-CNKTQ5MG.js → chunk-UYTPURFW.js} +16 -50
- package/dist/{chunk-AJVU5YW6.js → chunk-WBRW67HX.js} +4 -3
- package/dist/{chunk-J3YQCEP3.js → chunk-WC526MLS.js} +3 -3
- package/dist/{chunk-XFH6SLDK.js → chunk-XNARCHMT.js} +2 -2
- package/dist/{chunk-W5WML3OO.js → chunk-XWINH6CR.js} +1 -1
- package/dist/{chunk-Y6M7K4UG.js → chunk-Y4UCHFGK.js} +1 -1
- package/dist/{chunk-OCJTTHTS.js → chunk-Y7FKJJMF.js} +1 -9
- package/dist/{client-YVZMLEQX.js → client-62VHXHKN.js} +2 -2
- package/dist/code-editor-field-WWPDMF4O.js +3 -0
- package/dist/executions.js +17 -15
- package/dist/{global-client-N5EIFW6T.js → global-client-PJ5LANJA.js} +2 -2
- package/dist/history.js +11 -8
- package/dist/index.d.ts +10 -4
- package/dist/index.js +69 -52
- package/dist/{node-detail-view-WIWW5N6N.js → node-detail-view-P5NV5CMO.js} +14 -12
- package/dist/nodes.js +3 -3
- package/dist/observability.js +10 -8
- package/dist/{quick-config-panel-O64TXXK3.js → quick-config-panel-ZNSBVF4G.js} +11 -9
- package/dist/settings.js +11 -9
- package/dist/templates.js +17 -14
- package/dist/{workflow-builder-7vv9dCdp.d.ts → workflow-builder-C-ekFbwR.d.ts} +37 -4
- package/dist/workflow-builder.d.ts +1 -1
- package/dist/workflow-builder.js +19 -16
- package/dist/workflow-preview.d.ts +158 -0
- package/dist/workflow-preview.js +721 -0
- package/dist/workflows-list.js +12 -10
- package/package.json +5 -1
- package/dist/ExecutionDetailPage-HQB2SWBP.js +0 -28
- package/dist/ExecutionsListPage-RSLL634L.js +0 -22
- package/dist/WorkflowBuilder-E3PNZX74.js +0 -32
- package/dist/WorkflowsList-473FRRP2.js +0 -21
- package/dist/code-editor-field-XWUVOKTA.js +0 -2
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import { SdkPermissionGate, FLUIDGRIDS_PERMISSIONS } from './chunk-5375NUIO.js';
|
|
2
|
-
import { useBuilderReadOnly
|
|
3
|
-
import {
|
|
2
|
+
import { useBuilderReadOnly } from './chunk-SDZEAIIE.js';
|
|
3
|
+
import { STICKY_NOTE_TYPE, useFlowStore, resolveOperationName, synchronizeOperationUpdate, isNodeTrigger, resolveOutputHandles, resolveInputHandles, outputHandlesSpacerHeight, WAIT_FOR_SIGNAL_NODE_TYPE, CODE_WORKFLOW_NODE_TYPE, readSignalName, LogicNodeCard, NodeCard, NodeCardHeader, NodeCardBody, InputHandles, OutputHandles, NodeTypeIcon, nodeAccent, readCodeWorkflowState, partitionStickyNotes, interfaceFields, interfaceHandlers } from './chunk-TGWDFLEX.js';
|
|
4
|
+
import { getGlobalStoreClient, createGlobalStoreClient, setGlobalStoreClient, resetGlobalStoreClient } from './chunk-TYI2XOSI.js';
|
|
4
5
|
import { GetMyNodeInstallationsDocument } from './chunk-G77IGC3Y.js';
|
|
5
6
|
import { fetchAllNodeEndpointConfigs, NodeManifestDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, ExecuteStepDocument, TriggerWorkflowDocument, RunFromNodeDocument, ExecutionDetailDocument, WorkflowDefinitionDocument, WorkflowRunDocument } from './chunk-Z3ABLERJ.js';
|
|
6
7
|
import { useTr, ENGLISH_FALLBACK_TRANSLATOR, FluidGridsTranslationProvider } from './chunk-UULVIT25.js';
|
|
7
|
-
import { waitForFluidGridsClient, getFluidGridsClient, getFluidGridsClientSafe, createFluidGridsClient, setFluidGridsClient, resetFluidGridsClient } from './chunk-
|
|
8
|
-
import { throwIfResultError, emitFluidGridsEvent, emitOperationErrorEvent, describeOperationError, emitRunCompletedOnce } from './chunk-
|
|
8
|
+
import { waitForFluidGridsClient, getFluidGridsClient, getFluidGridsClientSafe, createFluidGridsClient, setFluidGridsClient, resetFluidGridsClient } from './chunk-PDODDDHY.js';
|
|
9
|
+
import { throwIfResultError, emitFluidGridsEvent, emitOperationErrorEvent, describeOperationError, emitRunCompletedOnce } from './chunk-JKLZ6YZ3.js';
|
|
9
10
|
import { getFluidGridsConfig, validateTrustedOrigin, resetFluidGridsExecutionState, resetFluidGridsConfig, setFluidGridsConfig } from './chunk-UEG2WC3G.js';
|
|
10
|
-
import * as React from 'react';
|
|
11
11
|
import { memo, forwardRef, useState, useImperativeHandle, useRef, useEffect, useMemo, createContext, useCallback, useSyncExternalStore, useContext } from 'react';
|
|
12
12
|
import { useOptionalFeatureFlags } from '@burdenoff/fe-libs/shared/feature-flags';
|
|
13
13
|
import { dispatchUpgradePrompt } from '@burdenoff/fe-libs/shared/components';
|
|
14
|
-
import { nanoid } from 'nanoid/non-secure';
|
|
15
|
-
import {
|
|
16
|
-
import { create } from 'zustand';
|
|
17
|
-
import { produce } from 'immer';
|
|
14
|
+
import { nanoid as nanoid$1 } from 'nanoid/non-secure';
|
|
15
|
+
import { useReactFlow, NodeResizer, getConnectedEdges, useStore, Handle, Position } from '@xyflow/react';
|
|
18
16
|
import { Icon } from '@iconify/react';
|
|
19
|
-
import { nanoid
|
|
17
|
+
import { nanoid } from 'nanoid';
|
|
20
18
|
import ReactMarkdown from 'react-markdown';
|
|
21
19
|
import { cn } from '@burdenoff/fe-libs/utils';
|
|
22
|
-
import {
|
|
20
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
23
21
|
import { toast } from 'sonner';
|
|
24
|
-
import { nodeCategoryColor
|
|
22
|
+
import { nodeCategoryColor } from '@burdenoff/fe-libs/shared/utils';
|
|
25
23
|
import { gql } from '@apollo/client';
|
|
26
24
|
import { Textarea, Input, Button, Card, Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuItem, DropdownMenuSeparator, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel } from '@burdenoff/fe-libs/ui';
|
|
27
25
|
import * as AdaptiveCards from 'adaptivecards';
|
|
@@ -31,6 +29,7 @@ import { v4 } from 'uuid';
|
|
|
31
29
|
import { useParams, useNavigate } from 'react-router';
|
|
32
30
|
import { useEventBus } from '@burdenoff/fe-libs/shared/events';
|
|
33
31
|
import { ApolloProvider } from '@apollo/client/react';
|
|
32
|
+
import { create } from 'zustand';
|
|
34
33
|
import { useShallow } from 'zustand/shallow';
|
|
35
34
|
import { InfoCircledIcon } from '@radix-ui/react-icons';
|
|
36
35
|
import { Button as Button$1 } from '@burdenoff/fe-libs/button';
|
|
@@ -276,6 +275,35 @@ function usePaletteGates() {
|
|
|
276
275
|
return useMemo(() => resolvePaletteGates(context), [context]);
|
|
277
276
|
}
|
|
278
277
|
|
|
278
|
+
// src/modules/executions/utils/duration.ts
|
|
279
|
+
function spanMs(start, end) {
|
|
280
|
+
if (!start || !end) return null;
|
|
281
|
+
const ms = new Date(end).getTime() - new Date(start).getTime();
|
|
282
|
+
return Number.isFinite(ms) && ms >= 0 ? ms : null;
|
|
283
|
+
}
|
|
284
|
+
function secondsToMs(seconds) {
|
|
285
|
+
return typeof seconds === "number" && Number.isFinite(seconds) && seconds >= 0 ? Math.round(seconds * 1e3) : null;
|
|
286
|
+
}
|
|
287
|
+
function nodeStateDurationMs(node) {
|
|
288
|
+
return spanMs(node.startTime, node.endTime) ?? secondsToMs(node.duration);
|
|
289
|
+
}
|
|
290
|
+
function runDurationMs(run) {
|
|
291
|
+
return spanMs(run.startedAt, run.completedAt) ?? secondsToMs(run.duration);
|
|
292
|
+
}
|
|
293
|
+
function formatElapsedMs(ms, empty = "-") {
|
|
294
|
+
if (ms === null || ms === void 0 || !Number.isFinite(ms) || ms < 0) {
|
|
295
|
+
return empty;
|
|
296
|
+
}
|
|
297
|
+
if (ms < 999.5) return `${Math.round(ms)}ms`;
|
|
298
|
+
if (ms < 59950) return `${(ms / 1e3).toFixed(1)}s`;
|
|
299
|
+
const totalSeconds = Math.round(ms / 1e3);
|
|
300
|
+
if (totalSeconds < 3600) {
|
|
301
|
+
return `${Math.floor(totalSeconds / 60)}m ${totalSeconds % 60}s`;
|
|
302
|
+
}
|
|
303
|
+
const totalMinutes = Math.floor(totalSeconds / 60);
|
|
304
|
+
return `${Math.floor(totalMinutes / 60)}h ${totalMinutes % 60}m`;
|
|
305
|
+
}
|
|
306
|
+
|
|
279
307
|
// src/billing/quota.ts
|
|
280
308
|
var RUNS_QUOTA_NAME = "fluidgrids.runs.monthly";
|
|
281
309
|
var WORKFLOWS_QUOTA_NAME = "fluidgrids.workflows.count";
|
|
@@ -510,901 +538,6 @@ function openRunQuotaUpgradePrompt(error, tr = ENGLISH_FALLBACK_TRANSLATOR, anal
|
|
|
510
538
|
});
|
|
511
539
|
return true;
|
|
512
540
|
}
|
|
513
|
-
|
|
514
|
-
// src/builder/lib/node-role.ts
|
|
515
|
-
function isRecord(value) {
|
|
516
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
517
|
-
}
|
|
518
|
-
function readRecord(value) {
|
|
519
|
-
return isRecord(value) ? value : void 0;
|
|
520
|
-
}
|
|
521
|
-
function readString(value) {
|
|
522
|
-
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
523
|
-
}
|
|
524
|
-
function operationRole(operation) {
|
|
525
|
-
const metadata = readRecord(operation);
|
|
526
|
-
const role = readString(metadata?.role);
|
|
527
|
-
if (role) return role === "trigger" ? "trigger" : "action";
|
|
528
|
-
const type = readString(metadata?.type);
|
|
529
|
-
if (type === "trigger" || type === "subscription" || readString(metadata?.delivery)) {
|
|
530
|
-
return "trigger";
|
|
531
|
-
}
|
|
532
|
-
if (type === "action" || type === "query" || type === "mutation") {
|
|
533
|
-
return "action";
|
|
534
|
-
}
|
|
535
|
-
return void 0;
|
|
536
|
-
}
|
|
537
|
-
function isTriggerOperation(operation) {
|
|
538
|
-
return operationRole(operation) === "trigger";
|
|
539
|
-
}
|
|
540
|
-
function isLegacyTriggerType(type) {
|
|
541
|
-
return type === "trigger" || type.startsWith("trigger:") || type.startsWith("internal:schedule") || type.startsWith("internal:webhook") || type.startsWith("internal:api") || type.startsWith("internal:form") || type.startsWith("internal:mcp") || type.endsWith("_trigger") || type.endsWith("Trigger") || type.endsWith("-trigger");
|
|
542
|
-
}
|
|
543
|
-
function getSelectedOperationRole(nodeType, nodeData) {
|
|
544
|
-
const data = readRecord(nodeData);
|
|
545
|
-
const operationName = data?.operation_name;
|
|
546
|
-
if (typeof operationName !== "string" || !operationName.trim())
|
|
547
|
-
return void 0;
|
|
548
|
-
const manifest = readRecord(data?.nodeData);
|
|
549
|
-
const declared = manifest?.operations;
|
|
550
|
-
const operations = Array.isArray(declared) ? declared : readRecord(declared)?.operations;
|
|
551
|
-
const operation = Array.isArray(operations) ? operations.find(
|
|
552
|
-
(entry) => readRecord(entry)?.name === operationName
|
|
553
|
-
) : void 0;
|
|
554
|
-
const selectedRole = operationRole(operation) ?? operationRole({ type: data?.operation_type });
|
|
555
|
-
if (selectedRole) return selectedRole;
|
|
556
|
-
if (nodeType === "integration/channel" || nodeType?.startsWith("store/")) {
|
|
557
|
-
return operationName.startsWith("on") ? "trigger" : "action";
|
|
558
|
-
}
|
|
559
|
-
return void 0;
|
|
560
|
-
}
|
|
561
|
-
function isNodeTrigger(node) {
|
|
562
|
-
const data = readRecord(node.data);
|
|
563
|
-
const selectedRole = getSelectedOperationRole(node.type, data);
|
|
564
|
-
if (selectedRole) return selectedRole === "trigger";
|
|
565
|
-
const state = readRecord(readRecord(data?.args)?.state);
|
|
566
|
-
for (const legacyRole of [data?.role, state?.role]) {
|
|
567
|
-
const explicitRole = readString(legacyRole);
|
|
568
|
-
if (explicitRole === "trigger" || explicitRole === "action") {
|
|
569
|
-
return explicitRole === "trigger";
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
const savedRole = operationRole({ type: data?.operation_type });
|
|
573
|
-
if (savedRole) return savedRole === "trigger";
|
|
574
|
-
const type = node.type ?? "";
|
|
575
|
-
if (isLegacyTriggerType(type)) return true;
|
|
576
|
-
const manifest = readRecord(data?.nodeData);
|
|
577
|
-
if (!data?.operation_name && Array.isArray(manifest?.kind) && manifest.kind.includes("trigger")) {
|
|
578
|
-
return true;
|
|
579
|
-
}
|
|
580
|
-
return false;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
// src/builder/hooks/use-is-valid-connection.ts
|
|
584
|
-
function isLoopController(source) {
|
|
585
|
-
const type = source?.type?.toLowerCase();
|
|
586
|
-
const disabled = source?.data?.disabled === true || source !== void 0 && "disabled" in source && source.disabled === true;
|
|
587
|
-
return (type === "internal:loop" || type === "loop") && !disabled;
|
|
588
|
-
}
|
|
589
|
-
function isRecord2(value) {
|
|
590
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
591
|
-
}
|
|
592
|
-
function readRecord2(value) {
|
|
593
|
-
return isRecord2(value) ? value : void 0;
|
|
594
|
-
}
|
|
595
|
-
function loopBodyHandle(source) {
|
|
596
|
-
const node = readRecord2(source);
|
|
597
|
-
const data = readRecord2(node?.data);
|
|
598
|
-
const parameters = {
|
|
599
|
-
...data,
|
|
600
|
-
...readRecord2(node?.config),
|
|
601
|
-
...readRecord2(readRecord2(data?.args)?.state),
|
|
602
|
-
...readRecord2(readRecord2(node?.args)?.state)
|
|
603
|
-
};
|
|
604
|
-
return typeof parameters.loopHandle === "string" && parameters.loopHandle ? parameters.loopHandle : "loop";
|
|
605
|
-
}
|
|
606
|
-
function isLoopBodyEdge(edge, nodes) {
|
|
607
|
-
const source = nodes.find((node) => node.id === edge.source);
|
|
608
|
-
return source !== void 0 && isLoopController(source) && edge.sourceHandle === loopBodyHandle(source);
|
|
609
|
-
}
|
|
610
|
-
function adjacency(edges) {
|
|
611
|
-
const outgoing = /* @__PURE__ */ new Map();
|
|
612
|
-
for (const edge of edges) {
|
|
613
|
-
const targets = outgoing.get(edge.source) ?? /* @__PURE__ */ new Set();
|
|
614
|
-
targets.add(edge.target);
|
|
615
|
-
outgoing.set(edge.source, targets);
|
|
616
|
-
}
|
|
617
|
-
return outgoing;
|
|
618
|
-
}
|
|
619
|
-
function reachable(starts, outgoing, blocked = /* @__PURE__ */ new Set()) {
|
|
620
|
-
const pending = [...starts];
|
|
621
|
-
const visited = /* @__PURE__ */ new Set();
|
|
622
|
-
while (pending.length > 0) {
|
|
623
|
-
const current = pending.pop();
|
|
624
|
-
if (current === void 0 || visited.has(current) || blocked.has(current))
|
|
625
|
-
continue;
|
|
626
|
-
visited.add(current);
|
|
627
|
-
pending.push(...outgoing.get(current) ?? []);
|
|
628
|
-
}
|
|
629
|
-
return visited;
|
|
630
|
-
}
|
|
631
|
-
function controlledReturns(nodes, edges) {
|
|
632
|
-
const outgoing = adjacency(edges);
|
|
633
|
-
const incomingTargets = new Set(edges.map((edge) => edge.target));
|
|
634
|
-
const entries = nodes.filter((node) => !incomingTargets.has(node.id) || isNodeTrigger(node)).map((node) => node.id);
|
|
635
|
-
const returns = /* @__PURE__ */ new Set();
|
|
636
|
-
for (const controller of nodes.filter(isLoopController)) {
|
|
637
|
-
const bodyHandle = loopBodyHandle(controller);
|
|
638
|
-
const controllerEdges = edges.filter(
|
|
639
|
-
(edge) => edge.source === controller.id
|
|
640
|
-
);
|
|
641
|
-
const outside = reachable(
|
|
642
|
-
[
|
|
643
|
-
...entries,
|
|
644
|
-
...controllerEdges.filter((edge) => edge.sourceHandle !== bodyHandle).map((edge) => edge.target)
|
|
645
|
-
],
|
|
646
|
-
outgoing,
|
|
647
|
-
/* @__PURE__ */ new Set([controller.id])
|
|
648
|
-
);
|
|
649
|
-
const body = reachable(
|
|
650
|
-
controllerEdges.filter((edge) => edge.sourceHandle === bodyHandle).map((edge) => edge.target),
|
|
651
|
-
outgoing,
|
|
652
|
-
/* @__PURE__ */ new Set([controller.id, ...outside])
|
|
653
|
-
);
|
|
654
|
-
for (const edge of edges) {
|
|
655
|
-
if (edge.target === controller.id && body.has(edge.source))
|
|
656
|
-
returns.add(edge);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
return returns;
|
|
660
|
-
}
|
|
661
|
-
function isValidWorkflowConnection(nodes, edges, connection) {
|
|
662
|
-
if (connection.target === connection.source) return false;
|
|
663
|
-
const candidates = [...edges, connection];
|
|
664
|
-
const previousReturns = controlledReturns(nodes, edges);
|
|
665
|
-
const nextReturns = controlledReturns(nodes, candidates);
|
|
666
|
-
const outgoing = adjacency(
|
|
667
|
-
candidates.filter((edge) => !nextReturns.has(edge))
|
|
668
|
-
);
|
|
669
|
-
const invalidated = [connection, ...previousReturns].filter(
|
|
670
|
-
(edge) => !nextReturns.has(edge)
|
|
671
|
-
);
|
|
672
|
-
return invalidated.every(
|
|
673
|
-
(edge) => !reachable([edge.target], outgoing).has(edge.source)
|
|
674
|
-
);
|
|
675
|
-
}
|
|
676
|
-
function useIsValidConnection(nodes, edges) {
|
|
677
|
-
return useCallback(
|
|
678
|
-
(connection) => isValidWorkflowConnection(nodes, edges, connection),
|
|
679
|
-
[nodes, edges]
|
|
680
|
-
);
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
// src/builder/stores/flow-store.ts
|
|
684
|
-
var HISTORY_LIMIT = 100;
|
|
685
|
-
var CLONE_OFFSET = 48;
|
|
686
|
-
function cloneValue(value) {
|
|
687
|
-
try {
|
|
688
|
-
return structuredClone(value);
|
|
689
|
-
} catch {
|
|
690
|
-
return JSON.parse(JSON.stringify(value));
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
var TAGS = [
|
|
694
|
-
{ value: "marketing", label: "Marketing", color: "var(--color-chart-5)" },
|
|
695
|
-
{ value: "support", label: "Support", color: "var(--color-chart-5)" },
|
|
696
|
-
{ value: "lead", label: "Lead", color: "var(--color-chart-4)" },
|
|
697
|
-
{ value: "new", label: "New", color: "var(--color-chart-7)" }
|
|
698
|
-
];
|
|
699
|
-
var INITIAL_EXECUTION = {
|
|
700
|
-
isExecuting: false,
|
|
701
|
-
executingNodeId: null,
|
|
702
|
-
currentRunId: null,
|
|
703
|
-
sourceRun: null,
|
|
704
|
-
stepPlan: null,
|
|
705
|
-
logs: [],
|
|
706
|
-
selectedLogId: null,
|
|
707
|
-
panelExpanded: false,
|
|
708
|
-
nodeStatuses: {},
|
|
709
|
-
nodeItemCounts: {},
|
|
710
|
-
followRequest: null
|
|
711
|
-
};
|
|
712
|
-
var INITIAL_HISTORY = { past: [], future: [] };
|
|
713
|
-
var useFlowStore = create()((set, get) => {
|
|
714
|
-
let lastCheckpointKind = null;
|
|
715
|
-
let lastCheckpointAt = 0;
|
|
716
|
-
function pushCheckpoint(kind, coalesce) {
|
|
717
|
-
const now = Date.now();
|
|
718
|
-
const isCoalesced = coalesce && kind === lastCheckpointKind && now - lastCheckpointAt < 800;
|
|
719
|
-
if (!isCoalesced) {
|
|
720
|
-
const state = get();
|
|
721
|
-
const snapshot = {
|
|
722
|
-
nodes: cloneValue(state.workflow.nodes),
|
|
723
|
-
edges: cloneValue(state.workflow.edges)
|
|
724
|
-
};
|
|
725
|
-
set((s) => ({
|
|
726
|
-
history: {
|
|
727
|
-
past: [...s.history.past, snapshot].slice(-HISTORY_LIMIT),
|
|
728
|
-
future: []
|
|
729
|
-
}
|
|
730
|
-
}));
|
|
731
|
-
} else if (get().history.future.length > 0) {
|
|
732
|
-
set((s) => ({ history: { ...s.history, future: [] } }));
|
|
733
|
-
}
|
|
734
|
-
lastCheckpointKind = kind;
|
|
735
|
-
lastCheckpointAt = now;
|
|
736
|
-
noteEdit();
|
|
737
|
-
}
|
|
738
|
-
function noteEdit() {
|
|
739
|
-
set((s) => ({ editRevision: s.editRevision + 1 }));
|
|
740
|
-
}
|
|
741
|
-
const REMOVAL_KINDS = /* @__PURE__ */ new Set(["nodes:remove", "edges:remove"]);
|
|
742
|
-
const SAME_ACTION_WINDOW_MS = 150;
|
|
743
|
-
function joinsPrecedingRemoval(kind) {
|
|
744
|
-
return lastCheckpointKind !== null && lastCheckpointKind !== kind && REMOVAL_KINDS.has(kind) && REMOVAL_KINDS.has(lastCheckpointKind) && Date.now() - lastCheckpointAt < SAME_ACTION_WINDOW_MS;
|
|
745
|
-
}
|
|
746
|
-
function resetCoalescing() {
|
|
747
|
-
lastCheckpointKind = null;
|
|
748
|
-
lastCheckpointAt = 0;
|
|
749
|
-
}
|
|
750
|
-
return {
|
|
751
|
-
tags: TAGS,
|
|
752
|
-
history: { ...INITIAL_HISTORY },
|
|
753
|
-
editRevision: 0,
|
|
754
|
-
loadGeneration: 0,
|
|
755
|
-
workflow: {
|
|
756
|
-
id: nanoid(),
|
|
757
|
-
workflowKey: "",
|
|
758
|
-
name: "",
|
|
759
|
-
version: "",
|
|
760
|
-
alias: "",
|
|
761
|
-
edges: [],
|
|
762
|
-
nodes: [],
|
|
763
|
-
ndv: null,
|
|
764
|
-
quickConfig: null,
|
|
765
|
-
pendingConnection: null,
|
|
766
|
-
renamingNodeId: null,
|
|
767
|
-
sidebar: {
|
|
768
|
-
active: "none",
|
|
769
|
-
panels: {
|
|
770
|
-
nodeProperties: {
|
|
771
|
-
selectedNode: null
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
},
|
|
776
|
-
execution: { ...INITIAL_EXECUTION },
|
|
777
|
-
actions: {
|
|
778
|
-
saveWorkflow: () => {
|
|
779
|
-
const { workflow } = get();
|
|
780
|
-
const { id, name, version, alias, dbId, status, nodes, edges } = workflow;
|
|
781
|
-
set({ workflow });
|
|
782
|
-
return { id, name, version, alias, dbId, status, nodes, edges };
|
|
783
|
-
},
|
|
784
|
-
setWorkflow: (workflow) => {
|
|
785
|
-
const current = get().workflow;
|
|
786
|
-
if (workflow.name !== void 0 && workflow.name !== current.name || workflow.alias !== void 0 && workflow.alias !== current.alias) {
|
|
787
|
-
noteEdit();
|
|
788
|
-
}
|
|
789
|
-
const nodes = workflow.nodes?.map(
|
|
790
|
-
(node) => node.data === void 0 || node.data === null ? { ...node, data: {} } : node
|
|
791
|
-
);
|
|
792
|
-
set((state) => ({
|
|
793
|
-
workflow: {
|
|
794
|
-
...state.workflow,
|
|
795
|
-
...workflow,
|
|
796
|
-
...nodes ? { nodes } : {}
|
|
797
|
-
}
|
|
798
|
-
}));
|
|
799
|
-
},
|
|
800
|
-
resetWorkflow: () => {
|
|
801
|
-
resetCoalescing();
|
|
802
|
-
set((s) => ({
|
|
803
|
-
loadGeneration: s.loadGeneration + 1,
|
|
804
|
-
workflow: {
|
|
805
|
-
id: nanoid(),
|
|
806
|
-
workflowKey: "",
|
|
807
|
-
name: "",
|
|
808
|
-
version: "",
|
|
809
|
-
alias: "",
|
|
810
|
-
dbId: void 0,
|
|
811
|
-
status: void 0,
|
|
812
|
-
codeBuildId: void 0,
|
|
813
|
-
edges: [],
|
|
814
|
-
nodes: [],
|
|
815
|
-
ndv: null,
|
|
816
|
-
quickConfig: null,
|
|
817
|
-
pendingConnection: null,
|
|
818
|
-
renamingNodeId: null,
|
|
819
|
-
sidebar: {
|
|
820
|
-
active: "none",
|
|
821
|
-
panels: {
|
|
822
|
-
nodeProperties: {
|
|
823
|
-
selectedNode: null
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
},
|
|
828
|
-
// Wipe run state too — resetWorkflow fires when the builder loads a
|
|
829
|
-
// (different) workflow, so the previous workflow's logs must not carry
|
|
830
|
-
// over into this one's Logs panel.
|
|
831
|
-
execution: { ...INITIAL_EXECUTION },
|
|
832
|
-
// A freshly loaded workflow must not be undo-able back to empty —
|
|
833
|
-
// undo/redo only ever applies within the currently open workflow.
|
|
834
|
-
history: { ...INITIAL_HISTORY }
|
|
835
|
-
}));
|
|
836
|
-
},
|
|
837
|
-
history: {
|
|
838
|
-
undo: () => {
|
|
839
|
-
const { past, future } = get().history;
|
|
840
|
-
const previous = past[past.length - 1];
|
|
841
|
-
if (!previous) return;
|
|
842
|
-
const { nodes, edges } = get().workflow;
|
|
843
|
-
const current = {
|
|
844
|
-
nodes: cloneValue(nodes),
|
|
845
|
-
edges: cloneValue(edges)
|
|
846
|
-
};
|
|
847
|
-
resetCoalescing();
|
|
848
|
-
noteEdit();
|
|
849
|
-
set((s) => ({
|
|
850
|
-
workflow: {
|
|
851
|
-
...s.workflow,
|
|
852
|
-
nodes: previous.nodes,
|
|
853
|
-
edges: previous.edges
|
|
854
|
-
},
|
|
855
|
-
history: {
|
|
856
|
-
past: past.slice(0, -1),
|
|
857
|
-
future: [current, ...future].slice(0, HISTORY_LIMIT)
|
|
858
|
-
}
|
|
859
|
-
}));
|
|
860
|
-
},
|
|
861
|
-
redo: () => {
|
|
862
|
-
const { past, future } = get().history;
|
|
863
|
-
const next = future[0];
|
|
864
|
-
if (!next) return;
|
|
865
|
-
const { nodes, edges } = get().workflow;
|
|
866
|
-
const current = {
|
|
867
|
-
nodes: cloneValue(nodes),
|
|
868
|
-
edges: cloneValue(edges)
|
|
869
|
-
};
|
|
870
|
-
resetCoalescing();
|
|
871
|
-
noteEdit();
|
|
872
|
-
set((s) => ({
|
|
873
|
-
workflow: {
|
|
874
|
-
...s.workflow,
|
|
875
|
-
nodes: next.nodes,
|
|
876
|
-
edges: next.edges
|
|
877
|
-
},
|
|
878
|
-
history: {
|
|
879
|
-
past: [...past, current].slice(-HISTORY_LIMIT),
|
|
880
|
-
future: future.slice(1)
|
|
881
|
-
}
|
|
882
|
-
}));
|
|
883
|
-
},
|
|
884
|
-
clear: () => {
|
|
885
|
-
resetCoalescing();
|
|
886
|
-
set({ history: { ...INITIAL_HISTORY } });
|
|
887
|
-
}
|
|
888
|
-
},
|
|
889
|
-
ndv: {
|
|
890
|
-
// Opening the full NDV supersedes the floating quick-config panel — the
|
|
891
|
-
// two edit the same node data, so only one should be visible at a time.
|
|
892
|
-
open: (node) => set((state) => ({
|
|
893
|
-
workflow: { ...state.workflow, ndv: node, quickConfig: null }
|
|
894
|
-
})),
|
|
895
|
-
close: () => set((state) => ({
|
|
896
|
-
workflow: { ...state.workflow, ndv: null }
|
|
897
|
-
}))
|
|
898
|
-
},
|
|
899
|
-
quickConfig: {
|
|
900
|
-
open: (node) => set((state) => ({
|
|
901
|
-
workflow: { ...state.workflow, quickConfig: node }
|
|
902
|
-
})),
|
|
903
|
-
close: () => set((state) => ({
|
|
904
|
-
workflow: { ...state.workflow, quickConfig: null }
|
|
905
|
-
}))
|
|
906
|
-
},
|
|
907
|
-
pendingConnection: {
|
|
908
|
-
start: (connection) => set((state) => ({
|
|
909
|
-
workflow: {
|
|
910
|
-
...state.workflow,
|
|
911
|
-
pendingConnection: connection,
|
|
912
|
-
sidebar: { ...state.workflow.sidebar, active: "store-browse" }
|
|
913
|
-
}
|
|
914
|
-
})),
|
|
915
|
-
clear: () => set((state) => ({
|
|
916
|
-
workflow: { ...state.workflow, pendingConnection: null }
|
|
917
|
-
}))
|
|
918
|
-
},
|
|
919
|
-
sidebar: {
|
|
920
|
-
// Leaving the store panel abandons any armed "+" attach mode — the
|
|
921
|
-
// pending handle would otherwise silently capture a later insert.
|
|
922
|
-
setActivePanel: (panel) => set((state) => ({
|
|
923
|
-
workflow: {
|
|
924
|
-
...state.workflow,
|
|
925
|
-
sidebar: { ...state.workflow.sidebar, active: panel },
|
|
926
|
-
...panel !== "store-browse" ? { pendingConnection: null } : {}
|
|
927
|
-
}
|
|
928
|
-
})),
|
|
929
|
-
showNodePropertiesOf: (node) => {
|
|
930
|
-
set((state) => ({
|
|
931
|
-
workflow: {
|
|
932
|
-
...state.workflow,
|
|
933
|
-
pendingConnection: null,
|
|
934
|
-
sidebar: {
|
|
935
|
-
...state.workflow.sidebar,
|
|
936
|
-
active: "node-properties",
|
|
937
|
-
panels: {
|
|
938
|
-
...state.workflow.sidebar.panels,
|
|
939
|
-
nodeProperties: {
|
|
940
|
-
...state.workflow.sidebar.panels.nodeProperties,
|
|
941
|
-
selectedNode: node
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
}));
|
|
947
|
-
},
|
|
948
|
-
panels: {
|
|
949
|
-
nodeProperties: {
|
|
950
|
-
setSelectedNode: (node) => set((state) => ({
|
|
951
|
-
workflow: {
|
|
952
|
-
...state.workflow,
|
|
953
|
-
sidebar: {
|
|
954
|
-
...state.workflow.sidebar,
|
|
955
|
-
panels: {
|
|
956
|
-
...state.workflow.sidebar.panels,
|
|
957
|
-
nodeProperties: {
|
|
958
|
-
...state.workflow.sidebar.panels.nodeProperties,
|
|
959
|
-
selectedNode: node
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
}))
|
|
965
|
-
},
|
|
966
|
-
tags: {
|
|
967
|
-
setTags: (tags) => set({ tags }),
|
|
968
|
-
createTag: (tag) => set((state) => ({
|
|
969
|
-
tags: [...state.tags, tag]
|
|
970
|
-
})),
|
|
971
|
-
updateTag: (tag, newTag) => set((state) => ({
|
|
972
|
-
tags: state.tags.map(
|
|
973
|
-
(f) => f.value === tag.value ? newTag : f
|
|
974
|
-
)
|
|
975
|
-
})),
|
|
976
|
-
deleteTag: (tag) => set((state) => ({
|
|
977
|
-
tags: state.tags.filter((f) => f.value !== tag.value)
|
|
978
|
-
}))
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
},
|
|
982
|
-
nodes: {
|
|
983
|
-
onNodesChange: (changes) => {
|
|
984
|
-
const removedIds = new Set(
|
|
985
|
-
changes.filter(
|
|
986
|
-
(c) => c.type === "remove"
|
|
987
|
-
).map((c) => c.id)
|
|
988
|
-
);
|
|
989
|
-
const addedCount = changes.filter((c) => c.type === "add").length;
|
|
990
|
-
if (removedIds.size > 0) {
|
|
991
|
-
const stillPresent = get().workflow.nodes.some(
|
|
992
|
-
(n) => removedIds.has(n.id)
|
|
993
|
-
);
|
|
994
|
-
if (stillPresent && !joinsPrecedingRemoval("nodes:remove")) {
|
|
995
|
-
pushCheckpoint("nodes:remove", false);
|
|
996
|
-
}
|
|
997
|
-
} else if (addedCount > 0) {
|
|
998
|
-
pushCheckpoint("nodes:add", false);
|
|
999
|
-
} else {
|
|
1000
|
-
const startsDrag = changes.some(
|
|
1001
|
-
(c) => c.type === "position" && c.dragging === true && !get().workflow.nodes.find((n) => n.id === c.id)?.dragging
|
|
1002
|
-
);
|
|
1003
|
-
if (startsDrag) noteEdit();
|
|
1004
|
-
const finishedDragIds = changes.filter(
|
|
1005
|
-
(c) => c.type === "position" && c.dragging === false
|
|
1006
|
-
);
|
|
1007
|
-
const actuallyMoved = finishedDragIds.some((c) => {
|
|
1008
|
-
const current = get().workflow.nodes.find((n) => n.id === c.id);
|
|
1009
|
-
return current && c.position && (current.position.x !== c.position.x || current.position.y !== c.position.y);
|
|
1010
|
-
});
|
|
1011
|
-
if (actuallyMoved) pushCheckpoint("nodes:move", false);
|
|
1012
|
-
}
|
|
1013
|
-
set(
|
|
1014
|
-
(state) => produce(state, (draft) => {
|
|
1015
|
-
const updatedNodes = applyNodeChanges(
|
|
1016
|
-
changes,
|
|
1017
|
-
draft.workflow.nodes
|
|
1018
|
-
);
|
|
1019
|
-
draft.workflow.nodes = updatedNodes;
|
|
1020
|
-
})
|
|
1021
|
-
);
|
|
1022
|
-
},
|
|
1023
|
-
setNodes: (nodes, opts) => {
|
|
1024
|
-
if (!opts?.skipHistory) {
|
|
1025
|
-
pushCheckpoint(
|
|
1026
|
-
opts?.historyKind ?? "nodes:set",
|
|
1027
|
-
!!opts?.historyKind
|
|
1028
|
-
);
|
|
1029
|
-
}
|
|
1030
|
-
set({ workflow: { ...get().workflow, nodes } });
|
|
1031
|
-
},
|
|
1032
|
-
deleteNode: (node) => {
|
|
1033
|
-
const exists = get().workflow.nodes.some((n) => n.id === node.id);
|
|
1034
|
-
if (exists) pushCheckpoint("nodes:delete", false);
|
|
1035
|
-
set((state) => ({
|
|
1036
|
-
workflow: {
|
|
1037
|
-
...state.workflow,
|
|
1038
|
-
nodes: state.workflow.nodes.filter((n) => n.id !== node.id),
|
|
1039
|
-
// Drop any UI state pointing at the removed node.
|
|
1040
|
-
...state.workflow.quickConfig?.nodeId === node.id ? { quickConfig: null } : {},
|
|
1041
|
-
...state.workflow.pendingConnection?.nodeId === node.id ? { pendingConnection: null } : {}
|
|
1042
|
-
}
|
|
1043
|
-
}));
|
|
1044
|
-
},
|
|
1045
|
-
deleteNodes: (nodes) => {
|
|
1046
|
-
const ids = new Set(nodes.map((n) => n.id));
|
|
1047
|
-
if (ids.size === 0) return;
|
|
1048
|
-
const anyExist = get().workflow.nodes.some((n) => ids.has(n.id));
|
|
1049
|
-
if (anyExist) pushCheckpoint("nodes:delete", false);
|
|
1050
|
-
set((state) => ({
|
|
1051
|
-
workflow: {
|
|
1052
|
-
...state.workflow,
|
|
1053
|
-
nodes: state.workflow.nodes.filter((n) => !ids.has(n.id)),
|
|
1054
|
-
edges: state.workflow.edges.filter(
|
|
1055
|
-
(e) => !ids.has(e.source) && !ids.has(e.target)
|
|
1056
|
-
),
|
|
1057
|
-
...state.workflow.quickConfig && ids.has(state.workflow.quickConfig.nodeId) ? { quickConfig: null } : {},
|
|
1058
|
-
...state.workflow.pendingConnection && ids.has(state.workflow.pendingConnection.nodeId) ? { pendingConnection: null } : {}
|
|
1059
|
-
}
|
|
1060
|
-
}));
|
|
1061
|
-
},
|
|
1062
|
-
duplicateNodes: (nodeIds) => {
|
|
1063
|
-
const { nodes, edges } = get().workflow;
|
|
1064
|
-
const idSet = new Set(nodeIds);
|
|
1065
|
-
const selected = nodes.filter((n) => idSet.has(n.id));
|
|
1066
|
-
if (selected.length === 0) return;
|
|
1067
|
-
pushCheckpoint("nodes:duplicate", false);
|
|
1068
|
-
const idMap = /* @__PURE__ */ new Map();
|
|
1069
|
-
const clones = selected.map((n) => {
|
|
1070
|
-
const newId = nanoid();
|
|
1071
|
-
idMap.set(n.id, newId);
|
|
1072
|
-
const cloned = cloneValue(n);
|
|
1073
|
-
return {
|
|
1074
|
-
...cloned,
|
|
1075
|
-
id: newId,
|
|
1076
|
-
position: {
|
|
1077
|
-
x: cloned.position.x + CLONE_OFFSET,
|
|
1078
|
-
y: cloned.position.y + CLONE_OFFSET
|
|
1079
|
-
},
|
|
1080
|
-
selected: true
|
|
1081
|
-
};
|
|
1082
|
-
});
|
|
1083
|
-
const clonedEdges = edges.filter((e) => idMap.has(e.source) && idMap.has(e.target)).map((e) => {
|
|
1084
|
-
const cloned = cloneValue(e);
|
|
1085
|
-
return {
|
|
1086
|
-
...cloned,
|
|
1087
|
-
id: nanoid(),
|
|
1088
|
-
source: idMap.get(e.source),
|
|
1089
|
-
target: idMap.get(e.target),
|
|
1090
|
-
selected: false
|
|
1091
|
-
};
|
|
1092
|
-
});
|
|
1093
|
-
set((state) => ({
|
|
1094
|
-
workflow: {
|
|
1095
|
-
...state.workflow,
|
|
1096
|
-
nodes: [
|
|
1097
|
-
...state.workflow.nodes.map(
|
|
1098
|
-
(n) => idSet.has(n.id) ? { ...n, selected: false } : n
|
|
1099
|
-
),
|
|
1100
|
-
...clones
|
|
1101
|
-
],
|
|
1102
|
-
edges: [...state.workflow.edges, ...clonedEdges]
|
|
1103
|
-
}
|
|
1104
|
-
}));
|
|
1105
|
-
},
|
|
1106
|
-
pasteNodes: (payload) => {
|
|
1107
|
-
const pasteNodesIn = payload.nodes ?? [];
|
|
1108
|
-
if (pasteNodesIn.length === 0) return;
|
|
1109
|
-
pushCheckpoint("nodes:paste", false);
|
|
1110
|
-
const idMap = /* @__PURE__ */ new Map();
|
|
1111
|
-
const clones = pasteNodesIn.map((n) => {
|
|
1112
|
-
const newId = nanoid();
|
|
1113
|
-
idMap.set(n.id, newId);
|
|
1114
|
-
const cloned = cloneValue(n);
|
|
1115
|
-
return {
|
|
1116
|
-
...cloned,
|
|
1117
|
-
id: newId,
|
|
1118
|
-
position: {
|
|
1119
|
-
x: (cloned.position?.x ?? 0) + CLONE_OFFSET,
|
|
1120
|
-
y: (cloned.position?.y ?? 0) + CLONE_OFFSET
|
|
1121
|
-
},
|
|
1122
|
-
selected: true
|
|
1123
|
-
};
|
|
1124
|
-
});
|
|
1125
|
-
const clonedEdges = (payload.edges ?? []).filter((e) => idMap.has(e.source) && idMap.has(e.target)).map((e) => {
|
|
1126
|
-
const cloned = cloneValue(e);
|
|
1127
|
-
return {
|
|
1128
|
-
...cloned,
|
|
1129
|
-
id: nanoid(),
|
|
1130
|
-
source: idMap.get(e.source),
|
|
1131
|
-
target: idMap.get(e.target),
|
|
1132
|
-
selected: false
|
|
1133
|
-
};
|
|
1134
|
-
});
|
|
1135
|
-
set((state) => ({
|
|
1136
|
-
workflow: {
|
|
1137
|
-
...state.workflow,
|
|
1138
|
-
nodes: [
|
|
1139
|
-
...state.workflow.nodes.map((n) => ({ ...n, selected: false })),
|
|
1140
|
-
...clones
|
|
1141
|
-
],
|
|
1142
|
-
edges: [...state.workflow.edges, ...clonedEdges]
|
|
1143
|
-
}
|
|
1144
|
-
}));
|
|
1145
|
-
},
|
|
1146
|
-
toggleDisabled: (nodeId) => {
|
|
1147
|
-
const { nodes, edges } = get().workflow;
|
|
1148
|
-
const updatedNodes = nodes.map((node) => {
|
|
1149
|
-
if (node.id !== nodeId) return node;
|
|
1150
|
-
const data = node.data ?? {};
|
|
1151
|
-
return {
|
|
1152
|
-
...node,
|
|
1153
|
-
data: { ...data, disabled: !(data.disabled === true) }
|
|
1154
|
-
};
|
|
1155
|
-
});
|
|
1156
|
-
const breaksLoop = edges.some(
|
|
1157
|
-
(edge) => edge.source === nodeId && isLoopBodyEdge(edge, nodes) && !isValidWorkflowConnection(updatedNodes, edges, edge)
|
|
1158
|
-
);
|
|
1159
|
-
if (breaksLoop) return false;
|
|
1160
|
-
pushCheckpoint("nodes:disable", false);
|
|
1161
|
-
set((state) => ({
|
|
1162
|
-
workflow: {
|
|
1163
|
-
...state.workflow,
|
|
1164
|
-
nodes: updatedNodes
|
|
1165
|
-
}
|
|
1166
|
-
}));
|
|
1167
|
-
return true;
|
|
1168
|
-
},
|
|
1169
|
-
renameNode: (nodeId, label) => {
|
|
1170
|
-
pushCheckpoint("nodes:rename", false);
|
|
1171
|
-
set((state) => ({
|
|
1172
|
-
workflow: {
|
|
1173
|
-
...state.workflow,
|
|
1174
|
-
nodes: state.workflow.nodes.map(
|
|
1175
|
-
(n) => n.id === nodeId ? { ...n, data: { ...n.data ?? {}, label } } : n
|
|
1176
|
-
),
|
|
1177
|
-
renamingNodeId: null
|
|
1178
|
-
}
|
|
1179
|
-
}));
|
|
1180
|
-
},
|
|
1181
|
-
startRename: (nodeId) => {
|
|
1182
|
-
set((state) => ({
|
|
1183
|
-
workflow: { ...state.workflow, renamingNodeId: nodeId }
|
|
1184
|
-
}));
|
|
1185
|
-
},
|
|
1186
|
-
endRename: () => {
|
|
1187
|
-
set((state) => ({
|
|
1188
|
-
workflow: { ...state.workflow, renamingNodeId: null }
|
|
1189
|
-
}));
|
|
1190
|
-
}
|
|
1191
|
-
},
|
|
1192
|
-
edges: {
|
|
1193
|
-
onEdgesChange: (changes) => {
|
|
1194
|
-
const removedIds = new Set(
|
|
1195
|
-
changes.filter(
|
|
1196
|
-
(c) => c.type === "remove"
|
|
1197
|
-
).map((c) => c.id)
|
|
1198
|
-
);
|
|
1199
|
-
if (removedIds.size > 0) {
|
|
1200
|
-
const stillPresent = get().workflow.edges.some(
|
|
1201
|
-
(e) => removedIds.has(e.id)
|
|
1202
|
-
);
|
|
1203
|
-
if (stillPresent && !joinsPrecedingRemoval("edges:remove")) {
|
|
1204
|
-
pushCheckpoint("edges:remove", false);
|
|
1205
|
-
}
|
|
1206
|
-
} else if (changes.some((c) => c.type === "add")) {
|
|
1207
|
-
pushCheckpoint("edges:add", false);
|
|
1208
|
-
}
|
|
1209
|
-
set(
|
|
1210
|
-
(state) => produce(state, (draft) => {
|
|
1211
|
-
const updatedEdges = applyEdgeChanges(
|
|
1212
|
-
changes,
|
|
1213
|
-
draft.workflow.edges
|
|
1214
|
-
);
|
|
1215
|
-
draft.workflow.edges = updatedEdges;
|
|
1216
|
-
})
|
|
1217
|
-
);
|
|
1218
|
-
},
|
|
1219
|
-
onConnect: (connection) => {
|
|
1220
|
-
pushCheckpoint("edges:connect", false);
|
|
1221
|
-
const edge = {
|
|
1222
|
-
...connection,
|
|
1223
|
-
id: nanoid(),
|
|
1224
|
-
type: "deletable"
|
|
1225
|
-
};
|
|
1226
|
-
set({
|
|
1227
|
-
workflow: {
|
|
1228
|
-
...get().workflow,
|
|
1229
|
-
edges: addEdge(edge, get().workflow.edges)
|
|
1230
|
-
}
|
|
1231
|
-
});
|
|
1232
|
-
},
|
|
1233
|
-
setEdges: (edges, opts) => {
|
|
1234
|
-
if (!opts?.skipHistory) {
|
|
1235
|
-
pushCheckpoint(
|
|
1236
|
-
opts?.historyKind ?? "edges:set",
|
|
1237
|
-
!!opts?.historyKind
|
|
1238
|
-
);
|
|
1239
|
-
}
|
|
1240
|
-
set({ workflow: { ...get().workflow, edges } });
|
|
1241
|
-
},
|
|
1242
|
-
deleteEdge: (edge) => {
|
|
1243
|
-
const exists = get().workflow.edges.some((e) => e.id === edge.id);
|
|
1244
|
-
if (exists) pushCheckpoint("edges:delete", false);
|
|
1245
|
-
set((state) => ({
|
|
1246
|
-
workflow: {
|
|
1247
|
-
...state.workflow,
|
|
1248
|
-
edges: state.workflow.edges.filter((e) => e.id !== edge.id)
|
|
1249
|
-
}
|
|
1250
|
-
}));
|
|
1251
|
-
}
|
|
1252
|
-
},
|
|
1253
|
-
execution: {
|
|
1254
|
-
startExecution: (nodeId, runId, metadata) => {
|
|
1255
|
-
set((state) => ({
|
|
1256
|
-
execution: {
|
|
1257
|
-
...state.execution,
|
|
1258
|
-
isExecuting: true,
|
|
1259
|
-
executingNodeId: nodeId,
|
|
1260
|
-
currentRunId: runId,
|
|
1261
|
-
sourceRun: metadata ? { runId, ...metadata } : { runId, workflowKey: "", version: "" },
|
|
1262
|
-
panelExpanded: true,
|
|
1263
|
-
nodeStatuses: {
|
|
1264
|
-
...state.execution.nodeStatuses,
|
|
1265
|
-
[nodeId]: "running"
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
}));
|
|
1269
|
-
},
|
|
1270
|
-
setRunMetadata: (metadata) => {
|
|
1271
|
-
set((state) => {
|
|
1272
|
-
if (state.execution.currentRunId !== metadata.runId && state.execution.sourceRun?.runId !== metadata.runId) {
|
|
1273
|
-
return state;
|
|
1274
|
-
}
|
|
1275
|
-
return {
|
|
1276
|
-
execution: {
|
|
1277
|
-
...state.execution,
|
|
1278
|
-
currentRunId: metadata.runId,
|
|
1279
|
-
sourceRun: metadata
|
|
1280
|
-
}
|
|
1281
|
-
};
|
|
1282
|
-
});
|
|
1283
|
-
},
|
|
1284
|
-
setStepPlan: (plan) => {
|
|
1285
|
-
set((state) => ({
|
|
1286
|
-
execution: {
|
|
1287
|
-
...state.execution,
|
|
1288
|
-
stepPlan: plan
|
|
1289
|
-
}
|
|
1290
|
-
}));
|
|
1291
|
-
},
|
|
1292
|
-
addLog: (log) => {
|
|
1293
|
-
set((state) => ({
|
|
1294
|
-
execution: {
|
|
1295
|
-
...state.execution,
|
|
1296
|
-
logs: [...state.execution.logs, log],
|
|
1297
|
-
selectedLogId: log.id
|
|
1298
|
-
}
|
|
1299
|
-
}));
|
|
1300
|
-
},
|
|
1301
|
-
updateLog: (logId, updates) => {
|
|
1302
|
-
set((state) => ({
|
|
1303
|
-
execution: {
|
|
1304
|
-
...state.execution,
|
|
1305
|
-
logs: state.execution.logs.map(
|
|
1306
|
-
(log) => log.id === logId ? { ...log, ...updates } : log
|
|
1307
|
-
)
|
|
1308
|
-
}
|
|
1309
|
-
}));
|
|
1310
|
-
},
|
|
1311
|
-
setNodeStatus: (nodeId, status) => {
|
|
1312
|
-
set((state) => ({
|
|
1313
|
-
execution: {
|
|
1314
|
-
...state.execution,
|
|
1315
|
-
nodeStatuses: {
|
|
1316
|
-
...state.execution.nodeStatuses,
|
|
1317
|
-
[nodeId]: status
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
}));
|
|
1321
|
-
},
|
|
1322
|
-
setNodeItemCount: (nodeId, count) => {
|
|
1323
|
-
set((state) => ({
|
|
1324
|
-
execution: {
|
|
1325
|
-
...state.execution,
|
|
1326
|
-
nodeItemCounts: {
|
|
1327
|
-
...state.execution.nodeItemCounts,
|
|
1328
|
-
[nodeId]: count
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
}));
|
|
1332
|
-
},
|
|
1333
|
-
selectLog: (logId) => {
|
|
1334
|
-
set((state) => ({
|
|
1335
|
-
execution: {
|
|
1336
|
-
...state.execution,
|
|
1337
|
-
selectedLogId: logId
|
|
1338
|
-
}
|
|
1339
|
-
}));
|
|
1340
|
-
},
|
|
1341
|
-
togglePanel: () => {
|
|
1342
|
-
set((state) => ({
|
|
1343
|
-
execution: {
|
|
1344
|
-
...state.execution,
|
|
1345
|
-
panelExpanded: !state.execution.panelExpanded
|
|
1346
|
-
}
|
|
1347
|
-
}));
|
|
1348
|
-
},
|
|
1349
|
-
clearLogs: () => {
|
|
1350
|
-
set((state) => ({
|
|
1351
|
-
execution: {
|
|
1352
|
-
...state.execution,
|
|
1353
|
-
logs: [],
|
|
1354
|
-
stepPlan: null,
|
|
1355
|
-
currentRunId: null,
|
|
1356
|
-
sourceRun: null,
|
|
1357
|
-
selectedLogId: null,
|
|
1358
|
-
nodeStatuses: {},
|
|
1359
|
-
nodeItemCounts: {}
|
|
1360
|
-
}
|
|
1361
|
-
}));
|
|
1362
|
-
},
|
|
1363
|
-
completeExecution: () => {
|
|
1364
|
-
set((state) => ({
|
|
1365
|
-
execution: {
|
|
1366
|
-
...state.execution,
|
|
1367
|
-
isExecuting: false,
|
|
1368
|
-
executingNodeId: null
|
|
1369
|
-
}
|
|
1370
|
-
}));
|
|
1371
|
-
},
|
|
1372
|
-
requestFollowRun: (runId, triggerNodeId) => {
|
|
1373
|
-
set((state) => ({
|
|
1374
|
-
execution: {
|
|
1375
|
-
...state.execution,
|
|
1376
|
-
followRequest: { runId, triggerNodeId }
|
|
1377
|
-
}
|
|
1378
|
-
}));
|
|
1379
|
-
},
|
|
1380
|
-
clearFollowRequest: () => {
|
|
1381
|
-
set((state) => ({
|
|
1382
|
-
execution: { ...state.execution, followRequest: null }
|
|
1383
|
-
}));
|
|
1384
|
-
},
|
|
1385
|
-
loadDebugRun: (runId, logs, metadata) => {
|
|
1386
|
-
const nodeStatuses = {};
|
|
1387
|
-
for (const log of logs) {
|
|
1388
|
-
nodeStatuses[log.nodeId] = log.status === "completed" ? "success" : log.status === "failed" ? "error" : log.status === "running" ? "running" : "idle";
|
|
1389
|
-
}
|
|
1390
|
-
set(() => ({
|
|
1391
|
-
execution: {
|
|
1392
|
-
...INITIAL_EXECUTION,
|
|
1393
|
-
currentRunId: runId,
|
|
1394
|
-
sourceRun: metadata ? { runId, ...metadata } : { runId, workflowKey: "", version: "" },
|
|
1395
|
-
logs,
|
|
1396
|
-
nodeStatuses,
|
|
1397
|
-
panelExpanded: true
|
|
1398
|
-
}
|
|
1399
|
-
}));
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
};
|
|
1404
|
-
});
|
|
1405
|
-
if (typeof window !== "undefined" && import.meta.env?.DEV) {
|
|
1406
|
-
window.__fgFlowStore = useFlowStore;
|
|
1407
|
-
}
|
|
1408
541
|
function useDeleteNode() {
|
|
1409
542
|
const { getNode, getEdges, deleteElements } = useReactFlow();
|
|
1410
543
|
const deleteNodes = useFlowStore((state) => state.actions.nodes.deleteNodes);
|
|
@@ -1420,11 +553,6 @@ function useDeleteNode() {
|
|
|
1420
553
|
[deleteElements, getEdges, getNode, deleteNodes]
|
|
1421
554
|
);
|
|
1422
555
|
}
|
|
1423
|
-
|
|
1424
|
-
// src/builder/contants/symbols.ts
|
|
1425
|
-
var NODE_TYPE_DRAG_DATA_FORMAT = "application/flow-builder.node-type";
|
|
1426
|
-
var NODE_OPERATION_DRAG_DATA_FORMAT = "application/flow-builder.node-operation";
|
|
1427
|
-
var STICKY_NOTE_TYPE = "sticky-note";
|
|
1428
556
|
var STICKY_COLORS = {
|
|
1429
557
|
yellow: "var(--color-chart-4)",
|
|
1430
558
|
orange: "var(--color-status-warning-bg)",
|
|
@@ -1520,7 +648,7 @@ function StickyNoteNodeComponent({
|
|
|
1520
648
|
if (!source) return;
|
|
1521
649
|
const clone = {
|
|
1522
650
|
...source,
|
|
1523
|
-
id: nanoid
|
|
651
|
+
id: nanoid(),
|
|
1524
652
|
position: {
|
|
1525
653
|
x: source.position.x + 24,
|
|
1526
654
|
y: source.position.y + 24
|
|
@@ -1644,1158 +772,204 @@ function StickyNoteNodeComponent({
|
|
|
1644
772
|
/* @__PURE__ */ jsx(
|
|
1645
773
|
"div",
|
|
1646
774
|
{
|
|
1647
|
-
className: "flex h-full w-full flex-col overflow-hidden rounded-lg border",
|
|
1648
|
-
style: {
|
|
1649
|
-
backgroundColor: `${accent}1F`,
|
|
1650
|
-
// Same border whether selected or not — selection shows only via the
|
|
1651
|
-
// floating toolbar (no extra border/outline on click).
|
|
1652
|
-
borderColor: `${accent}59`
|
|
1653
|
-
},
|
|
1654
|
-
onDoubleClick: (e) => {
|
|
1655
|
-
e.stopPropagation();
|
|
1656
|
-
if (!readOnly) startEditing();
|
|
1657
|
-
},
|
|
1658
|
-
children: editing ? /* @__PURE__ */ jsx(
|
|
1659
|
-
"textarea",
|
|
1660
|
-
{
|
|
1661
|
-
ref: textareaRef,
|
|
1662
|
-
readOnly,
|
|
1663
|
-
value: draft,
|
|
1664
|
-
onChange: (e) => setDraft(e.target.value),
|
|
1665
|
-
onBlur: commitEdit,
|
|
1666
|
-
onKeyDown: (e) => {
|
|
1667
|
-
e.stopPropagation();
|
|
1668
|
-
if (e.key === "Escape") cancelEdit();
|
|
1669
|
-
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) commitEdit();
|
|
1670
|
-
},
|
|
1671
|
-
placeholder: tr(
|
|
1672
|
-
"fluidgrids.builder.stickyNote.editorPlaceholder",
|
|
1673
|
-
"# Note\nSupports **markdown** \u2014 headings, lists, links\u2026"
|
|
1674
|
-
),
|
|
1675
|
-
className: "nodrag nowheel h-full w-full resize-none bg-transparent p-3 font-mono text-xs leading-relaxed text-foreground outline-none placeholder:text-muted-foreground/60"
|
|
1676
|
-
}
|
|
1677
|
-
) : content.trim() ? /* @__PURE__ */ jsx(
|
|
1678
|
-
"div",
|
|
1679
|
-
{
|
|
1680
|
-
className: cn(
|
|
1681
|
-
"nowheel h-full w-full overflow-auto p-3 text-xs leading-relaxed text-foreground",
|
|
1682
|
-
// Compact markdown typography scoped to the note body.
|
|
1683
|
-
"[&_h1]:mb-1.5 [&_h1]:text-sm [&_h1]:font-bold",
|
|
1684
|
-
"[&_h2]:mb-1 [&_h2]:text-[13px] [&_h2]:font-bold",
|
|
1685
|
-
"[&_h3]:mb-1 [&_h3]:text-xs [&_h3]:font-semibold",
|
|
1686
|
-
"[&_p]:mb-1.5 [&_ul]:mb-1.5 [&_ul]:list-disc [&_ul]:pl-4",
|
|
1687
|
-
"[&_ol]:mb-1.5 [&_ol]:list-decimal [&_ol]:pl-4 [&_li]:mb-0.5",
|
|
1688
|
-
"[&_a]:underline [&_code]:rounded [&_code]:bg-muted [&_code]:px-1"
|
|
1689
|
-
),
|
|
1690
|
-
children: /* @__PURE__ */ jsx(ReactMarkdown, { children: content })
|
|
1691
|
-
}
|
|
1692
|
-
) : /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center p-3 text-xs text-muted-foreground/70", children: tr(
|
|
1693
|
-
"fluidgrids.builder.stickyNote.emptyStateHint",
|
|
1694
|
-
"Double-click to edit"
|
|
1695
|
-
) })
|
|
1696
|
-
}
|
|
1697
|
-
)
|
|
1698
|
-
] })
|
|
1699
|
-
);
|
|
1700
|
-
}
|
|
1701
|
-
var StickyNoteNode = memo(StickyNoteNodeComponent);
|
|
1702
|
-
function buildStickyNode(position) {
|
|
1703
|
-
return {
|
|
1704
|
-
id: nanoid$1(),
|
|
1705
|
-
type: STICKY_NOTE_TYPE,
|
|
1706
|
-
position,
|
|
1707
|
-
width: STICKY_DEFAULT_SIZE.width,
|
|
1708
|
-
height: STICKY_DEFAULT_SIZE.height,
|
|
1709
|
-
// Render under regular nodes and edges — notes are a background layer.
|
|
1710
|
-
zIndex: -1,
|
|
1711
|
-
selected: true,
|
|
1712
|
-
data: { content: "", color: DEFAULT_STICKY_COLOR }
|
|
1713
|
-
};
|
|
1714
|
-
}
|
|
1715
|
-
|
|
1716
|
-
// src/modules/connections/utils/adapter-selection.ts
|
|
1717
|
-
var ANY_PROVIDER = "*";
|
|
1718
|
-
function isOptionalAdapter(adapter) {
|
|
1719
|
-
return adapter.required === false;
|
|
1720
|
-
}
|
|
1721
|
-
function newConnectionProviderKey(adapters) {
|
|
1722
|
-
if (adapters.length !== 1) return void 0;
|
|
1723
|
-
const provider = adapters[0]?.provider;
|
|
1724
|
-
return provider && provider !== ANY_PROVIDER ? provider : void 0;
|
|
1725
|
-
}
|
|
1726
|
-
function matchesAdapterProvider(adapter, providerKey) {
|
|
1727
|
-
const normalizedKey = providerKey.trim().toLowerCase();
|
|
1728
|
-
if (normalizedKey.length === 0) return false;
|
|
1729
|
-
if (adapter.provider.trim() === ANY_PROVIDER) return true;
|
|
1730
|
-
return adapter.provider.trim().toLowerCase() === normalizedKey || adapter.name.trim().toLowerCase() === normalizedKey;
|
|
1731
|
-
}
|
|
1732
|
-
function connectionsForAdapter(connections, adapterName) {
|
|
1733
|
-
return connections.filter(
|
|
1734
|
-
(connection) => connection.adapter.toLowerCase() === adapterName.toLowerCase()
|
|
1735
|
-
);
|
|
1736
|
-
}
|
|
1737
|
-
function replaceAdapterConnections(connections, adapterName, connectionIds = []) {
|
|
1738
|
-
const otherConnections = connections.filter(
|
|
1739
|
-
(connection) => connection.adapter.toLowerCase() !== adapterName.toLowerCase()
|
|
1740
|
-
);
|
|
1741
|
-
const uniqueIds = [...new Set(connectionIds.filter(Boolean))];
|
|
1742
|
-
return [
|
|
1743
|
-
...otherConnections,
|
|
1744
|
-
...uniqueIds.map((connectionId) => ({
|
|
1745
|
-
connectionId,
|
|
1746
|
-
adapter: adapterName
|
|
1747
|
-
}))
|
|
1748
|
-
];
|
|
1749
|
-
}
|
|
1750
|
-
function missingRequiredAdapters(adapters, selected) {
|
|
1751
|
-
return adapters.filter(
|
|
1752
|
-
(adapter) => !isOptionalAdapter(adapter) && !selected.some((connection) => connection.adapter === adapter.name)
|
|
1753
|
-
);
|
|
1754
|
-
}
|
|
1755
|
-
var NODE_DOCS_URL = gql`
|
|
1756
|
-
query NodeDocsUrlLookup($nodeType: String!, $nodeVersion: String!) {
|
|
1757
|
-
nodeEndpointConfig(nodeType: $nodeType, nodeVersion: $nodeVersion) {
|
|
1758
|
-
docsUrl
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
`;
|
|
1762
|
-
var cache = /* @__PURE__ */ new Map();
|
|
1763
|
-
var inFlight = /* @__PURE__ */ new Map();
|
|
1764
|
-
function fetchDocsUrl(nodeType, nodeVersion) {
|
|
1765
|
-
const key = `${nodeType}@${nodeVersion}`;
|
|
1766
|
-
if (cache.has(key)) return Promise.resolve(cache.get(key));
|
|
1767
|
-
const existing = inFlight.get(key);
|
|
1768
|
-
if (existing) return existing;
|
|
1769
|
-
const client = getFluidGridsClientSafe();
|
|
1770
|
-
if (!client) {
|
|
1771
|
-
cache.set(key, void 0);
|
|
1772
|
-
return Promise.resolve(void 0);
|
|
1773
|
-
}
|
|
1774
|
-
const promise = client.query({
|
|
1775
|
-
query: NODE_DOCS_URL,
|
|
1776
|
-
variables: { nodeType, nodeVersion },
|
|
1777
|
-
fetchPolicy: "cache-first"
|
|
1778
|
-
}).then((result) => result.data?.nodeEndpointConfig?.docsUrl ?? void 0).catch(() => void 0).finally(() => inFlight.delete(key));
|
|
1779
|
-
inFlight.set(key, promise);
|
|
1780
|
-
return promise.then((url) => {
|
|
1781
|
-
cache.set(key, url);
|
|
1782
|
-
return url;
|
|
1783
|
-
});
|
|
1784
|
-
}
|
|
1785
|
-
function useNodeDocsUrl(nodeType, nodeVersion) {
|
|
1786
|
-
const [docsUrl, setDocsUrl] = useState(
|
|
1787
|
-
() => nodeType && nodeVersion ? cache.get(`${nodeType}@${nodeVersion}`) : void 0
|
|
1788
|
-
);
|
|
1789
|
-
useEffect(() => {
|
|
1790
|
-
if (!nodeType || !nodeVersion) {
|
|
1791
|
-
setDocsUrl(void 0);
|
|
1792
|
-
return;
|
|
1793
|
-
}
|
|
1794
|
-
let cancelled = false;
|
|
1795
|
-
fetchDocsUrl(nodeType, nodeVersion).then((url) => {
|
|
1796
|
-
if (!cancelled) setDocsUrl(url);
|
|
1797
|
-
});
|
|
1798
|
-
return () => {
|
|
1799
|
-
cancelled = true;
|
|
1800
|
-
};
|
|
1801
|
-
}, [nodeType, nodeVersion]);
|
|
1802
|
-
return docsUrl;
|
|
1803
|
-
}
|
|
1804
|
-
function isImageIcon(icon) {
|
|
1805
|
-
return !!icon && (/^https?:\/\//.test(icon) || icon.startsWith("data:"));
|
|
1806
|
-
}
|
|
1807
|
-
function NodeTypeIcon({
|
|
1808
|
-
icon,
|
|
1809
|
-
alt,
|
|
1810
|
-
className,
|
|
1811
|
-
fallbackIcon = "mynaui:puzzle"
|
|
1812
|
-
}) {
|
|
1813
|
-
if (isImageIcon(icon)) {
|
|
1814
|
-
return /* @__PURE__ */ jsx(
|
|
1815
|
-
"img",
|
|
1816
|
-
{
|
|
1817
|
-
src: icon,
|
|
1818
|
-
alt: alt ?? "",
|
|
1819
|
-
className: cn("object-contain", className)
|
|
1820
|
-
}
|
|
1821
|
-
);
|
|
1822
|
-
}
|
|
1823
|
-
return /* @__PURE__ */ jsx(Icon, { icon: icon || fallbackIcon, className });
|
|
1824
|
-
}
|
|
1825
|
-
var PROVIDER_ACCENTS = [
|
|
1826
|
-
[/gmail|google/, "var(--color-chart-5)"],
|
|
1827
|
-
[/slack/, "var(--color-chart-3)"],
|
|
1828
|
-
[/github|gitlab/, nodeCategoryColor("utility")],
|
|
1829
|
-
[/stripe/, "var(--color-chart-12)"],
|
|
1830
|
-
[/discord|telegram/, "var(--color-chart-1)"],
|
|
1831
|
-
[/notion/, "var(--color-text-primary)"],
|
|
1832
|
-
[/whatsapp|sheet|excel/, "var(--color-chart-7)"],
|
|
1833
|
-
[/openai|anthropic|claude/, nodeCategoryColor("ai")],
|
|
1834
|
-
[/twilio/, "var(--color-chart-10)"],
|
|
1835
|
-
[/http|api|webhook|rest/, nodeCategoryColor("integration")],
|
|
1836
|
-
[/db|sql|postgres|mysql|mongo/, nodeCategoryColor("data")]
|
|
1837
|
-
];
|
|
1838
|
-
function nodeAccent(key) {
|
|
1839
|
-
const k = (key || "").toLowerCase();
|
|
1840
|
-
for (const [re, color] of PROVIDER_ACCENTS) if (re.test(k)) return color;
|
|
1841
|
-
return chartSeriesColor(chartSeriesIndex(k));
|
|
1842
|
-
}
|
|
1843
|
-
function tint(color, pct = 14) {
|
|
1844
|
-
return `color-mix(in srgb, ${color} ${pct}%, transparent)`;
|
|
1845
|
-
}
|
|
1846
|
-
function InlineEditableLabel({
|
|
1847
|
-
value,
|
|
1848
|
-
placeholder,
|
|
1849
|
-
editing,
|
|
1850
|
-
onStartEdit,
|
|
1851
|
-
onCommit,
|
|
1852
|
-
onCancel,
|
|
1853
|
-
className,
|
|
1854
|
-
inputClassName
|
|
1855
|
-
}) {
|
|
1856
|
-
const tr = useTr();
|
|
1857
|
-
const [draft, setDraft] = React.useState(value);
|
|
1858
|
-
const inputRef = React.useRef(null);
|
|
1859
|
-
React.useEffect(() => {
|
|
1860
|
-
if (!editing) return;
|
|
1861
|
-
setDraft(value);
|
|
1862
|
-
const raf = requestAnimationFrame(() => {
|
|
1863
|
-
inputRef.current?.focus();
|
|
1864
|
-
inputRef.current?.select();
|
|
1865
|
-
});
|
|
1866
|
-
return () => cancelAnimationFrame(raf);
|
|
1867
|
-
}, [editing, value]);
|
|
1868
|
-
if (editing) {
|
|
1869
|
-
return /* @__PURE__ */ jsx(
|
|
1870
|
-
"input",
|
|
1871
|
-
{
|
|
1872
|
-
ref: inputRef,
|
|
1873
|
-
value: draft,
|
|
1874
|
-
onChange: (e) => setDraft(e.target.value),
|
|
1875
|
-
onClick: (e) => e.stopPropagation(),
|
|
1876
|
-
onDoubleClick: (e) => e.stopPropagation(),
|
|
1877
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
1878
|
-
onKeyDown: (e) => {
|
|
1879
|
-
e.stopPropagation();
|
|
1880
|
-
if (e.key === "Enter") {
|
|
1881
|
-
e.preventDefault();
|
|
1882
|
-
onCommit(draft.trim());
|
|
1883
|
-
} else if (e.key === "Escape") {
|
|
1884
|
-
e.preventDefault();
|
|
1885
|
-
onCancel();
|
|
1886
|
-
}
|
|
1887
|
-
},
|
|
1888
|
-
onBlur: () => onCommit(draft.trim()),
|
|
1889
|
-
className: cn(
|
|
1890
|
-
"min-w-0 flex-1 rounded border border-primary/50 bg-card px-1 text-inherit outline-none",
|
|
1891
|
-
inputClassName
|
|
1892
|
-
)
|
|
1893
|
-
}
|
|
1894
|
-
);
|
|
1895
|
-
}
|
|
1896
|
-
return /* @__PURE__ */ jsx(
|
|
1897
|
-
"span",
|
|
1898
|
-
{
|
|
1899
|
-
className: cn("cursor-text truncate", className),
|
|
1900
|
-
title: tr(
|
|
1901
|
-
"fluidgrids.builder.nodeCard.renameTooltip",
|
|
1902
|
-
"Double-click or press F2 to rename"
|
|
1903
|
-
),
|
|
1904
|
-
onDoubleClick: (e) => {
|
|
1905
|
-
e.stopPropagation();
|
|
1906
|
-
onStartEdit();
|
|
1907
|
-
},
|
|
1908
|
-
children: value || placeholder
|
|
1909
|
-
}
|
|
1910
|
-
);
|
|
1911
|
-
}
|
|
1912
|
-
var NodeCard = React.forwardRef(
|
|
1913
|
-
({
|
|
1914
|
-
className,
|
|
1915
|
-
selected = false,
|
|
1916
|
-
executionStatus = "idle",
|
|
1917
|
-
itemCount,
|
|
1918
|
-
isTrigger = false,
|
|
1919
|
-
accent = nodeCategoryColor("action"),
|
|
1920
|
-
onSettings,
|
|
1921
|
-
onExecute,
|
|
1922
|
-
onDelete,
|
|
1923
|
-
isExecuting = false,
|
|
1924
|
-
infoButton,
|
|
1925
|
-
disabled = false,
|
|
1926
|
-
onToggleDisabled,
|
|
1927
|
-
children,
|
|
1928
|
-
...props
|
|
1929
|
-
}, ref) => {
|
|
1930
|
-
const tr = useTr();
|
|
1931
|
-
const [hovered, setHovered] = React.useState(false);
|
|
1932
|
-
const statusRing = executionStatus === "running" ? "ring-2 ring-[var(--color-status-success-border)] animate-pulse-border" : executionStatus === "success" ? "ring-2 ring-[var(--color-status-success-border)]" : executionStatus === "error" ? "ring-2 ring-[var(--color-status-error-border)]" : "";
|
|
1933
|
-
return /* @__PURE__ */ jsxs(
|
|
1934
|
-
"div",
|
|
1935
|
-
{
|
|
1936
|
-
className: "group/node relative",
|
|
1937
|
-
onMouseEnter: () => setHovered(true),
|
|
1938
|
-
onMouseLeave: () => setHovered(false),
|
|
1939
|
-
children: [
|
|
1940
|
-
itemCount !== void 0 && itemCount > 0 && /* @__PURE__ */ jsx("div", { className: "absolute -top-7 left-1/2 -translate-x-1/2 z-10", children: /* @__PURE__ */ jsxs("div", { className: "rounded-full border border-border bg-card px-2 py-0.5 text-[10px] font-medium text-muted-foreground shadow-sm", children: [
|
|
1941
|
-
itemCount,
|
|
1942
|
-
" ",
|
|
1943
|
-
itemCount !== 1 ? tr("fluidgrids.builder.nodeCard.itemCountOther", "items") : tr("fluidgrids.builder.nodeCard.itemCountOne", "item")
|
|
1944
|
-
] }) }),
|
|
1945
|
-
(onSettings || onExecute || onDelete || onToggleDisabled || infoButton) && /* @__PURE__ */ jsxs(
|
|
1946
|
-
"div",
|
|
1947
|
-
{
|
|
1948
|
-
className: cn(
|
|
1949
|
-
"absolute right-1 z-20 flex items-center gap-0.5 rounded-lg border border-border bg-card p-0.5 shadow-md transition-all duration-150",
|
|
1950
|
-
hovered ? "pointer-events-auto opacity-100" : "pointer-events-none opacity-0"
|
|
1951
|
-
),
|
|
1952
|
-
style: {
|
|
1953
|
-
// Inline offset (not a `-top-*` class) so it survives the host
|
|
1954
|
-
// app's Tailwind scan of fe-sdk source, which drops some spacing
|
|
1955
|
-
// utilities. The toolbar is ~30px tall; top:-15px centers it on
|
|
1956
|
-
// the card's top edge (half outside, half over the card).
|
|
1957
|
-
top: -15,
|
|
1958
|
-
transform: hovered ? "translateY(0)" : "translateY(4px)"
|
|
1959
|
-
},
|
|
1960
|
-
onClick: (e) => e.stopPropagation(),
|
|
1961
|
-
onDoubleClick: (e) => e.stopPropagation(),
|
|
1962
|
-
children: [
|
|
1963
|
-
onSettings && /* @__PURE__ */ jsx(
|
|
1964
|
-
ToolbarButton2,
|
|
1965
|
-
{
|
|
1966
|
-
title: tr(
|
|
1967
|
-
"fluidgrids.builder.nodeCard.configureTooltip",
|
|
1968
|
-
"Configure"
|
|
1969
|
-
),
|
|
1970
|
-
onClick: onSettings,
|
|
1971
|
-
children: /* @__PURE__ */ jsx(Icon, { icon: "lucide:sliders-horizontal", className: "size-4" })
|
|
1972
|
-
}
|
|
1973
|
-
),
|
|
1974
|
-
onExecute && /* @__PURE__ */ jsx(
|
|
1975
|
-
ToolbarButton2,
|
|
1976
|
-
{
|
|
1977
|
-
"data-agent": "confirm",
|
|
1978
|
-
title: tr(
|
|
1979
|
-
"fluidgrids.builder.nodeCard.executeTooltip",
|
|
1980
|
-
"Execute step"
|
|
1981
|
-
),
|
|
1982
|
-
onClick: onExecute,
|
|
1983
|
-
disabled: isExecuting,
|
|
1984
|
-
children: isExecuting ? /* @__PURE__ */ jsx(
|
|
1985
|
-
Icon,
|
|
1986
|
-
{
|
|
1987
|
-
icon: "svg-spinners:ring-resize",
|
|
1988
|
-
className: "size-4 text-[var(--color-status-success-text)]"
|
|
1989
|
-
}
|
|
1990
|
-
) : /* @__PURE__ */ jsx(
|
|
1991
|
-
Icon,
|
|
1992
|
-
{
|
|
1993
|
-
icon: "mdi:play",
|
|
1994
|
-
className: "size-4 text-[var(--color-status-success-text)]"
|
|
1995
|
-
}
|
|
1996
|
-
)
|
|
1997
|
-
}
|
|
1998
|
-
),
|
|
1999
|
-
infoButton,
|
|
2000
|
-
onToggleDisabled && /* @__PURE__ */ jsx(
|
|
2001
|
-
ToolbarButton2,
|
|
2002
|
-
{
|
|
2003
|
-
title: disabled ? tr(
|
|
2004
|
-
"fluidgrids.builder.nodeCard.enableTooltip",
|
|
2005
|
-
"Enable node"
|
|
2006
|
-
) : tr(
|
|
2007
|
-
"fluidgrids.builder.nodeCard.disableTooltip",
|
|
2008
|
-
"Disable node (skip on run)"
|
|
2009
|
-
),
|
|
2010
|
-
onClick: onToggleDisabled,
|
|
2011
|
-
children: /* @__PURE__ */ jsx(
|
|
2012
|
-
Icon,
|
|
2013
|
-
{
|
|
2014
|
-
icon: disabled ? "mdi:power" : "mdi:power-off",
|
|
2015
|
-
className: cn(
|
|
2016
|
-
"size-4",
|
|
2017
|
-
disabled ? "text-[var(--color-status-warning-text)]" : "text-muted-foreground"
|
|
2018
|
-
)
|
|
2019
|
-
}
|
|
2020
|
-
)
|
|
2021
|
-
}
|
|
2022
|
-
),
|
|
2023
|
-
onDelete && /* @__PURE__ */ jsx(
|
|
2024
|
-
ToolbarButton2,
|
|
2025
|
-
{
|
|
2026
|
-
title: tr(
|
|
2027
|
-
"fluidgrids.builder.nodeCard.deleteTooltip",
|
|
2028
|
-
"Delete"
|
|
2029
|
-
),
|
|
2030
|
-
onClick: onDelete,
|
|
2031
|
-
children: /* @__PURE__ */ jsx(
|
|
2032
|
-
Icon,
|
|
2033
|
-
{
|
|
2034
|
-
icon: "mynaui:trash",
|
|
2035
|
-
className: "size-4 text-[var(--color-status-error-text)]"
|
|
2036
|
-
}
|
|
2037
|
-
)
|
|
2038
|
-
}
|
|
2039
|
-
)
|
|
2040
|
-
]
|
|
2041
|
-
}
|
|
2042
|
-
),
|
|
2043
|
-
disabled && /* @__PURE__ */ jsx("div", { className: "absolute -top-2 right-2 z-10", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 rounded-full border border-[var(--color-status-warning-border)] bg-[var(--color-status-warning-bg)] px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-[var(--color-status-warning-text)] shadow-sm", children: [
|
|
2044
|
-
/* @__PURE__ */ jsx(Icon, { icon: "mdi:power-off", className: "size-2.5" }),
|
|
2045
|
-
tr("fluidgrids.builder.nodeCard.disabledBadge", "Disabled")
|
|
2046
|
-
] }) }),
|
|
2047
|
-
/* @__PURE__ */ jsxs(
|
|
2048
|
-
"div",
|
|
2049
|
-
{
|
|
2050
|
-
ref,
|
|
2051
|
-
"data-selected": selected,
|
|
2052
|
-
className: cn(
|
|
2053
|
-
"relative w-72 rounded-xl border border-border bg-card shadow-sm will-change-transform",
|
|
2054
|
-
statusRing,
|
|
2055
|
-
executionStatus === "success" && "animate-success-glow",
|
|
2056
|
-
disabled && "opacity-50 grayscale-[0.6]",
|
|
2057
|
-
className
|
|
2058
|
-
),
|
|
2059
|
-
style: {
|
|
2060
|
-
borderTop: `3px solid ${accent}`,
|
|
2061
|
-
transition: "transform 0.15s ease, box-shadow 0.15s ease",
|
|
2062
|
-
transform: hovered ? "translateY(-2px)" : "none",
|
|
2063
|
-
boxShadow: hovered ? "var(--shadow-float)" : void 0
|
|
2064
|
-
},
|
|
2065
|
-
...props,
|
|
2066
|
-
children: [
|
|
2067
|
-
/* @__PURE__ */ jsx(
|
|
2068
|
-
"div",
|
|
2069
|
-
{
|
|
2070
|
-
className: "pointer-events-none absolute -inset-0.5 transition-opacity duration-150",
|
|
2071
|
-
style: {
|
|
2072
|
-
borderRadius: 14,
|
|
2073
|
-
opacity: selected || hovered ? 1 : 0,
|
|
2074
|
-
boxShadow: selected ? `0 0 0 2px ${accent}, 0 0 0 5px ${tint(accent, 18)}` : `0 0 0 2px ${accent}`
|
|
2075
|
-
}
|
|
2076
|
-
}
|
|
2077
|
-
),
|
|
2078
|
-
isTrigger && /* @__PURE__ */ jsx(
|
|
2079
|
-
"div",
|
|
2080
|
-
{
|
|
2081
|
-
className: "absolute -top-2 -left-2 z-10 flex size-5 items-center justify-center rounded-full shadow-md ring-2 ring-card",
|
|
2082
|
-
style: { backgroundColor: "var(--color-status-success-text)" },
|
|
2083
|
-
children: /* @__PURE__ */ jsx(
|
|
2084
|
-
Icon,
|
|
2085
|
-
{
|
|
2086
|
-
icon: "mdi:lightning-bolt",
|
|
2087
|
-
className: "size-3",
|
|
2088
|
-
style: { color: "var(--color-status-success-text-inverse)" }
|
|
2089
|
-
}
|
|
2090
|
-
)
|
|
2091
|
-
}
|
|
2092
|
-
),
|
|
2093
|
-
children
|
|
2094
|
-
]
|
|
2095
|
-
}
|
|
2096
|
-
),
|
|
2097
|
-
executionStatus === "success" && /* @__PURE__ */ jsx(StatusCorner, { icon: "mdi:check", tone: "success" }),
|
|
2098
|
-
executionStatus === "error" && /* @__PURE__ */ jsx(StatusCorner, { icon: "mdi:close", tone: "error" }),
|
|
2099
|
-
executionStatus === "running" && /* @__PURE__ */ jsx(StatusCorner, { icon: "svg-spinners:ring-resize", tone: "success" })
|
|
2100
|
-
]
|
|
2101
|
-
}
|
|
2102
|
-
);
|
|
2103
|
-
}
|
|
2104
|
-
);
|
|
2105
|
-
NodeCard.displayName = "NodeCard";
|
|
2106
|
-
function ToolbarButton2({
|
|
2107
|
-
title,
|
|
2108
|
-
onClick,
|
|
2109
|
-
disabled,
|
|
2110
|
-
children,
|
|
2111
|
-
"data-agent": agent
|
|
2112
|
-
}) {
|
|
2113
|
-
return /* @__PURE__ */ jsx(
|
|
2114
|
-
"button",
|
|
2115
|
-
{
|
|
2116
|
-
type: "button",
|
|
2117
|
-
"data-agent": agent,
|
|
2118
|
-
title,
|
|
2119
|
-
disabled,
|
|
2120
|
-
onClick: (e) => {
|
|
2121
|
-
e.stopPropagation();
|
|
2122
|
-
onClick?.();
|
|
2123
|
-
},
|
|
2124
|
-
className: "flex size-6 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50",
|
|
2125
|
-
children
|
|
2126
|
-
}
|
|
2127
|
-
);
|
|
2128
|
-
}
|
|
2129
|
-
function StatusCorner({
|
|
2130
|
-
icon,
|
|
2131
|
-
tone
|
|
2132
|
-
}) {
|
|
2133
|
-
const bg = tone === "success" ? "var(--color-status-success-bg)" : "var(--color-status-error-bg)";
|
|
2134
|
-
const fg = tone === "success" ? "var(--color-status-success-text-inverse)" : "var(--color-status-error-text-inverse)";
|
|
2135
|
-
return /* @__PURE__ */ jsx("div", { className: "absolute -bottom-1.5 -right-1.5 z-10", children: /* @__PURE__ */ jsx(
|
|
2136
|
-
"div",
|
|
2137
|
-
{
|
|
2138
|
-
className: "rounded-full p-0.5 shadow-md animate-in zoom-in duration-200",
|
|
2139
|
-
style: { backgroundColor: bg },
|
|
2140
|
-
children: /* @__PURE__ */ jsx(Icon, { icon, className: "size-3", style: { color: fg } })
|
|
2141
|
-
}
|
|
2142
|
-
) });
|
|
2143
|
-
}
|
|
2144
|
-
var NodeCardHeader = React.forwardRef(
|
|
2145
|
-
({
|
|
2146
|
-
icon,
|
|
2147
|
-
appName,
|
|
2148
|
-
accentKey,
|
|
2149
|
-
missingCredentials = false,
|
|
2150
|
-
label,
|
|
2151
|
-
isRenaming = false,
|
|
2152
|
-
onStartRename,
|
|
2153
|
-
onCommitRename,
|
|
2154
|
-
onCancelRename
|
|
2155
|
-
}, ref) => {
|
|
2156
|
-
const tr = useTr();
|
|
2157
|
-
const accent = nodeAccent(accentKey);
|
|
2158
|
-
return /* @__PURE__ */ jsxs("div", { ref, className: "flex items-center gap-2.5 px-3 pb-3 pt-4", children: [
|
|
2159
|
-
/* @__PURE__ */ jsx(
|
|
2160
|
-
"div",
|
|
2161
|
-
{
|
|
2162
|
-
className: "flex size-8 shrink-0 items-center justify-center rounded-lg",
|
|
2163
|
-
style: {
|
|
2164
|
-
backgroundColor: tint(accent, 13),
|
|
2165
|
-
color: accent,
|
|
2166
|
-
border: `1px solid ${tint(accent, 26)}`
|
|
2167
|
-
},
|
|
2168
|
-
children: /* @__PURE__ */ jsx(NodeTypeIcon, { icon, alt: appName, className: "size-[18px]" })
|
|
2169
|
-
}
|
|
2170
|
-
),
|
|
2171
|
-
onStartRename && onCommitRename && onCancelRename ? /* @__PURE__ */ jsx(
|
|
2172
|
-
InlineEditableLabel,
|
|
2173
|
-
{
|
|
2174
|
-
value: label ?? "",
|
|
2175
|
-
placeholder: appName,
|
|
2176
|
-
editing: isRenaming,
|
|
2177
|
-
onStartEdit: onStartRename,
|
|
2178
|
-
onCommit: onCommitRename,
|
|
2179
|
-
onCancel: onCancelRename,
|
|
2180
|
-
className: "min-w-0 flex-1 truncate text-[11px] font-semibold uppercase tracking-wide text-muted-foreground",
|
|
2181
|
-
inputClassName: "text-[11px] font-semibold uppercase tracking-wide"
|
|
2182
|
-
}
|
|
2183
|
-
) : /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: label || appName }),
|
|
2184
|
-
missingCredentials && /* @__PURE__ */ jsx(
|
|
2185
|
-
"span",
|
|
2186
|
-
{
|
|
2187
|
-
title: tr(
|
|
2188
|
-
"fluidgrids.builder.nodeCard.missingCredentialsTooltip",
|
|
2189
|
-
"Credentials not configured"
|
|
2190
|
-
),
|
|
2191
|
-
className: "flex items-center text-[var(--color-status-warning-text)]",
|
|
2192
|
-
"aria-label": tr(
|
|
2193
|
-
"fluidgrids.builder.nodeCard.missingCredentialsAriaLabel",
|
|
2194
|
-
"Credentials not configured"
|
|
2195
|
-
),
|
|
2196
|
-
children: /* @__PURE__ */ jsx(Icon, { icon: "lucide:alert-triangle", className: "size-4" })
|
|
2197
|
-
}
|
|
2198
|
-
)
|
|
2199
|
-
] });
|
|
2200
|
-
}
|
|
2201
|
-
);
|
|
2202
|
-
NodeCardHeader.displayName = "NodeCardHeader";
|
|
2203
|
-
var NodeCardBody = React.forwardRef(
|
|
2204
|
-
({ operationName, description }, ref) => {
|
|
2205
|
-
const tr = useTr();
|
|
2206
|
-
return /* @__PURE__ */ jsxs(
|
|
2207
|
-
"div",
|
|
2208
|
-
{
|
|
2209
|
-
ref,
|
|
2210
|
-
className: "rounded-b-xl border-t border-border/60 px-3 pb-3 pt-2.5",
|
|
2211
|
-
children: [
|
|
2212
|
-
/* @__PURE__ */ jsx("div", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: tr("fluidgrids.builder.nodeCard.operationLabel", "Operation") }),
|
|
2213
|
-
/* @__PURE__ */ jsx("div", { className: "mt-0.5 truncate font-mono text-[13px] font-bold text-card-foreground", children: operationName }),
|
|
2214
|
-
description ? /* @__PURE__ */ jsx("p", { className: "mt-1 line-clamp-2 text-xs leading-snug text-muted-foreground", children: description }) : null
|
|
2215
|
-
]
|
|
2216
|
-
}
|
|
2217
|
-
);
|
|
2218
|
-
}
|
|
2219
|
-
);
|
|
2220
|
-
NodeCardBody.displayName = "NodeCardBody";
|
|
2221
|
-
function CustomHandle({
|
|
2222
|
-
className,
|
|
2223
|
-
isConnectable,
|
|
2224
|
-
accent,
|
|
2225
|
-
...props
|
|
2226
|
-
}) {
|
|
2227
|
-
const { nodeLookup, edges } = useStore(({ nodeLookup: nodeLookup2, edges: edges2 }) => ({
|
|
2228
|
-
nodeLookup: nodeLookup2,
|
|
2229
|
-
edges: edges2
|
|
2230
|
-
}));
|
|
2231
|
-
const nodeId = useNodeId();
|
|
2232
|
-
const isHandleConnectable = useMemo(() => {
|
|
2233
|
-
if (!nodeId) return false;
|
|
2234
|
-
const node = nodeLookup.get(nodeId);
|
|
2235
|
-
if (!node) return false;
|
|
2236
|
-
const connectedEdges = getConnectedEdges([node], edges);
|
|
2237
|
-
if (typeof isConnectable === "function")
|
|
2238
|
-
return isConnectable({ node, connectedEdges });
|
|
2239
|
-
if (typeof isConnectable === "number")
|
|
2240
|
-
return connectedEdges.length < isConnectable;
|
|
2241
|
-
return isConnectable;
|
|
2242
|
-
}, [edges, isConnectable, nodeId, nodeLookup]);
|
|
2243
|
-
return /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
|
|
2244
|
-
Handle,
|
|
2245
|
-
{
|
|
2246
|
-
className: cn(
|
|
2247
|
-
"cursor-crosshair transition-transform hover:scale-110",
|
|
2248
|
-
!accent && "size-3 border-2 border-card-foreground/40 hover:border-primary/50",
|
|
2249
|
-
className
|
|
2250
|
-
),
|
|
2251
|
-
isConnectable: isHandleConnectable,
|
|
2252
|
-
style: accent ? {
|
|
2253
|
-
width: 14,
|
|
2254
|
-
height: 14,
|
|
2255
|
-
borderRadius: "50%",
|
|
2256
|
-
background: "var(--color-node-bg)",
|
|
2257
|
-
border: `2.5px solid ${accent}`,
|
|
2258
|
-
boxShadow: `0 0 0 3px color-mix(in srgb, ${accent} 12%, transparent)`
|
|
2259
|
-
} : void 0,
|
|
2260
|
-
...props
|
|
2261
|
-
}
|
|
2262
|
-
) });
|
|
2263
|
-
}
|
|
2264
|
-
|
|
2265
|
-
// src/builder/components/flow-builder/components/blocks/nodes/node/handle-spec.ts
|
|
2266
|
-
function isDynamicSpec(spec) {
|
|
2267
|
-
return !!spec && !Array.isArray(spec) && typeof spec.fromStateRecord === "string";
|
|
2268
|
-
}
|
|
2269
|
-
var DEFAULT_HANDLES = [{ id: "source", label: "" }];
|
|
2270
|
-
var BUILTIN_OUTPUT_HANDLES = {
|
|
2271
|
-
"internal:wait-for-signal": [
|
|
2272
|
-
{ id: "received", label: "Received", tone: "success" },
|
|
2273
|
-
{ id: "timedOut", label: "Timed out", tone: "warning" }
|
|
2274
|
-
]
|
|
2275
|
-
};
|
|
2276
|
-
function resolveOutputHandles(data, nodeType) {
|
|
2277
|
-
const nodeData = data?.nodeData;
|
|
2278
|
-
const operationsBlob = Array.isArray(nodeData?.operations) ? void 0 : nodeData?.operations;
|
|
2279
|
-
const operationList = Array.isArray(nodeData?.operations) ? nodeData.operations : operationsBlob?.operations ?? [];
|
|
2280
|
-
const operationName = typeof data?.operation_name === "string" ? data.operation_name : void 0;
|
|
2281
|
-
const operationSpec = operationName ? operationList.find((op) => op?.name === operationName)?.outputHandles : void 0;
|
|
2282
|
-
const spec = operationSpec ?? nodeData?.outputHandles ?? operationsBlob?.outputHandles;
|
|
2283
|
-
if (!spec)
|
|
2284
|
-
return nodeType && BUILTIN_OUTPUT_HANDLES[nodeType] || DEFAULT_HANDLES;
|
|
2285
|
-
if (isDynamicSpec(spec)) {
|
|
2286
|
-
const args = data?.args;
|
|
2287
|
-
const record2 = args?.state?.[spec.fromStateRecord] ?? data?.[spec.fromStateRecord] ?? {};
|
|
2288
|
-
const dynamic = Object.entries(record2).filter(([, handleId]) => typeof handleId === "string" && handleId).map(([label, handleId]) => ({ id: handleId, label }));
|
|
2289
|
-
return [...dynamic, ...spec.extra ?? []];
|
|
2290
|
-
}
|
|
2291
|
-
if (spec.length === 0) return DEFAULT_HANDLES;
|
|
2292
|
-
return spec;
|
|
2293
|
-
}
|
|
2294
|
-
var DEFAULT_INPUT_HANDLES = [{ id: "target", label: "" }];
|
|
2295
|
-
function resolveInputHandles(data) {
|
|
2296
|
-
const nodeData = data?.nodeData;
|
|
2297
|
-
const spec = nodeData?.inputHandles ?? nodeData?.operations?.inputHandles;
|
|
2298
|
-
if (!Array.isArray(spec) || spec.length === 0) return DEFAULT_INPUT_HANDLES;
|
|
2299
|
-
return spec;
|
|
2300
|
-
}
|
|
2301
|
-
function outputHandlesSpacerHeight(count) {
|
|
2302
|
-
return count > 2 ? (count - 2) * 26 : 0;
|
|
2303
|
-
}
|
|
2304
|
-
var TONE_COLORS = {
|
|
2305
|
-
success: "var(--color-status-success-text)",
|
|
2306
|
-
error: "var(--color-status-error-text)",
|
|
2307
|
-
warning: "var(--color-status-warning-text)",
|
|
2308
|
-
info: "var(--color-status-info-text)",
|
|
2309
|
-
neutral: "var(--color-text-muted)"
|
|
2310
|
-
};
|
|
2311
|
-
function HandlePlusStub({
|
|
2312
|
-
nodeId,
|
|
2313
|
-
handleId,
|
|
2314
|
-
color,
|
|
2315
|
-
isConnectable,
|
|
2316
|
-
isOnlyHandle,
|
|
2317
|
-
anchor
|
|
2318
|
-
}) {
|
|
2319
|
-
const tr = useTr();
|
|
2320
|
-
const startAttach = useFlowStore((s) => s.actions.pendingConnection.start);
|
|
2321
|
-
const isArmedHere = useFlowStore(
|
|
2322
|
-
(s) => s.workflow.pendingConnection?.nodeId === nodeId && s.workflow.pendingConnection?.handleId === handleId
|
|
2323
|
-
);
|
|
2324
|
-
const hasOutgoing = useStore(
|
|
2325
|
-
(s) => s.edges.some(
|
|
2326
|
-
(e) => e.source === nodeId && (e.sourceHandle === handleId || isOnlyHandle && (e.sourceHandle === null || e.sourceHandle === void 0))
|
|
2327
|
-
)
|
|
2328
|
-
);
|
|
2329
|
-
if (hasOutgoing || isConnectable === false) return null;
|
|
2330
|
-
const containerStyle = anchor === "card" ? {
|
|
2331
|
-
left: "100%",
|
|
2332
|
-
top: "50%",
|
|
2333
|
-
transform: "translateY(-50%)",
|
|
2334
|
-
marginLeft: 10
|
|
2335
|
-
} : { left: 10, top: 0, transform: "translateY(-50%)" };
|
|
2336
|
-
return /* @__PURE__ */ jsxs(
|
|
2337
|
-
"div",
|
|
2338
|
-
{
|
|
2339
|
-
className: "nodrag nopan absolute flex items-center",
|
|
2340
|
-
style: { ...containerStyle, pointerEvents: "none", zIndex: 5 },
|
|
2341
|
-
children: [
|
|
2342
|
-
/* @__PURE__ */ jsx(
|
|
2343
|
-
"div",
|
|
2344
|
-
{
|
|
2345
|
-
style: {
|
|
2346
|
-
width: 16,
|
|
2347
|
-
borderTop: `1.5px dashed ${color}`,
|
|
2348
|
-
opacity: 0.5
|
|
2349
|
-
}
|
|
2350
|
-
}
|
|
2351
|
-
),
|
|
2352
|
-
/* @__PURE__ */ jsx(
|
|
2353
|
-
"button",
|
|
2354
|
-
{
|
|
2355
|
-
type: "button",
|
|
2356
|
-
title: tr(
|
|
2357
|
-
"fluidgrids.builder.outputHandles.addNextNodeTooltip",
|
|
2358
|
-
"Add next node"
|
|
2359
|
-
),
|
|
2360
|
-
"aria-label": `Add next node from ${handleId}`,
|
|
2361
|
-
"data-testid": `handle-plus-${nodeId}-${handleId}`,
|
|
2362
|
-
onClick: (e) => {
|
|
2363
|
-
e.stopPropagation();
|
|
2364
|
-
startAttach({ nodeId, handleId });
|
|
2365
|
-
},
|
|
2366
|
-
onDoubleClick: (e) => e.stopPropagation(),
|
|
2367
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
2368
|
-
className: "cursor-pointer transition-transform hover:scale-110",
|
|
2369
|
-
style: {
|
|
2370
|
-
pointerEvents: "all",
|
|
2371
|
-
width: 16,
|
|
2372
|
-
height: 16,
|
|
2373
|
-
borderRadius: "50%",
|
|
2374
|
-
display: "flex",
|
|
2375
|
-
alignItems: "center",
|
|
2376
|
-
justifyContent: "center",
|
|
2377
|
-
border: `1.5px solid ${color}`,
|
|
2378
|
-
background: isArmedHere ? color : "var(--color-node-bg)",
|
|
2379
|
-
color: isArmedHere ? "var(--color-node-bg)" : color,
|
|
2380
|
-
boxShadow: isArmedHere ? `0 0 0 3px color-mix(in srgb, ${color} 22%, transparent)` : `0 0 0 2px color-mix(in srgb, ${color} 10%, transparent)`,
|
|
2381
|
-
transition: "transform .12s ease, background .12s ease, color .12s ease"
|
|
2382
|
-
},
|
|
2383
|
-
children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:plus", className: "size-2.5" })
|
|
2384
|
-
}
|
|
2385
|
-
)
|
|
2386
|
-
]
|
|
2387
|
-
}
|
|
2388
|
-
);
|
|
2389
|
-
}
|
|
2390
|
-
function OutputHandles({
|
|
2391
|
-
nodeId,
|
|
2392
|
-
handles,
|
|
2393
|
-
accent,
|
|
2394
|
-
isConnectable
|
|
2395
|
-
}) {
|
|
2396
|
-
const updateNodeInternals = useUpdateNodeInternals();
|
|
2397
|
-
const signature = useMemo(
|
|
2398
|
-
() => handles.map((h) => h.id).join("|"),
|
|
2399
|
-
[handles]
|
|
2400
|
-
);
|
|
2401
|
-
useEffect(() => {
|
|
2402
|
-
updateNodeInternals(nodeId);
|
|
2403
|
-
}, [nodeId, signature, updateNodeInternals]);
|
|
2404
|
-
if (handles.length === 1) {
|
|
2405
|
-
const handle = handles[0];
|
|
2406
|
-
const color = handle.tone ? TONE_COLORS[handle.tone] : accent;
|
|
2407
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2408
|
-
/* @__PURE__ */ jsx(
|
|
2409
|
-
CustomHandle,
|
|
2410
|
-
{
|
|
2411
|
-
type: "source",
|
|
2412
|
-
id: handle.id,
|
|
2413
|
-
position: Position.Right,
|
|
2414
|
-
isConnectable,
|
|
2415
|
-
accent: color
|
|
2416
|
-
}
|
|
2417
|
-
),
|
|
2418
|
-
/* @__PURE__ */ jsx(
|
|
2419
|
-
HandlePlusStub,
|
|
2420
|
-
{
|
|
2421
|
-
nodeId,
|
|
2422
|
-
handleId: handle.id,
|
|
2423
|
-
color,
|
|
2424
|
-
isConnectable,
|
|
2425
|
-
isOnlyHandle: true,
|
|
2426
|
-
anchor: "card"
|
|
2427
|
-
}
|
|
2428
|
-
)
|
|
2429
|
-
] });
|
|
2430
|
-
}
|
|
2431
|
-
const total = handles.length;
|
|
2432
|
-
return /* @__PURE__ */ jsx(Fragment, { children: handles.map((handle, index) => {
|
|
2433
|
-
const top = `${(index + 1) / (total + 1) * 100}%`;
|
|
2434
|
-
const color = handle.tone ? TONE_COLORS[handle.tone] : accent;
|
|
2435
|
-
return /* @__PURE__ */ jsxs(
|
|
2436
|
-
"div",
|
|
2437
|
-
{
|
|
2438
|
-
className: "absolute right-0",
|
|
2439
|
-
style: { top, transform: "translateY(-50%)" },
|
|
2440
|
-
children: [
|
|
2441
|
-
/* @__PURE__ */ jsx(
|
|
2442
|
-
CustomHandle,
|
|
2443
|
-
{
|
|
2444
|
-
type: "source",
|
|
2445
|
-
id: handle.id,
|
|
2446
|
-
position: Position.Right,
|
|
2447
|
-
isConnectable,
|
|
2448
|
-
accent: color
|
|
2449
|
-
}
|
|
2450
|
-
),
|
|
2451
|
-
handle.label && /* @__PURE__ */ jsx(
|
|
2452
|
-
"span",
|
|
775
|
+
className: "flex h-full w-full flex-col overflow-hidden rounded-lg border",
|
|
776
|
+
style: {
|
|
777
|
+
backgroundColor: `${accent}1F`,
|
|
778
|
+
// Same border whether selected or not — selection shows only via the
|
|
779
|
+
// floating toolbar (no extra border/outline on click).
|
|
780
|
+
borderColor: `${accent}59`
|
|
781
|
+
},
|
|
782
|
+
onDoubleClick: (e) => {
|
|
783
|
+
e.stopPropagation();
|
|
784
|
+
if (!readOnly) startEditing();
|
|
785
|
+
},
|
|
786
|
+
children: editing ? /* @__PURE__ */ jsx(
|
|
787
|
+
"textarea",
|
|
2453
788
|
{
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
789
|
+
ref: textareaRef,
|
|
790
|
+
readOnly,
|
|
791
|
+
value: draft,
|
|
792
|
+
onChange: (e) => setDraft(e.target.value),
|
|
793
|
+
onBlur: commitEdit,
|
|
794
|
+
onKeyDown: (e) => {
|
|
795
|
+
e.stopPropagation();
|
|
796
|
+
if (e.key === "Escape") cancelEdit();
|
|
797
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) commitEdit();
|
|
798
|
+
},
|
|
799
|
+
placeholder: tr(
|
|
800
|
+
"fluidgrids.builder.stickyNote.editorPlaceholder",
|
|
801
|
+
"# Note\nSupports **markdown** \u2014 headings, lists, links\u2026"
|
|
802
|
+
),
|
|
803
|
+
className: "nodrag nowheel h-full w-full resize-none bg-transparent p-3 font-mono text-xs leading-relaxed text-foreground outline-none placeholder:text-muted-foreground/60"
|
|
2458
804
|
}
|
|
2459
|
-
)
|
|
2460
|
-
|
|
2461
|
-
HandlePlusStub,
|
|
805
|
+
) : content.trim() ? /* @__PURE__ */ jsx(
|
|
806
|
+
"div",
|
|
2462
807
|
{
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
808
|
+
className: cn(
|
|
809
|
+
"nowheel h-full w-full overflow-auto p-3 text-xs leading-relaxed text-foreground",
|
|
810
|
+
// Compact markdown typography scoped to the note body.
|
|
811
|
+
"[&_h1]:mb-1.5 [&_h1]:text-sm [&_h1]:font-bold",
|
|
812
|
+
"[&_h2]:mb-1 [&_h2]:text-[13px] [&_h2]:font-bold",
|
|
813
|
+
"[&_h3]:mb-1 [&_h3]:text-xs [&_h3]:font-semibold",
|
|
814
|
+
"[&_p]:mb-1.5 [&_ul]:mb-1.5 [&_ul]:list-disc [&_ul]:pl-4",
|
|
815
|
+
"[&_ol]:mb-1.5 [&_ol]:list-decimal [&_ol]:pl-4 [&_li]:mb-0.5",
|
|
816
|
+
"[&_a]:underline [&_code]:rounded [&_code]:bg-muted [&_code]:px-1"
|
|
817
|
+
),
|
|
818
|
+
children: /* @__PURE__ */ jsx(ReactMarkdown, { children: content })
|
|
2469
819
|
}
|
|
2470
|
-
)
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
}
|
|
2477
|
-
function InputHandles({
|
|
2478
|
-
nodeId,
|
|
2479
|
-
handles,
|
|
2480
|
-
accent,
|
|
2481
|
-
isConnectable
|
|
2482
|
-
}) {
|
|
2483
|
-
const updateNodeInternals = useUpdateNodeInternals();
|
|
2484
|
-
const signature = useMemo(
|
|
2485
|
-
() => handles.map((h) => h.id).join("|"),
|
|
2486
|
-
[handles]
|
|
820
|
+
) : /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center p-3 text-xs text-muted-foreground/70", children: tr(
|
|
821
|
+
"fluidgrids.builder.stickyNote.emptyStateHint",
|
|
822
|
+
"Double-click to edit"
|
|
823
|
+
) })
|
|
824
|
+
}
|
|
825
|
+
)
|
|
826
|
+
] })
|
|
2487
827
|
);
|
|
2488
|
-
useEffect(() => {
|
|
2489
|
-
updateNodeInternals(nodeId);
|
|
2490
|
-
}, [nodeId, signature, updateNodeInternals]);
|
|
2491
|
-
if (handles.length === 1) {
|
|
2492
|
-
const handle = handles[0];
|
|
2493
|
-
return /* @__PURE__ */ jsx(
|
|
2494
|
-
CustomHandle,
|
|
2495
|
-
{
|
|
2496
|
-
type: "target",
|
|
2497
|
-
id: handle.id,
|
|
2498
|
-
position: Position.Left,
|
|
2499
|
-
isConnectable,
|
|
2500
|
-
accent: handle.tone ? TONE_COLORS[handle.tone] : accent
|
|
2501
|
-
}
|
|
2502
|
-
);
|
|
2503
|
-
}
|
|
2504
|
-
const total = handles.length;
|
|
2505
|
-
return /* @__PURE__ */ jsx(Fragment, { children: handles.map((handle, index) => {
|
|
2506
|
-
const top = `${(index + 1) / (total + 1) * 100}%`;
|
|
2507
|
-
const color = handle.tone ? TONE_COLORS[handle.tone] : accent;
|
|
2508
|
-
return /* @__PURE__ */ jsxs(
|
|
2509
|
-
"div",
|
|
2510
|
-
{
|
|
2511
|
-
className: "absolute left-0",
|
|
2512
|
-
style: { top, transform: "translateY(-50%)" },
|
|
2513
|
-
children: [
|
|
2514
|
-
/* @__PURE__ */ jsx(
|
|
2515
|
-
CustomHandle,
|
|
2516
|
-
{
|
|
2517
|
-
type: "target",
|
|
2518
|
-
id: handle.id,
|
|
2519
|
-
position: Position.Left,
|
|
2520
|
-
isConnectable,
|
|
2521
|
-
accent: color
|
|
2522
|
-
}
|
|
2523
|
-
),
|
|
2524
|
-
handle.label && /* @__PURE__ */ jsx(
|
|
2525
|
-
"span",
|
|
2526
|
-
{
|
|
2527
|
-
className: "pointer-events-none absolute whitespace-nowrap text-[10px] font-medium leading-none",
|
|
2528
|
-
style: {
|
|
2529
|
-
color,
|
|
2530
|
-
right: "100%",
|
|
2531
|
-
marginRight: 16,
|
|
2532
|
-
top: "50%",
|
|
2533
|
-
transform: "translateY(-50%)"
|
|
2534
|
-
},
|
|
2535
|
-
title: handle.label,
|
|
2536
|
-
children: handle.label
|
|
2537
|
-
}
|
|
2538
|
-
)
|
|
2539
|
-
]
|
|
2540
|
-
},
|
|
2541
|
-
handle.id
|
|
2542
|
-
);
|
|
2543
|
-
}) });
|
|
2544
828
|
}
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
isConnectable,
|
|
2559
|
-
onClick,
|
|
2560
|
-
onDoubleClick,
|
|
2561
|
-
onSettings,
|
|
2562
|
-
onExecute,
|
|
2563
|
-
onDelete,
|
|
2564
|
-
infoButton,
|
|
2565
|
-
disabled = false,
|
|
2566
|
-
onToggleDisabled,
|
|
2567
|
-
isRenaming = false,
|
|
2568
|
-
onStartRename,
|
|
2569
|
-
onCommitRename,
|
|
2570
|
-
onCancelRename
|
|
2571
|
-
}) {
|
|
2572
|
-
const minHeight = Math.max(
|
|
2573
|
-
64,
|
|
2574
|
-
Math.max(outputHandles.length, inputHandles.length) * 30 + 24
|
|
2575
|
-
);
|
|
2576
|
-
return /* @__PURE__ */ jsxs(
|
|
2577
|
-
NodeCard,
|
|
2578
|
-
{
|
|
2579
|
-
className: "w-48",
|
|
2580
|
-
"data-selected": selected,
|
|
2581
|
-
selected,
|
|
2582
|
-
onClick,
|
|
2583
|
-
onDoubleClick,
|
|
2584
|
-
executionStatus,
|
|
2585
|
-
itemCount,
|
|
2586
|
-
isTrigger,
|
|
2587
|
-
accent,
|
|
2588
|
-
isExecuting,
|
|
2589
|
-
onSettings,
|
|
2590
|
-
onExecute,
|
|
2591
|
-
onDelete,
|
|
2592
|
-
infoButton,
|
|
2593
|
-
disabled,
|
|
2594
|
-
onToggleDisabled,
|
|
2595
|
-
children: [
|
|
2596
|
-
/* @__PURE__ */ jsxs(
|
|
2597
|
-
"div",
|
|
2598
|
-
{
|
|
2599
|
-
className: "flex flex-col items-center justify-center gap-1 px-3 py-3 text-center",
|
|
2600
|
-
style: { minHeight },
|
|
2601
|
-
children: [
|
|
2602
|
-
/* @__PURE__ */ jsx("div", { className: "flex size-9 items-center justify-center rounded-lg bg-muted", children: /* @__PURE__ */ jsx(Icon, { icon, className: "size-5", style: { color: accent } }) }),
|
|
2603
|
-
onStartRename && onCommitRename && onCancelRename ? /* @__PURE__ */ jsx(
|
|
2604
|
-
InlineEditableLabel,
|
|
2605
|
-
{
|
|
2606
|
-
value: title,
|
|
2607
|
-
placeholder: title,
|
|
2608
|
-
editing: isRenaming,
|
|
2609
|
-
onStartEdit: onStartRename,
|
|
2610
|
-
onCommit: onCommitRename,
|
|
2611
|
-
onCancel: onCancelRename,
|
|
2612
|
-
className: "max-w-full truncate text-sm font-semibold leading-tight",
|
|
2613
|
-
inputClassName: "text-sm font-semibold text-center"
|
|
2614
|
-
}
|
|
2615
|
-
) : /* @__PURE__ */ jsx("span", { className: "max-w-full truncate text-sm font-semibold leading-tight", children: title }),
|
|
2616
|
-
subtitle && /* @__PURE__ */ jsx(
|
|
2617
|
-
"span",
|
|
2618
|
-
{
|
|
2619
|
-
className: "max-w-full truncate font-mono text-[10px] text-muted-foreground",
|
|
2620
|
-
title: subtitle,
|
|
2621
|
-
children: subtitle
|
|
2622
|
-
}
|
|
2623
|
-
)
|
|
2624
|
-
]
|
|
2625
|
-
}
|
|
2626
|
-
),
|
|
2627
|
-
/* @__PURE__ */ jsx(
|
|
2628
|
-
InputHandles,
|
|
2629
|
-
{
|
|
2630
|
-
nodeId,
|
|
2631
|
-
handles: inputHandles,
|
|
2632
|
-
accent,
|
|
2633
|
-
isConnectable
|
|
2634
|
-
}
|
|
2635
|
-
),
|
|
2636
|
-
/* @__PURE__ */ jsx(
|
|
2637
|
-
OutputHandles,
|
|
2638
|
-
{
|
|
2639
|
-
nodeId,
|
|
2640
|
-
handles: outputHandles,
|
|
2641
|
-
accent,
|
|
2642
|
-
isConnectable
|
|
2643
|
-
}
|
|
2644
|
-
)
|
|
2645
|
-
]
|
|
2646
|
-
}
|
|
2647
|
-
);
|
|
829
|
+
var StickyNoteNode = memo(StickyNoteNodeComponent);
|
|
830
|
+
function buildStickyNode(position) {
|
|
831
|
+
return {
|
|
832
|
+
id: nanoid(),
|
|
833
|
+
type: STICKY_NOTE_TYPE,
|
|
834
|
+
position,
|
|
835
|
+
width: STICKY_DEFAULT_SIZE.width,
|
|
836
|
+
height: STICKY_DEFAULT_SIZE.height,
|
|
837
|
+
// Render under regular nodes and edges — notes are a background layer.
|
|
838
|
+
zIndex: -1,
|
|
839
|
+
selected: true,
|
|
840
|
+
data: { content: "", color: DEFAULT_STICKY_COLOR }
|
|
841
|
+
};
|
|
2648
842
|
}
|
|
2649
843
|
|
|
2650
|
-
// src/
|
|
2651
|
-
var
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2655
|
-
}
|
|
2656
|
-
function str(value) {
|
|
2657
|
-
return typeof value === "string" && value.trim() ? value : void 0;
|
|
844
|
+
// src/modules/connections/utils/adapter-selection.ts
|
|
845
|
+
var ANY_PROVIDER = "*";
|
|
846
|
+
function isOptionalAdapter(adapter) {
|
|
847
|
+
return adapter.required === false;
|
|
2658
848
|
}
|
|
2659
|
-
function
|
|
2660
|
-
|
|
2661
|
-
const
|
|
2662
|
-
|
|
2663
|
-
return {
|
|
2664
|
-
workflowFn: str(s.workflowFn),
|
|
2665
|
-
taskQueue: str(s.taskQueue) ?? "managed",
|
|
2666
|
-
waitForCompletion,
|
|
2667
|
-
parentClosePolicy: policy === "TERMINATE" || policy === "ABANDON" || policy === "REQUEST_CANCEL" ? policy : waitForCompletion ? "TERMINATE" : "ABANDON",
|
|
2668
|
-
timeout: typeof s.timeout === "number" && s.timeout > 0 ? s.timeout : 0
|
|
2669
|
-
};
|
|
849
|
+
function newConnectionProviderKey(adapters) {
|
|
850
|
+
if (adapters.length !== 1) return void 0;
|
|
851
|
+
const provider = adapters[0]?.provider;
|
|
852
|
+
return provider && provider !== ANY_PROVIDER ? provider : void 0;
|
|
2670
853
|
}
|
|
2671
|
-
function
|
|
2672
|
-
|
|
854
|
+
function matchesAdapterProvider(adapter, providerKey) {
|
|
855
|
+
const normalizedKey = providerKey.trim().toLowerCase();
|
|
856
|
+
if (normalizedKey.length === 0) return false;
|
|
857
|
+
if (adapter.provider.trim() === ANY_PROVIDER) return true;
|
|
858
|
+
return adapter.provider.trim().toLowerCase() === normalizedKey || adapter.name.trim().toLowerCase() === normalizedKey;
|
|
2673
859
|
}
|
|
2674
|
-
function
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
if (schema.type === "array") return `${typeLabel(schema.items)}[]`;
|
|
2679
|
-
return typeof schema.type === "string" ? schema.type : "any";
|
|
860
|
+
function connectionsForAdapter(connections, adapterName) {
|
|
861
|
+
return connections.filter(
|
|
862
|
+
(connection) => connection.adapter.toLowerCase() === adapterName.toLowerCase()
|
|
863
|
+
);
|
|
2680
864
|
}
|
|
2681
|
-
function
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
Array.isArray(schema.required) ? schema.required.map(String) : []
|
|
865
|
+
function replaceAdapterConnections(connections, adapterName, connectionIds = []) {
|
|
866
|
+
const otherConnections = connections.filter(
|
|
867
|
+
(connection) => connection.adapter.toLowerCase() !== adapterName.toLowerCase()
|
|
2685
868
|
);
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
869
|
+
const uniqueIds = [...new Set(connectionIds.filter(Boolean))];
|
|
870
|
+
return [
|
|
871
|
+
...otherConnections,
|
|
872
|
+
...uniqueIds.map((connectionId) => ({
|
|
873
|
+
connectionId,
|
|
874
|
+
adapter: adapterName
|
|
875
|
+
}))
|
|
876
|
+
];
|
|
2692
877
|
}
|
|
2693
|
-
function
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
queries: of("queries"),
|
|
2698
|
-
updates: of("updates")
|
|
2699
|
-
};
|
|
878
|
+
function missingRequiredAdapters(adapters, selected) {
|
|
879
|
+
return adapters.filter(
|
|
880
|
+
(adapter) => !isOptionalAdapter(adapter) && !selected.some((connection) => connection.adapter === adapter.name)
|
|
881
|
+
);
|
|
2700
882
|
}
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
const fromColumn = str(state.childRunId);
|
|
2706
|
-
if (fromColumn) return fromColumn;
|
|
2707
|
-
if (isRecord3(state.output)) {
|
|
2708
|
-
const fromOutput = str(state.output._childRunId);
|
|
2709
|
-
if (fromOutput) return fromOutput;
|
|
883
|
+
var NODE_DOCS_URL = gql`
|
|
884
|
+
query NodeDocsUrlLookup($nodeType: String!, $nodeVersion: String!) {
|
|
885
|
+
nodeEndpointConfig(nodeType: $nodeType, nodeVersion: $nodeVersion) {
|
|
886
|
+
docsUrl
|
|
2710
887
|
}
|
|
2711
888
|
}
|
|
2712
|
-
|
|
889
|
+
`;
|
|
890
|
+
var cache = /* @__PURE__ */ new Map();
|
|
891
|
+
var inFlight = /* @__PURE__ */ new Map();
|
|
892
|
+
function fetchDocsUrl(nodeType, nodeVersion) {
|
|
893
|
+
const key = `${nodeType}@${nodeVersion}`;
|
|
894
|
+
if (cache.has(key)) return Promise.resolve(cache.get(key));
|
|
895
|
+
const existing = inFlight.get(key);
|
|
896
|
+
if (existing) return existing;
|
|
897
|
+
const client = getFluidGridsClientSafe();
|
|
898
|
+
if (!client) {
|
|
899
|
+
cache.set(key, void 0);
|
|
900
|
+
return Promise.resolve(void 0);
|
|
901
|
+
}
|
|
902
|
+
const promise = client.query({
|
|
903
|
+
query: NODE_DOCS_URL,
|
|
904
|
+
variables: { nodeType, nodeVersion },
|
|
905
|
+
fetchPolicy: "cache-first"
|
|
906
|
+
}).then((result) => result.data?.nodeEndpointConfig?.docsUrl ?? void 0).catch(() => void 0).finally(() => inFlight.delete(key));
|
|
907
|
+
inFlight.set(key, promise);
|
|
908
|
+
return promise.then((url) => {
|
|
909
|
+
cache.set(key, url);
|
|
910
|
+
return url;
|
|
911
|
+
});
|
|
2713
912
|
}
|
|
2714
|
-
function
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
return files.some(
|
|
2727
|
-
(file) => file.path.startsWith("workflows/") && file.path.endsWith(".py")
|
|
2728
|
-
) ? "python" : "typescript";
|
|
2729
|
-
}
|
|
2730
|
-
function changedSourceFiles(loaded, current) {
|
|
2731
|
-
return loaded.filter((file) => {
|
|
2732
|
-
const now = current[file.path];
|
|
2733
|
-
return now !== void 0 && now !== file.content;
|
|
2734
|
-
}).map((file) => ({ path: file.path, content: current[file.path] })).sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
2735
|
-
}
|
|
2736
|
-
function defaultSourcePath(files, entry) {
|
|
2737
|
-
if (entry && files.some((file) => file.path === entry)) return entry;
|
|
2738
|
-
return files.find(
|
|
2739
|
-
(file) => file.path.startsWith("workflows/") && isEditableSourcePath(file.path)
|
|
2740
|
-
)?.path ?? files[0]?.path;
|
|
2741
|
-
}
|
|
2742
|
-
function diagnosticsByPath(diagnostics) {
|
|
2743
|
-
const result = /* @__PURE__ */ new Map();
|
|
2744
|
-
for (const diagnostic of diagnostics) {
|
|
2745
|
-
const path = diagnostic.path?.replace(/^\.\//, "") ?? "";
|
|
2746
|
-
const list = result.get(path) ?? [];
|
|
2747
|
-
list.push({
|
|
2748
|
-
line: diagnostic.line,
|
|
2749
|
-
column: diagnostic.column,
|
|
2750
|
-
severity: editorSeverity(diagnostic.severity),
|
|
2751
|
-
code: diagnostic.code,
|
|
2752
|
-
message: diagnostic.message
|
|
913
|
+
function useNodeDocsUrl(nodeType, nodeVersion) {
|
|
914
|
+
const [docsUrl, setDocsUrl] = useState(
|
|
915
|
+
() => nodeType && nodeVersion ? cache.get(`${nodeType}@${nodeVersion}`) : void 0
|
|
916
|
+
);
|
|
917
|
+
useEffect(() => {
|
|
918
|
+
if (!nodeType || !nodeVersion) {
|
|
919
|
+
setDocsUrl(void 0);
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
let cancelled = false;
|
|
923
|
+
fetchDocsUrl(nodeType, nodeVersion).then((url) => {
|
|
924
|
+
if (!cancelled) setDocsUrl(url);
|
|
2753
925
|
});
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
926
|
+
return () => {
|
|
927
|
+
cancelled = true;
|
|
928
|
+
};
|
|
929
|
+
}, [nodeType, nodeVersion]);
|
|
930
|
+
return docsUrl;
|
|
2757
931
|
}
|
|
2758
932
|
|
|
2759
933
|
// src/modules/executions/utils/signal-targets.ts
|
|
2760
|
-
function
|
|
934
|
+
function isRecord(value) {
|
|
2761
935
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2762
936
|
}
|
|
2763
|
-
function
|
|
937
|
+
function str(value) {
|
|
2764
938
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
2765
939
|
}
|
|
2766
940
|
function durableInterfaceOf(definitionJson, workflowFn) {
|
|
2767
|
-
if (!
|
|
941
|
+
if (!isRecord(definitionJson)) return void 0;
|
|
2768
942
|
const code = definitionJson.code;
|
|
2769
|
-
if (
|
|
943
|
+
if (isRecord(code) && isRecord(code.exports) && workflowFn) {
|
|
2770
944
|
const workflows = code.exports.workflows;
|
|
2771
|
-
if (
|
|
945
|
+
if (isRecord(workflows)) {
|
|
2772
946
|
const entry = workflows[workflowFn];
|
|
2773
|
-
if (
|
|
947
|
+
if (isRecord(entry) && isRecord(entry.interface)) return entry.interface;
|
|
2774
948
|
}
|
|
2775
949
|
}
|
|
2776
|
-
return
|
|
950
|
+
return isRecord(definitionJson.interface) ? definitionJson.interface : void 0;
|
|
2777
951
|
}
|
|
2778
952
|
function declaredSignals(iface) {
|
|
2779
953
|
if (!iface) return { targets: [], openNames: false };
|
|
2780
|
-
const signals =
|
|
954
|
+
const signals = isRecord(iface.signals) ? iface.signals : {};
|
|
2781
955
|
const targets = Object.keys(signals).sort().map((name) => {
|
|
2782
956
|
const entry = signals[name];
|
|
2783
|
-
const payload =
|
|
957
|
+
const payload = isRecord(entry) && isRecord(entry.payload) ? entry.payload : void 0;
|
|
2784
958
|
return payload ? { name, payloadSchema: payload } : { name };
|
|
2785
959
|
});
|
|
2786
|
-
const open =
|
|
960
|
+
const open = isRecord(iface.open) && iface.open.signals === true;
|
|
2787
961
|
return { targets, openNames: open };
|
|
2788
962
|
}
|
|
2789
963
|
function nodeStateArgs(node) {
|
|
2790
|
-
if (!
|
|
2791
|
-
const root =
|
|
2792
|
-
if (root &&
|
|
2793
|
-
const data =
|
|
2794
|
-
const mirror = data &&
|
|
2795
|
-
return mirror &&
|
|
964
|
+
if (!isRecord(node)) return void 0;
|
|
965
|
+
const root = isRecord(node.args) ? node.args : void 0;
|
|
966
|
+
if (root && isRecord(root.state)) return root.state;
|
|
967
|
+
const data = isRecord(node.data) ? node.data : void 0;
|
|
968
|
+
const mirror = data && isRecord(data.args) ? data.args : void 0;
|
|
969
|
+
return mirror && isRecord(mirror.state) ? mirror.state : void 0;
|
|
2796
970
|
}
|
|
2797
971
|
function definitionNodes(definitionJson) {
|
|
2798
|
-
if (!
|
|
972
|
+
if (!isRecord(definitionJson) || !isRecord(definitionJson.data)) return [];
|
|
2799
973
|
const nodes = definitionJson.data.nodes;
|
|
2800
974
|
return Array.isArray(nodes) ? nodes : [];
|
|
2801
975
|
}
|
|
@@ -2804,16 +978,16 @@ function parkedSignalTargets(nodeStates, definitionJson) {
|
|
|
2804
978
|
const result = [];
|
|
2805
979
|
const seen = /* @__PURE__ */ new Set();
|
|
2806
980
|
for (const state of nodeStates) {
|
|
2807
|
-
if (state.status !== "WAITING" || !
|
|
981
|
+
if (state.status !== "WAITING" || !isRecord(state.output)) continue;
|
|
2808
982
|
if (state.output._waiting !== "signal") continue;
|
|
2809
|
-
const name =
|
|
983
|
+
const name = str(state.output._signalName);
|
|
2810
984
|
if (!name || seen.has(`${state.nodeId}:${name}`)) continue;
|
|
2811
985
|
seen.add(`${state.nodeId}:${name}`);
|
|
2812
986
|
const node = nodes.find(
|
|
2813
|
-
(candidate) =>
|
|
987
|
+
(candidate) => isRecord(candidate) && candidate.id === state.nodeId
|
|
2814
988
|
);
|
|
2815
989
|
const args = nodeStateArgs(node);
|
|
2816
|
-
const schema = args &&
|
|
990
|
+
const schema = args && isRecord(args.payloadSchema) ? args.payloadSchema : void 0;
|
|
2817
991
|
result.push(
|
|
2818
992
|
schema ? { name, payloadSchema: schema, nodeId: state.nodeId } : { name, nodeId: state.nodeId }
|
|
2819
993
|
);
|
|
@@ -2836,9 +1010,9 @@ function canSignalRun(targets) {
|
|
|
2836
1010
|
return targets.targets.length > 0 || targets.openNames;
|
|
2837
1011
|
}
|
|
2838
1012
|
function fieldOf(name, schema, required) {
|
|
2839
|
-
if (!
|
|
2840
|
-
const title =
|
|
2841
|
-
const description =
|
|
1013
|
+
if (!isRecord(schema)) return null;
|
|
1014
|
+
const title = str(schema.title) ?? name;
|
|
1015
|
+
const description = str(schema.description);
|
|
2842
1016
|
if (Array.isArray(schema.enum)) {
|
|
2843
1017
|
const choices = schema.enum.filter(
|
|
2844
1018
|
(value) => typeof value === "string"
|
|
@@ -2853,7 +1027,7 @@ function fieldOf(name, schema, required) {
|
|
|
2853
1027
|
return null;
|
|
2854
1028
|
}
|
|
2855
1029
|
function formFieldsOf(schema) {
|
|
2856
|
-
if (!schema || schema.type !== "object" || !
|
|
1030
|
+
if (!schema || schema.type !== "object" || !isRecord(schema.properties))
|
|
2857
1031
|
return null;
|
|
2858
1032
|
const required = new Set(
|
|
2859
1033
|
Array.isArray(schema.required) ? schema.required.filter(
|
|
@@ -3134,20 +1308,20 @@ function listCustomBlocks() {
|
|
|
3134
1308
|
// src/builder/components/lib/expression-preview.ts
|
|
3135
1309
|
var PURE_EXPRESSION_REGEX = /^\{\{(.*)\}\}$/s;
|
|
3136
1310
|
var PURE_LEGACY_REGEX = /^\$\{(.*)\}$/s;
|
|
3137
|
-
function containsExpressionSyntax(
|
|
3138
|
-
return typeof
|
|
1311
|
+
function containsExpressionSyntax(str2) {
|
|
1312
|
+
return typeof str2 === "string" && str2.includes("{{");
|
|
3139
1313
|
}
|
|
3140
|
-
function findEmbeddedExpressions(
|
|
1314
|
+
function findEmbeddedExpressions(str2) {
|
|
3141
1315
|
const matches2 = [];
|
|
3142
1316
|
let searchFrom = 0;
|
|
3143
|
-
while (searchFrom <
|
|
3144
|
-
const start =
|
|
1317
|
+
while (searchFrom < str2.length) {
|
|
1318
|
+
const start = str2.indexOf("{{", searchFrom);
|
|
3145
1319
|
if (start === -1) break;
|
|
3146
|
-
const end =
|
|
1320
|
+
const end = str2.indexOf("}}", start + 2);
|
|
3147
1321
|
if (end === -1) break;
|
|
3148
1322
|
matches2.push({
|
|
3149
|
-
full:
|
|
3150
|
-
expression:
|
|
1323
|
+
full: str2.slice(start, end + 2),
|
|
1324
|
+
expression: str2.slice(start + 2, end).trim()
|
|
3151
1325
|
});
|
|
3152
1326
|
searchFrom = end + 2;
|
|
3153
1327
|
}
|
|
@@ -3237,9 +1411,9 @@ function stringifyForInterpolation(value) {
|
|
|
3237
1411
|
if (typeof value === "object") return JSON.stringify(value);
|
|
3238
1412
|
return String(value);
|
|
3239
1413
|
}
|
|
3240
|
-
function previewNewSyntax(
|
|
1414
|
+
function previewNewSyntax(str2, scope) {
|
|
3241
1415
|
const sandbox = buildExpressionSandbox(scope);
|
|
3242
|
-
const pure = PURE_EXPRESSION_REGEX.exec(
|
|
1416
|
+
const pure = PURE_EXPRESSION_REGEX.exec(str2);
|
|
3243
1417
|
try {
|
|
3244
1418
|
if (pure) {
|
|
3245
1419
|
const expression = pure[1]?.trim();
|
|
@@ -3248,8 +1422,8 @@ function previewNewSyntax(str3, scope) {
|
|
|
3248
1422
|
}
|
|
3249
1423
|
return { isTemplate: true, value: evaluateBare(expression, sandbox) };
|
|
3250
1424
|
}
|
|
3251
|
-
let result =
|
|
3252
|
-
for (const match of findEmbeddedExpressions(
|
|
1425
|
+
let result = str2;
|
|
1426
|
+
for (const match of findEmbeddedExpressions(str2)) {
|
|
3253
1427
|
if (!match.expression) continue;
|
|
3254
1428
|
const value = evaluateBare(match.expression, sandbox);
|
|
3255
1429
|
result = result.replace(match.full, stringifyForInterpolation(value));
|
|
@@ -3262,7 +1436,7 @@ function previewNewSyntax(str3, scope) {
|
|
|
3262
1436
|
};
|
|
3263
1437
|
}
|
|
3264
1438
|
}
|
|
3265
|
-
function previewLegacySyntax(
|
|
1439
|
+
function previewLegacySyntax(str2, scope) {
|
|
3266
1440
|
const sandbox = {
|
|
3267
1441
|
...SAFE_GLOBALS,
|
|
3268
1442
|
output: scope.input,
|
|
@@ -3279,19 +1453,19 @@ function previewLegacySyntax(str3, scope) {
|
|
|
3279
1453
|
version: scope.version ?? "1.0.0"
|
|
3280
1454
|
}
|
|
3281
1455
|
};
|
|
3282
|
-
const pure = PURE_LEGACY_REGEX.exec(
|
|
1456
|
+
const pure = PURE_LEGACY_REGEX.exec(str2);
|
|
3283
1457
|
try {
|
|
3284
1458
|
if (pure) {
|
|
3285
1459
|
const expression = pure[1]?.trim();
|
|
3286
1460
|
if (!expression) return { isTemplate: true, error: "Empty expression" };
|
|
3287
1461
|
return { isTemplate: true, value: evaluateBare(expression, sandbox) };
|
|
3288
1462
|
}
|
|
3289
|
-
if (!
|
|
1463
|
+
if (!str2.includes("${")) {
|
|
3290
1464
|
return { isTemplate: false };
|
|
3291
1465
|
}
|
|
3292
|
-
let result =
|
|
1466
|
+
let result = str2;
|
|
3293
1467
|
const templateRegex = /\$\{([^}]+)\}/g;
|
|
3294
|
-
for (const match of
|
|
1468
|
+
for (const match of str2.matchAll(templateRegex)) {
|
|
3295
1469
|
const expression = match[1]?.trim();
|
|
3296
1470
|
if (!expression) continue;
|
|
3297
1471
|
const value = evaluateBare(expression, sandbox);
|
|
@@ -3305,14 +1479,14 @@ function previewLegacySyntax(str3, scope) {
|
|
|
3305
1479
|
};
|
|
3306
1480
|
}
|
|
3307
1481
|
}
|
|
3308
|
-
function evaluateExpressionPreview(
|
|
3309
|
-
if (typeof
|
|
1482
|
+
function evaluateExpressionPreview(str2, scope) {
|
|
1483
|
+
if (typeof str2 !== "string" || str2.trim() === "") {
|
|
3310
1484
|
return { isTemplate: false };
|
|
3311
1485
|
}
|
|
3312
|
-
if (containsExpressionSyntax(
|
|
3313
|
-
return previewNewSyntax(
|
|
1486
|
+
if (containsExpressionSyntax(str2)) {
|
|
1487
|
+
return previewNewSyntax(str2, scope);
|
|
3314
1488
|
}
|
|
3315
|
-
return previewLegacySyntax(
|
|
1489
|
+
return previewLegacySyntax(str2, scope);
|
|
3316
1490
|
}
|
|
3317
1491
|
var EXPRESSION_BUILTINS = [
|
|
3318
1492
|
{ insert: "$json", label: "$json", description: "Current item's data" },
|
|
@@ -4361,7 +2535,7 @@ var AdaptiveCardRenderer = forwardRef(function AdaptiveCardRenderer2({ cardData,
|
|
|
4361
2535
|
var components_default = AdaptiveCardRenderer;
|
|
4362
2536
|
|
|
4363
2537
|
// src/modules/ui-blocks/parse.ts
|
|
4364
|
-
function
|
|
2538
|
+
function isRecord2(value) {
|
|
4365
2539
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4366
2540
|
}
|
|
4367
2541
|
function humanizeFieldName(name) {
|
|
@@ -4372,7 +2546,7 @@ function synthesizeCardFromInputFields(inputFields) {
|
|
|
4372
2546
|
if (names.length === 0) return null;
|
|
4373
2547
|
const body = [];
|
|
4374
2548
|
for (const name of names) {
|
|
4375
|
-
const field =
|
|
2549
|
+
const field = isRecord2(inputFields[name]) ? inputFields[name] : {};
|
|
4376
2550
|
const description = typeof field.description === "string" ? field.description : void 0;
|
|
4377
2551
|
const required = field.required === true;
|
|
4378
2552
|
const secret = field.secret === true;
|
|
@@ -4403,9 +2577,9 @@ function synthesizeCardFromInputFields(inputFields) {
|
|
|
4403
2577
|
}
|
|
4404
2578
|
function secretFieldNames(inputFields) {
|
|
4405
2579
|
const names = /* @__PURE__ */ new Set();
|
|
4406
|
-
if (!
|
|
2580
|
+
if (!isRecord2(inputFields)) return names;
|
|
4407
2581
|
for (const [name, field] of Object.entries(inputFields)) {
|
|
4408
|
-
if (
|
|
2582
|
+
if (isRecord2(field) && field.secret === true) names.add(name);
|
|
4409
2583
|
}
|
|
4410
2584
|
return names;
|
|
4411
2585
|
}
|
|
@@ -4418,7 +2592,7 @@ function maskSecretInputs(card, secrets) {
|
|
|
4418
2592
|
if (secrets.size === 0) return card;
|
|
4419
2593
|
const visit = (value) => {
|
|
4420
2594
|
if (Array.isArray(value)) return value.map(visit);
|
|
4421
|
-
if (!
|
|
2595
|
+
if (!isRecord2(value)) return value;
|
|
4422
2596
|
const copy = {};
|
|
4423
2597
|
for (const [key, nested] of Object.entries(value))
|
|
4424
2598
|
copy[key] = visit(nested);
|
|
@@ -4432,7 +2606,7 @@ function maskSecretInputs(card, secrets) {
|
|
|
4432
2606
|
return visit(card);
|
|
4433
2607
|
}
|
|
4434
2608
|
function validateUiSpec(raw) {
|
|
4435
|
-
if (!
|
|
2609
|
+
if (!isRecord2(raw)) return "ui is not an object";
|
|
4436
2610
|
if (raw.version !== 1)
|
|
4437
2611
|
return `unsupported ui.version: ${String(raw.version)}`;
|
|
4438
2612
|
if (!Array.isArray(raw.blocks) || raw.blocks.length === 0) {
|
|
@@ -4441,7 +2615,7 @@ function validateUiSpec(raw) {
|
|
|
4441
2615
|
const seenIds = /* @__PURE__ */ new Set();
|
|
4442
2616
|
const blocks = [];
|
|
4443
2617
|
for (const [index, rawBlock] of raw.blocks.entries()) {
|
|
4444
|
-
if (!
|
|
2618
|
+
if (!isRecord2(rawBlock)) return `ui.blocks[${index}] is not an object`;
|
|
4445
2619
|
const id = rawBlock.id;
|
|
4446
2620
|
if (typeof id !== "string" || id.length === 0) {
|
|
4447
2621
|
return `ui.blocks[${index}] is missing a non-empty string id`;
|
|
@@ -4449,7 +2623,7 @@ function validateUiSpec(raw) {
|
|
|
4449
2623
|
if (seenIds.has(id)) return `ui.blocks has duplicate id "${id}"`;
|
|
4450
2624
|
seenIds.add(id);
|
|
4451
2625
|
if (rawBlock.type === "adaptive_card") {
|
|
4452
|
-
if (!
|
|
2626
|
+
if (!isRecord2(rawBlock.card)) {
|
|
4453
2627
|
return `ui.blocks[${index}] ("${id}") has no card object`;
|
|
4454
2628
|
}
|
|
4455
2629
|
blocks.push({ id, type: "adaptive_card", card: rawBlock.card });
|
|
@@ -4461,7 +2635,7 @@ function validateUiSpec(raw) {
|
|
|
4461
2635
|
id,
|
|
4462
2636
|
type: "custom",
|
|
4463
2637
|
component: rawBlock.component,
|
|
4464
|
-
props:
|
|
2638
|
+
props: isRecord2(rawBlock.props) ? rawBlock.props : void 0
|
|
4465
2639
|
});
|
|
4466
2640
|
} else {
|
|
4467
2641
|
return `ui.blocks[${index}] ("${id}") has unknown type "${String(rawBlock.type)}"`;
|
|
@@ -4488,7 +2662,7 @@ function resolveUiSpec(operation) {
|
|
|
4488
2662
|
`ui-blocks: invalid ui declaration on operation "${operation.name ?? "?"}" (${result}); falling back to adaptive_card`
|
|
4489
2663
|
);
|
|
4490
2664
|
}
|
|
4491
|
-
if (
|
|
2665
|
+
if (isRecord2(operation.adaptive_card)) {
|
|
4492
2666
|
return {
|
|
4493
2667
|
spec: {
|
|
4494
2668
|
version: 1,
|
|
@@ -4503,7 +2677,7 @@ function resolveUiSpec(operation) {
|
|
|
4503
2677
|
synthesized: true
|
|
4504
2678
|
};
|
|
4505
2679
|
}
|
|
4506
|
-
if (
|
|
2680
|
+
if (isRecord2(operation.input_fields)) {
|
|
4507
2681
|
const card = synthesizeCardFromInputFields(operation.input_fields);
|
|
4508
2682
|
if (card) {
|
|
4509
2683
|
return {
|
|
@@ -4518,17 +2692,17 @@ function resolveUiSpec(operation) {
|
|
|
4518
2692
|
return null;
|
|
4519
2693
|
}
|
|
4520
2694
|
function isSubmitAction(action) {
|
|
4521
|
-
return
|
|
2695
|
+
return isRecord2(action) && action.type === "Action.Submit";
|
|
4522
2696
|
}
|
|
4523
2697
|
function stripFromActions(actions) {
|
|
4524
2698
|
return actions.filter((action) => !isSubmitAction(action)).map(
|
|
4525
|
-
(action) =>
|
|
2699
|
+
(action) => isRecord2(action) && isRecord2(action.card) ? { ...action, card: stripSubmitActions(action.card) } : action
|
|
4526
2700
|
);
|
|
4527
2701
|
}
|
|
4528
2702
|
function stripFromElements(elements) {
|
|
4529
2703
|
const result = [];
|
|
4530
2704
|
for (const element of elements) {
|
|
4531
|
-
if (!
|
|
2705
|
+
if (!isRecord2(element)) {
|
|
4532
2706
|
result.push(element);
|
|
4533
2707
|
continue;
|
|
4534
2708
|
}
|
|
@@ -4543,7 +2717,7 @@ function stripFromElements(elements) {
|
|
|
4543
2717
|
}
|
|
4544
2718
|
if (Array.isArray(el.columns)) {
|
|
4545
2719
|
el.columns = el.columns.map(
|
|
4546
|
-
(column) =>
|
|
2720
|
+
(column) => isRecord2(column) && Array.isArray(column.items) ? { ...column, items: stripFromElements(column.items) } : column
|
|
4547
2721
|
);
|
|
4548
2722
|
}
|
|
4549
2723
|
result.push(el);
|
|
@@ -5854,23 +4028,6 @@ function AdapterConnectionSelector({
|
|
|
5854
4028
|
] });
|
|
5855
4029
|
}
|
|
5856
4030
|
|
|
5857
|
-
// src/builder/lib/sticky-notes.ts
|
|
5858
|
-
function isStickyNode(node) {
|
|
5859
|
-
return node?.type === STICKY_NOTE_TYPE;
|
|
5860
|
-
}
|
|
5861
|
-
function partitionStickyNotes(nodes) {
|
|
5862
|
-
return {
|
|
5863
|
-
nodes: nodes.filter((n) => !isStickyNode(n)),
|
|
5864
|
-
stickyNotes: nodes.filter((n) => isStickyNode(n))
|
|
5865
|
-
};
|
|
5866
|
-
}
|
|
5867
|
-
function mergeStickyNotes(def) {
|
|
5868
|
-
const nodes = Array.isArray(def.nodes) ? def.nodes : [];
|
|
5869
|
-
const stickies = Array.isArray(def.stickyNotes) ? def.stickyNotes : [];
|
|
5870
|
-
const seen = new Set(nodes.map((n) => n.id));
|
|
5871
|
-
return [...nodes, ...stickies.filter((s) => s?.id && !seen.has(s.id))];
|
|
5872
|
-
}
|
|
5873
|
-
|
|
5874
4031
|
// src/hooks/workflow-saved-events.ts
|
|
5875
4032
|
var listeners = /* @__PURE__ */ new Map();
|
|
5876
4033
|
function subscribeWorkflowSaved(workflowKey, listener) {
|
|
@@ -5887,11 +4044,11 @@ function notifyWorkflowSaved(workflowKey) {
|
|
|
5887
4044
|
}
|
|
5888
4045
|
|
|
5889
4046
|
// src/builder/lib/display-options.ts
|
|
5890
|
-
function
|
|
4047
|
+
function isRecord3(value) {
|
|
5891
4048
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5892
4049
|
}
|
|
5893
4050
|
function readRuleSet(value) {
|
|
5894
|
-
if (!
|
|
4051
|
+
if (!isRecord3(value)) return void 0;
|
|
5895
4052
|
const rules = {};
|
|
5896
4053
|
for (const [key, allowed] of Object.entries(value)) {
|
|
5897
4054
|
if (Array.isArray(allowed)) rules[key] = allowed;
|
|
@@ -5900,8 +4057,8 @@ function readRuleSet(value) {
|
|
|
5900
4057
|
return Object.keys(rules).length > 0 ? rules : void 0;
|
|
5901
4058
|
}
|
|
5902
4059
|
function readDisplayOptions(spec) {
|
|
5903
|
-
const raw =
|
|
5904
|
-
if (!
|
|
4060
|
+
const raw = isRecord3(spec) ? spec.displayOptions : void 0;
|
|
4061
|
+
if (!isRecord3(raw)) return void 0;
|
|
5905
4062
|
const show = readRuleSet(raw.show);
|
|
5906
4063
|
const hide = readRuleSet(raw.hide);
|
|
5907
4064
|
if (!show && !hide) return void 0;
|
|
@@ -5914,7 +4071,7 @@ function matches(current, allowed) {
|
|
|
5914
4071
|
);
|
|
5915
4072
|
}
|
|
5916
4073
|
function isParamVisible(spec, values, defaults = {}) {
|
|
5917
|
-
const options =
|
|
4074
|
+
const options = isRecord3(spec) ? readDisplayOptions(spec) ?? (isRecord3(spec.show) || isRecord3(spec.hide) ? readDisplayOptions({ displayOptions: spec }) : void 0) : void 0;
|
|
5918
4075
|
if (!options) return true;
|
|
5919
4076
|
const valueOf = (key) => values[key] === void 0 ? defaults[key] : values[key];
|
|
5920
4077
|
if (options.show) {
|
|
@@ -5934,7 +4091,7 @@ function isParamVisible(spec, values, defaults = {}) {
|
|
|
5934
4091
|
function defaultsOf(fields) {
|
|
5935
4092
|
const defaults = {};
|
|
5936
4093
|
for (const [name, spec] of Object.entries(fields)) {
|
|
5937
|
-
if (
|
|
4094
|
+
if (isRecord3(spec) && spec.default !== void 0)
|
|
5938
4095
|
defaults[name] = spec.default;
|
|
5939
4096
|
}
|
|
5940
4097
|
return defaults;
|
|
@@ -5945,17 +4102,17 @@ function dropHiddenParameters(state, fields, mappedFields = /* @__PURE__ */ new
|
|
|
5945
4102
|
let next;
|
|
5946
4103
|
const ensure = () => next ??= { ...state };
|
|
5947
4104
|
for (const [name, spec] of Object.entries(fields)) {
|
|
5948
|
-
if (!
|
|
4105
|
+
if (!isRecord3(spec)) continue;
|
|
5949
4106
|
if (!mappedFields.has(name) && Object.hasOwn(state, name) && !isParamVisible(spec, state, defaults)) {
|
|
5950
4107
|
delete ensure()[name];
|
|
5951
4108
|
continue;
|
|
5952
4109
|
}
|
|
5953
|
-
const rowFields =
|
|
4110
|
+
const rowFields = isRecord3(spec.fields) ? spec.fields : void 0;
|
|
5954
4111
|
const rows = state[name];
|
|
5955
4112
|
if (rowFields && Array.isArray(rows)) {
|
|
5956
4113
|
let changed = false;
|
|
5957
4114
|
const cleaned = rows.map((row) => {
|
|
5958
|
-
if (!
|
|
4115
|
+
if (!isRecord3(row)) return row;
|
|
5959
4116
|
const cleanedRow = dropHiddenParameters(row, rowFields);
|
|
5960
4117
|
if (cleanedRow !== row) changed = true;
|
|
5961
4118
|
return cleanedRow;
|
|
@@ -5967,7 +4124,7 @@ function dropHiddenParameters(state, fields, mappedFields = /* @__PURE__ */ new
|
|
|
5967
4124
|
}
|
|
5968
4125
|
|
|
5969
4126
|
// src/builder/lib/field-schema.ts
|
|
5970
|
-
function
|
|
4127
|
+
function isRecord4(value) {
|
|
5971
4128
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5972
4129
|
}
|
|
5973
4130
|
function isIdentifier(key) {
|
|
@@ -5986,11 +4143,11 @@ function pathToExpression(path) {
|
|
|
5986
4143
|
function mergeFieldSpecs(common, variant) {
|
|
5987
4144
|
const base = typeof common === "string" ? { type: common } : common;
|
|
5988
4145
|
const branch = typeof variant === "string" ? { type: variant } : variant;
|
|
5989
|
-
if (!
|
|
4146
|
+
if (!isRecord4(base) || !isRecord4(branch)) return branch;
|
|
5990
4147
|
const merged = { ...base, ...branch };
|
|
5991
4148
|
const commonProperties = base.properties;
|
|
5992
4149
|
const branchProperties = branch.properties;
|
|
5993
|
-
if (
|
|
4150
|
+
if (isRecord4(commonProperties) && isRecord4(branchProperties)) {
|
|
5994
4151
|
merged.properties = Object.fromEntries(
|
|
5995
4152
|
Object.entries({ ...commonProperties, ...branchProperties }).map(
|
|
5996
4153
|
([key, value]) => [
|
|
@@ -6009,14 +4166,14 @@ function fieldFromSpec(key, path, spec) {
|
|
|
6009
4166
|
if (typeof spec === "string") {
|
|
6010
4167
|
return { key, path, type: spec };
|
|
6011
4168
|
}
|
|
6012
|
-
if (
|
|
4169
|
+
if (isRecord4(spec)) {
|
|
6013
4170
|
const declaredType2 = typeof spec.type === "string" ? spec.type : void 0;
|
|
6014
4171
|
const description = typeof spec.description === "string" ? spec.description : void 0;
|
|
6015
4172
|
const required = spec.required === true;
|
|
6016
4173
|
const alternatives = ["oneOf", "anyOf"].flatMap((keyword) => {
|
|
6017
4174
|
const variants = spec[keyword];
|
|
6018
4175
|
return Array.isArray(variants) ? variants.flatMap(
|
|
6019
|
-
(variant, index) =>
|
|
4176
|
+
(variant, index) => isRecord4(variant) || typeof variant === "string" ? [{ keyword, index, variant }] : []
|
|
6020
4177
|
) : [];
|
|
6021
4178
|
});
|
|
6022
4179
|
if (alternatives.length > 0) {
|
|
@@ -6045,7 +4202,7 @@ function fieldFromSpec(key, path, spec) {
|
|
|
6045
4202
|
type: declaredType2 ?? [...new Set(children.map((field) => field.type))].join(" | ")
|
|
6046
4203
|
};
|
|
6047
4204
|
}
|
|
6048
|
-
if (
|
|
4205
|
+
if (isRecord4(spec.properties) && (!declaredType2 || declaredType2 === "object")) {
|
|
6049
4206
|
const children = Object.entries(spec.properties).map(
|
|
6050
4207
|
([childKey, childSpec]) => fieldFromSpec(childKey, joinPath(path, childKey), childSpec)
|
|
6051
4208
|
);
|
|
@@ -6067,7 +4224,7 @@ function fieldFromSpec(key, path, spec) {
|
|
|
6067
4224
|
return { key, path, type: "any" };
|
|
6068
4225
|
}
|
|
6069
4226
|
function fieldsFromIO(io, root = "") {
|
|
6070
|
-
if (!
|
|
4227
|
+
if (!isRecord4(io)) return [];
|
|
6071
4228
|
return Object.entries(io).map(
|
|
6072
4229
|
([key, spec]) => fieldFromSpec(key, joinPath(root, key), spec)
|
|
6073
4230
|
);
|
|
@@ -6086,7 +4243,7 @@ function fieldFromValue(key, path, value) {
|
|
|
6086
4243
|
const children = value.length > 0 ? [fieldFromValue("0", `${path}[0]`, value[0])] : void 0;
|
|
6087
4244
|
return { key, path, type: "array", children };
|
|
6088
4245
|
}
|
|
6089
|
-
if (
|
|
4246
|
+
if (isRecord4(value)) {
|
|
6090
4247
|
const children = Object.entries(value).map(
|
|
6091
4248
|
([k, v]) => fieldFromValue(k, joinPath(path, k), v)
|
|
6092
4249
|
);
|
|
@@ -6095,7 +4252,7 @@ function fieldFromValue(key, path, value) {
|
|
|
6095
4252
|
return { key, path, type: typeOfValue(value) };
|
|
6096
4253
|
}
|
|
6097
4254
|
function fieldsFromValue(value, root = "") {
|
|
6098
|
-
if (!
|
|
4255
|
+
if (!isRecord4(value)) return [];
|
|
6099
4256
|
return Object.entries(value).map(
|
|
6100
4257
|
([key, v]) => fieldFromValue(key, joinPath(root, key), v)
|
|
6101
4258
|
);
|
|
@@ -6111,13 +4268,13 @@ function declaredOutputFields(nodeType, op) {
|
|
|
6111
4268
|
}
|
|
6112
4269
|
function normalizeOperations(raw) {
|
|
6113
4270
|
if (Array.isArray(raw)) return raw;
|
|
6114
|
-
if (
|
|
4271
|
+
if (isRecord4(raw) && Array.isArray(raw.operations)) {
|
|
6115
4272
|
return raw.operations;
|
|
6116
4273
|
}
|
|
6117
4274
|
return [];
|
|
6118
4275
|
}
|
|
6119
4276
|
function resolveNodeOperation(data, fallbackOperations) {
|
|
6120
|
-
const nodeData =
|
|
4277
|
+
const nodeData = isRecord4(data?.nodeData) ? data?.nodeData : void 0;
|
|
6121
4278
|
let operations = normalizeOperations(nodeData?.operations);
|
|
6122
4279
|
if (operations.length === 0) {
|
|
6123
4280
|
operations = normalizeOperations(data?.operations);
|
|
@@ -6131,11 +4288,11 @@ function resolveNodeOperation(data, fallbackOperations) {
|
|
|
6131
4288
|
}
|
|
6132
4289
|
|
|
6133
4290
|
// src/builder/lib/parameter-values.ts
|
|
6134
|
-
function
|
|
4291
|
+
function isRecord5(value) {
|
|
6135
4292
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6136
4293
|
}
|
|
6137
4294
|
function record(value) {
|
|
6138
|
-
return
|
|
4295
|
+
return isRecord5(value) ? value : void 0;
|
|
6139
4296
|
}
|
|
6140
4297
|
function declaredType(schema) {
|
|
6141
4298
|
const type = typeof schema === "string" ? schema : record(schema)?.type;
|
|
@@ -8211,7 +6368,7 @@ function useNodeExecution() {
|
|
|
8211
6368
|
executionId: runId,
|
|
8212
6369
|
trigger: analyticsTrigger,
|
|
8213
6370
|
errorCode: run.errorType,
|
|
8214
|
-
durationMs: run
|
|
6371
|
+
durationMs: runDurationMs(run)
|
|
8215
6372
|
});
|
|
8216
6373
|
}
|
|
8217
6374
|
completeExecution();
|
|
@@ -8310,7 +6467,7 @@ function useNodeExecution() {
|
|
|
8310
6467
|
} catch (error) {
|
|
8311
6468
|
console.error("[useNodeExecution] Error executing step:", error);
|
|
8312
6469
|
const errorMessage = describeOperationError(error);
|
|
8313
|
-
const errorRunId = nanoid();
|
|
6470
|
+
const errorRunId = nanoid$1();
|
|
8314
6471
|
const errorLog = {
|
|
8315
6472
|
id: `${errorRunId}-${nodeId}`,
|
|
8316
6473
|
runId: errorRunId,
|
|
@@ -8423,7 +6580,7 @@ function useNodeExecution() {
|
|
|
8423
6580
|
surface: "builder-run"
|
|
8424
6581
|
});
|
|
8425
6582
|
const errorMessage = describeOperationError(error);
|
|
8426
|
-
const errorRunId = nanoid();
|
|
6583
|
+
const errorRunId = nanoid$1();
|
|
8427
6584
|
const errorLog = {
|
|
8428
6585
|
id: `${errorRunId}-${triggerNode.id}`,
|
|
8429
6586
|
runId: errorRunId,
|
|
@@ -9076,45 +7233,6 @@ function useInsertNode() {
|
|
|
9076
7233
|
[screenToFlowPosition, getNodes, addNodes, updateNode]
|
|
9077
7234
|
);
|
|
9078
7235
|
}
|
|
9079
|
-
|
|
9080
|
-
// src/builder/lib/node-operation-selection.ts
|
|
9081
|
-
function resolveOperationName(selectedOperation, fallback) {
|
|
9082
|
-
return typeof selectedOperation === "string" && selectedOperation.trim() ? selectedOperation : fallback;
|
|
9083
|
-
}
|
|
9084
|
-
function canRenderOperationPanel(selectedOperation, supportedOperations) {
|
|
9085
|
-
const operationName = resolveOperationName(selectedOperation, "");
|
|
9086
|
-
return operationName === "" || supportedOperations.includes(operationName);
|
|
9087
|
-
}
|
|
9088
|
-
function isRecord9(value) {
|
|
9089
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9090
|
-
}
|
|
9091
|
-
function readRecord3(value) {
|
|
9092
|
-
return isRecord9(value) ? value : void 0;
|
|
9093
|
-
}
|
|
9094
|
-
function readOperations(value) {
|
|
9095
|
-
const operations = Array.isArray(value) ? value : readRecord3(value)?.operations;
|
|
9096
|
-
return Array.isArray(operations) ? operations : [];
|
|
9097
|
-
}
|
|
9098
|
-
function synchronizeOperationUpdate(currentData, updates, registeredOperations) {
|
|
9099
|
-
const operationName = resolveOperationName(updates.operation_name, "");
|
|
9100
|
-
if (!operationName || operationName === currentData.operation_name)
|
|
9101
|
-
return updates;
|
|
9102
|
-
const manifest = readRecord3(updates.nodeData ?? currentData.nodeData);
|
|
9103
|
-
const operations = [
|
|
9104
|
-
...readOperations(manifest?.operations),
|
|
9105
|
-
...readOperations(registeredOperations)
|
|
9106
|
-
];
|
|
9107
|
-
const selected = readRecord3(
|
|
9108
|
-
operations.find(
|
|
9109
|
-
(operation) => readRecord3(operation)?.name === operationName
|
|
9110
|
-
)
|
|
9111
|
-
);
|
|
9112
|
-
return {
|
|
9113
|
-
...updates,
|
|
9114
|
-
operation_type: typeof selected?.type === "string" ? selected.type : updates.operation_type,
|
|
9115
|
-
nodeData: { ...manifest, operations: selected ? [selected] : [] }
|
|
9116
|
-
};
|
|
9117
|
-
}
|
|
9118
7236
|
function isAutoManagedConnectionAdapter(nodeType, adapter) {
|
|
9119
7237
|
const isBigConsoleDataSinkAutoAdapter = nodeType === "store/bigconsole_datasink" && adapter.name === "bigconsole" && adapter.provider === "bigconsole";
|
|
9120
7238
|
return isBigConsoleDataSinkAutoAdapter || adapter.mode === "auto" || adapter.autoProvision === true || adapter.autoManaged === true || adapter.hidden === true;
|
|
@@ -10109,7 +8227,7 @@ function getNodeDetail(nodeType) {
|
|
|
10109
8227
|
}
|
|
10110
8228
|
function createNodeData(type, data) {
|
|
10111
8229
|
return {
|
|
10112
|
-
id: nanoid(),
|
|
8230
|
+
id: nanoid$1(),
|
|
10113
8231
|
type,
|
|
10114
8232
|
data
|
|
10115
8233
|
};
|
|
@@ -10119,4 +8237,4 @@ function createNodeWithDefaultData(type, data) {
|
|
|
10119
8237
|
return Object.assign(createNodeData(type, defaultData), data);
|
|
10120
8238
|
}
|
|
10121
8239
|
|
|
10122
|
-
export { AUTOSAVE_DEBOUNCE_MS, AUTOSAVE_RETRY_DELAYS_MS, AVAILABLE_NODES, BILLING_PLANS_PATH,
|
|
8240
|
+
export { AUTOSAVE_DEBOUNCE_MS, AUTOSAVE_RETRY_DELAYS_MS, AVAILABLE_NODES, BILLING_PLANS_PATH, ConnectionFormDialog, ConnectionSelector, DURABLE_FUNCTION_NODE_TYPES, EDIT_SESSION_ID, ExpressionEditor, FLUIDGRIDS_FLAGS, FLUIDGRIDS_FLAG_DEFAULTS, FluidGridsContext, FluidGridsProvider, NODES, NODES_METADATA, NODE_CONFIGS, NODE_TYPES, NodePropertyPanel, PHASE_C_FLAGS_OFF, RUNS_QUOTA_NAME, RUN_CONTROL_NODE_TYPES, WORKFLOWS_QUOTA_NAME, WORKFLOW_TEST_NODE_TYPES, autosaveAllowedFor, bannerOf, blankWorkflowCreateInput, buildOperationSeed, buildStickyNode, builderPathOf, canAutosave, canSignalRun, classifyCreateRefusal, clearCodeWorkflowDefinitionCache, codeBuildIdOf, components_default, createConfiguredNode, createThenOpen, declaredOutputFields, declaredSignals, departingSave, editStateFor, editingLeaseLocked, emitNodeInstalled, emitRunFailed, emitRunLimitHit, emitRunStarted, emitTemplateUsed, emitUpgradeClicked, emitWorkflowCreated, emitWorkflowLimitHit, emitWorkflowPublished, ensureNodeConfigsLoaded, fieldsFromIO, fieldsFromValue, filterPaletteNodes, findQuotaRefusal, findSaveConflict, forgetSessionForReload, formatElapsedMs, formatParameterValue, getNodeDetail, getNodeMetadata, inAppLeaveTarget, isDurableFunctionNodeType, isFlowComplete, isLocked, isNodeConfigsInitialized, isNodeTypeHiddenFromPalette, isParamVisible, isQuotaExhaustedFailure, isRunControlNodeType, leaseCallQueue, leavingLosesChanges, listCustomBlocks, liveInternalOperations, loadDefinitionJson, nodeStateDurationMs, nodesOf, onNodeTypesUpdate, openRunQuotaUpgradePrompt, parseParameterValue, parseRawSignalPayload, pathToExpression, payloadFromCardValues, phaseAfterAcquire, phaseAfterTakeOver, readDisplayOptions, refetchStoreNodes, registerCustomBlock, registerWorkflowNodeTypes, releasesOnClose, rememberOwnStatusChange, rememberRevision, rememberSessionForReload, resolveNodeOperation, resolvePhaseCFlags, resolveUiSpec, runDurationMs, runSignalTargets, runTriggerFromMode, saveIndicatorOf, savedEverythingBeforeLeaving, sessionBeforeReload, shouldReleaseForIdle, signalPayloadCard, stripSubmitActions, structuredParameterType, subscribeWorkflowSaved, tickAction, touchesSavedFields, useAgentDefinitionList, useAgentDefinitions, useCodeWorkflowInterface, useConnection, useConnections, useConnectionsByProvider, useContinuousOptimisationEnabled, useCreateConnection, useDurableFunctionNodesEnabled, useDurableParityEnabled, useEditLeaseLocked, useEditLeaseStore, useFlowValidator, useFluidGridsAnalytics, useFluidGridsContext, useFluidGridsFlag, useGuardedNavigate, useInitiateOAuth, useInsertNode, useManualSave, useNodeExecution, useNodeRegistryRevision, usePaletteGates, usePhaseCFlags, useProviders, useRunGuard, useSaveStatusStore, useSaveWorkflow, useSelfHostedWorkersEnabled, useWorkflowTestsEnabled, watchLeavingLosesChanges, workflowFingerprint };
|