@burdenoff/fluidgrids-fe-sdk 2026.1114.6 → 2026.1114.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.
Files changed (49) hide show
  1. package/dist/{AiStudioPage-C2SBRqab.js → AiStudioPage-DLl4ld32.js} +2 -2
  2. package/dist/{ExecutionDetailPage-B-8s_Sqw.js → ExecutionDetailPage-DxeySgR3.js} +3 -3
  3. package/dist/{ExecutionsListPage-Ky3TAL9U.js → ExecutionsListPage-CMrOaFKQ.js} +2 -2
  4. package/dist/FileDownloadUrlDocument-CVOYKcL5.js +92 -0
  5. package/dist/NodeUsageStatusDocument-B-XguSjm.js +531 -0
  6. package/dist/{OpenTemplateAsCodeButton-pepQUqje.js → OpenTemplateAsCodeButton-Cjnagq9H.js} +2 -2
  7. package/dist/{PaidTemplateConfirm-BJCcJh5t.js → PaidTemplateConfirm-IWOHVR6s.js} +1 -1
  8. package/dist/{SettingsPage-BSucNHrq.js → SettingsPage-DwA2ZjyH.js} +4 -4
  9. package/dist/{TaskQueuesPage-WMJz9imi.js → TaskQueuesPage-BuWQwT5I.js} +2 -2
  10. package/dist/{TemplateCard-Cx_eZr9q.js → TemplateCard-9Beuqm5_.js} +19 -3
  11. package/dist/{TemplateConfigurationModal-D2i7ZXOM.js → TemplateConfigurationModal-B_ME8M-1.js} +1 -1
  12. package/dist/{TemplatePreview-DwdGa8bH.js → TemplatePreview-Bi6LSeH8.js} +5 -5
  13. package/dist/{TemplatesPage-DF5PK7CB.js → TemplatesPage-D9fOKAn4.js} +355 -13
  14. package/dist/{WorkflowBuilder-CjsO7i-D.js → WorkflowBuilder-Bzx-e5lX.js} +2 -2
  15. package/dist/{WorkflowBuilder-DkzzbrNn.js → WorkflowBuilder-CdcGE0Mf.js} +3 -3
  16. package/dist/{WorkflowsList-4VADoiz_.js → WorkflowsList-CBqxxI44.js} +3 -4
  17. package/dist/{api-DKfMt0IX.js → api-CEzqoN5H.js} +1 -1
  18. package/dist/{api-CEnNq15C.js → api-o5UUDbr8.js} +1 -1
  19. package/dist/executions.js +2 -2
  20. package/dist/{flow-builder-CIV6u8y-.js → flow-builder-CbF9P7cI.js} +9 -24
  21. package/dist/{index-BY0V255h.d.ts → index-D10JzNP1.d.ts} +4 -2
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.js +30 -27
  24. package/dist/{node-detail-view-DkajTGfb.js → node-detail-view-CP6sq02c.js} +7 -217
  25. package/dist/{node-editor-tab-body-ChLrBfKp.js → node-editor-tab-body-B6kxLf6Q.js} +1 -1
  26. package/dist/observability.d.ts +1 -1
  27. package/dist/{popover-CCJlf41J.js → popover-9gY3-2dY.js} +2 -2
  28. package/dist/{quick-config-panel-Bq_uF9XF.js → quick-config-panel-TGCW64qe.js} +2 -2
  29. package/dist/{schedule-panel-7TtPt1t_.js → schedule-panel-zrFYGtkx.js} +4 -4
  30. package/dist/settings.js +1 -1
  31. package/dist/{shared-C0LCTtyh.js → shared-mbyvDPde.js} +2 -24
  32. package/dist/{sidebar-node-editor-n-7ux5IN.js → sidebar-node-editor-BPg2NKzJ.js} +2 -2
  33. package/dist/{template-code-B3cMigJS.js → template-code-B7x-XMAm.js} +9 -2
  34. package/dist/templates.js +2 -2
  35. package/dist/typed-calls-BqokR321.js +26 -0
  36. package/dist/{WorkflowEditLeaseStatusDocument-Dp62med3.js → use-workflow-code-editor-CBOkjntt.js} +216 -90
  37. package/dist/{useAgentDefinitions-Daa3fGVg.js → useAgentDefinitions-9pmnEpb8.js} +1 -1
  38. package/dist/useConnections-CmnwGk09.js +439 -0
  39. package/dist/{useWorkflowCodeExport-lRmbjY49.js → useWorkflowCodeExport-ChAzmhi6.js} +78 -114
  40. package/dist/workflow-builder.js +2 -2
  41. package/dist/workflow-description-ReGwCZXS.js +123 -0
  42. package/dist/workflow-pages.d.ts +1 -1
  43. package/dist/workflow-pages.js +9 -9
  44. package/dist/{workflow-code-transfer-BsLPUrKP.js → workflow-transfer-CktP7o1c.js} +103 -1
  45. package/dist/workflows-list.js +1 -1
  46. package/package.json +1 -1
  47. package/dist/QuotaExhaustedDialog-YjKgRTmu.js +0 -55
  48. package/dist/useConnections-BlB0gbOB.js +0 -931
  49. package/dist/workflow-transfer-CQnQC-ke.js +0 -104
