@burdenoff/fluidgrids-fe-sdk 2026.923.1 → 2026.923.3

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.
Files changed (44) hide show
  1. package/dist/{ExecutionDetailPage-22KHNXBI.js → ExecutionDetailPage-BD7CS4KL.js} +4 -4
  2. package/dist/{ExecutionDetailPage-22KHNXBI.js.map → ExecutionDetailPage-BD7CS4KL.js.map} +1 -1
  3. package/dist/{ExecutionsListPage-NQWK2NCN.js → ExecutionsListPage-VOGSLA7T.js} +4 -4
  4. package/dist/{ExecutionsListPage-NQWK2NCN.js.map → ExecutionsListPage-VOGSLA7T.js.map} +1 -1
  5. package/dist/{WorkflowBuilder-2PLQT5OZ.js → WorkflowBuilder-WLJBVVHS.js} +4 -4
  6. package/dist/{WorkflowBuilder-2PLQT5OZ.js.map → WorkflowBuilder-WLJBVVHS.js.map} +1 -1
  7. package/dist/{WorkflowsList-M2GOHL6L.js → WorkflowsList-O7SLDXML.js} +3 -3
  8. package/dist/{WorkflowsList-M2GOHL6L.js.map → WorkflowsList-O7SLDXML.js.map} +1 -1
  9. package/dist/{chunk-YNDQYVT2.js → chunk-4C6UYNC5.js} +3 -3
  10. package/dist/{chunk-YNDQYVT2.js.map → chunk-4C6UYNC5.js.map} +1 -1
  11. package/dist/{chunk-24A4C63H.js → chunk-5A7GP6O7.js} +189 -67
  12. package/dist/chunk-5A7GP6O7.js.map +1 -0
  13. package/dist/{chunk-C7OR5C6R.js → chunk-5PZDLMC4.js} +3 -3
  14. package/dist/{chunk-C7OR5C6R.js.map → chunk-5PZDLMC4.js.map} +1 -1
  15. package/dist/{chunk-EGQB462S.js → chunk-FKOUPL6Z.js} +355 -128
  16. package/dist/chunk-FKOUPL6Z.js.map +1 -0
  17. package/dist/{chunk-AQBWMYKP.js → chunk-HNVWIVJH.js} +52 -16
  18. package/dist/chunk-HNVWIVJH.js.map +1 -0
  19. package/dist/{chunk-ILH7U6VB.js → chunk-LH2YML5F.js} +3 -3
  20. package/dist/{chunk-ILH7U6VB.js.map → chunk-LH2YML5F.js.map} +1 -1
  21. package/dist/{chunk-RRBFISAU.js → chunk-TEZV7I6A.js} +3 -3
  22. package/dist/{chunk-RRBFISAU.js.map → chunk-TEZV7I6A.js.map} +1 -1
  23. package/dist/{chunk-PTI43PVQ.js → chunk-TOHTP3BT.js} +3 -3
  24. package/dist/{chunk-PTI43PVQ.js.map → chunk-TOHTP3BT.js.map} +1 -1
  25. package/dist/{chunk-WTKMWWSI.js → chunk-VTPBYPDV.js} +10 -4
  26. package/dist/chunk-VTPBYPDV.js.map +1 -0
  27. package/dist/{chunk-XQ7FGXPM.js → chunk-X3OSUZIS.js} +397 -7
  28. package/dist/chunk-X3OSUZIS.js.map +1 -0
  29. package/dist/{chunk-JMJRE5RT.js → chunk-XF7QA3QT.js} +414 -152
  30. package/dist/chunk-XF7QA3QT.js.map +1 -0
  31. package/dist/executions.js +3 -3
  32. package/dist/index.js +17 -17
  33. package/dist/observability.js +2 -2
  34. package/dist/settings.js +2 -2
  35. package/dist/templates.js +2 -2
  36. package/dist/workflow-builder.js +3 -3
  37. package/dist/workflows-list.js +1 -1
  38. package/package.json +1 -1
  39. package/dist/chunk-24A4C63H.js.map +0 -1
  40. package/dist/chunk-AQBWMYKP.js.map +0 -1
  41. package/dist/chunk-EGQB462S.js.map +0 -1
  42. package/dist/chunk-JMJRE5RT.js.map +0 -1
  43. package/dist/chunk-WTKMWWSI.js.map +0 -1
  44. package/dist/chunk-XQ7FGXPM.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { QuotaExhaustedDialog } from './chunk-AANIWER2.js';
