@burdenoff/fluidgrids-fe-sdk 2026.918.2 → 2026.922.1
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.
- package/dist/{WorkflowBuilder-GFFW5WSB.js → WorkflowBuilder-RG4QXBZN.js} +4 -4
- package/dist/{WorkflowBuilder-GFFW5WSB.js.map → WorkflowBuilder-RG4QXBZN.js.map} +1 -1
- package/dist/{chunk-TOFLHYUQ.js → chunk-EFLYJTQI.js} +3 -3
- package/dist/{chunk-TOFLHYUQ.js.map → chunk-EFLYJTQI.js.map} +1 -1
- package/dist/{chunk-77Y5WTBD.js → chunk-GCUAXFMW.js} +3 -3
- package/dist/{chunk-77Y5WTBD.js.map → chunk-GCUAXFMW.js.map} +1 -1
- package/dist/{chunk-YH2QC6D6.js → chunk-ND4ACNAW.js} +3 -3
- package/dist/{chunk-YH2QC6D6.js.map → chunk-ND4ACNAW.js.map} +1 -1
- package/dist/{chunk-HY7K7SLI.js → chunk-XASNLRFQ.js} +415 -27
- package/dist/chunk-XASNLRFQ.js.map +1 -0
- package/dist/index.js +7 -7
- package/dist/templates.js +2 -2
- package/dist/workflow-builder.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-HY7K7SLI.js.map +0 -1
|
@@ -224,6 +224,245 @@ function stripSubmitActions(card) {
|
|
|
224
224
|
}
|
|
225
225
|
return result;
|
|
226
226
|
}
|
|
227
|
+
|
|
228
|
+
// src/builder/components/lib/expression-preview.ts
|
|
229
|
+
var PURE_EXPRESSION_REGEX = /^\{\{(.*)\}\}$/s;
|
|
230
|
+
var PURE_LEGACY_REGEX = /^\$\{(.*)\}$/s;
|
|
231
|
+
function containsExpressionSyntax(str) {
|
|
232
|
+
return typeof str === "string" && str.includes("{{");
|
|
233
|
+
}
|
|
234
|
+
function findEmbeddedExpressions(str) {
|
|
235
|
+
const matches = [];
|
|
236
|
+
let searchFrom = 0;
|
|
237
|
+
while (searchFrom < str.length) {
|
|
238
|
+
const start = str.indexOf("{{", searchFrom);
|
|
239
|
+
if (start === -1) break;
|
|
240
|
+
const end = str.indexOf("}}", start + 2);
|
|
241
|
+
if (end === -1) break;
|
|
242
|
+
matches.push({
|
|
243
|
+
full: str.slice(start, end + 2),
|
|
244
|
+
expression: str.slice(start + 2, end).trim()
|
|
245
|
+
});
|
|
246
|
+
searchFrom = end + 2;
|
|
247
|
+
}
|
|
248
|
+
return matches;
|
|
249
|
+
}
|
|
250
|
+
function toItems(value) {
|
|
251
|
+
if (value === void 0 || value === null) return [];
|
|
252
|
+
if (Array.isArray(value)) return value.map((entry) => ({ json: entry }));
|
|
253
|
+
return [{ json: value }];
|
|
254
|
+
}
|
|
255
|
+
var SAFE_GLOBALS = {
|
|
256
|
+
parseInt,
|
|
257
|
+
parseFloat,
|
|
258
|
+
isNaN,
|
|
259
|
+
isFinite,
|
|
260
|
+
Number,
|
|
261
|
+
String,
|
|
262
|
+
Boolean,
|
|
263
|
+
JSON,
|
|
264
|
+
Date,
|
|
265
|
+
Math,
|
|
266
|
+
Array,
|
|
267
|
+
Object,
|
|
268
|
+
console: {
|
|
269
|
+
log: () => void 0,
|
|
270
|
+
error: () => void 0,
|
|
271
|
+
warn: () => void 0
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
function buildExpressionSandbox(scope) {
|
|
275
|
+
const inputItems = toItems(scope.input);
|
|
276
|
+
const currentItem = inputItems[0] ?? { json: {} };
|
|
277
|
+
const itemsForNode = (nodeName) => toItems(scope.nodeOutputs[nodeName]);
|
|
278
|
+
const dollarNode = (nodeName) => {
|
|
279
|
+
const items = itemsForNode(nodeName);
|
|
280
|
+
const at = items[0] ?? { json: {} };
|
|
281
|
+
return {
|
|
282
|
+
item: at.json,
|
|
283
|
+
all: () => items,
|
|
284
|
+
first: () => items[0]?.json ?? {},
|
|
285
|
+
last: () => items[items.length - 1]?.json ?? {}
|
|
286
|
+
};
|
|
287
|
+
};
|
|
288
|
+
const nodeObject = {};
|
|
289
|
+
for (const nodeName of Object.keys(scope.nodeOutputs)) {
|
|
290
|
+
nodeObject[nodeName] = dollarNode(nodeName);
|
|
291
|
+
}
|
|
292
|
+
const now = /* @__PURE__ */ new Date();
|
|
293
|
+
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
294
|
+
return {
|
|
295
|
+
...SAFE_GLOBALS,
|
|
296
|
+
$json: currentItem.json,
|
|
297
|
+
$node: nodeObject,
|
|
298
|
+
$: dollarNode,
|
|
299
|
+
$items: (nodeName) => nodeName ? itemsForNode(nodeName) : inputItems,
|
|
300
|
+
$input: {
|
|
301
|
+
item: currentItem.json,
|
|
302
|
+
all: () => inputItems,
|
|
303
|
+
first: () => inputItems[0]?.json ?? {},
|
|
304
|
+
last: () => inputItems[inputItems.length - 1]?.json ?? {}
|
|
305
|
+
},
|
|
306
|
+
$workflow: {
|
|
307
|
+
id: scope.workflowKey,
|
|
308
|
+
name: scope.workflowKey,
|
|
309
|
+
version: scope.version
|
|
310
|
+
},
|
|
311
|
+
$execution: { id: scope.runId },
|
|
312
|
+
// Stubbed pending BOFF-7517 (Variables model) — mirrors the backend stub.
|
|
313
|
+
$vars: {},
|
|
314
|
+
// Never real env vars in the browser preview.
|
|
315
|
+
$env: {},
|
|
316
|
+
$now: now,
|
|
317
|
+
$today: today
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function evaluateBare(expression, sandbox) {
|
|
321
|
+
const paramNames = Object.keys(sandbox);
|
|
322
|
+
const paramValues = Object.values(sandbox);
|
|
323
|
+
const fn = new Function(
|
|
324
|
+
...paramNames,
|
|
325
|
+
`"use strict"; return (${expression});`
|
|
326
|
+
);
|
|
327
|
+
return fn(...paramValues);
|
|
328
|
+
}
|
|
329
|
+
function stringifyForInterpolation(value) {
|
|
330
|
+
if (value === null || value === void 0) return "";
|
|
331
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
332
|
+
return String(value);
|
|
333
|
+
}
|
|
334
|
+
function previewNewSyntax(str, scope) {
|
|
335
|
+
const sandbox = buildExpressionSandbox(scope);
|
|
336
|
+
const pure = PURE_EXPRESSION_REGEX.exec(str);
|
|
337
|
+
try {
|
|
338
|
+
if (pure) {
|
|
339
|
+
const expression = pure[1]?.trim();
|
|
340
|
+
if (!expression) {
|
|
341
|
+
return { isTemplate: true, error: "Empty expression" };
|
|
342
|
+
}
|
|
343
|
+
return { isTemplate: true, value: evaluateBare(expression, sandbox) };
|
|
344
|
+
}
|
|
345
|
+
let result = str;
|
|
346
|
+
for (const match of findEmbeddedExpressions(str)) {
|
|
347
|
+
if (!match.expression) continue;
|
|
348
|
+
const value = evaluateBare(match.expression, sandbox);
|
|
349
|
+
result = result.replace(match.full, stringifyForInterpolation(value));
|
|
350
|
+
}
|
|
351
|
+
return { isTemplate: true, value: result };
|
|
352
|
+
} catch (error) {
|
|
353
|
+
return {
|
|
354
|
+
isTemplate: true,
|
|
355
|
+
error: error instanceof Error ? error.message : String(error)
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
function previewLegacySyntax(str, scope) {
|
|
360
|
+
const sandbox = {
|
|
361
|
+
...SAFE_GLOBALS,
|
|
362
|
+
output: scope.input,
|
|
363
|
+
TriggerInput: {},
|
|
364
|
+
WorkflowState: Object.fromEntries(
|
|
365
|
+
Object.entries(scope.nodeOutputs).map(([nodeId, output]) => [
|
|
366
|
+
nodeId,
|
|
367
|
+
{ output, status: "COMPLETED" }
|
|
368
|
+
])
|
|
369
|
+
),
|
|
370
|
+
RunContext: {
|
|
371
|
+
runId: scope.runId ?? "preview",
|
|
372
|
+
workflowKey: scope.workflowKey ?? "preview",
|
|
373
|
+
version: scope.version ?? "1.0.0"
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
const pure = PURE_LEGACY_REGEX.exec(str);
|
|
377
|
+
try {
|
|
378
|
+
if (pure) {
|
|
379
|
+
const expression = pure[1]?.trim();
|
|
380
|
+
if (!expression) return { isTemplate: true, error: "Empty expression" };
|
|
381
|
+
return { isTemplate: true, value: evaluateBare(expression, sandbox) };
|
|
382
|
+
}
|
|
383
|
+
if (!str.includes("${")) {
|
|
384
|
+
return { isTemplate: false };
|
|
385
|
+
}
|
|
386
|
+
let result = str;
|
|
387
|
+
const templateRegex = /\$\{([^}]+)\}/g;
|
|
388
|
+
for (const match of str.matchAll(templateRegex)) {
|
|
389
|
+
const expression = match[1]?.trim();
|
|
390
|
+
if (!expression) continue;
|
|
391
|
+
const value = evaluateBare(expression, sandbox);
|
|
392
|
+
result = result.replace(match[0], stringifyForInterpolation(value));
|
|
393
|
+
}
|
|
394
|
+
return { isTemplate: true, value: result };
|
|
395
|
+
} catch (error) {
|
|
396
|
+
return {
|
|
397
|
+
isTemplate: true,
|
|
398
|
+
error: error instanceof Error ? error.message : String(error)
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function evaluateExpressionPreview(str, scope) {
|
|
403
|
+
if (typeof str !== "string" || str.trim() === "") {
|
|
404
|
+
return { isTemplate: false };
|
|
405
|
+
}
|
|
406
|
+
if (containsExpressionSyntax(str)) {
|
|
407
|
+
return previewNewSyntax(str, scope);
|
|
408
|
+
}
|
|
409
|
+
return previewLegacySyntax(str, scope);
|
|
410
|
+
}
|
|
411
|
+
var EXPRESSION_BUILTINS = [
|
|
412
|
+
{ insert: "$json", label: "$json", description: "Current item's data" },
|
|
413
|
+
{
|
|
414
|
+
insert: '$node["NodeName"]',
|
|
415
|
+
label: '$node["NodeName"]',
|
|
416
|
+
description: "Another node's current item"
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
insert: '$("NodeName")',
|
|
420
|
+
label: '$("NodeName")',
|
|
421
|
+
description: "Lineage helper: .item / .all() / .first() / .last()"
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
insert: "$items()",
|
|
425
|
+
label: "$items()",
|
|
426
|
+
description: "This node's input as a list of items"
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
insert: "$input",
|
|
430
|
+
label: "$input",
|
|
431
|
+
description: "Input helper: .item / .all() / .first() / .last()"
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
insert: "$workflow",
|
|
435
|
+
label: "$workflow",
|
|
436
|
+
description: "Workflow id / name / version"
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
insert: "$execution",
|
|
440
|
+
label: "$execution",
|
|
441
|
+
description: "Current execution id"
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
insert: "$vars",
|
|
445
|
+
label: "$vars",
|
|
446
|
+
description: "Workflow variables (coming soon)"
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
insert: "$env",
|
|
450
|
+
label: "$env",
|
|
451
|
+
description: "Allowlisted environment values"
|
|
452
|
+
},
|
|
453
|
+
{ insert: "$now", label: "$now", description: "Current date/time" },
|
|
454
|
+
{ insert: "$today", label: "$today", description: "Start of today" }
|
|
455
|
+
];
|
|
456
|
+
var AUTOCOMPLETE_LOOKBACK = 40;
|
|
457
|
+
function openExpressionPrefix(value, cursor) {
|
|
458
|
+
const windowStart = Math.max(0, cursor - AUTOCOMPLETE_LOOKBACK);
|
|
459
|
+
const before = value.slice(windowStart, cursor);
|
|
460
|
+
const openIndex = before.lastIndexOf("{{");
|
|
461
|
+
if (openIndex === -1) return null;
|
|
462
|
+
const between = before.slice(openIndex + 2);
|
|
463
|
+
if (between.includes("}}")) return null;
|
|
464
|
+
return between.trimStart();
|
|
465
|
+
}
|
|
227
466
|
function ExpressionEditor({
|
|
228
467
|
value,
|
|
229
468
|
onChange,
|
|
@@ -231,14 +470,18 @@ function ExpressionEditor({
|
|
|
231
470
|
className,
|
|
232
471
|
rows = 4,
|
|
233
472
|
label,
|
|
234
|
-
helpText
|
|
473
|
+
helpText,
|
|
474
|
+
nodeId
|
|
235
475
|
}) {
|
|
236
476
|
const tr = useTr();
|
|
237
477
|
const editorRef = useRef(null);
|
|
238
478
|
const [isFocused, setIsFocused] = useState(false);
|
|
479
|
+
const [suggestionsOpen, setSuggestionsOpen] = useState(false);
|
|
239
480
|
const handleChange = useCallback(
|
|
240
481
|
(e) => {
|
|
241
482
|
onChange(e.target.value);
|
|
483
|
+
const cursor = e.target.selectionStart;
|
|
484
|
+
setSuggestionsOpen(openExpressionPrefix(e.target.value, cursor) !== null);
|
|
242
485
|
},
|
|
243
486
|
[onChange]
|
|
244
487
|
);
|
|
@@ -260,6 +503,83 @@ function ExpressionEditor({
|
|
|
260
503
|
},
|
|
261
504
|
[value, onChange]
|
|
262
505
|
);
|
|
506
|
+
const applySuggestion = useCallback(
|
|
507
|
+
(insert) => {
|
|
508
|
+
const textarea = editorRef.current;
|
|
509
|
+
if (!textarea) {
|
|
510
|
+
insertTemplate(`{{ ${insert} }}`);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
const cursor = textarea.selectionStart;
|
|
514
|
+
const windowStart = Math.max(0, cursor - AUTOCOMPLETE_LOOKBACK);
|
|
515
|
+
const before = value.slice(windowStart, cursor);
|
|
516
|
+
const openIndex = before.lastIndexOf("{{");
|
|
517
|
+
if (openIndex === -1) {
|
|
518
|
+
insertTemplate(`{{ ${insert} }}`);
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const replaceStart = windowStart + openIndex;
|
|
522
|
+
const newValue = value.slice(0, replaceStart) + `{{ ${insert} }}` + value.slice(cursor);
|
|
523
|
+
onChange(newValue);
|
|
524
|
+
setSuggestionsOpen(false);
|
|
525
|
+
const cursorAfter = replaceStart + `{{ ${insert} }}`.length;
|
|
526
|
+
setTimeout(() => {
|
|
527
|
+
textarea.focus();
|
|
528
|
+
textarea.setSelectionRange(cursorAfter, cursorAfter);
|
|
529
|
+
}, 0);
|
|
530
|
+
},
|
|
531
|
+
[value, onChange, insertTemplate]
|
|
532
|
+
);
|
|
533
|
+
const cursorPos = editorRef.current?.selectionStart ?? value.length;
|
|
534
|
+
const filterText = suggestionsOpen ? openExpressionPrefix(value, cursorPos) ?? "" : "";
|
|
535
|
+
const suggestions = useMemo(() => {
|
|
536
|
+
if (!suggestionsOpen) return [];
|
|
537
|
+
const needle = filterText.toLowerCase();
|
|
538
|
+
return EXPRESSION_BUILTINS.filter(
|
|
539
|
+
(b) => b.label.toLowerCase().startsWith(needle || "$")
|
|
540
|
+
).slice(0, 8);
|
|
541
|
+
}, [suggestionsOpen, filterText]);
|
|
542
|
+
const logs = useFlowStore((s) => s.execution.logs);
|
|
543
|
+
const workflowKey = useFlowStore((s) => s.workflow.workflowKey);
|
|
544
|
+
const workflowVersion = useFlowStore((s) => s.workflow.version);
|
|
545
|
+
const previewScope = useMemo(() => {
|
|
546
|
+
const nodeOutputs = {};
|
|
547
|
+
let input = {};
|
|
548
|
+
let runId;
|
|
549
|
+
for (const log of logs) {
|
|
550
|
+
if (log.status !== "completed" || !log.output) continue;
|
|
551
|
+
nodeOutputs[log.nodeId] = log.output;
|
|
552
|
+
if (log.nodeId === nodeId) {
|
|
553
|
+
input = log.inputArgs ?? {};
|
|
554
|
+
runId = log.runId;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return { input, nodeOutputs, workflowKey, version: workflowVersion, runId };
|
|
558
|
+
}, [logs, nodeId, workflowKey, workflowVersion]);
|
|
559
|
+
const hasPreviewData = Object.keys(previewScope.input).length > 0;
|
|
560
|
+
const [preview, setPreview] = useState(null);
|
|
561
|
+
useEffect(() => {
|
|
562
|
+
if (!nodeId || !value.trim()) {
|
|
563
|
+
setPreview(null);
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
const timer = setTimeout(() => {
|
|
567
|
+
setPreview(evaluateExpressionPreview(value, previewScope));
|
|
568
|
+
}, 200);
|
|
569
|
+
return () => clearTimeout(timer);
|
|
570
|
+
}, [value, previewScope, nodeId]);
|
|
571
|
+
const previewText = useMemo(() => {
|
|
572
|
+
if (!preview) return null;
|
|
573
|
+
if (!preview.isTemplate) return null;
|
|
574
|
+
if (preview.error) return null;
|
|
575
|
+
if (preview.value === void 0) return "undefined";
|
|
576
|
+
if (typeof preview.value === "string") return preview.value;
|
|
577
|
+
try {
|
|
578
|
+
return JSON.stringify(preview.value);
|
|
579
|
+
} catch {
|
|
580
|
+
return String(preview.value);
|
|
581
|
+
}
|
|
582
|
+
}, [preview]);
|
|
263
583
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
|
|
264
584
|
label && /* @__PURE__ */ jsx("label", { className: "text-sm font-medium text-foreground", children: label }),
|
|
265
585
|
/* @__PURE__ */ jsxs(
|
|
@@ -270,7 +590,7 @@ function ExpressionEditor({
|
|
|
270
590
|
isFocused && "ring-2 ring-primary ring-offset-1"
|
|
271
591
|
),
|
|
272
592
|
children: [
|
|
273
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 px-2 py-1.5 border-b bg-muted/30", children: [
|
|
593
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1 px-2 py-1.5 border-b bg-muted/30", children: [
|
|
274
594
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mr-2", children: tr("fluidgrids.builder.expressionEditor.insertLabel", "Insert:") }),
|
|
275
595
|
/* @__PURE__ */ jsx(
|
|
276
596
|
"button",
|
|
@@ -298,29 +618,97 @@ function ExpressionEditor({
|
|
|
298
618
|
className: "text-xs px-2 py-0.5 rounded bg-primary/10 text-primary hover:bg-primary/20 transition-colors",
|
|
299
619
|
children: "${WorkflowState}"
|
|
300
620
|
}
|
|
621
|
+
),
|
|
622
|
+
/* @__PURE__ */ jsx("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
623
|
+
/* @__PURE__ */ jsx(
|
|
624
|
+
"button",
|
|
625
|
+
{
|
|
626
|
+
type: "button",
|
|
627
|
+
onClick: () => insertTemplate("{{ $json. }}"),
|
|
628
|
+
className: "text-xs px-2 py-0.5 rounded bg-secondary/40 text-secondary-foreground hover:bg-secondary/60 transition-colors",
|
|
629
|
+
children: "{{ $json }}"
|
|
630
|
+
}
|
|
301
631
|
)
|
|
302
632
|
] }),
|
|
303
|
-
/* @__PURE__ */
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
633
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
634
|
+
/* @__PURE__ */ jsx(
|
|
635
|
+
"textarea",
|
|
636
|
+
{
|
|
637
|
+
ref: editorRef,
|
|
638
|
+
value,
|
|
639
|
+
onChange: handleChange,
|
|
640
|
+
onKeyUp: (e) => {
|
|
641
|
+
const target = e.currentTarget;
|
|
642
|
+
setSuggestionsOpen(
|
|
643
|
+
openExpressionPrefix(target.value, target.selectionStart) !== null
|
|
644
|
+
);
|
|
645
|
+
},
|
|
646
|
+
onFocus: () => setIsFocused(true),
|
|
647
|
+
onBlur: () => {
|
|
648
|
+
setIsFocused(false);
|
|
649
|
+
setTimeout(() => setSuggestionsOpen(false), 150);
|
|
650
|
+
},
|
|
651
|
+
placeholder: placeholder ?? tr(
|
|
652
|
+
"fluidgrids.builder.expressionEditor.defaultPlaceholder",
|
|
653
|
+
"Enter expression..."
|
|
654
|
+
),
|
|
655
|
+
rows,
|
|
656
|
+
spellCheck: false,
|
|
657
|
+
className: cn(
|
|
658
|
+
"w-full p-3 font-mono text-sm bg-background resize-none",
|
|
659
|
+
"focus:outline-none",
|
|
660
|
+
"placeholder:text-muted-foreground/50"
|
|
661
|
+
)
|
|
662
|
+
}
|
|
663
|
+
),
|
|
664
|
+
suggestionsOpen && suggestions.length > 0 && /* @__PURE__ */ jsx(
|
|
665
|
+
"div",
|
|
666
|
+
{
|
|
667
|
+
className: "absolute z-20 left-2 right-2 top-full mt-1 rounded-md border bg-popover shadow-md overflow-hidden",
|
|
668
|
+
role: "listbox",
|
|
669
|
+
"aria-label": tr(
|
|
670
|
+
"fluidgrids.builder.expressionEditor.autocompleteLabel",
|
|
671
|
+
"Expression variable suggestions"
|
|
672
|
+
),
|
|
673
|
+
children: suggestions.map((s) => /* @__PURE__ */ jsxs(
|
|
674
|
+
"button",
|
|
675
|
+
{
|
|
676
|
+
type: "button",
|
|
677
|
+
role: "option",
|
|
678
|
+
"aria-selected": false,
|
|
679
|
+
onMouseDown: (e) => {
|
|
680
|
+
e.preventDefault();
|
|
681
|
+
applySuggestion(s.insert);
|
|
682
|
+
},
|
|
683
|
+
className: "flex w-full items-baseline gap-2 px-3 py-1.5 text-left hover:bg-accent",
|
|
684
|
+
children: [
|
|
685
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-xs text-primary", children: s.label }),
|
|
686
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground truncate", children: s.description })
|
|
687
|
+
]
|
|
688
|
+
},
|
|
689
|
+
s.insert
|
|
690
|
+
))
|
|
691
|
+
}
|
|
692
|
+
)
|
|
693
|
+
] }),
|
|
694
|
+
nodeId && value.trim() && /* @__PURE__ */ jsx("div", { className: "border-t bg-muted/20 px-3 py-1.5 text-xs", children: preview?.error ? /* @__PURE__ */ jsxs("span", { className: "text-destructive", children: [
|
|
695
|
+
tr(
|
|
696
|
+
"fluidgrids.builder.expressionEditor.previewError",
|
|
697
|
+
"Preview error:"
|
|
698
|
+
),
|
|
699
|
+
" ",
|
|
700
|
+
preview.error
|
|
701
|
+
] }) : previewText !== null ? /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
702
|
+
tr(
|
|
703
|
+
"fluidgrids.builder.expressionEditor.previewLabel",
|
|
704
|
+
"Preview:"
|
|
705
|
+
),
|
|
706
|
+
" ",
|
|
707
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-foreground", children: previewText })
|
|
708
|
+
] }) : !hasPreviewData ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/70 italic", children: tr(
|
|
709
|
+
"fluidgrids.builder.expressionEditor.previewNoData",
|
|
710
|
+
'Run "Execute step" on this node to preview real values.'
|
|
711
|
+
) }) : null })
|
|
324
712
|
]
|
|
325
713
|
}
|
|
326
714
|
),
|
|
@@ -13819,7 +14207,7 @@ var DEFAULT_CONFIG = {
|
|
|
13819
14207
|
maxTemplateLength: 1e4,
|
|
13820
14208
|
debug: false
|
|
13821
14209
|
};
|
|
13822
|
-
var
|
|
14210
|
+
var SAFE_GLOBALS2 = {
|
|
13823
14211
|
// Type conversion
|
|
13824
14212
|
parseInt,
|
|
13825
14213
|
parseFloat,
|
|
@@ -13866,7 +14254,7 @@ function parseTemplate(template) {
|
|
|
13866
14254
|
}
|
|
13867
14255
|
function buildSandbox(scope) {
|
|
13868
14256
|
return {
|
|
13869
|
-
...
|
|
14257
|
+
...SAFE_GLOBALS2,
|
|
13870
14258
|
output: scope.output,
|
|
13871
14259
|
TriggerInput: scope.TriggerInput,
|
|
13872
14260
|
WorkflowState: scope.WorkflowState,
|
|
@@ -23436,5 +23824,5 @@ var FlowBuilderPage = ({
|
|
|
23436
23824
|
};
|
|
23437
23825
|
|
|
23438
23826
|
export { Card2 as Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ConnectionFormDialog, ConnectionSelector, EntityTagPicker, FLUIDGRIDS_ENTITY_TYPES, FlowBuilderPage, FluidGridsProvider, ProviderPicker, SchemaConnectionForm, ScopePicker, TemplateCard, buildNodeCheck, buildRequiredNodeTypes, listCustomBlocks, mergeStickyNotes, refetchStoreNodes, registerCustomBlock, resolveUiSpec, stripSubmitActions, tagLabel, useAvailableTags, useConnection, useConnectionDialog, useConnections, useConnectionsByProvider, useCreateConnection, useCreateTag, useDraftEntityTags, useEntityTags, useFluidGridsContext, useImportWorkflowTemplate, useInitiateOAuth, useInstalledNodes, useNodeExecution, useProviderByKey, useProviderCatalog, useProviders, useReplaceEntityTags, useSearchTags, useTagEntity, useUntagEntity, useWorkflowTemplates };
|
|
23439
|
-
//# sourceMappingURL=chunk-
|
|
23440
|
-
//# sourceMappingURL=chunk-
|
|
23827
|
+
//# sourceMappingURL=chunk-XASNLRFQ.js.map
|
|
23828
|
+
//# sourceMappingURL=chunk-XASNLRFQ.js.map
|