@burdenoff/fluidgrids-fe-sdk 2026.1113.1 → 2026.1113.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 (127) hide show
  1. package/dist/{AiStudioPage-D3MAk-bs.js → AiStudioPage-5KYZ8r8-.js} +464 -7
  2. package/dist/{ApprovalInboxPage-Bb8H9ruw.js → ApprovalInboxPage-BsJX4osU.js} +4 -3
  3. package/dist/{ConnectionFormDialog-Bg9_OdHX.js → ConnectionFormDialog-Dr1-CTan.js} +2 -1
  4. package/dist/CreateFluidgridsTagDocument-Dtp9KPLJ.js +1055 -0
  5. package/dist/{DataSinkDashboardPage-Dc2QuJbL.js → DataSinkDashboardPage-8ZDn85e2.js} +1 -1
  6. package/dist/{DataTablesPage-Cv4veaKK.js → DataTablesPage-BBvABuxE.js} +5 -4
  7. package/dist/{EntityTagPicker-D8ws706D.js → EntityTagPicker-BppBSEJk.js} +2 -2
  8. package/dist/{ExecutionDetailPage-CTVGE-d-.js → ExecutionDetailPage-BXDF2eoT.js} +1444 -18
  9. package/dist/ExecutionsListDocument-CzdLPpj5.js +1259 -0
  10. package/dist/{ExecutionsListPage-J0sJPuoM.js → ExecutionsListPage--4BthM8L.js} +285 -11
  11. package/dist/FailureTriagePanel-B5WCSRFo.js +1252 -0
  12. package/dist/{FluidGridsProvider-C4FVNz0n.js → FluidGridsProvider-Dc_Jhtch.js} +8666 -8734
  13. package/dist/{HistoryPage-B9XcTPrO.js → HistoryPage-BvFk2m1m.js} +4 -3
  14. package/dist/{InsightsPage-DFOltjyj.js → InsightsPage-Dwmb02F6.js} +2682 -5
  15. package/dist/{MissingNodesInstallModal-D8H-YNCJ.js → MissingNodesInstallModal-Cze674hp.js} +2 -2
  16. package/dist/{NodesPage-YQ-hP60x.js → NodesPage-C5Dq-ru-.js} +3 -2
  17. package/dist/{OpenTemplateAsCodeButton-hH26HQCk.js → OpenTemplateAsCodeButton-8MZHih6I.js} +2 -2
  18. package/dist/{PaidTemplateConfirm-DoKWMBtR.js → PaidTemplateConfirm-0G-gv29n.js} +1 -1
  19. package/dist/{PublishCustomNodeAction-5XXnSA3H.js → PublishCustomNodeAction-OOY35dUv.js} +1 -1
  20. package/dist/QuotaExhaustedDialog-wvu_-WJ-.js +55 -0
  21. package/dist/{RunnerStatusPill-Ctg4TJcP.js → RunnerStatusPill-Bh7mEsPh.js} +2 -1
  22. package/dist/{RunnersPage-CAt4YDhB.js → RunnersPage-DHeuUDil.js} +2 -2
  23. package/dist/{SettingsPage-DEKPCVVP.js → SettingsPage-CfjXiGpb.js} +694 -14
  24. package/dist/{TagFilterSelect-CwM2-DU6.js → TagFilterSelect-CAShgvbS.js} +1 -1
  25. package/dist/{TaskQueuesPage-Dhi6SIT4.js → TaskQueuesPage--Mmn36b-.js} +3 -3
  26. package/dist/{TemplateCard-DVSd_4zJ.js → TemplateCard-BA_9em22.js} +644 -352
  27. package/dist/{TemplateConfigurationModal-BKi1z7z7.js → TemplateConfigurationModal-BT3PaR0O.js} +4 -3
  28. package/dist/{TemplateDetailPanel-DK1gF7P5.js → TemplateDetailPanel-BxFNnlXm.js} +2 -1
  29. package/dist/{TemplatePreview-DuSX2Q7H.js → TemplatePreview-Bagja6WN.js} +7 -7
  30. package/dist/{TemplatesPage-CAWHh61l.js → TemplatesPage-CAajpJ5w.js} +711 -6
  31. package/dist/{VariablesPage-D7CoatWf.js → VariablesPage-CgUBKhAe.js} +3 -3
  32. package/dist/{VersionDiffDialog-DGwysiyE.js → VersionDiffDialog-D9W5Fm56.js} +233 -129
  33. package/dist/VersionLifecycleBar-DuphLOT0.js +131 -0
  34. package/dist/{WorkflowBuilder-DAeoQi5E.js → WorkflowBuilder-DMpSPElu.js} +16 -13
  35. package/dist/{WorkflowBuilder-BJgqDboZ.js → WorkflowBuilder-v8h8skwG.js} +5 -5
  36. package/dist/WorkflowDefinitionDocument-DZLbTPUZ.js +321 -0
  37. package/dist/WorkflowEditLeaseStatusDocument-Dp62med3.js +627 -0
  38. package/dist/WorkflowProposalCard-zCdUpCk8.js +249 -0
  39. package/dist/WorkflowProposalDocument-BdUbsrd0.js +620 -0
  40. package/dist/{WorkflowSearchRedirect-CMEvd_AR.js → WorkflowSearchRedirect-G78lINAE.js} +1 -1
  41. package/dist/{WorkflowShareDialog-BgHRsDP0.js → WorkflowShareDialog-B7VOgr4-.js} +304 -3
  42. package/dist/WorkflowVersionsDocument-CfPMloRW.js +3195 -0
  43. package/dist/{WorkflowsList-CcQPxWKL.js → WorkflowsList-CPYzfE4K.js} +11 -9
  44. package/dist/agent-form-D0uLvzx4.js +718 -0
  45. package/dist/{agentTools-DKpNKztf.js → agentTools-DTXUqtfu.js} +4 -4
  46. package/dist/api-BZVyX5d2.js +2286 -0
  47. package/dist/api-BqA-f-AD.js +8064 -0
  48. package/dist/app-BJUvugPM.js +3813 -0
  49. package/dist/assert-rules-CPNrO44K.js +318 -0
  50. package/dist/attach-node-helpers-CNsYtLOR.js +32 -0
  51. package/dist/badge-CXfPhoMH.js +26 -0
  52. package/dist/{canvasNoteTools-C_AN79m0.js → canvasNoteTools-DmfZwtnL.js} +3 -3
  53. package/dist/{channel-CZ70oI81.js → channel-DtF1n_ab.js} +1 -1
  54. package/dist/client-Ctl4jmY3.js +127 -0
  55. package/dist/code-editor-diagnostics-Zr0cIcx1.js +46 -0
  56. package/dist/{code-editor-field-Dt6KNWwN.js → code-editor-field-Cv907s3W.js} +2 -2
  57. package/dist/{codec-client-CJ95Rmqo.js → codec-client-CAYl6j46.js} +2 -1
  58. package/dist/conditionBuilder-D8aLGL1w.js +1134 -0
  59. package/dist/config-X97zrIvn.js +600 -0
  60. package/dist/{definition-canvas-Bshn_dSP.js → definition-canvas-DL25_6NH.js} +1 -1
  61. package/dist/{dialog-Cjb4lB4D.js → dialog-BVd152GS.js} +3 -14
  62. package/dist/durable-nodes-DXCCQYWD.js +81 -0
  63. package/dist/errors-xPZ-IbQd.js +142 -0
  64. package/dist/executions.js +2 -2
  65. package/dist/{flow-builder-D3Hl2AFk.js → flow-builder-Dv5fWJ6F.js} +9301 -8189
  66. package/dist/{node-registry-refresh-Dy0uRg9f.js → global-client-DP_Wxe5t.js} +2 -27
  67. package/dist/global-operations-7pvXw_j9.js +145 -0
  68. package/dist/history.js +1 -1
  69. package/dist/{index-CWcP-tG1.d.ts → index-DtMUtXNq.d.ts} +247 -247
  70. package/dist/index.d.ts +1 -1
  71. package/dist/index.js +4403 -46
  72. package/dist/input-ChT6Q-Pr.js +17 -0
  73. package/dist/logs-panel-DtG93ocy.js +342 -0
  74. package/dist/mapping-colors-BIX_YeCQ.js +48 -0
  75. package/dist/{node-detail-view-bVLeYarT.js → node-detail-view-BKI_2kM6.js} +12 -11
  76. package/dist/{node-editor-tab-body-JHHVtQgR.js → node-editor-tab-body-Cc1MWEFR.js} +3 -3
  77. package/dist/{node-operation-selection-DAbS6jSY.js → node-operation-selection-Czeeb2D4.js} +2 -139
  78. package/dist/node-registry-refresh-s3okf83X.js +27 -0
  79. package/dist/nodes.js +1 -1
  80. package/dist/notesKey-5EaREBGA.js +12 -0
  81. package/dist/observability.d.ts +1 -1
  82. package/dist/observability.js +2 -2
  83. package/dist/{popover-Xx3gN7vg.js → popover-DDv7J1Kl.js} +717 -6
  84. package/dist/{quick-config-panel-BvVQXuIL.js → quick-config-panel-BPCRfqWI.js} +4 -4
  85. package/dist/read-only-context-Dt9N9SIG.js +18 -0
  86. package/dist/{schedule-panel-DCb40TPN.js → schedule-panel-C1KwfLCE.js} +14 -12
  87. package/dist/settings.js +1 -1
  88. package/dist/{shared-CMfn30xT.js → shared-Ctl9ZHo1.js} +2 -1
  89. package/dist/{sidebar-node-editor-DxCWFZG2.js → sidebar-node-editor-d9Rlq5pU.js} +4 -4
  90. package/dist/sticky-notes-23j-wL6Q.js +96 -0
  91. package/dist/template-code-dqRunGOv.js +184 -0
  92. package/dist/template-preview-C01KV277.js +29 -0
  93. package/dist/templates.js +2 -2
  94. package/dist/token-refresh-link-BjN7H4qA.js +291 -0
  95. package/dist/useAgentDefinitions-ZKX2N9aP.js +3101 -0
  96. package/dist/useConnections-BlB0gbOB.js +931 -0
  97. package/dist/useDurableParity-BgLH_SCF.js +2088 -0
  98. package/dist/{useEntityTags-Db4Pc8_M.js → useEntityTags-4iW6UTly.js} +227 -3
  99. package/dist/{useExecutions-DOpG1pUQ.js → useExecutions-Bm7q_UwN.js} +6 -3
  100. package/dist/useGlobalStoreClient-DMTrywdX.js +24 -0
  101. package/dist/{useHumanRequests-ZiR0sSzS.js → useHumanRequests-DwG2tQ3f.js} +2 -1
  102. package/dist/{useObservability-rQmwhoZZ.js → useObservability-DPATdbw7.js} +4 -2
  103. package/dist/{useRunHistory-COn6dl7l.js → useRunHistory-CGfjCsJ3.js} +1122 -4
  104. package/dist/{useVariables-2ddyJX4a.js → useVariables-DFdZofLQ.js} +2 -1
  105. package/dist/{useWorkflowCodeExport-ZoUJKRSK.js → useWorkflowCodeExport-D_mCuhKP.js} +289 -4
  106. package/dist/useWorkflowOrganization-r5FWNBs6.js +1690 -0
  107. package/dist/useWorkflowProposal-Bh2_qjmM.js +7478 -0
  108. package/dist/{useWorkflows-jOW60YmD.js → useWorkflows-aqVD7kGa.js} +694 -4
  109. package/dist/workflow-builder.js +5 -5
  110. package/dist/{workflow-code-transfer-l9wO34S0.js → workflow-code-transfer-5C0HUzae.js} +1 -53
  111. package/dist/workflow-host.js +4 -2
  112. package/dist/workflow-pages.d.ts +1 -1
  113. package/dist/workflow-pages.js +19 -19
  114. package/dist/workflow-preview.js +3 -2
  115. package/dist/workflows-list.js +1 -1
  116. package/package.json +1 -1
  117. package/dist/FailureTriagePanel-BbYFYeV_.js +0 -311
  118. package/dist/WorkflowProposalCard-DGMdZC4R.js +0 -1432
  119. package/dist/agent-form-Bfvm32j1.js +0 -83
  120. package/dist/api-DQtHXbIg.js +0 -224
  121. package/dist/api-MeAm6g7E.js +0 -55
  122. package/dist/client-C9XSzSXr.js +0 -1147
  123. package/dist/graphql-operation-types-C9qbvRa8.js +0 -53122
  124. package/dist/useAgentDefinitions-_hgNCK1A.js +0 -550
  125. package/dist/useConnections-Cs7LCWEM.js +0 -401
  126. package/dist/useDurableParity-CcLeCDfv.js +0 -504
  127. package/dist/useWorkflowOrganization-QxVePSkk.js +0 -282
