@burdenoff/fluidgrids-fe-sdk 2026.1111.16 → 2026.1111.17

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 (112) hide show
  1. package/README.md +41 -0
  2. package/dist/AiStudioPage-kJHSsIcj.js +774 -0
  3. package/dist/ApprovalInboxPage-dbBDSJ-f.js +558 -0
  4. package/dist/DataSinkDashboardPage-1h2QsMzH.js +270 -0
  5. package/dist/DataTablesPage-BZy2z0LB.js +1690 -0
  6. package/dist/EntityTagPicker-BqRNsLCQ.js +135 -0
  7. package/dist/{ExecutionDetailPage-D-0_POAf.js → ExecutionDetailPage-BdcZmLT4.js} +799 -4420
  8. package/dist/ExecutionDetailPage-DvQ667OE.d.ts +10 -0
  9. package/dist/ExecutionsListPage-BCUJoAIE.js +2742 -0
  10. package/dist/{FailureTriagePanel-BHiduL7A.js → FailureTriagePanel-B9hDQymi.js} +4 -97
  11. package/dist/{FluidGridsProvider-DmvFADFa.js → FluidGridsProvider-dvZSNtSW.js} +10 -350
  12. package/dist/HistoryPage-BLoRpJ1R.d.ts +6 -0
  13. package/dist/{HistoryPage-BbUgxx1I.js → HistoryPage-U0tqupBN.js} +6 -4
  14. package/dist/HumanRequestCard-D-ooVPDn.js +439 -0
  15. package/dist/{InsightsPage-s6f5bU-8.js → InsightsPage-CALo16eB.js} +17 -328
  16. package/dist/ManagedAiPolicyAuthority-BxwJ3ptd.js +40 -0
  17. package/dist/{ManagedAiPolicyAuthority-CGux_DaV.d.ts → ManagedAiPolicyAuthority-DM3t3wNr.d.ts} +1 -5
  18. package/dist/ManagedAiPolicyAuthorityContext-CNkxIOZ1.js +10 -0
  19. package/dist/{MissingNodesInstallModal-B-9gHy2K.js → MissingNodesInstallModal-CMybsI8h.js} +3 -2
  20. package/dist/{NodesPage-ClvhUfbh.js → NodesPage-Bf5PhfBK.js} +7 -3
  21. package/dist/NodesPage-DEbnz9iU.d.ts +6 -0
  22. package/dist/{PublishCustomNodeAction-D2F7oN0S.js → PublishCustomNodeAction-5XXnSA3H.js} +3 -45
  23. package/dist/QuotaExhaustedDialog-7IFSaLyi.js +54 -0
  24. package/dist/RunnerStatusPill-Ctg4TJcP.js +187 -0
  25. package/dist/RunnersPage-CLCOCclc.js +467 -0
  26. package/dist/{ManagedAiPolicyAuthority-DsSaz-vg.js → SettingsPage-CgkRlCM5.js} +19 -50
  27. package/dist/SettingsPage-DMHQFj5-.d.ts +9 -0
  28. package/dist/TagFilterSelect-DCBOH6Ou.js +41 -0
  29. package/dist/TaskQueuesPage-9VgSnLdL.js +951 -0
  30. package/dist/TemplateCard-DsC0KNH1.js +1416 -0
  31. package/dist/{TemplateConfigurationModal-D_Mvgxqa.js → TemplateConfigurationModal-BhGWIzpm.js} +3 -2
  32. package/dist/{TemplateDetailPanel-DfFfUcOe.js → TemplateDetailPanel-D4cUVr-m.js} +3 -3
  33. package/dist/TemplatePreview-GthzCOSo.js +231 -0
  34. package/dist/TemplatesPage-BG3H-6v6.d.ts +10 -0
  35. package/dist/{TemplatesPage-Cku13bav.js → TemplatesPage-CsDNT54N.js} +11 -228
  36. package/dist/VariablesPage-67WR_lVE.js +949 -0
  37. package/dist/{VersionDiffDialog-Dq2xlPFI.js → VersionDiffDialog-DSN0mU0f.js} +2 -1
  38. package/dist/WorkflowBuilder-DEi_9YOb.js +555 -0
  39. package/dist/{WorkflowSearchRedirect-CaoOOpEl.js → WorkflowBuilder-iPqXgbYr.js} +19 -585
  40. package/dist/{WorkflowProposalCard-8Vr56kQa.js → WorkflowProposalCard-qrEeNyYG.js} +4 -405
  41. package/dist/WorkflowSearchRedirect-DwDNZ_q5.js +36 -0
  42. package/dist/{WorkflowShareDialog-6RRDe-_v.js → WorkflowShareDialog-B_gn968c.js} +6 -52
  43. package/dist/{WorkflowsList-B2j1Pehb.js → WorkflowsList-CA20dVIl.js} +11 -6
  44. package/dist/WorkflowsList-CcNDQge5.d.ts +6 -0
  45. package/dist/agent-form-Bfvm32j1.js +83 -0
  46. package/dist/{agentTools-DJ5o2ekg.js → agentTools-CkRJB7r5.js} +3 -2
  47. package/dist/{ai-usage-D5p7ZeRR.js → ai-usage-glCwHyQz.js} +1 -1
  48. package/dist/api-BrCHB5oA.js +224 -0
  49. package/dist/api-C8e0iV-Q.js +55 -0
  50. package/dist/button-DG7y_FVJ.js +48 -0
  51. package/dist/{canvasNoteTools-D3zUdEeg.js → canvasNoteTools-CQIc7Oxg.js} +2 -2
  52. package/dist/client-C9XSzSXr.js +1147 -0
  53. package/dist/{codec-client-DstqyzTN.js → codec-client-CJ95Rmqo.js} +1 -1
  54. package/dist/constants-B2lhWNoN.js +202 -0
  55. package/dist/constants-XdvUxeWK.d.ts +162 -0
  56. package/dist/dialog-Cjb4lB4D.js +105 -0
  57. package/dist/executions.d.ts +1 -1
  58. package/dist/executions.js +2 -1
  59. package/dist/feature-flags-DM5myWaD.js +296 -0
  60. package/dist/flags.d.ts +3 -0
  61. package/dist/flags.js +4 -0
  62. package/dist/{flow-builder-DEzT8TQu.js → flow-builder-y2Y1iG4Y.js} +70 -1731
  63. package/dist/{node-endpoint-configs-DHFGA5MQ.js → graphql-operation-types-kX-MMjgW.js} +1 -1194
  64. package/dist/{graphql-types-XcDLtFwU.js → graphql-types-CDKVWH2R.js} +2 -202
  65. package/dist/history.d.ts +1 -1
  66. package/dist/history.js +1 -1
  67. package/dist/index-72XFgvbn.d.ts +132 -0
  68. package/dist/index-BcdtKBM-.d.ts +56 -0
  69. package/dist/{index-B3BWqafN.d.ts → index-DjiFgEQl.d.ts} +5 -131
  70. package/dist/{index-DRf25-D3.d.ts → index-W2o__Nm6.d.ts} +32 -214
  71. package/dist/index.d.ts +13 -9
  72. package/dist/index.js +50 -5300
  73. package/dist/{node-detail-view-LNqeIqN-.js → node-detail-view-B91kXzIy.js} +11 -8
  74. package/dist/node-endpoint-configs-B5bjNMDW.js +37 -0
  75. package/dist/node-registry-refresh-Dy0uRg9f.js +84 -0
  76. package/dist/nodes.d.ts +1 -1
  77. package/dist/nodes.js +1 -1
  78. package/dist/observability.d.ts +1 -1
  79. package/dist/observability.js +2 -1
  80. package/dist/{quick-config-panel-D3ogsaFL.js → quick-config-panel-DggPl1vY.js} +2 -2
  81. package/dist/rolldown-runtime-hDbaFkMy.js +18 -0
  82. package/dist/run-display-BycKYSU0.js +46 -0
  83. package/dist/run-list-links-ByYC0OlV.js +98 -0
  84. package/dist/settings.d.ts +2 -1
  85. package/dist/settings.js +2 -1
  86. package/dist/shared-CMfn30xT.js +196 -0
  87. package/dist/templates.d.ts +1 -1
  88. package/dist/templates.js +2 -1
  89. package/dist/theme-provider-B3mIuz2d.js +11 -0
  90. package/dist/{useAgentDefinitions-NFtLytDR.js → useAgentDefinitions-Dpz0HDTq.js} +2 -1
  91. package/dist/useDurableParity-CzUQMFJ3.js +415 -0
  92. package/dist/useEntityTags-DhnsZcTl.js +236 -0
  93. package/dist/{useExecutions-DAzeWHS6.js → useExecutions-9aLuOt1c.js} +4 -3
  94. package/dist/{useObservability-COCZ0hUS.js → useObservability-CfEw3ZFD.js} +2 -2
  95. package/dist/{useRunHistory-CsYUbouO.js → useRunHistory-B1xJDwl1.js} +4 -3
  96. package/dist/{useWorkflows-w4Dx2fF2.js → useWorkflows-BlVVu8NM.js} +3 -2
  97. package/dist/utils-uaL5UVxb.js +65 -0
  98. package/dist/workflow-builder.d.ts +1 -1
  99. package/dist/workflow-builder.js +4 -2
  100. package/dist/workflow-host.d.ts +6 -0
  101. package/dist/workflow-host.js +9 -0
  102. package/dist/workflow-pages.d.ts +55 -0
  103. package/dist/workflow-pages.js +113 -0
  104. package/dist/workflows-list.d.ts +1 -1
  105. package/dist/workflows-list.js +1 -1
  106. package/package.json +13 -1
  107. package/dist/ExecutionDetailPage-MvsnOnE1.d.ts +0 -4
  108. package/dist/HistoryPage-BqUizaFv.d.ts +0 -3
  109. package/dist/NodesPage-C97-9K2Y.d.ts +0 -3
  110. package/dist/TemplatesPage-D0qnXzHh.d.ts +0 -4
  111. package/dist/WorkflowsList-0d5GSKdh.d.ts +0 -3
  112. package/dist/agent-form-BvMWhQ42.js +0 -496
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
3
- import { Bi as describeOperationError, Dr as WorkflowDefinitionDocument, Oi as getFluidGridsClient, Ui as throwIfResultError, bi as WorkflowVersionDiffDocument } from "./node-endpoint-configs-DHFGA5MQ.js";
3
+ import { _ as throwIfResultError, m as describeOperationError, n as getFluidGridsClient } from "./client-C9XSzSXr.js";
4
+ import { Er as WorkflowDefinitionDocument, yi as WorkflowVersionDiffDocument } from "./graphql-operation-types-kX-MMjgW.js";
4
5
  import { t as canvasFromDefinition } from "./definition-canvas--3MPHoP-.js";
