@flytedan/flytebot-design-system 0.12.4 → 0.12.6
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 +334 -316
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +814 -796
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components.css +73 -1
package/dist/index.cjs
CHANGED
|
@@ -253,6 +253,11 @@ function Button({
|
|
|
253
253
|
);
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
// src/components/actions/overflowRowContext.ts
|
|
257
|
+
var React = __toESM(require("react"), 1);
|
|
258
|
+
var OverflowRowContext = React.createContext(false);
|
|
259
|
+
var useOverflowRow = () => React.useContext(OverflowRowContext);
|
|
260
|
+
|
|
256
261
|
// src/components/actions/IconButton.tsx
|
|
257
262
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
258
263
|
function IconButton({
|
|
@@ -266,19 +271,24 @@ function IconButton({
|
|
|
266
271
|
className = "",
|
|
267
272
|
...rest
|
|
268
273
|
}) {
|
|
274
|
+
const overflowRow = useOverflowRow();
|
|
269
275
|
const cls = [
|
|
270
276
|
"fd-btn-icon",
|
|
271
277
|
variant === "outline" ? "fd-btn-icon-outline" : variant === "solid" ? "fd-btn-icon-solid" : "",
|
|
272
278
|
tone !== "neutral" ? "is-" + tone : "",
|
|
273
279
|
size === "sm" ? "fd-btn-icon-sm" : size === "lg" ? "fd-btn-icon-lg" : "",
|
|
274
280
|
round ? "fd-btn-icon-round" : "",
|
|
281
|
+
overflowRow ? "fd-btn-icon-row" : "",
|
|
275
282
|
className
|
|
276
283
|
].filter(Boolean).join(" ");
|
|
277
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.
|
|
284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: cls, "aria-label": label, title: label, disabled, ...rest, children: [
|
|
285
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "ph ph-" + icon, "aria-hidden": "true" }),
|
|
286
|
+
overflowRow ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fd-btn-icon-row-label", children: label }) : null
|
|
287
|
+
] });
|
|
278
288
|
}
|
|
279
289
|
|
|
280
290
|
// src/components/actions/Popover.tsx
|
|
281
|
-
var
|
|
291
|
+
var React2 = __toESM(require("react"), 1);
|
|
282
292
|
var import_react_dom = require("react-dom");
|
|
283
293
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
284
294
|
var MARGIN = 8;
|
|
@@ -310,12 +320,12 @@ function measureLayer(el) {
|
|
|
310
320
|
function usePopoverPosition(open, anchorRef, opts) {
|
|
311
321
|
const o = opts || {};
|
|
312
322
|
const { side: wantSide, align } = parsePlacement(o.placement);
|
|
313
|
-
const [pos, setPos] =
|
|
314
|
-
const posRef =
|
|
315
|
-
const detachRef =
|
|
323
|
+
const [pos, setPos] = React2.useState(null);
|
|
324
|
+
const posRef = React2.useRef(null);
|
|
325
|
+
const detachRef = React2.useRef(o.onDetach);
|
|
316
326
|
detachRef.current = o.onDetach;
|
|
317
327
|
const layerRef = o.layerRef;
|
|
318
|
-
|
|
328
|
+
React2.useLayoutEffect(() => {
|
|
319
329
|
if (!open || !anchorRef || !anchorRef.current) {
|
|
320
330
|
posRef.current = null;
|
|
321
331
|
setPos(null);
|
|
@@ -390,8 +400,8 @@ var portal = (node) => {
|
|
|
390
400
|
};
|
|
391
401
|
var ROOT_LAYER = 0;
|
|
392
402
|
var LAYER_STEP = 10;
|
|
393
|
-
var LayerContext =
|
|
394
|
-
var useLayer = () =>
|
|
403
|
+
var LayerContext = React2.createContext(ROOT_LAYER);
|
|
404
|
+
var useLayer = () => React2.useContext(LayerContext);
|
|
395
405
|
var useOverlayLayer = (base) => {
|
|
396
406
|
const parent = useLayer();
|
|
397
407
|
return parent === ROOT_LAYER ? base : parent + LAYER_STEP;
|
|
@@ -421,7 +431,7 @@ function Popover({
|
|
|
421
431
|
footer,
|
|
422
432
|
children
|
|
423
433
|
}) {
|
|
424
|
-
const ref =
|
|
434
|
+
const ref = React2.useRef(null);
|
|
425
435
|
const pos = usePopoverPosition(!!open, anchorRef, {
|
|
426
436
|
placement,
|
|
427
437
|
offset,
|
|
@@ -433,9 +443,9 @@ function Popover({
|
|
|
433
443
|
onDetach: onClose,
|
|
434
444
|
layerRef: ref
|
|
435
445
|
});
|
|
436
|
-
const restore =
|
|
446
|
+
const restore = React2.useRef(null);
|
|
437
447
|
const zIndex = useOverlayLayer(POPOVER_BASE);
|
|
438
|
-
|
|
448
|
+
React2.useEffect(() => {
|
|
439
449
|
if (!open) return;
|
|
440
450
|
restore.current = typeof document !== "undefined" ? document.activeElement : null;
|
|
441
451
|
return () => {
|
|
@@ -447,7 +457,7 @@ function Popover({
|
|
|
447
457
|
}
|
|
448
458
|
};
|
|
449
459
|
}, [open, returnFocus]);
|
|
450
|
-
|
|
460
|
+
React2.useEffect(() => {
|
|
451
461
|
if (!open) return;
|
|
452
462
|
const away = (e) => {
|
|
453
463
|
if (!closeOnOutside) return;
|
|
@@ -521,12 +531,12 @@ function Popover({
|
|
|
521
531
|
}
|
|
522
532
|
var isItem = (it) => !!it && it.kind !== "separator" && it.kind !== "section" && it.kind !== "custom" && !it.disabled;
|
|
523
533
|
function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "", footer, header }) {
|
|
524
|
-
const listRef =
|
|
525
|
-
const [active, setActive] =
|
|
526
|
-
const [openSub, setOpenSub] =
|
|
527
|
-
const subAnchor =
|
|
528
|
-
const typed =
|
|
529
|
-
|
|
534
|
+
const listRef = React2.useRef(null);
|
|
535
|
+
const [active, setActive] = React2.useState(() => items.findIndex(isItem));
|
|
536
|
+
const [openSub, setOpenSub] = React2.useState(null);
|
|
537
|
+
const subAnchor = React2.useRef(null);
|
|
538
|
+
const typed = React2.useRef({ s: "", t: 0 });
|
|
539
|
+
React2.useEffect(() => {
|
|
530
540
|
if (autoFocus && listRef.current) listRef.current.focus({ preventScroll: true });
|
|
531
541
|
}, [autoFocus]);
|
|
532
542
|
const move = (dir) => {
|
|
@@ -588,7 +598,7 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
|
|
|
588
598
|
}
|
|
589
599
|
};
|
|
590
600
|
const sub = openSub != null ? items[openSub] : null;
|
|
591
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React2.Fragment, { children: [
|
|
592
602
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "fd-menu-frame", children: [
|
|
593
603
|
header != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "fd-menu-header", children: header }) : null,
|
|
594
604
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -702,9 +712,9 @@ function MenuButton({
|
|
|
702
712
|
header,
|
|
703
713
|
footer
|
|
704
714
|
}) {
|
|
705
|
-
const [open, setOpen] =
|
|
706
|
-
const ref =
|
|
707
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
715
|
+
const [open, setOpen] = React2.useState(false);
|
|
716
|
+
const ref = React2.useRef(null);
|
|
717
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React2.Fragment, { children: [
|
|
708
718
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
709
719
|
"button",
|
|
710
720
|
{
|
|
@@ -797,7 +807,7 @@ function CardRow({ label, children, className = "" }) {
|
|
|
797
807
|
}
|
|
798
808
|
|
|
799
809
|
// src/components/surfaces/Collapsible.tsx
|
|
800
|
-
var
|
|
810
|
+
var React3 = __toESM(require("react"), 1);
|
|
801
811
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
802
812
|
function Collapsible({
|
|
803
813
|
title,
|
|
@@ -811,7 +821,7 @@ function Collapsible({
|
|
|
811
821
|
className = "",
|
|
812
822
|
...rest
|
|
813
823
|
}) {
|
|
814
|
-
const [internal, setInternal] =
|
|
824
|
+
const [internal, setInternal] = React3.useState(defaultOpen);
|
|
815
825
|
const isOpen = open === void 0 ? internal : open;
|
|
816
826
|
const toggle = () => {
|
|
817
827
|
if (open === void 0) setInternal(!isOpen);
|
|
@@ -832,19 +842,19 @@ function Collapsible({
|
|
|
832
842
|
}
|
|
833
843
|
|
|
834
844
|
// src/components/surfaces/Drawer.tsx
|
|
835
|
-
var
|
|
845
|
+
var React4 = __toESM(require("react"), 1);
|
|
836
846
|
var import_react_dom2 = require("react-dom");
|
|
837
847
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
838
848
|
var DRAWER_BASE = 90;
|
|
839
849
|
function Drawer({ open = true, title, onClose, footer, children, className = "", ...rest }) {
|
|
840
850
|
const zIndex = useOverlayLayer(DRAWER_BASE);
|
|
841
|
-
const [closing, setClosing] =
|
|
842
|
-
const close =
|
|
851
|
+
const [closing, setClosing] = React4.useState(false);
|
|
852
|
+
const close = React4.useCallback(() => {
|
|
843
853
|
if (!onClose) return;
|
|
844
854
|
setClosing(true);
|
|
845
855
|
setTimeout(onClose, 210);
|
|
846
856
|
}, [onClose]);
|
|
847
|
-
|
|
857
|
+
React4.useEffect(() => {
|
|
848
858
|
if (!open || !onClose) return;
|
|
849
859
|
const h = (e) => {
|
|
850
860
|
if (e.key === "Escape") close();
|
|
@@ -870,17 +880,17 @@ function Drawer({ open = true, title, onClose, footer, children, className = "",
|
|
|
870
880
|
}
|
|
871
881
|
|
|
872
882
|
// src/components/surfaces/Modal.tsx
|
|
873
|
-
var
|
|
883
|
+
var React5 = __toESM(require("react"), 1);
|
|
874
884
|
var import_react_dom3 = require("react-dom");
|
|
875
885
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
876
886
|
function Modal({ open = true, title, description, onClose, footer, wide = false, children, className = "", ...rest }) {
|
|
877
|
-
const [closing, setClosing] =
|
|
878
|
-
const close =
|
|
887
|
+
const [closing, setClosing] = React5.useState(false);
|
|
888
|
+
const close = React5.useCallback(() => {
|
|
879
889
|
if (!onClose) return;
|
|
880
890
|
setClosing(true);
|
|
881
891
|
setTimeout(onClose, 190);
|
|
882
892
|
}, [onClose]);
|
|
883
|
-
|
|
893
|
+
React5.useEffect(() => {
|
|
884
894
|
if (!open || !onClose) return;
|
|
885
895
|
const h = (e) => {
|
|
886
896
|
if (e.key === "Escape") close();
|
|
@@ -1107,13 +1117,13 @@ function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
|
1107
1117
|
}
|
|
1108
1118
|
|
|
1109
1119
|
// src/components/navigation/Topbar.tsx
|
|
1110
|
-
var
|
|
1120
|
+
var React6 = __toESM(require("react"), 1);
|
|
1111
1121
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1112
1122
|
function useIsNarrow(breakpoint) {
|
|
1113
|
-
const [narrow, setNarrow] =
|
|
1123
|
+
const [narrow, setNarrow] = React6.useState(
|
|
1114
1124
|
() => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
1115
1125
|
);
|
|
1116
|
-
|
|
1126
|
+
React6.useEffect(() => {
|
|
1117
1127
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1118
1128
|
const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
1119
1129
|
const apply = () => setNarrow(mq.matches);
|
|
@@ -1134,11 +1144,11 @@ function Topbar({
|
|
|
1134
1144
|
...rest
|
|
1135
1145
|
}) {
|
|
1136
1146
|
const narrow = useIsNarrow(overflowBreakpoint);
|
|
1137
|
-
const [moreOpen, setMoreOpen] =
|
|
1138
|
-
const moreRef =
|
|
1147
|
+
const [moreOpen, setMoreOpen] = React6.useState(false);
|
|
1148
|
+
const moreRef = React6.useRef(null);
|
|
1139
1149
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
|
|
1140
1150
|
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,
|
|
1141
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1151
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React6.Fragment, { children: [
|
|
1142
1152
|
i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
|
|
1143
1153
|
i === crumbs.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fd-crumb-current", children: c.label }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1144
1154
|
"a",
|
|
@@ -1177,7 +1187,7 @@ function Topbar({
|
|
|
1177
1187
|
padded: true,
|
|
1178
1188
|
label: "More actions",
|
|
1179
1189
|
className: "fd-topbar-overflow",
|
|
1180
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fd-stack fd-topbar-overflow-list", children: overflowActions })
|
|
1190
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fd-stack fd-topbar-overflow-list", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(OverflowRowContext.Provider, { value: true, children: overflowActions }) })
|
|
1181
1191
|
}
|
|
1182
1192
|
)
|
|
1183
1193
|
] }) : overflowActions : null,
|
|
@@ -1343,19 +1353,19 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
|
|
|
1343
1353
|
}
|
|
1344
1354
|
|
|
1345
1355
|
// src/components/feedback/Tooltip.tsx
|
|
1346
|
-
var
|
|
1356
|
+
var React7 = __toESM(require("react"), 1);
|
|
1347
1357
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1348
1358
|
var TOOLTIP_BASE = 150;
|
|
1349
1359
|
var CLOSE_DELAY_MS = 120;
|
|
1350
1360
|
function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
1351
|
-
const anchorRef =
|
|
1352
|
-
const bubbleRef =
|
|
1353
|
-
const [reason, setReason] =
|
|
1354
|
-
const closeTimer =
|
|
1355
|
-
const id =
|
|
1361
|
+
const anchorRef = React7.useRef(null);
|
|
1362
|
+
const bubbleRef = React7.useRef(null);
|
|
1363
|
+
const [reason, setReason] = React7.useState(null);
|
|
1364
|
+
const closeTimer = React7.useRef(null);
|
|
1365
|
+
const id = React7.useId();
|
|
1356
1366
|
const descId = id + "-desc";
|
|
1357
1367
|
const open = reason != null;
|
|
1358
|
-
const cancelClose =
|
|
1368
|
+
const cancelClose = React7.useCallback(() => {
|
|
1359
1369
|
if (closeTimer.current) {
|
|
1360
1370
|
clearTimeout(closeTimer.current);
|
|
1361
1371
|
closeTimer.current = null;
|
|
@@ -1365,7 +1375,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1365
1375
|
cancelClose();
|
|
1366
1376
|
setReason(why);
|
|
1367
1377
|
};
|
|
1368
|
-
const hide =
|
|
1378
|
+
const hide = React7.useCallback(() => {
|
|
1369
1379
|
cancelClose();
|
|
1370
1380
|
setReason(null);
|
|
1371
1381
|
}, [cancelClose]);
|
|
@@ -1380,7 +1390,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1380
1390
|
setReason((r) => r === "hover" ? null : r);
|
|
1381
1391
|
}, CLOSE_DELAY_MS);
|
|
1382
1392
|
};
|
|
1383
|
-
|
|
1393
|
+
React7.useEffect(() => cancelClose, [cancelClose]);
|
|
1384
1394
|
const pos = usePopoverPosition(open, anchorRef, {
|
|
1385
1395
|
placement: placement === "bottom" ? "bottom-center" : "top-center",
|
|
1386
1396
|
offset: 8,
|
|
@@ -1390,7 +1400,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1390
1400
|
onDetach: hide
|
|
1391
1401
|
});
|
|
1392
1402
|
const zIndex = useOverlayLayer(TOOLTIP_BASE);
|
|
1393
|
-
|
|
1403
|
+
React7.useEffect(() => {
|
|
1394
1404
|
if (!open) return;
|
|
1395
1405
|
const key = (e) => {
|
|
1396
1406
|
if (e.key === "Escape") hide();
|
|
@@ -1418,7 +1428,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1418
1428
|
}
|
|
1419
1429
|
if (keyboard) show("focus");
|
|
1420
1430
|
};
|
|
1421
|
-
const described =
|
|
1431
|
+
const described = React7.isValidElement(children) ? React7.cloneElement(children, {
|
|
1422
1432
|
"aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
|
|
1423
1433
|
}) : children;
|
|
1424
1434
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
@@ -1426,7 +1436,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1426
1436
|
{
|
|
1427
1437
|
ref: anchorRef,
|
|
1428
1438
|
className: "fd-tooltip-anchor",
|
|
1429
|
-
"aria-describedby":
|
|
1439
|
+
"aria-describedby": React7.isValidElement(children) ? void 0 : descId,
|
|
1430
1440
|
onPointerEnter: (e) => {
|
|
1431
1441
|
if (isMouse(e)) hover();
|
|
1432
1442
|
},
|
|
@@ -1470,7 +1480,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1470
1480
|
}
|
|
1471
1481
|
|
|
1472
1482
|
// src/components/data/Clamp.tsx
|
|
1473
|
-
var
|
|
1483
|
+
var React8 = __toESM(require("react"), 1);
|
|
1474
1484
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1475
1485
|
function Clamp({
|
|
1476
1486
|
children,
|
|
@@ -1482,16 +1492,16 @@ function Clamp({
|
|
|
1482
1492
|
onToggle,
|
|
1483
1493
|
className = ""
|
|
1484
1494
|
}) {
|
|
1485
|
-
const [open, setOpen] =
|
|
1486
|
-
const [overflows, setOverflows] =
|
|
1487
|
-
const bodyRef =
|
|
1488
|
-
const charClamped =
|
|
1495
|
+
const [open, setOpen] = React8.useState(false);
|
|
1496
|
+
const [overflows, setOverflows] = React8.useState(false);
|
|
1497
|
+
const bodyRef = React8.useRef(null);
|
|
1498
|
+
const charClamped = React8.useMemo(() => {
|
|
1489
1499
|
if (open || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
|
|
1490
1500
|
const cut = text.slice(0, maxChars);
|
|
1491
1501
|
const at = cut.lastIndexOf(" ");
|
|
1492
1502
|
return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
1493
1503
|
}, [text, maxChars, open]);
|
|
1494
|
-
|
|
1504
|
+
React8.useLayoutEffect(() => {
|
|
1495
1505
|
const node = bodyRef.current;
|
|
1496
1506
|
if (maxChars || !node || !maxHeight) return;
|
|
1497
1507
|
const measure = () => {
|
|
@@ -1630,17 +1640,19 @@ function DataTable({
|
|
|
1630
1640
|
}
|
|
1631
1641
|
|
|
1632
1642
|
// src/components/data/FilterBar.tsx
|
|
1633
|
-
var
|
|
1643
|
+
var React9 = __toESM(require("react"), 1);
|
|
1634
1644
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1645
|
+
var FILTER_BAR_BASE = 120;
|
|
1635
1646
|
var isSet = (v) => !(v == null || v === "" || v === false);
|
|
1636
1647
|
function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", className = "", ...rest }) {
|
|
1637
|
-
const [panel, setPanel] =
|
|
1638
|
-
const
|
|
1639
|
-
const
|
|
1640
|
-
const
|
|
1648
|
+
const [panel, setPanel] = React9.useState(null);
|
|
1649
|
+
const zIndex = useOverlayLayer(FILTER_BAR_BASE);
|
|
1650
|
+
const rootRef = React9.useRef(null);
|
|
1651
|
+
const textInputRef = React9.useRef(null);
|
|
1652
|
+
const optionsRef = React9.useRef(null);
|
|
1641
1653
|
const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
|
|
1642
1654
|
const dismissible = !!panel && (panel.kind === "add" || panel.kind === "edit" && editingField?.type === "select");
|
|
1643
|
-
|
|
1655
|
+
React9.useEffect(() => {
|
|
1644
1656
|
if (!dismissible) return;
|
|
1645
1657
|
const away = (e) => {
|
|
1646
1658
|
if (rootRef.current && !rootRef.current.contains(e.target)) setPanel(null);
|
|
@@ -1655,7 +1667,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1655
1667
|
document.removeEventListener("keydown", esc);
|
|
1656
1668
|
};
|
|
1657
1669
|
}, [dismissible]);
|
|
1658
|
-
|
|
1670
|
+
React9.useEffect(() => {
|
|
1659
1671
|
if (!panel || panel.kind !== "edit") return;
|
|
1660
1672
|
if (editingField?.type === "text") {
|
|
1661
1673
|
textInputRef.current?.focus();
|
|
@@ -1725,11 +1737,11 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1725
1737
|
field.label,
|
|
1726
1738
|
chosen ? ": " + chosen.label : ""
|
|
1727
1739
|
] }),
|
|
1728
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1740
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(LayerProvider, { zIndex, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1729
1741
|
"span",
|
|
1730
1742
|
{
|
|
1731
1743
|
className: "fd-view-enter",
|
|
1732
|
-
style: { position: "absolute", top: "calc(100% + 6px)", left: 0, zIndex
|
|
1744
|
+
style: { position: "absolute", top: "calc(100% + 6px)", left: 0, zIndex, minWidth: 200, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 },
|
|
1733
1745
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fd-stack", role: "listbox", "aria-label": field.label, ref: optionsRef, style: { gap: 2 }, children: field.options.map((o) => {
|
|
1734
1746
|
const on = o.value === value;
|
|
1735
1747
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -1750,7 +1762,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1750
1762
|
);
|
|
1751
1763
|
}) })
|
|
1752
1764
|
}
|
|
1753
|
-
)
|
|
1765
|
+
) })
|
|
1754
1766
|
] }, field.key);
|
|
1755
1767
|
}
|
|
1756
1768
|
if (isSet(value)) {
|
|
@@ -1777,11 +1789,11 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1777
1789
|
children: "Filter"
|
|
1778
1790
|
}
|
|
1779
1791
|
),
|
|
1780
|
-
panel?.kind === "add" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1792
|
+
panel?.kind === "add" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(LayerProvider, { zIndex, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1781
1793
|
"span",
|
|
1782
1794
|
{
|
|
1783
1795
|
className: "fd-view-enter",
|
|
1784
|
-
style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex
|
|
1796
|
+
style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex, width: 220, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 },
|
|
1785
1797
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "fd-stack", role: "menu", "aria-label": "Add filter", style: { gap: 2 }, children: [
|
|
1786
1798
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Add filter" }),
|
|
1787
1799
|
addableFields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -1798,7 +1810,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1798
1810
|
))
|
|
1799
1811
|
] })
|
|
1800
1812
|
}
|
|
1801
|
-
) : null
|
|
1813
|
+
) }) : null
|
|
1802
1814
|
] }) : null
|
|
1803
1815
|
] });
|
|
1804
1816
|
}
|
|
@@ -1821,7 +1833,7 @@ function StatTile({ label, value, sub, delta, loading = false, compact: compact3
|
|
|
1821
1833
|
}
|
|
1822
1834
|
|
|
1823
1835
|
// src/components/data/CodeBlock.tsx
|
|
1824
|
-
var
|
|
1836
|
+
var React10 = __toESM(require("react"), 1);
|
|
1825
1837
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1826
1838
|
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)$/;
|
|
1827
1839
|
var RULES = {
|
|
@@ -1977,13 +1989,13 @@ function tokenize(src, lang) {
|
|
|
1977
1989
|
return out;
|
|
1978
1990
|
}
|
|
1979
1991
|
function Highlighted({ code, lang }) {
|
|
1980
|
-
const toks =
|
|
1992
|
+
const toks = React10.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
1981
1993
|
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) });
|
|
1982
1994
|
}
|
|
1983
1995
|
function useCopy() {
|
|
1984
|
-
const [done, setDone] =
|
|
1985
|
-
const timer =
|
|
1986
|
-
|
|
1996
|
+
const [done, setDone] = React10.useState(false);
|
|
1997
|
+
const timer = React10.useRef(null);
|
|
1998
|
+
React10.useEffect(() => () => {
|
|
1987
1999
|
if (timer.current) clearTimeout(timer.current);
|
|
1988
2000
|
}, []);
|
|
1989
2001
|
const copy = (text) => {
|
|
@@ -2019,8 +2031,8 @@ function CodeBlock({
|
|
|
2019
2031
|
actions,
|
|
2020
2032
|
className = ""
|
|
2021
2033
|
}) {
|
|
2022
|
-
const [wrap, setWrap] =
|
|
2023
|
-
const [open, setOpen] =
|
|
2034
|
+
const [wrap, setWrap] = React10.useState(!!wrapDefault);
|
|
2035
|
+
const [open, setOpen] = React10.useState(false);
|
|
2024
2036
|
const [copied, copy] = useCopy();
|
|
2025
2037
|
const body = String(code).replace(/\n$/, "");
|
|
2026
2038
|
const lines = body.split("\n");
|
|
@@ -2049,7 +2061,7 @@ function CodeBlock({
|
|
|
2049
2061
|
] });
|
|
2050
2062
|
}
|
|
2051
2063
|
function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
|
|
2052
|
-
const [open, setOpen] =
|
|
2064
|
+
const [open, setOpen] = React10.useState(false);
|
|
2053
2065
|
const [copied, copy] = useCopy();
|
|
2054
2066
|
const raw = String(diff).replace(/\n$/, "");
|
|
2055
2067
|
const all = raw.split("\n").map((line) => {
|
|
@@ -2095,7 +2107,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
2095
2107
|
}
|
|
2096
2108
|
|
|
2097
2109
|
// src/components/data/Markdown.tsx
|
|
2098
|
-
var
|
|
2110
|
+
var React11 = __toESM(require("react"), 1);
|
|
2099
2111
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
2100
2112
|
var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
|
|
2101
2113
|
var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
|
|
@@ -2134,7 +2146,7 @@ function inlineNodes(src, ctx, keyBase) {
|
|
|
2134
2146
|
const href = safeHref(g(2));
|
|
2135
2147
|
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()));
|
|
2136
2148
|
} else if (kind === "cite") {
|
|
2137
|
-
out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
2149
|
+
out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(React11.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("sup", { className: "fd-md-cite", children: g(1) }, key()));
|
|
2138
2150
|
} 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()));
|
|
2139
2151
|
else if (kind === "strong") out.push(/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
2140
2152
|
else if (kind === "em") out.push(/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
@@ -2299,7 +2311,7 @@ function Markdown({
|
|
|
2299
2311
|
onLinkClick
|
|
2300
2312
|
}) {
|
|
2301
2313
|
const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
|
|
2302
|
-
const blocks =
|
|
2314
|
+
const blocks = React11.useMemo(() => parseBlocks(source), [source]);
|
|
2303
2315
|
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
|
|
2304
2316
|
}
|
|
2305
2317
|
function MarkdownInline({ source = "", className = "", onLinkClick }) {
|
|
@@ -2407,7 +2419,7 @@ function Pagination({
|
|
|
2407
2419
|
}
|
|
2408
2420
|
|
|
2409
2421
|
// src/components/data/RelativeTime.tsx
|
|
2410
|
-
var
|
|
2422
|
+
var React12 = __toESM(require("react"), 1);
|
|
2411
2423
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
2412
2424
|
var MIN = 6e4;
|
|
2413
2425
|
var HOUR = 36e5;
|
|
@@ -2459,9 +2471,9 @@ function formatDuration(ms) {
|
|
|
2459
2471
|
return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
|
|
2460
2472
|
}
|
|
2461
2473
|
function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
|
|
2462
|
-
const [, force] =
|
|
2474
|
+
const [, force] = React12.useState(0);
|
|
2463
2475
|
const t = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
2464
|
-
|
|
2476
|
+
React12.useEffect(() => {
|
|
2465
2477
|
if (!refresh2 || !t || isNaN(t)) return;
|
|
2466
2478
|
const abs = Math.abs(t - Date.now());
|
|
2467
2479
|
if (abs > DAY) return;
|
|
@@ -2477,10 +2489,10 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
|
|
|
2477
2489
|
}
|
|
2478
2490
|
|
|
2479
2491
|
// src/components/data/ScoreMeter.tsx
|
|
2480
|
-
var
|
|
2492
|
+
var React14 = __toESM(require("react"), 1);
|
|
2481
2493
|
|
|
2482
2494
|
// src/components/data/SegmentedMeter.tsx
|
|
2483
|
-
var
|
|
2495
|
+
var React13 = __toESM(require("react"), 1);
|
|
2484
2496
|
|
|
2485
2497
|
// src/kits/files.ts
|
|
2486
2498
|
function formatBytes(n) {
|
|
@@ -2685,7 +2697,7 @@ function SegmentedMeter({
|
|
|
2685
2697
|
const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
|
|
2686
2698
|
const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
|
|
2687
2699
|
const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
|
|
2688
|
-
const generatedId =
|
|
2700
|
+
const generatedId = React13.useId();
|
|
2689
2701
|
const uid2 = id || generatedId;
|
|
2690
2702
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
|
|
2691
2703
|
label || showTotal ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "fd-segmeter-head", children: [
|
|
@@ -2769,10 +2781,10 @@ function ScoreMeter({
|
|
|
2769
2781
|
breakdownWidth = 280,
|
|
2770
2782
|
className = ""
|
|
2771
2783
|
}) {
|
|
2772
|
-
const [open, setOpen] =
|
|
2773
|
-
const ref =
|
|
2784
|
+
const [open, setOpen] = React14.useState(false);
|
|
2785
|
+
const ref = React14.useRef(null);
|
|
2774
2786
|
const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
2775
|
-
const body = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
2787
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(React14.Fragment, { children: [
|
|
2776
2788
|
/* @__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 }) }),
|
|
2777
2789
|
showScore ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
|
|
2778
2790
|
] });
|
|
@@ -2791,7 +2803,7 @@ function ScoreMeter({
|
|
|
2791
2803
|
}
|
|
2792
2804
|
);
|
|
2793
2805
|
}
|
|
2794
|
-
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
2806
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(React14.Fragment, { children: [
|
|
2795
2807
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2796
2808
|
"button",
|
|
2797
2809
|
{
|
|
@@ -2822,12 +2834,14 @@ function ScoreMeter({
|
|
|
2822
2834
|
}
|
|
2823
2835
|
|
|
2824
2836
|
// src/components/data/SortMenu.tsx
|
|
2825
|
-
var
|
|
2837
|
+
var React15 = __toESM(require("react"), 1);
|
|
2826
2838
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
2839
|
+
var SORT_MENU_BASE = 120;
|
|
2827
2840
|
function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", className = "", ...rest }) {
|
|
2828
|
-
const [open, setOpen] =
|
|
2829
|
-
const
|
|
2830
|
-
|
|
2841
|
+
const [open, setOpen] = React15.useState(false);
|
|
2842
|
+
const zIndex = useOverlayLayer(SORT_MENU_BASE);
|
|
2843
|
+
const ref = React15.useRef(null);
|
|
2844
|
+
React15.useEffect(() => {
|
|
2831
2845
|
if (!open) return;
|
|
2832
2846
|
const away = (e) => {
|
|
2833
2847
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -2874,7 +2888,7 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
|
|
|
2874
2888
|
cur ? cur.label : "Unsorted",
|
|
2875
2889
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("i", { className: "ph ph-" + (dir === "asc" ? "arrow-up" : "arrow-down"), style: { fontSize: 12, marginLeft: 6, opacity: 0.75 } })
|
|
2876
2890
|
] }),
|
|
2877
|
-
open ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "fd-view-enter", style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex
|
|
2891
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(LayerProvider, { zIndex, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "fd-view-enter", style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex, width: 280, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
2878
2892
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Sort by" }),
|
|
2879
2893
|
fields.map((f) => {
|
|
2880
2894
|
const active = cur && cur.key === f.key;
|
|
@@ -2884,12 +2898,12 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
|
|
|
2884
2898
|
arrow(f, "desc")
|
|
2885
2899
|
] }, f.key);
|
|
2886
2900
|
})
|
|
2887
|
-
] }) }) : null
|
|
2901
|
+
] }) }) }) : null
|
|
2888
2902
|
] });
|
|
2889
2903
|
}
|
|
2890
2904
|
|
|
2891
2905
|
// src/components/data/StepList.tsx
|
|
2892
|
-
var
|
|
2906
|
+
var React16 = __toESM(require("react"), 1);
|
|
2893
2907
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
2894
2908
|
var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
|
|
2895
2909
|
function StepList({
|
|
@@ -2902,9 +2916,9 @@ function StepList({
|
|
|
2902
2916
|
dense = false,
|
|
2903
2917
|
className = ""
|
|
2904
2918
|
}) {
|
|
2905
|
-
const [openState, setOpenState] =
|
|
2919
|
+
const [openState, setOpenState] = React16.useState(defaultOpen);
|
|
2906
2920
|
const open = openProp == null ? openState : openProp;
|
|
2907
|
-
const [expanded, setExpanded] =
|
|
2921
|
+
const [expanded, setExpanded] = React16.useState({});
|
|
2908
2922
|
if (!steps.length) return null;
|
|
2909
2923
|
const running = steps.some((s) => s.status === "running");
|
|
2910
2924
|
const failed = steps.filter((s) => s.status === "error").length;
|
|
@@ -2962,7 +2976,7 @@ function StepList({
|
|
|
2962
2976
|
}
|
|
2963
2977
|
|
|
2964
2978
|
// src/components/data/VirtualList.tsx
|
|
2965
|
-
var
|
|
2979
|
+
var React17 = __toESM(require("react"), 1);
|
|
2966
2980
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
2967
2981
|
var VIRTUAL_LIST_BUFFER_ROWS = 20;
|
|
2968
2982
|
var VIRTUAL_LIST_ROW_GAP = 6;
|
|
@@ -3014,35 +3028,35 @@ function VirtualList({
|
|
|
3014
3028
|
className = "",
|
|
3015
3029
|
style
|
|
3016
3030
|
}) {
|
|
3017
|
-
const [scrollTop, setScrollTop] =
|
|
3018
|
-
const loaded =
|
|
3031
|
+
const [scrollTop, setScrollTop] = React17.useState(0);
|
|
3032
|
+
const loaded = React17.useMemo(
|
|
3019
3033
|
() => ({ firstItemIndex, count: items.length }),
|
|
3020
3034
|
[firstItemIndex, items.length]
|
|
3021
3035
|
);
|
|
3022
3036
|
const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
|
|
3023
3037
|
const bandKey = firstItemIndex + ":" + items.length;
|
|
3024
|
-
const win =
|
|
3038
|
+
const win = React17.useMemo(
|
|
3025
3039
|
() => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
|
|
3026
3040
|
[scrollTop, height, itemHeight, total, loaded]
|
|
3027
3041
|
);
|
|
3028
|
-
const need =
|
|
3042
|
+
const need = React17.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
|
|
3029
3043
|
const wantStart = need.start && hasMore?.start !== false;
|
|
3030
3044
|
const wantEnd = need.end && hasMore?.end !== false;
|
|
3031
3045
|
const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
|
|
3032
3046
|
const askKey = bandKey + "@" + bucket2;
|
|
3033
|
-
const asked =
|
|
3034
|
-
|
|
3047
|
+
const asked = React17.useRef({ start: null, end: null });
|
|
3048
|
+
React17.useEffect(() => {
|
|
3035
3049
|
if (loading || !wantStart || asked.current.start === askKey) return;
|
|
3036
3050
|
asked.current.start = askKey;
|
|
3037
3051
|
onNeedMore("start", win);
|
|
3038
3052
|
}, [wantStart, loading, askKey, onNeedMore, win]);
|
|
3039
|
-
|
|
3053
|
+
React17.useEffect(() => {
|
|
3040
3054
|
if (loading || !wantEnd || asked.current.end === askKey) return;
|
|
3041
3055
|
asked.current.end = askKey;
|
|
3042
3056
|
onNeedMore("end", win);
|
|
3043
3057
|
}, [wantEnd, loading, askKey, onNeedMore, win]);
|
|
3044
|
-
const lastKeysRef =
|
|
3045
|
-
const newKeys =
|
|
3058
|
+
const lastKeysRef = React17.useRef(null);
|
|
3059
|
+
const newKeys = React17.useMemo(() => {
|
|
3046
3060
|
const prev = lastKeysRef.current;
|
|
3047
3061
|
if (!prev) return /* @__PURE__ */ new Set();
|
|
3048
3062
|
const fresh = /* @__PURE__ */ new Set();
|
|
@@ -3052,7 +3066,7 @@ function VirtualList({
|
|
|
3052
3066
|
}
|
|
3053
3067
|
return fresh;
|
|
3054
3068
|
}, [items]);
|
|
3055
|
-
|
|
3069
|
+
React17.useEffect(() => {
|
|
3056
3070
|
lastKeysRef.current = new Set(items.map(keyOf));
|
|
3057
3071
|
}, [items]);
|
|
3058
3072
|
const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
|
|
@@ -3097,7 +3111,7 @@ function VirtualList({
|
|
|
3097
3111
|
}
|
|
3098
3112
|
|
|
3099
3113
|
// src/components/data/EntityRow.tsx
|
|
3100
|
-
var
|
|
3114
|
+
var React18 = __toESM(require("react"), 1);
|
|
3101
3115
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
3102
3116
|
var ENTITY_ROW_METRIC_WIDTH = 74;
|
|
3103
3117
|
var METRIC_TONE_COLOR = {
|
|
@@ -3110,7 +3124,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
|
|
|
3110
3124
|
const key = m.id || m.label || i;
|
|
3111
3125
|
const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
|
|
3112
3126
|
const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
|
|
3113
|
-
const content = /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
3127
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(React18.Fragment, { children: [
|
|
3114
3128
|
m.icon ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
|
|
3115
3129
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
|
|
3116
3130
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "fd-sr", children: " " + m.label })
|
|
@@ -3178,14 +3192,14 @@ function EntityRow({
|
|
|
3178
3192
|
}
|
|
3179
3193
|
|
|
3180
3194
|
// src/components/data/TransferList.tsx
|
|
3181
|
-
var
|
|
3195
|
+
var React20 = __toESM(require("react"), 1);
|
|
3182
3196
|
var import_react_dom4 = require("react-dom");
|
|
3183
3197
|
|
|
3184
3198
|
// src/components/forms/field.tsx
|
|
3185
|
-
var
|
|
3199
|
+
var React19 = __toESM(require("react"), 1);
|
|
3186
3200
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
3187
3201
|
function useFieldId(id) {
|
|
3188
|
-
const generated =
|
|
3202
|
+
const generated = React19.useId();
|
|
3189
3203
|
return id || generated;
|
|
3190
3204
|
}
|
|
3191
3205
|
function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
|
|
@@ -3303,12 +3317,12 @@ function TransferList({
|
|
|
3303
3317
|
listHeight = 440,
|
|
3304
3318
|
className = ""
|
|
3305
3319
|
}) {
|
|
3306
|
-
const [drag, setDrag] =
|
|
3307
|
-
const [dragOverSide, setDragOverSide] =
|
|
3308
|
-
const dragRef =
|
|
3309
|
-
const armedRef =
|
|
3310
|
-
const sideRefs =
|
|
3311
|
-
const hitTestSide =
|
|
3320
|
+
const [drag, setDrag] = React20.useState(null);
|
|
3321
|
+
const [dragOverSide, setDragOverSide] = React20.useState(null);
|
|
3322
|
+
const dragRef = React20.useRef(null);
|
|
3323
|
+
const armedRef = React20.useRef(null);
|
|
3324
|
+
const sideRefs = React20.useRef({ left: null, right: null });
|
|
3325
|
+
const hitTestSide = React20.useCallback((x, y) => {
|
|
3312
3326
|
for (const side of ["left", "right"]) {
|
|
3313
3327
|
const el = sideRefs.current[side];
|
|
3314
3328
|
if (!el) continue;
|
|
@@ -3317,7 +3331,7 @@ function TransferList({
|
|
|
3317
3331
|
}
|
|
3318
3332
|
return null;
|
|
3319
3333
|
}, []);
|
|
3320
|
-
const findItem =
|
|
3334
|
+
const findItem = React20.useCallback(
|
|
3321
3335
|
(side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
|
|
3322
3336
|
[left.items, right.items, keyOf]
|
|
3323
3337
|
);
|
|
@@ -3339,7 +3353,7 @@ function TransferList({
|
|
|
3339
3353
|
height: rect.height
|
|
3340
3354
|
};
|
|
3341
3355
|
};
|
|
3342
|
-
|
|
3356
|
+
React20.useEffect(() => {
|
|
3343
3357
|
const onMovePointer = (e) => {
|
|
3344
3358
|
const armed = armedRef.current;
|
|
3345
3359
|
if (!armed || e.pointerId !== armed.pointerId) return;
|
|
@@ -3392,7 +3406,7 @@ function TransferList({
|
|
|
3392
3406
|
window.removeEventListener("pointercancel", endDrag);
|
|
3393
3407
|
};
|
|
3394
3408
|
}, [hitTestSide, findItem, onMove]);
|
|
3395
|
-
|
|
3409
|
+
React20.useEffect(() => {
|
|
3396
3410
|
if (!drag || typeof document === "undefined") return;
|
|
3397
3411
|
const prev = document.body.style.userSelect;
|
|
3398
3412
|
document.body.style.userSelect = "none";
|
|
@@ -3500,11 +3514,11 @@ function TransferList({
|
|
|
3500
3514
|
}
|
|
3501
3515
|
|
|
3502
3516
|
// src/components/forms/Checkbox.tsx
|
|
3503
|
-
var
|
|
3517
|
+
var React21 = __toESM(require("react"), 1);
|
|
3504
3518
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
3505
3519
|
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
3506
|
-
const ref =
|
|
3507
|
-
|
|
3520
|
+
const ref = React21.useRef(null);
|
|
3521
|
+
React21.useEffect(() => {
|
|
3508
3522
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
3509
3523
|
}, [indeterminate]);
|
|
3510
3524
|
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
@@ -3563,7 +3577,7 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
|
|
|
3563
3577
|
}
|
|
3564
3578
|
|
|
3565
3579
|
// src/components/forms/NumberInput.tsx
|
|
3566
|
-
var
|
|
3580
|
+
var React22 = __toESM(require("react"), 1);
|
|
3567
3581
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
3568
3582
|
function NumberInput({
|
|
3569
3583
|
label,
|
|
@@ -3591,10 +3605,10 @@ function NumberInput({
|
|
|
3591
3605
|
const n = Number(String(v == null ? "" : v).replace(/[^0-9.-]/g, ""));
|
|
3592
3606
|
return isNaN(n) ? null : n;
|
|
3593
3607
|
};
|
|
3594
|
-
const [text, setText] =
|
|
3595
|
-
const [editing, setEditing] =
|
|
3596
|
-
const timer =
|
|
3597
|
-
|
|
3608
|
+
const [text, setText] = React22.useState(value == null || value === "" ? "" : String(value));
|
|
3609
|
+
const [editing, setEditing] = React22.useState(false);
|
|
3610
|
+
const timer = React22.useRef(null);
|
|
3611
|
+
React22.useEffect(() => {
|
|
3598
3612
|
if (!editing) setText(value == null || value === "" ? "" : String(value));
|
|
3599
3613
|
}, [value, editing]);
|
|
3600
3614
|
const clamp = (n) => Math.min(max, Math.max(min, n));
|
|
@@ -3618,7 +3632,7 @@ function NumberInput({
|
|
|
3618
3632
|
const release = () => {
|
|
3619
3633
|
if (timer.current) clearTimeout(timer.current);
|
|
3620
3634
|
};
|
|
3621
|
-
|
|
3635
|
+
React22.useEffect(() => () => {
|
|
3622
3636
|
if (timer.current) clearTimeout(timer.current);
|
|
3623
3637
|
}, []);
|
|
3624
3638
|
const shown = editing ? text : (() => {
|
|
@@ -3705,7 +3719,7 @@ function NumberInput({
|
|
|
3705
3719
|
}
|
|
3706
3720
|
|
|
3707
3721
|
// src/components/forms/Select.tsx
|
|
3708
|
-
var
|
|
3722
|
+
var React23 = __toESM(require("react"), 1);
|
|
3709
3723
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
3710
3724
|
var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
|
|
3711
3725
|
function Select({
|
|
@@ -3732,13 +3746,13 @@ function Select({
|
|
|
3732
3746
|
const isOn = (v) => multiple ? vals.includes(v) : v === value;
|
|
3733
3747
|
const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
|
|
3734
3748
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
3735
|
-
const [open, setOpen] =
|
|
3736
|
-
const [q, setQ] =
|
|
3737
|
-
const [active, setActive] =
|
|
3738
|
-
const rootRef =
|
|
3739
|
-
const boxRef =
|
|
3740
|
-
const listRef =
|
|
3741
|
-
const typeBuf =
|
|
3749
|
+
const [open, setOpen] = React23.useState(false);
|
|
3750
|
+
const [q, setQ] = React23.useState("");
|
|
3751
|
+
const [active, setActive] = React23.useState(-1);
|
|
3752
|
+
const rootRef = React23.useRef(null);
|
|
3753
|
+
const boxRef = React23.useRef(null);
|
|
3754
|
+
const listRef = React23.useRef(null);
|
|
3755
|
+
const typeBuf = React23.useRef({ s: "", t: 0 });
|
|
3742
3756
|
const selected = multiple ? null : opts.find((o) => o.value === value);
|
|
3743
3757
|
const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
|
|
3744
3758
|
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;
|
|
@@ -3763,7 +3777,7 @@ function Select({
|
|
|
3763
3777
|
}
|
|
3764
3778
|
setOpen(!open);
|
|
3765
3779
|
};
|
|
3766
|
-
|
|
3780
|
+
React23.useEffect(() => {
|
|
3767
3781
|
if (!open || active < 0 || !listRef.current) return;
|
|
3768
3782
|
const el = listRef.current.querySelector('[data-i="' + active + '"]');
|
|
3769
3783
|
if (el) {
|
|
@@ -3884,7 +3898,7 @@ function Select({
|
|
|
3884
3898
|
),
|
|
3885
3899
|
q ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
|
|
3886
3900
|
] }) : void 0,
|
|
3887
|
-
footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3901
|
+
footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React23.Fragment, { children: [
|
|
3888
3902
|
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3889
3903
|
"button",
|
|
3890
3904
|
{
|
|
@@ -3915,7 +3929,7 @@ function Select({
|
|
|
3915
3929
|
'Nothing matches "',
|
|
3916
3930
|
q,
|
|
3917
3931
|
'".'
|
|
3918
|
-
] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3932
|
+
] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React23.Fragment, { children: [
|
|
3919
3933
|
grp.g ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "fd-pop-group", children: grp.g }) : null,
|
|
3920
3934
|
grp.items.map(({ o, i }) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3921
3935
|
"button",
|
|
@@ -3952,7 +3966,7 @@ function Select({
|
|
|
3952
3966
|
}
|
|
3953
3967
|
|
|
3954
3968
|
// src/components/forms/DatePicker.tsx
|
|
3955
|
-
var
|
|
3969
|
+
var React24 = __toESM(require("react"), 1);
|
|
3956
3970
|
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
3957
3971
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
3958
3972
|
var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
@@ -3970,10 +3984,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3970
3984
|
const today = /* @__PURE__ */ new Date();
|
|
3971
3985
|
const sel = range ? value || {} : { start: value, end: value };
|
|
3972
3986
|
const anchor = parse(sel.start) || parse(initialMonth) || today;
|
|
3973
|
-
const [vy, setVy] =
|
|
3974
|
-
const [vm, setVm] =
|
|
3975
|
-
const [mode2, setMode] =
|
|
3976
|
-
const [hover, setHover] =
|
|
3987
|
+
const [vy, setVy] = React24.useState(anchor.getFullYear());
|
|
3988
|
+
const [vm, setVm] = React24.useState(anchor.getMonth());
|
|
3989
|
+
const [mode2, setMode] = React24.useState("days");
|
|
3990
|
+
const [hover, setHover] = React24.useState(null);
|
|
3977
3991
|
const s = parse(sel.start), e = parse(sel.end);
|
|
3978
3992
|
const hoverEnd = range && s && !e && hover ? parse(hover) : null;
|
|
3979
3993
|
const inRange = (d) => {
|
|
@@ -4089,9 +4103,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
4089
4103
|
}
|
|
4090
4104
|
function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, ...rest }) {
|
|
4091
4105
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
4092
|
-
const [open, setOpen] =
|
|
4093
|
-
const rootRef =
|
|
4094
|
-
const boxRef =
|
|
4106
|
+
const [open, setOpen] = React24.useState(false);
|
|
4107
|
+
const rootRef = React24.useRef(null);
|
|
4108
|
+
const boxRef = React24.useRef(null);
|
|
4095
4109
|
const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
|
|
4096
4110
|
const toggle = () => {
|
|
4097
4111
|
if (!disabled) setOpen(!open);
|
|
@@ -4153,7 +4167,7 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
|
|
|
4153
4167
|
}
|
|
4154
4168
|
|
|
4155
4169
|
// src/components/forms/TimePicker.tsx
|
|
4156
|
-
var
|
|
4170
|
+
var React25 = __toESM(require("react"), 1);
|
|
4157
4171
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
4158
4172
|
var pad = (n) => String(n).padStart(2, "0");
|
|
4159
4173
|
function ClockFace({ value = "09:00", onChange }) {
|
|
@@ -4162,9 +4176,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
4162
4176
|
if (isNaN(m)) m = 0;
|
|
4163
4177
|
const pm = h24 >= 12;
|
|
4164
4178
|
const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
|
|
4165
|
-
const [mode2, setMode] =
|
|
4166
|
-
const faceRef =
|
|
4167
|
-
const dragging =
|
|
4179
|
+
const [mode2, setMode] = React25.useState("h");
|
|
4180
|
+
const faceRef = React25.useRef(null);
|
|
4181
|
+
const dragging = React25.useRef(false);
|
|
4168
4182
|
const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
|
|
4169
4183
|
const R = 108, NR = 80;
|
|
4170
4184
|
const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
|
|
@@ -4237,9 +4251,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
4237
4251
|
}
|
|
4238
4252
|
function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
|
|
4239
4253
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
4240
|
-
const [open, setOpen] =
|
|
4241
|
-
const rootRef =
|
|
4242
|
-
const boxRef =
|
|
4254
|
+
const [open, setOpen] = React25.useState(false);
|
|
4255
|
+
const rootRef = React25.useRef(null);
|
|
4256
|
+
const boxRef = React25.useRef(null);
|
|
4243
4257
|
const disp = () => {
|
|
4244
4258
|
if (!value) return "";
|
|
4245
4259
|
const [h, m] = value.split(":").map(Number);
|
|
@@ -4282,7 +4296,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
4282
4296
|
offset: 6,
|
|
4283
4297
|
width: 262,
|
|
4284
4298
|
role: "presentation",
|
|
4285
|
-
footer: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
4299
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(React25.Fragment, { children: [
|
|
4286
4300
|
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
4287
4301
|
"button",
|
|
4288
4302
|
{
|
|
@@ -4310,7 +4324,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
4310
4324
|
}
|
|
4311
4325
|
|
|
4312
4326
|
// src/components/forms/Slider.tsx
|
|
4313
|
-
var
|
|
4327
|
+
var React26 = __toESM(require("react"), 1);
|
|
4314
4328
|
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
4315
4329
|
function Slider({
|
|
4316
4330
|
label,
|
|
@@ -4328,7 +4342,7 @@ function Slider({
|
|
|
4328
4342
|
...rest
|
|
4329
4343
|
}) {
|
|
4330
4344
|
const fieldId = useFieldId(id);
|
|
4331
|
-
const [dragging, setDragging] =
|
|
4345
|
+
const [dragging, setDragging] = React26.useState(false);
|
|
4332
4346
|
const v = value === void 0 ? min : Number(value);
|
|
4333
4347
|
const pct = max === min ? 0 : (v - min) / (max - min) * 100;
|
|
4334
4348
|
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
|
|
@@ -4362,7 +4376,7 @@ function Slider({
|
|
|
4362
4376
|
}
|
|
4363
4377
|
|
|
4364
4378
|
// src/components/forms/RangeSlider.tsx
|
|
4365
|
-
var
|
|
4379
|
+
var React27 = __toESM(require("react"), 1);
|
|
4366
4380
|
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
4367
4381
|
function RangeSlider({
|
|
4368
4382
|
label,
|
|
@@ -4382,9 +4396,9 @@ function RangeSlider({
|
|
|
4382
4396
|
}) {
|
|
4383
4397
|
const fmt2 = format || ((v) => String(v));
|
|
4384
4398
|
const [a, b] = value || [min, max];
|
|
4385
|
-
const [drag, setDrag] =
|
|
4386
|
-
const [focus, setFocus] =
|
|
4387
|
-
const railRef =
|
|
4399
|
+
const [drag, setDrag] = React27.useState(null);
|
|
4400
|
+
const [focus, setFocus] = React27.useState(null);
|
|
4401
|
+
const railRef = React27.useRef(null);
|
|
4388
4402
|
const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
|
|
4389
4403
|
const clampPair = (i, v) => {
|
|
4390
4404
|
v = Math.min(max, Math.max(min, Math.round(v / step) * step));
|
|
@@ -4399,7 +4413,7 @@ function RangeSlider({
|
|
|
4399
4413
|
const r = railRef.current.getBoundingClientRect();
|
|
4400
4414
|
return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
|
|
4401
4415
|
};
|
|
4402
|
-
|
|
4416
|
+
React27.useEffect(() => {
|
|
4403
4417
|
if (drag === null) return;
|
|
4404
4418
|
const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
|
|
4405
4419
|
const upH = () => setDrag(null);
|
|
@@ -4480,7 +4494,7 @@ function RangeSlider({
|
|
|
4480
4494
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
|
|
4481
4495
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-rail", ref: railRef }),
|
|
4482
4496
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
|
|
4483
|
-
marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
|
|
4497
|
+
marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(React27.Fragment, { children: [
|
|
4484
4498
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
|
|
4485
4499
|
m.label ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
|
|
4486
4500
|
] }, m.value)),
|
|
@@ -4509,7 +4523,7 @@ function RangeSlider({
|
|
|
4509
4523
|
}
|
|
4510
4524
|
|
|
4511
4525
|
// src/components/forms/Dropzone.tsx
|
|
4512
|
-
var
|
|
4526
|
+
var React28 = __toESM(require("react"), 1);
|
|
4513
4527
|
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
4514
4528
|
function Dropzone({
|
|
4515
4529
|
onFiles,
|
|
@@ -4524,8 +4538,8 @@ function Dropzone({
|
|
|
4524
4538
|
className = "",
|
|
4525
4539
|
style
|
|
4526
4540
|
}) {
|
|
4527
|
-
const [over, setOver] =
|
|
4528
|
-
const depth =
|
|
4541
|
+
const [over, setOver] = React28.useState(false);
|
|
4542
|
+
const depth = React28.useRef(0);
|
|
4529
4543
|
const has = (e) => {
|
|
4530
4544
|
const dt = e.dataTransfer;
|
|
4531
4545
|
if (!dt) return false;
|
|
@@ -4587,8 +4601,8 @@ function FilePickButton({
|
|
|
4587
4601
|
className = "",
|
|
4588
4602
|
children
|
|
4589
4603
|
}) {
|
|
4590
|
-
const ref =
|
|
4591
|
-
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
4604
|
+
const ref = React28.useRef(null);
|
|
4605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(React28.Fragment, { children: [
|
|
4592
4606
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
4593
4607
|
"button",
|
|
4594
4608
|
{
|
|
@@ -4621,10 +4635,10 @@ function FilePickButton({
|
|
|
4621
4635
|
}
|
|
4622
4636
|
function useStagedFiles(upload, opts) {
|
|
4623
4637
|
const o = opts || {};
|
|
4624
|
-
const [items, setItems] =
|
|
4625
|
-
const controllers =
|
|
4638
|
+
const [items, setItems] = React28.useState([]);
|
|
4639
|
+
const controllers = React28.useRef({});
|
|
4626
4640
|
const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
|
|
4627
|
-
const run =
|
|
4641
|
+
const run = React28.useCallback((att) => {
|
|
4628
4642
|
if (!upload) return;
|
|
4629
4643
|
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
4630
4644
|
controllers.current[att.id] = ac;
|
|
@@ -4641,14 +4655,14 @@ function useStagedFiles(upload, opts) {
|
|
|
4641
4655
|
delete controllers.current[att.id];
|
|
4642
4656
|
});
|
|
4643
4657
|
}, [upload]);
|
|
4644
|
-
const add =
|
|
4658
|
+
const add = React28.useCallback((files) => {
|
|
4645
4659
|
if (!upload) return [];
|
|
4646
4660
|
const atts = Array.from(files).map((f) => toAttachment(f));
|
|
4647
4661
|
setItems((list) => list.concat(atts));
|
|
4648
4662
|
atts.forEach(run);
|
|
4649
4663
|
return atts;
|
|
4650
4664
|
}, [upload, run]);
|
|
4651
|
-
const remove =
|
|
4665
|
+
const remove = React28.useCallback((att) => {
|
|
4652
4666
|
const ac = controllers.current[att.id];
|
|
4653
4667
|
if (ac) {
|
|
4654
4668
|
try {
|
|
@@ -4659,10 +4673,10 @@ function useStagedFiles(upload, opts) {
|
|
|
4659
4673
|
}
|
|
4660
4674
|
setItems((list) => list.filter((f) => f.id !== att.id));
|
|
4661
4675
|
}, []);
|
|
4662
|
-
const retry =
|
|
4676
|
+
const retry = React28.useCallback((att) => {
|
|
4663
4677
|
run(att);
|
|
4664
4678
|
}, [run]);
|
|
4665
|
-
const clear =
|
|
4679
|
+
const clear = React28.useCallback(() => {
|
|
4666
4680
|
Object.values(controllers.current).forEach((ac) => {
|
|
4667
4681
|
try {
|
|
4668
4682
|
ac && ac.abort();
|
|
@@ -4786,7 +4800,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
|
|
|
4786
4800
|
}
|
|
4787
4801
|
|
|
4788
4802
|
// src/components/forms/MarkdownEditor.tsx
|
|
4789
|
-
var
|
|
4803
|
+
var React29 = __toESM(require("react"), 1);
|
|
4790
4804
|
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
4791
4805
|
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
|
|
4792
4806
|
var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
|
|
@@ -5000,7 +5014,7 @@ function syncDom(root, value) {
|
|
|
5000
5014
|
while (root.children.length > lines.length) root.removeChild(root.lastChild);
|
|
5001
5015
|
}
|
|
5002
5016
|
var LIST_CONT = RE_LI;
|
|
5003
|
-
var MarkdownEditor =
|
|
5017
|
+
var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
|
|
5004
5018
|
value = "",
|
|
5005
5019
|
onChange,
|
|
5006
5020
|
onSubmit,
|
|
@@ -5019,10 +5033,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
|
|
|
5019
5033
|
className = "",
|
|
5020
5034
|
id
|
|
5021
5035
|
}, ref) {
|
|
5022
|
-
const boxRef =
|
|
5023
|
-
const composing =
|
|
5024
|
-
const pendingCaret =
|
|
5025
|
-
|
|
5036
|
+
const boxRef = React29.useRef(null);
|
|
5037
|
+
const composing = React29.useRef(false);
|
|
5038
|
+
const pendingCaret = React29.useRef(null);
|
|
5039
|
+
React29.useLayoutEffect(() => {
|
|
5026
5040
|
const root = boxRef.current;
|
|
5027
5041
|
if (!root || composing.current) return;
|
|
5028
5042
|
const active = document.activeElement === root || root.contains(document.activeElement);
|
|
@@ -5031,7 +5045,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
|
|
|
5031
5045
|
pendingCaret.current = null;
|
|
5032
5046
|
if (active && caret != null) placeCaret(root, caret);
|
|
5033
5047
|
}, [value]);
|
|
5034
|
-
|
|
5048
|
+
React29.useEffect(() => {
|
|
5035
5049
|
if (autoFocus && boxRef.current) boxRef.current.focus();
|
|
5036
5050
|
}, [autoFocus]);
|
|
5037
5051
|
const caretNow = () => {
|
|
@@ -5098,7 +5112,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
|
|
|
5098
5112
|
api.replaceRange(from, to, next, from + next.length);
|
|
5099
5113
|
}
|
|
5100
5114
|
};
|
|
5101
|
-
|
|
5115
|
+
React29.useImperativeHandle(ref, () => api);
|
|
5102
5116
|
function detect(text, caret) {
|
|
5103
5117
|
if (!onTrigger) return;
|
|
5104
5118
|
const upto = text.slice(0, caret);
|
|
@@ -5250,10 +5264,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
|
|
|
5250
5264
|
});
|
|
5251
5265
|
|
|
5252
5266
|
// src/components/platform/AccountMenu.tsx
|
|
5253
|
-
var
|
|
5267
|
+
var React31 = __toESM(require("react"), 1);
|
|
5254
5268
|
|
|
5255
5269
|
// src/kits/session.ts
|
|
5256
|
-
var
|
|
5270
|
+
var React30 = __toESM(require("react"), 1);
|
|
5257
5271
|
var PERMISSION_CATALOG = [
|
|
5258
5272
|
{ group: "Plans", items: [
|
|
5259
5273
|
{ key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
|
|
@@ -6820,8 +6834,8 @@ function roadmap(overrides) {
|
|
|
6820
6834
|
};
|
|
6821
6835
|
}
|
|
6822
6836
|
function useSession() {
|
|
6823
|
-
const [s, setS] =
|
|
6824
|
-
|
|
6837
|
+
const [s, setS] = React30.useState(getSession);
|
|
6838
|
+
React30.useEffect(() => subscribe(setS), []);
|
|
6825
6839
|
return s;
|
|
6826
6840
|
}
|
|
6827
6841
|
var SessionKit = {
|
|
@@ -6891,9 +6905,9 @@ function AccountMenu({
|
|
|
6891
6905
|
...rest
|
|
6892
6906
|
}) {
|
|
6893
6907
|
const session = SessionKit.useSession();
|
|
6894
|
-
const [open, setOpen] =
|
|
6895
|
-
const [switching, setSwitching] =
|
|
6896
|
-
const ref =
|
|
6908
|
+
const [open, setOpen] = React31.useState(false);
|
|
6909
|
+
const [switching, setSwitching] = React31.useState(false);
|
|
6910
|
+
const ref = React31.useRef(null);
|
|
6897
6911
|
const user = session.user;
|
|
6898
6912
|
const visibleAdmin = adminLinks.filter((l) => !l.perm || SessionKit.can(l.perm));
|
|
6899
6913
|
const pick = (item) => {
|
|
@@ -6977,14 +6991,14 @@ function AccountMenu({
|
|
|
6977
6991
|
}
|
|
6978
6992
|
|
|
6979
6993
|
// src/components/platform/ApiSpecBrowser.tsx
|
|
6980
|
-
var
|
|
6994
|
+
var React32 = __toESM(require("react"), 1);
|
|
6981
6995
|
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
6982
6996
|
var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
|
|
6983
6997
|
function Json({ obj }) {
|
|
6984
6998
|
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
|
|
6985
6999
|
}
|
|
6986
7000
|
function Endpoint({ s, onRequest }) {
|
|
6987
|
-
const [tried, setTried] =
|
|
7001
|
+
const [tried, setTried] = React32.useState(null);
|
|
6988
7002
|
const run = async () => {
|
|
6989
7003
|
setTried("busy");
|
|
6990
7004
|
const t0 = (window.performance || Date).now();
|
|
@@ -7057,10 +7071,10 @@ function ApiSpecBrowser({
|
|
|
7057
7071
|
className = "",
|
|
7058
7072
|
...rest
|
|
7059
7073
|
}) {
|
|
7060
|
-
const [q, setQ] =
|
|
7061
|
-
const [method, setMethod] =
|
|
7062
|
-
const [mod, setMod] =
|
|
7063
|
-
const [listOnly, setListOnly] =
|
|
7074
|
+
const [q, setQ] = React32.useState("");
|
|
7075
|
+
const [method, setMethod] = React32.useState(null);
|
|
7076
|
+
const [mod, setMod] = React32.useState(null);
|
|
7077
|
+
const [listOnly, setListOnly] = React32.useState(false);
|
|
7064
7078
|
const activeModule = modules && modules.find((m) => m.id === mod);
|
|
7065
7079
|
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())));
|
|
7066
7080
|
const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
|
|
@@ -7139,7 +7153,7 @@ function ApiSpecBrowser({
|
|
|
7139
7153
|
}
|
|
7140
7154
|
|
|
7141
7155
|
// src/components/platform/ProfilePage.tsx
|
|
7142
|
-
var
|
|
7156
|
+
var React33 = __toESM(require("react"), 1);
|
|
7143
7157
|
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
7144
7158
|
var TIMEZONES = ["America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles", "America/Anchorage", "Pacific/Honolulu", "Europe/London", "Europe/Berlin"];
|
|
7145
7159
|
var NOTIFY = [
|
|
@@ -7152,7 +7166,7 @@ var NOTIFY = [
|
|
|
7152
7166
|
function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSessions = true, className = "", ...rest }) {
|
|
7153
7167
|
const session = SessionKit.useSession();
|
|
7154
7168
|
const user = userProp || session.user;
|
|
7155
|
-
const [draft, setDraft] =
|
|
7169
|
+
const [draft, setDraft] = React33.useState(() => ({
|
|
7156
7170
|
name: user.name || "",
|
|
7157
7171
|
title: user.title || "",
|
|
7158
7172
|
email: user.email || "",
|
|
@@ -7161,8 +7175,8 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7161
7175
|
bio: user.bio || "",
|
|
7162
7176
|
notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true }
|
|
7163
7177
|
}));
|
|
7164
|
-
const [saving, setSaving] =
|
|
7165
|
-
const [saved, setSaved] =
|
|
7178
|
+
const [saving, setSaving] = React33.useState(false);
|
|
7179
|
+
const [saved, setSaved] = React33.useState(false);
|
|
7166
7180
|
const set = (k, v) => {
|
|
7167
7181
|
setDraft((d) => Object.assign({}, d, { [k]: v }));
|
|
7168
7182
|
setSaved(false);
|
|
@@ -7352,10 +7366,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7352
7366
|
}
|
|
7353
7367
|
|
|
7354
7368
|
// src/components/platform/RoadmapTimeline.tsx
|
|
7355
|
-
var
|
|
7369
|
+
var React35 = __toESM(require("react"), 1);
|
|
7356
7370
|
|
|
7357
7371
|
// src/kits/runtime.ts
|
|
7358
|
-
var
|
|
7372
|
+
var React34 = __toESM(require("react"), 1);
|
|
7359
7373
|
var WIRED_ENDPOINTS = [
|
|
7360
7374
|
// Nothing yet. Every id below would come from a real service:
|
|
7361
7375
|
// "plan.get", "placements.list", …
|
|
@@ -7526,8 +7540,8 @@ var RuntimeKit = {
|
|
|
7526
7540
|
};
|
|
7527
7541
|
RuntimeKit.declare(FEATURE_NEEDS);
|
|
7528
7542
|
function useRuntimeMode() {
|
|
7529
|
-
const [m, setM] =
|
|
7530
|
-
|
|
7543
|
+
const [m, setM] = React34.useState(RuntimeKit.getMode());
|
|
7544
|
+
React34.useEffect(() => RuntimeKit.subscribe(setM), []);
|
|
7531
7545
|
return m;
|
|
7532
7546
|
}
|
|
7533
7547
|
function useFeatureStatus(key) {
|
|
@@ -7610,12 +7624,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
7610
7624
|
}
|
|
7611
7625
|
function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
7612
7626
|
const session = SessionKit.useSession();
|
|
7613
|
-
const [project, setProject] =
|
|
7614
|
-
const [q, setQ] =
|
|
7615
|
-
const scrollRef =
|
|
7616
|
-
const nowRef =
|
|
7617
|
-
const rm =
|
|
7618
|
-
const byKey =
|
|
7627
|
+
const [project, setProject] = React35.useState("");
|
|
7628
|
+
const [q, setQ] = React35.useState("");
|
|
7629
|
+
const scrollRef = React35.useRef(null);
|
|
7630
|
+
const nowRef = React35.useRef(null);
|
|
7631
|
+
const rm = React35.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
|
|
7632
|
+
const byKey = React35.useMemo(() => {
|
|
7619
7633
|
const m = {};
|
|
7620
7634
|
rm.items.forEach((i) => {
|
|
7621
7635
|
m[i.key] = i;
|
|
@@ -7624,7 +7638,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
7624
7638
|
}, [rm]);
|
|
7625
7639
|
const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
|
|
7626
7640
|
const projects = [...new Set(rm.items.map((i) => i.project))];
|
|
7627
|
-
|
|
7641
|
+
React35.useEffect(() => {
|
|
7628
7642
|
let raf1 = 0, raf2 = 0;
|
|
7629
7643
|
const place = () => {
|
|
7630
7644
|
const box = scrollRef.current, mark = nowRef.current;
|
|
@@ -7698,7 +7712,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
7698
7712
|
lastPhase = item.phase;
|
|
7699
7713
|
const inPhase = items.filter((i) => i.phase === item.phase).length;
|
|
7700
7714
|
const isBoundary = n === firstPending;
|
|
7701
|
-
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
7715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(React35.Fragment, { children: [
|
|
7702
7716
|
showPhase ? /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "fd-rm-era", children: [
|
|
7703
7717
|
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
|
|
7704
7718
|
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
|
|
@@ -7742,9 +7756,10 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
7742
7756
|
}
|
|
7743
7757
|
|
|
7744
7758
|
// src/components/platform/ComingSoon.tsx
|
|
7745
|
-
var
|
|
7759
|
+
var React36 = __toESM(require("react"), 1);
|
|
7746
7760
|
var import_react_dom5 = require("react-dom");
|
|
7747
7761
|
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
7762
|
+
var SOON_HOVERCARD_BASE = 220;
|
|
7748
7763
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
7749
7764
|
function readBypassed() {
|
|
7750
7765
|
try {
|
|
@@ -7760,8 +7775,8 @@ function writeBypassed(list) {
|
|
|
7760
7775
|
}
|
|
7761
7776
|
}
|
|
7762
7777
|
function useBypass(key) {
|
|
7763
|
-
const [on, setOn] =
|
|
7764
|
-
|
|
7778
|
+
const [on, setOn] = React36.useState(() => !!key && readBypassed().indexOf(key) >= 0);
|
|
7779
|
+
React36.useEffect(() => {
|
|
7765
7780
|
setOn(!!key && readBypassed().indexOf(key) >= 0);
|
|
7766
7781
|
}, [key]);
|
|
7767
7782
|
const set = (next) => {
|
|
@@ -7808,9 +7823,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
|
|
|
7808
7823
|
] });
|
|
7809
7824
|
}
|
|
7810
7825
|
function useHoverCard(open) {
|
|
7811
|
-
const anchor =
|
|
7812
|
-
const [pos, setPos] =
|
|
7813
|
-
|
|
7826
|
+
const anchor = React36.useRef(null);
|
|
7827
|
+
const [pos, setPos] = React36.useState(null);
|
|
7828
|
+
React36.useLayoutEffect(() => {
|
|
7814
7829
|
if (!open || !anchor.current) {
|
|
7815
7830
|
setPos(null);
|
|
7816
7831
|
return;
|
|
@@ -7937,9 +7952,10 @@ function ComingSoon({
|
|
|
7937
7952
|
] });
|
|
7938
7953
|
}
|
|
7939
7954
|
function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
|
|
7940
|
-
const [open, setOpen] =
|
|
7955
|
+
const [open, setOpen] = React36.useState(false);
|
|
7941
7956
|
const [anchor, pos] = useHoverCard(open);
|
|
7942
|
-
const
|
|
7957
|
+
const zIndex = useOverlayLayer(SOON_HOVERCARD_BASE);
|
|
7958
|
+
const close = React36.useRef(null);
|
|
7943
7959
|
const show = () => {
|
|
7944
7960
|
if (close.current) {
|
|
7945
7961
|
clearTimeout(close.current);
|
|
@@ -7955,7 +7971,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
7955
7971
|
setOpen(false);
|
|
7956
7972
|
}, 140);
|
|
7957
7973
|
};
|
|
7958
|
-
|
|
7974
|
+
React36.useEffect(() => () => {
|
|
7959
7975
|
if (close.current) clearTimeout(close.current);
|
|
7960
7976
|
}, []);
|
|
7961
7977
|
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
|
|
@@ -7985,12 +8001,12 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
7985
8001
|
}
|
|
7986
8002
|
),
|
|
7987
8003
|
open && pos ? (0, import_react_dom5.createPortal)(
|
|
7988
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
8004
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(LayerProvider, { zIndex, children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
7989
8005
|
"div",
|
|
7990
8006
|
{
|
|
7991
8007
|
className: "fd-soon-note fd-soon-hovercard",
|
|
7992
8008
|
role: "tooltip",
|
|
7993
|
-
style: { position: "fixed", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width },
|
|
8009
|
+
style: { position: "fixed", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width, zIndex },
|
|
7994
8010
|
onMouseEnter: show,
|
|
7995
8011
|
onMouseLeave: hide,
|
|
7996
8012
|
children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
@@ -8007,7 +8023,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
8007
8023
|
}
|
|
8008
8024
|
)
|
|
8009
8025
|
}
|
|
8010
|
-
),
|
|
8026
|
+
) }),
|
|
8011
8027
|
document.body
|
|
8012
8028
|
) : null
|
|
8013
8029
|
]
|
|
@@ -8124,13 +8140,15 @@ function PermissionHint({ perm, children }) {
|
|
|
8124
8140
|
}
|
|
8125
8141
|
|
|
8126
8142
|
// src/components/platform/ModeSwitch.tsx
|
|
8127
|
-
var
|
|
8143
|
+
var React37 = __toESM(require("react"), 1);
|
|
8128
8144
|
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
8145
|
+
var MODE_SWITCH_BASE = 140;
|
|
8129
8146
|
function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
|
|
8130
8147
|
const mode2 = useRuntimeMode();
|
|
8131
|
-
const [open, setOpen] =
|
|
8132
|
-
const
|
|
8133
|
-
|
|
8148
|
+
const [open, setOpen] = React37.useState(false);
|
|
8149
|
+
const zIndex = useOverlayLayer(MODE_SWITCH_BASE);
|
|
8150
|
+
const ref = React37.useRef(null);
|
|
8151
|
+
React37.useEffect(() => {
|
|
8134
8152
|
if (!open) return;
|
|
8135
8153
|
const away = (e) => {
|
|
8136
8154
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -8168,7 +8186,7 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
8168
8186
|
]
|
|
8169
8187
|
}
|
|
8170
8188
|
),
|
|
8171
|
-
open ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "fd-view-enter fd-mode-pop", children: [
|
|
8189
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(LayerProvider, { zIndex, children: /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
|
|
8172
8190
|
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
|
|
8173
8191
|
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
|
|
8174
8192
|
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
|
|
@@ -8226,7 +8244,7 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
8226
8244
|
] })
|
|
8227
8245
|
] }),
|
|
8228
8246
|
test && renderLog ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { style: { display: "block", maxHeight: 340, overflowY: "auto", borderTop: "1px solid var(--border)" }, children: renderLog() }) : null
|
|
8229
|
-
] }) : null
|
|
8247
|
+
] }) }) : null
|
|
8230
8248
|
] });
|
|
8231
8249
|
}
|
|
8232
8250
|
function TestModeBar({ onExit }) {
|
|
@@ -8379,7 +8397,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
8379
8397
|
}
|
|
8380
8398
|
|
|
8381
8399
|
// src/components/planner/MixGap.tsx
|
|
8382
|
-
var
|
|
8400
|
+
var React38 = __toESM(require("react"), 1);
|
|
8383
8401
|
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
8384
8402
|
var MIX_GAP_LAYOUT = {
|
|
8385
8403
|
trackHeight: 30,
|
|
@@ -8394,7 +8412,7 @@ function mixGapOffset(value, max) {
|
|
|
8394
8412
|
}
|
|
8395
8413
|
function MixGap({ rows = [], loading = false, className = "" }) {
|
|
8396
8414
|
const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
|
|
8397
|
-
const [hover, setHover] =
|
|
8415
|
+
const [hover, setHover] = React38.useState(null);
|
|
8398
8416
|
const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
|
|
8399
8417
|
const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
|
|
8400
8418
|
const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
|
|
@@ -8537,7 +8555,7 @@ function ChannelContribution({
|
|
|
8537
8555
|
}
|
|
8538
8556
|
|
|
8539
8557
|
// src/components/planner/BudgetReallocator.tsx
|
|
8540
|
-
var
|
|
8558
|
+
var React39 = __toESM(require("react"), 1);
|
|
8541
8559
|
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
8542
8560
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
8543
8561
|
function BudgetReallocator({
|
|
@@ -8553,8 +8571,8 @@ function BudgetReallocator({
|
|
|
8553
8571
|
onCancel,
|
|
8554
8572
|
className = ""
|
|
8555
8573
|
}) {
|
|
8556
|
-
const [draft, setDraft] =
|
|
8557
|
-
|
|
8574
|
+
const [draft, setDraft] = React39.useState(spend);
|
|
8575
|
+
React39.useEffect(() => setDraft(spend), [spend]);
|
|
8558
8576
|
const dirty = draft !== spend;
|
|
8559
8577
|
const nextCrp = scoreFor ? scoreFor(draft) : crp;
|
|
8560
8578
|
const nextBand = bandFor(nextCrp);
|
|
@@ -8724,7 +8742,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "" })
|
|
|
8724
8742
|
}
|
|
8725
8743
|
|
|
8726
8744
|
// src/components/planner/PreferenceMeter.tsx
|
|
8727
|
-
var
|
|
8745
|
+
var React40 = __toESM(require("react"), 1);
|
|
8728
8746
|
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
8729
8747
|
function preferenceScore(criteria) {
|
|
8730
8748
|
const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
|
|
@@ -8754,7 +8772,7 @@ function PreferenceMeter({
|
|
|
8754
8772
|
className = ""
|
|
8755
8773
|
}) {
|
|
8756
8774
|
const value = score == null ? preferenceScore(criteria) : score;
|
|
8757
|
-
const segments =
|
|
8775
|
+
const segments = React40.useMemo(() => preferenceSegments(criteria), [criteria]);
|
|
8758
8776
|
return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
8759
8777
|
ScoreMeter,
|
|
8760
8778
|
{
|
|
@@ -8793,10 +8811,10 @@ function PreferenceMeter({
|
|
|
8793
8811
|
}
|
|
8794
8812
|
|
|
8795
8813
|
// src/components/chat/AgentChatPanel.tsx
|
|
8796
|
-
var
|
|
8814
|
+
var React46 = __toESM(require("react"), 1);
|
|
8797
8815
|
|
|
8798
8816
|
// src/components/chat/chatEngine.ts
|
|
8799
|
-
var
|
|
8817
|
+
var React41 = __toESM(require("react"), 1);
|
|
8800
8818
|
var CHAT_UNAVAILABLE = "chat_unavailable";
|
|
8801
8819
|
var JOB_PENDING = ["queued", "running"];
|
|
8802
8820
|
var JOB_SUCCESS = ["completed", "recovered"];
|
|
@@ -8850,22 +8868,22 @@ function useChatEngine(opts) {
|
|
|
8850
8868
|
onClear,
|
|
8851
8869
|
onFeedback
|
|
8852
8870
|
} = opts || {};
|
|
8853
|
-
const [status, setStatus] =
|
|
8854
|
-
const [threadId, setThreadId] =
|
|
8855
|
-
const [messages, setMessages] =
|
|
8856
|
-
const [queue, setQueue] =
|
|
8857
|
-
const [fatal, setFatal] =
|
|
8858
|
-
const [busy, setBusy] =
|
|
8859
|
-
const [turnStartedAt, setTurnStartedAt] =
|
|
8860
|
-
const listRef =
|
|
8861
|
-
const queueRef =
|
|
8862
|
-
const busyRef =
|
|
8863
|
-
const stoppedRef =
|
|
8864
|
-
const abortRef =
|
|
8865
|
-
const serverCount =
|
|
8866
|
-
const threadRef =
|
|
8867
|
-
const mounted =
|
|
8868
|
-
|
|
8871
|
+
const [status, setStatus] = React41.useState("idle");
|
|
8872
|
+
const [threadId, setThreadId] = React41.useState(null);
|
|
8873
|
+
const [messages, setMessages] = React41.useState([]);
|
|
8874
|
+
const [queue, setQueue] = React41.useState([]);
|
|
8875
|
+
const [fatal, setFatal] = React41.useState(null);
|
|
8876
|
+
const [busy, setBusy] = React41.useState(false);
|
|
8877
|
+
const [turnStartedAt, setTurnStartedAt] = React41.useState(null);
|
|
8878
|
+
const listRef = React41.useRef([]);
|
|
8879
|
+
const queueRef = React41.useRef([]);
|
|
8880
|
+
const busyRef = React41.useRef(false);
|
|
8881
|
+
const stoppedRef = React41.useRef(false);
|
|
8882
|
+
const abortRef = React41.useRef(null);
|
|
8883
|
+
const serverCount = React41.useRef(0);
|
|
8884
|
+
const threadRef = React41.useRef(null);
|
|
8885
|
+
const mounted = React41.useRef(true);
|
|
8886
|
+
React41.useEffect(() => {
|
|
8869
8887
|
mounted.current = true;
|
|
8870
8888
|
return () => {
|
|
8871
8889
|
mounted.current = false;
|
|
@@ -8887,14 +8905,14 @@ function useChatEngine(opts) {
|
|
|
8887
8905
|
}
|
|
8888
8906
|
return false;
|
|
8889
8907
|
};
|
|
8890
|
-
const loadThread =
|
|
8908
|
+
const loadThread = React41.useCallback(async (id) => {
|
|
8891
8909
|
const data = await apiAdapter.getThread(id);
|
|
8892
8910
|
const list = [...data && data.messages || []];
|
|
8893
8911
|
serverCount.current = list.length;
|
|
8894
8912
|
commit(list);
|
|
8895
8913
|
return list;
|
|
8896
8914
|
}, [apiAdapter]);
|
|
8897
|
-
|
|
8915
|
+
React41.useEffect(() => {
|
|
8898
8916
|
if (!apiAdapter) {
|
|
8899
8917
|
setStatus("idle");
|
|
8900
8918
|
setFatal(null);
|
|
@@ -9107,7 +9125,7 @@ function useChatEngine(opts) {
|
|
|
9107
9125
|
await dispatchTurn(turn);
|
|
9108
9126
|
}
|
|
9109
9127
|
}
|
|
9110
|
-
const send =
|
|
9128
|
+
const send = React41.useCallback((text, attachments) => {
|
|
9111
9129
|
const body = (text || "").trim();
|
|
9112
9130
|
if (!body && !(attachments && attachments.length)) return;
|
|
9113
9131
|
if (status === "disconnected") return;
|
|
@@ -9117,7 +9135,7 @@ function useChatEngine(opts) {
|
|
|
9117
9135
|
stoppedRef.current = false;
|
|
9118
9136
|
drain();
|
|
9119
9137
|
}, [status]);
|
|
9120
|
-
const stop =
|
|
9138
|
+
const stop = React41.useCallback(() => {
|
|
9121
9139
|
stoppedRef.current = true;
|
|
9122
9140
|
const ac = abortRef.current;
|
|
9123
9141
|
if (ac) {
|
|
@@ -9136,11 +9154,11 @@ function useChatEngine(opts) {
|
|
|
9136
9154
|
store.del(STORAGE_PREFIX + threadRef.current);
|
|
9137
9155
|
}
|
|
9138
9156
|
}, [apiAdapter]);
|
|
9139
|
-
const removeQueued =
|
|
9157
|
+
const removeQueued = React41.useCallback((id) => {
|
|
9140
9158
|
queueRef.current = queueRef.current.filter((t) => t.id !== id);
|
|
9141
9159
|
setQueue(queueRef.current.slice());
|
|
9142
9160
|
}, []);
|
|
9143
|
-
const retry =
|
|
9161
|
+
const retry = React41.useCallback(() => {
|
|
9144
9162
|
const list = listRef.current;
|
|
9145
9163
|
let at = -1;
|
|
9146
9164
|
for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
|
|
@@ -9156,19 +9174,19 @@ function useChatEngine(opts) {
|
|
|
9156
9174
|
setQueue(queueRef.current.slice());
|
|
9157
9175
|
drain();
|
|
9158
9176
|
}, []);
|
|
9159
|
-
const clear =
|
|
9177
|
+
const clear = React41.useCallback(() => {
|
|
9160
9178
|
commit([]);
|
|
9161
9179
|
serverCount.current = 0;
|
|
9162
9180
|
queueRef.current = [];
|
|
9163
9181
|
setQueue([]);
|
|
9164
9182
|
onClear && onClear();
|
|
9165
9183
|
}, [onClear]);
|
|
9166
|
-
const setFeedback =
|
|
9184
|
+
const setFeedback = React41.useCallback((id, value) => {
|
|
9167
9185
|
patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
|
|
9168
9186
|
const msg = listRef.current.find((m) => m.id === id);
|
|
9169
9187
|
onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
|
|
9170
9188
|
}, [onFeedback]);
|
|
9171
|
-
const reload =
|
|
9189
|
+
const reload = React41.useCallback(async () => {
|
|
9172
9190
|
if (!threadRef.current) return;
|
|
9173
9191
|
setStatus("loading");
|
|
9174
9192
|
try {
|
|
@@ -9206,10 +9224,10 @@ var ChatKit = {
|
|
|
9206
9224
|
};
|
|
9207
9225
|
|
|
9208
9226
|
// src/components/chat/ChatTranscript.tsx
|
|
9209
|
-
var
|
|
9227
|
+
var React43 = __toESM(require("react"), 1);
|
|
9210
9228
|
|
|
9211
9229
|
// src/components/chat/ChatTurn.tsx
|
|
9212
|
-
var
|
|
9230
|
+
var React42 = __toESM(require("react"), 1);
|
|
9213
9231
|
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
9214
9232
|
function JsonView({ value }) {
|
|
9215
9233
|
let text;
|
|
@@ -9246,7 +9264,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
|
9246
9264
|
] });
|
|
9247
9265
|
}
|
|
9248
9266
|
function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
9249
|
-
const [open, setOpen] =
|
|
9267
|
+
const [open, setOpen] = React42.useState(defaultOpen);
|
|
9250
9268
|
if (!text) return null;
|
|
9251
9269
|
return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
|
|
9252
9270
|
/* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
@@ -9263,7 +9281,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
|
9263
9281
|
] });
|
|
9264
9282
|
}
|
|
9265
9283
|
function Citations({ items = [], onOpen }) {
|
|
9266
|
-
const [open, setOpen] =
|
|
9284
|
+
const [open, setOpen] = React42.useState(false);
|
|
9267
9285
|
if (!items.length) return null;
|
|
9268
9286
|
return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "fdc-cites", children: [
|
|
9269
9287
|
/* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
@@ -9289,7 +9307,7 @@ function clampText(text, max) {
|
|
|
9289
9307
|
return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
9290
9308
|
}
|
|
9291
9309
|
function MessageBody({ message: m, ctx }) {
|
|
9292
|
-
const [expanded, setExpanded] =
|
|
9310
|
+
const [expanded, setExpanded] = React42.useState(false);
|
|
9293
9311
|
const isUser = m.role === "user";
|
|
9294
9312
|
const raw = m.text || "";
|
|
9295
9313
|
const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
|
|
@@ -9356,9 +9374,9 @@ function MessageBody({ message: m, ctx }) {
|
|
|
9356
9374
|
] });
|
|
9357
9375
|
}
|
|
9358
9376
|
function useCopyRun() {
|
|
9359
|
-
const [done, setDone] =
|
|
9360
|
-
const t =
|
|
9361
|
-
|
|
9377
|
+
const [done, setDone] = React42.useState(false);
|
|
9378
|
+
const t = React42.useRef(null);
|
|
9379
|
+
React42.useEffect(() => () => {
|
|
9362
9380
|
if (t.current) clearTimeout(t.current);
|
|
9363
9381
|
}, []);
|
|
9364
9382
|
return [done, (text) => {
|
|
@@ -9385,7 +9403,7 @@ function RunActions({ group, ctx }) {
|
|
|
9385
9403
|
] }),
|
|
9386
9404
|
isAssistant && ctx.onRetry ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
|
|
9387
9405
|
group.role === "user" && ctx.onEdit ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
|
|
9388
|
-
isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
|
|
9406
|
+
isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(React42.Fragment, { children: [
|
|
9389
9407
|
/* @__PURE__ */ (0, import_jsx_runtime73.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_runtime73.jsx)("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
|
|
9390
9408
|
/* @__PURE__ */ (0, import_jsx_runtime73.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_runtime73.jsx)("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
|
|
9391
9409
|
] }) : null,
|
|
@@ -9480,10 +9498,10 @@ function ChatTranscript({
|
|
|
9480
9498
|
renderEmpty,
|
|
9481
9499
|
className = ""
|
|
9482
9500
|
}) {
|
|
9483
|
-
const scroller =
|
|
9484
|
-
const stick =
|
|
9485
|
-
const [pill, setPill] =
|
|
9486
|
-
const seen =
|
|
9501
|
+
const scroller = React43.useRef(null);
|
|
9502
|
+
const stick = React43.useRef(true);
|
|
9503
|
+
const [pill, setPill] = React43.useState(0);
|
|
9504
|
+
const seen = React43.useRef(0);
|
|
9487
9505
|
const toBottom = (smooth) => {
|
|
9488
9506
|
const el = scroller.current;
|
|
9489
9507
|
if (!el) return;
|
|
@@ -9502,7 +9520,7 @@ function ChatTranscript({
|
|
|
9502
9520
|
seen.current = messages.length;
|
|
9503
9521
|
}
|
|
9504
9522
|
};
|
|
9505
|
-
|
|
9523
|
+
React43.useLayoutEffect(() => {
|
|
9506
9524
|
const el = scroller.current;
|
|
9507
9525
|
if (!el) return;
|
|
9508
9526
|
if (stick.current) {
|
|
@@ -9510,7 +9528,7 @@ function ChatTranscript({
|
|
|
9510
9528
|
seen.current = messages.length;
|
|
9511
9529
|
} else setPill(Math.max(0, messages.length - seen.current));
|
|
9512
9530
|
}, [messages]);
|
|
9513
|
-
|
|
9531
|
+
React43.useEffect(() => {
|
|
9514
9532
|
const el = scroller.current;
|
|
9515
9533
|
const inner = el && el.firstChild;
|
|
9516
9534
|
if (!el || !inner || typeof ResizeObserver === "undefined") return;
|
|
@@ -9520,7 +9538,7 @@ function ChatTranscript({
|
|
|
9520
9538
|
ro.observe(inner);
|
|
9521
9539
|
return () => ro.disconnect();
|
|
9522
9540
|
}, []);
|
|
9523
|
-
const groups =
|
|
9541
|
+
const groups = React43.useMemo(() => groupMessages(messages), [messages]);
|
|
9524
9542
|
const empty = !messages.length && status === "ready";
|
|
9525
9543
|
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
|
|
9526
9544
|
/* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
|
|
@@ -9544,7 +9562,7 @@ function ChatTranscript({
|
|
|
9544
9562
|
const prev = groups[i - 1];
|
|
9545
9563
|
const k = dayKey(g.messages[0].timestamp);
|
|
9546
9564
|
const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
|
|
9547
|
-
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
|
|
9565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(React43.Fragment, { children: [
|
|
9548
9566
|
showDay ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "fdc-day", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { children: dayLabel(k) }) }) : null,
|
|
9549
9567
|
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ChatTurn, { group: g, ctx })
|
|
9550
9568
|
] }, g.key || i);
|
|
@@ -9561,7 +9579,7 @@ function ChatTranscript({
|
|
|
9561
9579
|
var TranscriptKit = { groupMessages };
|
|
9562
9580
|
|
|
9563
9581
|
// src/components/chat/ChatComposer.tsx
|
|
9564
|
-
var
|
|
9582
|
+
var React44 = __toESM(require("react"), 1);
|
|
9565
9583
|
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
9566
9584
|
function ChatComposer({
|
|
9567
9585
|
onSubmit,
|
|
@@ -9589,17 +9607,17 @@ function ChatComposer({
|
|
|
9589
9607
|
onReject,
|
|
9590
9608
|
onOpenAttachment
|
|
9591
9609
|
}) {
|
|
9592
|
-
const [text, setText] =
|
|
9593
|
-
const [trigger, setTrigger] =
|
|
9594
|
-
const [mentionItems, setMentionItems] =
|
|
9595
|
-
const [listening, setListening] =
|
|
9596
|
-
const [notice, setNotice] =
|
|
9597
|
-
const editor =
|
|
9598
|
-
const wrap =
|
|
9599
|
-
const stopVoice =
|
|
9610
|
+
const [text, setText] = React44.useState(draft || "");
|
|
9611
|
+
const [trigger, setTrigger] = React44.useState(null);
|
|
9612
|
+
const [mentionItems, setMentionItems] = React44.useState([]);
|
|
9613
|
+
const [listening, setListening] = React44.useState(false);
|
|
9614
|
+
const [notice, setNotice] = React44.useState(null);
|
|
9615
|
+
const editor = React44.useRef(null);
|
|
9616
|
+
const wrap = React44.useRef(null);
|
|
9617
|
+
const stopVoice = React44.useRef(null);
|
|
9600
9618
|
const staged = useStagedFiles(fileUploadHandler, { onError: () => {
|
|
9601
9619
|
} });
|
|
9602
|
-
|
|
9620
|
+
React44.useEffect(() => {
|
|
9603
9621
|
if (draft != null && draft !== text) setText(draft);
|
|
9604
9622
|
}, [draft]);
|
|
9605
9623
|
const change = (v) => {
|
|
@@ -9633,7 +9651,7 @@ function ChatComposer({
|
|
|
9633
9651
|
e.preventDefault();
|
|
9634
9652
|
staged.add(found.files);
|
|
9635
9653
|
};
|
|
9636
|
-
|
|
9654
|
+
React44.useEffect(() => {
|
|
9637
9655
|
if (!trigger || trigger.type !== "mention" || !mentionSources) {
|
|
9638
9656
|
setMentionItems([]);
|
|
9639
9657
|
return;
|
|
@@ -9651,7 +9669,7 @@ function ChatComposer({
|
|
|
9651
9669
|
const q = (trigger.query || "").toLowerCase();
|
|
9652
9670
|
setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
|
|
9653
9671
|
}, [trigger, mentionSources]);
|
|
9654
|
-
const slashItems =
|
|
9672
|
+
const slashItems = React44.useMemo(() => {
|
|
9655
9673
|
if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
|
|
9656
9674
|
const q = (trigger.query || "").toLowerCase();
|
|
9657
9675
|
return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
|
|
@@ -9825,12 +9843,12 @@ function ChatComposer({
|
|
|
9825
9843
|
}
|
|
9826
9844
|
|
|
9827
9845
|
// src/components/chat/ChatSessionBar.tsx
|
|
9828
|
-
var
|
|
9846
|
+
var React45 = __toESM(require("react"), 1);
|
|
9829
9847
|
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
9830
9848
|
var compact2 = meterFormats.compact;
|
|
9831
9849
|
function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
|
|
9832
|
-
const [open, setOpen] =
|
|
9833
|
-
const anchor =
|
|
9850
|
+
const [open, setOpen] = React45.useState(false);
|
|
9851
|
+
const anchor = React45.useRef(null);
|
|
9834
9852
|
const stats = sessionStats || null;
|
|
9835
9853
|
const cu = contextUsage || null;
|
|
9836
9854
|
const limits = usageLimits || null;
|
|
@@ -9845,7 +9863,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
9845
9863
|
if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
|
|
9846
9864
|
if (cu) bits.push(pct + "% context");
|
|
9847
9865
|
const expandable = !!(cu || limits);
|
|
9848
|
-
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
9866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(React45.Fragment, { children: [
|
|
9849
9867
|
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "fdc-bar", children: [
|
|
9850
9868
|
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
9851
9869
|
"button",
|
|
@@ -9986,7 +10004,7 @@ function ModelControls({
|
|
|
9986
10004
|
] })
|
|
9987
10005
|
});
|
|
9988
10006
|
}
|
|
9989
|
-
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
10007
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(React45.Fragment, { children: [
|
|
9990
10008
|
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
9991
10009
|
MenuButton,
|
|
9992
10010
|
{
|
|
@@ -10103,11 +10121,11 @@ function AgentChatPanel({
|
|
|
10103
10121
|
onFeedback,
|
|
10104
10122
|
onEditMessage
|
|
10105
10123
|
}) {
|
|
10106
|
-
const [panelWidth, setPanelWidth] =
|
|
10107
|
-
const [applied, setApplied] =
|
|
10108
|
-
const [draft, setDraft] =
|
|
10109
|
-
const dragging =
|
|
10110
|
-
|
|
10124
|
+
const [panelWidth, setPanelWidth] = React46.useState(width);
|
|
10125
|
+
const [applied, setApplied] = React46.useState({});
|
|
10126
|
+
const [draft, setDraft] = React46.useState("");
|
|
10127
|
+
const dragging = React46.useRef(null);
|
|
10128
|
+
React46.useEffect(() => setPanelWidth(width), [width]);
|
|
10111
10129
|
const engine = useChatEngine({
|
|
10112
10130
|
contextType,
|
|
10113
10131
|
contextId,
|
|
@@ -10311,7 +10329,7 @@ function AgentChatPanel({
|
|
|
10311
10329
|
}
|
|
10312
10330
|
|
|
10313
10331
|
// src/kits/query.ts
|
|
10314
|
-
var
|
|
10332
|
+
var React47 = __toESM(require("react"), 1);
|
|
10315
10333
|
function eqFilter(get2) {
|
|
10316
10334
|
return (row, value) => Array.isArray(value) ? value.includes(get2(row)) : get2(row) === value;
|
|
10317
10335
|
}
|
|
@@ -10343,22 +10361,22 @@ function compare(a, b, dir) {
|
|
|
10343
10361
|
var API = null;
|
|
10344
10362
|
var PREFS = null;
|
|
10345
10363
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
|
|
10346
|
-
const [query, setQuery] =
|
|
10364
|
+
const [query, setQuery] = React47.useState(() => {
|
|
10347
10365
|
const store = PREFS || window.PlannerPrefs;
|
|
10348
10366
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
10349
10367
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
10350
10368
|
});
|
|
10351
|
-
const savePref =
|
|
10369
|
+
const savePref = React47.useCallback((patch2) => {
|
|
10352
10370
|
const store = PREFS || window.PlannerPrefs;
|
|
10353
10371
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
10354
10372
|
}, [prefsKey]);
|
|
10355
|
-
const [res, setRes] =
|
|
10356
|
-
const [loading, setLoading] =
|
|
10357
|
-
const seq2 =
|
|
10373
|
+
const [res, setRes] = React47.useState(null);
|
|
10374
|
+
const [loading, setLoading] = React47.useState(true);
|
|
10375
|
+
const seq2 = React47.useRef(0);
|
|
10358
10376
|
const depKey = (deps || []).join("|");
|
|
10359
10377
|
const paramKey = JSON.stringify(params || {});
|
|
10360
10378
|
const queryKey = JSON.stringify(query);
|
|
10361
|
-
|
|
10379
|
+
React47.useEffect(() => {
|
|
10362
10380
|
const id = ++seq2.current;
|
|
10363
10381
|
setLoading(true);
|
|
10364
10382
|
const t = setTimeout(() => {
|