2
2
  import { SdkPermissionButton, FLUIDGRIDS_PERMISSIONS, SdkPermissionGate } from './chunk-W23ZXNKU.js';
3
- import { useWorkflowDefinitions, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-Q4RPP67K.js';
3
+ import { useWorkflowDefinitions, useLazyWorkflowDefinition, useCreateWorkflow, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-Q4RPP67K.js';
4
4
  import { config } from './chunk-WWU2O2SR.js';
5
5
  import { useFlowStore } from './chunk-YMD3T6J2.js';
6
6
  import { useTr } from './chunk-7YWBH2A5.js';
@@ -8,7 +8,7 @@ import { useState, useMemo } from 'react';
8
8
  import { useNavigate } from 'react-router';
9
9
  import { v4 } from 'uuid';
10
10
  import { Icon } from '@iconify/react';
11
- import { Button, Badge, Input, IllustratedEmptyState, Skeleton, TooltipProvider, Card, Tooltip, TooltipTrigger, TooltipContent, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from '@burdenoff/fe-libs/ui';
11
+ import { Button, Badge, Input, IllustratedEmptyState, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Label, Textarea, DialogFooter, Skeleton, TooltipProvider, Card, Tooltip, TooltipTrigger, TooltipContent, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from '@burdenoff/fe-libs/ui';
12
12
  import { cn } from '@burdenoff/fe-libs/utils';
13
13
  import { TagBadge } from '@burdenoff/fe-libs/tag';
14
14
  import { isQuotaExhaustedError } from '@burdenoff/fe-libs/shared/utils';
@@ -191,7 +191,8 @@ function relativeTime(iso) {
191
191
  }
192
192
  var CardWorkflow = ({
193
193
  workflow,
194
- onUpdateSuccess
194
+ onUpdateSuccess,
195
+ onExport
195
196
  }) => {
196
197
  const tr = useTr();
197
198
  const navigate = useNavigate();
@@ -255,6 +256,9 @@ var CardWorkflow = ({
255
256
  const handleOnEdit = () => {
256
257
  navigate("../workflow/" + workflow.workflow_key + "/" + workflow.version);
257
258
  };
259
+ const handleOnSettings = () => {
260
+ navigate("../settings/" + workflow.workflow_key);
261
+ };
258
262
  const handleCardClick = (e) => {
259
263
  const el = e.target;
260
264
  if (el.closest("button, a, input, [role='dialog'], .fixed")) return;
@@ -370,6 +374,26 @@ var CardWorkflow = ({
370
374
  "Edit workflow"
371
375
  ) }) })
372
376
  ] }),
377
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
378
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
379
+ Button,
380
+ {
381
+ variant: "ghost",
382
+ size: "icon",
383
+ className: "size-8",
384
+ onClick: handleOnSettings,
385
+ "aria-label": tr(
386
+ "fluidgrids.builder.cardWorkflow.workflowSettings",
387
+ "Workflow settings"
388
+ ),
389
+ children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:cog-outline", className: "size-4" })
390
+ }
391
+ ) }),
392
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: tr(
393
+ "fluidgrids.builder.cardWorkflow.workflowSettings",
394
+ "Workflow settings"
395
+ ) }) })
396
+ ] }),
373
397
  /* @__PURE__ */ jsxs(Tooltip, { children: [
374
398
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
375
399
  SharePopup,
@@ -383,6 +407,26 @@ var CardWorkflow = ({
383
407
  "Share workflow"
384
408
  ) }) })
385
409
  ] }),
410
+ onExport && /* @__PURE__ */ jsxs(Tooltip, { children: [
411
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
412
+ Button,
413
+ {
414
+ variant: "ghost",
415
+ size: "icon",
416
+ className: "size-8",
417
+ onClick: onExport,
418
+ "aria-label": tr(
419
+ "fluidgrids.builder.cardWorkflow.exportWorkflow",
420
+ "Export workflow JSON"
421
+ ),
422
+ children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:download", className: "size-4" })
423
+ }
424
+ ) }),
425
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: tr(
426
+ "fluidgrids.builder.cardWorkflow.exportWorkflow",
427
+ "Export workflow JSON"
428
+ ) }) })
429
+ ] }),
386
430
  /* @__PURE__ */ jsx(
387
431
  SdkPermissionGate,
388
432
  {
@@ -491,6 +535,340 @@ var CardWorkflow = ({
491
535
  )
492
536
  ] });
