@flytedan/flytebot-design-system 0.16.0 → 0.17.0
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/index.cjs +458 -371
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -2
- package/dist/index.d.ts +55 -2
- package/dist/index.js +457 -371
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -212,6 +212,7 @@ __export(index_exports, {
|
|
|
212
212
|
useChatEngine: () => useChatEngine,
|
|
213
213
|
useFeatureStatus: () => useFeatureStatus,
|
|
214
214
|
usePopoverPosition: () => usePopoverPosition,
|
|
215
|
+
useResponsiveRail: () => useResponsiveRail,
|
|
215
216
|
useRuntimeMode: () => useRuntimeMode,
|
|
216
217
|
useServerTable: () => useServerTable,
|
|
217
218
|
useSessionContext: () => useSessionContext,
|
|
@@ -1107,37 +1108,48 @@ function Spinner({ size = "md", label = "Loading", className = "", style, ...res
|
|
|
1107
1108
|
}
|
|
1108
1109
|
|
|
1109
1110
|
// src/components/navigation/SidebarNav.tsx
|
|
1111
|
+
var React6 = __toESM(require("react"), 1);
|
|
1110
1112
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1111
1113
|
function Tip({ label, children }) {
|
|
1112
1114
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { title: label, style: { display: "inline-flex", flex: "none" }, children });
|
|
1113
1115
|
}
|
|
1114
|
-
|
|
1115
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
children:
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
}
|
|
1116
|
+
var SidebarNav = React6.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open = false, className = "", ...rest }, ref) {
|
|
1117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1118
|
+
"nav",
|
|
1119
|
+
{
|
|
1120
|
+
ref,
|
|
1121
|
+
tabIndex: -1,
|
|
1122
|
+
className: ["fd-side", className].filter(Boolean).join(" "),
|
|
1123
|
+
"data-open": open ? "true" : "false",
|
|
1124
|
+
...rest,
|
|
1125
|
+
children: [
|
|
1126
|
+
brand ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { height: "var(--topbar-h)", display: "flex", alignItems: "center", padding: "0 18px", borderBottom: "1px solid var(--border)", flex: "none", overflow: "hidden" }, children: brand }) : null,
|
|
1127
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { flex: 1, overflow: "auto", padding: "4px 10px 18px" }, children: groups.map((g, gi) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
1128
|
+
g.label ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "fd-side-group", children: g.label }) : null,
|
|
1129
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "fd-stack", style: { gap: 2 }, children: g.items.map((it) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1130
|
+
"button",
|
|
1131
|
+
{
|
|
1132
|
+
type: "button",
|
|
1133
|
+
className: "fd-side-item",
|
|
1134
|
+
"aria-current": current2 === it.value ? "page" : void 0,
|
|
1135
|
+
onClick: onNavigate ? () => onNavigate(it.value) : void 0,
|
|
1136
|
+
children: [
|
|
1137
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "fd-side-item-icon", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) }),
|
|
1138
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, title: truncationTitle(it.label), children: it.label }),
|
|
1139
|
+
it.preview ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tip, { label: "Designed, backend not wired yet", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("i", { className: "ph ph-traffic-cone", style: { fontSize: 13, color: "var(--warn-solid)", flex: "none" } }) }) : null,
|
|
1140
|
+
it.locked ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tip, { label: "You do not have permission for this", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("i", { className: "ph ph-lock-simple", style: { fontSize: 13, color: "var(--text-muted)", flex: "none" } }) }) : null,
|
|
1141
|
+
it.count !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "fd-side-item-count", children: it.count }) : null,
|
|
1142
|
+
it.loading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "fd-skel fd-skel-text", style: { width: 22, height: 11, marginLeft: "auto" } }) : null
|
|
1143
|
+
]
|
|
1144
|
+
},
|
|
1145
|
+
it.value
|
|
1146
|
+
)) })
|
|
1147
|
+
] }, gi)) }),
|
|
1148
|
+
footer ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { borderTop: "1px solid var(--border)", padding: 14, flex: "none" }, children: footer }) : null
|
|
1149
|
+
]
|
|
1150
|
+
}
|
|
1151
|
+
);
|
|
1152
|
+
});
|
|
1141
1153
|
|
|
1142
1154
|
// src/components/navigation/FlytedeskBrand.tsx
|
|
1143
1155
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
@@ -1178,13 +1190,13 @@ function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
|
1178
1190
|
}
|
|
1179
1191
|
|
|
1180
1192
|
// src/components/navigation/Topbar.tsx
|
|
1181
|
-
var
|
|
1193
|
+
var React7 = __toESM(require("react"), 1);
|
|
1182
1194
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1183
1195
|
function useIsNarrow(breakpoint) {
|
|
1184
|
-
const [narrow, setNarrow] =
|
|
1196
|
+
const [narrow, setNarrow] = React7.useState(
|
|
1185
1197
|
() => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
1186
1198
|
);
|
|
1187
|
-
|
|
1199
|
+
React7.useEffect(() => {
|
|
1188
1200
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1189
1201
|
const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
1190
1202
|
const apply = () => setNarrow(mq.matches);
|
|
@@ -1205,11 +1217,11 @@ function Topbar({
|
|
|
1205
1217
|
...rest
|
|
1206
1218
|
}) {
|
|
1207
1219
|
const narrow = useIsNarrow(overflowBreakpoint);
|
|
1208
|
-
const [moreOpen, setMoreOpen] =
|
|
1209
|
-
const moreRef =
|
|
1220
|
+
const [moreOpen, setMoreOpen] = React7.useState(false);
|
|
1221
|
+
const moreRef = React7.useRef(null);
|
|
1210
1222
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
|
|
1211
1223
|
onMenu ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("i", { className: "ph ph-list" }) }) : null,
|
|
1212
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1224
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React7.Fragment, { children: [
|
|
1213
1225
|
i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
|
|
1214
1226
|
i === crumbs.length - 1 ? (
|
|
1215
1227
|
// MP-141: the current crumb mixes a static route label with (usually) a
|
|
@@ -1418,18 +1430,18 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
|
|
|
1418
1430
|
}
|
|
1419
1431
|
|
|
1420
1432
|
// src/components/feedback/Tooltip.tsx
|
|
1421
|
-
var
|
|
1433
|
+
var React8 = __toESM(require("react"), 1);
|
|
1422
1434
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1423
1435
|
var CLOSE_DELAY_MS = 120;
|
|
1424
1436
|
function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
1425
|
-
const anchorRef =
|
|
1426
|
-
const bubbleRef =
|
|
1427
|
-
const [reason, setReason] =
|
|
1428
|
-
const closeTimer =
|
|
1429
|
-
const id =
|
|
1437
|
+
const anchorRef = React8.useRef(null);
|
|
1438
|
+
const bubbleRef = React8.useRef(null);
|
|
1439
|
+
const [reason, setReason] = React8.useState(null);
|
|
1440
|
+
const closeTimer = React8.useRef(null);
|
|
1441
|
+
const id = React8.useId();
|
|
1430
1442
|
const descId = id + "-desc";
|
|
1431
1443
|
const open = reason != null;
|
|
1432
|
-
const cancelClose =
|
|
1444
|
+
const cancelClose = React8.useCallback(() => {
|
|
1433
1445
|
if (closeTimer.current) {
|
|
1434
1446
|
clearTimeout(closeTimer.current);
|
|
1435
1447
|
closeTimer.current = null;
|
|
@@ -1439,7 +1451,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1439
1451
|
cancelClose();
|
|
1440
1452
|
setReason(why);
|
|
1441
1453
|
};
|
|
1442
|
-
const hide =
|
|
1454
|
+
const hide = React8.useCallback(() => {
|
|
1443
1455
|
cancelClose();
|
|
1444
1456
|
setReason(null);
|
|
1445
1457
|
}, [cancelClose]);
|
|
@@ -1454,7 +1466,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1454
1466
|
setReason((r) => r === "hover" ? null : r);
|
|
1455
1467
|
}, CLOSE_DELAY_MS);
|
|
1456
1468
|
};
|
|
1457
|
-
|
|
1469
|
+
React8.useEffect(() => cancelClose, [cancelClose]);
|
|
1458
1470
|
const pos = usePopoverPosition(open, anchorRef, {
|
|
1459
1471
|
placement: placement === "bottom" ? "bottom-center" : "top-center",
|
|
1460
1472
|
offset: 8,
|
|
@@ -1464,7 +1476,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1464
1476
|
onDetach: hide
|
|
1465
1477
|
});
|
|
1466
1478
|
const zIndex = useOverlayLayer(open);
|
|
1467
|
-
|
|
1479
|
+
React8.useEffect(() => {
|
|
1468
1480
|
if (!open) return;
|
|
1469
1481
|
const key = (e) => {
|
|
1470
1482
|
if (e.key === "Escape") hide();
|
|
@@ -1492,7 +1504,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1492
1504
|
}
|
|
1493
1505
|
if (keyboard) show("focus");
|
|
1494
1506
|
};
|
|
1495
|
-
const described =
|
|
1507
|
+
const described = React8.isValidElement(children) ? React8.cloneElement(children, {
|
|
1496
1508
|
"aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
|
|
1497
1509
|
}) : children;
|
|
1498
1510
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
@@ -1500,7 +1512,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1500
1512
|
{
|
|
1501
1513
|
ref: anchorRef,
|
|
1502
1514
|
className: "fd-tooltip-anchor",
|
|
1503
|
-
"aria-describedby":
|
|
1515
|
+
"aria-describedby": React8.isValidElement(children) ? void 0 : descId,
|
|
1504
1516
|
onPointerEnter: (e) => {
|
|
1505
1517
|
if (isMouse(e)) hover();
|
|
1506
1518
|
},
|
|
@@ -1544,7 +1556,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1544
1556
|
}
|
|
1545
1557
|
|
|
1546
1558
|
// src/components/data/Clamp.tsx
|
|
1547
|
-
var
|
|
1559
|
+
var React9 = __toESM(require("react"), 1);
|
|
1548
1560
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1549
1561
|
function Clamp({
|
|
1550
1562
|
children,
|
|
@@ -1556,16 +1568,16 @@ function Clamp({
|
|
|
1556
1568
|
onToggle,
|
|
1557
1569
|
className = ""
|
|
1558
1570
|
}) {
|
|
1559
|
-
const [open, setOpen] =
|
|
1560
|
-
const [overflows, setOverflows] =
|
|
1561
|
-
const bodyRef =
|
|
1562
|
-
const charClamped =
|
|
1571
|
+
const [open, setOpen] = React9.useState(false);
|
|
1572
|
+
const [overflows, setOverflows] = React9.useState(false);
|
|
1573
|
+
const bodyRef = React9.useRef(null);
|
|
1574
|
+
const charClamped = React9.useMemo(() => {
|
|
1563
1575
|
if (open || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
|
|
1564
1576
|
const cut = text.slice(0, maxChars);
|
|
1565
1577
|
const at = cut.lastIndexOf(" ");
|
|
1566
1578
|
return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
1567
1579
|
}, [text, maxChars, open]);
|
|
1568
|
-
|
|
1580
|
+
React9.useLayoutEffect(() => {
|
|
1569
1581
|
const node = bodyRef.current;
|
|
1570
1582
|
if (maxChars || !node || !maxHeight) return;
|
|
1571
1583
|
const measure = () => {
|
|
@@ -1704,18 +1716,18 @@ function DataTable({
|
|
|
1704
1716
|
}
|
|
1705
1717
|
|
|
1706
1718
|
// src/components/data/FilterBar.tsx
|
|
1707
|
-
var
|
|
1719
|
+
var React10 = __toESM(require("react"), 1);
|
|
1708
1720
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1709
1721
|
var isSet = (v) => !(v == null || v === "" || v === false);
|
|
1710
1722
|
function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", className = "", ...rest }) {
|
|
1711
|
-
const [panel, setPanel] =
|
|
1723
|
+
const [panel, setPanel] = React10.useState(null);
|
|
1712
1724
|
const zIndex = useOverlayLayer(!!panel);
|
|
1713
|
-
const rootRef =
|
|
1714
|
-
const textInputRef =
|
|
1715
|
-
const optionsRef =
|
|
1725
|
+
const rootRef = React10.useRef(null);
|
|
1726
|
+
const textInputRef = React10.useRef(null);
|
|
1727
|
+
const optionsRef = React10.useRef(null);
|
|
1716
1728
|
const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
|
|
1717
1729
|
const dismissible = !!panel && (panel.kind === "add" || panel.kind === "edit" && editingField?.type === "select");
|
|
1718
|
-
|
|
1730
|
+
React10.useEffect(() => {
|
|
1719
1731
|
if (!dismissible) return;
|
|
1720
1732
|
const away = (e) => {
|
|
1721
1733
|
if (rootRef.current && !rootRef.current.contains(e.target)) setPanel(null);
|
|
@@ -1730,7 +1742,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1730
1742
|
document.removeEventListener("keydown", esc);
|
|
1731
1743
|
};
|
|
1732
1744
|
}, [dismissible]);
|
|
1733
|
-
|
|
1745
|
+
React10.useEffect(() => {
|
|
1734
1746
|
if (!panel || panel.kind !== "edit") return;
|
|
1735
1747
|
if (editingField?.type === "text") {
|
|
1736
1748
|
textInputRef.current?.focus();
|
|
@@ -1896,7 +1908,7 @@ function StatTile({ label, value, sub, delta, loading = false, compact: compact3
|
|
|
1896
1908
|
}
|
|
1897
1909
|
|
|
1898
1910
|
// src/components/data/CodeBlock.tsx
|
|
1899
|
-
var
|
|
1911
|
+
var React11 = __toESM(require("react"), 1);
|
|
1900
1912
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1901
1913
|
var JS_KW = /^(?:const|let|var|function|return|if|else|for|while|do|new|class|extends|import|from|export|default|await|async|try|catch|finally|throw|typeof|instanceof|of|in|switch|case|break|continue|delete|void|yield|static|get|set|this|super|interface|type|enum|implements|public|private|protected|readonly|abstract|as|satisfies|declare|namespace)$/;
|
|
1902
1914
|
var RULES = {
|
|
@@ -2052,13 +2064,13 @@ function tokenize(src, lang) {
|
|
|
2052
2064
|
return out;
|
|
2053
2065
|
}
|
|
2054
2066
|
function Highlighted({ code, lang }) {
|
|
2055
|
-
const toks =
|
|
2067
|
+
const toks = React11.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
2056
2068
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_jsx_runtime30.Fragment, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
|
|
2057
2069
|
}
|
|
2058
2070
|
function useCopy() {
|
|
2059
|
-
const [done, setDone] =
|
|
2060
|
-
const timer =
|
|
2061
|
-
|
|
2071
|
+
const [done, setDone] = React11.useState(false);
|
|
2072
|
+
const timer = React11.useRef(null);
|
|
2073
|
+
React11.useEffect(() => () => {
|
|
2062
2074
|
if (timer.current) clearTimeout(timer.current);
|
|
2063
2075
|
}, []);
|
|
2064
2076
|
const copy = (text) => {
|
|
@@ -2094,8 +2106,8 @@ function CodeBlock({
|
|
|
2094
2106
|
actions,
|
|
2095
2107
|
className = ""
|
|
2096
2108
|
}) {
|
|
2097
|
-
const [wrap, setWrap] =
|
|
2098
|
-
const [open, setOpen] =
|
|
2109
|
+
const [wrap, setWrap] = React11.useState(!!wrapDefault);
|
|
2110
|
+
const [open, setOpen] = React11.useState(false);
|
|
2099
2111
|
const [copied, copy] = useCopy();
|
|
2100
2112
|
const body = String(code).replace(/\n$/, "");
|
|
2101
2113
|
const lines = body.split("\n");
|
|
@@ -2124,7 +2136,7 @@ function CodeBlock({
|
|
|
2124
2136
|
] });
|
|
2125
2137
|
}
|
|
2126
2138
|
function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
|
|
2127
|
-
const [open, setOpen] =
|
|
2139
|
+
const [open, setOpen] = React11.useState(false);
|
|
2128
2140
|
const [copied, copy] = useCopy();
|
|
2129
2141
|
const raw = String(diff).replace(/\n$/, "");
|
|
2130
2142
|
const all = raw.split("\n").map((line) => {
|
|
@@ -2170,7 +2182,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
2170
2182
|
}
|
|
2171
2183
|
|
|
2172
2184
|
// src/components/data/Markdown.tsx
|
|
2173
|
-
var
|
|
2185
|
+
var React12 = __toESM(require("react"), 1);
|
|
2174
2186
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
2175
2187
|
var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
|
|
2176
2188
|
var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
|
|
@@ -2209,7 +2221,7 @@ function inlineNodes(src, ctx, keyBase) {
|
|
|
2209
2221
|
const href = safeHref(g(2));
|
|
2210
2222
|
out.push(href ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("a", { href, title: g(3) || void 0, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: inlineNodes(g(1), ctx, key()) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { children: g(1) }, key()));
|
|
2211
2223
|
} else if (kind === "cite") {
|
|
2212
|
-
out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
2224
|
+
out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(React12.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("sup", { className: "fd-md-cite", children: g(1) }, key()));
|
|
2213
2225
|
} else if (kind === "strongem") out.push(/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("strong", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
|
|
2214
2226
|
else if (kind === "strong") out.push(/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
2215
2227
|
else if (kind === "em") out.push(/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
@@ -2374,7 +2386,7 @@ function Markdown({
|
|
|
2374
2386
|
onLinkClick
|
|
2375
2387
|
}) {
|
|
2376
2388
|
const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
|
|
2377
|
-
const blocks =
|
|
2389
|
+
const blocks = React12.useMemo(() => parseBlocks(source), [source]);
|
|
2378
2390
|
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
|
|
2379
2391
|
}
|
|
2380
2392
|
function MarkdownInline({ source = "", className = "", onLinkClick }) {
|
|
@@ -2488,7 +2500,7 @@ function Pagination({
|
|
|
2488
2500
|
}
|
|
2489
2501
|
|
|
2490
2502
|
// src/components/data/RelativeTime.tsx
|
|
2491
|
-
var
|
|
2503
|
+
var React13 = __toESM(require("react"), 1);
|
|
2492
2504
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
2493
2505
|
var MIN = 6e4;
|
|
2494
2506
|
var HOUR = 36e5;
|
|
@@ -2540,9 +2552,9 @@ function formatDuration(ms) {
|
|
|
2540
2552
|
return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
|
|
2541
2553
|
}
|
|
2542
2554
|
function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
|
|
2543
|
-
const [, force] =
|
|
2555
|
+
const [, force] = React13.useState(0);
|
|
2544
2556
|
const t = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
2545
|
-
|
|
2557
|
+
React13.useEffect(() => {
|
|
2546
2558
|
if (!refresh2 || !t || isNaN(t)) return;
|
|
2547
2559
|
const abs = Math.abs(t - Date.now());
|
|
2548
2560
|
if (abs > DAY) return;
|
|
@@ -2558,10 +2570,10 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
|
|
|
2558
2570
|
}
|
|
2559
2571
|
|
|
2560
2572
|
// src/components/data/ScoreMeter.tsx
|
|
2561
|
-
var
|
|
2573
|
+
var React15 = __toESM(require("react"), 1);
|
|
2562
2574
|
|
|
2563
2575
|
// src/components/data/SegmentedMeter.tsx
|
|
2564
|
-
var
|
|
2576
|
+
var React14 = __toESM(require("react"), 1);
|
|
2565
2577
|
|
|
2566
2578
|
// src/kits/files.ts
|
|
2567
2579
|
function formatBytes(n) {
|
|
@@ -2766,7 +2778,7 @@ function SegmentedMeter({
|
|
|
2766
2778
|
const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
|
|
2767
2779
|
const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
|
|
2768
2780
|
const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
|
|
2769
|
-
const generatedId =
|
|
2781
|
+
const generatedId = React14.useId();
|
|
2770
2782
|
const uid2 = id || generatedId;
|
|
2771
2783
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
|
|
2772
2784
|
label || showTotal ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "fd-segmeter-head", children: [
|
|
@@ -2850,10 +2862,10 @@ function ScoreMeter({
|
|
|
2850
2862
|
breakdownWidth = 280,
|
|
2851
2863
|
className = ""
|
|
2852
2864
|
}) {
|
|
2853
|
-
const [open, setOpen] =
|
|
2854
|
-
const ref =
|
|
2865
|
+
const [open, setOpen] = React15.useState(false);
|
|
2866
|
+
const ref = React15.useRef(null);
|
|
2855
2867
|
const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
2856
|
-
const body = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
2868
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(React15.Fragment, { children: [
|
|
2857
2869
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
|
|
2858
2870
|
showScore ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
|
|
2859
2871
|
] });
|
|
@@ -2872,7 +2884,7 @@ function ScoreMeter({
|
|
|
2872
2884
|
}
|
|
2873
2885
|
);
|
|
2874
2886
|
}
|
|
2875
|
-
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
2887
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(React15.Fragment, { children: [
|
|
2876
2888
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2877
2889
|
"button",
|
|
2878
2890
|
{
|
|
@@ -2903,13 +2915,13 @@ function ScoreMeter({
|
|
|
2903
2915
|
}
|
|
2904
2916
|
|
|
2905
2917
|
// src/components/data/SortMenu.tsx
|
|
2906
|
-
var
|
|
2918
|
+
var React16 = __toESM(require("react"), 1);
|
|
2907
2919
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
2908
2920
|
function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", className = "", ...rest }) {
|
|
2909
|
-
const [open, setOpen] =
|
|
2921
|
+
const [open, setOpen] = React16.useState(false);
|
|
2910
2922
|
const zIndex = useOverlayLayer(open);
|
|
2911
|
-
const ref =
|
|
2912
|
-
|
|
2923
|
+
const ref = React16.useRef(null);
|
|
2924
|
+
React16.useEffect(() => {
|
|
2913
2925
|
if (!open) return;
|
|
2914
2926
|
const away = (e) => {
|
|
2915
2927
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -2971,7 +2983,7 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
|
|
|
2971
2983
|
}
|
|
2972
2984
|
|
|
2973
2985
|
// src/components/data/StepList.tsx
|
|
2974
|
-
var
|
|
2986
|
+
var React17 = __toESM(require("react"), 1);
|
|
2975
2987
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
2976
2988
|
var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
|
|
2977
2989
|
function StepList({
|
|
@@ -2984,9 +2996,9 @@ function StepList({
|
|
|
2984
2996
|
dense = false,
|
|
2985
2997
|
className = ""
|
|
2986
2998
|
}) {
|
|
2987
|
-
const [openState, setOpenState] =
|
|
2999
|
+
const [openState, setOpenState] = React17.useState(defaultOpen);
|
|
2988
3000
|
const open = openProp == null ? openState : openProp;
|
|
2989
|
-
const [expanded, setExpanded] =
|
|
3001
|
+
const [expanded, setExpanded] = React17.useState({});
|
|
2990
3002
|
if (!steps.length) return null;
|
|
2991
3003
|
const running = steps.some((s) => s.status === "running");
|
|
2992
3004
|
const failed = steps.filter((s) => s.status === "error").length;
|
|
@@ -3044,7 +3056,7 @@ function StepList({
|
|
|
3044
3056
|
}
|
|
3045
3057
|
|
|
3046
3058
|
// src/components/data/VirtualList.tsx
|
|
3047
|
-
var
|
|
3059
|
+
var React18 = __toESM(require("react"), 1);
|
|
3048
3060
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
3049
3061
|
var VIRTUAL_LIST_BUFFER_ROWS = 20;
|
|
3050
3062
|
var VIRTUAL_LIST_ROW_GAP = 6;
|
|
@@ -3096,35 +3108,35 @@ function VirtualList({
|
|
|
3096
3108
|
className = "",
|
|
3097
3109
|
style
|
|
3098
3110
|
}) {
|
|
3099
|
-
const [scrollTop, setScrollTop] =
|
|
3100
|
-
const loaded =
|
|
3111
|
+
const [scrollTop, setScrollTop] = React18.useState(0);
|
|
3112
|
+
const loaded = React18.useMemo(
|
|
3101
3113
|
() => ({ firstItemIndex, count: items.length }),
|
|
3102
3114
|
[firstItemIndex, items.length]
|
|
3103
3115
|
);
|
|
3104
3116
|
const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
|
|
3105
3117
|
const bandKey = firstItemIndex + ":" + items.length;
|
|
3106
|
-
const win =
|
|
3118
|
+
const win = React18.useMemo(
|
|
3107
3119
|
() => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
|
|
3108
3120
|
[scrollTop, height, itemHeight, total, loaded]
|
|
3109
3121
|
);
|
|
3110
|
-
const need =
|
|
3122
|
+
const need = React18.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
|
|
3111
3123
|
const wantStart = need.start && hasMore?.start !== false;
|
|
3112
3124
|
const wantEnd = need.end && hasMore?.end !== false;
|
|
3113
3125
|
const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
|
|
3114
3126
|
const askKey = bandKey + "@" + bucket2;
|
|
3115
|
-
const asked =
|
|
3116
|
-
|
|
3127
|
+
const asked = React18.useRef({ start: null, end: null });
|
|
3128
|
+
React18.useEffect(() => {
|
|
3117
3129
|
if (loading || !wantStart || asked.current.start === askKey) return;
|
|
3118
3130
|
asked.current.start = askKey;
|
|
3119
3131
|
onNeedMore("start", win);
|
|
3120
3132
|
}, [wantStart, loading, askKey, onNeedMore, win]);
|
|
3121
|
-
|
|
3133
|
+
React18.useEffect(() => {
|
|
3122
3134
|
if (loading || !wantEnd || asked.current.end === askKey) return;
|
|
3123
3135
|
asked.current.end = askKey;
|
|
3124
3136
|
onNeedMore("end", win);
|
|
3125
3137
|
}, [wantEnd, loading, askKey, onNeedMore, win]);
|
|
3126
|
-
const lastKeysRef =
|
|
3127
|
-
const newKeys =
|
|
3138
|
+
const lastKeysRef = React18.useRef(null);
|
|
3139
|
+
const newKeys = React18.useMemo(() => {
|
|
3128
3140
|
const prev = lastKeysRef.current;
|
|
3129
3141
|
if (!prev) return /* @__PURE__ */ new Set();
|
|
3130
3142
|
const fresh = /* @__PURE__ */ new Set();
|
|
@@ -3134,7 +3146,7 @@ function VirtualList({
|
|
|
3134
3146
|
}
|
|
3135
3147
|
return fresh;
|
|
3136
3148
|
}, [items]);
|
|
3137
|
-
|
|
3149
|
+
React18.useEffect(() => {
|
|
3138
3150
|
lastKeysRef.current = new Set(items.map(keyOf));
|
|
3139
3151
|
}, [items]);
|
|
3140
3152
|
const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
|
|
@@ -3179,7 +3191,7 @@ function VirtualList({
|
|
|
3179
3191
|
}
|
|
3180
3192
|
|
|
3181
3193
|
// src/components/data/EntityRow.tsx
|
|
3182
|
-
var
|
|
3194
|
+
var React19 = __toESM(require("react"), 1);
|
|
3183
3195
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
3184
3196
|
var ENTITY_ROW_METRIC_WIDTH = 74;
|
|
3185
3197
|
var METRIC_TONE_COLOR = {
|
|
@@ -3192,7 +3204,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
|
|
|
3192
3204
|
const key = m.id || m.label || i;
|
|
3193
3205
|
const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
|
|
3194
3206
|
const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
|
|
3195
|
-
const content = /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
3207
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(React19.Fragment, { children: [
|
|
3196
3208
|
m.icon ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
|
|
3197
3209
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
|
|
3198
3210
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "fd-sr", children: " " + m.label })
|
|
@@ -3284,14 +3296,14 @@ function EntityRow({
|
|
|
3284
3296
|
}
|
|
3285
3297
|
|
|
3286
3298
|
// src/components/data/TransferList.tsx
|
|
3287
|
-
var
|
|
3299
|
+
var React21 = __toESM(require("react"), 1);
|
|
3288
3300
|
var import_react_dom4 = require("react-dom");
|
|
3289
3301
|
|
|
3290
3302
|
// src/components/forms/field.tsx
|
|
3291
|
-
var
|
|
3303
|
+
var React20 = __toESM(require("react"), 1);
|
|
3292
3304
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
3293
3305
|
function useFieldId(id) {
|
|
3294
|
-
const generated =
|
|
3306
|
+
const generated = React20.useId();
|
|
3295
3307
|
return id || generated;
|
|
3296
3308
|
}
|
|
3297
3309
|
function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
|
|
@@ -3409,12 +3421,12 @@ function TransferList({
|
|
|
3409
3421
|
listHeight = 440,
|
|
3410
3422
|
className = ""
|
|
3411
3423
|
}) {
|
|
3412
|
-
const [drag, setDrag] =
|
|
3413
|
-
const [dragOverSide, setDragOverSide] =
|
|
3414
|
-
const dragRef =
|
|
3415
|
-
const armedRef =
|
|
3416
|
-
const sideRefs =
|
|
3417
|
-
const hitTestSide =
|
|
3424
|
+
const [drag, setDrag] = React21.useState(null);
|
|
3425
|
+
const [dragOverSide, setDragOverSide] = React21.useState(null);
|
|
3426
|
+
const dragRef = React21.useRef(null);
|
|
3427
|
+
const armedRef = React21.useRef(null);
|
|
3428
|
+
const sideRefs = React21.useRef({ left: null, right: null });
|
|
3429
|
+
const hitTestSide = React21.useCallback((x, y) => {
|
|
3418
3430
|
for (const side of ["left", "right"]) {
|
|
3419
3431
|
const el = sideRefs.current[side];
|
|
3420
3432
|
if (!el) continue;
|
|
@@ -3423,7 +3435,7 @@ function TransferList({
|
|
|
3423
3435
|
}
|
|
3424
3436
|
return null;
|
|
3425
3437
|
}, []);
|
|
3426
|
-
const findItem =
|
|
3438
|
+
const findItem = React21.useCallback(
|
|
3427
3439
|
(side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
|
|
3428
3440
|
[left.items, right.items, keyOf]
|
|
3429
3441
|
);
|
|
@@ -3445,7 +3457,7 @@ function TransferList({
|
|
|
3445
3457
|
height: rect.height
|
|
3446
3458
|
};
|
|
3447
3459
|
};
|
|
3448
|
-
|
|
3460
|
+
React21.useEffect(() => {
|
|
3449
3461
|
const onMovePointer = (e) => {
|
|
3450
3462
|
const armed = armedRef.current;
|
|
3451
3463
|
if (!armed || e.pointerId !== armed.pointerId) return;
|
|
@@ -3498,7 +3510,7 @@ function TransferList({
|
|
|
3498
3510
|
window.removeEventListener("pointercancel", endDrag);
|
|
3499
3511
|
};
|
|
3500
3512
|
}, [hitTestSide, findItem, onMove]);
|
|
3501
|
-
|
|
3513
|
+
React21.useEffect(() => {
|
|
3502
3514
|
if (!drag || typeof document === "undefined") return;
|
|
3503
3515
|
const prev = document.body.style.userSelect;
|
|
3504
3516
|
document.body.style.userSelect = "none";
|
|
@@ -3606,11 +3618,11 @@ function TransferList({
|
|
|
3606
3618
|
}
|
|
3607
3619
|
|
|
3608
3620
|
// src/components/forms/Checkbox.tsx
|
|
3609
|
-
var
|
|
3621
|
+
var React22 = __toESM(require("react"), 1);
|
|
3610
3622
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
3611
3623
|
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
3612
|
-
const ref =
|
|
3613
|
-
|
|
3624
|
+
const ref = React22.useRef(null);
|
|
3625
|
+
React22.useEffect(() => {
|
|
3614
3626
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
3615
3627
|
}, [indeterminate]);
|
|
3616
3628
|
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
@@ -3669,7 +3681,7 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
|
|
|
3669
3681
|
}
|
|
3670
3682
|
|
|
3671
3683
|
// src/components/forms/NumberInput.tsx
|
|
3672
|
-
var
|
|
3684
|
+
var React23 = __toESM(require("react"), 1);
|
|
3673
3685
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
3674
3686
|
function NumberInput({
|
|
3675
3687
|
label,
|
|
@@ -3697,10 +3709,10 @@ function NumberInput({
|
|
|
3697
3709
|
const n = Number(String(v == null ? "" : v).replace(/[^0-9.-]/g, ""));
|
|
3698
3710
|
return isNaN(n) ? null : n;
|
|
3699
3711
|
};
|
|
3700
|
-
const [text, setText] =
|
|
3701
|
-
const [editing, setEditing] =
|
|
3702
|
-
const timer =
|
|
3703
|
-
|
|
3712
|
+
const [text, setText] = React23.useState(value == null || value === "" ? "" : String(value));
|
|
3713
|
+
const [editing, setEditing] = React23.useState(false);
|
|
3714
|
+
const timer = React23.useRef(null);
|
|
3715
|
+
React23.useEffect(() => {
|
|
3704
3716
|
if (!editing) setText(value == null || value === "" ? "" : String(value));
|
|
3705
3717
|
}, [value, editing]);
|
|
3706
3718
|
const clamp = (n) => Math.min(max, Math.max(min, n));
|
|
@@ -3724,7 +3736,7 @@ function NumberInput({
|
|
|
3724
3736
|
const release = () => {
|
|
3725
3737
|
if (timer.current) clearTimeout(timer.current);
|
|
3726
3738
|
};
|
|
3727
|
-
|
|
3739
|
+
React23.useEffect(() => () => {
|
|
3728
3740
|
if (timer.current) clearTimeout(timer.current);
|
|
3729
3741
|
}, []);
|
|
3730
3742
|
const shown = editing ? text : (() => {
|
|
@@ -3811,7 +3823,7 @@ function NumberInput({
|
|
|
3811
3823
|
}
|
|
3812
3824
|
|
|
3813
3825
|
// src/components/forms/Select.tsx
|
|
3814
|
-
var
|
|
3826
|
+
var React24 = __toESM(require("react"), 1);
|
|
3815
3827
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
3816
3828
|
var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
|
|
3817
3829
|
function Select({
|
|
@@ -3838,13 +3850,13 @@ function Select({
|
|
|
3838
3850
|
const isOn = (v) => multiple ? vals.includes(v) : v === value;
|
|
3839
3851
|
const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
|
|
3840
3852
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
3841
|
-
const [open, setOpen] =
|
|
3842
|
-
const [q, setQ] =
|
|
3843
|
-
const [active, setActive] =
|
|
3844
|
-
const rootRef =
|
|
3845
|
-
const boxRef =
|
|
3846
|
-
const listRef =
|
|
3847
|
-
const typeBuf =
|
|
3853
|
+
const [open, setOpen] = React24.useState(false);
|
|
3854
|
+
const [q, setQ] = React24.useState("");
|
|
3855
|
+
const [active, setActive] = React24.useState(-1);
|
|
3856
|
+
const rootRef = React24.useRef(null);
|
|
3857
|
+
const boxRef = React24.useRef(null);
|
|
3858
|
+
const listRef = React24.useRef(null);
|
|
3859
|
+
const typeBuf = React24.useRef({ s: "", t: 0 });
|
|
3848
3860
|
const selected = multiple ? null : opts.find((o) => o.value === value);
|
|
3849
3861
|
const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
|
|
3850
3862
|
const boxText = multiple ? chosen.length === 0 ? placeholder : chosen.length === 1 ? chosen[0].label : summary ? summary(chosen.map((o) => o.value)) : chosen.length + " selected" : selected ? selected.label : placeholder;
|
|
@@ -3869,7 +3881,7 @@ function Select({
|
|
|
3869
3881
|
}
|
|
3870
3882
|
setOpen(!open);
|
|
3871
3883
|
};
|
|
3872
|
-
|
|
3884
|
+
React24.useEffect(() => {
|
|
3873
3885
|
if (!open || active < 0 || !listRef.current) return;
|
|
3874
3886
|
const el = listRef.current.querySelector('[data-i="' + active + '"]');
|
|
3875
3887
|
if (el) {
|
|
@@ -3990,7 +4002,7 @@ function Select({
|
|
|
3990
4002
|
),
|
|
3991
4003
|
q ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
|
|
3992
4004
|
] }) : void 0,
|
|
3993
|
-
footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
4005
|
+
footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React24.Fragment, { children: [
|
|
3994
4006
|
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3995
4007
|
"button",
|
|
3996
4008
|
{
|
|
@@ -4021,7 +4033,7 @@ function Select({
|
|
|
4021
4033
|
'Nothing matches "',
|
|
4022
4034
|
q,
|
|
4023
4035
|
'".'
|
|
4024
|
-
] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
4036
|
+
] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React24.Fragment, { children: [
|
|
4025
4037
|
grp.g ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "fd-pop-group", children: grp.g }) : null,
|
|
4026
4038
|
grp.items.map(({ o, i }) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
4027
4039
|
"button",
|
|
@@ -4058,7 +4070,7 @@ function Select({
|
|
|
4058
4070
|
}
|
|
4059
4071
|
|
|
4060
4072
|
// src/components/forms/DatePicker.tsx
|
|
4061
|
-
var
|
|
4073
|
+
var React25 = __toESM(require("react"), 1);
|
|
4062
4074
|
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
4063
4075
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
4064
4076
|
var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
@@ -4076,10 +4088,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
4076
4088
|
const today = /* @__PURE__ */ new Date();
|
|
4077
4089
|
const sel = range ? value || {} : { start: value, end: value };
|
|
4078
4090
|
const anchor = parse(sel.start) || parse(initialMonth) || today;
|
|
4079
|
-
const [vy, setVy] =
|
|
4080
|
-
const [vm, setVm] =
|
|
4081
|
-
const [mode2, setMode] =
|
|
4082
|
-
const [hover, setHover] =
|
|
4091
|
+
const [vy, setVy] = React25.useState(anchor.getFullYear());
|
|
4092
|
+
const [vm, setVm] = React25.useState(anchor.getMonth());
|
|
4093
|
+
const [mode2, setMode] = React25.useState("days");
|
|
4094
|
+
const [hover, setHover] = React25.useState(null);
|
|
4083
4095
|
const s = parse(sel.start), e = parse(sel.end);
|
|
4084
4096
|
const hoverEnd = range && s && !e && hover ? parse(hover) : null;
|
|
4085
4097
|
const inRange = (d) => {
|
|
@@ -4195,9 +4207,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
4195
4207
|
}
|
|
4196
4208
|
function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, ...rest }) {
|
|
4197
4209
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
4198
|
-
const [open, setOpen] =
|
|
4199
|
-
const rootRef =
|
|
4200
|
-
const boxRef =
|
|
4210
|
+
const [open, setOpen] = React25.useState(false);
|
|
4211
|
+
const rootRef = React25.useRef(null);
|
|
4212
|
+
const boxRef = React25.useRef(null);
|
|
4201
4213
|
const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
|
|
4202
4214
|
const toggle = () => {
|
|
4203
4215
|
if (!disabled) setOpen(!open);
|
|
@@ -4260,7 +4272,7 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
|
|
|
4260
4272
|
}
|
|
4261
4273
|
|
|
4262
4274
|
// src/components/forms/TimePicker.tsx
|
|
4263
|
-
var
|
|
4275
|
+
var React26 = __toESM(require("react"), 1);
|
|
4264
4276
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
4265
4277
|
var pad = (n) => String(n).padStart(2, "0");
|
|
4266
4278
|
function ClockFace({ value = "09:00", onChange }) {
|
|
@@ -4269,9 +4281,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
4269
4281
|
if (isNaN(m)) m = 0;
|
|
4270
4282
|
const pm = h24 >= 12;
|
|
4271
4283
|
const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
|
|
4272
|
-
const [mode2, setMode] =
|
|
4273
|
-
const faceRef =
|
|
4274
|
-
const dragging =
|
|
4284
|
+
const [mode2, setMode] = React26.useState("h");
|
|
4285
|
+
const faceRef = React26.useRef(null);
|
|
4286
|
+
const dragging = React26.useRef(false);
|
|
4275
4287
|
const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
|
|
4276
4288
|
const R = 108, NR = 80;
|
|
4277
4289
|
const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
|
|
@@ -4344,9 +4356,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
4344
4356
|
}
|
|
4345
4357
|
function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
|
|
4346
4358
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
4347
|
-
const [open, setOpen] =
|
|
4348
|
-
const rootRef =
|
|
4349
|
-
const boxRef =
|
|
4359
|
+
const [open, setOpen] = React26.useState(false);
|
|
4360
|
+
const rootRef = React26.useRef(null);
|
|
4361
|
+
const boxRef = React26.useRef(null);
|
|
4350
4362
|
const disp = () => {
|
|
4351
4363
|
if (!value) return "";
|
|
4352
4364
|
const [h, m] = value.split(":").map(Number);
|
|
@@ -4389,7 +4401,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
4389
4401
|
offset: 6,
|
|
4390
4402
|
width: 262,
|
|
4391
4403
|
role: "presentation",
|
|
4392
|
-
footer: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
4404
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(React26.Fragment, { children: [
|
|
4393
4405
|
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
4394
4406
|
"button",
|
|
4395
4407
|
{
|
|
@@ -4417,7 +4429,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
4417
4429
|
}
|
|
4418
4430
|
|
|
4419
4431
|
// src/components/forms/Slider.tsx
|
|
4420
|
-
var
|
|
4432
|
+
var React27 = __toESM(require("react"), 1);
|
|
4421
4433
|
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
4422
4434
|
function Slider({
|
|
4423
4435
|
label,
|
|
@@ -4435,7 +4447,7 @@ function Slider({
|
|
|
4435
4447
|
...rest
|
|
4436
4448
|
}) {
|
|
4437
4449
|
const fieldId = useFieldId(id);
|
|
4438
|
-
const [dragging, setDragging] =
|
|
4450
|
+
const [dragging, setDragging] = React27.useState(false);
|
|
4439
4451
|
const v = value === void 0 ? min : Number(value);
|
|
4440
4452
|
const pct = max === min ? 0 : (v - min) / (max - min) * 100;
|
|
4441
4453
|
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
|
|
@@ -4469,7 +4481,7 @@ function Slider({
|
|
|
4469
4481
|
}
|
|
4470
4482
|
|
|
4471
4483
|
// src/components/forms/RangeSlider.tsx
|
|
4472
|
-
var
|
|
4484
|
+
var React28 = __toESM(require("react"), 1);
|
|
4473
4485
|
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
4474
4486
|
function RangeSlider({
|
|
4475
4487
|
label,
|
|
@@ -4489,9 +4501,9 @@ function RangeSlider({
|
|
|
4489
4501
|
}) {
|
|
4490
4502
|
const fmt2 = format || ((v) => String(v));
|
|
4491
4503
|
const [a, b] = value || [min, max];
|
|
4492
|
-
const [drag, setDrag] =
|
|
4493
|
-
const [focus, setFocus] =
|
|
4494
|
-
const railRef =
|
|
4504
|
+
const [drag, setDrag] = React28.useState(null);
|
|
4505
|
+
const [focus, setFocus] = React28.useState(null);
|
|
4506
|
+
const railRef = React28.useRef(null);
|
|
4495
4507
|
const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
|
|
4496
4508
|
const clampPair = (i, v) => {
|
|
4497
4509
|
v = Math.min(max, Math.max(min, Math.round(v / step) * step));
|
|
@@ -4506,7 +4518,7 @@ function RangeSlider({
|
|
|
4506
4518
|
const r = railRef.current.getBoundingClientRect();
|
|
4507
4519
|
return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
|
|
4508
4520
|
};
|
|
4509
|
-
|
|
4521
|
+
React28.useEffect(() => {
|
|
4510
4522
|
if (drag === null) return;
|
|
4511
4523
|
const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
|
|
4512
4524
|
const upH = () => setDrag(null);
|
|
@@ -4587,7 +4599,7 @@ function RangeSlider({
|
|
|
4587
4599
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
|
|
4588
4600
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-rail", ref: railRef }),
|
|
4589
4601
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
|
|
4590
|
-
marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
|
|
4602
|
+
marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(React28.Fragment, { children: [
|
|
4591
4603
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
|
|
4592
4604
|
m.label ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
|
|
4593
4605
|
] }, m.value)),
|
|
@@ -4616,7 +4628,7 @@ function RangeSlider({
|
|
|
4616
4628
|
}
|
|
4617
4629
|
|
|
4618
4630
|
// src/components/forms/Dropzone.tsx
|
|
4619
|
-
var
|
|
4631
|
+
var React29 = __toESM(require("react"), 1);
|
|
4620
4632
|
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
4621
4633
|
function Dropzone({
|
|
4622
4634
|
onFiles,
|
|
@@ -4631,8 +4643,8 @@ function Dropzone({
|
|
|
4631
4643
|
className = "",
|
|
4632
4644
|
style
|
|
4633
4645
|
}) {
|
|
4634
|
-
const [over, setOver] =
|
|
4635
|
-
const depth =
|
|
4646
|
+
const [over, setOver] = React29.useState(false);
|
|
4647
|
+
const depth = React29.useRef(0);
|
|
4636
4648
|
const has = (e) => {
|
|
4637
4649
|
const dt = e.dataTransfer;
|
|
4638
4650
|
if (!dt) return false;
|
|
@@ -4694,8 +4706,8 @@ function FilePickButton({
|
|
|
4694
4706
|
className = "",
|
|
4695
4707
|
children
|
|
4696
4708
|
}) {
|
|
4697
|
-
const ref =
|
|
4698
|
-
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
4709
|
+
const ref = React29.useRef(null);
|
|
4710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(React29.Fragment, { children: [
|
|
4699
4711
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
4700
4712
|
"button",
|
|
4701
4713
|
{
|
|
@@ -4728,10 +4740,10 @@ function FilePickButton({
|
|
|
4728
4740
|
}
|
|
4729
4741
|
function useStagedFiles(upload, opts) {
|
|
4730
4742
|
const o = opts || {};
|
|
4731
|
-
const [items, setItems] =
|
|
4732
|
-
const controllers =
|
|
4743
|
+
const [items, setItems] = React29.useState([]);
|
|
4744
|
+
const controllers = React29.useRef({});
|
|
4733
4745
|
const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
|
|
4734
|
-
const run =
|
|
4746
|
+
const run = React29.useCallback((att) => {
|
|
4735
4747
|
if (!upload) return;
|
|
4736
4748
|
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
4737
4749
|
controllers.current[att.id] = ac;
|
|
@@ -4748,14 +4760,14 @@ function useStagedFiles(upload, opts) {
|
|
|
4748
4760
|
delete controllers.current[att.id];
|
|
4749
4761
|
});
|
|
4750
4762
|
}, [upload]);
|
|
4751
|
-
const add =
|
|
4763
|
+
const add = React29.useCallback((files) => {
|
|
4752
4764
|
if (!upload) return [];
|
|
4753
4765
|
const atts = Array.from(files).map((f) => toAttachment(f));
|
|
4754
4766
|
setItems((list) => list.concat(atts));
|
|
4755
4767
|
atts.forEach(run);
|
|
4756
4768
|
return atts;
|
|
4757
4769
|
}, [upload, run]);
|
|
4758
|
-
const remove =
|
|
4770
|
+
const remove = React29.useCallback((att) => {
|
|
4759
4771
|
const ac = controllers.current[att.id];
|
|
4760
4772
|
if (ac) {
|
|
4761
4773
|
try {
|
|
@@ -4766,10 +4778,10 @@ function useStagedFiles(upload, opts) {
|
|
|
4766
4778
|
}
|
|
4767
4779
|
setItems((list) => list.filter((f) => f.id !== att.id));
|
|
4768
4780
|
}, []);
|
|
4769
|
-
const retry =
|
|
4781
|
+
const retry = React29.useCallback((att) => {
|
|
4770
4782
|
run(att);
|
|
4771
4783
|
}, [run]);
|
|
4772
|
-
const clear =
|
|
4784
|
+
const clear = React29.useCallback(() => {
|
|
4773
4785
|
Object.values(controllers.current).forEach((ac) => {
|
|
4774
4786
|
try {
|
|
4775
4787
|
ac && ac.abort();
|
|
@@ -4893,7 +4905,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
|
|
|
4893
4905
|
}
|
|
4894
4906
|
|
|
4895
4907
|
// src/components/forms/MarkdownEditor.tsx
|
|
4896
|
-
var
|
|
4908
|
+
var React30 = __toESM(require("react"), 1);
|
|
4897
4909
|
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
4898
4910
|
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
|
|
4899
4911
|
var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
|
|
@@ -5107,7 +5119,7 @@ function syncDom(root, value) {
|
|
|
5107
5119
|
while (root.children.length > lines.length) root.removeChild(root.lastChild);
|
|
5108
5120
|
}
|
|
5109
5121
|
var LIST_CONT = RE_LI;
|
|
5110
|
-
var MarkdownEditor =
|
|
5122
|
+
var MarkdownEditor = React30.forwardRef(function MarkdownEditor2({
|
|
5111
5123
|
value = "",
|
|
5112
5124
|
onChange,
|
|
5113
5125
|
onSubmit,
|
|
@@ -5126,10 +5138,10 @@ var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
|
|
|
5126
5138
|
className = "",
|
|
5127
5139
|
id
|
|
5128
5140
|
}, ref) {
|
|
5129
|
-
const boxRef =
|
|
5130
|
-
const composing =
|
|
5131
|
-
const pendingCaret =
|
|
5132
|
-
|
|
5141
|
+
const boxRef = React30.useRef(null);
|
|
5142
|
+
const composing = React30.useRef(false);
|
|
5143
|
+
const pendingCaret = React30.useRef(null);
|
|
5144
|
+
React30.useLayoutEffect(() => {
|
|
5133
5145
|
const root = boxRef.current;
|
|
5134
5146
|
if (!root || composing.current) return;
|
|
5135
5147
|
const active = document.activeElement === root || root.contains(document.activeElement);
|
|
@@ -5138,7 +5150,7 @@ var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
|
|
|
5138
5150
|
pendingCaret.current = null;
|
|
5139
5151
|
if (active && caret != null) placeCaret(root, caret);
|
|
5140
5152
|
}, [value]);
|
|
5141
|
-
|
|
5153
|
+
React30.useEffect(() => {
|
|
5142
5154
|
if (autoFocus && boxRef.current) boxRef.current.focus();
|
|
5143
5155
|
}, [autoFocus]);
|
|
5144
5156
|
const caretNow = () => {
|
|
@@ -5205,7 +5217,7 @@ var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
|
|
|
5205
5217
|
api.replaceRange(from, to, next, from + next.length);
|
|
5206
5218
|
}
|
|
5207
5219
|
};
|
|
5208
|
-
|
|
5220
|
+
React30.useImperativeHandle(ref, () => api);
|
|
5209
5221
|
function detect(text, caret) {
|
|
5210
5222
|
if (!onTrigger) return;
|
|
5211
5223
|
const upto = text.slice(0, caret);
|
|
@@ -5357,16 +5369,16 @@ var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
|
|
|
5357
5369
|
});
|
|
5358
5370
|
|
|
5359
5371
|
// src/components/platform/AccountMenu.tsx
|
|
5360
|
-
var
|
|
5372
|
+
var React32 = __toESM(require("react"), 1);
|
|
5361
5373
|
|
|
5362
5374
|
// src/kits/sessionContext.tsx
|
|
5363
|
-
var
|
|
5364
|
-
var SessionContext =
|
|
5375
|
+
var React31 = __toESM(require("react"), 1);
|
|
5376
|
+
var SessionContext = React31.createContext(null);
|
|
5365
5377
|
function SessionProvider({ value, children }) {
|
|
5366
|
-
return
|
|
5378
|
+
return React31.createElement(SessionContext.Provider, { value }, children);
|
|
5367
5379
|
}
|
|
5368
5380
|
function useSessionContext() {
|
|
5369
|
-
const ctx =
|
|
5381
|
+
const ctx = React31.useContext(SessionContext);
|
|
5370
5382
|
if (!ctx) {
|
|
5371
5383
|
throw new Error(
|
|
5372
5384
|
"useSessionContext() was called outside a <SessionProvider>. Wrap your app root in <SessionProvider value={...}> with your real session, or \u2014 in the docs site or a demo \u2014 in <DemoSessionProvider>, before rendering AccountMenu, Gate, ProfilePage or AppSwitcher."
|
|
@@ -5377,20 +5389,8 @@ function useSessionContext() {
|
|
|
5377
5389
|
|
|
5378
5390
|
// src/components/platform/AccountMenu.tsx
|
|
5379
5391
|
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
5380
|
-
var DEFAULT_LINKS = [
|
|
5381
|
-
|
|
5382
|
-
{ id: "preferences", label: "Preferences", icon: "sliders-horizontal", href: "../admin/index.html#preferences" }
|
|
5383
|
-
];
|
|
5384
|
-
var DEFAULT_GROUPS = [
|
|
5385
|
-
{
|
|
5386
|
-
label: "Administration",
|
|
5387
|
-
links: [
|
|
5388
|
-
{ id: "users", label: "Users", icon: "users-three", href: "../admin/index.html#users", perm: "users.view" },
|
|
5389
|
-
{ id: "roles", label: "Roles & permissions", icon: "shield-check", href: "../admin/index.html#roles", perm: "roles.manage" },
|
|
5390
|
-
{ id: "flags", label: "Feature flags", icon: "toggle-right", href: "../admin/index.html#flags", perm: "flags.manage" }
|
|
5391
|
-
]
|
|
5392
|
-
}
|
|
5393
|
-
];
|
|
5392
|
+
var DEFAULT_LINKS = [];
|
|
5393
|
+
var DEFAULT_GROUPS = [];
|
|
5394
5394
|
function Item({ item, onPick }) {
|
|
5395
5395
|
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
|
|
5396
5396
|
"button",
|
|
@@ -5418,10 +5418,10 @@ function AccountMenu({
|
|
|
5418
5418
|
...rest
|
|
5419
5419
|
}) {
|
|
5420
5420
|
const { user, roles, can: can2, signOut: ctxSignOut, demo } = useSessionContext();
|
|
5421
|
-
const [open, setOpen] =
|
|
5422
|
-
const [switching, setSwitching] =
|
|
5423
|
-
const [signingOut, setSigningOut] =
|
|
5424
|
-
const ref =
|
|
5421
|
+
const [open, setOpen] = React32.useState(false);
|
|
5422
|
+
const [switching, setSwitching] = React32.useState(false);
|
|
5423
|
+
const [signingOut, setSigningOut] = React32.useState(false);
|
|
5424
|
+
const ref = React32.useRef(null);
|
|
5425
5425
|
const visibleLinks = links.filter((l) => !l.perm || can2(l.perm));
|
|
5426
5426
|
const visibleGroups = groups.map((g) => ({ label: g.label, links: g.links.filter((l) => !l.perm || can2(l.perm)) })).filter((g) => g.links.length);
|
|
5427
5427
|
const pick = (item) => {
|
|
@@ -5524,13 +5524,13 @@ function AccountMenu({
|
|
|
5524
5524
|
}
|
|
5525
5525
|
|
|
5526
5526
|
// src/components/platform/AppSwitcher.tsx
|
|
5527
|
-
var
|
|
5527
|
+
var React33 = __toESM(require("react"), 1);
|
|
5528
5528
|
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
5529
5529
|
function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
5530
5530
|
const { apps: contextApps } = useSessionContext();
|
|
5531
5531
|
const apps = appsProp ?? contextApps ?? [];
|
|
5532
|
-
const [open, setOpen] =
|
|
5533
|
-
const anchorRef =
|
|
5532
|
+
const [open, setOpen] = React33.useState(false);
|
|
5533
|
+
const anchorRef = React33.useRef(null);
|
|
5534
5534
|
if (!apps.length) return null;
|
|
5535
5535
|
const items = apps.map((app) => ({
|
|
5536
5536
|
id: app.key,
|
|
@@ -5544,7 +5544,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
5544
5544
|
window.location.href = app.url;
|
|
5545
5545
|
}
|
|
5546
5546
|
}));
|
|
5547
|
-
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
|
|
5547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(React33.Fragment, { children: [
|
|
5548
5548
|
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
5549
5549
|
IconButton,
|
|
5550
5550
|
{
|
|
@@ -5573,10 +5573,10 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
5573
5573
|
}
|
|
5574
5574
|
|
|
5575
5575
|
// src/components/platform/AppearanceMenu.tsx
|
|
5576
|
-
var
|
|
5576
|
+
var React35 = __toESM(require("react"), 1);
|
|
5577
5577
|
|
|
5578
5578
|
// src/kits/appearance.ts
|
|
5579
|
-
var
|
|
5579
|
+
var React34 = __toESM(require("react"), 1);
|
|
5580
5580
|
var DEFAULT_STORAGE_KEY = "fd-appearance";
|
|
5581
5581
|
var DEFAULT_PREFS = {
|
|
5582
5582
|
theme: "system",
|
|
@@ -5671,11 +5671,11 @@ function applyPrefs(prefs, root = document.documentElement) {
|
|
|
5671
5671
|
else root.removeAttribute("data-motion");
|
|
5672
5672
|
}
|
|
5673
5673
|
function useAppearancePrefs(store) {
|
|
5674
|
-
const prefs =
|
|
5675
|
-
|
|
5674
|
+
const prefs = React34.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
5675
|
+
React34.useEffect(() => {
|
|
5676
5676
|
applyPrefs(prefs);
|
|
5677
5677
|
}, [prefs]);
|
|
5678
|
-
|
|
5678
|
+
React34.useEffect(() => {
|
|
5679
5679
|
if (prefs.theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
5680
5680
|
return;
|
|
5681
5681
|
}
|
|
@@ -5684,7 +5684,7 @@ function useAppearancePrefs(store) {
|
|
|
5684
5684
|
mq.addEventListener("change", onChange);
|
|
5685
5685
|
return () => mq.removeEventListener("change", onChange);
|
|
5686
5686
|
}, [prefs]);
|
|
5687
|
-
const update =
|
|
5687
|
+
const update = React34.useCallback(
|
|
5688
5688
|
(patch) => {
|
|
5689
5689
|
store.write({ ...store.getSnapshot(), ...patch });
|
|
5690
5690
|
},
|
|
@@ -5707,15 +5707,15 @@ var TEXT_SCALE_OPTIONS = [
|
|
|
5707
5707
|
{ value: "xl", label: "XL" }
|
|
5708
5708
|
];
|
|
5709
5709
|
function AppearanceMenu({ className = "", store: storeProp, storageKey, storage, defaults }) {
|
|
5710
|
-
const store =
|
|
5710
|
+
const store = React35.useMemo(
|
|
5711
5711
|
() => storeProp ?? createLocalStorageAppearanceStore({ storageKey, storage, defaults }),
|
|
5712
5712
|
[storeProp, storageKey, storage, defaults]
|
|
5713
5713
|
);
|
|
5714
5714
|
const [prefs, update] = useAppearancePrefs(store);
|
|
5715
|
-
const [open, setOpen] =
|
|
5716
|
-
const anchorRef =
|
|
5715
|
+
const [open, setOpen] = React35.useState(false);
|
|
5716
|
+
const anchorRef = React35.useRef(null);
|
|
5717
5717
|
const patch = (p) => update(p);
|
|
5718
|
-
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
5718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(React35.Fragment, { children: [
|
|
5719
5719
|
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
5720
5720
|
IconButton,
|
|
5721
5721
|
{
|
|
@@ -5784,14 +5784,14 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
|
|
|
5784
5784
|
}
|
|
5785
5785
|
|
|
5786
5786
|
// src/components/platform/ApiSpecBrowser.tsx
|
|
5787
|
-
var
|
|
5787
|
+
var React36 = __toESM(require("react"), 1);
|
|
5788
5788
|
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
5789
5789
|
var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
|
|
5790
5790
|
function Json({ obj }) {
|
|
5791
5791
|
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
|
|
5792
5792
|
}
|
|
5793
5793
|
function Endpoint({ s, onRequest }) {
|
|
5794
|
-
const [tried, setTried] =
|
|
5794
|
+
const [tried, setTried] = React36.useState(null);
|
|
5795
5795
|
const run = async () => {
|
|
5796
5796
|
setTried("busy");
|
|
5797
5797
|
const t0 = (window.performance || Date).now();
|
|
@@ -5864,10 +5864,10 @@ function ApiSpecBrowser({
|
|
|
5864
5864
|
className = "",
|
|
5865
5865
|
...rest
|
|
5866
5866
|
}) {
|
|
5867
|
-
const [q, setQ] =
|
|
5868
|
-
const [method, setMethod] =
|
|
5869
|
-
const [mod, setMod] =
|
|
5870
|
-
const [listOnly, setListOnly] =
|
|
5867
|
+
const [q, setQ] = React36.useState("");
|
|
5868
|
+
const [method, setMethod] = React36.useState(null);
|
|
5869
|
+
const [mod, setMod] = React36.useState(null);
|
|
5870
|
+
const [listOnly, setListOnly] = React36.useState(false);
|
|
5871
5871
|
const activeModule = modules && modules.find((m) => m.id === mod);
|
|
5872
5872
|
const hits = spec.filter((s) => (!method || s.method === method) && (!listOnly || s.isList) && (!activeModule || activeModule.endpoints.indexOf(s.id) >= 0) && (!q || (s.path + " " + s.title + " " + s.purpose + " " + (s.usedBy || []).join(" ")).toLowerCase().includes(q.toLowerCase())));
|
|
5873
5873
|
const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
|
|
@@ -5946,7 +5946,7 @@ function ApiSpecBrowser({
|
|
|
5946
5946
|
}
|
|
5947
5947
|
|
|
5948
5948
|
// src/components/platform/ProfilePage.tsx
|
|
5949
|
-
var
|
|
5949
|
+
var React37 = __toESM(require("react"), 1);
|
|
5950
5950
|
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
5951
5951
|
function fieldInitialValue(field, user) {
|
|
5952
5952
|
if (field.value) return field.value(user);
|
|
@@ -5982,21 +5982,21 @@ function ProfilePage({
|
|
|
5982
5982
|
}) {
|
|
5983
5983
|
const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
|
|
5984
5984
|
const user = userProp || sessionUser;
|
|
5985
|
-
const initialFieldValues =
|
|
5985
|
+
const initialFieldValues = React37.useMemo(() => {
|
|
5986
5986
|
const values2 = {};
|
|
5987
5987
|
for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
|
|
5988
5988
|
return values2;
|
|
5989
5989
|
}, [user.id, fields]);
|
|
5990
|
-
const initialNotify =
|
|
5990
|
+
const initialNotify = React37.useMemo(() => {
|
|
5991
5991
|
const values2 = {};
|
|
5992
5992
|
for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
|
|
5993
5993
|
return values2;
|
|
5994
5994
|
}, [user.id, notifications]);
|
|
5995
|
-
const [values, setValues] =
|
|
5996
|
-
const [notify, setNotify] =
|
|
5997
|
-
const [saving, setSaving] =
|
|
5998
|
-
const [saved, setSaved] =
|
|
5999
|
-
const [prevUserId, setPrevUserId] =
|
|
5995
|
+
const [values, setValues] = React37.useState(initialFieldValues);
|
|
5996
|
+
const [notify, setNotify] = React37.useState(initialNotify);
|
|
5997
|
+
const [saving, setSaving] = React37.useState(false);
|
|
5998
|
+
const [saved, setSaved] = React37.useState(false);
|
|
5999
|
+
const [prevUserId, setPrevUserId] = React37.useState(user.id);
|
|
6000
6000
|
if (user.id !== prevUserId) {
|
|
6001
6001
|
setPrevUserId(user.id);
|
|
6002
6002
|
setValues(initialFieldValues);
|
|
@@ -6184,10 +6184,10 @@ function ProfilePage({
|
|
|
6184
6184
|
}
|
|
6185
6185
|
|
|
6186
6186
|
// src/components/platform/RoadmapTimeline.tsx
|
|
6187
|
-
var
|
|
6187
|
+
var React40 = __toESM(require("react"), 1);
|
|
6188
6188
|
|
|
6189
6189
|
// src/kits/session.ts
|
|
6190
|
-
var
|
|
6190
|
+
var React38 = __toESM(require("react"), 1);
|
|
6191
6191
|
var PERMISSION_CATALOG = [
|
|
6192
6192
|
{ group: "Plans", items: [
|
|
6193
6193
|
{ key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
|
|
@@ -7754,8 +7754,8 @@ function roadmap(overrides) {
|
|
|
7754
7754
|
};
|
|
7755
7755
|
}
|
|
7756
7756
|
function useSession() {
|
|
7757
|
-
const [s, setS] =
|
|
7758
|
-
|
|
7757
|
+
const [s, setS] = React38.useState(getSession);
|
|
7758
|
+
React38.useEffect(() => subscribe(setS), []);
|
|
7759
7759
|
return s;
|
|
7760
7760
|
}
|
|
7761
7761
|
var SessionKit = {
|
|
@@ -7788,7 +7788,7 @@ var SessionKit = {
|
|
|
7788
7788
|
};
|
|
7789
7789
|
function DemoSessionProvider({ children }) {
|
|
7790
7790
|
const session = useSession();
|
|
7791
|
-
const value =
|
|
7791
|
+
const value = React38.useMemo(
|
|
7792
7792
|
() => ({
|
|
7793
7793
|
user: session.user,
|
|
7794
7794
|
roles: session.roles,
|
|
@@ -7804,11 +7804,11 @@ function DemoSessionProvider({ children }) {
|
|
|
7804
7804
|
}),
|
|
7805
7805
|
[session]
|
|
7806
7806
|
);
|
|
7807
|
-
return
|
|
7807
|
+
return React38.createElement(SessionProvider, { value }, children);
|
|
7808
7808
|
}
|
|
7809
7809
|
|
|
7810
7810
|
// src/kits/runtime.ts
|
|
7811
|
-
var
|
|
7811
|
+
var React39 = __toESM(require("react"), 1);
|
|
7812
7812
|
var WIRED_ENDPOINTS = [
|
|
7813
7813
|
// Nothing yet. Every id below would come from a real service:
|
|
7814
7814
|
// "plan.get", "placements.list", …
|
|
@@ -7979,8 +7979,8 @@ var RuntimeKit = {
|
|
|
7979
7979
|
};
|
|
7980
7980
|
RuntimeKit.declare(FEATURE_NEEDS);
|
|
7981
7981
|
function useRuntimeMode() {
|
|
7982
|
-
const [m, setM] =
|
|
7983
|
-
|
|
7982
|
+
const [m, setM] = React39.useState(RuntimeKit.getMode());
|
|
7983
|
+
React39.useEffect(() => RuntimeKit.subscribe(setM), []);
|
|
7984
7984
|
return m;
|
|
7985
7985
|
}
|
|
7986
7986
|
function useFeatureStatus(key) {
|
|
@@ -8063,12 +8063,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
8063
8063
|
}
|
|
8064
8064
|
function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
8065
8065
|
const session = SessionKit.useSession();
|
|
8066
|
-
const [project, setProject] =
|
|
8067
|
-
const [q, setQ] =
|
|
8068
|
-
const scrollRef =
|
|
8069
|
-
const nowRef =
|
|
8070
|
-
const rm =
|
|
8071
|
-
const byKey =
|
|
8066
|
+
const [project, setProject] = React40.useState("");
|
|
8067
|
+
const [q, setQ] = React40.useState("");
|
|
8068
|
+
const scrollRef = React40.useRef(null);
|
|
8069
|
+
const nowRef = React40.useRef(null);
|
|
8070
|
+
const rm = React40.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
|
|
8071
|
+
const byKey = React40.useMemo(() => {
|
|
8072
8072
|
const m = {};
|
|
8073
8073
|
rm.items.forEach((i) => {
|
|
8074
8074
|
m[i.key] = i;
|
|
@@ -8077,7 +8077,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
8077
8077
|
}, [rm]);
|
|
8078
8078
|
const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
|
|
8079
8079
|
const projects = [...new Set(rm.items.map((i) => i.project))];
|
|
8080
|
-
|
|
8080
|
+
React40.useEffect(() => {
|
|
8081
8081
|
let raf1 = 0, raf2 = 0;
|
|
8082
8082
|
const place = () => {
|
|
8083
8083
|
const box = scrollRef.current, mark = nowRef.current;
|
|
@@ -8151,7 +8151,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
8151
8151
|
lastPhase = item.phase;
|
|
8152
8152
|
const inPhase = items.filter((i) => i.phase === item.phase).length;
|
|
8153
8153
|
const isBoundary = n === firstPending;
|
|
8154
|
-
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
8154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(React40.Fragment, { children: [
|
|
8155
8155
|
showPhase ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "fd-rm-era", children: [
|
|
8156
8156
|
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
|
|
8157
8157
|
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
|
|
@@ -8195,7 +8195,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
8195
8195
|
}
|
|
8196
8196
|
|
|
8197
8197
|
// src/components/platform/ComingSoon.tsx
|
|
8198
|
-
var
|
|
8198
|
+
var React41 = __toESM(require("react"), 1);
|
|
8199
8199
|
var import_react_dom5 = require("react-dom");
|
|
8200
8200
|
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
8201
8201
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
@@ -8213,8 +8213,8 @@ function writeBypassed(list) {
|
|
|
8213
8213
|
}
|
|
8214
8214
|
}
|
|
8215
8215
|
function useBypass(key) {
|
|
8216
|
-
const [on, setOn] =
|
|
8217
|
-
|
|
8216
|
+
const [on, setOn] = React41.useState(() => !!key && readBypassed().indexOf(key) >= 0);
|
|
8217
|
+
React41.useEffect(() => {
|
|
8218
8218
|
setOn(!!key && readBypassed().indexOf(key) >= 0);
|
|
8219
8219
|
}, [key]);
|
|
8220
8220
|
const set = (next) => {
|
|
@@ -8261,9 +8261,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
|
|
|
8261
8261
|
] });
|
|
8262
8262
|
}
|
|
8263
8263
|
function useHoverCard(open) {
|
|
8264
|
-
const anchor =
|
|
8265
|
-
const [pos, setPos] =
|
|
8266
|
-
|
|
8264
|
+
const anchor = React41.useRef(null);
|
|
8265
|
+
const [pos, setPos] = React41.useState(null);
|
|
8266
|
+
React41.useLayoutEffect(() => {
|
|
8267
8267
|
if (!open || !anchor.current) {
|
|
8268
8268
|
setPos(null);
|
|
8269
8269
|
return;
|
|
@@ -8390,10 +8390,10 @@ function ComingSoon({
|
|
|
8390
8390
|
] });
|
|
8391
8391
|
}
|
|
8392
8392
|
function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
|
|
8393
|
-
const [open, setOpen] =
|
|
8393
|
+
const [open, setOpen] = React41.useState(false);
|
|
8394
8394
|
const [anchor, pos] = useHoverCard(open);
|
|
8395
8395
|
const zIndex = useOverlayLayer(open);
|
|
8396
|
-
const close =
|
|
8396
|
+
const close = React41.useRef(null);
|
|
8397
8397
|
const show = () => {
|
|
8398
8398
|
if (close.current) {
|
|
8399
8399
|
clearTimeout(close.current);
|
|
@@ -8409,7 +8409,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
8409
8409
|
setOpen(false);
|
|
8410
8410
|
}, 140);
|
|
8411
8411
|
};
|
|
8412
|
-
|
|
8412
|
+
React41.useEffect(() => () => {
|
|
8413
8413
|
if (close.current) clearTimeout(close.current);
|
|
8414
8414
|
}, []);
|
|
8415
8415
|
return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
|
|
@@ -8580,14 +8580,14 @@ function PermissionHint({ perm, children }) {
|
|
|
8580
8580
|
}
|
|
8581
8581
|
|
|
8582
8582
|
// src/components/platform/ModeSwitch.tsx
|
|
8583
|
-
var
|
|
8583
|
+
var React42 = __toESM(require("react"), 1);
|
|
8584
8584
|
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
8585
8585
|
function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
|
|
8586
8586
|
const mode2 = useRuntimeMode();
|
|
8587
|
-
const [open, setOpen] =
|
|
8587
|
+
const [open, setOpen] = React42.useState(false);
|
|
8588
8588
|
const zIndex = useOverlayLayer(open);
|
|
8589
|
-
const ref =
|
|
8590
|
-
|
|
8589
|
+
const ref = React42.useRef(null);
|
|
8590
|
+
React42.useEffect(() => {
|
|
8591
8591
|
if (!open) return;
|
|
8592
8592
|
const away = (e) => {
|
|
8593
8593
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -8843,7 +8843,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
8843
8843
|
}
|
|
8844
8844
|
|
|
8845
8845
|
// src/components/planner/MixGap.tsx
|
|
8846
|
-
var
|
|
8846
|
+
var React43 = __toESM(require("react"), 1);
|
|
8847
8847
|
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
8848
8848
|
var MIX_GAP_LAYOUT = {
|
|
8849
8849
|
trackHeight: 30,
|
|
@@ -8858,7 +8858,7 @@ function mixGapOffset(value, max) {
|
|
|
8858
8858
|
}
|
|
8859
8859
|
function MixGap({ rows = [], loading = false, className = "" }) {
|
|
8860
8860
|
const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
|
|
8861
|
-
const [hover, setHover] =
|
|
8861
|
+
const [hover, setHover] = React43.useState(null);
|
|
8862
8862
|
const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
|
|
8863
8863
|
const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
|
|
8864
8864
|
const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
|
|
@@ -9001,7 +9001,7 @@ function ChannelContribution({
|
|
|
9001
9001
|
}
|
|
9002
9002
|
|
|
9003
9003
|
// src/components/planner/BudgetReallocator.tsx
|
|
9004
|
-
var
|
|
9004
|
+
var React44 = __toESM(require("react"), 1);
|
|
9005
9005
|
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
9006
9006
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
9007
9007
|
function BudgetReallocator({
|
|
@@ -9017,8 +9017,8 @@ function BudgetReallocator({
|
|
|
9017
9017
|
onCancel,
|
|
9018
9018
|
className = ""
|
|
9019
9019
|
}) {
|
|
9020
|
-
const [draft, setDraft] =
|
|
9021
|
-
|
|
9020
|
+
const [draft, setDraft] = React44.useState(spend);
|
|
9021
|
+
React44.useEffect(() => setDraft(spend), [spend]);
|
|
9022
9022
|
const dirty = draft !== spend;
|
|
9023
9023
|
const nextCrp = scoreFor ? scoreFor(draft) : crp;
|
|
9024
9024
|
const nextBand = bandFor(nextCrp);
|
|
@@ -9033,10 +9033,10 @@ function BudgetReallocator({
|
|
|
9033
9033
|
setDraft(spend);
|
|
9034
9034
|
if (onCancel) onCancel();
|
|
9035
9035
|
};
|
|
9036
|
-
const trackRef =
|
|
9037
|
-
const chipRef =
|
|
9038
|
-
const [chipLeft, setChipLeft] =
|
|
9039
|
-
|
|
9036
|
+
const trackRef = React44.useRef(null);
|
|
9037
|
+
const chipRef = React44.useRef(null);
|
|
9038
|
+
const [chipLeft, setChipLeft] = React44.useState(null);
|
|
9039
|
+
React44.useLayoutEffect(() => {
|
|
9040
9040
|
const track = trackRef.current;
|
|
9041
9041
|
if (!dirty || !track) {
|
|
9042
9042
|
setChipLeft(null);
|
|
@@ -9223,7 +9223,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "" })
|
|
|
9223
9223
|
}
|
|
9224
9224
|
|
|
9225
9225
|
// src/components/planner/PreferenceMeter.tsx
|
|
9226
|
-
var
|
|
9226
|
+
var React45 = __toESM(require("react"), 1);
|
|
9227
9227
|
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
9228
9228
|
function preferenceScore(criteria) {
|
|
9229
9229
|
const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
|
|
@@ -9253,7 +9253,7 @@ function PreferenceMeter({
|
|
|
9253
9253
|
className = ""
|
|
9254
9254
|
}) {
|
|
9255
9255
|
const value = score == null ? preferenceScore(criteria) : score;
|
|
9256
|
-
const segments =
|
|
9256
|
+
const segments = React45.useMemo(() => preferenceSegments(criteria), [criteria]);
|
|
9257
9257
|
return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
9258
9258
|
ScoreMeter,
|
|
9259
9259
|
{
|
|
@@ -9292,10 +9292,10 @@ function PreferenceMeter({
|
|
|
9292
9292
|
}
|
|
9293
9293
|
|
|
9294
9294
|
// src/components/chat/AgentChatPanel.tsx
|
|
9295
|
-
var
|
|
9295
|
+
var React51 = __toESM(require("react"), 1);
|
|
9296
9296
|
|
|
9297
9297
|
// src/components/chat/chatEngine.ts
|
|
9298
|
-
var
|
|
9298
|
+
var React46 = __toESM(require("react"), 1);
|
|
9299
9299
|
var CHAT_UNAVAILABLE = "chat_unavailable";
|
|
9300
9300
|
var JOB_PENDING = ["queued", "running"];
|
|
9301
9301
|
var JOB_SUCCESS = ["completed", "recovered"];
|
|
@@ -9349,22 +9349,22 @@ function useChatEngine(opts) {
|
|
|
9349
9349
|
onClear,
|
|
9350
9350
|
onFeedback
|
|
9351
9351
|
} = opts || {};
|
|
9352
|
-
const [status, setStatus] =
|
|
9353
|
-
const [threadId, setThreadId] =
|
|
9354
|
-
const [messages, setMessages] =
|
|
9355
|
-
const [queue, setQueue] =
|
|
9356
|
-
const [fatal, setFatal] =
|
|
9357
|
-
const [busy, setBusy] =
|
|
9358
|
-
const [turnStartedAt, setTurnStartedAt] =
|
|
9359
|
-
const listRef =
|
|
9360
|
-
const queueRef =
|
|
9361
|
-
const busyRef =
|
|
9362
|
-
const stoppedRef =
|
|
9363
|
-
const abortRef =
|
|
9364
|
-
const serverCount =
|
|
9365
|
-
const threadRef =
|
|
9366
|
-
const mounted =
|
|
9367
|
-
|
|
9352
|
+
const [status, setStatus] = React46.useState("idle");
|
|
9353
|
+
const [threadId, setThreadId] = React46.useState(null);
|
|
9354
|
+
const [messages, setMessages] = React46.useState([]);
|
|
9355
|
+
const [queue, setQueue] = React46.useState([]);
|
|
9356
|
+
const [fatal, setFatal] = React46.useState(null);
|
|
9357
|
+
const [busy, setBusy] = React46.useState(false);
|
|
9358
|
+
const [turnStartedAt, setTurnStartedAt] = React46.useState(null);
|
|
9359
|
+
const listRef = React46.useRef([]);
|
|
9360
|
+
const queueRef = React46.useRef([]);
|
|
9361
|
+
const busyRef = React46.useRef(false);
|
|
9362
|
+
const stoppedRef = React46.useRef(false);
|
|
9363
|
+
const abortRef = React46.useRef(null);
|
|
9364
|
+
const serverCount = React46.useRef(0);
|
|
9365
|
+
const threadRef = React46.useRef(null);
|
|
9366
|
+
const mounted = React46.useRef(true);
|
|
9367
|
+
React46.useEffect(() => {
|
|
9368
9368
|
mounted.current = true;
|
|
9369
9369
|
return () => {
|
|
9370
9370
|
mounted.current = false;
|
|
@@ -9386,14 +9386,14 @@ function useChatEngine(opts) {
|
|
|
9386
9386
|
}
|
|
9387
9387
|
return false;
|
|
9388
9388
|
};
|
|
9389
|
-
const loadThread =
|
|
9389
|
+
const loadThread = React46.useCallback(async (id) => {
|
|
9390
9390
|
const data = await apiAdapter.getThread(id);
|
|
9391
9391
|
const list = [...data && data.messages || []];
|
|
9392
9392
|
serverCount.current = list.length;
|
|
9393
9393
|
commit(list);
|
|
9394
9394
|
return list;
|
|
9395
9395
|
}, [apiAdapter]);
|
|
9396
|
-
|
|
9396
|
+
React46.useEffect(() => {
|
|
9397
9397
|
if (!apiAdapter) {
|
|
9398
9398
|
setStatus("idle");
|
|
9399
9399
|
setFatal(null);
|
|
@@ -9606,7 +9606,7 @@ function useChatEngine(opts) {
|
|
|
9606
9606
|
await dispatchTurn(turn);
|
|
9607
9607
|
}
|
|
9608
9608
|
}
|
|
9609
|
-
const send =
|
|
9609
|
+
const send = React46.useCallback((text, attachments) => {
|
|
9610
9610
|
const body = (text || "").trim();
|
|
9611
9611
|
if (!body && !(attachments && attachments.length)) return;
|
|
9612
9612
|
if (status === "disconnected") return;
|
|
@@ -9616,7 +9616,7 @@ function useChatEngine(opts) {
|
|
|
9616
9616
|
stoppedRef.current = false;
|
|
9617
9617
|
drain();
|
|
9618
9618
|
}, [status]);
|
|
9619
|
-
const stop =
|
|
9619
|
+
const stop = React46.useCallback(() => {
|
|
9620
9620
|
stoppedRef.current = true;
|
|
9621
9621
|
const ac = abortRef.current;
|
|
9622
9622
|
if (ac) {
|
|
@@ -9635,11 +9635,11 @@ function useChatEngine(opts) {
|
|
|
9635
9635
|
store.del(STORAGE_PREFIX + threadRef.current);
|
|
9636
9636
|
}
|
|
9637
9637
|
}, [apiAdapter]);
|
|
9638
|
-
const removeQueued =
|
|
9638
|
+
const removeQueued = React46.useCallback((id) => {
|
|
9639
9639
|
queueRef.current = queueRef.current.filter((t) => t.id !== id);
|
|
9640
9640
|
setQueue(queueRef.current.slice());
|
|
9641
9641
|
}, []);
|
|
9642
|
-
const retry =
|
|
9642
|
+
const retry = React46.useCallback(() => {
|
|
9643
9643
|
const list = listRef.current;
|
|
9644
9644
|
let at = -1;
|
|
9645
9645
|
for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
|
|
@@ -9655,19 +9655,19 @@ function useChatEngine(opts) {
|
|
|
9655
9655
|
setQueue(queueRef.current.slice());
|
|
9656
9656
|
drain();
|
|
9657
9657
|
}, []);
|
|
9658
|
-
const clear =
|
|
9658
|
+
const clear = React46.useCallback(() => {
|
|
9659
9659
|
commit([]);
|
|
9660
9660
|
serverCount.current = 0;
|
|
9661
9661
|
queueRef.current = [];
|
|
9662
9662
|
setQueue([]);
|
|
9663
9663
|
onClear && onClear();
|
|
9664
9664
|
}, [onClear]);
|
|
9665
|
-
const setFeedback =
|
|
9665
|
+
const setFeedback = React46.useCallback((id, value) => {
|
|
9666
9666
|
patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
|
|
9667
9667
|
const msg = listRef.current.find((m) => m.id === id);
|
|
9668
9668
|
onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
|
|
9669
9669
|
}, [onFeedback]);
|
|
9670
|
-
const reload =
|
|
9670
|
+
const reload = React46.useCallback(async () => {
|
|
9671
9671
|
if (!threadRef.current) return;
|
|
9672
9672
|
setStatus("loading");
|
|
9673
9673
|
try {
|
|
@@ -9705,10 +9705,10 @@ var ChatKit = {
|
|
|
9705
9705
|
};
|
|
9706
9706
|
|
|
9707
9707
|
// src/components/chat/ChatTranscript.tsx
|
|
9708
|
-
var
|
|
9708
|
+
var React48 = __toESM(require("react"), 1);
|
|
9709
9709
|
|
|
9710
9710
|
// src/components/chat/ChatTurn.tsx
|
|
9711
|
-
var
|
|
9711
|
+
var React47 = __toESM(require("react"), 1);
|
|
9712
9712
|
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
9713
9713
|
function JsonView({ value }) {
|
|
9714
9714
|
let text;
|
|
@@ -9745,7 +9745,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
|
9745
9745
|
] });
|
|
9746
9746
|
}
|
|
9747
9747
|
function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
9748
|
-
const [open, setOpen] =
|
|
9748
|
+
const [open, setOpen] = React47.useState(defaultOpen);
|
|
9749
9749
|
if (!text) return null;
|
|
9750
9750
|
return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
|
|
9751
9751
|
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
@@ -9762,7 +9762,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
|
9762
9762
|
] });
|
|
9763
9763
|
}
|
|
9764
9764
|
function Citations({ items = [], onOpen }) {
|
|
9765
|
-
const [open, setOpen] =
|
|
9765
|
+
const [open, setOpen] = React47.useState(false);
|
|
9766
9766
|
if (!items.length) return null;
|
|
9767
9767
|
return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "fdc-cites", children: [
|
|
9768
9768
|
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
@@ -9788,7 +9788,7 @@ function clampText(text, max) {
|
|
|
9788
9788
|
return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
9789
9789
|
}
|
|
9790
9790
|
function MessageBody({ message: m, ctx }) {
|
|
9791
|
-
const [expanded, setExpanded] =
|
|
9791
|
+
const [expanded, setExpanded] = React47.useState(false);
|
|
9792
9792
|
const isUser = m.role === "user";
|
|
9793
9793
|
const raw = m.text || "";
|
|
9794
9794
|
const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
|
|
@@ -9855,9 +9855,9 @@ function MessageBody({ message: m, ctx }) {
|
|
|
9855
9855
|
] });
|
|
9856
9856
|
}
|
|
9857
9857
|
function useCopyRun() {
|
|
9858
|
-
const [done, setDone] =
|
|
9859
|
-
const t =
|
|
9860
|
-
|
|
9858
|
+
const [done, setDone] = React47.useState(false);
|
|
9859
|
+
const t = React47.useRef(null);
|
|
9860
|
+
React47.useEffect(() => () => {
|
|
9861
9861
|
if (t.current) clearTimeout(t.current);
|
|
9862
9862
|
}, []);
|
|
9863
9863
|
return [done, (text) => {
|
|
@@ -9884,7 +9884,7 @@ function RunActions({ group, ctx }) {
|
|
|
9884
9884
|
] }),
|
|
9885
9885
|
isAssistant && ctx.onRetry ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
|
|
9886
9886
|
group.role === "user" && ctx.onEdit ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
|
|
9887
|
-
isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
|
|
9887
|
+
isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(React47.Fragment, { children: [
|
|
9888
9888
|
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", className: "fdc-act" + (fb === "up" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "up"), "aria-pressed": fb === "up", "aria-label": "Good response", children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
|
|
9889
9889
|
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", className: "fdc-act" + (fb === "down" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "down"), "aria-pressed": fb === "down", "aria-label": "Bad response", children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
|
|
9890
9890
|
] }) : null,
|
|
@@ -9979,10 +9979,10 @@ function ChatTranscript({
|
|
|
9979
9979
|
renderEmpty,
|
|
9980
9980
|
className = ""
|
|
9981
9981
|
}) {
|
|
9982
|
-
const scroller =
|
|
9983
|
-
const stick =
|
|
9984
|
-
const [pill, setPill] =
|
|
9985
|
-
const seen =
|
|
9982
|
+
const scroller = React48.useRef(null);
|
|
9983
|
+
const stick = React48.useRef(true);
|
|
9984
|
+
const [pill, setPill] = React48.useState(0);
|
|
9985
|
+
const seen = React48.useRef(0);
|
|
9986
9986
|
const toBottom = (smooth) => {
|
|
9987
9987
|
const el = scroller.current;
|
|
9988
9988
|
if (!el) return;
|
|
@@ -10001,7 +10001,7 @@ function ChatTranscript({
|
|
|
10001
10001
|
seen.current = messages.length;
|
|
10002
10002
|
}
|
|
10003
10003
|
};
|
|
10004
|
-
|
|
10004
|
+
React48.useLayoutEffect(() => {
|
|
10005
10005
|
const el = scroller.current;
|
|
10006
10006
|
if (!el) return;
|
|
10007
10007
|
if (stick.current) {
|
|
@@ -10009,7 +10009,7 @@ function ChatTranscript({
|
|
|
10009
10009
|
seen.current = messages.length;
|
|
10010
10010
|
} else setPill(Math.max(0, messages.length - seen.current));
|
|
10011
10011
|
}, [messages]);
|
|
10012
|
-
|
|
10012
|
+
React48.useEffect(() => {
|
|
10013
10013
|
const el = scroller.current;
|
|
10014
10014
|
const inner = el && el.firstChild;
|
|
10015
10015
|
if (!el || !inner || typeof ResizeObserver === "undefined") return;
|
|
@@ -10019,7 +10019,7 @@ function ChatTranscript({
|
|
|
10019
10019
|
ro.observe(inner);
|
|
10020
10020
|
return () => ro.disconnect();
|
|
10021
10021
|
}, []);
|
|
10022
|
-
const groups =
|
|
10022
|
+
const groups = React48.useMemo(() => groupMessages(messages), [messages]);
|
|
10023
10023
|
const empty = !messages.length && status === "ready";
|
|
10024
10024
|
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
|
|
10025
10025
|
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
|
|
@@ -10043,7 +10043,7 @@ function ChatTranscript({
|
|
|
10043
10043
|
const prev = groups[i - 1];
|
|
10044
10044
|
const k = dayKey(g.messages[0].timestamp);
|
|
10045
10045
|
const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
|
|
10046
|
-
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
10046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(React48.Fragment, { children: [
|
|
10047
10047
|
showDay ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "fdc-day", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { children: dayLabel(k) }) }) : null,
|
|
10048
10048
|
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ChatTurn, { group: g, ctx })
|
|
10049
10049
|
] }, g.key || i);
|
|
@@ -10060,7 +10060,7 @@ function ChatTranscript({
|
|
|
10060
10060
|
var TranscriptKit = { groupMessages };
|
|
10061
10061
|
|
|
10062
10062
|
// src/components/chat/ChatComposer.tsx
|
|
10063
|
-
var
|
|
10063
|
+
var React49 = __toESM(require("react"), 1);
|
|
10064
10064
|
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
10065
10065
|
function ChatComposer({
|
|
10066
10066
|
onSubmit,
|
|
@@ -10088,17 +10088,17 @@ function ChatComposer({
|
|
|
10088
10088
|
onReject,
|
|
10089
10089
|
onOpenAttachment
|
|
10090
10090
|
}) {
|
|
10091
|
-
const [text, setText] =
|
|
10092
|
-
const [trigger, setTrigger] =
|
|
10093
|
-
const [mentionItems, setMentionItems] =
|
|
10094
|
-
const [listening, setListening] =
|
|
10095
|
-
const [notice, setNotice] =
|
|
10096
|
-
const editor =
|
|
10097
|
-
const wrap =
|
|
10098
|
-
const stopVoice =
|
|
10091
|
+
const [text, setText] = React49.useState(draft || "");
|
|
10092
|
+
const [trigger, setTrigger] = React49.useState(null);
|
|
10093
|
+
const [mentionItems, setMentionItems] = React49.useState([]);
|
|
10094
|
+
const [listening, setListening] = React49.useState(false);
|
|
10095
|
+
const [notice, setNotice] = React49.useState(null);
|
|
10096
|
+
const editor = React49.useRef(null);
|
|
10097
|
+
const wrap = React49.useRef(null);
|
|
10098
|
+
const stopVoice = React49.useRef(null);
|
|
10099
10099
|
const staged = useStagedFiles(fileUploadHandler, { onError: () => {
|
|
10100
10100
|
} });
|
|
10101
|
-
|
|
10101
|
+
React49.useEffect(() => {
|
|
10102
10102
|
if (draft != null && draft !== text) setText(draft);
|
|
10103
10103
|
}, [draft]);
|
|
10104
10104
|
const change = (v) => {
|
|
@@ -10134,7 +10134,7 @@ function ChatComposer({
|
|
|
10134
10134
|
e.preventDefault();
|
|
10135
10135
|
staged.add(found.files);
|
|
10136
10136
|
};
|
|
10137
|
-
|
|
10137
|
+
React49.useEffect(() => {
|
|
10138
10138
|
if (!trigger || trigger.type !== "mention" || !mentionSources) {
|
|
10139
10139
|
setMentionItems([]);
|
|
10140
10140
|
return;
|
|
@@ -10152,7 +10152,7 @@ function ChatComposer({
|
|
|
10152
10152
|
const q = (trigger.query || "").toLowerCase();
|
|
10153
10153
|
setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
|
|
10154
10154
|
}, [trigger, mentionSources]);
|
|
10155
|
-
const slashItems =
|
|
10155
|
+
const slashItems = React49.useMemo(() => {
|
|
10156
10156
|
if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
|
|
10157
10157
|
const q = (trigger.query || "").toLowerCase();
|
|
10158
10158
|
return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
|
|
@@ -10326,12 +10326,12 @@ function ChatComposer({
|
|
|
10326
10326
|
}
|
|
10327
10327
|
|
|
10328
10328
|
// src/components/chat/ChatSessionBar.tsx
|
|
10329
|
-
var
|
|
10329
|
+
var React50 = __toESM(require("react"), 1);
|
|
10330
10330
|
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
10331
10331
|
var compact2 = meterFormats.compact;
|
|
10332
10332
|
function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
|
|
10333
|
-
const [open, setOpen] =
|
|
10334
|
-
const anchor =
|
|
10333
|
+
const [open, setOpen] = React50.useState(false);
|
|
10334
|
+
const anchor = React50.useRef(null);
|
|
10335
10335
|
const stats = sessionStats || null;
|
|
10336
10336
|
const cu = contextUsage || null;
|
|
10337
10337
|
const limits = usageLimits || null;
|
|
@@ -10346,7 +10346,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
10346
10346
|
if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
|
|
10347
10347
|
if (cu) bits.push(pct + "% context");
|
|
10348
10348
|
const expandable = !!(cu || limits);
|
|
10349
|
-
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
|
|
10349
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(React50.Fragment, { children: [
|
|
10350
10350
|
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "fdc-bar", children: [
|
|
10351
10351
|
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
|
|
10352
10352
|
"button",
|
|
@@ -10487,7 +10487,7 @@ function ModelControls({
|
|
|
10487
10487
|
] })
|
|
10488
10488
|
});
|
|
10489
10489
|
}
|
|
10490
|
-
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
|
|
10490
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(React50.Fragment, { children: [
|
|
10491
10491
|
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
10492
10492
|
MenuButton,
|
|
10493
10493
|
{
|
|
@@ -10604,11 +10604,11 @@ function AgentChatPanel({
|
|
|
10604
10604
|
onFeedback,
|
|
10605
10605
|
onEditMessage
|
|
10606
10606
|
}) {
|
|
10607
|
-
const [panelWidth, setPanelWidth] =
|
|
10608
|
-
const [applied, setApplied] =
|
|
10609
|
-
const [draft, setDraft] =
|
|
10610
|
-
const dragging =
|
|
10611
|
-
|
|
10607
|
+
const [panelWidth, setPanelWidth] = React51.useState(width);
|
|
10608
|
+
const [applied, setApplied] = React51.useState({});
|
|
10609
|
+
const [draft, setDraft] = React51.useState("");
|
|
10610
|
+
const dragging = React51.useRef(null);
|
|
10611
|
+
React51.useEffect(() => setPanelWidth(width), [width]);
|
|
10612
10612
|
const engine = useChatEngine({
|
|
10613
10613
|
contextType,
|
|
10614
10614
|
contextId,
|
|
@@ -10812,7 +10812,7 @@ function AgentChatPanel({
|
|
|
10812
10812
|
}
|
|
10813
10813
|
|
|
10814
10814
|
// src/components/files/FileViewer.tsx
|
|
10815
|
-
var
|
|
10815
|
+
var React52 = __toESM(require("react"), 1);
|
|
10816
10816
|
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
10817
10817
|
function previewKindOf(file) {
|
|
10818
10818
|
const mime = (file.mime || "").toLowerCase();
|
|
@@ -10869,13 +10869,13 @@ function parseDelimited(text, delimiter) {
|
|
|
10869
10869
|
return rows;
|
|
10870
10870
|
}
|
|
10871
10871
|
function usePreview(file, kind, resolveUrl) {
|
|
10872
|
-
const [state, setState] =
|
|
10873
|
-
const [attempt, setAttempt] =
|
|
10874
|
-
const resolveRef =
|
|
10875
|
-
|
|
10872
|
+
const [state, setState] = React52.useState({ status: "loading" });
|
|
10873
|
+
const [attempt, setAttempt] = React52.useState(0);
|
|
10874
|
+
const resolveRef = React52.useRef(resolveUrl);
|
|
10875
|
+
React52.useEffect(() => {
|
|
10876
10876
|
resolveRef.current = resolveUrl;
|
|
10877
10877
|
}, [resolveUrl]);
|
|
10878
|
-
|
|
10878
|
+
React52.useEffect(() => {
|
|
10879
10879
|
if (kind === "none") {
|
|
10880
10880
|
setState({ status: "ready" });
|
|
10881
10881
|
return;
|
|
@@ -10905,7 +10905,7 @@ function usePreview(file, kind, resolveUrl) {
|
|
|
10905
10905
|
if (ac) ac.abort();
|
|
10906
10906
|
};
|
|
10907
10907
|
}, [file.id, kind, attempt]);
|
|
10908
|
-
return { ...state, retry:
|
|
10908
|
+
return { ...state, retry: React52.useCallback(() => setAttempt((a) => a + 1), []) };
|
|
10909
10909
|
}
|
|
10910
10910
|
function PreviewBody({ file, kind, state }) {
|
|
10911
10911
|
if (kind === "image") return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
|
|
@@ -10950,13 +10950,13 @@ function PreviewBody({ file, kind, state }) {
|
|
|
10950
10950
|
] });
|
|
10951
10951
|
}
|
|
10952
10952
|
function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
|
|
10953
|
-
const kind =
|
|
10953
|
+
const kind = React52.useMemo(() => previewKindOf(file), [file]);
|
|
10954
10954
|
const preview = usePreview(file, kind, resolveUrl);
|
|
10955
|
-
const [tab, setTab] =
|
|
10956
|
-
const [downloading, setDownloading] =
|
|
10957
|
-
const [downloadError, setDownloadError] =
|
|
10955
|
+
const [tab, setTab] = React52.useState("preview");
|
|
10956
|
+
const [downloading, setDownloading] = React52.useState(false);
|
|
10957
|
+
const [downloadError, setDownloadError] = React52.useState(null);
|
|
10958
10958
|
const hasSide = sidePanel != null;
|
|
10959
|
-
|
|
10959
|
+
React52.useEffect(() => {
|
|
10960
10960
|
setTab("preview");
|
|
10961
10961
|
}, [file.id]);
|
|
10962
10962
|
const download = () => {
|
|
@@ -11023,7 +11023,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
11023
11023
|
}
|
|
11024
11024
|
|
|
11025
11025
|
// src/components/files/FileBrowser.tsx
|
|
11026
|
-
var
|
|
11026
|
+
var React53 = __toESM(require("react"), 1);
|
|
11027
11027
|
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
11028
11028
|
function childrenOf(folders, parentId) {
|
|
11029
11029
|
return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -11094,10 +11094,10 @@ function FolderPickerMenu({
|
|
|
11094
11094
|
destinations,
|
|
11095
11095
|
onPick
|
|
11096
11096
|
}) {
|
|
11097
|
-
const [open, setOpen] =
|
|
11097
|
+
const [open, setOpen] = React53.useState(false);
|
|
11098
11098
|
const zIndex = useOverlayLayer(open);
|
|
11099
|
-
const ref =
|
|
11100
|
-
|
|
11099
|
+
const ref = React53.useRef(null);
|
|
11100
|
+
React53.useEffect(() => {
|
|
11101
11101
|
if (!open) return;
|
|
11102
11102
|
const away = (e) => {
|
|
11103
11103
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -11149,8 +11149,8 @@ function FolderPickerMenu({
|
|
|
11149
11149
|
] });
|
|
11150
11150
|
}
|
|
11151
11151
|
function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
|
|
11152
|
-
const [over, setOver] =
|
|
11153
|
-
const dragCounter =
|
|
11152
|
+
const [over, setOver] = React53.useState(false);
|
|
11153
|
+
const dragCounter = React53.useRef(0);
|
|
11154
11154
|
const dropHandlers = isDropTarget ? {
|
|
11155
11155
|
onDragEnter: (e) => {
|
|
11156
11156
|
if (!hasInternalPayload(e)) return;
|
|
@@ -11198,8 +11198,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
|
|
|
11198
11198
|
}
|
|
11199
11199
|
function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
|
|
11200
11200
|
const kids = childrenOf(folders, folder.id);
|
|
11201
|
-
const [expanded, setExpanded] =
|
|
11202
|
-
|
|
11201
|
+
const [expanded, setExpanded] = React53.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
|
|
11202
|
+
React53.useEffect(() => {
|
|
11203
11203
|
if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
|
|
11204
11204
|
}, [currentFolderId, folder.id, folders]);
|
|
11205
11205
|
const isCurrent = folder.id === currentFolderId;
|
|
@@ -11265,15 +11265,15 @@ function FileBrowser({
|
|
|
11265
11265
|
const canUpload = perm.canUpload !== false && !!onUpload;
|
|
11266
11266
|
const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
|
|
11267
11267
|
const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
|
|
11268
|
-
const [createOpen, setCreateOpen] =
|
|
11269
|
-
const [createName, setCreateName] =
|
|
11270
|
-
const [renameTarget, setRenameTarget] =
|
|
11271
|
-
const [renameValue, setRenameValue] =
|
|
11272
|
-
const [deleteTarget, setDeleteTarget] =
|
|
11273
|
-
const uploadInputRef =
|
|
11274
|
-
const crumbFolders =
|
|
11275
|
-
const subfolders =
|
|
11276
|
-
const currentFiles =
|
|
11268
|
+
const [createOpen, setCreateOpen] = React53.useState(false);
|
|
11269
|
+
const [createName, setCreateName] = React53.useState("");
|
|
11270
|
+
const [renameTarget, setRenameTarget] = React53.useState(null);
|
|
11271
|
+
const [renameValue, setRenameValue] = React53.useState("");
|
|
11272
|
+
const [deleteTarget, setDeleteTarget] = React53.useState(null);
|
|
11273
|
+
const uploadInputRef = React53.useRef(null);
|
|
11274
|
+
const crumbFolders = React53.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
11275
|
+
const subfolders = React53.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
11276
|
+
const currentFiles = React53.useMemo(
|
|
11277
11277
|
() => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
|
|
11278
11278
|
[files, currentFolderId]
|
|
11279
11279
|
);
|
|
@@ -11505,8 +11505,8 @@ function BreadcrumbCrumb({
|
|
|
11505
11505
|
isDropTarget,
|
|
11506
11506
|
onDropPayload
|
|
11507
11507
|
}) {
|
|
11508
|
-
const [over, setOver] =
|
|
11509
|
-
const dragCounter =
|
|
11508
|
+
const [over, setOver] = React53.useState(false);
|
|
11509
|
+
const dragCounter = React53.useRef(0);
|
|
11510
11510
|
const dropHandlers = isDropTarget ? {
|
|
11511
11511
|
onDragEnter: (e) => {
|
|
11512
11512
|
if (!hasInternalPayload(e)) return;
|
|
@@ -11535,7 +11535,7 @@ function BreadcrumbCrumb({
|
|
|
11535
11535
|
}
|
|
11536
11536
|
|
|
11537
11537
|
// src/kits/query.ts
|
|
11538
|
-
var
|
|
11538
|
+
var React54 = __toESM(require("react"), 1);
|
|
11539
11539
|
function eqFilter(get2) {
|
|
11540
11540
|
return (row, value) => Array.isArray(value) ? value.includes(get2(row)) : get2(row) === value;
|
|
11541
11541
|
}
|
|
@@ -11567,22 +11567,22 @@ function compare(a, b, dir) {
|
|
|
11567
11567
|
var API = null;
|
|
11568
11568
|
var PREFS = null;
|
|
11569
11569
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
|
|
11570
|
-
const [query, setQuery] =
|
|
11570
|
+
const [query, setQuery] = React54.useState(() => {
|
|
11571
11571
|
const store = PREFS || window.PlannerPrefs;
|
|
11572
11572
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
11573
11573
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
11574
11574
|
});
|
|
11575
|
-
const savePref =
|
|
11575
|
+
const savePref = React54.useCallback((patch2) => {
|
|
11576
11576
|
const store = PREFS || window.PlannerPrefs;
|
|
11577
11577
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
11578
11578
|
}, [prefsKey]);
|
|
11579
|
-
const [res, setRes] =
|
|
11580
|
-
const [loading, setLoading] =
|
|
11581
|
-
const seq2 =
|
|
11579
|
+
const [res, setRes] = React54.useState(null);
|
|
11580
|
+
const [loading, setLoading] = React54.useState(true);
|
|
11581
|
+
const seq2 = React54.useRef(0);
|
|
11582
11582
|
const depKey = (deps || []).join("|");
|
|
11583
11583
|
const paramKey = JSON.stringify(params || {});
|
|
11584
11584
|
const queryKey = JSON.stringify(query);
|
|
11585
|
-
|
|
11585
|
+
React54.useEffect(() => {
|
|
11586
11586
|
const id = ++seq2.current;
|
|
11587
11587
|
setLoading(true);
|
|
11588
11588
|
const t = setTimeout(() => {
|
|
@@ -11879,6 +11879,92 @@ function createVersionStore(initialState, options) {
|
|
|
11879
11879
|
}
|
|
11880
11880
|
};
|
|
11881
11881
|
}
|
|
11882
|
+
|
|
11883
|
+
// src/kits/useResponsiveRail.ts
|
|
11884
|
+
var React55 = __toESM(require("react"), 1);
|
|
11885
|
+
function matchesBreakpoint(breakpoint) {
|
|
11886
|
+
return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches;
|
|
11887
|
+
}
|
|
11888
|
+
var FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
11889
|
+
function getFocusable(container) {
|
|
11890
|
+
return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR));
|
|
11891
|
+
}
|
|
11892
|
+
function useResponsiveRail(options = {}) {
|
|
11893
|
+
const { breakpoint = 1024, initialOpen = true, onPersist } = options;
|
|
11894
|
+
const navRef = React55.useRef(null);
|
|
11895
|
+
const [overlay, setOverlay] = React55.useState(() => matchesBreakpoint(breakpoint));
|
|
11896
|
+
const [open, setOpenRaw] = React55.useState(() => matchesBreakpoint(breakpoint) ? false : initialOpen);
|
|
11897
|
+
const setOpen = React55.useCallback(
|
|
11898
|
+
(value) => {
|
|
11899
|
+
setOpenRaw(value);
|
|
11900
|
+
if (!matchesBreakpoint(breakpoint)) onPersist?.(value);
|
|
11901
|
+
},
|
|
11902
|
+
[breakpoint, onPersist]
|
|
11903
|
+
);
|
|
11904
|
+
const toggle = React55.useCallback(() => setOpen(!open), [open, setOpen]);
|
|
11905
|
+
const close = React55.useCallback(() => setOpenRaw(false), []);
|
|
11906
|
+
React55.useEffect(() => {
|
|
11907
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
11908
|
+
const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
11909
|
+
const handler = (e) => {
|
|
11910
|
+
setOverlay(e.matches);
|
|
11911
|
+
setOpenRaw(!e.matches);
|
|
11912
|
+
};
|
|
11913
|
+
mq.addEventListener("change", handler);
|
|
11914
|
+
return () => mq.removeEventListener("change", handler);
|
|
11915
|
+
}, [breakpoint]);
|
|
11916
|
+
React55.useEffect(() => {
|
|
11917
|
+
if (!overlay || !open) return;
|
|
11918
|
+
const handler = (e) => {
|
|
11919
|
+
if (e.key === "Escape") close();
|
|
11920
|
+
};
|
|
11921
|
+
document.addEventListener("keydown", handler);
|
|
11922
|
+
return () => document.removeEventListener("keydown", handler);
|
|
11923
|
+
}, [overlay, open, close]);
|
|
11924
|
+
React55.useEffect(() => {
|
|
11925
|
+
if (!overlay || !open) return;
|
|
11926
|
+
const previousOverflow = document.body.style.overflow;
|
|
11927
|
+
document.body.style.overflow = "hidden";
|
|
11928
|
+
return () => {
|
|
11929
|
+
document.body.style.overflow = previousOverflow;
|
|
11930
|
+
};
|
|
11931
|
+
}, [overlay, open]);
|
|
11932
|
+
React55.useEffect(() => {
|
|
11933
|
+
if (!overlay || !open) return;
|
|
11934
|
+
const container = navRef.current;
|
|
11935
|
+
if (!container) return;
|
|
11936
|
+
const previouslyFocused = document.activeElement;
|
|
11937
|
+
const focusable = getFocusable(container);
|
|
11938
|
+
(focusable[0] ?? container).focus();
|
|
11939
|
+
const handler = (e) => {
|
|
11940
|
+
if (e.key !== "Tab") return;
|
|
11941
|
+
const items = getFocusable(container);
|
|
11942
|
+
if (items.length === 0) {
|
|
11943
|
+
e.preventDefault();
|
|
11944
|
+
return;
|
|
11945
|
+
}
|
|
11946
|
+
const first = items[0];
|
|
11947
|
+
const last = items[items.length - 1];
|
|
11948
|
+
const active = document.activeElement;
|
|
11949
|
+
const outside = !(active instanceof Node) || !container.contains(active);
|
|
11950
|
+
if (e.shiftKey) {
|
|
11951
|
+
if (outside || active === first) {
|
|
11952
|
+
e.preventDefault();
|
|
11953
|
+
last.focus();
|
|
11954
|
+
}
|
|
11955
|
+
} else if (outside || active === last) {
|
|
11956
|
+
e.preventDefault();
|
|
11957
|
+
first.focus();
|
|
11958
|
+
}
|
|
11959
|
+
};
|
|
11960
|
+
document.addEventListener("keydown", handler);
|
|
11961
|
+
return () => {
|
|
11962
|
+
document.removeEventListener("keydown", handler);
|
|
11963
|
+
previouslyFocused?.focus?.();
|
|
11964
|
+
};
|
|
11965
|
+
}, [overlay, open]);
|
|
11966
|
+
return { open, overlay, navRef, toggle, close, setOpen };
|
|
11967
|
+
}
|
|
11882
11968
|
// Annotate the CommonJS export names for ESM import in node:
|
|
11883
11969
|
0 && (module.exports = {
|
|
11884
11970
|
AccountMenu,
|
|
@@ -12063,6 +12149,7 @@ function createVersionStore(initialState, options) {
|
|
|
12063
12149
|
useChatEngine,
|
|
12064
12150
|
useFeatureStatus,
|
|
12065
12151
|
usePopoverPosition,
|
|
12152
|
+
useResponsiveRail,
|
|
12066
12153
|
useRuntimeMode,
|
|
12067
12154
|
useServerTable,
|
|
12068
12155
|
useSessionContext,
|