5
6
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
6
7
  import { Background, Controls, Handle, MiniMap, Position, ReactFlow, ReactFlowProvider } from "@xyflow/react";
@@ -0,0 +1,555 @@
1
+ "use client";
2
+ import { hn as useCanvasEdges, n as FluidGridsProvider } from "./FluidGridsProvider-dvZSNtSW.js";
3
+ import { H as useFlowStore } from "./node-operation-selection--oy-yEq_.js";
4
+ import { t as Button } from "./button-DG7y_FVJ.js";
5
+ import { d as Input } from "./dialog-Cjb4lB4D.js";
6
+ import { b as Card } from "./TemplateCard-DsC0KNH1.js";
7
+ import { t as cn } from "./cn-QqidFIgr.js";
8
+ import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
9
+ import { B as FluidGridsMark, z as useNodeSelectedEvent } from "./flow-builder-y2Y1iG4Y.js";
10
+ import { useCallback, useEffect, useRef, useState } from "react";
11
+ import { Background, Controls, Handle, MarkerType, MiniMap, Position, ReactFlow, ReactFlowProvider, useReactFlow } from "@xyflow/react";
12
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
+ import { Toaster } from "sonner";
14
+ import { edgeColor, nodeCategoryColor } from "@burdenoff/fe-libs/shared/utils";
15
+ import { useShallow } from "zustand/shallow";
16
+ import { ThemeProvider } from "@burdenoff/fe-libs/shared/providers/shell";
17
+ import { useTheme, useThemeOrNull } from "@burdenoff/fe-libs/shared/hooks/shell";
18
+ import "@xyflow/react/dist/style.css";
19
+ import { ArrowLeft, Play, Save, Trash2 } from "lucide-react";
20
+
21
+ // src/theme/EnsureThemeProvider.tsx
22
+ /**
23
+ * Give the SDK's components a fe-libs theme context when the host has none.
24
+ *
25
+ * Several SDK components (the toast host, theme toggles, editors) read the
26
+ * theme through fe-libs `useTheme`, which throws outside a `ThemeProvider`.
27
+ * The Burdenoff app shells always mount one, but a third-party page that
28
+ * renders `<WorkflowBuilder>` or `<FluidGridsRoot>` directly does not. This
29
+ * wrapper mounts the SDK's own provider only in that case: when the host
30
+ * already has a provider, its children render inside the host's context
31
+ * unchanged, so there is never a second provider fighting over the
32
+ * document's theme attributes.
33
+ */
34
+ function EnsureThemeProvider({ children }) {
35
+ if (useThemeOrNull()) return /* @__PURE__ */ jsx(Fragment, { children });
36
+ return /* @__PURE__ */ jsx(ThemeProvider, { children });
37
+ }
38
+
39
+ // src/builder/components/ui/sonner.tsx
40
+ const Toaster$1 = ({ ...props }) => {
41
+ const { resolvedTheme = "light" } = useTheme();
42
+ return /* @__PURE__ */ jsx(Toaster, {
43
+ theme: resolvedTheme,
44
+ className: "toaster group",
45
+ toastOptions: { classNames: {
46
+ toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
47
+ description: "group-[.toast]:text-muted-foreground",
48
+ actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
49
+ cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground"
50
+ } },
51
+ ...props
52
+ });
53
+ };
54
+
55
+ // src/components/WorkflowBuilderCore.tsx
56
+ const defaultEdgeOptions = {
57
+ type: "smoothstep",
58
+ markerEnd: {
59
+ type: MarkerType.ArrowClosed,
60
+ width: 21,
61
+ height: 21
62
+ },
63
+ style: { stroke: edgeColor("default") }
64
+ };
65
+ const handleStyle = {
66
+ width: 10,
67
+ height: 10,
68
+ background: "var(--color-node-handle-connected)",
69
+ border: "2px solid var(--color-node-bg)"
70
+ };
71
+ const baseNodeStyle = {
72
+ padding: "8px 16px",
73
+ borderRadius: "8px",
74
+ fontWeight: 500,
75
+ boxShadow: "var(--shadow-elevation-2)",
76
+ position: "relative",
77
+ color: "var(--color-action-primary-text)"
78
+ };
79
+ const NODE_CATEGORY_BY_TYPE = {
80
+ "trigger:api": "trigger",
81
+ end: "end",
82
+ "internal:if": "logic",
83
+ "internal:switch": "logic",
84
+ "internal:loop": "loop",
85
+ "internal:merge": "utility",
86
+ "internal:set": "data",
87
+ "internal:filter": "data",
88
+ "internal:aggregate": "data",
89
+ "internal:wait": "utility",
90
+ "internal:noop": "utility",
91
+ "internal:http": "integration"
92
+ };
93
+ function getNodeColor(type) {
94
+ return nodeCategoryColor(NODE_CATEGORY_BY_TYPE[type] ?? "default");
95
+ }
96
+ function TriggerNode({ data }) {
97
+ const tr = useTr();
98
+ const label = data.label;
99
+ return /* @__PURE__ */ jsxs("div", {
100
+ style: {
101
+ ...baseNodeStyle,
102
+ background: getNodeColor("trigger:api")
103
+ },
104
+ children: [label || tr("fluidgrids.components.workflowBuilderCore.triggerNodeLabel", "API Trigger"), /* @__PURE__ */ jsx(Handle, {
105
+ type: "source",
106
+ position: Position.Bottom,
107
+ style: handleStyle
108
+ })]
109
+ });
110
+ }
111
+ function EndNode({ data }) {
112
+ const tr = useTr();
113
+ const label = data.label;
114
+ return /* @__PURE__ */ jsxs("div", {
115
+ style: {
116
+ ...baseNodeStyle,
117
+ background: getNodeColor("end")
118
+ },
119
+ children: [/* @__PURE__ */ jsx(Handle, {
120
+ type: "target",
121
+ position: Position.Top,
122
+ style: handleStyle
123
+ }), label || tr("fluidgrids.components.workflowBuilderCore.endNodeLabel", "End")]
124
+ });
125
+ }
126
+ function ActionNode({ data, type }) {
127
+ const tr = useTr();
128
+ const label = data.label;
129
+ const color = getNodeColor(type || "default");
130
+ return /* @__PURE__ */ jsxs("div", {
131
+ style: {
132
+ ...baseNodeStyle,
133
+ background: color,
134
+ minWidth: 120,
135
+ textAlign: "center"
136
+ },
137
+ children: [
138
+ /* @__PURE__ */ jsx(Handle, {
139
+ type: "target",
140
+ position: Position.Top,
141
+ style: handleStyle
142
+ }),
143
+ label || tr("fluidgrids.components.workflowBuilderCore.actionNodeLabel", "Action"),
144
+ /* @__PURE__ */ jsx(Handle, {
145
+ type: "source",
146
+ position: Position.Bottom,
147
+ style: handleStyle
148
+ })
149
+ ]
150
+ });
151
+ }
152
+ const NODE_TYPES = {
153
+ "trigger:api": TriggerNode,
154
+ end: EndNode,
155
+ "internal:if": ActionNode,
156
+ "internal:switch": ActionNode,
157
+ "internal:loop": ActionNode,
158
+ "internal:merge": ActionNode,
159
+ "internal:set": ActionNode,
160
+ "internal:filter": ActionNode,
161
+ "internal:aggregate": ActionNode,
162
+ "internal:wait": ActionNode,
163
+ "internal:noop": ActionNode,
164
+ "internal:http": ActionNode,
165
+ "internal:subworkflow": ActionNode,
166
+ default: ActionNode
167
+ };
168
+ let nodeIdCounter = 0;
169
+ function FlowBuilderInner({ workflow, readonly = false, hideHeader = false, hideSidebar = false, hideLogsPanel = false, onSave, onExecute, onNodeClick, onBack, className }) {
170
+ const reactFlowInstance = useReactFlow();
171
+ const tr = useTr();
172
+ useNodeSelectedEvent();
173
+ const setWorkflow = useFlowStore((s) => s.actions.setWorkflow);
174
+ const resetWorkflow = useFlowStore((s) => s.actions.resetWorkflow);
175
+ const deleteNode = useFlowStore((s) => s.actions.nodes.deleteNode);
176
+ const setNodes = useFlowStore((s) => s.actions.nodes.setNodes);
177
+ const [nodes, edges, onNodesChange, onEdgesChange, onConnect] = useFlowStore(useShallow((s) => [
178
+ s.workflow.nodes,
179
+ s.workflow.edges,
180
+ s.actions.nodes.onNodesChange,
181
+ s.actions.edges.onEdgesChange,
182
+ s.actions.edges.onConnect
183
+ ]));
184
+ const canvasEdges = useCanvasEdges(nodes, edges);
185
+ const [workflowName, setWorkflowName] = useState(workflow?.name || "Untitled Workflow");
186
+ const [selectedNodeId, setSelectedNodeId] = useState(null);
187
+ const reactFlowWrapper = useRef(null);
188
+ useEffect(() => {
189
+ resetWorkflow();
190
+ if (workflow) {
191
+ setWorkflow(workflow);
192
+ setWorkflowName(workflow.name || "Untitled Workflow");
193
+ }
194
+ }, [
195
+ workflow,
196
+ resetWorkflow,
197
+ setWorkflow
198
+ ]);
199
+ const handleNameChange = (e) => {
200
+ setWorkflowName(e.target.value);
201
+ setWorkflow({ name: e.target.value });
202
+ };
203
+ const handleSave = () => {
204
+ const savedWorkflow = {
205
+ id: workflow?.id || "",
206
+ workflowKey: workflow?.workflowKey || "",
207
+ name: workflowName,
208
+ version: workflow?.version || "1",
209
+ alias: workflow?.alias,
210
+ nodes,
211
+ edges,
212
+ sidebar: {
213
+ active: "none",
214
+ panels: { nodeProperties: { selectedNode: null } }
215
+ }
216
+ };
217
+ onSave?.(savedWorkflow);
218
+ };
219
+ const handleExecute = () => {
220
+ const runId = `run-${Date.now()}`;
221
+ onExecute?.(runId);
222
+ };
223
+ const handleNodeClick = useCallback((_event, node) => {
224
+ setSelectedNodeId(node.id);
225
+ onNodeClick?.(node);
226
+ }, [onNodeClick]);
227
+ const handlePaneClick = useCallback(() => {
228
+ setSelectedNodeId(null);
229
+ }, []);
230
+ const handleDragOver = useCallback((event) => {
231
+ event.preventDefault();
232
+ event.dataTransfer.dropEffect = "copy";
233
+ }, []);
234
+ const handleDrop = useCallback((event) => {
235
+ event.preventDefault();
236
+ const raw = event.dataTransfer.getData("application/json");
237
+ if (!raw) return;
238
+ let payload;
239
+ try {
240
+ payload = JSON.parse(raw);
241
+ } catch {
242
+ return;
243
+ }
244
+ const nodeType = payload.type || payload.id || "default";
245
+ const label = payload.label || nodeType;
246
+ const bounds = reactFlowWrapper.current?.getBoundingClientRect();
247
+ if (!bounds) return;
248
+ const position = reactFlowInstance.screenToFlowPosition({
249
+ x: event.clientX - bounds.left,
250
+ y: event.clientY - bounds.top
251
+ });
252
+ nodeIdCounter += 1;
253
+ const newNode = {
254
+ id: `${nodeType}-${Date.now()}-${nodeIdCounter}`,
255
+ type: nodeType,
256
+ position,
257
+ data: { label }
258
+ };
259
+ const currentNodes = useFlowStore.getState().workflow.nodes;
260
+ setNodes([...currentNodes, newNode]);
261
+ }, [reactFlowInstance, setNodes]);
262
+ const selectedNode = selectedNodeId ? nodes.find((n) => n.id === selectedNodeId) : null;
263
+ const handleSelectedNodeLabelChange = useCallback((newLabel) => {
264
+ if (!selectedNodeId) return;
265
+ const updated = useFlowStore.getState().workflow.nodes.map((n) => n.id === selectedNodeId ? {
266
+ ...n,
267
+ data: {
268
+ ...n.data,
269
+ label: newLabel
270
+ }
271
+ } : n);
272
+ setNodes(updated);
273
+ }, [selectedNodeId, setNodes]);
274
+ const handleDeleteSelectedNode = useCallback(() => {
275
+ if (!selectedNode) return;
276
+ if (selectedNode.deletable === false) return;
277
+ deleteNode(selectedNode);
278
+ setSelectedNodeId(null);
279
+ }, [selectedNode, deleteNode]);
280
+ return /* @__PURE__ */ jsxs("div", {
281
+ className: cn("flex flex-col flex-1 h-full w-full min-h-0", className),
282
+ children: [
283
+ !hideHeader && /* @__PURE__ */ jsxs(Card, {
284
+ className: "h-14 shrink-0 border-0 rounded-none bg-gradient-to-r from-primary/20 to-transparent p-2 flex items-center justify-between border-b",
285
+ children: [/* @__PURE__ */ jsxs("div", {
286
+ className: "flex items-center gap-2",
287
+ children: [onBack && /* @__PURE__ */ jsx(Button, {
288
+ variant: "ghost",
289
+ size: "icon",
290
+ onClick: onBack,
291
+ children: /* @__PURE__ */ jsx(ArrowLeft, { className: "size-5" })
292
+ }), /* @__PURE__ */ jsx(Input, {
293
+ className: "font-semibold max-w-[300px]",
294
+ value: workflowName,
295
+ onChange: handleNameChange,
296
+ placeholder: tr("fluidgrids.components.workflowBuilderCore.workflowNamePlaceholder", "Workflow Name"),
297
+ disabled: readonly
298
+ })]
299
+ }), !readonly && /* @__PURE__ */ jsxs("div", {
300
+ className: "flex items-center gap-2",
301
+ children: [/* @__PURE__ */ jsxs(Button, {
302
+ "data-agent": "confirm",
303
+ variant: "outline",
304
+ size: "sm",
305
+ onClick: handleSave,
306
+ children: [/* @__PURE__ */ jsx(Save, { className: "size-4 mr-1" }), tr("fluidgrids.components.workflowBuilderCore.save", "Save")]
307
+ }), /* @__PURE__ */ jsxs(Button, {
308
+ "data-agent": "confirm",
309
+ size: "sm",
310
+ onClick: handleExecute,
311
+ children: [/* @__PURE__ */ jsx(Play, { className: "size-4 mr-1" }), tr("fluidgrids.components.workflowBuilderCore.run", "Run")]
312
+ })]
313
+ })]
314
+ }),
315
+ /* @__PURE__ */ jsxs("div", {
316
+ className: "flex flex-1 min-h-0 overflow-hidden",
317
+ children: [/* @__PURE__ */ jsxs("div", {
318
+ className: "flex-1 h-full relative",
319
+ ref: reactFlowWrapper,
320
+ children: [/* @__PURE__ */ jsxs(ReactFlow, {
321
+ nodes,
322
+ edges: canvasEdges,
323
+ onNodesChange: readonly ? void 0 : onNodesChange,
324
+ onEdgesChange: readonly ? void 0 : onEdgesChange,
325
+ onConnect: readonly ? void 0 : onConnect,
326
+ onNodeClick: readonly ? void 0 : handleNodeClick,
327
+ onPaneClick: handlePaneClick,
328
+ onDragOver: readonly ? void 0 : handleDragOver,
329
+ onDrop: readonly ? void 0 : handleDrop,
330
+ nodeTypes: NODE_TYPES,
331
+ defaultEdgeOptions,
332
+ fitView: true,
333
+ snapToGrid: true,
334
+ snapGrid: [16, 16],
335
+ proOptions: { hideAttribution: true },
336
+ deleteKeyCode: readonly ? null : "Backspace",
337
+ children: [
338
+ /* @__PURE__ */ jsx(Background, { gap: 24 }),
339
+ /* @__PURE__ */ jsx(Controls, {}),
340
+ /* @__PURE__ */ jsx(MiniMap, {})
341
+ ]
342
+ }), /* @__PURE__ */ jsx(FluidGridsMark, {})]
343
+ }), !hideSidebar && !readonly && /* @__PURE__ */ jsxs("div", {
344
+ className: "w-60 shrink-0 border-l bg-card overflow-y-auto",
345
+ children: [/* @__PURE__ */ jsx("div", {
346
+ className: "p-4 border-b",
347
+ children: /* @__PURE__ */ jsx("div", {
348
+ className: "text-sm font-semibold",
349
+ children: tr("fluidgrids.components.workflowBuilderCore.nodePropertiesHeading", "Node Properties")
350
+ })
351
+ }), selectedNode ? /* @__PURE__ */ jsxs("div", {
352
+ className: "p-4 space-y-4",
353
+ children: [
354
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
355
+ className: "block text-xs font-medium text-muted-foreground mb-1",
356
+ children: tr("fluidgrids.components.workflowBuilderCore.nodeIdLabel", "Node ID")
357
+ }), /* @__PURE__ */ jsx("code", {
358
+ className: "block text-xs bg-muted px-2 py-1 rounded font-mono break-all",
359
+ children: selectedNode.id
360
+ })] }),
361
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
362
+ className: "block text-xs font-medium text-muted-foreground mb-1",
363
+ children: tr("fluidgrids.components.workflowBuilderCore.nodeTypeLabel", "Type")
364
+ }), /* @__PURE__ */ jsxs("div", {
365
+ className: "flex items-center gap-2",
366
+ children: [/* @__PURE__ */ jsx("span", {
367
+ className: "inline-block w-3 h-3 rounded-full shrink-0",
368
+ style: { background: getNodeColor(selectedNode.type || "default") }
369
+ }), /* @__PURE__ */ jsx("code", {
370
+ className: "text-xs font-mono",
371
+ children: selectedNode.type
372
+ })]
373
+ })] }),
374
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
375
+ className: "block text-xs font-medium text-muted-foreground mb-1",
376
+ children: tr("fluidgrids.components.workflowBuilderCore.nodeLabelLabel", "Label")
377
+ }), /* @__PURE__ */ jsx(Input, {
378
+ value: selectedNode.data?.label ?? "",
379
+ onChange: (e) => handleSelectedNodeLabelChange(e.target.value),
380
+ className: "text-sm",
381
+ placeholder: tr("fluidgrids.components.workflowBuilderCore.nodeLabelPlaceholder", "Node label")
382
+ })] }),
383
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
384
+ className: "block text-xs font-medium text-muted-foreground mb-1",
385
+ children: tr("fluidgrids.components.workflowBuilderCore.positionLabel", "Position")
386
+ }), /* @__PURE__ */ jsxs("div", {
387
+ className: "grid grid-cols-2 gap-2 text-xs text-muted-foreground",
388
+ children: [/* @__PURE__ */ jsxs("div", { children: [
389
+ "X:",
390
+ " ",
391
+ /* @__PURE__ */ jsx("span", {
392
+ className: "font-mono",
393
+ children: Math.round(selectedNode.position.x)
394
+ })
395
+ ] }), /* @__PURE__ */ jsxs("div", { children: [
396
+ "Y:",
397
+ " ",
398
+ /* @__PURE__ */ jsx("span", {
399
+ className: "font-mono",
400
+ children: Math.round(selectedNode.position.y)
401
+ })
402
+ ] })]
403
+ })] }),
404
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
405
+ className: "block text-xs font-medium text-muted-foreground mb-1",
406
+ children: tr("fluidgrids.components.workflowBuilderCore.connectionsLabel", "Connections")
407
+ }), /* @__PURE__ */ jsx("div", {
408
+ className: "text-xs text-muted-foreground",
409
+ children: (() => {
410
+ const inbound = edges.filter((e) => e.target === selectedNode.id);
411
+ const outbound = edges.filter((e) => e.source === selectedNode.id);
412
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { children: [
413
+ inbound.length,
414
+ " inbound, ",
415
+ outbound.length,
416
+ " outbound"
417
+ ] }) });
418
+ })()
419
+ })] }),
420
+ selectedNode.deletable !== false && /* @__PURE__ */ jsx("div", {
421
+ className: "pt-2 border-t",
422
+ children: /* @__PURE__ */ jsxs(Button, {
423
+ variant: "destructive",
424
+ size: "sm",
425
+ className: "w-full",
426
+ onClick: handleDeleteSelectedNode,
427
+ children: [/* @__PURE__ */ jsx(Trash2, { className: "size-4 mr-1" }), tr("fluidgrids.components.workflowBuilderCore.deleteNode", "Delete Node")]
428
+ })
429
+ })
430
+ ]
431
+ }) : /* @__PURE__ */ jsxs("div", {
432
+ className: "p-4",
433
+ children: [/* @__PURE__ */ jsx("p", {
434
+ className: "text-xs text-muted-foreground",
435
+ children: tr("fluidgrids.components.workflowBuilderCore.noSelectionHint", "Click a node on the canvas to view and edit its properties.")
436
+ }), /* @__PURE__ */ jsx("p", {
437
+ className: "text-xs text-muted-foreground mt-2",
438
+ children: tr("fluidgrids.components.workflowBuilderCore.dragPaletteHint", "Drag nodes from the palette on the left to add them to the workflow.")
439
+ })]
440
+ })]
441
+ })]
442
+ }),
443
+ !hideLogsPanel && /* @__PURE__ */ jsxs("div", {
444
+ className: "h-32 border-t bg-card p-2",
445
+ children: [/* @__PURE__ */ jsx("div", {
446
+ className: "text-sm font-medium mb-2",
447
+ children: tr("fluidgrids.components.workflowBuilderCore.executionLogsHeading", "Execution Logs")
448
+ }), /* @__PURE__ */ jsx("p", {
449
+ className: "text-xs text-muted-foreground",
450
+ children: tr("fluidgrids.components.workflowBuilderCore.executionLogsEmpty", "Execution logs will appear here when you run the workflow")
451
+ })]
452
+ })
453
+ ]
454
+ });
455
+ }
456
+ /**
457
+ * Lightweight, local-only workflow canvas.
458
+ *
459
+ * Host events (`FluidGridsEventMap`): reports `node:selected` exactly like the
460
+ * full builder canvas. Save and Run only hand data to `onSave` / `onExecute`
461
+ * and call no backend, so it emits no `workflow:saved`, `run:started` or
462
+ * `error` events: the host performs those actions and already knows their
463
+ * outcome. Works without a host `ThemeProvider`.
464
+ */
465
+ function WorkflowBuilderCore(props) {
466
+ return /* @__PURE__ */ jsx(EnsureThemeProvider, { children: /* @__PURE__ */ jsxs(ReactFlowProvider, { children: [/* @__PURE__ */ jsx(FlowBuilderInner, { ...props }), /* @__PURE__ */ jsx(Toaster$1, {
467
+ richColors: true,
468
+ position: "bottom-center",
469
+ duration: 2e3
470
+ })] }) });
471
+ }
472
+
473
+ // src/components/WorkflowBuilder.tsx
474
+ /**
475
+ * WorkflowBuilder - Standalone workflow builder component with Apollo client support
476
+ *
477
+ * Use this component when you want to embed the workflow builder in any React app.
478
+ * You can either:
479
+ * 1. Provide pre-configured Apollo clients (workspaceClient + globalClient) - Recommended
480
+ * 2. Provide URLs and let the component create clients internally
481
+ *
482
+ * It needs no host `ThemeProvider` (one is mounted only when the page has
483
+ * none). Host events: `onEvent` receives `node:selected`; Save and Run are
484
+ * local (they call `onSave` / `onExecute` and no backend), so they emit no
485
+ * `workflow:saved` / `run:started`. See `WorkflowBuilderCore`.
486
+ *
487
+ * @example Dual Client Injection (Recommended)
488
+ * ```tsx
489
+ * import { createFluidGridsClients } from '@fluidgrids/fe-sdk';
490
+ *
491
+ * const { workspaceClient, globalClient } = createFluidGridsClients({
492
+ * workspaceApiUrl: 'http://localhost:4000/workspaces/graphql',
493
+ * globalApiUrl: 'http://localhost:4000/global/graphql',
494
+ * authToken: token,
495
+ * workspaceId: 'ws-123',
496
+ * });
497
+ *
498
+ * <WorkflowBuilder
499
+ * workspaceClient={workspaceClient}
500
+ * globalClient={globalClient}
501
+ * workspaceId="ws-123"
502
+ * onSave={(workflow) => console.log(workflow)}
503
+ * />
504
+ * ```
505
+ *
506
+ * @example URL-based (Simpler, less flexible)
507
+ * ```tsx
508
+ * <WorkflowBuilder
509
+ * apiGatewayUrl="http://localhost:4000/workspaces/graphql"
510
+ * globalApiUrl="http://localhost:4000/global/graphql"
511
+ * authToken={token}
512
+ * workspaceId="ws-123"
513
+ * onSave={(workflow) => console.log(workflow)}
514
+ * />
515
+ * ```
516
+ */
517
+ function WorkflowBuilder({ workflowId, workflowVersion, initialWorkflow, apiGatewayUrl, globalApiUrl, authToken, workspaceId, tenantId, productId, userId, workspaceToken, organizationId, workspaceClient, globalClient, theme, auth, onEvent, ...coreProps }) {
518
+ const workflow = initialWorkflow || createDefaultWorkflow(workflowId, workflowVersion);
519
+ return /* @__PURE__ */ jsx(FluidGridsProvider, {
520
+ apiGatewayUrl,
521
+ globalApiUrl,
522
+ authToken,
523
+ workspaceId,
524
+ tenantId,
525
+ productId,
526
+ userId,
527
+ workspaceToken,
528
+ organizationId,
529
+ workspaceClient,
530
+ globalClient,
531
+ theme,
532
+ auth,
533
+ onEvent,
534
+ children: /* @__PURE__ */ jsx(WorkflowBuilderCore, {
535
+ workflow,
536
+ ...coreProps
537
+ })
538
+ });
539
+ }
540
+ function createDefaultWorkflow(id, version) {
541
+ return {
542
+ id: id || `workflow-${Date.now()}`,
543
+ workflowKey: id || `workflow-${Date.now()}`,
544
+ name: "Untitled Workflow",
545
+ version: version || "1",
546
+ nodes: [],
547
+ edges: [],
548
+ sidebar: {
549
+ active: "store-browse",
550
+ panels: { nodeProperties: { selectedNode: null } }
551
+ }
552
+ };
553
+ }
554
+
555
+ export { WorkflowBuilderCore as n, EnsureThemeProvider as r, WorkflowBuilder as t };