@@ -0,0 +1,123 @@
1
+ "use client";
2
+ import { o as throwIfResultError } from "./errors-xPZ-IbQd.js";
3
+ import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
4
+ import { o as UpdateWorkflowDefinitionDocument } from "./WorkflowVersionsDocument-DRVOp8Uj.js";
5
+ import { i as QuotaExhaustedDialog } from "./useWorkflowCodeExport-ChAzmhi6.js";
6
+ import { jsx } from "react/jsx-runtime";
7
+
8
+ // src/components/shared/CreateWorkflowRefusalDialog.tsx
9
+ /**
10
+ * Says why "Create Workflow" created nothing, on the page it was pressed on.
11
+ * The builder shows it too when saving a new workflow is refused by a plan
12
+ * quota (BOFF-9998), since that save is the create.
13
+ *
14
+ * - `quota-exhausted`: the plan's workflow slots are used up (G43 copy).
15
+ * - `quota-not-provisioned`: the workspace has no plan that includes FluidGrids
16
+ * workflows. Nothing is used up; choosing a plan for the workspace is the way
17
+ * past it, so the dialog still offers View plans (round-3 verification: the
18
+ * refusal toast vanished and nothing pointed at billing).
19
+ * - `failed`: no dialog. The shell's backend-error toast already shows the
20
+ * server's message, and nothing navigated.
21
+ */
22
+ function CreateWorkflowRefusalDialog({ refusal, onClose, onUpgrade, surface }) {
23
+ const tr = useTr();
24
+ const notProvisioned = refusal?.kind === "quota-not-provisioned";
25
+ const open = refusal?.kind === "quota-exhausted" || refusal?.kind === "quota-not-provisioned";
26
+ return /* @__PURE__ */ jsx(QuotaExhaustedDialog, {
27
+ surface,
28
+ open,
29
+ limitHit: !notProvisioned,
30
+ onOpenChange: (next) => {
31
+ if (!next) onClose();
32
+ },
33
+ onUpgrade: () => {
34
+ onUpgrade();
35
+ onClose();
36
+ },
37
+ ...notProvisioned ? {
38
+ title: tr("fluidgrids.components.createRefusal.notProvisionedTitle", "Workflows aren't in this workspace's plan"),
39
+ description: tr("fluidgrids.components.createRefusal.notProvisionedDescription", "This workspace has no plan that includes FluidGrids workflows, so no workflow was created. Choose a plan for this workspace, or ask a workspace admin to add one.")
40
+ } : {}
41
+ });
42
+ }
43
+
44
+ // src/utils/workflow-description.ts
45
+ /** The longest description the editors accept. */
46
+ const WORKFLOW_DESCRIPTION_MAX_LENGTH = 500;
47
+ /**
48
+ * Descriptions older builder saves wrote in place of a real one: every save
49
+ * copied the workflow's name into its description, with these fallbacks for an
50
+ * unnamed workflow. A description that only repeats the name says nothing.
51
+ */
52
+ const LEGACY_PLACEHOLDERS = /* @__PURE__ */ new Set([
53
+ "Untitled Workflow",
54
+ "Workflow update",
55
+ "Workflow Description"
56
+ ]);
57
+ /** The description as it is stored: surrounding whitespace removed. */
58
+ function normalizeWorkflowDescription(text) {
59
+ return text.trim();
60
+ }
61
+ /**
62
+ * The description worth showing for a workflow: empty when there is none, or
63
+ * when it is a placeholder an older builder save wrote (the name again, or one
64
+ * of the unnamed-workflow fallbacks).
65
+ */
66
+ function visibleWorkflowDescription(description, name) {
67
+ const text = normalizeWorkflowDescription(description ?? "");
68
+ if (!text) return "";
69
+ if (text === (name ?? "").trim()) return "";
70
+ if (LEGACY_PLACEHOLDERS.has(text)) return "";
71
+ return text;
72
+ }
73
+ /** Decide what to do with `draft`, given the description shown before editing. */
74
+ function commitWorkflowDescription(shown, draft) {
75
+ const description = normalizeWorkflowDescription(draft);
76
+ if (description.length > 500) return {
77
+ kind: "too-long",
78
+ length: description.length
79
+ };
80
+ if (description === normalizeWorkflowDescription(shown)) return { kind: "unchanged" };
81
+ return {
82
+ kind: "save",
83
+ description
84
+ };
85
+ }
86
+ /** The characters left for a draft; negative once it is too long. */
87
+ function workflowDescriptionCharactersLeft(draft) {
88
+ return 500 - normalizeWorkflowDescription(draft).length;
89
+ }
90
+ /**
91
+ * The `updateWorkflowDefinition` input that changes only the description. An
92
+ * empty description is sent as "" (not null), which is what clears it.
93
+ */
94
+ function workflowDescriptionUpdateInput(description, guard = {}) {
95
+ return {
96
+ description: normalizeWorkflowDescription(description),
97
+ ...guard.expectedRevision !== void 0 ? { expectedRevision: guard.expectedRevision } : {},
98
+ ...guard.editSessionId ? { editSessionId: guard.editSessionId } : {}
99
+ };
100
+ }
101
+ /**
102
+ * Save `description` on the version `id`, in place. Throws the service's
103
+ * refusal (permission, a conflict, a viewer of a shared workflow) so the
104
+ * caller can roll its optimistic copy back and say why.
105
+ */
106
+ async function saveWorkflowDescription(client, id, description, guard = {}) {
107
+ const { data } = throwIfResultError(await client.mutate({
108
+ mutation: UpdateWorkflowDefinitionDocument,
109
+ variables: {
110
+ id,
111
+ input: workflowDescriptionUpdateInput(description, guard)
112
+ }
113
+ }));
114
+ const saved = data?.updateWorkflowDefinition;
115
+ if (!saved) throw new Error("The description was not saved");
116
+ return {
117
+ id: saved.id,
118
+ description: saved.description ?? "",
119
+ revision: saved.revision
120
+ };
121
+ }
122
+
123
+ export { workflowDescriptionCharactersLeft as a, visibleWorkflowDescription as i, normalizeWorkflowDescription as n, CreateWorkflowRefusalDialog as o, saveWorkflowDescription as r, commitWorkflowDescription as t };
@@ -1,8 +1,8 @@
1
1
 
