@burdenoff/fluidgrids-fe-sdk 2026.1104.1 → 2026.1104.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/ExecutionDetailPage-ND2VMU45.js +25 -0
  2. package/dist/{ExecutionsListPage-3KSHXY4G.js → ExecutionsListPage-EZ65FXER.js} +9 -9
  3. package/dist/{TemplateDetailPanel-XJ43LW3G.js → TemplateDetailPanel-7MPY5MYT.js} +1 -1
  4. package/dist/{WorkflowBuilder-LG7TFPU2.js → WorkflowBuilder-4I44FWII.js} +14 -14
  5. package/dist/{WorkflowsList-KB23QLNI.js → WorkflowsList-YFD2RKKQ.js} +9 -9
  6. package/dist/{agentTools-J7A22OD5.js → agentTools-SZZN6TP3.js} +5 -5
  7. package/dist/{chunk-N3WDPUGC.js → chunk-4EUEKSEQ.js} +1 -1
  8. package/dist/{chunk-H5WEPFLT.js → chunk-4YCMMBSK.js} +2 -2
  9. package/dist/{chunk-ZUVFD5KV.js → chunk-5375NUIO.js} +2 -0
  10. package/dist/{chunk-L2MUO3VU.js → chunk-5D4XS3WJ.js} +2 -2
  11. package/dist/{chunk-BOTM2YQG.js → chunk-5UHAB75U.js} +1 -1
  12. package/dist/{chunk-WWR7ZCS5.js → chunk-AAIZ6S6E.js} +2 -2
  13. package/dist/{chunk-4YB6BMV3.js → chunk-AFX3EKFN.js} +2 -2
  14. package/dist/{chunk-H3RSOHD5.js → chunk-AVHBWJRY.js} +4 -2
  15. package/dist/{chunk-VB4STO5K.js → chunk-BIB7IH26.js} +4 -4
  16. package/dist/{chunk-LQ7KYFAK.js → chunk-D4WA2M2N.js} +2 -2
  17. package/dist/{chunk-IO2MKIEI.js → chunk-DFIX6YWP.js} +59 -16
  18. package/dist/{chunk-7GI3457S.js → chunk-F7LQL43U.js} +1 -1
  19. package/dist/{chunk-D46ZR6XI.js → chunk-GEY7RXRZ.js} +5 -5
  20. package/dist/{chunk-AOLY5INN.js → chunk-H4ERTSMX.js} +31 -1
  21. package/dist/{chunk-3HM6SO5A.js → chunk-IK7IGG6T.js} +6 -6
  22. package/dist/{chunk-YGGPLCJD.js → chunk-KHXRYQYP.js} +2 -2
  23. package/dist/{chunk-WFDNMJBW.js → chunk-MF7JLSJX.js} +1 -1
  24. package/dist/{chunk-D7DZB3MU.js → chunk-NGXJHYV5.js} +1 -1
  25. package/dist/{chunk-PR6QP4R7.js → chunk-NIY6R42C.js} +4 -4
  26. package/dist/{chunk-B5L7VBDH.js → chunk-NJRCAE6K.js} +4 -4
  27. package/dist/{chunk-64WNLW7J.js → chunk-NYBL5WHP.js} +2 -2
  28. package/dist/{chunk-626EGC24.js → chunk-OMB3WMDQ.js} +6 -6
  29. package/dist/{chunk-PN2XVTLA.js → chunk-ON7LK6QH.js} +5 -5
  30. package/dist/{chunk-7S6M2BYB.js → chunk-Q72EOY4T.js} +3 -3
  31. package/dist/{chunk-QH5KODNH.js → chunk-SS7Y66P5.js} +2 -2
  32. package/dist/{chunk-FSU6LYGU.js → chunk-TBHAZK52.js} +1 -1
  33. package/dist/{chunk-4C6XRZK6.js → chunk-VDJFTZ2H.js} +1 -1
  34. package/dist/{chunk-PXVHPGUB.js → chunk-WTV6SQYK.js} +11 -11
  35. package/dist/{chunk-MJGB6XAP.js → chunk-X6PIU7FE.js} +201 -5
  36. package/dist/{chunk-QA7O5PUG.js → chunk-XCSCD3IU.js} +261 -217
  37. package/dist/{chunk-BJ5H5QV4.js → chunk-XNU2PLJ2.js} +4 -4
  38. package/dist/{chunk-JFG2XCJR.js → chunk-YYVRBROH.js} +1 -1
  39. package/dist/{chunk-OXDRU5GT.js → chunk-ZDCJPQ5M.js} +1 -1
  40. package/dist/executions.js +14 -14
  41. package/dist/history.js +6 -6
  42. package/dist/index.d.ts +152 -1
  43. package/dist/index.js +46 -46
  44. package/dist/{node-detail-view-NWY5PDKY.js → node-detail-view-GAGSLHAO.js} +10 -10
  45. package/dist/nodes.js +2 -2
  46. package/dist/observability.js +7 -7
  47. package/dist/{quick-config-panel-SCNELONP.js → quick-config-panel-44RBX6YR.js} +7 -7
  48. package/dist/settings.js +7 -7
  49. package/dist/templates.js +13 -13
  50. package/dist/workflow-builder.js +15 -15
  51. package/dist/workflows-list.js +9 -9
  52. package/package.json +4 -4
  53. package/dist/ExecutionDetailPage-WNDMCMME.js +0 -25
