@burdenoff/fluidgrids-fe-sdk 2026.701.5 → 2026.701.7

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.
@@ -1,16 +1,16 @@
1
1
  import { Dialog as Dialog$1, DialogContent as DialogContent$1, DialogHeader as DialogHeader$1, DialogTitle as DialogTitle$1, DialogDescription as DialogDescription$1, DialogFooter, Input as Input$1 } from './chunk-7VEOUEIN.js';
2
- import { createGlobalStoreClient, getGlobalStoreClient } from './chunk-BQXHJIER.js';
2
+ import { getGlobalStoreClient, createGlobalStoreClient } from './chunk-BQXHJIER.js';
3
3
  import { useFlowStore } from './chunk-KU64CCSV.js';
4
4
  import { useLazyWorkflowDefinition, useCreateWorkflow, useWorkflowVersions, useRestoreWorkflowVersion, useActivateWorkflow, useDeactivateWorkflow } from './chunk-4FFPGQD3.js';
5
- import { NodeEndpointConfigsDocument, NodeManifestDocument, TriggerWorkflowDocument, WorkflowRunDocument, NodeSchemaIntrospectionDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument } from './chunk-FGYVIXQ7.js';
5
+ import { NodeEndpointConfigsDocument, NodeManifestDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, TriggerWorkflowDocument, WorkflowRunDocument, NodeSchemaIntrospectionDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument } from './chunk-FGYVIXQ7.js';
6
6
  import { waitForFluidGridsClient, getFluidGridsClient, createFluidGridsClient, setFluidGridsClient, resetFluidGridsClient } from './chunk-5BDQNSP3.js';
7
7
  import { config, getFluidGridsConfig, validateTrustedOrigin, setFluidGridsConfig, resetFluidGridsConfig } from './chunk-WWU2O2SR.js';
8
- import { BrowseWorkflowTemplatesDocument, InstallWorkflowNodeDocument, InstallPurchasedNodeDocument, GetMyNodeInstallationsDocument, BrowseWorkflowNodesDocument, UninstallWorkflowNodeDocument, CreateStoreOrderDocument } from './chunk-LUGJJ7LL.js';
8
+ import { GetMyNodeInstallationsDocument, BrowseWorkflowTemplatesDocument, InstallWorkflowNodeDocument, InstallPurchasedNodeDocument, BrowseWorkflowNodesDocument, UninstallWorkflowNodeDocument, CreateStoreOrderDocument } from './chunk-LUGJJ7LL.js';
9
9
  import { deepClone, applyTemplateInputs } from './chunk-XQP33UJR.js';
10
10
  import { cn as cn$1, Badge as Badge$1, Button as Button$1 } from './chunk-Z54K22LP.js';
11
11
  import { ThemeProvider as ThemeProvider$1 } from '@burdenoff/fe-libs/shared/providers/shell';
12
12
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
13
- import { useNavigate, useParams } from 'react-router-dom';
13
+ import { useParams, useNavigate } from 'react-router-dom';
14
14
  import { useShallow, shallow } from 'zustand/shallow';
15
15
  import * as React2 from 'react';
16
16
  import React2__default, { forwardRef, useState, useImperativeHandle, useRef, useEffect, useMemo, createContext, lazy, memo, useCallback, useContext, useLayoutEffect, Suspense, useDeferredValue } from 'react';
@@ -28,7 +28,7 @@ import { toast } from 'sonner';
28
28
  import { InfoCircledIcon } from '@radix-ui/react-icons';
29
29
  import { isEmpty } from 'radash';
30
30
  import { ApolloProvider, useQuery, useMutation } from '@apollo/client/react';
31
- import JSZip from 'jszip';
31
+ import 'jszip';
32
32
  import { gql as gql$1 } from '@apollo/client/core';
33
33
  import { Sparkles, Star, Download, Eye, History, Loader2, RotateCcw, Maximize2, LayoutGrid, Plus, Trash2, GitBranch, AlertCircle, Search, RefreshCw, CheckCircle2, Package, Info, Copy, BadgeCheck, DollarSign, PlusCircle, ChevronDown, Type, Code, Hash, List, Braces, Workflow, ChevronRight, Layers, X, AlertTriangle } from 'lucide-react';
34
34
  import { animate, easeOut } from 'popmotion';
@@ -7313,6 +7313,179 @@ function ArrayField({
7313
7313
  description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: description })
7314
7314
  ] });
7315
7315
  }