2
2
  import { n as WorkflowsList_d_exports } from "./WorkflowsList-CcNDQge5.js";
3
+ import { Da as VariablesPage_d_exports, Pi as ApprovalInboxPage_d_exports, QRa as InsightsPage_d_exports, Wi as TaskQueuesPage_d_exports, ZRa as InsightsPageProps, bza as AiStudioPage_d_exports, di as DataTablesPage_d_exports, eza as DataSinkDashboardPage_d_exports, ra as RunnersPage_d_exports } from "./index-D10JzNP1.js";
3
4
  import { a as WorkflowSearchRedirect_d_exports, o as WorkflowBuilder } from "./index-RWAuYE2j.js";
4
5
  import { i as TemplatePreview_d_exports, n as TemplatesPage_d_exports } from "./TemplatesPage-BG3H-6v6.js";
5
- import { Da as VariablesPage_d_exports, Pi as ApprovalInboxPage_d_exports, QRa as InsightsPage_d_exports, Wi as TaskQueuesPage_d_exports, ZRa as InsightsPageProps, bza as AiStudioPage_d_exports, di as DataTablesPage_d_exports, eza as DataSinkDashboardPage_d_exports, ra as RunnersPage_d_exports } from "./index-BY0V255h.js";
6
6
  import { i as ExecutionsListPage_d_exports, n as ExecutionDetailPage_d_exports } from "./ExecutionDetailPage-DvQ667OE.js";