@@ -1,16 +1,16 @@
1
- import { CreateWorkflowRefusalDialog, firstWorkflowProgress, GUIDED_TOUR_STATE, builderPathFor } from './chunk-FSU6LYGU.js';
2
- import { useExecutions } from './chunk-L2MUO3VU.js';
3
- import { useExportWorkflowAs, downloadWorkflowExport, importAcceptAttribute, QuotaExhaustedDialog, importFileKind, parseWorkflowImport, CODE_EXPORT_FORMATS, ImportSourceError, assertImportByteSize, MAX_IMPORT_ARCHIVE_BYTES, readProjectArchive, checkTypeScriptImport, MAX_IMPORT_SOURCE_BYTES, typeScriptModuleFile, typeScriptImportSource, workflowNameFromFile, primaryImportModule } from './chunk-MJGB6XAP.js';
1
+ import { CreateWorkflowRefusalDialog, firstWorkflowProgress, GUIDED_TOUR_STATE, builderPathFor } from './chunk-TBHAZK52.js';
2
+ import { useExecutions } from './chunk-5D4XS3WJ.js';
3
+ import { useExportWorkflowAs, WorkflowShareDialog, downloadWorkflowExport, importAcceptAttribute, canEditWorkflow, canShareWorkflow, QuotaExhaustedDialog, importFileKind, parseWorkflowImport, CODE_EXPORT_FORMATS, ImportSourceError, assertImportByteSize, MAX_IMPORT_ARCHIVE_BYTES, readProjectArchive, checkTypeScriptImport, MAX_IMPORT_SOURCE_BYTES, typeScriptModuleFile, typeScriptImportSource, workflowNameFromFile, primaryImportModule } from './chunk-X6PIU7FE.js';
4
4
  import { workflowsListControls } from './chunk-FNZZ5JJL.js';
5
- import { useCreateWorkflow, useWorkflowDefinitions, useLazyWorkflowDefinition, useImportWorkflow, usePreviewN8nImport, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-4YB6BMV3.js';
5
+ import { useCreateWorkflow, useWorkflowDefinitions, useLazyWorkflowDefinition, useImportWorkflow, usePreviewN8nImport, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-AFX3EKFN.js';
6
6
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
7
7
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
8
- import { createThenOpen, useFluidGridsFlag, FLUIDGRIDS_FLAGS, BILLING_PLANS_PATH, describeOperationError, useFlowStore, throwIfResultError, isQuotaExhaustedFailure } from './chunk-WWR7ZCS5.js';
9
- import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton, SdkPermissionGate } from './chunk-ZUVFD5KV.js';
10
- import { WorkflowFoldersDocument, CreateWorkflowFolderDocument, RenameWorkflowFolderDocument, MoveWorkflowFolderDocument, DeleteWorkflowFolderDocument, WorkflowProjectsDocument, CreateWorkflowProjectDocument, RenameWorkflowProjectDocument, DeleteWorkflowProjectDocument, BulkMoveWorkflowsToFolderDocument, BulkAssignWorkflowsToProjectDocument, BulkDeleteWorkflowsDocument } from './chunk-H3RSOHD5.js';
8
+ import { createThenOpen, FluidGridsContext, useFluidGridsFlag, FLUIDGRIDS_FLAGS, BILLING_PLANS_PATH, describeOperationError, useFlowStore, throwIfResultError, isQuotaExhaustedFailure } from './chunk-AAIZ6S6E.js';
9
+ import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton, SdkPermissionGate } from './chunk-5375NUIO.js';
10
+ import { WorkflowFoldersDocument, CreateWorkflowFolderDocument, RenameWorkflowFolderDocument, MoveWorkflowFolderDocument, DeleteWorkflowFolderDocument, WorkflowProjectsDocument, CreateWorkflowProjectDocument, RenameWorkflowProjectDocument, DeleteWorkflowProjectDocument, BulkMoveWorkflowsToFolderDocument, BulkAssignWorkflowsToProjectDocument, BulkDeleteWorkflowsDocument } from './chunk-AVHBWJRY.js';
11
11
  import { useTr } from './chunk-UULVIT25.js';
12
12
  import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