493
537
  };
538
+
539
+ // src/utils/workflow-transfer.ts
540
+ function asRecord(value) {
541
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
542
+ }
543
+ function collectWorkflowNodeReferences(definition) {
544
+ const root = asRecord(definition);
545
+ const data = asRecord(root?.data);
546
+ const nodes = data?.nodes;
547
+ if (!Array.isArray(nodes)) return [];
548
+ const seen = /* @__PURE__ */ new Set();
549
+ const references = [];
550
+ for (const candidate of nodes) {
551
+ const node = asRecord(candidate);
552
+ const nodeData = asRecord(node?.data);
553
+ const nodeId = typeof node?.id === "string" ? node.id : null;
554
+ const nodeType = typeof nodeData?.nodeId === "string" ? nodeData.nodeId : node?.type;
555
+ if (!nodeId || typeof nodeType !== "string") continue;
556
+ const nodeVersion = typeof nodeData?.nodeVersion === "string" ? nodeData.nodeVersion : null;
557
+ const key = `${nodeId}:${nodeType}:${nodeVersion ?? ""}`;
558
+ if (seen.has(key)) continue;
559
+ seen.add(key);
560
+ references.push({ nodeId, nodeType, nodeVersion });
561
+ }
562
+ return references;
563
+ }
564
+ function createWorkflowExportPayload(workflow) {
565
+ const definitionJson = asRecord(workflow.definitionJson);
566
+ if (!definitionJson)
567
+ throw new Error("Workflow definition JSON must be an object");
568
+ return {
569
+ format: "fluidgrids.workflow",
570
+ schemaVersion: 1,
571
+ exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
572
+ workflowKey: workflow.workflowKey,
573
+ version: workflow.version,
574
+ name: workflow.name,
575
+ description: workflow.description ?? null,
576
+ definitionJson,
577
+ context: asRecord(workflow.context),
578
+ tags: workflow.tags,
579
+ tagsV2: workflow.tagsV2,
580
+ icon: workflow.icon ?? null,
581
+ category: workflow.category ?? null,
582
+ nodeReferences: collectWorkflowNodeReferences(definitionJson)
583
+ };
584
+ }
585
+ function downloadWorkflowExport(workflow) {
586
+ const payload = createWorkflowExportPayload(workflow);
587
+ const blob = new Blob([JSON.stringify(payload, null, 2)], {
588
+ type: "application/json"
589
+ });
590
+ const url = URL.createObjectURL(blob);
591
+ const anchor = document.createElement("a");
592
+ anchor.href = url;
593
+ anchor.download = `${workflow.workflowKey}-${workflow.version}.fluidgrids.json`;
594
+ anchor.click();
595
+ URL.revokeObjectURL(url);
596
+ }
597
+ function parseWorkflowImport(raw) {
598
+ const parsed = JSON.parse(raw);
599
+ const root = asRecord(parsed);
600
+ if (!root) throw new Error("Import must contain a JSON object");
601
+ const definitionJson = asRecord(root.definitionJson) ?? root;
602
+ const name = typeof root.name === "string" && root.name.trim() ? root.name : "Imported workflow";
603
+ return {
604
+ definitionJson,
605
+ name,
606
+ workflowKey: typeof root.workflowKey === "string" ? root.workflowKey : void 0,
607
+ version: typeof root.version === "string" ? root.version : void 0,
608
+ description: typeof root.description === "string" ? root.description : void 0,
609
+ context: asRecord(root.context) ?? void 0,
610
+ tags: Array.isArray(root.tags) && root.tags.every((tag) => typeof tag === "string") ? root.tags : void 0,
611
+ tagsV2: root.tagsV2,
612
+ icon: typeof root.icon === "string" ? root.icon : void 0,
613
+ category: typeof root.category === "string" ? root.category : void 0,
614
+ nodeReferences: Array.isArray(root.nodeReferences) ? root.nodeReferences : collectWorkflowNodeReferences(definitionJson)
615
+ };
616
+ }
617
+ function WorkflowImportDialog({
618
+ onImported
619
+ }) {
620
+ const tr = useTr();
621
+ const { createWorkflow, loading } = useCreateWorkflow();
622
+ const [open, setOpen] = useState(false);
623
+ const [rawJson, setRawJson] = useState("");
624
+ const [url, setUrl] = useState("");
625
+ const [parsed, setParsed] = useState(null);
626
+ const [name, setName] = useState("");
627
+ const [workflowKey, setWorkflowKey] = useState("");
628
+ const [version, setVersion] = useState("");
629
+ const [loadingUrl, setLoadingUrl] = useState(false);
630
+ const reset = () => {
631
+ setRawJson("");
632
+ setUrl("");
633
+ setParsed(null);
634
+ setName("");
635
+ setWorkflowKey("");
636
+ setVersion("");
637
+ };
638
+ const parse = (value) => {
639
+ try {
640
+ const next = parseWorkflowImport(value);
641
+ setParsed(next);
642
+ setName(next.name);
643
+ setWorkflowKey("");
644
+ setVersion(next.version ?? "");
645
+ } catch (error) {
646
+ setParsed(null);
647
+ toast.error(
648
+ error instanceof Error ? error.message : tr(
649
+ "fluidgrids.workflowsList.importInvalidJson",
650
+ "Invalid workflow JSON"
651
+ )
652
+ );
653
+ }
654
+ };
655
+ const handleFile = async (file) => {
656
+ if (!file) return;
657
+ try {
658
+ parse(await file.text());
659
+ } catch (error) {
660
+ toast.error(
661
+ error instanceof Error ? error.message : "Unable to read import file"
662
+ );
663
+ }
664
+ };
665
+ const handleUrl = async () => {
666
+ if (!url.trim()) return;
667
+ let parsedUrl;
668
+ try {
669
+ parsedUrl = new URL(url.trim());
670
+ if (parsedUrl.protocol !== "https:")
671
+ throw new Error("Import URLs must use HTTPS");
672
+ } catch (error) {
673
+ toast.error(
674
+ error instanceof Error ? error.message : "Invalid import URL"
675
+ );
676
+ return;
677
+ }
678
+ setLoadingUrl(true);
679
+ try {
680
+ const response = await fetch(parsedUrl, { credentials: "omit" });
681
+ if (!response.ok)
682
+ throw new Error(`Import URL returned HTTP ${response.status}`);
683
+ parse(await response.text());
684
+ } catch (error) {
685
+ toast.error(
686
+ error instanceof Error ? error.message : "Unable to fetch import URL"
687
+ );
688
+ } finally {
689
+ setLoadingUrl(false);
690
+ }
691
+ };
692
+ const handleImport = async () => {
693
+ if (!parsed || !name.trim()) return;
694
+ const input = {
695
+ workflowKey: workflowKey.trim() || `${name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-")}-${Date.now()}`,
696
+ version: version.trim() || "v1",
697
+ name: name.trim(),
698
+ description: parsed.description,
699
+ definitionJson: parsed.definitionJson,
700
+ context: parsed.context,
701
+ tags: parsed.tags,
702
+ tagsV2: parsed.tagsV2,
703
+ icon: parsed.icon,
704
+ category: parsed.category
705
+ };
706
+ const created = await createWorkflow(input);
707
+ if (!created) return;
708
+ toast.success(
709
+ tr("fluidgrids.workflowsList.importSuccess", "Workflow imported")
710
+ );
711
+ setOpen(false);
712
+ reset();
713
+ onImported();
714
+ };
715
+ return /* @__PURE__ */ jsxs(
716
+ Dialog,
717
+ {
718
+ open,
719
+ onOpenChange: (nextOpen) => {
720
+ setOpen(nextOpen);
721
+ if (!nextOpen) reset();
722
+ },
723
+ children: [
724
+ /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "default", onClick: () => setOpen(true), children: [
725
+ /* @__PURE__ */ jsx(Icon, { icon: "mynaui:download", className: "size-4" }),
726
+ tr("fluidgrids.workflowsList.importButton", "Import")
727
+ ] }),
728
+ /* @__PURE__ */ jsxs(DialogContent, { className: "max-h-[90vh] overflow-y-auto sm:max-w-2xl", children: [
729
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
730
+ /* @__PURE__ */ jsx(DialogTitle, { children: tr("fluidgrids.workflowsList.importTitle", "Import workflow JSON") }),
731
+ /* @__PURE__ */ jsx(DialogDescription, { children: tr(
732
+ "fluidgrids.workflowsList.importDescription",
733
+ "Import from a file, an HTTPS URL, or pasted JSON. Credentials remain references and must be configured in this workspace."
734
+ ) })
735
+ ] }),
736
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
737
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
738
+ /* @__PURE__ */ jsxs(
739
+ Label,
740
+ {
741
+ htmlFor: "fluidgrids-workflow-import-file",
742
+ className: "inline-flex cursor-pointer items-center gap-2 rounded-md border border-border px-3 py-2 text-sm hover:bg-accent",
743
+ children: [
744
+ /* @__PURE__ */ jsx(Icon, { icon: "mynaui:upload", className: "size-4" }),
745
+ tr(
746
+ "fluidgrids.workflowsList.importChooseFile",
747
+ "Choose JSON file"
748
+ )
749
+ ]
750
+ }
751
+ ),
752
+ /* @__PURE__ */ jsx(
753
+ "input",
754
+ {
755
+ id: "fluidgrids-workflow-import-file",
756
+ type: "file",
757
+ accept: "application/json,.json",
758
+ className: "sr-only",
759
+ onChange: (event) => void handleFile(event.currentTarget.files?.[0])
760
+ }
761
+ )
762
+ ] }),
763
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
764
+ /* @__PURE__ */ jsx(
765
+ Input,
766
+ {
767
+ value: url,
768
+ onChange: (event) => setUrl(event.target.value),
769
+ placeholder: "https://example.com/workflow.json",
770
+ "aria-label": tr(
771
+ "fluidgrids.workflowsList.importUrlLabel",
772
+ "Workflow JSON URL"
773
+ )
774
+ }
775
+ ),
776
+ /* @__PURE__ */ jsx(
777
+ Button,
778
+ {
779
+ variant: "outline",
780
+ onClick: () => void handleUrl(),
781
+ disabled: loadingUrl || !url.trim(),
782
+ children: loadingUrl ? "Loading\u2026" : tr("fluidgrids.workflowsList.importFetchUrl", "Fetch")
783
+ }
784
+ )
785
+ ] }),
786
+ /* @__PURE__ */ jsx(
787
+ Textarea,
788
+ {
789
+ value: rawJson,
790
+ onChange: (event) => {
791
+ setRawJson(event.target.value);
792
+ setParsed(null);
793
+ },
794
+ onBlur: () => rawJson.trim() && parse(rawJson),
795
+ placeholder: tr(
796
+ "fluidgrids.workflowsList.importPastePlaceholder",
797
+ "Paste workflow JSON here"
798
+ ),
799
+ className: "min-h-44 font-mono text-xs",
800
+ "aria-label": tr(
801
+ "fluidgrids.workflowsList.importPasteLabel",
802
+ "Workflow JSON"
803
+ )
804
+ }
805
+ ),
806
+ parsed && /* @__PURE__ */ jsxs("div", { className: "space-y-3 rounded-lg border border-border bg-muted/30 p-3", children: [
807
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
808
+ parsed.nodeReferences.length,
809
+ " ",
810
+ tr(
811
+ "fluidgrids.workflowsList.importNodeReferences",
812
+ "node references found"
813
+ )
814
+ ] }),
815
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-3 sm:grid-cols-3", children: [
816
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1 sm:col-span-3", children: [
817
+ /* @__PURE__ */ jsx(Label, { htmlFor: "fluidgrids-import-name", children: tr("fluidgrids.workflowsList.importName", "Name") }),
818
+ /* @__PURE__ */ jsx(
819
+ Input,
820
+ {
821
+ id: "fluidgrids-import-name",
822
+ value: name,
823
+ onChange: (event) => setName(event.target.value)
824
+ }
825
+ )
826
+ ] }),
827
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1 sm:col-span-2", children: [
828
+ /* @__PURE__ */ jsx(Label, { htmlFor: "fluidgrids-import-key", children: tr(
829
+ "fluidgrids.workflowsList.importKey",
830
+ "Workflow key (optional)"
831
+ ) }),
832
+ /* @__PURE__ */ jsx(
833
+ Input,
834
+ {
835
+ id: "fluidgrids-import-key",
836
+ value: workflowKey,
837
+ onChange: (event) => setWorkflowKey(event.target.value)
838
+ }
839
+ )
840
+ ] }),
841
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
842
+ /* @__PURE__ */ jsx(Label, { htmlFor: "fluidgrids-import-version", children: tr("fluidgrids.workflowsList.importVersion", "Version") }),
843
+ /* @__PURE__ */ jsx(
844
+ Input,
845
+ {
846
+ id: "fluidgrids-import-version",
847
+ value: version,
848
+ onChange: (event) => setVersion(event.target.value),
849
+ placeholder: "v1"
850
+ }
851
+ )
852
+ ] })
853
+ ] })
854
+ ] })
855
+ ] }),
856
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
857
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setOpen(false), children: tr("fluidgrids.workflowsList.importCancel", "Cancel") }),
858
+ /* @__PURE__ */ jsx(
859
+ Button,
860
+ {
861
+ onClick: () => void handleImport(),
862
+ disabled: loading || !parsed || !name.trim(),
863
+ children: loading ? tr("fluidgrids.workflowsList.importing", "Importing\u2026") : tr("fluidgrids.workflowsList.importConfirm", "Import workflow")
864
+ }
865
+ )
866
+ ] })
867
+ ] })
868
+ ]
869
+ }
870
+ );
871
+ }
494
872
  function useStatusFilters() {
495
873
  const tr = useTr();
496
874
  return useMemo(
@@ -536,6 +914,7 @@ function WorkflowsList() {
536
914
  limit: 100,
537
915
  latestOnly: true
538
916
  });
917
+ const { getWorkflow } = useLazyWorkflowDefinition();
539
918
  const [search, setSearch] = useState("");
540
919
  const [statusFilter, setStatusFilter] = useState(null);
541
920
  const [tagFilter, setTagFilter] = useState(null);
@@ -567,6 +946,15 @@ function WorkflowsList() {
567
946
  return [w.name, w.description, w.alias].filter((v) => typeof v === "string").some((v) => v.toLowerCase().includes(q));
568
947
  });