7
7
  import { n as HistoryPage_d_exports } from "./HistoryPage-BLoRpJ1R.js";
8
8
  import { n as NodesPage_d_exports } from "./NodesPage-DEbnz9iU.js";
@@ -54,23 +54,23 @@ function createWorkflowPages(importers) {
54
54
  * loader, so it costs a host's first load about a kilobyte.
55
55
  */
56
56
  const pages = createWorkflowPages({
57
- WorkflowsList: () => import("./WorkflowsList-4VADoiz_.js").then((n) => n.n),
58
- WorkflowBuilderPage: () => import("./WorkflowBuilder-DkzzbrNn.js").then((n) => n.n).then((m) => ({ WorkflowBuilderPage: m.WorkflowBuilder })),
57
+ WorkflowsList: () => import("./WorkflowsList-CBqxxI44.js").then((n) => n.n),
58
+ WorkflowBuilderPage: () => import("./WorkflowBuilder-CdcGE0Mf.js").then((n) => n.n).then((m) => ({ WorkflowBuilderPage: m.WorkflowBuilder })),
59
59
  WorkflowSearchRedirect: () => import("./WorkflowSearchRedirect-0MLrCjDn.js").then((n) => n.n),
60
- TemplatePreview: () => import("./TemplatePreview-DwdGa8bH.js").then((n) => n.n),
61
- AiStudioPage: () => import("./AiStudioPage-C2SBRqab.js").then((n) => n.n),
62
- ExecutionsListPage: () => import("./ExecutionsListPage-Ky3TAL9U.js").then((n) => n.n),
63
- ExecutionDetailPage: () => import("./ExecutionDetailPage-B-8s_Sqw.js").then((n) => n.n),
60
+ TemplatePreview: () => import("./TemplatePreview-Bi6LSeH8.js").then((n) => n.n),
61
+ AiStudioPage: () => import("./AiStudioPage-DLl4ld32.js").then((n) => n.n),
62
+ ExecutionsListPage: () => import("./ExecutionsListPage-CMrOaFKQ.js").then((n) => n.n),
63
+ ExecutionDetailPage: () => import("./ExecutionDetailPage-DxeySgR3.js").then((n) => n.n),
64
64
  HistoryPage: () => import("./HistoryPage-D4rkw4zu.js").then((n) => n.n),
65
- TemplatesPage: () => import("./TemplatesPage-DF5PK7CB.js").then((n) => n.n),
65
+ TemplatesPage: () => import("./TemplatesPage-D9fOKAn4.js").then((n) => n.n),
66
66
  NodesPage: () => import("./NodesPage-C3sh0aL9.js").then((n) => n.n),
67
- SettingsPage: () => import("./SettingsPage-BSucNHrq.js").then((n) => n.n),
67
+ SettingsPage: () => import("./SettingsPage-DwA2ZjyH.js").then((n) => n.n),
68
68
  InsightsPage: () => import("./InsightsPage-CVzNu4F7.js").then((n) => n.r),
69
69
  ErrorAnalyticsPage: () => import("./InsightsPage-CVzNu4F7.js").then((n) => n.r),
70
70
  DataSinkDashboardPage: () => import("./DataSinkDashboardPage-Dnp1yRYQ.js").then((n) => n.n),
71
71
  VariablesPage: () => import("./VariablesPage-Bx3LNar7.js").then((n) => n.n),
72
72
  RunnersPage: () => import("./RunnersPage-D2teM_sE.js").then((n) => n.n),
73
- TaskQueuesPage: () => import("./TaskQueuesPage-WMJz9imi.js").then((n) => n.r),
73
+ TaskQueuesPage: () => import("./TaskQueuesPage-BuWQwT5I.js").then((n) => n.r),
74
74
  ApprovalInboxPage: () => import("./ApprovalInboxPage-CM2nA4eE.js").then((n) => n.n),
75
75
  DataTablesPage: () => import("./DataTablesPage-C7I_PCvD.js").then((n) => n.n)
76
76
  });
@@ -320,4 +320,106 @@ function lineOfNode(source, nodeId) {
320
320
  return null;
321
321
  }
322
322
 
323
- export { sortFidelityItems as _, assertImportByteSize as a, utf8Length as b, fileBaseName as c, isLosslessReport as d, isLossyFidelityItem as f, readProjectArchive as g, primaryImportModule as h, MAX_IMPORT_SOURCE_BYTES as i, importAcceptAttribute as l, orderedExportFiles as m, ImportSourceError as n, buildExportDownload as o, lineOfNode as p, MAX_IMPORT_ARCHIVE_BYTES as r, checkTypeScriptImport as s, CODE_EXPORT_FORMATS as t, importFileKind as u, typeScriptImportSource as v, workflowNameFromFile as x, typeScriptModuleFile as y };
323
+ // src/utils/workflow-transfer.ts
324
+ function asRecord(value) {
325
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
326
+ }
327
+ function collectWorkflowNodeReferences(definition) {
328
+ const nodes = asRecord(asRecord(definition)?.data)?.nodes;
329
+ if (!Array.isArray(nodes)) return [];
330
+ const seen = /* @__PURE__ */ new Set();
331
+ const references = [];
332
+ for (const candidate of nodes) {
333
+ const node = asRecord(candidate);
334
+ const nodeData = asRecord(node?.data);
335
+ const nodeId = typeof node?.id === "string" ? node.id : null;
336
+ const nodeType = typeof nodeData?.nodeId === "string" ? nodeData.nodeId : node?.type;
337
+ if (!nodeId || typeof nodeType !== "string") continue;
338
+ const nodeVersion = typeof nodeData?.nodeVersion === "string" ? nodeData.nodeVersion : null;
339
+ const key = `${nodeId}:${nodeType}:${nodeVersion ?? ""}`;
340
+ if (seen.has(key)) continue;
341
+ seen.add(key);
342
+ references.push({
343
+ nodeId,
344
+ nodeType,
345
+ nodeVersion
346
+ });
347
+ }
348
+ return references;
349
+ }
350
+ function createWorkflowExportPayload(workflow) {
351
+ const definitionJson = asRecord(workflow.definitionJson);
352
+ if (!definitionJson) throw new Error("Workflow definition JSON must be an object");
353
+ return {
354
+ format: "fluidgrids.workflow",
355
+ schemaVersion: 1,
356
+ exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
357
+ workflowKey: workflow.workflowKey,
358
+ version: workflow.version,
359
+ name: workflow.name,
360
+ description: workflow.description ?? null,
361
+ definitionJson,
362
+ context: asRecord(workflow.context),
363
+ tags: workflow.tags,
364
+ tagsV2: workflow.tagsV2,
365
+ icon: workflow.icon ?? null,
366
+ category: workflow.category ?? null,
367
+ nodeReferences: collectWorkflowNodeReferences(definitionJson)
368
+ };
369
+ }
370
+ /** Saves a blob through a temporary object URL and anchor click. */
371
+ function downloadBlob(filename, blob) {
372
+ const url = URL.createObjectURL(blob);
373
+ const anchor = document.createElement("a");
374
+ anchor.href = url;
375
+ anchor.download = filename;
376
+ anchor.click();
377
+ URL.revokeObjectURL(url);
378
+ }
379
+ function downloadWorkflowExport(workflow) {
380
+ const payload = createWorkflowExportPayload(workflow);
381
+ const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json" });
382
+ downloadBlob(`${workflow.workflowKey}-${workflow.version}.fluidgrids.json`, blob);
383
+ }
384
+ function isN8nNodeType(type) {
385
+ return typeof type === "string" && (type.startsWith("n8n-nodes-") || type.startsWith("@n8n/"));
386
+ }
387
+ /**
388
+ * Whether a JSON document is an n8n workflow export (as exported, or copied
389
+ * from the n8n canvas): a `nodes` list of named n8n nodes and a
390
+ * `connections` object. The service applies the same test (BOFF-9730).
391
+ */
392
+ function isN8nWorkflowJson(value) {
393
+ const root = asRecord(value);
394
+ if (!root || !Array.isArray(root.nodes) || root.nodes.length === 0) return false;
395
+ if (root.connections !== void 0 && !asRecord(root.connections)) return false;
396
+ const nodes = root.nodes.map(asRecord);
397
+ return nodes.every((node) => node !== null && typeof node.name === "string" && typeof node.type === "string" && node.type.length > 0) && nodes.some((node) => isN8nNodeType(node?.type));
398
+ }
399
+ function parseWorkflowImport(raw) {
400
+ const root = asRecord(JSON.parse(raw));
401
+ if (!root) throw new Error("Import must contain a JSON object");
402
+ if (isN8nWorkflowJson(root)) return {
403
+ source: "n8n",
404
+ definitionJson: root,
405
+ name: typeof root.name === "string" && root.name.trim() ? root.name.trim() : "Imported n8n workflow",
406
+ nodeReferences: []
407
+ };
408
+ const definitionJson = asRecord(root.definitionJson) ?? root;
409
+ return {
410
+ source: "fluidgrids",
411
+ definitionJson,
412
+ name: typeof root.name === "string" && root.name.trim() ? root.name : "Imported workflow",
413
+ workflowKey: typeof root.workflowKey === "string" ? root.workflowKey : void 0,
414
+ version: typeof root.version === "string" ? root.version : void 0,
415
+ description: typeof root.description === "string" ? root.description : void 0,
416
+ context: asRecord(root.context) ?? void 0,
417
+ tags: Array.isArray(root.tags) && root.tags.every((tag) => typeof tag === "string") ? root.tags : void 0,
418
+ tagsV2: root.tagsV2,
419
+ icon: typeof root.icon === "string" ? root.icon : void 0,
420
+ category: typeof root.category === "string" ? root.category : void 0,
421
+ nodeReferences: Array.isArray(root.nodeReferences) ? root.nodeReferences : collectWorkflowNodeReferences(definitionJson)
422
+ };
423
+ }
424
+
425
+ export { utf8Length as C, typeScriptModuleFile as S, orderedExportFiles as _, ImportSourceError as a, sortFidelityItems as b, assertImportByteSize as c, fileBaseName as d, importAcceptAttribute as f, lineOfNode as g, isLossyFidelityItem as h, CODE_EXPORT_FORMATS as i, buildExportDownload as l, isLosslessReport as m, downloadWorkflowExport as n, MAX_IMPORT_ARCHIVE_BYTES as o, importFileKind as p, parseWorkflowImport as r, MAX_IMPORT_SOURCE_BYTES as s, downloadBlob as t, checkTypeScriptImport as u, primaryImportModule as v, workflowNameFromFile as w, typeScriptImportSource as x, readProjectArchive as y };
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as WorkflowsList } from "./WorkflowsList-4VADoiz_.js";
2
+ import { t as WorkflowsList } from "./WorkflowsList-CBqxxI44.js";
3
3
  import { n as ACTION_PARAM_VALUES, t as ACTION_PARAM } from "./useActionParam-B0ebTZmg.js";
