@burdenoff/fluidgrids-fe-sdk 2026.1031.4 → 2026.1031.6

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 (43) hide show
  1. package/dist/ExecutionDetailPage-GKX4OUUR.js +23 -0
  2. package/dist/{WorkflowsList-BZXBTGNL.js → ExecutionsListPage-ZZOUZQBS.js} +9 -8
  3. package/dist/{TemplateDetailPanel-MTKW3SPM.js → TemplateDetailPanel-WH74G7PF.js} +18 -7
  4. package/dist/{WorkflowBuilder-N3ZUYFRK.js → WorkflowBuilder-4QEJNKVE.js} +12 -11
  5. package/dist/{ExecutionsListPage-AYDGFU6W.js → WorkflowsList-4CTHUYM7.js} +9 -8
  6. package/dist/{chunk-VJWJGSRS.js → chunk-34HHBNZE.js} +1 -1
  7. package/dist/{chunk-P3TGCUXP.js → chunk-34XK5BC7.js} +5 -37
  8. package/dist/{chunk-JFQGODKK.js → chunk-35N3PEO6.js} +1 -1
  9. package/dist/{chunk-DHR2YURL.js → chunk-3KKGE7CE.js} +164 -9
  10. package/dist/{chunk-XX6D7IND.js → chunk-5XQMYHJ7.js} +2 -2
  11. package/dist/{chunk-OGYAC7QW.js → chunk-AHDYETEE.js} +1 -1
  12. package/dist/{chunk-WHPQRYZD.js → chunk-CAZHE2MQ.js} +6 -5
  13. package/dist/{chunk-GV5RJ6BU.js → chunk-E7AQAPZN.js} +33 -22
  14. package/dist/{chunk-6PGLJWIC.js → chunk-EPYTVCYH.js} +30 -188
  15. package/dist/{chunk-DJAGZUHW.js → chunk-FUYHCONW.js} +1257 -34
  16. package/dist/{chunk-ADTEMSJI.js → chunk-GMVXPC5N.js} +849 -4
  17. package/dist/{chunk-IGROOI7E.js → chunk-GREPXIXS.js} +2 -2
  18. package/dist/{chunk-PTROESUB.js → chunk-HCKYGGUU.js} +4 -4
  19. package/dist/{chunk-Z3FYBDE3.js → chunk-HQX7JZLY.js} +33 -1
  20. package/dist/{chunk-QKQOTEAB.js → chunk-I5BPMBIV.js} +1 -1
  21. package/dist/{chunk-R4Q37Q4X.js → chunk-IJBT25CS.js} +3 -3
  22. package/dist/{chunk-44KAAKFK.js → chunk-JUHSLK7C.js} +5 -5
  23. package/dist/{chunk-AW3UXMNI.js → chunk-KEYKB4E7.js} +12 -1
  24. package/dist/{chunk-P2VAHDGO.js → chunk-NLRQSHRS.js} +2 -2
  25. package/dist/{chunk-BHD4CDLL.js → chunk-P4R4ACCC.js} +1 -1
  26. package/dist/{chunk-CIR7WF4W.js → chunk-PP62ABIG.js} +1 -1
  27. package/dist/{chunk-Q3HKE627.js → chunk-RYUSWVIR.js} +3 -3
  28. package/dist/{chunk-INMYNHJL.js → chunk-TVOXRODW.js} +34 -2
  29. package/dist/{chunk-PKG6BCHB.js → chunk-VWFA3RQR.js} +2 -2
  30. package/dist/{chunk-475XP5J7.js → chunk-ZEHMJURX.js} +6 -5
  31. package/dist/chunk-ZUVFD5KV.js +186 -0
  32. package/dist/executions.js +13 -12
  33. package/dist/history.js +5 -4
  34. package/dist/index.d.ts +741 -4
  35. package/dist/index.js +45 -40
  36. package/dist/nodes.js +2 -2
  37. package/dist/observability.js +7 -6
  38. package/dist/settings.js +7 -6
  39. package/dist/templates.js +11 -10
  40. package/dist/workflow-builder.js +13 -12
  41. package/dist/workflows-list.js +9 -8
  42. package/package.json +1 -1
  43. package/dist/ExecutionDetailPage-WOOORXXU.js +0 -22