13
- import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
13
+ import { useState, useRef, useCallback, useContext, useMemo, useEffect } from 'react';
14
14
  import { useNavigate } from 'react-router';
15
15
  import { v4 } from 'uuid';
16
16
  import { Icon } from '@iconify/react';
@@ -18,7 +18,6 @@ import { NextSteps, Button, Badge, Input, IllustratedEmptyState, Checkbox, Dialo
18
18
  import { cn } from '@burdenoff/fe-libs/utils';
19
19
  import { TagBadge } from '@burdenoff/fe-libs/tag';
20
20
  import { toast } from 'sonner';
21
- import { Share2, Copy } from 'lucide-react';
22
21
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
23
22
 
24
23
  function useCreateWorkflowFirst(options = {}) {
@@ -52,200 +51,6 @@ function useCreateWorkflowFirst(options = {}) {
52
51
  const clearRefusal = useCallback(() => setRefusal(null), []);
53
52
  return { start, creating, refusal, clearRefusal };
54
53
  }
55
-
56
- // src/components/share-target.ts
57
- var PLACEHOLDER_SEGMENTS = /* @__PURE__ */ new Set(["undefined", "null"]);
58
- function toPublicUrl(raw) {
59
- if (typeof raw !== "string" || raw.trim() === "") return null;
60
- let parsed;
61
- try {
62
- parsed = new URL(raw);
63
- } catch {
64
- return null;
65
- }
66
- if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null;
67
- if (!parsed.hostname || PLACEHOLDER_SEGMENTS.has(parsed.hostname)) {
68
- return null;
69
- }
70
- const hasPlaceholderSegment = parsed.pathname.split("/").some((segment) => PLACEHOLDER_SEGMENTS.has(segment.toLowerCase()));
71
- if (hasPlaceholderSegment) return null;
72
- return parsed.href;
73
- }
74
- function resolveShareTarget(input) {
75
- const shareUrl = toPublicUrl(input.shareUrl);
76
- if (!shareUrl) return null;
77
- const embedUrl = toPublicUrl(input.embedUrl);
78
- return embedUrl ? { shareUrl, embedUrl } : { shareUrl };
79
- }
80
- var MIN_EMBED_SIZE = 100;
81
- var MAX_EMBED_SIZE = 4e3;
82
- function clampEmbedSize(value, fallback) {
83
- if (!Number.isFinite(value)) return fallback;
84
- return Math.min(MAX_EMBED_SIZE, Math.max(MIN_EMBED_SIZE, Math.round(value)));
85
- }
86
- function buildEmbedSnippet(embedUrl, width, height) {
87
- const w = clampEmbedSize(width, 600);
88
- const h = clampEmbedSize(height, 400);
89
- return `<iframe src="${embedUrl}" width="${w}" height="${h}" frameborder="0"></iframe>`;
90
- }
91
- function SharePopup({ shareUrl, embedUrl }) {
92
- const tr = useTr();
93
- const [isOpen, setIsOpen] = useState(false);
94
- const [width, setWidth] = useState(600);
95
- const [height, setHeight] = useState(400);
96
- const [activeTab, setActiveTab] = useState("link");
97
- const target = resolveShareTarget({ shareUrl, embedUrl });
98
- if (!target) {
99
- return /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "icon", disabled: true, "aria-disabled": "true", children: [
100
- /* @__PURE__ */ jsx(Share2, { className: "h-4 w-4" }),
101
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: tr(
102
- "fluidgrids.components.sharePopup.unavailableLabel",
103
- "Sharing is not available yet"
104
- ) })
105
- ] });
106
- }
107
- const embedCode = target.embedUrl ? buildEmbedSnippet(target.embedUrl, width, height) : "";
108
- const copyToClipboard = (text, message) => {
109
- navigator.clipboard.writeText(text).then(
110
- () => toast.success(message),
111
- () => toast.error(
112
- tr(
113
- "fluidgrids.components.sharePopup.copyFailedToast",
114
- "Could not copy to clipboard"
115
- )
116
- )
117
- );
118
- };
119
- if (!isOpen) {
120
- return /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "icon", onClick: () => setIsOpen(true), children: [
121
- /* @__PURE__ */ jsx(Share2, { className: "h-4 w-4" }),
122
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: tr("fluidgrids.components.sharePopup.openLabel", "Share") })
123
- ] });
124
- }
125
- return /* @__PURE__ */ jsx(
126
- "div",
127
- {
128
- className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay",
129
- onClick: () => setIsOpen(false),
130
- children: /* @__PURE__ */ jsxs(
131
- "div",
132
- {
133
- className: "bg-card rounded-lg p-6 max-w-md w-full mx-4",
134
- onClick: (e) => e.stopPropagation(),
135
- children: [
136
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
137
- /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: tr("fluidgrids.components.sharePopup.title", "Share") }),
138
- /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", onClick: () => setIsOpen(false), children: "\xD7" })
139
- ] }),
140
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2 mb-4", children: [
141
- /* @__PURE__ */ jsx(
142
- Button,
143
- {
144
- variant: activeTab === "link" ? "default" : "outline",
145
- size: "sm",
146
- onClick: () => setActiveTab("link"),
147
- children: tr("fluidgrids.components.sharePopup.tabShareLink", "Share Link")
148
- }
149
- ),
150
- target.embedUrl && /* @__PURE__ */ jsx(
151
- Button,
152
- {
153
- variant: activeTab === "embed" ? "default" : "outline",
154
- size: "sm",
155
- onClick: () => setActiveTab("embed"),
156
- children: tr("fluidgrids.components.sharePopup.tabEmbed", "Embed")
157
- }
158
- )
159
- ] }),
160
- activeTab === "link" && /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
161
- /* @__PURE__ */ jsx(
162
- "input",
163
- {
164
- readOnly: true,
165
- value: target.shareUrl,
166
- className: "flex-1 h-9 px-3 rounded-md border bg-background text-sm"
167
- }
168
- ),
169
- /* @__PURE__ */ jsx(
170
- Button,
171
- {
172
- size: "sm",
173
- onClick: () => copyToClipboard(
174
- target.shareUrl,
175
- tr(
176
- "fluidgrids.components.sharePopup.linkCopiedToast",
177
- "Link copied to clipboard"
178
- )
179
- ),
180
- children: /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" })
181
- }
182
- )
183
- ] }),
184
- activeTab === "embed" && target.embedUrl && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
185
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
186
- /* @__PURE__ */ jsxs("div", { children: [
187
- /* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: tr("fluidgrids.components.sharePopup.widthLabel", "Width") }),
188
- /* @__PURE__ */ jsx(
189
- "input",
190
- {
191
- type: "number",
192
- value: width,
193
- onChange: (e) => setWidth(Number(e.target.value)),
194
- className: "w-full h-9 px-3 rounded-md border bg-background text-sm mt-1"
195
- }
196
- )
197
- ] }),
198
- /* @__PURE__ */ jsxs("div", { children: [
199
- /* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: tr("fluidgrids.components.sharePopup.heightLabel", "Height") }),
200
- /* @__PURE__ */ jsx(
201
- "input",
202
- {
203
- type: "number",
204
- value: height,
205
- onChange: (e) => setHeight(Number(e.target.value)),
206
- className: "w-full h-9 px-3 rounded-md border bg-background text-sm mt-1"
207
- }
208
- )
209
- ] })
210
- ] }),
211
- /* @__PURE__ */ jsxs("div", { children: [
212
- /* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: tr(
213
- "fluidgrids.components.sharePopup.embedCodeLabel",
214
- "Embed Code"
215
- ) }),
216
- /* @__PURE__ */ jsxs("div", { className: "relative mt-1", children: [
217
- /* @__PURE__ */ jsx(
218
- "input",
219
- {
220
- readOnly: true,
221
- value: embedCode,
222
- className: "w-full h-9 px-3 pr-12 rounded-md border bg-background text-sm font-mono"
223
- }
224
- ),
225
- /* @__PURE__ */ jsx(
226
- Button,
227
- {
228
- size: "sm",
229
- className: "absolute right-1 top-1/2 -translate-y-1/2 h-7",
230
- onClick: () => copyToClipboard(
231
- embedCode,
232
- tr(
233
- "fluidgrids.components.sharePopup.embedCopiedToast",
234
- "Embed code copied to clipboard"
235
- )
236
- ),
237
- children: /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" })
238
- }
239
- )
240
- ] })
241
- ] })
242
- ] })
243
- ]
244
- }
245
- )
246
- }
247
- );
248
- }
249
54
  function WorkflowStatusPill({ status }) {
250
55
  const tr = useTr();
251
56
  const styles = {
@@ -360,7 +165,9 @@ var CardWorkflow = ({
360
165
  onUpdateSuccess,
361
166
  onExport,
362
167
  onExportAs,
363
- exportingFormat = null
168
+ exportingFormat = null,
169
+ onShare,
170
+ onMoveToProject
364
171
  }) => {
365
172
  const tr = useTr();
366
173
  const navigate = useNavigate();
@@ -435,6 +242,9 @@ var CardWorkflow = ({
435
242
  return;
436
243
  handleOnEdit();
437
244
  };
245
+ const restricted = workflow.visibility === "RESTRICTED";
246
+ const editable = canEditWorkflow(workflow.my_access);
247
+ const shareable = canShareWorkflow(workflow.my_access);
438
248
  const updatedExact = workflow.updated_at ? new Date(workflow.updated_at).toLocaleString() : void 0;
439
249
  return /* @__PURE__ */ jsxs(TooltipProvider, { children: [
440
250
  /* @__PURE__ */ jsxs(
@@ -460,7 +270,27 @@ var CardWorkflow = ({
460
270
  /* @__PURE__ */ jsx("div", { className: "flex size-9 shrink-0 items-center justify-center rounded-lg border border-primary/20 bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:transit-connection-variant", className: "size-5" }) }),
461
271
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
462
272
  /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
463
- /* @__PURE__ */ jsx("h3", { className: "truncate font-semibold leading-6 text-card-foreground", children: workflow?.name }),
273
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
274
+ /* @__PURE__ */ jsx("h3", { className: "truncate font-semibold leading-6 text-card-foreground", children: workflow?.name }),
275
+ restricted && /* @__PURE__ */ jsxs(Tooltip, { children: [
276
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
277
+ "span",
278
+ {
279
+ className: "shrink-0 text-muted-foreground",
280
+ "data-testid": "workflow-restricted-badge",
281
+ "aria-label": tr(
282
+ "fluidgrids.builder.cardWorkflow.restricted",
283
+ "Shared only with chosen people"
284
+ ),
285
+ children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:lock-outline", className: "size-3.5" })
286
+ }
287
+ ) }),
288
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: tr(
289
+ "fluidgrids.builder.cardWorkflow.restricted",
290
+ "Shared only with chosen people"
291
+ ) }) })
292
+ ] })
293
+ ] }),
464
294
  /* @__PURE__ */ jsx(WorkflowStatusPill, { status: workflow.status })