569
948
  }, [workflows, search, statusFilter, tagFilter, tagsByKey]);
949
+ const handleExport = async (id) => {
950
+ const workflow = await getWorkflow(void 0, id);
951
+ if (!workflow) return;
952
+ try {
953
+ downloadWorkflowExport(workflow);
954
+ } catch (error2) {
955
+ console.error("Unable to export workflow", error2);
956
+ }
957
+ };
570
958
  const createButton = /* @__PURE__ */ jsx(
571
959
  SdkPermissionButton,
572
960
  {
@@ -616,7 +1004,8 @@ function WorkflowsList() {
616
1004
  "Build, run, and manage your automations. Open a workflow to edit it in the visual builder."
617
1005
  ) })
618
1006
  ] }),
619
- createButton
1007
+ createButton,
1008
+ /* @__PURE__ */ jsx(WorkflowImportDialog, { onImported: () => void refetch() })
620
1009
  ]
621
1010
  }
622
1011
  ),
@@ -790,7 +1179,8 @@ function WorkflowsList() {
790
1179
  color: a.tagInfo?.color ?? void 0
791
1180
  }))
792
1181
  },
793
- onUpdateSuccess: () => refetch()
1182
+ onUpdateSuccess: () => refetch(),
1183
+ onExport: () => void handleExport(workflow.id)
794
1184
  },
795
1185
  workflow.id
796
1186
  )) })
@@ -801,5 +1191,5 @@ function WorkflowsList() {
801
1191
  }
802
1192
 
803
1193
  export { WorkflowsList };
804
- //# sourceMappingURL=chunk-XQ7FGXPM.js.map
805
- //# sourceMappingURL=chunk-XQ7FGXPM.js.map
1194
+ //# sourceMappingURL=chunk-X3OSUZIS.js.map
1195
+ //# sourceMappingURL=chunk-X3OSUZIS.js.map