@@ -0,0 +1,23 @@
1
+ export { ExecutionDetailPage } from './chunk-3KKGE7CE.js';
2
+ import './chunk-34XK5BC7.js';
3
+ import './chunk-5XQMYHJ7.js';
4
+ import './chunk-NLRQSHRS.js';
5
+ import './chunk-34HHBNZE.js';
6
+ import './chunk-5ERAJC2I.js';
7
+ import './chunk-GMVXPC5N.js';
8
+ import './chunk-TVOXRODW.js';
9
+ import './chunk-Y53CVZVV.js';
10
+ import './chunk-FNZZ5JJL.js';
11
+ import './chunk-VWFA3RQR.js';
12
+ import './chunk-PJAWNFJV.js';
13
+ import './chunk-HQX7JZLY.js';
14
+ import './chunk-EPYTVCYH.js';
15
+ import './chunk-ZUVFD5KV.js';
16
+ import './chunk-JL7CASN5.js';
17
+ import './chunk-PXIFUMLA.js';
18
+ import './chunk-6AMNEX2Y.js';
19
+ import './chunk-G77IGC3Y.js';
20
+ import './chunk-KEYKB4E7.js';
21
+ import './chunk-UULVIT25.js';
22
+ import './chunk-NTWG3CJX.js';
23
+ import './chunk-62GWEYJ5.js';
@@ -1,19 +1,20 @@
1
- export { WorkflowsList } from './chunk-475XP5J7.js';
2
- import './chunk-BHD4CDLL.js';
3
- import './chunk-XX6D7IND.js';
1
+ export { ExecutionsListPage } from './chunk-HCKYGGUU.js';
2
+ import './chunk-34XK5BC7.js';
3
+ import './chunk-5XQMYHJ7.js';
4
4
  import './chunk-5ERAJC2I.js';
5
- import './chunk-IGROOI7E.js';
5
+ import './chunk-TVOXRODW.js';
6
6
  import './chunk-FNZZ5JJL.js';
7
- import './chunk-PKG6BCHB.js';
7
+ import './chunk-VWFA3RQR.js';
8
8
  import './chunk-PJAWNFJV.js';
9
- import './chunk-Z3FYBDE3.js';
9
+ import './chunk-HQX7JZLY.js';
10
10
  import './chunk-4VJ3MDOV.js';
11
- import './chunk-6PGLJWIC.js';
11
+ import './chunk-EPYTVCYH.js';
12
+ import './chunk-ZUVFD5KV.js';
12
13
  import './chunk-JL7CASN5.js';
13
14
  import './chunk-PXIFUMLA.js';
14
15
  import './chunk-6AMNEX2Y.js';
15
16
  import './chunk-G77IGC3Y.js';
16
- import './chunk-AW3UXMNI.js';
17
+ import './chunk-KEYKB4E7.js';
17
18
  import './chunk-UULVIT25.js';
18
19
  import './chunk-NTWG3CJX.js';
19
20
  import './chunk-62GWEYJ5.js';
@@ -1,5 +1,6 @@
1
1
  import { templatePreview } from './chunk-B6CCE2RW.js';
2
2
  import { Button, Badge } from './chunk-BQXVT32O.js';
3
+ import { SdkPermissionButton, FLUIDGRIDS_PERMISSIONS } from './chunk-ZUVFD5KV.js';
3
4
  import './chunk-JL7CASN5.js';
4
5
  import { useTr } from './chunk-UULVIT25.js';
5
6
  import './chunk-62GWEYJ5.js';
@@ -188,13 +189,23 @@ function TemplateDetailPanel({
188
189
  )) })
189
190
  ] }),