7316
+ function useSaveWorkflow() {
7317
+ const [isSaving, setIsSaving] = useState(false);
7318
+ const params = useParams();
7319
+ const navigate = useNavigate();
7320
+ const [saveWorkflow, setWorkflow] = useFlowStore(
7321
+ useShallow((s) => [s.actions.saveWorkflow, s.actions.setWorkflow])
7322
+ );
7323
+ const saveToBackend = useCallback(async () => {
7324
+ setIsSaving(true);
7325
+ try {
7326
+ const workflow = saveWorkflow();
7327
+ const workflowKey = params?.id || workflow?.id;
7328
+ if (!workflowKey) {
7329
+ throw new Error(
7330
+ "Workflow key not found. Navigate to /workflow/{key}/v1 to create a workflow."
7331
+ );
7332
+ }
7333
+ const isDraft = !workflow.status || workflow.status === "DRAFT";
7334
+ const client = getFluidGridsClient();
7335
+ const preparedWorkflow = {
7336
+ ...workflow,
7337
+ nodes: workflow.nodes?.map((n) => {
7338
+ const { nodeData: _ignoredNodeData, ...flattenedData } = n.data ?? {};
7339
+ void _ignoredNodeData;
7340
+ return { ...n, ...flattenedData };
7341
+ })
7342
+ };
7343
+ const definitionJson = {
7344
+ key: workflowKey,
7345
+ name: workflow?.name,
7346
+ description: workflow?.name || "Workflow Description",
7347
+ workflow_type: "query-conditional",
7348
+ data: {
7349
+ ...preparedWorkflow,
7350
+ version: workflow.version,
7351
+ alias: workflow?.alias || null
7352
+ },
7353
+ meta: {
7354
+ creator: "api_update",
7355
+ version: workflow.version
7356
+ },
7357
+ tags: [
7358
+ "rag",
7359
+ "cache",
7360
+ "websearch",
7361
+ "conditional",
7362
+ "python_expr",
7363
+ "retry",
7364
+ "api_trigger"
7365
+ ]
7366
+ };
7367
+ let savedVersion = workflow.version;
7368
+ let savedDbId = workflow.dbId;
7369
+ let operation = "updated";
7370
+ if (isDraft && workflow.dbId) {
7371
+ const { data } = await client.mutate({
7372
+ mutation: UpdateWorkflowDefinitionDocument,
7373
+ variables: {
7374
+ id: workflow.dbId,
7375
+ input: {
7376
+ definitionJson,
7377
+ name: workflow?.name,
7378
+ description: workflow?.name || "Workflow update",
7379
+ alias: workflow?.alias || void 0
7380
+ }
7381
+ }
7382
+ });
7383
+ if (data?.updateWorkflowDefinition) {
7384
+ savedVersion = data.updateWorkflowDefinition.version;
7385
+ savedDbId = data.updateWorkflowDefinition.id;
7386
+ operation = "updated";
7387
+ toast.success("Workflow saved", {
7388
+ description: `Updated version ${savedVersion}`,
7389
+ dismissible: true
7390
+ });
7391
+ } else {
7392
+ throw new Error("Failed to save workflow");
7393
+ }
7394
+ } else if (isDraft && !workflow.dbId) {
7395
+ const { data } = await client.mutate({
7396
+ mutation: CreateWorkflowDefinitionDocument,
7397
+ variables: {
7398
+ input: {
7399
+ workflowKey,
7400
+ version: workflow.version || params?.version || "v1",
7401
+ name: workflow?.name || "Untitled Workflow",
7402
+ description: workflow?.name || "Untitled Workflow",
7403
+ definitionJson
7404
+ }
7405
+ }
7406
+ });
7407
+ if (data?.createWorkflowDefinition) {
7408
+ savedVersion = data.createWorkflowDefinition.version;
7409
+ savedDbId = data.createWorkflowDefinition.id;
7410
+ operation = "created";
7411
+ setWorkflow({
7412
+ dbId: savedDbId,
7413
+ status: data.createWorkflowDefinition.status ?? "DRAFT",
7414
+ version: savedVersion
7415
+ });
7416
+ toast.success("Workflow saved", {
7417
+ description: `Created version ${savedVersion}`,
7418
+ dismissible: true
7419
+ });
7420
+ } else {
7421
+ throw new Error("Failed to create workflow");
7422
+ }
7423
+ } else {
7424
+ const { data } = await client.mutate({
7425
+ mutation: CreateWorkflowVersionDocument,
7426
+ variables: {
7427
+ workflowKey,
7428
+ input: {
7429
+ definitionJson,
7430
+ description: workflow?.name || "Workflow update"
7431
+ }
7432
+ }
7433
+ });
7434
+ if (data?.createWorkflowVersion?.success) {
7435
+ const newWorkflow = data.createWorkflowVersion.workflow;
7436
+ savedVersion = newWorkflow?.version ?? workflow.version;
7437
+ savedDbId = newWorkflow?.id ?? workflow.dbId;
7438
+ operation = "versioned";
7439
+ setWorkflow({
7440
+ version: savedVersion,
7441
+ dbId: savedDbId,
7442
+ status: "DRAFT"
7443
+ });
7444
+ navigate(`../workflow/${workflowKey}/${savedVersion}`, {
7445
+ replace: true
7446
+ });
7447
+ toast.success("New version created", {
7448
+ description: `Saved as version ${savedVersion} (Draft)`,
7449
+ dismissible: true
7450
+ });
7451
+ } else {
7452
+ throw new Error(
7453
+ data?.createWorkflowVersion?.message || "Failed to save workflow"
7454
+ );
7455
+ }
7456
+ }
7457
+ if (savedDbId) {
7458
+ const config2 = getFluidGridsConfig();
7459
+ if (config2.onWorkflowSaved) {
7460
+ try {
7461
+ await config2.onWorkflowSaved({
7462
+ dbId: savedDbId,
7463
+ workflowKey,
7464
+ version: savedVersion,
7465
+ name: workflow?.name || "Untitled Workflow",
7466
+ description: workflow?.alias || workflow?.name || void 0,
7467
+ operation
7468
+ });
7469
+ } catch (callbackError) {
7470
+ console.warn(
7471
+ "[useSaveWorkflow] onWorkflowSaved callback failed:",
7472
+ callbackError
7473
+ );
7474
+ }
7475
+ }
7476
+ }
7477
+ } catch (error) {
7478
+ const message = error instanceof Error ? error.message : "Unknown error";
7479
+ console.error("Error saving workflow:", message);
7480
+ toast.error("Failed to save workflow", {
7481
+ description: message
7482
+ });
7483
+ } finally {
7484
+ setIsSaving(false);
7485
+ }
7486
+ }, [saveWorkflow, setWorkflow, params?.id, params?.version, navigate]);
7487
+ return { saveToBackend, isSaving };
7488
+ }
7316
7489
  function NodePropertyPanel({
7317
7490
  id,
7318
7491
  type,
@@ -7334,6 +7507,7 @@ function NodePropertyPanel({
7334
7507
  const [searchTerm, setSearchTerm] = useState("");
7335
7508
  const [isLoading, setIsLoading] = useState(false);
7336
7509
  useFlowStore((s) => s.workflow.id);
7510
+ const { saveToBackend, isSaving } = useSaveWorkflow();
7337
7511
  const operationsArray = useMemo(() => {
7338
7512
  const nodeDataOps = data?.nodeData?.operations;
7339
7513
  if (nodeDataOps) {
@@ -7415,6 +7589,10 @@ function NodePropertyPanel({
7415
7589
  }
7416
7590
  return currentOperation;
7417
7591
  }, [currentOperation, type]);
7592
+ const shouldSaveConfigurationToBackend = useMemo(
7593
+ () => String(type) === "store/bigconsole_datasink" && effectiveCurrentOperation?.name === "postDataToDataSink",
7594
+ [effectiveCurrentOperation?.name, type]
7595
+ );
7418
7596
  const connectionAdapters = useMemo(
7419
7597
  () => effectiveCurrentOperation?.connectionAdapters || effectiveCurrentOperation?.credentialAdapters || data?.nodeData?.connectionAdapters || data?.nodeData?.credentialAdapters || [],
7420
7598
  [
@@ -7491,6 +7669,13 @@ function NodePropertyPanel({
7491
7669
  state: newState
7492
7670
  }
7493
7671
  });
7672
+ if (shouldSaveConfigurationToBackend && !isSaving) {
7673
+ window.setTimeout(() => {
7674
+ void saveToBackend().catch((error) => {
7675
+ console.error("Error saving DataSink configuration:", error);
7676
+ });
7677
+ }, 0);
7678
+ }
7494
7679
  };
7495
7680
  const resolvedUi = useMemo(
7496
7681
  () => resolveUiSpec(effectiveCurrentOperation),
@@ -8789,13 +8974,77 @@ async function fetchNodeManifest(nodeType, nodeVersion) {
8789
8974
  return null;
8790
8975
  }
8791
8976
  }
8977
+ function pushStoreNodeConfig(manifest, publishType = "STORE") {
8978
+ if (NODE_CONFIGS.some((c) => c.type === manifest.nodeType)) return;
8979
+ const manifestOps = manifest.operations;
8980
+ const operations = Array.isArray(manifestOps) ? manifestOps : manifestOps?.operations ?? manifestOps;
8981
+ NODE_CONFIGS.push({
8982
+ type: manifest.nodeType,
8983
+ detail: {
8984
+ icon: manifest.icon || "mynaui:keyboard-solid",
8985
+ title: manifest.name,
8986
+ description: manifest.description,
8987
+ gradientColor: "yellow"
8988
+ },
8989
+ defaultData: {
8990
+ operation_name: "",
8991
+ operation_type: "",
8992
+ nodeData: manifest,
8993
+ version: manifest.version,
8994
+ args: {
8995
+ context: {
8996
+ node: {
8997
+ id: manifest.nodeType,
8998
+ kind: manifest.kind,
8999
+ type: manifest.nodeType
9000
+ }
9001
+ },
9002
+ state: {},
9003
+ credentials: []
9004
+ }
9005
+ },
9006
+ operations,
9007
+ publishType
9008
+ });
9009
+ }
9010
+ async function loadInstalledStoreNodes() {
9011
+ const globalClient = getGlobalStoreClient();
9012
+ if (!globalClient) return;
9013
+ const { workspaceId } = getFluidGridsConfig();
9014
+ if (!workspaceId) return;
9015
+ try {
9016
+ const { data } = await globalClient.query({
9017
+ query: GetMyNodeInstallationsDocument,
9018
+ variables: { workspaceId, limit: 200, offset: 0 },
9019
+ fetchPolicy: "network-only"
9020
+ });
9021
+ const installations = data?.myStoreAppInstallations?.items ?? [];
9022
+ let loaded = 0;
9023
+ for (const installation of installations) {
9024
+ if (installation.status !== "ACTIVE") continue;
9025
+ const manifest = installation.manifest;
9026
+ if (!manifest?.nodeType) continue;
9027
+ pushStoreNodeConfig(manifest, "STORE");
9028
+ loaded++;
9029
+ }
9030
+ if (loaded > 0) {
9031
+ console.log(
9032
+ `[Workflows] Loaded ${loaded} installed store node(s) from workspace installations.`
9033
+ );
9034
+ }
9035
+ } catch (error) {
9036
+ const message = error instanceof Error ? error.message : "Unknown error";
9037
+ console.warn("[Workflows] Could not load installed store nodes:", message);
9038
+ }
9039
+ }
8792
9040
  async function initializeNodeConfigs() {
8793
9041
  try {
8794
9042
  const client = await waitForFluidGridsClient(15e3, 150);
8795
9043
  if (!client) {
8796
9044
  console.warn(
8797
- "[Workflows] Apollo client not available after timeout \u2014 node configs will use built-in nodes only."
9045
+ "[Workflows] Apollo client not available after timeout \u2014 loading store nodes only."
8798
9046
  );
9047
+ await loadInstalledStoreNodes();
8799
9048
  return;
8800
9049
  }
8801
9050
  const { data } = await client.query({
@@ -8808,6 +9057,7 @@ async function initializeNodeConfigs() {
8808
9057
  const nodes = data?.nodeEndpointConfigs?.configs ?? [];
8809
9058
  if (!Array.isArray(nodes) || nodes.length === 0) {
8810
9059
  console.warn("No nodes found or received data is not an array.");
9060
+ await loadInstalledStoreNodes();
8811
9061
  return;
8812
9062
  }
8813
9063
  const manifestPromises = nodes.map(async (node) => {
@@ -8867,6 +9117,7 @@ async function initializeNodeConfigs() {
8867
9117
  // Preserve publishType from GraphQL query
8868
9118
  });
8869
9119
  });
9120
+ await loadInstalledStoreNodes();
8870
9121
  } catch (error) {
8871
9122
  const message = error instanceof Error ? error.message : "Unknown error";
8872
9123
  console.error("Failed to fetch nodes or manifests:", message);
@@ -10358,136 +10609,6 @@ function useInstalledNodes() {
10358
10609
  refetch
10359
10610
  };
10360
10611
  }
10361
- function useNodePackageLoader() {
10362
- const downloadZip = useCallback(
10363
- async (zipUrl) => {
10364
- try {
10365
- const response = await fetch(zipUrl);
10366
- if (!response.ok) {
10367
- throw new Error(`Failed to download ZIP: ${response.statusText}`);
10368
- }
10369
- return await response.arrayBuffer();
10370
- } catch (error) {
10371
- console.error("[useNodePackageLoader] Download failed:", error);
10372
- throw new Error(`Download failed: ${error.message}`);
10373
- }
10374
- },
10375
- []
10376
- );
10377
- const extractManifest = useCallback(
10378
- async (zipData) => {
10379
- try {
10380
- const zip = await JSZip.loadAsync(zipData);
10381
- const manifestPaths = [
10382
- "manifest.json",
10383
- "package/manifest.json",
10384
- "node/manifest.json"
10385
- ];
10386
- let manifestFile = null;
10387
- for (const path of manifestPaths) {
10388
- manifestFile = zip.file(path);
10389
- if (manifestFile) break;
10390
- }
10391
- if (!manifestFile) {
10392
- throw new Error("manifest.json not found in ZIP package");
10393
- }
10394
- const manifestText = await manifestFile.async("text");
10395
- const manifest = JSON.parse(manifestText);
10396
- if (!manifest.nodeType || !manifest.name || !manifest.version) {
10397
- throw new Error(
10398
- "Invalid manifest: missing required fields (nodeType, name, version)"
10399
- );
10400
- }
10401
- return manifest;
10402
- } catch (error) {
10403
- console.error(
10404
- "[useNodePackageLoader] Manifest extraction failed:",
10405
- error
10406
- );
10407
- throw new Error(`Manifest extraction failed: ${error.message}`);
10408
- }
10409
- },
10410
- []
10411
- );
10412
- const registerNode = useCallback((manifest) => {
10413
- try {
10414
- const existingNode = NODE_CONFIGS.find(
10415
- (config2) => config2.type === manifest.nodeType
10416
- );
10417
- if (existingNode) {
10418
- console.warn(
10419
- `[useNodePackageLoader] Node ${manifest.nodeType} already registered, skipping`
10420
- );
10421
- return;
10422
- }
10423
- const manifestOps = manifest.operations;
10424
- const operations = Array.isArray(manifestOps) ? manifestOps : manifestOps?.operations ?? manifestOps;
10425
- NODE_CONFIGS.push({
10426
- type: manifest.nodeType,
10427
- detail: {
10428
- icon: manifest.icon || "mynaui:keyboard-solid",
10429
- title: manifest.name,
10430
- description: manifest.description,
10431
- gradientColor: "yellow"
10432
- // Default gradient for store nodes
10433
- },
10434
- defaultData: {
10435
- operation_name: "",
10436
- operation_type: "",
10437
- nodeData: manifest,
10438
- version: manifest.version,
10439
- args: {
10440
- context: {
10441
- node: {
10442
- id: manifest.nodeType,
10443
- kind: manifest.kind,
10444
- type: manifest.nodeType
10445
- }
10446
- },
10447
- state: {},
10448
- credentials: []
10449
- }
10450
- },
10451
- operations
10452
- });
10453
- console.log(
10454
- `[useNodePackageLoader] Successfully registered node: ${manifest.nodeType}`
10455
- );
10456
- } catch (error) {
10457
- console.error("[useNodePackageLoader] Node registration failed:", error);
10458
- throw new Error(`Node registration failed: ${error.message}`);
10459
- }
10460
- }, []);
10461
- const loadNodePackage = useCallback(
10462
- async (zipUrl) => {
10463
- try {
10464
- console.log(
10465
- `[useNodePackageLoader] Loading node package from: ${zipUrl}`
10466
- );
10467
- const zipData = await downloadZip(zipUrl);
10468
- const manifest = await extractManifest(zipData);
10469
- registerNode(manifest);
10470
- return {
10471
- success: true,
10472
- manifest
10473
- };
10474
- } catch (error) {
10475
- console.error("[useNodePackageLoader] Load package failed:", error);
10476
- return {
10477
- success: false,
10478
- error: error.message || "Failed to load node package"
10479
- };
10480
- }
10481
- },
10482
- [downloadZip, extractManifest, registerNode]
10483
- );
10484
- return {
10485
- loadNodePackage,
10486
- downloadZip,
10487
- extractManifest,
10488
- registerNode
10489
- };
10490
- }
10491
10612
  function useRefreshAvailableNodes() {
10492
10613
  const refreshAvailableNodes = useCallback(async () => {
10493
10614
  try {
@@ -10521,7 +10642,6 @@ function useInstallNode() {
10521
10642
  const workspaceId = context?.workspaceId ?? getFluidGridsConfig().workspaceId;
10522
10643
  const tenantId = context?.tenantId ?? getFluidGridsConfig().tenantId;
10523
10644
  const { refetch: refetchInstalled } = useInstalledNodes();
10524
- const { loadNodePackage } = useNodePackageLoader();
10525
10645
  const { refreshAvailableNodes } = useRefreshAvailableNodes();
10526
10646
  const [installing, setInstalling] = useState(null);
10527
10647
  const [installMutation] = useMutation(InstallWorkflowNodeDocument, {
@@ -10581,29 +10701,10 @@ function useInstallNode() {
10581
10701
  "[useInstallNode] Free node installation successful. Node registration handled by backend."
10582
10702
  );
10583
10703
  }
10584
- if (node.zipFileUrl) {
10704
+ const refreshResult = await refreshAvailableNodes();
10705
+ if (refreshResult.success) {
10585
10706
  console.log(
10586
- `[useInstallNode] Loading node package from: ${node.zipFileUrl}`
10587
- );
10588
- const packageResult = await loadNodePackage(node.zipFileUrl);
10589
- if (!packageResult.success) {
10590
- console.warn(
10591
- `[useInstallNode] Package loading failed: ${packageResult.error}. Node installed in database but not loaded in builder.`
10592
- );
10593
- } else {
10594
- console.log(
10595
- `[useInstallNode] Successfully loaded node package: ${packageResult.manifest?.nodeType}`
10596
- );
10597
- const refreshResult = await refreshAvailableNodes();
10598
- if (refreshResult.success) {
10599
- console.log(
10600
- `[useInstallNode] Available nodes refreshed. Total: ${refreshResult.totalNodes}`
10601
- );
10602
- }
10603
- }
10604
- } else {
10605
- console.warn(
10606
- `[useInstallNode] Node ${node.id} has no zipFileUrl. Installed in database but cannot be loaded in builder.`
10707
+ `[useInstallNode] Available nodes refreshed. Total: ${refreshResult.totalNodes}`
10607
10708
  );
10608
10709
  }
10609
10710
  await refetchInstalled();
@@ -10628,7 +10729,6 @@ function useInstallNode() {
10628
10729
  workspaceId,
10629
10730
  tenantId,
10630
10731
  refetchInstalled,
10631
- loadNodePackage,
10632
10732
  refreshAvailableNodes
10633
10733
  ]
10634
10734
  );
@@ -10679,7 +10779,13 @@ function useUpdateNode() {
10679
10779
  setUpdating(null);
10680
10780
  }
10681
10781
  },
10682
- [installMutation, workspaceId, tenantId, refetchInstalled, refreshAvailableNodes]
10782
+ [
10783
+ installMutation,
10784
+ workspaceId,
10785
+ tenantId,
10786
+ refetchInstalled,
10787
+ refreshAvailableNodes
10788
+ ]
10683
10789
  );
10684
10790
  return {
10685
10791
  updateNode,
@@ -12520,7 +12626,7 @@ function TemplatesModal({
12520
12626
  ) });
12521
12627
  }
12522
12628
  var LazyTemplateConfigurationModal = lazy(
12523
- () => import('./TemplateConfigurationModal-VU3Q4RFX.js').then((m) => ({
12629
+ () => import('./TemplateConfigurationModal-ZMCT3ZCH.js').then((m) => ({
12524
12630
  default: m.TemplateConfigurationModal
12525
12631
  }))
12526
12632
  );
@@ -12604,7 +12710,9 @@ function DesktopSidebarFragment({
12604
12710
  setInstallProgress(null);
12605
12711
  }
12606
12712
  toast.loading("Creating workflow...", { id: "template-import" });
12607
- const rawDef = JSON.parse(JSON.stringify(content.definitionJson));
12713
+ const rawDef = JSON.parse(
12714
+ JSON.stringify(content.definitionJson)
12715
+ );
12608
12716
  const nestedDef = rawDef?.data?.workflowDefinition?.definitionJson;
12609
12717
  let definitionJson = nestedDef && typeof nestedDef === "object" ? nestedDef : rawDef;
12610
12718
  if (overrides?.templateInputs) {
@@ -12685,7 +12793,9 @@ function DesktopSidebarFragment({
12685
12793
  });
12686
12794
  }
12687
12795
  } catch {
12688
- console.warn("[performImport] Failed to record template installation");
12796
+ console.warn(
12797
+ "[performImport] Failed to record template installation"
12798
+ );
12689
12799
  }
12690
12800
  toast.success("Workflow created from template!", {
12691
12801
  description: `"${importResult.workflow.name}" is ready to edit`
@@ -12806,7 +12916,12 @@ function DesktopSidebarFragment({
12806
12916
  async (config2) => {
12807
12917
  if (!configTemplate || !configContent) return;
12808
12918
  if (configNodeCheck && !configNodeCheck.canImport) return;
12809
- await performImport(configTemplate, configContent, config2, configNodeCheck);
12919
+ await performImport(
12920
+ configTemplate,
12921
+ configContent,
12922
+ config2,
12923
+ configNodeCheck
12924
+ );
12810
12925
  setConfigModalOpen(false);
12811
12926
  },
12812
12927
  [configTemplate, configContent, configNodeCheck, performImport]
@@ -13989,7 +14104,7 @@ function dispatch(action) {
13989
14104
  listener(memoryState);
13990
14105
  });
13991
14106
  }
13992
- function toast4({ ...props }) {
14107
+ function toast5({ ...props }) {
13993
14108
  const id = genId();
13994
14109
  const update = (props2) => dispatch({
13995
14110
  type: actionTypes.UPDATE_TOAST,
@@ -14026,7 +14141,7 @@ function useToast() {
14026
14141
  }, [state]);
14027
14142
  return {
14028
14143
  ...state,
14029
- toast: toast4,
14144
+ toast: toast5,
14030
14145
  dismiss: (toastId) => dispatch({ type: actionTypes.DISMISS_TOAST, toastId })
14031
14146
  };
14032
14147
  }
@@ -19581,179 +19696,6 @@ function useFlowValidator(onValidate) {
19581
19696
  }, [getNodes, getEdges, onValidate]);
19582
19697
  return [isValidating, validate];
19583
19698
  }
19584
- function useSaveWorkflow() {
19585
- const [isSaving, setIsSaving] = useState(false);
19586
- const params = useParams();
19587
- const navigate = useNavigate();
19588
- const [saveWorkflow, setWorkflow] = useFlowStore(
19589
- useShallow((s) => [s.actions.saveWorkflow, s.actions.setWorkflow])
19590
- );
19591
- const saveToBackend = useCallback(async () => {
19592
- setIsSaving(true);
19593
- try {
19594
- const workflow = saveWorkflow();
19595
- const workflowKey = params?.id || workflow?.id;
19596
- if (!workflowKey) {
19597
- throw new Error(
19598
- "Workflow key not found. Navigate to /workflow/{key}/v1 to create a workflow."
19599
- );
19600
- }
19601
- const isDraft = !workflow.status || workflow.status === "DRAFT";
19602
- const client = getFluidGridsClient();
19603
- const preparedWorkflow = {
19604
- ...workflow,
19605
- nodes: workflow.nodes?.map((n) => {
19606
- const { nodeData: _ignoredNodeData, ...flattenedData } = n.data ?? {};
19607
- void _ignoredNodeData;
19608
- return { ...n, ...flattenedData };
19609
- })
19610
- };
19611
- const definitionJson = {
19612
- key: workflowKey,
19613
- name: workflow?.name,
19614
- description: workflow?.name || "Workflow Description",
19615
- workflow_type: "query-conditional",
19616
- data: {
19617
- ...preparedWorkflow,
19618
- version: workflow.version,
19619
- alias: workflow?.alias || null
19620
- },
19621
- meta: {
19622
- creator: "api_update",
19623
- version: workflow.version
19624
- },
19625
- tags: [
19626
- "rag",
19627
- "cache",
19628
- "websearch",
19629
- "conditional",
19630
- "python_expr",
19631
- "retry",
19632
- "api_trigger"
19633
- ]
19634
- };
19635
- let savedVersion = workflow.version;
19636
- let savedDbId = workflow.dbId;
19637
- let operation = "updated";
19638
- if (isDraft && workflow.dbId) {
19639
- const { data } = await client.mutate({
19640
- mutation: UpdateWorkflowDefinitionDocument,
19641
- variables: {
19642
- id: workflow.dbId,
19643
- input: {
19644
- definitionJson,
19645
- name: workflow?.name,
19646
- description: workflow?.name || "Workflow update",
19647
- alias: workflow?.alias || void 0
19648
- }
19649
- }
19650
- });
19651
- if (data?.updateWorkflowDefinition) {
19652
- savedVersion = data.updateWorkflowDefinition.version;
19653
- savedDbId = data.updateWorkflowDefinition.id;
19654
- operation = "updated";
19655
- toast.success("Workflow saved", {
19656
- description: `Updated version ${savedVersion}`,
19657
- dismissible: true
19658
- });
19659
- } else {
19660
- throw new Error("Failed to save workflow");
19661
- }
19662
- } else if (isDraft && !workflow.dbId) {
19663
- const { data } = await client.mutate({
19664
- mutation: CreateWorkflowDefinitionDocument,
19665
- variables: {
19666
- input: {
19667
- workflowKey,
19668
- version: workflow.version || params?.version || "v1",
19669
- name: workflow?.name || "Untitled Workflow",
19670
- description: workflow?.name || "Untitled Workflow",
19671
- definitionJson
19672
- }
19673
- }
19674
- });
19675
- if (data?.createWorkflowDefinition) {
19676
- savedVersion = data.createWorkflowDefinition.version;
19677
- savedDbId = data.createWorkflowDefinition.id;
19678
- operation = "created";
19679
- setWorkflow({
19680
- dbId: savedDbId,
19681
- status: data.createWorkflowDefinition.status ?? "DRAFT",
19682
- version: savedVersion
19683
- });
19684
- toast.success("Workflow saved", {
19685
- description: `Created version ${savedVersion}`,
19686
- dismissible: true
19687
- });
19688
- } else {
19689
- throw new Error("Failed to create workflow");
19690
- }
19691
- } else {
19692
- const { data } = await client.mutate({
19693
- mutation: CreateWorkflowVersionDocument,
19694
- variables: {
19695
- workflowKey,
19696
- input: {
19697
- definitionJson,
19698
- description: workflow?.name || "Workflow update"
19699
- }
19700
- }
19701
- });
19702
- if (data?.createWorkflowVersion?.success) {
19703
- const newWorkflow = data.createWorkflowVersion.workflow;
19704
- savedVersion = newWorkflow?.version ?? workflow.version;
19705
- savedDbId = newWorkflow?.id ?? workflow.dbId;
19706
- operation = "versioned";
19707
- setWorkflow({
19708
- version: savedVersion,
19709
- dbId: savedDbId,
19710
- status: "DRAFT"
19711
- });
19712
- navigate(`../workflow/${workflowKey}/${savedVersion}`, {
19713
- replace: true
19714
- });
19715
- toast.success("New version created", {
19716
- description: `Saved as version ${savedVersion} (Draft)`,
19717
- dismissible: true
19718
- });
19719
- } else {
19720
- throw new Error(
19721
- data?.createWorkflowVersion?.message || "Failed to save workflow"
19722
- );
19723
- }
19724
- }
19725
- if (savedDbId) {
19726
- const config2 = getFluidGridsConfig();
19727
- if (config2.onWorkflowSaved) {
19728
- try {
19729
- await config2.onWorkflowSaved({
19730
- dbId: savedDbId,
19731
- workflowKey,
19732
- version: savedVersion,
19733
- name: workflow?.name || "Untitled Workflow",
19734
- description: workflow?.alias || workflow?.name || void 0,
19735
- operation
19736
- });
19737
- } catch (callbackError) {
19738
- console.warn(
19739
- "[useSaveWorkflow] onWorkflowSaved callback failed:",
19740
- callbackError
19741
- );
19742
- }
19743
- }
19744
- }
19745
- } catch (error) {
19746
- const message = error instanceof Error ? error.message : "Unknown error";
19747
- console.error("Error saving workflow:", message);
19748
- toast.error("Failed to save workflow", {
19749
- description: message
19750
- });
19751
- } finally {
19752
- setIsSaving(false);
19753
- }
19754
- }, [saveWorkflow, setWorkflow, params?.id, params?.version, navigate]);
19755
- return { saveToBackend, isSaving };
19756
- }
19757
19699
  var SaveFlowButton = () => {
19758
19700
  const { saveToBackend, isSaving } = useSaveWorkflow();
19759
19701
  const [isValidating, validateFlow] = useFlowValidator(async (isValid) => {
@@ -22085,5 +22027,5 @@ function WorkflowBuilder() {
22085
22027
  }
22086
22028
 
22087
22029
  export { Card2 as Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ConfigSchemaForm, ConnectionFormDialog, ConnectionSelector, FluidGridsProvider, ProviderPicker, TemplateCard, WorkflowBuilder, getProviderForm, listCustomBlocks, registerCustomBlock, resolveUiSpec, stripSubmitActions, useConnection, useConnectionDialog, useConnections, useConnectionsByProvider, useCreateConnection, useFluidGridsContext, useImportWorkflowTemplate, useInitiateOAuth, useNodeExecution, useProviderByKey, useProviderCatalog, useProviders, useWorkflowTemplates };
22088
- //# sourceMappingURL=chunk-KSDJEBNQ.js.map
22089
- //# sourceMappingURL=chunk-KSDJEBNQ.js.map
22030
+ //# sourceMappingURL=chunk-Z24M3SR3.js.map
22031
+ //# sourceMappingURL=chunk-Z24M3SR3.js.map