@octaviaflow/core 3.0.18-beta.22 → 3.0.18-beta.23
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/styles.css +1 -1
- package/dist/workflow/components/FxPanel/FxPanel.d.ts +26 -11
- package/dist/workflow/components/FxPanel/FxPanel.d.ts.map +1 -1
- package/dist/workflow.cjs +325 -71
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.js +333 -71
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
import { type CSSProperties, type DragEvent, type ReactNode } from "react";
|
|
2
2
|
export type FxItemKind = "function" | "variable";
|
|
3
|
+
/** Data type of a Source-Data field — drives the colour-coded badge. */
|
|
4
|
+
export type FxValueType = "string" | "number" | "boolean" | "object" | "array" | "date" | "any";
|
|
3
5
|
export interface FxPanelItem {
|
|
4
|
-
/** Stable key. */
|
|
6
|
+
/** Stable key + tree/keyboard identity. */
|
|
5
7
|
id: string;
|
|
6
|
-
/** Display label —
|
|
8
|
+
/** Display label — a function signature, variable name, or field key. */
|
|
7
9
|
label: string;
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The string handed to `dataTransfer` / inserted into a field.
|
|
12
|
+
* Branches may still set it (drag the whole object/array reference).
|
|
13
|
+
*/
|
|
14
|
+
insertValue?: string;
|
|
10
15
|
/** Short one-line description shown under the label. */
|
|
11
16
|
description?: string;
|
|
17
|
+
/** Data type — renders a colour-coded badge. Source-Data fields only. */
|
|
18
|
+
valueType?: FxValueType;
|
|
19
|
+
/** Sample value preview, shown dimmed at the end of the row. */
|
|
20
|
+
preview?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Nested children. When present the item renders as an expandable
|
|
23
|
+
* branch — this is what powers the n-th-level Source-Data tree.
|
|
24
|
+
*/
|
|
25
|
+
children?: FxPanelItem[];
|
|
12
26
|
}
|
|
13
27
|
export interface FxPanelCategory {
|
|
14
28
|
/** Stable key + accordion identity. */
|
|
@@ -17,10 +31,11 @@ export interface FxPanelCategory {
|
|
|
17
31
|
label: string;
|
|
18
32
|
/** Drives the badge glyph + drag payload. Defaults to "function". */
|
|
19
33
|
kind?: FxItemKind;
|
|
34
|
+
/** Items — flat for functions/variables, nested for Source Data. */
|
|
20
35
|
items: FxPanelItem[];
|
|
21
36
|
}
|
|
22
37
|
export interface FxPanelProps {
|
|
23
|
-
/** Categorised entries. Empty categories are
|
|
38
|
+
/** Categorised entries. Empty categories are dropped from render. */
|
|
24
39
|
categories: FxPanelCategory[];
|
|
25
40
|
/** Header title. Default "FX / IO". */
|
|
26
41
|
title?: ReactNode;
|
|
@@ -31,7 +46,7 @@ export interface FxPanelProps {
|
|
|
31
46
|
/** Initial search term when uncontrolled. */
|
|
32
47
|
defaultSearch?: string;
|
|
33
48
|
onSearchChange?: (next: string) => void;
|
|
34
|
-
/** Controlled open category (single-open accordion). `null` =
|
|
49
|
+
/** Controlled open category (single-open accordion). `null` = closed. */
|
|
35
50
|
expandedCategory?: string | null;
|
|
36
51
|
/** Initial open category when uncontrolled. */
|
|
37
52
|
defaultExpandedCategory?: string | null;
|
|
@@ -41,14 +56,14 @@ export interface FxPanelProps {
|
|
|
41
56
|
/**
|
|
42
57
|
* Fires when an item begins dragging. Use it to populate
|
|
43
58
|
* `e.dataTransfer`. When omitted, FxPanel writes a sensible default:
|
|
44
|
-
* - `text/plain`
|
|
45
|
-
* - `application/x-fx-insert
|
|
46
|
-
* - `application/x-fx-type`
|
|
59
|
+
* - `text/plain` → insertValue
|
|
60
|
+
* - `application/x-fx-insert` → insertValue
|
|
61
|
+
* - `application/x-fx-type` → category kind
|
|
47
62
|
*/
|
|
48
63
|
onItemDragStart?: (item: FxPanelItem, category: FxPanelCategory, e: DragEvent<HTMLElement>) => void;
|
|
49
|
-
/** Fires on
|
|
64
|
+
/** Fires on click / Enter of an item (insert at cursor). */
|
|
50
65
|
onItemSelect?: (item: FxPanelItem, category: FxPanelCategory) => void;
|
|
51
|
-
/** Panel width (px). Default
|
|
66
|
+
/** Panel width (px). Default 300. */
|
|
52
67
|
width?: number;
|
|
53
68
|
/** Message shown when a search matches nothing. Default "No matches". */
|
|
54
69
|
emptyLabel?: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FxPanel.d.ts","sourceRoot":"","sources":["../../../../src/workflow/components/FxPanel/FxPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FxPanel.d.ts","sourceRoot":"","sources":["../../../../src/workflow/components/FxPanel/FxPanel.tsx"],"names":[],"mappings":"AAiBA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,SAAS,EAEd,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAcf,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;AAEjD,wEAAwE;AACxE,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,MAAM,GACN,KAAK,CAAC;AAEV,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,oEAAoE;IACpE,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,uCAAuC;IACvC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,mEAAmE;IACnE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,+CAA+C;IAC/C,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,wBAAwB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,CAChB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,eAAe,EACzB,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,KACtB,IAAI,CAAC;IACV,4DAA4D;IAC5D,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IACtE,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AA8ED,wBAAgB,OAAO,CAAC,EACtB,UAAU,EACV,KAAiB,EACjB,IAKC,EACD,MAAM,EAAE,gBAAgB,EACxB,aAAkB,EAClB,cAAc,EACd,gBAAgB,EAAE,kBAAkB,EACpC,uBAAuB,EACvB,wBAAwB,EACxB,OAAO,EACP,eAAe,EACf,YAAY,EACZ,KAAW,EACX,UAAyB,EACzB,iBAA2D,EAC3D,SAAS,EACT,KAAK,GACN,EAAE,YAAY,2CAodd"}
|
package/dist/workflow.cjs
CHANGED
|
@@ -3587,13 +3587,48 @@ var KIND_GLYPH = {
|
|
|
3587
3587
|
function: "\u0192",
|
|
3588
3588
|
variable: "\u2B21"
|
|
3589
3589
|
};
|
|
3590
|
+
function countLeaves(items) {
|
|
3591
|
+
let n = 0;
|
|
3592
|
+
for (const it of items) {
|
|
3593
|
+
if (it.children && it.children.length > 0) n += countLeaves(it.children);
|
|
3594
|
+
else n += 1;
|
|
3595
|
+
}
|
|
3596
|
+
return n;
|
|
3597
|
+
}
|
|
3598
|
+
function collectBranchIds(items, out) {
|
|
3599
|
+
for (const it of items) {
|
|
3600
|
+
if (it.children && it.children.length > 0) {
|
|
3601
|
+
out.add(it.id);
|
|
3602
|
+
collectBranchIds(it.children, out);
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3605
|
+
}
|
|
3606
|
+
function flattenTree(items, depth, expandedItems, out) {
|
|
3607
|
+
for (const it of items) {
|
|
3608
|
+
const hasChildren = !!it.children && it.children.length > 0;
|
|
3609
|
+
const expanded = hasChildren && expandedItems.has(it.id);
|
|
3610
|
+
out.push({ item: it, depth, hasChildren, expanded });
|
|
3611
|
+
if (expanded) flattenTree(it.children, depth + 1, expandedItems, out);
|
|
3612
|
+
}
|
|
3613
|
+
}
|
|
3614
|
+
function collectHits(items, ancestors, q, out) {
|
|
3615
|
+
for (const it of items) {
|
|
3616
|
+
if (it.children && it.children.length > 0) {
|
|
3617
|
+
collectHits(it.children, [...ancestors, it.label], q, out);
|
|
3618
|
+
} else {
|
|
3619
|
+
const path = [...ancestors, it.label].join(" / ");
|
|
3620
|
+
const hay = `${it.label} ${it.description ?? ""} ${path} ${it.insertValue ?? ""}`.toLowerCase();
|
|
3621
|
+
if (hay.includes(q)) out.push({ item: it, ancestors });
|
|
3622
|
+
}
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3590
3625
|
function FxPanel({
|
|
3591
3626
|
categories,
|
|
3592
3627
|
title = "FX / IO",
|
|
3593
3628
|
hint = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
3594
|
-
"Drag
|
|
3629
|
+
"Drag a field into any input with the ",
|
|
3595
3630
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: "FX" }),
|
|
3596
|
-
"
|
|
3631
|
+
" badge, or click to insert."
|
|
3597
3632
|
] }),
|
|
3598
3633
|
search: controlledSearch,
|
|
3599
3634
|
defaultSearch = "",
|
|
@@ -3604,44 +3639,85 @@ function FxPanel({
|
|
|
3604
3639
|
onClose,
|
|
3605
3640
|
onItemDragStart,
|
|
3606
3641
|
onItemSelect,
|
|
3607
|
-
width =
|
|
3642
|
+
width = 300,
|
|
3608
3643
|
emptyLabel = "No matches",
|
|
3609
|
-
searchPlaceholder = "Search functions & variables\u2026",
|
|
3644
|
+
searchPlaceholder = "Search fields, functions & variables\u2026",
|
|
3610
3645
|
className,
|
|
3611
3646
|
style
|
|
3612
3647
|
}) {
|
|
3613
3648
|
const [internalSearch, setInternalSearch] = (0, import_react16.useState)(defaultSearch);
|
|
3614
3649
|
const search = controlledSearch ?? internalSearch;
|
|
3650
|
+
const query = search.trim().toLowerCase();
|
|
3615
3651
|
const setSearch = (next) => {
|
|
3616
3652
|
if (controlledSearch === void 0) setInternalSearch(next);
|
|
3617
3653
|
onSearchChange?.(next);
|
|
3618
3654
|
};
|
|
3619
|
-
const
|
|
3620
|
-
|
|
3655
|
+
const visibleCategories = (0, import_react16.useMemo)(
|
|
3656
|
+
() => categories.filter((c) => c.items.length > 0),
|
|
3657
|
+
[categories]
|
|
3621
3658
|
);
|
|
3622
|
-
const
|
|
3623
|
-
|
|
3624
|
-
|
|
3659
|
+
const [internalCat, setInternalCat] = (0, import_react16.useState)(
|
|
3660
|
+
defaultExpandedCategory !== void 0 ? defaultExpandedCategory : visibleCategories[0]?.id ?? null
|
|
3661
|
+
);
|
|
3662
|
+
const openCategoryId = controlledExpanded ?? internalCat;
|
|
3663
|
+
const setOpenCategory = (id) => {
|
|
3664
|
+
if (controlledExpanded === void 0) setInternalCat(id);
|
|
3625
3665
|
onExpandedCategoryChange?.(id);
|
|
3626
3666
|
};
|
|
3667
|
+
const [expandedItems, setExpandedItems] = (0, import_react16.useState)(() => {
|
|
3668
|
+
const ids = /* @__PURE__ */ new Set();
|
|
3669
|
+
for (const cat of categories) {
|
|
3670
|
+
for (const item of cat.items) {
|
|
3671
|
+
if (item.children && item.children.length > 0) ids.add(item.id);
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
return ids;
|
|
3675
|
+
});
|
|
3676
|
+
const toggleItem = (id) => {
|
|
3677
|
+
setExpandedItems((prev) => {
|
|
3678
|
+
const next = new Set(prev);
|
|
3679
|
+
if (next.has(id)) next.delete(id);
|
|
3680
|
+
else next.add(id);
|
|
3681
|
+
return next;
|
|
3682
|
+
});
|
|
3683
|
+
};
|
|
3684
|
+
const setCategoryExpansion = (cat, expand) => {
|
|
3685
|
+
const branchIds = /* @__PURE__ */ new Set();
|
|
3686
|
+
collectBranchIds(cat.items, branchIds);
|
|
3687
|
+
setExpandedItems((prev) => {
|
|
3688
|
+
const next = new Set(prev);
|
|
3689
|
+
for (const id of branchIds) {
|
|
3690
|
+
if (expand) next.add(id);
|
|
3691
|
+
else next.delete(id);
|
|
3692
|
+
}
|
|
3693
|
+
return next;
|
|
3694
|
+
});
|
|
3695
|
+
};
|
|
3627
3696
|
const [draggingId, setDraggingId] = (0, import_react16.useState)(null);
|
|
3628
|
-
const
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3697
|
+
const [copiedId, setCopiedId] = (0, import_react16.useState)(null);
|
|
3698
|
+
const [focusedId, setFocusedId] = (0, import_react16.useState)(null);
|
|
3699
|
+
const copyTimer = (0, import_react16.useRef)(null);
|
|
3700
|
+
(0, import_react16.useEffect)(
|
|
3701
|
+
() => () => {
|
|
3702
|
+
if (copyTimer.current) clearTimeout(copyTimer.current);
|
|
3703
|
+
},
|
|
3704
|
+
[]
|
|
3705
|
+
);
|
|
3706
|
+
const hits = (0, import_react16.useMemo)(() => {
|
|
3707
|
+
if (!query) return null;
|
|
3708
|
+
const all = [];
|
|
3709
|
+
for (const cat of visibleCategories) {
|
|
3710
|
+
const out = [];
|
|
3711
|
+
collectHits(cat.items, [], query, out);
|
|
3712
|
+
for (const hit of out) all.push({ category: cat, hit });
|
|
3713
|
+
}
|
|
3714
|
+
return all;
|
|
3715
|
+
}, [query, visibleCategories]);
|
|
3640
3716
|
const handleDragStart = (item, category) => (e) => {
|
|
3641
3717
|
setDraggingId(item.id);
|
|
3642
3718
|
if (onItemDragStart) {
|
|
3643
3719
|
onItemDragStart(item, category, e);
|
|
3644
|
-
} else {
|
|
3720
|
+
} else if (item.insertValue) {
|
|
3645
3721
|
e.dataTransfer.setData("text/plain", item.insertValue);
|
|
3646
3722
|
e.dataTransfer.setData("application/x-fx-insert", item.insertValue);
|
|
3647
3723
|
e.dataTransfer.setData(
|
|
@@ -3651,6 +3727,144 @@ function FxPanel({
|
|
|
3651
3727
|
e.dataTransfer.effectAllowed = "copy";
|
|
3652
3728
|
}
|
|
3653
3729
|
};
|
|
3730
|
+
const handleCopy = (item) => {
|
|
3731
|
+
if (!item.insertValue || typeof navigator === "undefined") return;
|
|
3732
|
+
void navigator.clipboard?.writeText(item.insertValue);
|
|
3733
|
+
setCopiedId(item.id);
|
|
3734
|
+
if (copyTimer.current) clearTimeout(copyTimer.current);
|
|
3735
|
+
copyTimer.current = setTimeout(() => setCopiedId(null), 1400);
|
|
3736
|
+
};
|
|
3737
|
+
const listRef = (0, import_react16.useRef)(null);
|
|
3738
|
+
const focusRow = (id) => {
|
|
3739
|
+
setFocusedId(id);
|
|
3740
|
+
requestAnimationFrame(() => {
|
|
3741
|
+
listRef.current?.querySelector(`[data-fx-row="${CSS.escape(id)}"]`)?.focus();
|
|
3742
|
+
});
|
|
3743
|
+
};
|
|
3744
|
+
const onRowKeyDown = (e, rows, row) => {
|
|
3745
|
+
const idx = rows.findIndex((r) => r.item.id === row.item.id);
|
|
3746
|
+
if (idx < 0) return;
|
|
3747
|
+
switch (e.key) {
|
|
3748
|
+
case "ArrowDown":
|
|
3749
|
+
e.preventDefault();
|
|
3750
|
+
if (idx < rows.length - 1) focusRow(rows[idx + 1].item.id);
|
|
3751
|
+
break;
|
|
3752
|
+
case "ArrowUp":
|
|
3753
|
+
e.preventDefault();
|
|
3754
|
+
if (idx > 0) focusRow(rows[idx - 1].item.id);
|
|
3755
|
+
break;
|
|
3756
|
+
case "ArrowRight":
|
|
3757
|
+
if (row.hasChildren) {
|
|
3758
|
+
e.preventDefault();
|
|
3759
|
+
if (!row.expanded) toggleItem(row.item.id);
|
|
3760
|
+
else if (idx < rows.length - 1) focusRow(rows[idx + 1].item.id);
|
|
3761
|
+
}
|
|
3762
|
+
break;
|
|
3763
|
+
case "ArrowLeft":
|
|
3764
|
+
if (row.hasChildren && row.expanded) {
|
|
3765
|
+
e.preventDefault();
|
|
3766
|
+
toggleItem(row.item.id);
|
|
3767
|
+
} else {
|
|
3768
|
+
for (let i = idx - 1; i >= 0; i--) {
|
|
3769
|
+
if (rows[i].depth < row.depth) {
|
|
3770
|
+
e.preventDefault();
|
|
3771
|
+
focusRow(rows[i].item.id);
|
|
3772
|
+
break;
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
break;
|
|
3777
|
+
case "Home":
|
|
3778
|
+
e.preventDefault();
|
|
3779
|
+
if (rows.length) focusRow(rows[0].item.id);
|
|
3780
|
+
break;
|
|
3781
|
+
case "End":
|
|
3782
|
+
e.preventDefault();
|
|
3783
|
+
if (rows.length) focusRow(rows[rows.length - 1].item.id);
|
|
3784
|
+
break;
|
|
3785
|
+
case "Enter":
|
|
3786
|
+
case " ":
|
|
3787
|
+
e.preventDefault();
|
|
3788
|
+
if (row.hasChildren) toggleItem(row.item.id);
|
|
3789
|
+
else {
|
|
3790
|
+
const cat = visibleCategories.find((c) => c.id === openCategoryId);
|
|
3791
|
+
if (cat) onItemSelect?.(row.item, cat);
|
|
3792
|
+
}
|
|
3793
|
+
break;
|
|
3794
|
+
default:
|
|
3795
|
+
break;
|
|
3796
|
+
}
|
|
3797
|
+
};
|
|
3798
|
+
const renderRow = (row, category, rows, opts = {}) => {
|
|
3799
|
+
const { item, depth, hasChildren, expanded } = row;
|
|
3800
|
+
const mono = category.kind === "function";
|
|
3801
|
+
const draggable = !!item.insertValue;
|
|
3802
|
+
const isFocused = focusedId === item.id;
|
|
3803
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3804
|
+
"div",
|
|
3805
|
+
{
|
|
3806
|
+
"data-fx-row": item.id,
|
|
3807
|
+
className: cn(
|
|
3808
|
+
"ods-flow-fx-panel__row",
|
|
3809
|
+
hasChildren ? "ods-flow-fx-panel__row--branch" : "ods-flow-fx-panel__row--leaf",
|
|
3810
|
+
draggingId === item.id && "ods-flow-fx-panel__row--dragging",
|
|
3811
|
+
isFocused && "ods-flow-fx-panel__row--focused"
|
|
3812
|
+
),
|
|
3813
|
+
role: "treeitem",
|
|
3814
|
+
"aria-expanded": hasChildren ? expanded : void 0,
|
|
3815
|
+
"aria-level": depth + 1,
|
|
3816
|
+
tabIndex: isFocused || focusedId === null && rows[0]?.item.id === item.id ? 0 : -1,
|
|
3817
|
+
draggable,
|
|
3818
|
+
onDragStart: draggable ? handleDragStart(item, category) : void 0,
|
|
3819
|
+
onDragEnd: () => setDraggingId(null),
|
|
3820
|
+
onFocus: () => setFocusedId(item.id),
|
|
3821
|
+
onKeyDown: opts.searching ? void 0 : (e) => onRowKeyDown(e, rows, row),
|
|
3822
|
+
onClick: () => {
|
|
3823
|
+
if (hasChildren) toggleItem(item.id);
|
|
3824
|
+
else onItemSelect?.(item, category);
|
|
3825
|
+
},
|
|
3826
|
+
title: item.insertValue,
|
|
3827
|
+
children: [
|
|
3828
|
+
Array.from({ length: depth }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__indent", "aria-hidden": "true" }, i)),
|
|
3829
|
+
hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__twisty", "aria-hidden": "true", children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.ChevronDownIcon, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.ChevronRightIcon, { size: "sm" }) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__grip", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.DraggableIcon, { size: "sm" }) }),
|
|
3830
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "ods-flow-fx-panel__row-main", children: [
|
|
3831
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "ods-flow-fx-panel__row-line", children: [
|
|
3832
|
+
mono ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { className: "ods-flow-fx-panel__row-label ods-flow-fx-panel__row-label--mono", children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__row-label", children: item.label }),
|
|
3833
|
+
item.valueType && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3834
|
+
"span",
|
|
3835
|
+
{
|
|
3836
|
+
className: cn(
|
|
3837
|
+
"ods-flow-fx-panel__type",
|
|
3838
|
+
`ods-flow-fx-panel__type--${item.valueType}`
|
|
3839
|
+
),
|
|
3840
|
+
children: item.valueType
|
|
3841
|
+
}
|
|
3842
|
+
),
|
|
3843
|
+
item.preview !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__preview", title: item.preview, children: item.preview })
|
|
3844
|
+
] }),
|
|
3845
|
+
(item.description || opts.crumb) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "ods-flow-fx-panel__row-sub", children: [
|
|
3846
|
+
opts.crumb && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__crumb", children: opts.crumb }),
|
|
3847
|
+
item.description
|
|
3848
|
+
] })
|
|
3849
|
+
] }),
|
|
3850
|
+
item.insertValue && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3851
|
+
"button",
|
|
3852
|
+
{
|
|
3853
|
+
type: "button",
|
|
3854
|
+
className: "ods-flow-fx-panel__copy",
|
|
3855
|
+
"aria-label": `Copy ${item.label}`,
|
|
3856
|
+
onClick: (e) => {
|
|
3857
|
+
e.stopPropagation();
|
|
3858
|
+
handleCopy(item);
|
|
3859
|
+
},
|
|
3860
|
+
children: copiedId === item.id ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.CheckmarkIcon, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.CopyIcon, { size: "sm" })
|
|
3861
|
+
}
|
|
3862
|
+
)
|
|
3863
|
+
]
|
|
3864
|
+
},
|
|
3865
|
+
item.id
|
|
3866
|
+
);
|
|
3867
|
+
};
|
|
3654
3868
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3655
3869
|
"aside",
|
|
3656
3870
|
{
|
|
@@ -3679,7 +3893,7 @@ function FxPanel({
|
|
|
3679
3893
|
type: "text",
|
|
3680
3894
|
className: "ods-flow-fx-panel__search-input",
|
|
3681
3895
|
placeholder: searchPlaceholder,
|
|
3682
|
-
"aria-label": "Search functions and variables",
|
|
3896
|
+
"aria-label": "Search fields, functions and variables",
|
|
3683
3897
|
value: search,
|
|
3684
3898
|
onChange: (e) => setSearch(e.target.value)
|
|
3685
3899
|
}
|
|
@@ -3695,76 +3909,116 @@ function FxPanel({
|
|
|
3695
3909
|
}
|
|
3696
3910
|
)
|
|
3697
3911
|
] }),
|
|
3698
|
-
hint && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "ods-flow-fx-panel__hint", children: hint }),
|
|
3699
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "ods-flow-fx-panel__list", children: [
|
|
3700
|
-
|
|
3701
|
-
|
|
3912
|
+
hint && !query && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "ods-flow-fx-panel__hint", children: hint }),
|
|
3913
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "ods-flow-fx-panel__list", ref: listRef, role: "tree", children: [
|
|
3914
|
+
query && hits && (hits.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "ods-flow-fx-panel__results", children: [
|
|
3915
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "ods-flow-fx-panel__results-count", children: [
|
|
3916
|
+
hits.length,
|
|
3917
|
+
" ",
|
|
3918
|
+
hits.length === 1 ? "match" : "matches"
|
|
3919
|
+
] }),
|
|
3920
|
+
hits.map(
|
|
3921
|
+
({ category, hit }) => renderRow(
|
|
3922
|
+
{ item: hit.item, depth: 0, hasChildren: false, expanded: false },
|
|
3923
|
+
category,
|
|
3924
|
+
hits.map((h) => ({
|
|
3925
|
+
item: h.hit.item,
|
|
3926
|
+
depth: 0,
|
|
3927
|
+
hasChildren: false,
|
|
3928
|
+
expanded: false
|
|
3929
|
+
})),
|
|
3930
|
+
{
|
|
3931
|
+
searching: true,
|
|
3932
|
+
crumb: hit.ancestors.length ? hit.ancestors.join(" / ") : category.label
|
|
3933
|
+
}
|
|
3934
|
+
)
|
|
3935
|
+
)
|
|
3936
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "ods-flow-fx-panel__empty", children: emptyLabel })),
|
|
3937
|
+
!query && visibleCategories.map((cat) => {
|
|
3938
|
+
const isOpen = openCategoryId === cat.id;
|
|
3702
3939
|
const kind = cat.kind ?? "function";
|
|
3940
|
+
const branchIds = /* @__PURE__ */ new Set();
|
|
3941
|
+
collectBranchIds(cat.items, branchIds);
|
|
3942
|
+
const hasTree = branchIds.size > 0;
|
|
3943
|
+
const rows = [];
|
|
3944
|
+
if (isOpen) flattenTree(cat.items, 0, expandedItems, rows);
|
|
3945
|
+
const allExpanded = hasTree && [...branchIds].every((id) => expandedItems.has(id));
|
|
3703
3946
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "ods-flow-fx-panel__category", children: [
|
|
3704
3947
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3705
|
-
"
|
|
3948
|
+
"div",
|
|
3706
3949
|
{
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3950
|
+
className: cn(
|
|
3951
|
+
"ods-flow-fx-panel__cat-header",
|
|
3952
|
+
isOpen && "ods-flow-fx-panel__cat-header--open"
|
|
3953
|
+
),
|
|
3711
3954
|
children: [
|
|
3712
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3713
|
-
import_icons2.ChevronRightIcon,
|
|
3714
|
-
{
|
|
3715
|
-
size: "sm",
|
|
3716
|
-
className: cn(
|
|
3717
|
-
"ods-flow-fx-panel__chevron",
|
|
3718
|
-
isOpen && "ods-flow-fx-panel__chevron--open"
|
|
3719
|
-
)
|
|
3720
|
-
}
|
|
3721
|
-
),
|
|
3722
3955
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3723
|
-
"
|
|
3956
|
+
"button",
|
|
3724
3957
|
{
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
),
|
|
3958
|
+
type: "button",
|
|
3959
|
+
className: "ods-flow-fx-panel__cat-toggle",
|
|
3960
|
+
"aria-expanded": isOpen,
|
|
3961
|
+
onClick: () => setOpenCategory(isOpen ? null : cat.id),
|
|
3729
3962
|
children: [
|
|
3730
3963
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3964
|
+
import_icons2.ChevronRightIcon,
|
|
3965
|
+
{
|
|
3966
|
+
size: "sm",
|
|
3967
|
+
className: cn(
|
|
3968
|
+
"ods-flow-fx-panel__chevron",
|
|
3969
|
+
isOpen && "ods-flow-fx-panel__chevron--open"
|
|
3970
|
+
)
|
|
3971
|
+
}
|
|
3972
|
+
),
|
|
3973
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3731
3974
|
"span",
|
|
3732
3975
|
{
|
|
3733
|
-
className:
|
|
3734
|
-
|
|
3735
|
-
|
|
3976
|
+
className: cn(
|
|
3977
|
+
"ods-flow-fx-panel__badge",
|
|
3978
|
+
`ods-flow-fx-panel__badge--${kind}`
|
|
3979
|
+
),
|
|
3980
|
+
children: [
|
|
3981
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3982
|
+
"span",
|
|
3983
|
+
{
|
|
3984
|
+
className: "ods-flow-fx-panel__badge-glyph",
|
|
3985
|
+
"aria-hidden": "true",
|
|
3986
|
+
children: KIND_GLYPH[kind]
|
|
3987
|
+
}
|
|
3988
|
+
),
|
|
3989
|
+
cat.label
|
|
3990
|
+
]
|
|
3736
3991
|
}
|
|
3737
3992
|
),
|
|
3738
|
-
cat.
|
|
3993
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__count", children: countLeaves(cat.items) })
|
|
3739
3994
|
]
|
|
3740
3995
|
}
|
|
3741
3996
|
),
|
|
3742
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3997
|
+
isOpen && hasTree && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3998
|
+
"button",
|
|
3999
|
+
{
|
|
4000
|
+
type: "button",
|
|
4001
|
+
className: "ods-flow-fx-panel__cat-action",
|
|
4002
|
+
"aria-label": allExpanded ? "Collapse all" : "Expand all",
|
|
4003
|
+
title: allExpanded ? "Collapse all" : "Expand all",
|
|
4004
|
+
onClick: () => setCategoryExpansion(cat, !allExpanded),
|
|
4005
|
+
children: allExpanded ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.CollapseAllIcon, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.ExpandAllIcon, { size: "sm" })
|
|
4006
|
+
}
|
|
4007
|
+
)
|
|
3743
4008
|
]
|
|
3744
4009
|
}
|
|
3745
4010
|
),
|
|
3746
|
-
isOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4011
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3747
4012
|
"div",
|
|
3748
4013
|
{
|
|
3749
|
-
className:
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
),
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
onDragStart: handleDragStart(item, cat),
|
|
3756
|
-
onDragEnd: () => setDraggingId(null),
|
|
3757
|
-
onClick: onItemSelect ? () => onItemSelect(item, cat) : void 0,
|
|
3758
|
-
children: [
|
|
3759
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { className: "ods-flow-fx-panel__item-label", children: item.label }),
|
|
3760
|
-
item.description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__item-desc", children: item.description })
|
|
3761
|
-
]
|
|
3762
|
-
},
|
|
3763
|
-
item.id
|
|
3764
|
-
)) })
|
|
4014
|
+
className: "ods-flow-fx-panel__rows",
|
|
4015
|
+
role: "group",
|
|
4016
|
+
"aria-label": cat.label,
|
|
4017
|
+
children: rows.map((row) => renderRow(row, cat, rows))
|
|
4018
|
+
}
|
|
4019
|
+
)
|
|
3765
4020
|
] }, cat.id);
|
|
3766
|
-
})
|
|
3767
|
-
!hasResults && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "ods-flow-fx-panel__empty", children: emptyLabel })
|
|
4021
|
+
})
|
|
3768
4022
|
] })
|
|
3769
4023
|
]
|
|
3770
4024
|
}
|