190
191
  /* @__PURE__ */ jsxs("div", { className: "pt-2 space-y-2", children: [
191
- /* @__PURE__ */ jsxs(Button, { className: "w-full", onClick: () => onUseTemplate(template), children: [
192
- /* @__PURE__ */ jsx(Sparkles, { className: "size-4 mr-2" }),
193
- tr(
194
- "fluidgrids.builder.templateDetailPanel.useTemplateButton",
195
- "Use This Template"
196
- )
197
- ] }),
192
+ /* @__PURE__ */ jsx(
193
+ SdkPermissionButton,
194
+ {
195
+ permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_CREATE,
196
+ deniedTooltip: tr(
197
+ "fluidgrids.templates.useDeniedTooltip",
198
+ "You don't have permission to create workflows from templates"
199
+ ),
200
+ children: /* @__PURE__ */ jsxs(Button, { className: "w-full", onClick: () => onUseTemplate(template), children: [
201
+ /* @__PURE__ */ jsx(Sparkles, { className: "size-4 mr-2" }),
202
+ tr(
203
+ "fluidgrids.builder.templateDetailPanel.useTemplateButton",
204
+ "Use This Template"
205
+ )
206
+ ] })
207
+ }
208
+ ),
198
209
  template.publisher?.websiteUrl && /* @__PURE__ */ jsx(Button, { variant: "outline", className: "w-full", asChild: true, children: /* @__PURE__ */ jsxs(
199
210
  "a",
200
211
  {
@@ -1,26 +1,27 @@
1
- export { WorkflowBuilder } from './chunk-44KAAKFK.js';
2
- import './chunk-BHD4CDLL.js';
1
+ export { WorkflowBuilder } from './chunk-JUHSLK7C.js';
2
+ import './chunk-P4R4ACCC.js';
3
3
  import './chunk-PIKYQE7P.js';
4
- import './chunk-DJAGZUHW.js';
4
+ import './chunk-FUYHCONW.js';
5
5
  import './chunk-GEMNVFPK.js';
6
6
  import './chunk-B6CCE2RW.js';
7
7
  import './chunk-IEVSFCFS.js';
8
8
  import './chunk-YXMFRQYV.js';
9
9
  import './chunk-BQXVT32O.js';
10
- import './chunk-IGROOI7E.js';
11
- import './chunk-ADTEMSJI.js';
12
- import './chunk-INMYNHJL.js';
10
+ import './chunk-GREPXIXS.js';
11
+ import './chunk-GMVXPC5N.js';
12
+ import './chunk-TVOXRODW.js';
13
13
  import './chunk-Y53CVZVV.js';
14
- import './chunk-PKG6BCHB.js';
15
- import './chunk-Z3FYBDE3.js';
16
- import './chunk-JFQGODKK.js';
14
+ import './chunk-VWFA3RQR.js';
15
+ import './chunk-HQX7JZLY.js';
16
+ import './chunk-35N3PEO6.js';
17
17
  import './chunk-4VJ3MDOV.js';
18
- import './chunk-6PGLJWIC.js';
18
+ import './chunk-EPYTVCYH.js';
19
+ import './chunk-ZUVFD5KV.js';
19
20
  import './chunk-JL7CASN5.js';
20
21
  import './chunk-PXIFUMLA.js';
21
22
  import './chunk-6AMNEX2Y.js';
22
23
  import './chunk-G77IGC3Y.js';
23
- import './chunk-AW3UXMNI.js';
24
+ import './chunk-KEYKB4E7.js';
24
25
  import './chunk-UULVIT25.js';
25
26
  import './chunk-NTWG3CJX.js';
26
27
  import './chunk-62GWEYJ5.js';
@@ -1,19 +1,20 @@
1
- export { ExecutionsListPage } from './chunk-PTROESUB.js';
2
- import './chunk-P3TGCUXP.js';
3
- import './chunk-XX6D7IND.js';
1
+ export { WorkflowsList } from './chunk-ZEHMJURX.js';
2
+ import './chunk-P4R4ACCC.js';
3
+ import './chunk-5XQMYHJ7.js';
4
4
  import './chunk-5ERAJC2I.js';
5
- import './chunk-INMYNHJL.js';
5
+ import './chunk-GREPXIXS.js';
6
6
  import './chunk-FNZZ5JJL.js';
7
- import './chunk-PKG6BCHB.js';
7
+ import './chunk-VWFA3RQR.js';
8
8
  import './chunk-PJAWNFJV.js';
9
- import './chunk-Z3FYBDE3.js';
9
+ import './chunk-HQX7JZLY.js';
10
10
  import './chunk-4VJ3MDOV.js';
11
- import './chunk-6PGLJWIC.js';
11
+ import './chunk-EPYTVCYH.js';
12
+ import './chunk-ZUVFD5KV.js';
12
13
  import './chunk-JL7CASN5.js';
13
14
  import './chunk-PXIFUMLA.js';
14
15
  import './chunk-6AMNEX2Y.js';
15
16
  import './chunk-G77IGC3Y.js';
16
- import './chunk-AW3UXMNI.js';
17
+ import './chunk-KEYKB4E7.js';
17
18
  import './chunk-UULVIT25.js';
18
19
  import './chunk-NTWG3CJX.js';
19
20
  import './chunk-62GWEYJ5.js';
@@ -1,4 +1,4 @@
1
- import { throwIfResultError, describeOperationError } from './chunk-6PGLJWIC.js';
1
+ import { throwIfResultError, describeOperationError } from './chunk-EPYTVCYH.js';
2
2
  import { useTr } from './chunk-UULVIT25.js';
3
3
  import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
4
4
  import { useState, useCallback, useEffect, useMemo } from 'react';
@@ -1,10 +1,10 @@
1
- import { validateDateRange, statusCountFilter, STATUS_COUNT_GROUP_BY, statusCountsOf } from './chunk-XX6D7IND.js';
2
- import { useAvailableTags } from './chunk-INMYNHJL.js';
1
+ import { validateDateRange, statusCountFilter, STATUS_COUNT_GROUP_BY, statusCountsOf } from './chunk-5XQMYHJ7.js';
2
+ import { useAvailableTags, formatRunVersion, nodeDisplayTitle } from './chunk-TVOXRODW.js';
3
3
  import { executionsControls } from './chunk-FNZZ5JJL.js';
4
4
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
5
- import { useDurableParityEnabled, throwIfResultError, describeOperationError } from './chunk-6PGLJWIC.js';
5
+ import { useDurableParityEnabled, throwIfResultError, describeOperationError } from './chunk-EPYTVCYH.js';
6
6
  import { useExecutionsStore } from './chunk-6AMNEX2Y.js';
7
- import { SetWorkflowRunVersioningOverrideDocument, WorkflowRunsCountDocument, DurableParityRunFieldsDocument, WorkflowRunPendingDocument, WorkflowRunMetadataDocument } from './chunk-AW3UXMNI.js';
7
+ import { SetWorkflowRunVersioningOverrideDocument, WorkflowRunsCountDocument, DurableParityRunFieldsDocument, WorkflowRunPendingDocument, WorkflowRunMetadataDocument } from './chunk-KEYKB4E7.js';
8
8
  import { useTr } from './chunk-UULVIT25.js';
9
9
  import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
10
10
  import { Icon } from '@iconify/react';
@@ -1018,38 +1018,6 @@ function ExecutionStats({
1018
1018
  )
1019
1019
  ] });
1020
1020
  }
1021
-
1022
- // src/modules/executions/utils/run-display.ts
1023
- function formatRunVersion(version) {
1024
- if (!version) return "";
1025
- return version.startsWith("v") ? version : `v${version}`;
1026
- }
1027
- function asString(value) {
1028
- return typeof value === "string" && value.trim() ? value : void 0;
1029
- }
1030
- function buildNodeDisplayMap(definitionJson) {
1031
- const map = {};
1032
- const nodes = definitionJson?.data?.nodes;
1033
- if (!Array.isArray(nodes)) return map;
1034
- for (const node of nodes) {
1035
- const id = asString(node?.id);
1036
- if (!id) continue;
1037
- const label = asString(node?.data?.label) ?? asString(node?.data?.nodeData?.name) ?? asString(node?.type);
1038
- if (!label) continue;
1039
- const operation = asString(node?.data?.operation_name);
1040
- map[id] = {
1041
- label,
1042
- // 'execute' is the internal single-op pseudo-operation — the builder
1043
- // hides it on cards, so the runs screens do too.
1044
- operation: operation === "execute" ? void 0 : operation
1045
- };
1046
- }
1047
- return map;
1048
- }
1049
- function nodeDisplayTitle(display, fallback) {
1050
- if (!display) return fallback;
1051
- return display.operation ? `${display.label} \xB7 ${display.operation}` : display.label;
1052
- }
1053
1021
  function ExecutionTable({
1054
1022
  executions,
1055
1023
  workflowNames,
@@ -2879,4 +2847,4 @@ function useRunStatusCounts(input, enabled) {
2879
2847
  return enabled ? { ...state, error, refetch } : { total: null, counts: [], error: null, refetch };
2880
2848
  }
2881
2849
 
2882
- export { ExecutionCards, ExecutionFilters, ExecutionStats, ExecutionStatusBadge, ExecutionTable, ExecutionTimeline, NodeTimeline, Pagination, RunLogViewer, TagFilterSelect, buildNodeDisplayMap, formatRunVersion, runStatusLabels, setRunVersioningOverride, useDurableParityRunFields, useRunMetadata, useRunPending, useRunStatusCounts };
2850
+ export { ExecutionCards, ExecutionFilters, ExecutionStats, ExecutionStatusBadge, ExecutionTable, ExecutionTimeline, NodeTimeline, Pagination, RunLogViewer, TagFilterSelect, runStatusLabels, setRunVersioningOverride, useDurableParityRunFields, useRunMetadata, useRunPending, useRunStatusCounts };
@@ -1,4 +1,4 @@
1
- import { useAgentDefinitions, useAgentDefinitionList, useConnections, describeOperationError } from './chunk-6PGLJWIC.js';
1
+ import { useAgentDefinitions, useAgentDefinitionList, useConnections, describeOperationError } from './chunk-EPYTVCYH.js';
2
2
  import { useTr } from './chunk-UULVIT25.js';
3
3
  import { useState, useCallback, useEffect } from 'react';
4
4
  import { Icon } from '@iconify/react';
@@ -1,13 +1,15 @@
1
- import { useDurableParityRunFields, buildNodeDisplayMap, useRunMetadata, useRunPending, ExecutionStatusBadge, formatRunVersion, NodeTimeline, RunLogViewer, setRunVersioningOverride } from './chunk-P3TGCUXP.js';
2
- import { useExecution, useExecutionActions, useAutoRefresh, runChainLinks, shortRunId, callbackTone, parseMetadataDefinition, overrideRequestOf } from './chunk-XX6D7IND.js';
3
- import { fetchRunFailureClusters, OPEN_STATUSES, dismissRunFailureCluster, BUCKET_LABELS } from './chunk-P2VAHDGO.js';
4
- import { useRunPolicyDecisions, RunPolicyDecisions } from './chunk-VJWJGSRS.js';
5
- import { useDurableRunFields, useRunHistory, useDeterminismStatus, useRunStackTrace, EntityTagPicker, RunHistoryView, SignalRunDialog, terminateDurableRun, useWorkflowProposal, WorkflowProposalCard } from './chunk-ADTEMSJI.js';
1
+ import { useDurableParityRunFields, useRunMetadata, useRunPending, ExecutionStatusBadge, NodeTimeline, RunLogViewer, setRunVersioningOverride } from './chunk-34XK5BC7.js';
2
+ import { useExecution, useExecutionActions, useAutoRefresh, runChainLinks, shortRunId, callbackTone, parseMetadataDefinition, overrideRequestOf } from './chunk-5XQMYHJ7.js';
3
+ import { fetchRunFailureClusters, OPEN_STATUSES, dismissRunFailureCluster, BUCKET_LABELS } from './chunk-NLRQSHRS.js';
4
+ import { useRunPolicyDecisions, RunPolicyDecisions } from './chunk-34HHBNZE.js';
5
+ import { useDurableRunFields, useRunHistory, useDeterminismStatus, useRunStackTrace, EntityTagPicker, RunHistoryView, SignalRunDialog, terminateDurableRun, canSaveRunAsTestCase, useWorkflowProposal, WorkflowProposalCard, MAX_CASE_NAME, saveRunAsTestCase } from './chunk-GMVXPC5N.js';
6
+ import { buildNodeDisplayMap, formatRunVersion } from './chunk-TVOXRODW.js';
6
7
  import { AiCreditBalanceSlot } from './chunk-Y53CVZVV.js';
7
- import { useWorkflowVersions } from './chunk-PKG6BCHB.js';
8
- import { throwIfResultError, useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, useDurableFunctionNodesEnabled, useDurableParityEnabled, runSignalTargets, canSignalRun, describeOperationError } from './chunk-6PGLJWIC.js';
8
+ import { useWorkflowVersions } from './chunk-VWFA3RQR.js';
9
+ import { throwIfResultError, useDurableFunctionNodesEnabled, useDurableParityEnabled, runSignalTargets, canSignalRun, useWorkflowTestsEnabled, describeOperationError } from './chunk-EPYTVCYH.js';
10
+ import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton } from './chunk-ZUVFD5KV.js';
9
11
  import { getFluidGridsConfig } from './chunk-6AMNEX2Y.js';
10
- import { RunLogsDocument, RunLogAppendedDocument, ExplainRunDocument } from './chunk-AW3UXMNI.js';
12
+ import { RunLogsDocument, RunLogAppendedDocument, ExplainRunDocument } from './chunk-KEYKB4E7.js';
11
13
  import { useTr } from './chunk-UULVIT25.js';
12
14
  import { getFluidGridsClient, getFluidGridsClientSafe } from './chunk-NTWG3CJX.js';
13
15
  import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
@@ -15,12 +17,13 @@ import { useParams, useNavigate, Link } from 'react-router';
15
17
  import { Icon } from '@iconify/react';
16
18
  import { toast } from 'sonner';
17
19
  import { Button } from '@burdenoff/fe-libs/button';
18
- import { Card, CardHeader, Badge, CardContent, Label, Textarea, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, Input, Button as Button$1 } from '@burdenoff/fe-libs/ui';
20
+ import { Card, CardHeader, Badge, CardContent, Label, Textarea, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, Input, Button as Button$1, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@burdenoff/fe-libs/ui';
19
21
  import { useActorProfiles, buildActorFallback } from '@burdenoff/fe-libs/shared';
20
22
  import { gql } from '@apollo/client';
21
23
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
22
24
  import ReactMarkdown from 'react-markdown';
23
25
  import { cn } from '@burdenoff/fe-libs/utils';
26
+ import { FlaskConical } from 'lucide-react';
24
27
 
25
28
  var POLL_INTERVAL_MS = 2e3;
26
29
  var PAGE_SIZE = 500;
@@ -2148,6 +2151,149 @@ function RunVersioningOverrideDialogHost({
2148
2151
  }
2149
2152
  );
2150
2153
  }
2154
+ function SaveRunAsTestCaseButton(props) {
2155
+ const enabled = useWorkflowTestsEnabled();
2156
+ if (!enabled || !canSaveRunAsTestCase(props)) return null;
2157
+ return /* @__PURE__ */ jsx(SaveRunAsTestCase, { runId: props.runId });
2158
+ }
2159
+ function SaveRunAsTestCase({ runId }) {
2160
+ const tr = useTr();
2161
+ const [open, setOpen] = useState(false);
2162
+ const [name, setName] = useState("");
2163
+ const [description, setDescription] = useState("");
2164
+ const [saving, setSaving] = useState(false);
2165
+ const openDialog = () => {
2166
+ setName(`Run ${runId.slice(0, 8)}`);
2167
+ setDescription("");
2168
+ setOpen(true);
2169
+ };
2170
+ const save = async () => {
2171
+ const trimmed = name.trim();
2172
+ if (!trimmed) return;
2173
+ setSaving(true);
2174
+ try {
2175
+ const created = await saveRunAsTestCase(
2176
+ runId,
2177
+ trimmed,
2178
+ description.trim() || void 0
2179
+ );
2180
+ toast.success(
2181
+ tr(
2182
+ "fluidgrids.executions.saveAsTestCase.saved",
2183
+ "Saved as a test case"
2184
+ ),
2185
+ {
2186
+ description: tr(
2187
+ "fluidgrids.executions.saveAsTestCase.savedDescription",
2188
+ "{{name}} is in the workflow's Tests panel.",
2189
+ { name: created.name }
2190
+ ),
2191
+ dismissible: true
2192
+ }
2193
+ );
2194
+ setOpen(false);
2195
+ } catch (err) {
2196
+ toast.error(
2197
+ tr(
2198
+ "fluidgrids.executions.saveAsTestCase.error",
2199
+ "Could not save the run as a test case"
2200
+ ),
2201
+ { description: err instanceof Error ? err.message : String(err) }
2202
+ );
2203
+ } finally {
2204
+ setSaving(false);
2205
+ }
2206
+ };
2207
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2208
+ /* @__PURE__ */ jsx(
2209
+ SdkPermissionButton,
2210
+ {
2211
+ permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_UPDATE,
2212
+ deniedTooltip: tr(
2213
+ "fluidgrids.executions.saveAsTestCase.denied",
2214
+ "You need edit access to this workflow to save test cases"
2215
+ ),
2216
+ children: /* @__PURE__ */ jsxs(
2217
+ Button,
2218
+ {
2219
+ variant: "outline",
2220
+ size: "sm",
2221
+ onClick: openDialog,
2222
+ "data-testid": "fluidgrids-save-run-as-test-case",
2223
+ children: [
2224
+ /* @__PURE__ */ jsx(FlaskConical, { className: "mr-1 size-4" }),
2225
+ tr(
2226
+ "fluidgrids.executions.saveAsTestCase.button",
2227
+ "Save as test case"
2228
+ )
2229
+ ]
2230
+ }
2231
+ )
2232
+ }
2233
+ ),
2234
+ /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => !saving && setOpen(next), children: /* @__PURE__ */ jsxs(DialogContent, { "data-testid": "fluidgrids-save-run-as-test-case-dialog", children: [
2235
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
2236
+ /* @__PURE__ */ jsx(DialogTitle, { children: tr(
2237
+ "fluidgrids.executions.saveAsTestCase.title",
2238
+ "Save this run as a test case"
2239
+ ) }),
2240
+ /* @__PURE__ */ jsx(DialogDescription, { children: tr(
2241
+ "fluidgrids.executions.saveAsTestCase.body",
2242
+ "The test case replays this run's input. Every connection call the run made is mocked with the output it returned; the workflow's own logic runs for real."
2243
+ ) })
2244
+ ] }),
2245
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
2246
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
2247
+ /* @__PURE__ */ jsx(Label, { htmlFor: "fg-run-test-case-name", className: "text-xs", children: tr("fluidgrids.executions.saveAsTestCase.name", "Name") }),
2248
+ /* @__PURE__ */ jsx(
2249
+ Input,
2250
+ {
2251
+ id: "fg-run-test-case-name",
2252
+ value: name,
2253
+ maxLength: MAX_CASE_NAME,
2254
+ onChange: (event) => setName(event.target.value)
2255
+ }
2256
+ )
2257
+ ] }),
2258
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
2259
+ /* @__PURE__ */ jsx(Label, { htmlFor: "fg-run-test-case-description", className: "text-xs", children: tr(
2260
+ "fluidgrids.executions.saveAsTestCase.description",
2261
+ "Description (optional)"
2262
+ ) }),
2263
+ /* @__PURE__ */ jsx(
2264
+ Textarea,
2265
+ {
2266
+ id: "fg-run-test-case-description",
2267
+ value: description,
2268
+ rows: 2,
2269
+ onChange: (event) => setDescription(event.target.value)
2270
+ }
2271
+ )
2272
+ ] })
2273
+ ] }),
2274
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
2275
+ /* @__PURE__ */ jsx(
2276
+ Button,
2277
+ {
2278
+ variant: "outline",
2279
+ disabled: saving,
2280
+ onClick: () => setOpen(false),
2281
+ children: tr("fluidgrids.executions.saveAsTestCase.cancel", "Cancel")
2282
+ }
2283
+ ),
2284
+ /* @__PURE__ */ jsx(
2285
+ Button,
2286
+ {
2287
+ disabled: saving || name.trim() === "",
2288
+ onClick: () => void save(),
2289
+ "data-testid": "fluidgrids-save-run-as-test-case-confirm",
2290
+ children: tr("fluidgrids.executions.saveAsTestCase.confirm", "Save")
2291
+ }
2292
+ )
2293
+ ] })
2294
+ ] }) })
2295
+ ] });
2296
+ }
2151
2297
  var ALL_DETAIL_TABS = [
2152
2298
  "timeline",
2153
2299
  "history",
@@ -2829,6 +2975,15 @@ function ExecutionDetailPage() {
2829
2975
  ]
2830
2976
  }