4
4
 
5
5
  export { ACTION_PARAM, ACTION_PARAM_VALUES, WorkflowsList };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fluidgrids-fe-sdk",
3
- "version": "2026.1114.6",
3
+ "version": "2026.1114.7",
4
4
  "description": "FluidGrids Workflow Builder SDK - Embeddable visual workflow automation",
5
5
  "type": "module",
6
6
  "imports": {
@@ -1,55 +0,0 @@
1
- "use client";
2
- import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
3
- import { un as useFluidGridsAnalytics } from "./FluidGridsProvider-C-WGQwuT.js";
4
- import { c as emitWorkflowLimitHit, o as emitUpgradeClicked } from "./fluidgridsEvents-Dm5CaHtr.js";
5
- import { i as WORKFLOWS_QUOTA_NAME } from "./quota-Cdt8yz7N.js";
6
- import { useEffect, useRef } from "react";
7
- import { jsx, jsxs } from "react/jsx-runtime";
8
- import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@burdenoff/fe-libs/ui";
9
-
10
- // src/components/shared/QuotaExhaustedDialog.tsx
11
- /**
12
- * Alert shown when a workflow-creating action (save/duplicate/import) is
13
- * rejected with `QUOTA_EXHAUSTED` for `fluidgrids.workflows.count`. Mirrors
14
- * the "Folder Limit Reached" dialog in microfe-files' BrowserPage.tsx, built
15
- * on the same `AlertDialog` primitives already used elsewhere in this SDK
16
- * (see card-workflow.tsx's delete-confirmation dialog).
17
- */
18
- function QuotaExhaustedDialog({ open, onOpenChange, onUpgrade, title, description, surface, limitHit = true }) {
19
- const tr = useTr();
20
- const { bus, workspaceId } = useFluidGridsAnalytics();
21
- const wasOpen = useRef(false);
22
- useEffect(() => {
23
- if (open && !wasOpen.current && limitHit) emitWorkflowLimitHit(bus, {
24
- workspaceId,
25
- surface
26
- });
27
- wasOpen.current = open;
28
- }, [
29
- open,
30
- bus,
31
- workspaceId,
32
- surface,
33
- limitHit
34
- ]);
35
- const handleUpgrade = () => {
36
- emitUpgradeClicked(bus, {
37
- workspaceId,
38
- surface: "quota-dialog",
39
- quotaKey: WORKFLOWS_QUOTA_NAME
40
- });
41
- onUpgrade();
42
- };
43
- const resolvedTitle = title ?? tr("fluidgrids.components.quotaExhaustedDialog.title", "Workflow Limit Reached");
44
- const resolvedDescription = description ?? tr("fluidgrids.components.quotaExhaustedDialog.description", "You've reached the workflow limit for your plan. Upgrade your plan to create more workflows.");
45
- return /* @__PURE__ */ jsx(AlertDialog, {
46
- open,
47
- onOpenChange,
48
- children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [/* @__PURE__ */ jsxs(AlertDialogHeader, { children: [/* @__PURE__ */ jsx(AlertDialogTitle, { children: resolvedTitle }), /* @__PURE__ */ jsx(AlertDialogDescription, { children: resolvedDescription })] }), /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [/* @__PURE__ */ jsx(AlertDialogCancel, { children: tr("fluidgrids.components.quotaExhaustedDialog.dismiss", "Dismiss") }), /* @__PURE__ */ jsx(AlertDialogAction, {
49
- onClick: handleUpgrade,
50
- children: tr("fluidgrids.components.quotaExhaustedDialog.viewPlans", "View plans")
51
- })] })] })
52
- });
53
- }
54
-
55
- export { QuotaExhaustedDialog as t };