@@ -0,0 +1,1134 @@
1
+ "use client";
2
+ import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
3
+ import { useCallback, useEffect, useMemo, useState } from "react";
4
+ import { useReactFlow } from "@xyflow/react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { toast } from "sonner";
7
+ import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, Label, ScrollArea, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Tabs, TabsContent, TabsList, TabsTrigger, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@burdenoff/fe-libs/ui";
8
+ import { AlertCircle, ChevronDown, ChevronRight, Copy, Info, Layers, Plus, Trash2 } from "lucide-react";
9
+
10
+ // src/builder/components/flow-builder/components/edges/conditionBuilder/custom-condition-edge.tsx
11
+ const OPERATORS = {
12
+ string: [
13
+ {
14
+ value: "==",
15
+ label: "Equals"
16
+ },
17
+ {
18
+ value: "contains",
19
+ label: "Contains"
20
+ },
21
+ {
22
+ value: "startsWith",
23
+ label: "Starts with"
24
+ },
25
+ {
26
+ value: "endsWith",
27
+ label: "Ends with"
28
+ },
29
+ {
30
+ value: "isNull",
31
+ label: "Is Null"
32
+ },
33
+ {
34
+ value: "isNotNull",
35
+ label: "Is Not Null"
36
+ }
37
+ ],
38
+ number: [
39
+ {
40
+ value: "==",
41
+ label: "Equals"
42
+ },
43
+ {
44
+ value: "!=",
45
+ label: "Not equals"
46
+ },
47
+ {
48
+ value: ">",
49
+ label: "Greater than"
50
+ },
51
+ {
52
+ value: ">=",
53
+ label: "Greater than or equal"
54
+ },
55
+ {
56
+ value: "<",
57
+ label: "Less than"
58
+ },
59
+ {
60
+ value: "<=",
61
+ label: "Less than or equal"
62
+ },
63
+ {
64
+ value: "isNull",
65
+ label: "Is Null"
66
+ },
67
+ {
68
+ value: "isNotNull",
69
+ label: "Is Not Null"
70
+ }
71
+ ],
72
+ integer: [
73
+ {
74
+ value: "==",
75
+ label: "Equals"
76
+ },
77
+ {
78
+ value: "!=",
79
+ label: "Not equals"
80
+ },
81
+ {
82
+ value: ">",
83
+ label: "Greater than"
84
+ },
85
+ {
86
+ value: ">=",
87
+ label: "Greater than or equal"
88
+ },
89
+ {
90
+ value: "<",
91
+ label: "Less than"
92
+ },
93
+ {
94
+ value: "<=",
95
+ label: "Less than or equal"
96
+ },
97
+ {
98
+ value: "isNull",
99
+ label: "Is Null"
100
+ },
101
+ {
102
+ value: "isNotNull",
103
+ label: "Is Not Null"
104
+ }
105
+ ],
106
+ boolean: [
107
+ {
108
+ value: "isTrue",
109
+ label: "Is True"
110
+ },
111
+ {
112
+ value: "isFalse",
113
+ label: "Is False"
114
+ },
115
+ {
116
+ value: "isNull",
117
+ label: "Is Null"
118
+ },
119
+ {
120
+ value: "isNotNull",
121
+ label: "Is Not Null"
122
+ }
123
+ ],
124
+ array: [
125
+ {
126
+ value: "isEmpty",
127
+ label: "Is Empty Array"
128
+ },
129
+ {
130
+ value: "isNotEmpty",
131
+ label: "Is Not Empty Array"
132
+ },
133
+ {
134
+ value: "contains",
135
+ label: "Contains Element"
136
+ },
137
+ {
138
+ value: "isNull",
139
+ label: "Is Null"
140
+ },
141
+ {
142
+ value: "isNotNull",
143
+ label: "Is Not Null"
144
+ }
145
+ ],
146
+ object: [
147
+ {
148
+ value: "isEmpty",
149
+ label: "Is Empty Object"
150
+ },
151
+ {
152
+ value: "isNotEmpty",
153
+ label: "Is Not Empty Object"
154
+ },
155
+ {
156
+ value: "hasProperty",
157
+ label: "Has Property"
158
+ },
159
+ {
160
+ value: "isNull",
161
+ label: "Is Null"
162
+ },
163
+ {
164
+ value: "isNotNull",
165
+ label: "Is Not Null"
166
+ }
167
+ ]
168
+ };
169
+ const parseSchema = (schema, currentPath = "", fields = []) => {
170
+ if (!schema || typeof schema !== "object") return fields;
171
+ const knownTypes = [
172
+ "string",
173
+ "number",
174
+ "integer",
175
+ "boolean",
176
+ "array",
177
+ "object"
178
+ ];
179
+ if (schema.type === "object" && schema.properties) for (const key in schema.properties) {
180
+ const property = schema.properties[key];
181
+ const newPath = currentPath ? `${currentPath}.${key}` : key;
182
+ if (property?.type && knownTypes.includes(property.type)) fields.push({
183
+ path: newPath,
184
+ type: property.type
185
+ });
186
+ if (property?.type === "object" && property.properties) parseSchema(property, newPath, fields);
187
+ if (property?.type === "array" && property.items && property.items.type === "object") {
188
+ fields.push({
189
+ path: newPath,
190
+ type: "array"
191
+ });
192
+ if (property.items.properties) for (const itemKey in property.items.properties) {
193
+ const itemProperty = property.items.properties[itemKey];
194
+ const itemPath = `${newPath}.${itemKey}`;
195
+ if (itemProperty?.type && knownTypes.includes(itemProperty.type)) fields.push({
196
+ path: itemPath,
197
+ type: itemProperty.type
198
+ });
199
+ if (itemProperty?.type === "object" && itemProperty.properties) parseSchema(itemProperty, itemPath, fields);
200
+ }
201
+ }
202
+ }
203
+ fields.sort((a, b) => a.path.localeCompare(b.path));
204
+ return Array.from(new Map(fields.map((f) => [f.path, f])).values());
205
+ };
206
+ const getOperatorsForType = (type) => OPERATORS[type] || [{
207
+ value: "isNull",
208
+ label: "Is Null"
209
+ }, {
210
+ value: "isNotNull",
211
+ label: "Is Not Null"
212
+ }];
213
+ const generateId = () => Date.now().toString(36) + Math.random().toString(36).substring(2);
214
+ const createEmptyGroup = (id) => ({
215
+ id: id || generateId(),
216
+ type: "group",
217
+ combinator: "AND",
218
+ children: []
219
+ });
220
+ const createEmptyRule = (id) => ({
221
+ id: id || generateId(),
222
+ type: "rule",
223
+ field: "",
224
+ operator: "",
225
+ value: ""
226
+ });
227
+ const findAndModifyNode = (node, targetId, modification) => {
228
+ if (node.id === targetId) return modification(node);
229
+ if (node.type === "group") {
230
+ let childrenChanged = false;
231
+ const newChildren = node.children.map((child) => {
232
+ const modifiedChild = findAndModifyNode(child, targetId, modification);
233
+ if (modifiedChild !== child) childrenChanged = true;
234
+ return modifiedChild;
235
+ }).filter((child) => child !== null);
236
+ if (childrenChanged) return {
237
+ ...node,
238
+ children: newChildren
239
+ };
240
+ }
241
+ return node;
242
+ };
243
+ const findAndAddNode = (node, parentId, nodeToAdd) => {
244
+ if (node.id === parentId && node.type === "group") return {
245
+ ...node,
246
+ children: [...node.children, nodeToAdd]
247
+ };
248
+ if (node.type === "group") {
249
+ let childrenChanged = false;
250
+ const newChildren = node.children.map((child) => {
251
+ const updatedChild = findAndAddNode(child, parentId, nodeToAdd);
252
+ if (updatedChild !== child) childrenChanged = true;
253
+ return updatedChild;
254
+ });
255
+ if (childrenChanged) return {
256
+ ...node,
257
+ children: newChildren
258
+ };
259
+ }
260
+ return node;
261
+ };
262
+ const ConditionNodeDisplay = ({ node, path, fieldMap, parsedFields, onUpdateNode, onRemoveNode, onAddRule, onAddGroup, onDuplicateNode, level }) => {
263
+ const tr = useTr();
264
+ const [isExpanded, setIsExpanded] = useState(true);
265
+ const translateOperatorLabel = (label) => {
266
+ switch (label) {
267
+ case "Equals": return tr("fluidgrids.builder.conditionBuilder.operatorEquals", "Equals");
268
+ case "Not equals": return tr("fluidgrids.builder.conditionBuilder.operatorNotEquals", "Not equals");
269
+ case "Contains": return tr("fluidgrids.builder.conditionBuilder.operatorContains", "Contains");
270
+ case "Starts with": return tr("fluidgrids.builder.conditionBuilder.operatorStartsWith", "Starts with");
271
+ case "Ends with": return tr("fluidgrids.builder.conditionBuilder.operatorEndsWith", "Ends with");
272
+ case "Greater than": return tr("fluidgrids.builder.conditionBuilder.operatorGreaterThan", "Greater than");
273
+ case "Greater than or equal": return tr("fluidgrids.builder.conditionBuilder.operatorGreaterThanOrEqual", "Greater than or equal");
274
+ case "Less than": return tr("fluidgrids.builder.conditionBuilder.operatorLessThan", "Less than");
275
+ case "Less than or equal": return tr("fluidgrids.builder.conditionBuilder.operatorLessThanOrEqual", "Less than or equal");
276
+ case "Is True": return tr("fluidgrids.builder.conditionBuilder.operatorIsTrue", "Is True");
277
+ case "Is False": return tr("fluidgrids.builder.conditionBuilder.operatorIsFalse", "Is False");
278
+ case "Is Null": return tr("fluidgrids.builder.conditionBuilder.operatorIsNull", "Is Null");
279
+ case "Is Not Null": return tr("fluidgrids.builder.conditionBuilder.operatorIsNotNull", "Is Not Null");
280
+ case "Is Empty Array": return tr("fluidgrids.builder.conditionBuilder.operatorIsEmptyArray", "Is Empty Array");
281
+ case "Is Not Empty Array": return tr("fluidgrids.builder.conditionBuilder.operatorIsNotEmptyArray", "Is Not Empty Array");
282
+ case "Contains Element": return tr("fluidgrids.builder.conditionBuilder.operatorContainsElement", "Contains Element");
283
+ case "Is Empty Object": return tr("fluidgrids.builder.conditionBuilder.operatorIsEmptyObject", "Is Empty Object");
284
+ case "Is Not Empty Object": return tr("fluidgrids.builder.conditionBuilder.operatorIsNotEmptyObject", "Is Not Empty Object");
285
+ case "Has Property": return tr("fluidgrids.builder.conditionBuilder.operatorHasProperty", "Has Property");
286
+ default: return label;
287
+ }
288
+ };
289
+ const handleUpdate = useCallback((updates) => {
290
+ onUpdateNode(node.id, updates);
291
+ }, [node.id, onUpdateNode]);
292
+ const handleRemove = useCallback(() => {
293
+ onRemoveNode(node.id);
294
+ }, [node.id, onRemoveNode]);
295
+ const handleDuplicate = useCallback(() => {
296
+ if (onDuplicateNode) onDuplicateNode(node.id);
297
+ }, [node.id, onDuplicateNode]);
298
+ if (node.type === "rule") {
299
+ const { field, operator, value } = node;
300
+ const selectedFieldType = fieldMap.get(field);
301
+ const availableOperators = selectedFieldType ? getOperatorsForType(selectedFieldType) : [];
302
+ const needsValue = field && operator && ![
303
+ "isTrue",
304
+ "isFalse",
305
+ "isEmpty",
306
+ "isNotEmpty",
307
+ "isNull",
308
+ "isNotNull"
309
+ ].includes(operator);
310
+ const renderValueInputForRule = () => {
311
+ if (!needsValue) return null;
312
+ switch (selectedFieldType) {
313
+ case "number":
314
+ case "integer": return /* @__PURE__ */ jsx(Input, {
315
+ type: "number",
316
+ placeholder: tr("fluidgrids.builder.conditionBuilder.numberValuePlaceholder", "Number"),
317
+ value: typeof value === "boolean" ? "" : value ?? "",
318
+ onChange: (e) => handleUpdate({ value: e.target.value === "" ? null : Number(e.target.value) }),
319
+ className: "w-full flex-grow"
320
+ });
321
+ case "boolean": return /* @__PURE__ */ jsx("span", {
322
+ className: "text-sm text-muted-foreground italic p-2",
323
+ children: tr("fluidgrids.builder.conditionBuilder.booleanValueHint", "Use 'Is True' / 'Is False'")
324
+ });
325
+ default: return /* @__PURE__ */ jsx(Input, {
326
+ type: "text",
327
+ placeholder: tr("fluidgrids.builder.conditionBuilder.textValuePlaceholder", "Value"),
328
+ value: typeof value === "boolean" ? String(value) : value ?? "",
329
+ onChange: (e) => handleUpdate({ value: e.target.value }),
330
+ className: "w-full flex-grow"
331
+ });
332
+ }
333
+ };
334
+ return /* @__PURE__ */ jsx(Card, {
335
+ className: "overflow-hidden border-muted-foreground/20 shadow-sm transition-all hover:shadow-md",
336
+ children: /* @__PURE__ */ jsx(CardContent, {
337
+ className: "p-3",
338
+ children: /* @__PURE__ */ jsxs("div", {
339
+ className: "flex flex-col sm:flex-row items-stretch sm:items-center gap-2",
340
+ children: [
341
+ /* @__PURE__ */ jsx("div", {
342
+ className: "w-full sm:w-[30%]",
343
+ children: /* @__PURE__ */ jsxs(Select, {
344
+ value: field,
345
+ onValueChange: (val) => handleUpdate({
346
+ field: val,
347
+ operator: "",
348
+ value: ""
349
+ }),
350
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
351
+ className: "h-9",
352
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: tr("fluidgrids.builder.conditionBuilder.selectFieldPlaceholder", "Select field") })
353
+ }), /* @__PURE__ */ jsx(SelectContent, {
354
+ className: "max-h-[300px] z-[100000]",
355
+ children: parsedFields.map((f) => /* @__PURE__ */ jsx(SelectItem, {
356
+ value: f.path,
357
+ children: /* @__PURE__ */ jsxs("div", {
358
+ className: "flex items-center gap-2 w-full",
359
+ children: [/* @__PURE__ */ jsx("span", {
360
+ className: "overflow-visible whitespace-normal break-words",
361
+ children: f.path
362
+ }), /* @__PURE__ */ jsx(Badge, {
363
+ variant: "outline",
364
+ className: "ml-auto shrink-0 text-xs",
365
+ children: f.type
366
+ })]
367
+ })
368
+ }, f.path))
369
+ })]
370
+ })
371
+ }),
372
+ /* @__PURE__ */ jsx("div", {
373
+ className: "w-full sm:w-[25%]",
374
+ children: /* @__PURE__ */ jsxs(Select, {
375
+ value: operator,
376
+ onValueChange: (val) => handleUpdate({
377
+ operator: val,
378
+ value: ""
379
+ }),
380
+ disabled: !field,
381
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
382
+ className: "h-9",
383
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: tr("fluidgrids.builder.conditionBuilder.operatorPlaceholder", "Operator") })
384
+ }), /* @__PURE__ */ jsx(SelectContent, {
385
+ className: "z-[100000]",
386
+ children: availableOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, {
387
+ value: op.value,
388
+ children: translateOperatorLabel(op.label)
389
+ }, op.value))
390
+ })]
391
+ })
392
+ }),
393
+ /* @__PURE__ */ jsxs("div", {
394
+ className: `w-full ${needsValue ? "sm:w-[35%]" : "sm:w-[25%]"} flex items-center`,
395
+ children: [renderValueInputForRule(), !needsValue && operator && /* @__PURE__ */ jsx("span", {
396
+ className: "text-sm text-muted-foreground italic p-2",
397
+ children: tr("fluidgrids.builder.conditionBuilder.noValueNeeded", "No value needed")
398
+ })]
399
+ }),
400
+ /* @__PURE__ */ jsxs("div", {
401
+ className: "w-full sm:w-[10%] flex justify-end sm:justify-center gap-1",
402
+ children: [/* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
403
+ asChild: true,
404
+ children: /* @__PURE__ */ jsx(Button, {
405
+ variant: "ghost",
406
+ size: "icon",
407
+ onClick: handleDuplicate,
408
+ className: "h-8 w-8",
409
+ children: /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" })
410
+ })
411
+ }), /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: tr("fluidgrids.builder.conditionBuilder.duplicateRuleTooltip", "Duplicate rule") }) })] }) }), /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
412
+ asChild: true,
413
+ children: /* @__PURE__ */ jsx(Button, {
414
+ variant: "ghost",
415
+ size: "icon",
416
+ onClick: handleRemove,
417
+ className: "h-8 w-8 text-destructive hover:text-destructive/90 hover:bg-destructive/10",
418
+ children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
419
+ })
420
+ }), /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: tr("fluidgrids.builder.conditionBuilder.removeRuleTooltip", "Remove rule") }) })] }) })]
421
+ })
422
+ ]
423
+ })
424
+ })
425
+ });
426
+ }
427
+ if (node.type === "group") {
428
+ const { combinator, children } = node;
429
+ const isRoot = path.length === 1 && path[0] === "root";
430
+ const hasChildren = children.length > 0;
431
+ const handleCombinatorChange = (value) => {
432
+ handleUpdate({ combinator: value });
433
+ };
434
+ const handleAddRuleClick = () => onAddRule(node.id);
435
+ const handleAddGroupClick = () => onAddGroup(node.id);
436
+ const toggleExpanded = () => setIsExpanded(!isExpanded);
437
+ const getBgColor = () => {
438
+ if (isRoot) return "bg-background";
439
+ return level % 2 === 0 ? "bg-muted/30" : "bg-background";
440
+ };
441
+ return /* @__PURE__ */ jsx("div", {
442
+ className: `rounded-lg border ${isRoot ? "border-primary/30" : "border-muted-foreground/20"} ${getBgColor()} transition-all`,
443
+ children: /* @__PURE__ */ jsxs("div", {
444
+ className: "p-3",
445
+ children: [/* @__PURE__ */ jsxs("div", {
446
+ className: "flex items-center gap-2 mb-2",
447
+ children: [
448
+ hasChildren && /* @__PURE__ */ jsx(Button, {
449
+ variant: "ghost",
450
+ size: "icon",
451
+ onClick: toggleExpanded,
452
+ className: "h-7 w-7 p-0",
453
+ children: isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
454
+ }),
455
+ /* @__PURE__ */ jsxs("div", {
456
+ className: "flex items-center",
457
+ children: [/* @__PURE__ */ jsx(Badge, {
458
+ variant: combinator === "AND" ? "default" : "secondary",
459
+ className: "mr-2 px-2 py-0.5 text-xs font-medium",
460
+ children: combinator === "AND" ? tr("fluidgrids.builder.conditionBuilder.combinatorAnd", "AND") : tr("fluidgrids.builder.conditionBuilder.combinatorOr", "OR")
461
+ }), /* @__PURE__ */ jsxs(Select, {
462
+ value: combinator,
463
+ onValueChange: handleCombinatorChange,
464
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
465
+ className: "w-[80px] h-7 text-xs",
466
+ children: /* @__PURE__ */ jsx(SelectValue, {})
467
+ }), /* @__PURE__ */ jsxs(SelectContent, { children: [/* @__PURE__ */ jsx(SelectItem, {
468
+ value: "AND",
469
+ children: tr("fluidgrids.builder.conditionBuilder.combinatorAnd", "AND")
470
+ }), /* @__PURE__ */ jsx(SelectItem, {
471
+ value: "OR",
472
+ children: tr("fluidgrids.builder.conditionBuilder.combinatorOr", "OR")
473
+ })] })]
474
+ })]
475
+ }),
476
+ /* @__PURE__ */ jsxs("div", {
477
+ className: "flex items-center gap-1 ml-auto",
478
+ children: [
479
+ /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
480
+ asChild: true,
481
+ children: /* @__PURE__ */ jsxs(Button, {
482
+ onClick: handleAddRuleClick,
483
+ variant: "outline",
484
+ size: "sm",
485
+ className: "h-7 text-xs",
486
+ children: [
487
+ /* @__PURE__ */ jsx(Plus, { className: "mr-1 h-3 w-3" }),
488
+ " ",
489
+ tr("fluidgrids.builder.conditionBuilder.addRuleButton", "Rule")
490
+ ]
491
+ })
492
+ }), /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: tr("fluidgrids.builder.conditionBuilder.addRuleTooltip", "Add a new rule") }) })] }) }),
493
+ /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
494
+ asChild: true,
495
+ children: /* @__PURE__ */ jsxs(Button, {
496
+ onClick: handleAddGroupClick,
497
+ variant: "outline",
498
+ size: "sm",
499
+ className: "h-7 text-xs",
500
+ children: [
501
+ /* @__PURE__ */ jsx(Layers, { className: "mr-1 h-3 w-3" }),
502
+ " ",
503
+ tr("fluidgrids.builder.conditionBuilder.addGroupButton", "Group")
504
+ ]
505
+ })
506
+ }), /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: tr("fluidgrids.builder.conditionBuilder.addGroupTooltip", "Add a nested group") }) })] }) }),
507
+ !isRoot && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
508
+ asChild: true,
509
+ children: /* @__PURE__ */ jsx(Button, {
510
+ variant: "ghost",
511
+ size: "icon",
512
+ onClick: handleRemove,
513
+ className: "h-7 w-7 text-destructive hover:text-destructive/90 hover:bg-destructive/10",
514
+ children: /* @__PURE__ */ jsx(Trash2, { className: "h-3 w-3" })
515
+ })
516
+ }), /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: tr("fluidgrids.builder.conditionBuilder.removeGroupTooltip", "Remove group") }) })] }) })
517
+ ]
518
+ })
519
+ ]
520
+ }), isExpanded && /* @__PURE__ */ jsxs("div", {
521
+ className: `space-y-3 mt-3 ${!isRoot ? "pl-4 border-l-2 border-muted/50" : ""}`,
522
+ children: [children.length === 0 && /* @__PURE__ */ jsxs("div", {
523
+ className: "flex items-center gap-2 p-3 text-sm text-muted-foreground bg-muted/20 rounded-md",
524
+ children: [/* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("p", { children: tr("fluidgrids.builder.conditionBuilder.emptyGroupMessage", "Group is empty. Add a rule or group to get started.") })]
525
+ }), children.map((childNode) => /* @__PURE__ */ jsx(ConditionNodeDisplay, {
526
+ node: childNode,
527
+ path: [...path, childNode.id],
528
+ fieldMap,
529
+ parsedFields,
530
+ onUpdateNode,
531
+ onRemoveNode,
532
+ onAddRule,
533
+ onAddGroup,
534
+ onDuplicateNode,
535
+ level: level + 1
536
+ }, childNode.id))]
537
+ })]
538
+ })
539
+ });
540
+ }
541
+ return null;
542
+ };
543
+ const ConditionBuilder$1 = ({ outputSchema, initialCondition, onConditionChange, predefinedFields }) => {
544
+ const tr = useTr();
545
+ const [conditionTree, setConditionTree] = useState(() => initialCondition || createEmptyGroup("root"));
546
+ const [showDebug, setShowDebug] = useState(false);
547
+ const parsedFields = useMemo(() => {
548
+ if (predefinedFields && predefinedFields.length > 0) return predefinedFields;
549
+ return parseSchema(outputSchema);
550
+ }, [outputSchema, predefinedFields]);
551
+ const fieldMap = useMemo(() => {
552
+ return new Map(parsedFields.map((f) => [f.path, f.type]));
553
+ }, [parsedFields]);
554
+ useEffect(() => {
555
+ onConditionChange(conditionTree);
556
+ }, [conditionTree, onConditionChange]);
557
+ const handleUpdateNode = useCallback((nodeId, updates) => {
558
+ setConditionTree((prevTree) => {
559
+ return findAndModifyNode(prevTree, nodeId, (node) => {
560
+ const validUpdates = {};
561
+ if ("field" in updates) validUpdates.field = updates.field;
562
+ if ("operator" in updates) validUpdates.operator = updates.operator;
563
+ if ("value" in updates) validUpdates.value = updates.value;
564
+ if ("combinator" in updates) validUpdates.combinator = updates.combinator;
565
+ if ("children" in updates) validUpdates.children = updates.children;
566
+ return {
567
+ ...node,
568
+ ...validUpdates
569
+ };
570
+ });
571
+ });
572
+ }, []);
573
+ const handleRemoveNode = useCallback((id) => {
574
+ if (id === "root") {
575
+ console.warn("Cannot remove the root node.");
576
+ return;
577
+ }
578
+ setConditionTree((prevTree) => {
579
+ return findAndModifyNode(prevTree, id, () => null);
580
+ });
581
+ }, []);
582
+ const handleAddRule = useCallback((parentId) => {
583
+ const newRule = createEmptyRule();
584
+ setConditionTree((prevTree) => findAndAddNode(prevTree, parentId, newRule));
585
+ }, []);
586
+ const handleAddGroup = useCallback((parentId) => {
587
+ const newGroup = createEmptyGroup();
588
+ setConditionTree((prevTree) => findAndAddNode(prevTree, parentId, newGroup));
589
+ }, []);
590
+ const handleDuplicateNode = useCallback((id) => {
591
+ setConditionTree((prevTree) => {
592
+ let nodeToDuplicate = null;
593
+ findAndModifyNode(prevTree, id, (node) => {
594
+ nodeToDuplicate = JSON.parse(JSON.stringify(node));
595
+ return node;
596
+ });
597
+ if (!nodeToDuplicate) return prevTree;
598
+ const findParent = (node, targetId) => {
599
+ if (node.type === "group") for (const child of node.children) {
600
+ if (child.id === targetId) return node.id;
601
+ const result = findParent(child, targetId);
602
+ if (result) return result;
603
+ }
604
+ return null;
605
+ };
606
+ const parentId = findParent(prevTree, id) || "root";
607
+ const assignNewIds = (node) => {
608
+ const newId = generateId();
609
+ if (node.type === "rule") return {
610
+ ...node,
611
+ id: newId
612
+ };
613
+ else return {
614
+ ...node,
615
+ id: newId,
616
+ children: node.children.map((child) => assignNewIds(child))
617
+ };
618
+ };
619
+ const duplicateWithNewIds = assignNewIds(nodeToDuplicate);
620
+ return findAndAddNode(prevTree, parentId, duplicateWithNewIds);
621
+ });
622
+ }, []);
623
+ const handleCopyToClipboard = useCallback(() => {
624
+ navigator.clipboard.writeText(JSON.stringify(conditionTree, null, 2)).then(() => {
625
+ toast.info(tr("fluidgrids.builder.conditionBuilder.copiedToClipboardToast", "Condition tree copied to clipboard!"));
626
+ }).catch((err) => {
627
+ console.error("Failed to copy: ", err);
628
+ });
629
+ }, [conditionTree, tr]);
630
+ return /* @__PURE__ */ jsxs("div", {
631
+ className: "space-y-4 p-4 bg-background border rounded-lg shadow-sm",
632
+ children: [
633
+ /* @__PURE__ */ jsxs("div", {
634
+ className: "flex items-center justify-between mb-4",
635
+ children: [/* @__PURE__ */ jsxs("div", {
636
+ className: "flex items-center gap-2",
637
+ children: [/* @__PURE__ */ jsx("h2", {
638
+ className: "text-lg font-semibold",
639
+ children: tr("fluidgrids.builder.conditionBuilder.title", "Condition Builder")
640
+ }), /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
641
+ asChild: true,
642
+ children: /* @__PURE__ */ jsx(Button, {
643
+ variant: "ghost",
644
+ size: "icon",
645
+ className: "h-6 w-6",
646
+ children: /* @__PURE__ */ jsx(Info, { className: "h-4 w-4" })
647
+ })
648
+ }), /* @__PURE__ */ jsx(TooltipContent, {
649
+ className: "max-w-sm",
650
+ children: /* @__PURE__ */ jsx("p", { children: tr("fluidgrids.builder.conditionBuilder.infoTooltip", "Build complex query conditions by adding rules and groups. Rules are individual conditions, while groups combine multiple conditions with AND/OR logic.") })
651
+ })] }) })]
652
+ }), /* @__PURE__ */ jsxs("div", {
653
+ className: "flex items-center gap-2",
654
+ children: [/* @__PURE__ */ jsx(Button, {
655
+ variant: "outline",
656
+ size: "sm",
657
+ onClick: () => setShowDebug(!showDebug),
658
+ className: "text-xs",
659
+ children: showDebug ? tr("fluidgrids.builder.conditionBuilder.hideJsonButton", "Hide JSON") : tr("fluidgrids.builder.conditionBuilder.showJsonButton", "Show JSON")
660
+ }), /* @__PURE__ */ jsxs(Button, {
661
+ variant: "outline",
662
+ size: "sm",
663
+ onClick: handleCopyToClipboard,
664
+ className: "text-xs",
665
+ children: [
666
+ /* @__PURE__ */ jsx(Copy, { className: "h-3 w-3 mr-1" }),
667
+ " ",
668
+ tr("fluidgrids.builder.conditionBuilder.copyJsonButton", "Copy JSON")
669
+ ]
670
+ })]
671
+ })]
672
+ }),
673
+ /* @__PURE__ */ jsx("div", {
674
+ className: "relative",
675
+ children: /* @__PURE__ */ jsx(ScrollArea, {
676
+ className: "max-h-[600px] pr-4",
677
+ children: /* @__PURE__ */ jsx(ConditionNodeDisplay, {
678
+ node: conditionTree,
679
+ path: ["root"],
680
+ fieldMap,
681
+ parsedFields,
682
+ onUpdateNode: handleUpdateNode,
683
+ onRemoveNode: handleRemoveNode,
684
+ onAddRule: handleAddRule,
685
+ onAddGroup: handleAddGroup,
686
+ onDuplicateNode: handleDuplicateNode,
687
+ level: 0
688
+ })
689
+ })
690
+ }),
691
+ showDebug && /* @__PURE__ */ jsxs("div", {
692
+ className: "mt-6 border-t pt-4",
693
+ children: [/* @__PURE__ */ jsxs("div", {
694
+ className: "flex items-center justify-between mb-2",
695
+ children: [/* @__PURE__ */ jsx(Label, {
696
+ className: "text-sm font-medium",
697
+ children: tr("fluidgrids.builder.conditionBuilder.debugJsonLabel", "Condition Tree JSON:")
698
+ }), /* @__PURE__ */ jsxs(Button, {
699
+ variant: "ghost",
700
+ size: "sm",
701
+ onClick: handleCopyToClipboard,
702
+ className: "h-7 text-xs",
703
+ children: [
704
+ /* @__PURE__ */ jsx(Copy, { className: "h-3 w-3 mr-1" }),
705
+ " ",
706
+ tr("fluidgrids.builder.conditionBuilder.copyButton", "Copy")
707
+ ]
708
+ })]
709
+ }), /* @__PURE__ */ jsx("div", {
710
+ className: "relative",
711
+ children: /* @__PURE__ */ jsx(ScrollArea, {
712
+ className: "h-[200px]",
713
+ children: /* @__PURE__ */ jsx("pre", {
714
+ className: "p-4 bg-muted rounded-md text-xs font-mono",
715
+ children: /* @__PURE__ */ jsx("code", { children: JSON.stringify(conditionTree, null, 2) })
716
+ })
717
+ })
718
+ })]
719
+ })
720
+ ]
721
+ });
722
+ };
723
+
724
+ // src/builder/components/flow-builder/components/edges/conditionBuilder/graphql-condition-builder.tsx
725
+ const Alert = ({ children, variant, className }) => /* @__PURE__ */ jsx("div", {
726
+ className: `relative w-full rounded-lg border p-4 ${variant === "destructive" ? "border-destructive/50 text-destructive bg-destructive/10" : "border-border"} ${className || ""}`,
727
+ children: /* @__PURE__ */ jsx("div", {
728
+ className: "flex gap-3",
729
+ children
730
+ })
731
+ });
732
+ const AlertTitle = ({ children }) => /* @__PURE__ */ jsx("h5", {
733
+ className: "mb-1 font-medium leading-none tracking-tight",
734
+ children
735
+ });
736
+ const AlertDescription = ({ children }) => /* @__PURE__ */ jsx("div", {
737
+ className: "text-sm opacity-90",
738
+ children
739
+ });
740
+ const findTypeInSchema = (types, typeName) => {
741
+ return types[typeName];
742
+ };
743
+ const mapGraphQLTypeToJSONType = (graphqlType) => {
744
+ return {
745
+ String: "string",
746
+ Int: "integer",
747
+ Float: "number",
748
+ Boolean: "boolean",
749
+ ID: "string"
750
+ }[graphqlType] || "string";
751
+ };
752
+ const extractFields = (schemaToExtract) => {
753
+ const extractedFields = [];
754
+ const processObject = (obj, path = "") => {
755
+ if (!obj || typeof obj !== "object") return;
756
+ if (obj.type) extractedFields.push({
757
+ path,
758
+ type: obj.type
759
+ });
760
+ if (obj.type === "object" && obj.properties) Object.keys(obj.properties).forEach((key) => {
761
+ const newPath = path ? `${path}.${key}` : key;
762
+ const property = obj.properties[key];
763
+ extractedFields.push({
764
+ path: newPath,
765
+ type: property.type
766
+ });
767
+ if (property.type === "object" && property.properties) processObject(property, newPath);
768
+ if (property.type === "array" && property.items) {
769
+ extractedFields.push({
770
+ path: newPath,
771
+ type: "array"
772
+ });
773
+ if (property.items.type === "object" && property.items.properties) Object.keys(property.items.properties).forEach((itemKey) => {
774
+ const itemPath = `${newPath}.${itemKey}`;
775
+ const itemProperty = property.items.properties[itemKey];
776
+ extractedFields.push({
777
+ path: itemPath,
778
+ type: itemProperty.type
779
+ });
780
+ if (itemProperty.type === "object" && itemProperty.properties) processObject(itemProperty, itemPath);
781
+ });
782
+ }
783
+ });
784
+ };
785
+ processObject(schemaToExtract);
786
+ extractedFields.sort((a, b) => a.path.localeCompare(b.path));
787
+ return extractedFields.filter((field, index, self) => field.path && self.findIndex((f) => f.path === field.path) === index);
788
+ };
789
+ const buildSchemaForOperation = (types, typeObj) => {
790
+ if (typeObj.name === "GmailSearchResult") return {
791
+ type: "object",
792
+ properties: {
793
+ emails: {
794
+ type: "array",
795
+ items: {
796
+ type: "object",
797
+ properties: {
798
+ metadata: {
799
+ type: "object",
800
+ properties: {
801
+ id: { type: "string" },
802
+ threadId: { type: "string" },
803
+ subject: { type: "string" },
804
+ from: { type: "string" },
805
+ to: { type: "string" },
806
+ date: { type: "string" },
807
+ labels: {
808
+ type: "array",
809
+ items: { type: "string" }
810
+ }
811
+ }
812
+ },
813
+ snippet: { type: "string" },
814
+ body: { type: "string" },
815
+ error: { type: "string" }
816
+ }
817
+ }
818
+ },
819
+ error: { type: "string" }
820
+ }
821
+ };
822
+ if (typeObj.name === "GmailBatchActionResult") return {
823
+ type: "object",
824
+ properties: {
825
+ succeededIds: {
826
+ type: "array",
827
+ items: { type: "string" }
828
+ },
829
+ failedItems: {
830
+ type: "array",
831
+ items: {
832
+ type: "object",
833
+ properties: {
834
+ messageId: { type: "string" },
835
+ error: { type: "string" }
836
+ }
837
+ }
838
+ }
839
+ }
840
+ };
841
+ const builtSchema = {
842
+ type: "object",
843
+ properties: {}
844
+ };
845
+ const buildNestedSchema = (nestedTypeObj) => {
846
+ if (!nestedTypeObj) return { type: "string" };
847
+ const result = { type: nestedTypeObj.kind === "scalar" ? mapGraphQLTypeToJSONType(nestedTypeObj.name) : "object" };
848
+ if (nestedTypeObj.kind === "type" && nestedTypeObj.fields) {
849
+ result.properties = {};
850
+ Object.keys(nestedTypeObj.fields).forEach((fieldName) => {
851
+ const field = nestedTypeObj.fields[fieldName];
852
+ const fieldType = field.type;
853
+ const fieldTypeObj = findTypeInSchema(types, fieldType);
854
+ if (!fieldTypeObj) return;
855
+ if (fieldTypeObj.kind === "scalar") result.properties[fieldName] = {
856
+ type: mapGraphQLTypeToJSONType(fieldTypeObj.name),
857
+ description: field.description || ""
858
+ };
859
+ else if (fieldTypeObj.kind === "type" && field.isList) result.properties[fieldName] = {
860
+ type: "array",
861
+ description: field.description || "",
862
+ items: buildNestedSchema(fieldTypeObj)
863
+ };
864
+ else if (fieldTypeObj.kind === "type") result.properties[fieldName] = buildNestedSchema(fieldTypeObj);
865
+ });
866
+ }
867
+ return result;
868
+ };
869
+ if (typeObj.kind === "type" && typeObj.fields) Object.keys(typeObj.fields).forEach((fieldName) => {
870
+ const field = typeObj.fields[fieldName];
871
+ const fieldType = field.type;
872
+ const fieldTypeObj = findTypeInSchema(types, fieldType);
873
+ if (!fieldTypeObj) return;
874
+ if (fieldTypeObj.kind === "scalar") builtSchema.properties[fieldName] = {
875
+ type: mapGraphQLTypeToJSONType(fieldTypeObj.name),
876
+ description: field.description || ""
877
+ };
878
+ else if (field.isList) builtSchema.properties[fieldName] = {
879
+ type: "array",
880
+ items: buildNestedSchema(fieldTypeObj)
881
+ };
882
+ else if (fieldTypeObj.kind === "type") builtSchema.properties[fieldName] = buildNestedSchema(fieldTypeObj);
883
+ });
884
+ return builtSchema;
885
+ };
886
+ const GraphQLConditionBuilder = ({ introspectionData, operationName, initialCondition, onConditionChange }) => {
887
+ const tr = useTr();
888
+ const { schema, fields, error } = useMemo(() => {
889
+ try {
890
+ if (!introspectionData || !operationName) return {
891
+ schema: null,
892
+ fields: [],
893
+ error: null
894
+ };
895
+ const queryType = introspectionData.queryType;
896
+ const mutationType = introspectionData.mutationType;
897
+ const queryTypeObj = introspectionData.types[queryType];
898
+ const mutationTypeObj = mutationType ? introspectionData.types[mutationType] : void 0;
899
+ if (queryTypeObj && queryTypeObj.fields && queryTypeObj.fields[operationName]) {
900
+ const returnType = queryTypeObj.fields[operationName].type;
901
+ const returnTypeObj = findTypeInSchema(introspectionData.types, returnType);
902
+ if (!returnTypeObj) return {
903
+ schema: null,
904
+ fields: [],
905
+ error: `Return type "${returnType}" not found in schema`
906
+ };
907
+ const builtSchema = buildSchemaForOperation(introspectionData.types, returnTypeObj);
908
+ return {
909
+ schema: builtSchema,
910
+ fields: extractFields(builtSchema),
911
+ error: null
912
+ };
913
+ }
914
+ if (mutationTypeObj && mutationTypeObj.fields && mutationTypeObj.fields[operationName]) {
915
+ const returnType = mutationTypeObj.fields[operationName].type;
916
+ const returnTypeObj = findTypeInSchema(introspectionData.types, returnType);
917
+ if (!returnTypeObj) return {
918
+ schema: null,
919
+ fields: [],
920
+ error: `Return type "${returnType}" not found in schema`
921
+ };
922
+ const builtSchema = buildSchemaForOperation(introspectionData.types, returnTypeObj);
923
+ return {
924
+ schema: builtSchema,
925
+ fields: extractFields(builtSchema),
926
+ error: null
927
+ };
928
+ }
929
+ return {
930
+ schema: null,
931
+ fields: [],
932
+ error: `Operation "${operationName}" not found in schema`
933
+ };
934
+ } catch (err) {
935
+ console.error("Error building schema:", err);
936
+ return {
937
+ schema: null,
938
+ fields: [],
939
+ error: "Failed to build schema from introspection data"
940
+ };
941
+ }
942
+ }, [introspectionData, operationName]);
943
+ useEffect(() => {
944
+ if (schema) {}
945
+ }, [schema, fields]);
946
+ if (error) return /* @__PURE__ */ jsxs(Alert, {
947
+ variant: "destructive",
948
+ children: [
949
+ /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
950
+ /* @__PURE__ */ jsx(AlertTitle, { children: tr("fluidgrids.builder.graphqlConditionBuilder.errorTitle", "Error") }),
951
+ /* @__PURE__ */ jsx(AlertDescription, { children: error })
952
+ ]
953
+ });
954
+ if (!schema) return /* @__PURE__ */ jsx("div", { children: tr("fluidgrids.builder.graphqlConditionBuilder.loadingSchema", "Loading schema...") });
955
+ return /* @__PURE__ */ jsx(ConditionBuilder$1, {
956
+ outputSchema: schema,
957
+ initialCondition,
958
+ onConditionChange,
959
+ predefinedFields: fields
960
+ });
961
+ };
962
+
963
+ // src/builder/components/flow-builder/components/edges/conditionBuilder/custom-condition-tree-converter.ts
964
+ function buildConditionString(conditionJson) {
965
+ const getFallback = (operator, isLast) => {
966
+ if (!isLast) return "{}";
967
+ if (operator === "contains") return `''`;
968
+ return "0";
969
+ };
970
+ const parseField = (field, operator) => {
971
+ const parts = field.split(".");
972
+ if (parts[0] === "emails" && parts.length > 1) {
973
+ const arrayPath = parts[0];
974
+ const remainingPath = parts.slice(1).join(".");
975
+ if (operator === "contains" || operator === "==") return `output.${arrayPath}.some(item => item.${remainingPath})`;
976
+ else if (operator === "!=" || operator === "isNotNull") return `output.${arrayPath}.some(item => item.${remainingPath})`;
977
+ else return `output.${arrayPath}[0]?.${remainingPath}`;
978
+ }
979
+ return `output${parts.map((key, i) => {
980
+ const isLast = i === parts.length - 1;
981
+ return `.get('${key}', ${getFallback(operator, isLast)})`;
982
+ }).join("")}`;
983
+ };
984
+ const parseRule = (rule) => {
985
+ const { field, operator, value } = rule;
986
+ const parts = field.split(".");
987
+ if (parts[0] === "emails" && parts.length > 1) {
988
+ const remainingPath = parts.slice(1).join(".");
989
+ const stringValue = typeof value === "string" ? `'${value}'` : value;
990
+ if (operator === "contains") return `output.emails.some(item => item.${remainingPath}?.includes(${stringValue}))`;
991
+ else if (operator === "==") return `output.emails.some(item => item.${remainingPath} === ${stringValue})`;
992
+ else if (operator === "!=") return `output.emails.some(item => item.${remainingPath} !== ${stringValue})`;
993
+ else if (operator === ">") return `output.emails.some(item => item.${remainingPath} > ${stringValue})`;
994
+ else if (operator === ">=") return `output.emails.some(item => item.${remainingPath} >= ${stringValue})`;
995
+ else if (operator === "<") return `output.emails.some(item => item.${remainingPath} < ${stringValue})`;
996
+ else if (operator === "<=") return `output.emails.some(item => item.${remainingPath} <= ${stringValue})`;
997
+ else if (operator === "isNull") return `output.emails.some(item => item.${remainingPath} === null || item.${remainingPath} === undefined)`;
998
+ else if (operator === "isNotNull") return `output.emails.some(item => item.${remainingPath} !== null && item.${remainingPath} !== undefined)`;
999
+ else if (operator === "hasProperty") return `output.emails.some(item => '${value}' in item.${remainingPath})`;
1000
+ }
1001
+ const fieldStr = parseField(field, operator);
1002
+ const stringValue = typeof value === "string" ? `'${value}'` : value;
1003
+ const opMap = {
1004
+ contains: "includes",
1005
+ "==": "==",
1006
+ "!=": "!=",
1007
+ ">": ">",
1008
+ "<": "<",
1009
+ ">=": ">=",
1010
+ "<=": "<=",
1011
+ hasProperty: "hasProperty"
1012
+ };
1013
+ if (operator === "contains") return `${fieldStr}.includes(${stringValue})`;
1014
+ else if (operator === "hasProperty") return `'${value}' in output${field.split(".").map((part) => `.get('${part}', {})`).join("")}`;
1015
+ else return `${fieldStr} ${opMap[operator] ?? operator} ${stringValue}`;
1016
+ };
1017
+ const parseGroup = (group) => {
1018
+ const combinator = group.combinator.toLowerCase();
1019
+ return group.children.map((child) => {
1020
+ if (child.type === "rule") return parseRule(child);
1021
+ else return `(${parseGroup(child)})`;
1022
+ }).join(` ${combinator} `);
1023
+ };
1024
+ return parseGroup(conditionJson);
1025
+ }
1026
+
1027
+ // src/builder/components/flow-builder/components/edges/conditionBuilder/index.tsx
1028
+ function convertToIntrospectionData(schema) {
1029
+ if (!schema.queryType) return null;
1030
+ return {
1031
+ queryType: schema.queryType,
1032
+ mutationType: schema.mutationType ?? void 0,
1033
+ types: Object.fromEntries(Object.entries(schema.types).map(([key, value]) => [key, {
1034
+ name: value.name,
1035
+ kind: value.kind,
1036
+ fields: value.fields ? Object.fromEntries(Object.entries(value.fields).map(([fieldKey, fieldValue]) => [fieldKey, {
1037
+ type: fieldValue.type,
1038
+ isList: fieldValue.isList,
1039
+ isNonNull: fieldValue.isNonNull
1040
+ }])) : void 0
1041
+ }]))
1042
+ };
1043
+ }
1044
+ function ConditionBuilder({ sourceNode, sourceOperation, edgeId, schema }) {
1045
+ const tr = useTr();
1046
+ const { setEdges } = useReactFlow();
1047
+ const [conditionTree, setConditionTree] = useState(null);
1048
+ const [conditionString, setConditionString] = useState("");
1049
+ const selectedOperation = sourceOperation || sourceNode?.data?.operation_name || "";
1050
+ const rawSchema = schema || sourceNode?.data?.schema || sourceNode?.data?.nodeData?.schema || null;
1051
+ const introspectionData = useMemo(() => {
1052
+ if (!rawSchema) return null;
1053
+ return convertToIntrospectionData(rawSchema);
1054
+ }, [rawSchema]);
1055
+ const handleConditionChange = (newTree) => {
1056
+ setConditionTree(newTree);
1057
+ try {
1058
+ const condString = buildConditionString(newTree);
1059
+ setConditionString(condString);
1060
+ } catch (error) {
1061
+ console.error("Error building condition string:", error);
1062
+ }
1063
+ };
1064
+ useEffect(() => {
1065
+ setEdges((edges) => {
1066
+ return edges.map((edge) => {
1067
+ if (edge.id === edgeId) return {
1068
+ ...edge,
1069
+ condition: conditionString
1070
+ };
1071
+ else return edge;
1072
+ });
1073
+ });
1074
+ }, [
1075
+ conditionString,
1076
+ edgeId,
1077
+ setEdges
1078
+ ]);
1079
+ if (!introspectionData) return /* @__PURE__ */ jsxs("div", {
1080
+ className: "flex items-center justify-center min-h-[200px] text-muted-foreground",
1081
+ children: [/* @__PURE__ */ jsx(AlertCircle, { className: "h-6 w-6 mr-2" }), /* @__PURE__ */ jsx("span", { children: tr("fluidgrids.builder.conditionBuilder.noSchema", "No schema available for this node. Configure the node schema first.") })]
1082
+ });
1083
+ return /* @__PURE__ */ jsx("div", {
1084
+ className: "container mx-auto py-8",
1085
+ children: introspectionData && selectedOperation && /* @__PURE__ */ jsxs(Tabs, {
1086
+ defaultValue: "builder",
1087
+ className: "w-full",
1088
+ children: [
1089
+ /* @__PURE__ */ jsxs(TabsList, {
1090
+ className: "mb-4",
1091
+ children: [/* @__PURE__ */ jsx(TabsTrigger, {
1092
+ value: "builder",
1093
+ children: tr("fluidgrids.builder.conditionBuilder.tabBuilder", "Condition Builder")
1094
+ }), /* @__PURE__ */ jsx(TabsTrigger, {
1095
+ value: "output",
1096
+ children: tr("fluidgrids.builder.conditionBuilder.tabOutput", "Generated Output")
1097
+ })]
1098
+ }),
1099
+ /* @__PURE__ */ jsx(TabsContent, {
1100
+ value: "builder",
1101
+ children: /* @__PURE__ */ jsx(GraphQLConditionBuilder, {
1102
+ introspectionData,
1103
+ operationName: selectedOperation,
1104
+ initialCondition: conditionTree || {
1105
+ id: "root",
1106
+ type: "group",
1107
+ combinator: "AND",
1108
+ children: []
1109
+ },
1110
+ onConditionChange: handleConditionChange
1111
+ })
1112
+ }),
1113
+ /* @__PURE__ */ jsx(TabsContent, {
1114
+ value: "output",
1115
+ children: /* @__PURE__ */ jsxs(Card, { children: [/* @__PURE__ */ jsxs(CardHeader, { children: [/* @__PURE__ */ jsx(CardTitle, { children: tr("fluidgrids.builder.conditionBuilder.generatedConditionTitle", "Generated Condition") }), /* @__PURE__ */ jsxs(CardDescription, { children: [
1116
+ tr("fluidgrids.builder.conditionBuilder.generatedConditionDescriptionStart", "The condition string that will be used to filter"),
1117
+ " ",
1118
+ selectedOperation,
1119
+ " ",
1120
+ tr("fluidgrids.builder.conditionBuilder.generatedConditionDescriptionEnd", "results")
1121
+ ] })] }), /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(ScrollArea, {
1122
+ className: "h-[300px] w-full rounded-md border p-4",
1123
+ children: /* @__PURE__ */ jsx("pre", {
1124
+ className: "font-mono text-sm",
1125
+ children: conditionString || tr("fluidgrids.builder.conditionBuilder.noConditionYet", "No condition generated yet")
1126
+ })
1127
+ }) })] })
1128
+ })
1129
+ ]
1130
+ })
1131
+ });
1132
+ }
1133
+
1134
+ export { ConditionBuilder as default };