2831
2977
  ),
2978
+ /* @__PURE__ */ jsx(
2979
+ SaveRunAsTestCaseButton,
2980
+ {
2981
+ runId: execution.id,
2982
+ status: execution.status,
2983
+ workflowKey: execution.workflowKey,
2984
+ isDurable: isDurableRun || durableEnabled && durableFields.fields?.id !== execution.id
2985
+ }
2986
+ ),
2832
2987
  /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: refetch, children: [
2833
2988
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:refresh", className: "mr-1", width: 16 }),
2834
2989
  tr(
@@ -1,7 +1,7 @@
1
1
  import { REPLAY_WORKFLOW_RUN, RETRY_WORKFLOW_RUNS } from './chunk-5ERAJC2I.js';
2
- import { useFluidGridsAnalytics, throwIfResultError, emitRunStarted, openRunQuotaUpgradePrompt } from './chunk-6PGLJWIC.js';
2
+ import { useFluidGridsAnalytics, throwIfResultError, emitRunStarted, openRunQuotaUpgradePrompt } from './chunk-EPYTVCYH.js';
3
3
  import { useExecutionsStore } from './chunk-6AMNEX2Y.js';
4
- import { ExecutionsListDocument, ExecutionDetailDocument, ExecutionStatsDocument, PauseExecutionDocument, ResumeExecutionDocument, CancelExecutionDocument, RetryNodeDocument, TriggerWorkflowDocument, TerminateExecutionDocument } from './chunk-AW3UXMNI.js';
4
+ import { ExecutionsListDocument, ExecutionDetailDocument, ExecutionStatsDocument, PauseExecutionDocument, ResumeExecutionDocument, CancelExecutionDocument, RetryNodeDocument, TriggerWorkflowDocument, TerminateExecutionDocument } from './chunk-KEYKB4E7.js';
5
5
  import { useTr } from './chunk-UULVIT25.js';
6
6
  import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
7
7
  import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
@@ -1,4 +1,4 @@
1
- import { NodeEndpointConfigsDocument, NodeEndpointConfigDocument, NodeManifestDocument, fetchAllNodeEndpointConfigs } from './chunk-AW3UXMNI.js';
1
+ import { NodeEndpointConfigsDocument, NodeEndpointConfigDocument, NodeManifestDocument, fetchAllNodeEndpointConfigs } from './chunk-KEYKB4E7.js';
2
2
  import { useTr } from './chunk-UULVIT25.js';
3
3
  import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
4
4
  import { useMemo, useState, useCallback, useEffect } from 'react';
@@ -1,11 +1,12 @@
1
- import { ActionPoliciesTab } from './chunk-VJWJGSRS.js';
2
- import { LogStreamingTab } from './chunk-CIR7WF4W.js';
3
- import { AgentsTab } from './chunk-JFQGODKK.js';
1
+ import { ActionPoliciesTab } from './chunk-34HHBNZE.js';
2
+ import { LogStreamingTab } from './chunk-PP62ABIG.js';
3
+ import { AgentsTab } from './chunk-35N3PEO6.js';
4
4
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
5
- import { useFlowStore, useFluidGridsFlag, FLUIDGRIDS_FLAGS, useSaveStatusStore, useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, findSaveConflict, useDurableParityEnabled, throwIfResultError, describeOperationError, useConnections } from './chunk-6PGLJWIC.js';
5
+ import { useFlowStore, useFluidGridsFlag, FLUIDGRIDS_FLAGS, useSaveStatusStore, findSaveConflict, useDurableParityEnabled, throwIfResultError, describeOperationError, useConnections } from './chunk-EPYTVCYH.js';
6
+ import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS } from './chunk-ZUVFD5KV.js';
6
7
  import { getGlobalStoreClient } from './chunk-PXIFUMLA.js';
7
8
  import { getFluidGridsConfig } from './chunk-6AMNEX2Y.js';
8
- import { useWorkflowDefinitionQuery, useUpdateWorkflowDefinitionMutation, useWorkflowDefinitionsQuery, DurableHistoryCapsDocument, UpdateDurableHistoryCapsDocument } from './chunk-AW3UXMNI.js';
9
+ import { useWorkflowDefinitionQuery, useUpdateWorkflowDefinitionMutation, useWorkflowDefinitionsQuery, DurableHistoryCapsDocument, UpdateDurableHistoryCapsDocument } from './chunk-KEYKB4E7.js';
9
10
  import { useTr } from './chunk-UULVIT25.js';
10
11
  import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
11
12
  import { useState, useMemo, useEffect, useCallback } from 'react';
@@ -1,10 +1,11 @@
1
- import { useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TEMPLATE_STORE_CATEGORIES, TemplateCard, useTemplateSubmissions, usePublishToStore } from './chunk-DJAGZUHW.js';
2
- import { QuotaExhaustedDialog } from './chunk-IGROOI7E.js';
1
+ import { useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TEMPLATE_STORE_CATEGORIES, TemplateCard, useTemplateSubmissions, usePublishToStore } from './chunk-FUYHCONW.js';
2
+ import { QuotaExhaustedDialog } from './chunk-GREPXIXS.js';
3
3
  import { templatesControls } from './chunk-FNZZ5JJL.js';
4
- import { useWorkflowDefinitions, useDuplicateWorkflow, useLazyWorkflowDefinition } from './chunk-PKG6BCHB.js';
4
+ import { useWorkflowDefinitions, useDuplicateWorkflow, useLazyWorkflowDefinition } from './chunk-VWFA3RQR.js';
5
5
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
6
6
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
7
- import { BILLING_PLANS_PATH, useFluidGridsAnalytics, emitTemplateUsed, isQuotaExhaustedFailure, SdkPermissionButton, FLUIDGRIDS_PERMISSIONS } from './chunk-6PGLJWIC.js';
7
+ import { BILLING_PLANS_PATH, useFluidGridsAnalytics, emitTemplateUsed, isQuotaExhaustedFailure } from './chunk-EPYTVCYH.js';
8
+ import { SdkPermissionButton, FLUIDGRIDS_PERMISSIONS } from './chunk-ZUVFD5KV.js';
8
9
  import { useTr } from './chunk-UULVIT25.js';
9
10
  import { useState, useEffect, useCallback, useMemo } from 'react';
10
11
  import { useParams, useNavigate } from 'react-router';
@@ -217,25 +218,35 @@ function TemplatePreview() {
217
218
  template?.description ? /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-muted-foreground", children: template.description }) : null
218
219
  ] })