465
295
  ] }),
466
296
  /* @__PURE__ */ jsx("p", { className: "mt-1 line-clamp-2 text-xs leading-snug text-muted-foreground", children: workflow.description || tr(
@@ -556,13 +386,60 @@ var CardWorkflow = ({
556
386
  "Workflow settings"
557
387
  ) }) })
558
388
  ] }),
559
- /* @__PURE__ */ jsxs(Tooltip, { children: [
560
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { tabIndex: 0, "data-card-action": "", children: /* @__PURE__ */ jsx(SharePopup, {}) }) }),
561
- /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: tr(
562
- "fluidgrids.builder.cardWorkflow.shareUnavailable",
563
- "Sharing is not available for workflows yet"
564
- ) }) })
565
- ] }),
389
+ onShare && shareable && /* @__PURE__ */ jsx(
390
+ SdkPermissionGate,
391
+ {
392
+ permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_SHARE,
393
+ children: /* @__PURE__ */ jsxs(Tooltip, { children: [
394
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
395
+ Button,
396
+ {
397
+ variant: "ghost",
398
+ size: "icon",
399
+ className: "size-8",
400
+ onClick: onShare,
401
+ "data-testid": "workflow-card-share",
402
+ "aria-label": tr(
403
+ "fluidgrids.builder.cardWorkflow.shareWorkflow",
404
+ "Share workflow"
405
+ ),
406
+ children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:share", className: "size-4" })
407
+ }
408
+ ) }),
409
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: tr(
410
+ "fluidgrids.builder.cardWorkflow.shareWorkflow",
411
+ "Share workflow"
412
+ ) }) })
413
+ ] })
414
+ }
415
+ ),
416
+ onMoveToProject && editable && /* @__PURE__ */ jsx(
417
+ SdkPermissionGate,
418
+ {
419
+ permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_UPDATE,
420
+ children: /* @__PURE__ */ jsxs(Tooltip, { children: [
421
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
422
+ Button,
423
+ {
424
+ variant: "ghost",
425
+ size: "icon",
426
+ className: "size-8",
427
+ onClick: onMoveToProject,
428
+ "data-testid": "workflow-card-move-project",
429
+ "aria-label": tr(
430
+ "fluidgrids.builder.cardWorkflow.moveToProject",
431
+ "Move to project"
432
+ ),
433
+ children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:folder-move-outline", className: "size-4" })
434
+ }
435
+ ) }),
436
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: tr(
437
+ "fluidgrids.builder.cardWorkflow.moveToProject",
438
+ "Move to project"
439
+ ) }) })
440
+ ] })
441
+ }
442
+ ),
566
443
  onExportAs ? /* @__PURE__ */ jsx("span", { "data-card-action": "", children: /* @__PURE__ */ jsx(
567
444
  WorkflowExportMenu,
568
445
  {
@@ -615,7 +492,7 @@ var CardWorkflow = ({
615
492
  ] })
616
493
  }
617
494
  ),
618
- /* @__PURE__ */ jsx(
495
+ editable && /* @__PURE__ */ jsx(
619
496
  SdkPermissionGate,
620
497
  {
621
498
  permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_DELETE,
@@ -2440,6 +2317,87 @@ function FirstWorkflowChecklist({
2440
2317
  }
2441
2318
  return /* @__PURE__ */ jsx(ChecklistWithRuns, { workflows, canCreate });
2442
2319
  }
2320
+ var NO_PROJECT = "__none__";
2321
+ function WorkflowMoveToProjectDialog({
2322
+ workflow,
2323
+ onClose,
2324
+ onMoved
2325
+ }) {
2326
+ const tr = useTr();
2327
+ const { projects } = useWorkflowProjects();
2328
+ const { bulkAssignToProject, loading } = useBulkWorkflowActions();
2329
+ const [choice, setChoice] = useState(null);
2330
+ const current = workflow?.projectId ?? NO_PROJECT;
2331
+ const selected = choice ?? current;
2332
+ const close = () => {
2333
+ setChoice(null);
2334
+ onClose();
2335
+ };
2336
+ const move = async () => {
2337
+ if (!workflow) return;
2338
+ const result = await bulkAssignToProject(
2339
+ [workflow.id],
2340
+ selected === NO_PROJECT ? null : selected
2341
+ );
2342
+ if (!result || result.failedIds.length > 0) {
2343
+ toast.error(
2344
+ tr(
2345
+ "fluidgrids.workflowsList.moveToProject.failed",
2346
+ "The workflow couldn't be moved"
2347
+ )
2348
+ );
2349
+ return;
2350
+ }
2351
+ toast.success(
2352
+ tr("fluidgrids.workflowsList.moveToProject.moved", "Workflow moved")
2353
+ );
2354
+ setChoice(null);
2355
+ onMoved?.();
2356
+ onClose();
2357
+ };
2358
+ return /* @__PURE__ */ jsx(Dialog, { open: workflow !== null, onOpenChange: (open) => !open && close(), children: /* @__PURE__ */ jsxs(DialogContent, { "data-testid": "move-to-project-dialog", children: [
2359
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
2360
+ /* @__PURE__ */ jsx(DialogTitle, { children: tr(
2361
+ "fluidgrids.workflowsList.moveToProject.title",
2362
+ "Move {{name}} to a project",
2363
+ { name: workflow?.name ?? "" }
2364
+ ) }),
2365
+ /* @__PURE__ */ jsx(DialogDescription, { children: tr(
2366
+ "fluidgrids.workflowsList.moveToProject.description",
2367
+ "Every version moves, and new versions stay in the project."
2368
+ ) })
2369
+ ] }),
2370
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
2371
+ /* @__PURE__ */ jsx(Label, { htmlFor: "move-to-project-select", children: tr("fluidgrids.workflowsList.moveToProject.label", "Project") }),
2372
+ /* @__PURE__ */ jsxs(Select, { value: selected, onValueChange: setChoice, children: [
2373
+ /* @__PURE__ */ jsx(
2374
+ SelectTrigger,
2375
+ {
2376
+ id: "move-to-project-select",
2377
+ "data-testid": "move-to-project-select",
2378
+ children: /* @__PURE__ */ jsx(SelectValue, {})
2379
+ }
2380
+ ),
2381
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
2382
+ /* @__PURE__ */ jsx(SelectItem, { value: NO_PROJECT, children: tr("fluidgrids.workflowsList.bulk.noProject", "No project") }),
2383
+ projects.map((project) => /* @__PURE__ */ jsx(SelectItem, { value: project.id, children: project.name }, project.id))
2384
+ ] })
2385
+ ] })
2386
+ ] }),
2387
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
2388
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: close, disabled: loading, children: tr("fluidgrids.workflowsList.moveToProject.cancel", "Cancel") }),
2389
+ /* @__PURE__ */ jsx(
2390
+ Button,
2391
+ {
2392
+ onClick: () => void move(),
2393
+ disabled: loading || selected === current,
2394
+ "data-testid": "move-to-project-confirm",
2395
+ children: tr("fluidgrids.workflowsList.moveToProject.confirm", "Move")
2396
+ }
2397
+ )
2398
+ ] })
2399
+ ] }) });
2400
+ }
2443
2401
  function useStatusFilters() {
2444
2402
  const tr = useTr();
2445
2403
  return useMemo(
@@ -2464,6 +2422,29 @@ function useStatusFilters() {
2464
2422
  [tr]
2465
2423
  );
2466
2424
  }
2425
+ function useAccessFilters() {
2426
+ const tr = useTr();
2427
+ return useMemo(
2428
+ () => [
2429
+ {
2430
+ value: "ALL" /* All */,
2431
+ label: tr("fluidgrids.workflowsList.access.all", "All")
2432
+ },
2433
+ {
2434
+ value: "OWNED_BY_ME" /* OwnedByMe */,
2435
+ label: tr("fluidgrids.workflowsList.access.mine", "Mine")
2436
+ },
2437
+ {
2438
+ value: "SHARED_WITH_ME" /* SharedWithMe */,
2439
+ label: tr(
2440
+ "fluidgrids.workflowsList.access.sharedWithMe",
2441
+ "Shared with me"
2442
+ )
2443
+ }
2444
+ ],
2445
+ [tr]
2446
+ );
2447
+ }
2467
2448
  function SkeletonCard() {
2468
2449
  return /* @__PURE__ */ jsxs("div", { className: "flex min-h-40 flex-col justify-between rounded-xl border border-border bg-card p-6", children: [
2469
2450
  /* @__PURE__ */ jsxs("div", { className: "space-y-2.5", children: [
@@ -2481,10 +2462,19 @@ function WorkflowsList() {
2481
2462
  const tr = useTr();
2482
2463
  const navigate = useNavigate();
2483
2464
  const STATUS_FILTERS = useStatusFilters();
2465
+ const ACCESS_FILTERS = useAccessFilters();
2466
+ const workspaceId = useContext(FluidGridsContext)?.workspaceId ?? "";
2467
+ const [accessFilter, setAccessFilter] = useState(
2468
+ "ALL" /* All */
2469
+ );
2484
2470
  const { workflows, loading, error, tagsByKey, refetch } = useWorkflowDefinitions({
2485
2471
  limit: 100,
2486
- latestOnly: true
2472
+ latestOnly: true,
2473
+ ...accessFilter === "ALL" /* All */ ? {} : { access: accessFilter }
2487
2474
  });
2475
+ const [sharing, setSharing] = useState(null);
2476
+ const [moving, setMoving] = useState(null);
2477
+ const filteredByAccess = accessFilter !== "ALL" /* All */;
2488
2478
  const { getWorkflow } = useLazyWorkflowDefinition();
2489
2479
  const { allowed: canCreate } = useFluidGridsPermission(
2490
2480
  FLUIDGRIDS_PERMISSIONS.WORKFLOW_CREATE
@@ -2671,7 +2661,7 @@ function WorkflowsList() {
2671
2661
  }
2672
2662
  ),
2673
2663
  !loading && !error && /* @__PURE__ */ jsx(FirstWorkflowChecklist, { workflows, canCreate }),
2674
- !loading && !error && workflows.length > 0 && /* @__PURE__ */ jsxs(
2664
+ !loading && !error && (workflows.length > 0 || filteredByAccess) && /* @__PURE__ */ jsxs(
2675
2665
  "div",
2676
2666
  {
2677
2667
  className: "flex flex-wrap items-center gap-3",
@@ -2709,6 +2699,29 @@ function WorkflowsList() {
2709
2699
  onSelectProject: setProjectFilter
2710
2700
  }
2711
2701
  ),
2702
+ /* @__PURE__ */ jsx(
2703
+ "div",
2704
+ {
2705
+ className: "flex flex-wrap items-center gap-1.5",
2706
+ role: "group",
2707
+ "aria-label": tr("fluidgrids.workflowsList.access.label", "Access"),
2708
+ "data-testid": "workflow-access-filter",
2709
+ children: ACCESS_FILTERS.map((option) => /* @__PURE__ */ jsx(
2710
+ "button",
2711
+ {
2712
+ type: "button",
2713
+ "aria-pressed": accessFilter === option.value,
2714
+ onClick: () => setAccessFilter(option.value),
2715
+ className: cn(
2716
+ "rounded-full border px-3 py-1 text-xs font-medium transition-colors",
2717
+ accessFilter === option.value ? "border-transparent bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:text-foreground"
2718
+ ),
2719
+ children: option.label
2720
+ },
2721
+ option.value
2722
+ ))
2723
+ }
2724
+ ),
2712
2725
  /* @__PURE__ */ jsxs(
2713
2726
  Button,
2714
2727
  {
@@ -2805,7 +2818,7 @@ function WorkflowsList() {
2805
2818
  /* @__PURE__ */ jsx(Icon, { icon: "mynaui:refresh", className: "size-4" }),
2806
2819
  tr("fluidgrids.workflowsList.tryAgainButton", "Try again")
2807
2820
  ] })
2808
- ] }) }) : workflows.length === 0 ? /* @__PURE__ */ jsx("div", { className: "grid flex-1 place-items-center", children: /* @__PURE__ */ jsx(
2821
+ ] }) }) : workflows.length === 0 && !filteredByAccess ? /* @__PURE__ */ jsx("div", { className: "grid flex-1 place-items-center", children: /* @__PURE__ */ jsx(
2809
2822
  IllustratedEmptyState,
2810
2823
  {
2811
2824
  illustration: "onboarding",
@@ -2840,6 +2853,7 @@ function WorkflowsList() {
2840
2853
  setSearch("");
2841
2854
  setStatusFilter(null);
2842
2855
  setTagFilter(null);
2856
+ setAccessFilter("ALL" /* All */);
2843
2857
  },
2844
2858
  children: tr(
2845
2859
  "fluidgrids.workflowsList.clearFiltersButton",
@@ -2881,9 +2895,20 @@ function WorkflowsList() {
2881
2895
  "Tag"
2882
2896
  ),
2883
2897
  color: a.tagInfo?.color ?? void 0
2884
- }))
2898
+ })),
2899
+ visibility: workflow.visibility ?? void 0,
2900
+ my_access: workflow.myAccess ?? null
2885
2901
  },
2886
2902
  onUpdateSuccess: () => refetch(),
2903
+ onShare: () => setSharing({
2904
+ workflowKey: workflow.workflowKey,
2905
+ name: workflow.name
2906
+ }),
2907
+ onMoveToProject: () => setMoving({
2908
+ id: workflow.id,
2909
+ name: workflow.name,
2910
+ projectId: workflow.projectId ?? null
2911
+ }),
2887
2912
  onExport: () => void handleExport(workflow.id),
2888
2913
  onExportAs: codeFirst ? (format) => void handleExportAs(
2889
2914
  workflow.workflowKey,
@@ -2897,6 +2922,25 @@ function WorkflowsList() {
2897
2922
  ]
2898
2923
  }
2899
2924
  ),
2925
+ /* @__PURE__ */ jsx(
2926
+ WorkflowShareDialog,
2927
+ {
2928
+ open: sharing !== null,
2929
+ onClose: () => setSharing(null),
2930
+ workflowKey: sharing?.workflowKey ?? null,
2931
+ workflowName: sharing?.name ?? "",
2932
+ workspaceId,
2933
+ onShared: () => void refetch()
2934
+ }
2935
+ ),
2936
+ /* @__PURE__ */ jsx(
2937
+ WorkflowMoveToProjectDialog,
2938
+ {
2939
+ workflow: moving,
2940
+ onClose: () => setMoving(null),
2941
+ onMoved: () => void refetch()
2942
+ }
2943
+ ),
2900
2944
  /* @__PURE__ */ jsx(
2901
2945
  CreateWorkflowRefusalDialog,
2902
2946
  {
@@ -1,10 +1,10 @@
1
- import { validateDateRange, statusCountFilter, STATUS_COUNT_GROUP_BY, statusCountsOf } from './chunk-L2MUO3VU.js';
2
- import { useAvailableTags, formatRunVersion, nodeDisplayTitle } from './chunk-7GI3457S.js';
1
+ import { validateDateRange, statusCountFilter, STATUS_COUNT_GROUP_BY, statusCountsOf } from './chunk-5D4XS3WJ.js';
2
+ import { useAvailableTags, formatRunVersion, nodeDisplayTitle } from './chunk-F7LQL43U.js';
3
3
  import { executionsControls } from './chunk-FNZZ5JJL.js';
4
4
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
5
- import { useDurableParityEnabled, throwIfResultError, describeOperationError } from './chunk-WWR7ZCS5.js';
5
+ import { useDurableParityEnabled, throwIfResultError, describeOperationError } from './chunk-AAIZ6S6E.js';
6
6
  import { useExecutionsStore } from './chunk-6AMNEX2Y.js';
7
- import { SetWorkflowRunVersioningOverrideDocument, WorkflowRunsCountDocument, DurableParityRunFieldsDocument, WorkflowRunPendingDocument, WorkflowRunMetadataDocument } from './chunk-H3RSOHD5.js';
7
+ import { SetWorkflowRunVersioningOverrideDocument, WorkflowRunsCountDocument, DurableParityRunFieldsDocument, WorkflowRunPendingDocument, WorkflowRunMetadataDocument } from './chunk-AVHBWJRY.js';
8
8
  import { useTr } from './chunk-UULVIT25.js';
9
9
  import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
10
10
  import { Icon } from '@iconify/react';
@@ -1,4 +1,4 @@
1
- import { useFlowStore } from './chunk-WWR7ZCS5.js';
1
+ import { useFlowStore } from './chunk-AAIZ6S6E.js';
2
2
  import { useTr } from './chunk-UULVIT25.js';
3
3
  import { useState, useRef, useCallback, useEffect } from 'react';
4
4
  import { cn } from '@burdenoff/fe-libs/utils';
@@ -1,4 +1,4 @@
1
- import { NodeEndpointConfigsDocument, NodeEndpointConfigDocument, NodeManifestDocument, fetchAllNodeEndpointConfigs } from './chunk-H3RSOHD5.js';
1
+ import { NodeEndpointConfigsDocument, NodeEndpointConfigDocument, NodeManifestDocument, fetchAllNodeEndpointConfigs } from './chunk-AVHBWJRY.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';