219
220
  ] }),
220
- /* @__PURE__ */ jsxs(
221
- Button,
221
+ /* @__PURE__ */ jsx(
222
+ SdkPermissionButton,
222
223
  {
223
- onClick: handleUse,
224
- disabled: importing || !template,
225
- className: "shrink-0 gap-2",
226
- children: [
227
- /* @__PURE__ */ jsx(
228
- Icon,
229
- {
230
- icon: importing ? "svg-spinners:ring-resize" : "mdi:plus",
231
- className: "size-4"
232
- }
233
- ),
234
- tr(
235
- "fluidgrids.pages.templatePreview.useThisTemplate",
236
- "Use this template"
237
- )
238
- ]
224
+ permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_CREATE,
225
+ deniedTooltip: tr(
226
+ "fluidgrids.templates.useDeniedTooltip",
227
+ "You don't have permission to create workflows from templates"
228
+ ),
229
+ children: /* @__PURE__ */ jsxs(
230
+ Button,
231
+ {
232
+ onClick: handleUse,
233
+ disabled: importing || !template,
234
+ className: "shrink-0 gap-2",
235
+ children: [
236
+ /* @__PURE__ */ jsx(
237
+ Icon,
238
+ {
239
+ icon: importing ? "svg-spinners:ring-resize" : "mdi:plus",
240
+ className: "size-4"
241
+ }
242
+ ),
243
+ tr(
244
+ "fluidgrids.pages.templatePreview.useThisTemplate",
245
+ "Use this template"
246
+ )
247
+ ]
248
+ }
249
+ )
239
250
  }
240
251
  )
241
252
  ] }),