@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.js
CHANGED
|
@@ -50,8 +50,13 @@ function Button({
|
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// src/components/actions/overflowRowContext.ts
|
|
54
|
+
import * as React from "react";
|
|
55
|
+
var OverflowRowContext = React.createContext(false);
|
|
56
|
+
var useOverflowRow = () => React.useContext(OverflowRowContext);
|
|
57
|
+
|
|
53
58
|
// src/components/actions/IconButton.tsx
|
|
54
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
59
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
55
60
|
function IconButton({
|
|
56
61
|
icon,
|
|
57
62
|
label,
|
|
@@ -63,21 +68,26 @@ function IconButton({
|
|
|
63
68
|
className = "",
|
|
64
69
|
...rest
|
|
65
70
|
}) {
|
|
71
|
+
const overflowRow = useOverflowRow();
|
|
66
72
|
const cls = [
|
|
67
73
|
"fd-btn-icon",
|
|
68
74
|
variant === "outline" ? "fd-btn-icon-outline" : variant === "solid" ? "fd-btn-icon-solid" : "",
|
|
69
75
|
tone !== "neutral" ? "is-" + tone : "",
|
|
70
76
|
size === "sm" ? "fd-btn-icon-sm" : size === "lg" ? "fd-btn-icon-lg" : "",
|
|
71
77
|
round ? "fd-btn-icon-round" : "",
|
|
78
|
+
overflowRow ? "fd-btn-icon-row" : "",
|
|
72
79
|
className
|
|
73
80
|
].filter(Boolean).join(" ");
|
|
74
|
-
return /* @__PURE__ */
|
|
81
|
+
return /* @__PURE__ */ jsxs2("button", { type: "button", className: cls, "aria-label": label, title: label, disabled, ...rest, children: [
|
|
82
|
+
/* @__PURE__ */ jsx2("i", { className: "ph ph-" + icon, "aria-hidden": "true" }),
|
|
83
|
+
overflowRow ? /* @__PURE__ */ jsx2("span", { className: "fd-btn-icon-row-label", children: label }) : null
|
|
84
|
+
] });
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
// src/components/actions/Popover.tsx
|
|
78
|
-
import * as
|
|
88
|
+
import * as React2 from "react";
|
|
79
89
|
import { createPortal } from "react-dom";
|
|
80
|
-
import { jsx as jsx3, jsxs as
|
|
90
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
81
91
|
var MARGIN = 8;
|
|
82
92
|
var parsePlacement = (p) => {
|
|
83
93
|
const [side, align = "start"] = String(p || "bottom-start").split("-");
|
|
@@ -107,12 +117,12 @@ function measureLayer(el) {
|
|
|
107
117
|
function usePopoverPosition(open, anchorRef, opts) {
|
|
108
118
|
const o = opts || {};
|
|
109
119
|
const { side: wantSide, align } = parsePlacement(o.placement);
|
|
110
|
-
const [pos, setPos] =
|
|
111
|
-
const posRef =
|
|
112
|
-
const detachRef =
|
|
120
|
+
const [pos, setPos] = React2.useState(null);
|
|
121
|
+
const posRef = React2.useRef(null);
|
|
122
|
+
const detachRef = React2.useRef(o.onDetach);
|
|
113
123
|
detachRef.current = o.onDetach;
|
|
114
124
|
const layerRef = o.layerRef;
|
|
115
|
-
|
|
125
|
+
React2.useLayoutEffect(() => {
|
|
116
126
|
if (!open || !anchorRef || !anchorRef.current) {
|
|
117
127
|
posRef.current = null;
|
|
118
128
|
setPos(null);
|
|
@@ -187,8 +197,8 @@ var portal = (node) => {
|
|
|
187
197
|
};
|
|
188
198
|
var ROOT_LAYER = 0;
|
|
189
199
|
var LAYER_STEP = 10;
|
|
190
|
-
var LayerContext =
|
|
191
|
-
var useLayer = () =>
|
|
200
|
+
var LayerContext = React2.createContext(ROOT_LAYER);
|
|
201
|
+
var useLayer = () => React2.useContext(LayerContext);
|
|
192
202
|
var useOverlayLayer = (base) => {
|
|
193
203
|
const parent = useLayer();
|
|
194
204
|
return parent === ROOT_LAYER ? base : parent + LAYER_STEP;
|
|
@@ -218,7 +228,7 @@ function Popover({
|
|
|
218
228
|
footer,
|
|
219
229
|
children
|
|
220
230
|
}) {
|
|
221
|
-
const ref =
|
|
231
|
+
const ref = React2.useRef(null);
|
|
222
232
|
const pos = usePopoverPosition(!!open, anchorRef, {
|
|
223
233
|
placement,
|
|
224
234
|
offset,
|
|
@@ -230,9 +240,9 @@ function Popover({
|
|
|
230
240
|
onDetach: onClose,
|
|
231
241
|
layerRef: ref
|
|
232
242
|
});
|
|
233
|
-
const restore =
|
|
243
|
+
const restore = React2.useRef(null);
|
|
234
244
|
const zIndex = useOverlayLayer(POPOVER_BASE);
|
|
235
|
-
|
|
245
|
+
React2.useEffect(() => {
|
|
236
246
|
if (!open) return;
|
|
237
247
|
restore.current = typeof document !== "undefined" ? document.activeElement : null;
|
|
238
248
|
return () => {
|
|
@@ -244,7 +254,7 @@ function Popover({
|
|
|
244
254
|
}
|
|
245
255
|
};
|
|
246
256
|
}, [open, returnFocus]);
|
|
247
|
-
|
|
257
|
+
React2.useEffect(() => {
|
|
248
258
|
if (!open) return;
|
|
249
259
|
const away = (e) => {
|
|
250
260
|
if (!closeOnOutside) return;
|
|
@@ -270,7 +280,7 @@ function Popover({
|
|
|
270
280
|
}, [open, closeOnOutside, closeOnEscape, onClose, anchorRef, triggerRef]);
|
|
271
281
|
if (!open || !pos) return null;
|
|
272
282
|
return portal(
|
|
273
|
-
/* @__PURE__ */ jsx3(LayerProvider, { zIndex, children: /* @__PURE__ */
|
|
283
|
+
/* @__PURE__ */ jsx3(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs3(
|
|
274
284
|
"div",
|
|
275
285
|
{
|
|
276
286
|
ref,
|
|
@@ -318,12 +328,12 @@ function Popover({
|
|
|
318
328
|
}
|
|
319
329
|
var isItem = (it) => !!it && it.kind !== "separator" && it.kind !== "section" && it.kind !== "custom" && !it.disabled;
|
|
320
330
|
function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "", footer, header }) {
|
|
321
|
-
const listRef =
|
|
322
|
-
const [active, setActive] =
|
|
323
|
-
const [openSub, setOpenSub] =
|
|
324
|
-
const subAnchor =
|
|
325
|
-
const typed =
|
|
326
|
-
|
|
331
|
+
const listRef = React2.useRef(null);
|
|
332
|
+
const [active, setActive] = React2.useState(() => items.findIndex(isItem));
|
|
333
|
+
const [openSub, setOpenSub] = React2.useState(null);
|
|
334
|
+
const subAnchor = React2.useRef(null);
|
|
335
|
+
const typed = React2.useRef({ s: "", t: 0 });
|
|
336
|
+
React2.useEffect(() => {
|
|
327
337
|
if (autoFocus && listRef.current) listRef.current.focus({ preventScroll: true });
|
|
328
338
|
}, [autoFocus]);
|
|
329
339
|
const move = (dir) => {
|
|
@@ -385,8 +395,8 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
|
|
|
385
395
|
}
|
|
386
396
|
};
|
|
387
397
|
const sub = openSub != null ? items[openSub] : null;
|
|
388
|
-
return /* @__PURE__ */
|
|
389
|
-
/* @__PURE__ */
|
|
398
|
+
return /* @__PURE__ */ jsxs3(React2.Fragment, { children: [
|
|
399
|
+
/* @__PURE__ */ jsxs3("div", { className: "fd-menu-frame", children: [
|
|
390
400
|
header != null ? /* @__PURE__ */ jsx3("div", { className: "fd-menu-header", children: header }) : null,
|
|
391
401
|
/* @__PURE__ */ jsx3(
|
|
392
402
|
"div",
|
|
@@ -402,7 +412,7 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
|
|
|
402
412
|
if (it.kind === "section") return /* @__PURE__ */ jsx3("div", { className: "fd-pop-group", role: "presentation", children: it.label }, "h" + i);
|
|
403
413
|
if (it.kind === "custom") return /* @__PURE__ */ jsx3("div", { className: "fd-menu-custom", children: it.render ? it.render() : null }, "c" + i);
|
|
404
414
|
const on = !!it.checked;
|
|
405
|
-
const row = /* @__PURE__ */
|
|
415
|
+
const row = /* @__PURE__ */ jsxs3(
|
|
406
416
|
"button",
|
|
407
417
|
{
|
|
408
418
|
type: "button",
|
|
@@ -420,7 +430,7 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
|
|
|
420
430
|
onClick: () => choose(it, i),
|
|
421
431
|
children: [
|
|
422
432
|
it.icon ? /* @__PURE__ */ jsx3("span", { className: "fd-menu-icon", children: /* @__PURE__ */ jsx3("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) }) : null,
|
|
423
|
-
/* @__PURE__ */
|
|
433
|
+
/* @__PURE__ */ jsxs3("span", { className: "fd-menu-text", children: [
|
|
424
434
|
/* @__PURE__ */ jsx3("span", { className: "fd-opt-label", children: it.label }),
|
|
425
435
|
it.description ? /* @__PURE__ */ jsx3("span", { className: "fd-opt-desc", children: it.description }) : null
|
|
426
436
|
] }),
|
|
@@ -434,7 +444,7 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
|
|
|
434
444
|
);
|
|
435
445
|
const ta = it.trailingAction;
|
|
436
446
|
if (!ta) return row;
|
|
437
|
-
return /* @__PURE__ */
|
|
447
|
+
return /* @__PURE__ */ jsxs3("div", { className: "fd-menu-row", onMouseEnter: () => setActive(i), children: [
|
|
438
448
|
row,
|
|
439
449
|
/* @__PURE__ */ jsx3(
|
|
440
450
|
"button",
|
|
@@ -499,10 +509,10 @@ function MenuButton({
|
|
|
499
509
|
header,
|
|
500
510
|
footer
|
|
501
511
|
}) {
|
|
502
|
-
const [open, setOpen] =
|
|
503
|
-
const ref =
|
|
504
|
-
return /* @__PURE__ */
|
|
505
|
-
/* @__PURE__ */
|
|
512
|
+
const [open, setOpen] = React2.useState(false);
|
|
513
|
+
const ref = React2.useRef(null);
|
|
514
|
+
return /* @__PURE__ */ jsxs3(React2.Fragment, { children: [
|
|
515
|
+
/* @__PURE__ */ jsxs3(
|
|
506
516
|
"button",
|
|
507
517
|
{
|
|
508
518
|
type: "button",
|
|
@@ -559,7 +569,7 @@ function SegmentedControl({ options = [], value, onChange, className = "", ...re
|
|
|
559
569
|
}
|
|
560
570
|
|
|
561
571
|
// src/components/surfaces/Card.tsx
|
|
562
|
-
import { jsx as jsx5, jsxs as
|
|
572
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
563
573
|
function Card({
|
|
564
574
|
title,
|
|
565
575
|
action,
|
|
@@ -577,8 +587,8 @@ function Card({
|
|
|
577
587
|
hoverable ? "fd-card-hoverable" : "",
|
|
578
588
|
className
|
|
579
589
|
].filter(Boolean).join(" ");
|
|
580
|
-
return /* @__PURE__ */
|
|
581
|
-
title ? /* @__PURE__ */
|
|
590
|
+
return /* @__PURE__ */ jsxs4("div", { className: cls, ...rest, children: [
|
|
591
|
+
title ? /* @__PURE__ */ jsxs4("div", { className: "fd-card-head", children: [
|
|
582
592
|
/* @__PURE__ */ jsx5("span", { className: "fd-card-head-title", children: title }),
|
|
583
593
|
action
|
|
584
594
|
] }) : null,
|
|
@@ -587,15 +597,15 @@ function Card({
|
|
|
587
597
|
] });
|
|
588
598
|
}
|
|
589
599
|
function CardRow({ label, children, className = "" }) {
|
|
590
|
-
return /* @__PURE__ */
|
|
600
|
+
return /* @__PURE__ */ jsxs4("div", { className: ["fd-card-row", className].filter(Boolean).join(" "), children: [
|
|
591
601
|
/* @__PURE__ */ jsx5("span", { className: "fd-card-row-label", children: label }),
|
|
592
602
|
/* @__PURE__ */ jsx5("span", { className: "fd-card-row-value", children })
|
|
593
603
|
] });
|
|
594
604
|
}
|
|
595
605
|
|
|
596
606
|
// src/components/surfaces/Collapsible.tsx
|
|
597
|
-
import * as
|
|
598
|
-
import { jsx as jsx6, jsxs as
|
|
607
|
+
import * as React3 from "react";
|
|
608
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
599
609
|
function Collapsible({
|
|
600
610
|
title,
|
|
601
611
|
subtitle,
|
|
@@ -608,16 +618,16 @@ function Collapsible({
|
|
|
608
618
|
className = "",
|
|
609
619
|
...rest
|
|
610
620
|
}) {
|
|
611
|
-
const [internal, setInternal] =
|
|
621
|
+
const [internal, setInternal] = React3.useState(defaultOpen);
|
|
612
622
|
const isOpen = open === void 0 ? internal : open;
|
|
613
623
|
const toggle = () => {
|
|
614
624
|
if (open === void 0) setInternal(!isOpen);
|
|
615
625
|
if (onToggle) onToggle(!isOpen);
|
|
616
626
|
};
|
|
617
|
-
return /* @__PURE__ */
|
|
618
|
-
/* @__PURE__ */
|
|
627
|
+
return /* @__PURE__ */ jsxs5("div", { className: ["fd-coll", className].filter(Boolean).join(" "), "data-open": isOpen ? "true" : "false", ...rest, children: [
|
|
628
|
+
/* @__PURE__ */ jsxs5("button", { type: "button", className: "fd-coll-trigger", "aria-expanded": isOpen, onClick: toggle, children: [
|
|
619
629
|
icon ? /* @__PURE__ */ jsx6("span", { className: "fd-coll-caret", style: { background: "var(--brand-soft)", color: "var(--brand)", transform: "none" }, children: /* @__PURE__ */ jsx6("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) }) : null,
|
|
620
|
-
/* @__PURE__ */
|
|
630
|
+
/* @__PURE__ */ jsxs5("span", { style: { flex: 1, minWidth: 0 }, children: [
|
|
621
631
|
/* @__PURE__ */ jsx6("span", { className: "fd-coll-title", style: { display: "block" }, children: title }),
|
|
622
632
|
subtitle ? /* @__PURE__ */ jsx6("span", { className: "fd-coll-sub", style: { display: "block" }, children: subtitle }) : null
|
|
623
633
|
] }),
|
|
@@ -629,19 +639,19 @@ function Collapsible({
|
|
|
629
639
|
}
|
|
630
640
|
|
|
631
641
|
// src/components/surfaces/Drawer.tsx
|
|
632
|
-
import * as
|
|
642
|
+
import * as React4 from "react";
|
|
633
643
|
import { createPortal as createPortal2 } from "react-dom";
|
|
634
|
-
import { jsx as jsx7, jsxs as
|
|
644
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
635
645
|
var DRAWER_BASE = 90;
|
|
636
646
|
function Drawer({ open = true, title, onClose, footer, children, className = "", ...rest }) {
|
|
637
647
|
const zIndex = useOverlayLayer(DRAWER_BASE);
|
|
638
|
-
const [closing, setClosing] =
|
|
639
|
-
const close =
|
|
648
|
+
const [closing, setClosing] = React4.useState(false);
|
|
649
|
+
const close = React4.useCallback(() => {
|
|
640
650
|
if (!onClose) return;
|
|
641
651
|
setClosing(true);
|
|
642
652
|
setTimeout(onClose, 210);
|
|
643
653
|
}, [onClose]);
|
|
644
|
-
|
|
654
|
+
React4.useEffect(() => {
|
|
645
655
|
if (!open || !onClose) return;
|
|
646
656
|
const h = (e) => {
|
|
647
657
|
if (e.key === "Escape") close();
|
|
@@ -651,10 +661,10 @@ function Drawer({ open = true, title, onClose, footer, children, className = "",
|
|
|
651
661
|
}, [open, onClose, close]);
|
|
652
662
|
if (!open) return null;
|
|
653
663
|
return createPortal2(
|
|
654
|
-
/* @__PURE__ */
|
|
664
|
+
/* @__PURE__ */ jsxs6(LayerProvider, { zIndex, children: [
|
|
655
665
|
/* @__PURE__ */ jsx7("div", { className: "fd-scrim" + (closing ? " is-closing" : ""), style: { display: "block", zIndex: zIndex - LAYER_STEP }, onClick: close }),
|
|
656
|
-
/* @__PURE__ */
|
|
657
|
-
/* @__PURE__ */
|
|
666
|
+
/* @__PURE__ */ jsxs6("aside", { className: ["fd-drawer", closing ? "is-closing" : "", className].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", ...rest, style: { zIndex }, children: [
|
|
667
|
+
/* @__PURE__ */ jsxs6("div", { className: "fd-card-head", style: { flex: "none" }, children: [
|
|
658
668
|
/* @__PURE__ */ jsx7("span", { className: "fd-card-head-title", children: title }),
|
|
659
669
|
onClose ? /* @__PURE__ */ jsx7("button", { type: "button", className: "fd-btn-icon", "aria-label": "Close", onClick: close, children: /* @__PURE__ */ jsx7("i", { className: "ph ph-x" }) }) : null
|
|
660
670
|
] }),
|
|
@@ -667,17 +677,17 @@ function Drawer({ open = true, title, onClose, footer, children, className = "",
|
|
|
667
677
|
}
|
|
668
678
|
|
|
669
679
|
// src/components/surfaces/Modal.tsx
|
|
670
|
-
import * as
|
|
680
|
+
import * as React5 from "react";
|
|
671
681
|
import { createPortal as createPortal3 } from "react-dom";
|
|
672
|
-
import { jsx as jsx8, jsxs as
|
|
682
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
673
683
|
function Modal({ open = true, title, description, onClose, footer, wide = false, children, className = "", ...rest }) {
|
|
674
|
-
const [closing, setClosing] =
|
|
675
|
-
const close =
|
|
684
|
+
const [closing, setClosing] = React5.useState(false);
|
|
685
|
+
const close = React5.useCallback(() => {
|
|
676
686
|
if (!onClose) return;
|
|
677
687
|
setClosing(true);
|
|
678
688
|
setTimeout(onClose, 190);
|
|
679
689
|
}, [onClose]);
|
|
680
|
-
|
|
690
|
+
React5.useEffect(() => {
|
|
681
691
|
if (!open || !onClose) return;
|
|
682
692
|
const h = (e) => {
|
|
683
693
|
if (e.key === "Escape") close();
|
|
@@ -694,7 +704,7 @@ function Modal({ open = true, title, description, onClose, footer, wide = false,
|
|
|
694
704
|
onClick: onClose ? (e) => {
|
|
695
705
|
if (e.target === e.currentTarget) close();
|
|
696
706
|
} : void 0,
|
|
697
|
-
children: /* @__PURE__ */
|
|
707
|
+
children: /* @__PURE__ */ jsxs7(
|
|
698
708
|
"div",
|
|
699
709
|
{
|
|
700
710
|
className: ["fd-modal", closing ? "is-closing" : "", wide ? "fd-modal-wide" : "", className].filter(Boolean).join(" "),
|
|
@@ -703,8 +713,8 @@ function Modal({ open = true, title, description, onClose, footer, wide = false,
|
|
|
703
713
|
"aria-label": typeof title === "string" ? title : void 0,
|
|
704
714
|
...rest,
|
|
705
715
|
children: [
|
|
706
|
-
title ? /* @__PURE__ */
|
|
707
|
-
/* @__PURE__ */
|
|
716
|
+
title ? /* @__PURE__ */ jsxs7("div", { className: "fd-modal-head", children: [
|
|
717
|
+
/* @__PURE__ */ jsxs7("span", { style: { flex: 1, minWidth: 0 }, children: [
|
|
708
718
|
/* @__PURE__ */ jsx8("span", { className: "fd-modal-title", style: { display: "block" }, children: title }),
|
|
709
719
|
description ? /* @__PURE__ */ jsx8("span", { className: "fd-body-sm fd-secondary", style: { display: "block", marginTop: 6 }, children: description }) : null
|
|
710
720
|
] }),
|
|
@@ -722,7 +732,7 @@ function Modal({ open = true, title, description, onClose, footer, wide = false,
|
|
|
722
732
|
}
|
|
723
733
|
|
|
724
734
|
// src/components/loading/LoadingRegion.tsx
|
|
725
|
-
import { jsx as jsx9, jsxs as
|
|
735
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
726
736
|
function LoadingRegion({
|
|
727
737
|
state = "ready",
|
|
728
738
|
skeleton,
|
|
@@ -734,7 +744,7 @@ function LoadingRegion({
|
|
|
734
744
|
...rest
|
|
735
745
|
}) {
|
|
736
746
|
if (state === "empty" || state === "error") {
|
|
737
|
-
return /* @__PURE__ */
|
|
747
|
+
return /* @__PURE__ */ jsxs8("div", { className: ["fd-empty", className].filter(Boolean).join(" "), ...rest, children: [
|
|
738
748
|
/* @__PURE__ */ jsx9("span", { className: "fd-empty-icon", children: /* @__PURE__ */ jsx9("i", { className: state === "error" ? "ph ph-warning" : "ph ph-tray", "aria-hidden": "true" }) }),
|
|
739
749
|
/* @__PURE__ */ jsx9("span", { className: "fd-empty-title", children: state === "error" ? "That didn't load" : "Nothing here yet" }),
|
|
740
750
|
/* @__PURE__ */ jsx9("span", { className: "fd-empty-body", children: error || "Data will appear here once it exists." }),
|
|
@@ -742,7 +752,7 @@ function LoadingRegion({
|
|
|
742
752
|
] });
|
|
743
753
|
}
|
|
744
754
|
if (state === "loading") {
|
|
745
|
-
return /* @__PURE__ */
|
|
755
|
+
return /* @__PURE__ */ jsxs8("div", { className, role: "status", "aria-busy": "true", "aria-label": label, ...rest, children: [
|
|
746
756
|
/* @__PURE__ */ jsx9("span", { className: "fd-sr", children: label }),
|
|
747
757
|
skeleton
|
|
748
758
|
] });
|
|
@@ -760,14 +770,14 @@ function LoadingRegion({
|
|
|
760
770
|
}
|
|
761
771
|
|
|
762
772
|
// src/components/loading/ProgressBar.tsx
|
|
763
|
-
import { jsx as jsx10, jsxs as
|
|
773
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
764
774
|
function ProgressBar({ value, label, showValue = false, className = "", ...rest }) {
|
|
765
775
|
const indeterminate = value === void 0 || value === null;
|
|
766
776
|
const pct = indeterminate ? 0 : Math.max(0, Math.min(100, value));
|
|
767
|
-
return /* @__PURE__ */
|
|
768
|
-
label || showValue ? /* @__PURE__ */
|
|
777
|
+
return /* @__PURE__ */ jsxs9("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 8 }, children: [
|
|
778
|
+
label || showValue ? /* @__PURE__ */ jsxs9("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
|
|
769
779
|
label ? /* @__PURE__ */ jsx10("span", { className: "fd-label-lg", children: label }) : /* @__PURE__ */ jsx10("span", {}),
|
|
770
|
-
showValue && !indeterminate ? /* @__PURE__ */
|
|
780
|
+
showValue && !indeterminate ? /* @__PURE__ */ jsxs9("span", { className: "fd-num fd-secondary", children: [
|
|
771
781
|
pct,
|
|
772
782
|
"%"
|
|
773
783
|
] }) : null
|
|
@@ -833,16 +843,16 @@ function Spinner({ size = "md", label = "Loading", className = "", style, ...res
|
|
|
833
843
|
}
|
|
834
844
|
|
|
835
845
|
// src/components/navigation/SidebarNav.tsx
|
|
836
|
-
import { jsx as jsx13, jsxs as
|
|
846
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
837
847
|
function Tip({ label, children }) {
|
|
838
848
|
return /* @__PURE__ */ jsx13("span", { title: label, style: { display: "inline-flex", flex: "none" }, children });
|
|
839
849
|
}
|
|
840
850
|
function SidebarNav({ brand, groups = [], current: current2, onNavigate, footer, open = false, className = "", ...rest }) {
|
|
841
|
-
return /* @__PURE__ */
|
|
851
|
+
return /* @__PURE__ */ jsxs10("nav", { className: ["fd-side", className].filter(Boolean).join(" "), "data-open": open ? "true" : "false", ...rest, children: [
|
|
842
852
|
brand ? /* @__PURE__ */ jsx13("div", { style: { height: "var(--topbar-h)", display: "flex", alignItems: "center", padding: "0 18px", borderBottom: "1px solid var(--border)", flex: "none", overflow: "hidden" }, children: brand }) : null,
|
|
843
|
-
/* @__PURE__ */ jsx13("div", { style: { flex: 1, overflow: "auto", padding: "4px 10px 18px" }, children: groups.map((g, gi) => /* @__PURE__ */
|
|
853
|
+
/* @__PURE__ */ jsx13("div", { style: { flex: 1, overflow: "auto", padding: "4px 10px 18px" }, children: groups.map((g, gi) => /* @__PURE__ */ jsxs10("div", { children: [
|
|
844
854
|
g.label ? /* @__PURE__ */ jsx13("div", { className: "fd-side-group", children: g.label }) : null,
|
|
845
|
-
/* @__PURE__ */ jsx13("div", { className: "fd-stack", style: { gap: 2 }, children: g.items.map((it) => /* @__PURE__ */
|
|
855
|
+
/* @__PURE__ */ jsx13("div", { className: "fd-stack", style: { gap: 2 }, children: g.items.map((it) => /* @__PURE__ */ jsxs10(
|
|
846
856
|
"button",
|
|
847
857
|
{
|
|
848
858
|
type: "button",
|
|
@@ -866,26 +876,26 @@ function SidebarNav({ brand, groups = [], current: current2, onNavigate, footer,
|
|
|
866
876
|
}
|
|
867
877
|
|
|
868
878
|
// src/components/navigation/FlytedeskBrand.tsx
|
|
869
|
-
import { jsx as jsx14, jsxs as
|
|
879
|
+
import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
870
880
|
var LOGO_SRC = "https://cdn.prod.website-files.com/69a96def413819b7db64de8c/69ac8ec2ed84b986a5fb76dc_Logo%20(dark)%202.svg";
|
|
871
881
|
function FlytedeskMark({ size = "md", className = "", ...rest }) {
|
|
872
882
|
return /* @__PURE__ */ jsx14("span", { className: ["fd-brand-mark", size !== "md" ? "fd-brand-mark-" + size : "", className].filter(Boolean).join(" "), ...rest, children: /* @__PURE__ */ jsx14("img", { src: LOGO_SRC, alt: "flytedesk" }) });
|
|
873
883
|
}
|
|
874
884
|
function FlytedeskBrand({ appName, size = "md", className = "", ...rest }) {
|
|
875
|
-
return /* @__PURE__ */
|
|
885
|
+
return /* @__PURE__ */ jsxs11("span", { className: ["fd-brand", size !== "md" ? "fd-brand-" + size : "", className].filter(Boolean).join(" "), ...rest, children: [
|
|
876
886
|
/* @__PURE__ */ jsx14(FlytedeskMark, { size }),
|
|
877
887
|
/* @__PURE__ */ jsx14("span", { className: "fd-overline fd-muted", children: appName })
|
|
878
888
|
] });
|
|
879
889
|
}
|
|
880
890
|
|
|
881
891
|
// src/components/navigation/Tabs.tsx
|
|
882
|
-
import { jsx as jsx15, jsxs as
|
|
892
|
+
import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
883
893
|
function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
884
894
|
return /* @__PURE__ */ jsx15("div", { className: ["fd-tabs", className].filter(Boolean).join(" "), role: "tablist", ...rest, children: tabs.map((t) => {
|
|
885
895
|
const v = typeof t === "string" ? t : t.value;
|
|
886
896
|
const label = typeof t === "string" ? t : t.label;
|
|
887
897
|
const count = typeof t === "string" ? void 0 : t.count;
|
|
888
|
-
return /* @__PURE__ */
|
|
898
|
+
return /* @__PURE__ */ jsxs12(
|
|
889
899
|
"button",
|
|
890
900
|
{
|
|
891
901
|
type: "button",
|
|
@@ -904,13 +914,13 @@ function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
|
904
914
|
}
|
|
905
915
|
|
|
906
916
|
// src/components/navigation/Topbar.tsx
|
|
907
|
-
import * as
|
|
908
|
-
import { Fragment as Fragment3, jsx as jsx16, jsxs as
|
|
917
|
+
import * as React6 from "react";
|
|
918
|
+
import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
909
919
|
function useIsNarrow(breakpoint) {
|
|
910
|
-
const [narrow, setNarrow] =
|
|
920
|
+
const [narrow, setNarrow] = React6.useState(
|
|
911
921
|
() => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
912
922
|
);
|
|
913
|
-
|
|
923
|
+
React6.useEffect(() => {
|
|
914
924
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
915
925
|
const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
916
926
|
const apply = () => setNarrow(mq.matches);
|
|
@@ -931,11 +941,11 @@ function Topbar({
|
|
|
931
941
|
...rest
|
|
932
942
|
}) {
|
|
933
943
|
const narrow = useIsNarrow(overflowBreakpoint);
|
|
934
|
-
const [moreOpen, setMoreOpen] =
|
|
935
|
-
const moreRef =
|
|
936
|
-
return /* @__PURE__ */
|
|
944
|
+
const [moreOpen, setMoreOpen] = React6.useState(false);
|
|
945
|
+
const moreRef = React6.useRef(null);
|
|
946
|
+
return /* @__PURE__ */ jsxs13("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
|
|
937
947
|
onMenu ? /* @__PURE__ */ jsx16("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ jsx16("i", { className: "ph ph-list" }) }) : null,
|
|
938
|
-
/* @__PURE__ */ jsx16("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */
|
|
948
|
+
/* @__PURE__ */ jsx16("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs13(React6.Fragment, { children: [
|
|
939
949
|
i > 0 ? /* @__PURE__ */ jsx16("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
|
|
940
950
|
i === crumbs.length - 1 ? /* @__PURE__ */ jsx16("span", { className: "fd-crumb-current", children: c.label }) : /* @__PURE__ */ jsx16(
|
|
941
951
|
"a",
|
|
@@ -950,7 +960,7 @@ function Topbar({
|
|
|
950
960
|
)
|
|
951
961
|
] }, i)) }),
|
|
952
962
|
/* @__PURE__ */ jsx16("span", { style: { flex: 1 } }),
|
|
953
|
-
overflowActions != null ? narrow ? /* @__PURE__ */
|
|
963
|
+
overflowActions != null ? narrow ? /* @__PURE__ */ jsxs13(Fragment3, { children: [
|
|
954
964
|
/* @__PURE__ */ jsx16(
|
|
955
965
|
"button",
|
|
956
966
|
{
|
|
@@ -974,7 +984,7 @@ function Topbar({
|
|
|
974
984
|
padded: true,
|
|
975
985
|
label: "More actions",
|
|
976
986
|
className: "fd-topbar-overflow",
|
|
977
|
-
children: /* @__PURE__ */ jsx16("div", { className: "fd-stack fd-topbar-overflow-list", children: overflowActions })
|
|
987
|
+
children: /* @__PURE__ */ jsx16("div", { className: "fd-stack fd-topbar-overflow-list", children: /* @__PURE__ */ jsx16(OverflowRowContext.Provider, { value: true, children: overflowActions }) })
|
|
978
988
|
}
|
|
979
989
|
)
|
|
980
990
|
] }) : overflowActions : null,
|
|
@@ -984,7 +994,7 @@ function Topbar({
|
|
|
984
994
|
}
|
|
985
995
|
|
|
986
996
|
// src/components/feedback/Avatar.tsx
|
|
987
|
-
import { jsx as jsx17, jsxs as
|
|
997
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
988
998
|
function Avatar({ name = "", src, size = "md", className = "", ...rest }) {
|
|
989
999
|
const initials = name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join("").toUpperCase();
|
|
990
1000
|
return /* @__PURE__ */ jsx17(
|
|
@@ -1000,17 +1010,17 @@ function Avatar({ name = "", src, size = "md", className = "", ...rest }) {
|
|
|
1000
1010
|
function AvatarStack({ people = [], size = "sm", max = 4, className = "" }) {
|
|
1001
1011
|
const shown = people.slice(0, max);
|
|
1002
1012
|
const rest = people.length - shown.length;
|
|
1003
|
-
return /* @__PURE__ */
|
|
1013
|
+
return /* @__PURE__ */ jsxs14("span", { className: ["fd-avatar-stack", className].filter(Boolean).join(" "), children: [
|
|
1004
1014
|
shown.map((p, i) => /* @__PURE__ */ jsx17(Avatar, { name: typeof p === "string" ? p : p.name, src: typeof p === "string" ? void 0 : p.src, size }, i)),
|
|
1005
1015
|
rest > 0 ? /* @__PURE__ */ jsx17(Avatar, { name: "+" + rest, size }) : null
|
|
1006
1016
|
] });
|
|
1007
1017
|
}
|
|
1008
1018
|
|
|
1009
1019
|
// src/components/feedback/Badge.tsx
|
|
1010
|
-
import { jsx as jsx18, jsxs as
|
|
1020
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1011
1021
|
var TONES = { neutral: "fd-badge-neutral", info: "fd-badge-info", success: "fd-badge-success", warning: "fd-badge-warning", danger: "fd-badge-danger", live: "fd-badge-live", approved: "fd-badge-approved", count: "fd-badge-count" };
|
|
1012
1022
|
function Badge({ children, tone = "neutral", dot = false, icon, className = "", ...rest }) {
|
|
1013
|
-
return /* @__PURE__ */
|
|
1023
|
+
return /* @__PURE__ */ jsxs15("span", { className: ["fd-badge", TONES[tone] || TONES.neutral, className].filter(Boolean).join(" "), ...rest, children: [
|
|
1014
1024
|
dot ? /* @__PURE__ */ jsx18("span", { className: "fd-badge-dot", "aria-hidden": "true" }) : null,
|
|
1015
1025
|
icon ? /* @__PURE__ */ jsx18("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) : null,
|
|
1016
1026
|
children
|
|
@@ -1018,9 +1028,9 @@ function Badge({ children, tone = "neutral", dot = false, icon, className = "",
|
|
|
1018
1028
|
}
|
|
1019
1029
|
|
|
1020
1030
|
// src/components/feedback/EmptyState.tsx
|
|
1021
|
-
import { jsx as jsx19, jsxs as
|
|
1031
|
+
import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1022
1032
|
function EmptyState({ icon = "tray", title, children, action, className = "", ...rest }) {
|
|
1023
|
-
return /* @__PURE__ */
|
|
1033
|
+
return /* @__PURE__ */ jsxs16("div", { className: ["fd-empty", className].filter(Boolean).join(" "), ...rest, children: [
|
|
1024
1034
|
/* @__PURE__ */ jsx19("span", { className: "fd-empty-icon", children: /* @__PURE__ */ jsx19("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) }),
|
|
1025
1035
|
/* @__PURE__ */ jsx19("span", { className: "fd-empty-title", children: title }),
|
|
1026
1036
|
children ? /* @__PURE__ */ jsx19("span", { className: "fd-empty-body", children }) : null,
|
|
@@ -1029,12 +1039,12 @@ function EmptyState({ icon = "tray", title, children, action, className = "", ..
|
|
|
1029
1039
|
}
|
|
1030
1040
|
|
|
1031
1041
|
// src/components/feedback/Flag.tsx
|
|
1032
|
-
import { Fragment as Fragment4, jsx as jsx20, jsxs as
|
|
1042
|
+
import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1033
1043
|
function Flag({ statement, cost, actions, tone = "warning", className = "", ...rest }) {
|
|
1034
|
-
return /* @__PURE__ */
|
|
1035
|
-
/* @__PURE__ */
|
|
1044
|
+
return /* @__PURE__ */ jsxs17("div", { className: ["fd-flag", "fd-flag-" + tone, className].filter(Boolean).join(" "), role: "status", ...rest, children: [
|
|
1045
|
+
/* @__PURE__ */ jsxs17("span", { className: "fd-flag-text", children: [
|
|
1036
1046
|
statement,
|
|
1037
|
-
cost ? /* @__PURE__ */
|
|
1047
|
+
cost ? /* @__PURE__ */ jsxs17(Fragment4, { children: [
|
|
1038
1048
|
" ",
|
|
1039
1049
|
/* @__PURE__ */ jsx20("span", { className: "fd-flag-cost", children: cost })
|
|
1040
1050
|
] }) : null
|
|
@@ -1086,10 +1096,10 @@ function hasModifier(e) {
|
|
|
1086
1096
|
}
|
|
1087
1097
|
|
|
1088
1098
|
// src/components/feedback/Tag.tsx
|
|
1089
|
-
import { jsx as jsx22, jsxs as
|
|
1099
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1090
1100
|
var TONES2 = { info: "fd-tag-info", success: "fd-tag-success", warning: "fd-tag-warning", danger: "fd-tag-danger" };
|
|
1091
1101
|
function Tag({ children, icon, selected = false, tone = "neutral", onRemove, onClick, className = "", ...rest }) {
|
|
1092
|
-
return /* @__PURE__ */
|
|
1102
|
+
return /* @__PURE__ */ jsxs18(
|
|
1093
1103
|
"button",
|
|
1094
1104
|
{
|
|
1095
1105
|
type: "button",
|
|
@@ -1119,7 +1129,7 @@ function Tag({ children, icon, selected = false, tone = "neutral", onRemove, onC
|
|
|
1119
1129
|
}
|
|
1120
1130
|
|
|
1121
1131
|
// src/components/feedback/Toast.tsx
|
|
1122
|
-
import { jsx as jsx23, jsxs as
|
|
1132
|
+
import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1123
1133
|
var ICON = {
|
|
1124
1134
|
success: { i: "check", bg: "var(--ok-solid)" },
|
|
1125
1135
|
error: { i: "x", bg: "var(--danger-solid)" },
|
|
@@ -1128,9 +1138,9 @@ var ICON = {
|
|
|
1128
1138
|
};
|
|
1129
1139
|
function Toast({ title, children, tone = "success", onUndo, onDismiss, className = "", ...rest }) {
|
|
1130
1140
|
const ic = ICON[tone] || ICON.info;
|
|
1131
|
-
return /* @__PURE__ */
|
|
1141
|
+
return /* @__PURE__ */ jsxs19("div", { className: ["fd-toast", className].filter(Boolean).join(" "), role: "status", ...rest, children: [
|
|
1132
1142
|
/* @__PURE__ */ jsx23("span", { className: "fd-toast-icon", style: { background: ic.bg }, "aria-hidden": "true", children: tone === "loading" ? /* @__PURE__ */ jsx23("span", { className: "fd-spinner", style: { width: 12, height: 12, borderWidth: 2, color: "#fff" } }) : /* @__PURE__ */ jsx23("i", { className: "ph ph-" + ic.i }) }),
|
|
1133
|
-
/* @__PURE__ */
|
|
1143
|
+
/* @__PURE__ */ jsxs19("span", { className: "fd-toast-body", children: [
|
|
1134
1144
|
/* @__PURE__ */ jsx23("span", { className: "fd-toast-title", style: { display: "block" }, children: title }),
|
|
1135
1145
|
children ? /* @__PURE__ */ jsx23("span", { className: "fd-secondary", style: { display: "block", marginTop: 2 }, children }) : null,
|
|
1136
1146
|
onUndo ? /* @__PURE__ */ jsx23("button", { type: "button", className: "fd-btn fd-btn-link", style: { marginTop: 8 }, onClick: onUndo, children: "Undo" }) : null
|
|
@@ -1140,19 +1150,19 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
|
|
|
1140
1150
|
}
|
|
1141
1151
|
|
|
1142
1152
|
// src/components/feedback/Tooltip.tsx
|
|
1143
|
-
import * as
|
|
1144
|
-
import { jsx as jsx24, jsxs as
|
|
1153
|
+
import * as React7 from "react";
|
|
1154
|
+
import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1145
1155
|
var TOOLTIP_BASE = 150;
|
|
1146
1156
|
var CLOSE_DELAY_MS = 120;
|
|
1147
1157
|
function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
1148
|
-
const anchorRef =
|
|
1149
|
-
const bubbleRef =
|
|
1150
|
-
const [reason, setReason] =
|
|
1151
|
-
const closeTimer =
|
|
1152
|
-
const id =
|
|
1158
|
+
const anchorRef = React7.useRef(null);
|
|
1159
|
+
const bubbleRef = React7.useRef(null);
|
|
1160
|
+
const [reason, setReason] = React7.useState(null);
|
|
1161
|
+
const closeTimer = React7.useRef(null);
|
|
1162
|
+
const id = React7.useId();
|
|
1153
1163
|
const descId = id + "-desc";
|
|
1154
1164
|
const open = reason != null;
|
|
1155
|
-
const cancelClose =
|
|
1165
|
+
const cancelClose = React7.useCallback(() => {
|
|
1156
1166
|
if (closeTimer.current) {
|
|
1157
1167
|
clearTimeout(closeTimer.current);
|
|
1158
1168
|
closeTimer.current = null;
|
|
@@ -1162,7 +1172,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1162
1172
|
cancelClose();
|
|
1163
1173
|
setReason(why);
|
|
1164
1174
|
};
|
|
1165
|
-
const hide =
|
|
1175
|
+
const hide = React7.useCallback(() => {
|
|
1166
1176
|
cancelClose();
|
|
1167
1177
|
setReason(null);
|
|
1168
1178
|
}, [cancelClose]);
|
|
@@ -1177,7 +1187,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1177
1187
|
setReason((r) => r === "hover" ? null : r);
|
|
1178
1188
|
}, CLOSE_DELAY_MS);
|
|
1179
1189
|
};
|
|
1180
|
-
|
|
1190
|
+
React7.useEffect(() => cancelClose, [cancelClose]);
|
|
1181
1191
|
const pos = usePopoverPosition(open, anchorRef, {
|
|
1182
1192
|
placement: placement === "bottom" ? "bottom-center" : "top-center",
|
|
1183
1193
|
offset: 8,
|
|
@@ -1187,7 +1197,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1187
1197
|
onDetach: hide
|
|
1188
1198
|
});
|
|
1189
1199
|
const zIndex = useOverlayLayer(TOOLTIP_BASE);
|
|
1190
|
-
|
|
1200
|
+
React7.useEffect(() => {
|
|
1191
1201
|
if (!open) return;
|
|
1192
1202
|
const key = (e) => {
|
|
1193
1203
|
if (e.key === "Escape") hide();
|
|
@@ -1215,15 +1225,15 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1215
1225
|
}
|
|
1216
1226
|
if (keyboard) show("focus");
|
|
1217
1227
|
};
|
|
1218
|
-
const described =
|
|
1228
|
+
const described = React7.isValidElement(children) ? React7.cloneElement(children, {
|
|
1219
1229
|
"aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
|
|
1220
1230
|
}) : children;
|
|
1221
|
-
return /* @__PURE__ */
|
|
1231
|
+
return /* @__PURE__ */ jsxs20(
|
|
1222
1232
|
"span",
|
|
1223
1233
|
{
|
|
1224
1234
|
ref: anchorRef,
|
|
1225
1235
|
className: "fd-tooltip-anchor",
|
|
1226
|
-
"aria-describedby":
|
|
1236
|
+
"aria-describedby": React7.isValidElement(children) ? void 0 : descId,
|
|
1227
1237
|
onPointerEnter: (e) => {
|
|
1228
1238
|
if (isMouse(e)) hover();
|
|
1229
1239
|
},
|
|
@@ -1267,8 +1277,8 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1267
1277
|
}
|
|
1268
1278
|
|
|
1269
1279
|
// src/components/data/Clamp.tsx
|
|
1270
|
-
import * as
|
|
1271
|
-
import { jsx as jsx25, jsxs as
|
|
1280
|
+
import * as React8 from "react";
|
|
1281
|
+
import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1272
1282
|
function Clamp({
|
|
1273
1283
|
children,
|
|
1274
1284
|
text,
|
|
@@ -1279,16 +1289,16 @@ function Clamp({
|
|
|
1279
1289
|
onToggle,
|
|
1280
1290
|
className = ""
|
|
1281
1291
|
}) {
|
|
1282
|
-
const [open, setOpen] =
|
|
1283
|
-
const [overflows, setOverflows] =
|
|
1284
|
-
const bodyRef =
|
|
1285
|
-
const charClamped =
|
|
1292
|
+
const [open, setOpen] = React8.useState(false);
|
|
1293
|
+
const [overflows, setOverflows] = React8.useState(false);
|
|
1294
|
+
const bodyRef = React8.useRef(null);
|
|
1295
|
+
const charClamped = React8.useMemo(() => {
|
|
1286
1296
|
if (open || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
|
|
1287
1297
|
const cut = text.slice(0, maxChars);
|
|
1288
1298
|
const at = cut.lastIndexOf(" ");
|
|
1289
1299
|
return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
1290
1300
|
}, [text, maxChars, open]);
|
|
1291
|
-
|
|
1301
|
+
React8.useLayoutEffect(() => {
|
|
1292
1302
|
const node = bodyRef.current;
|
|
1293
1303
|
if (maxChars || !node || !maxHeight) return;
|
|
1294
1304
|
const measure = () => {
|
|
@@ -1309,9 +1319,9 @@ function Clamp({
|
|
|
1309
1319
|
return !v;
|
|
1310
1320
|
});
|
|
1311
1321
|
};
|
|
1312
|
-
return /* @__PURE__ */
|
|
1322
|
+
return /* @__PURE__ */ jsxs21("div", { className: ["fd-clamp", clamped ? "is-clamped" : "", className].filter(Boolean).join(" "), children: [
|
|
1313
1323
|
/* @__PURE__ */ jsx25("div", { className: "fd-clamp-body", ref: bodyRef, style: !maxChars && clamped ? { maxHeight } : void 0, children: maxChars ? charClamped != null ? charClamped : text != null ? text : children : children }),
|
|
1314
|
-
(maxChars ? charClamped != null || open : overflows) ? /* @__PURE__ */
|
|
1324
|
+
(maxChars ? charClamped != null || open : overflows) ? /* @__PURE__ */ jsxs21("button", { type: "button", className: "fd-clamp-more", onClick: toggle, "aria-expanded": open, children: [
|
|
1315
1325
|
/* @__PURE__ */ jsx25("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
|
|
1316
1326
|
open ? lessLabel : moreLabel
|
|
1317
1327
|
] }) : null
|
|
@@ -1319,7 +1329,7 @@ function Clamp({
|
|
|
1319
1329
|
}
|
|
1320
1330
|
|
|
1321
1331
|
// src/components/data/CsiBadge.tsx
|
|
1322
|
-
import { jsx as jsx26, jsxs as
|
|
1332
|
+
import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1323
1333
|
var BANDS = {
|
|
1324
1334
|
weak: { n: 1, label: "Weak" },
|
|
1325
1335
|
adequate: { n: 2, label: "Adequate" },
|
|
@@ -1342,7 +1352,7 @@ function CsiMeter({ band = "weak", size = 4, width = 5, gap = 2 }) {
|
|
|
1342
1352
|
}
|
|
1343
1353
|
function CsiBadge({ band = "weak", crp, size = "compact", preview = false, alert = false, className = "", ...rest }) {
|
|
1344
1354
|
const b = BANDS[band] || BANDS.weak;
|
|
1345
|
-
return /* @__PURE__ */
|
|
1355
|
+
return /* @__PURE__ */ jsxs22(
|
|
1346
1356
|
"span",
|
|
1347
1357
|
{
|
|
1348
1358
|
className: ["fd-csi", "fd-csi-" + b.n, size === "medium" ? "fd-csi-medium" : "fd-csi-compact", preview ? "fd-csi-preview" : "", className].filter(Boolean).join(" "),
|
|
@@ -1359,7 +1369,7 @@ function CsiBadge({ band = "weak", crp, size = "compact", preview = false, alert
|
|
|
1359
1369
|
function CsiHero({ band = "weak", crp, label, className = "" }) {
|
|
1360
1370
|
const b = BANDS[band] || BANDS.weak;
|
|
1361
1371
|
const mark = "var(--csi-" + b.n + "-mark)";
|
|
1362
|
-
return /* @__PURE__ */
|
|
1372
|
+
return /* @__PURE__ */ jsxs22("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 10 }, children: [
|
|
1363
1373
|
/* @__PURE__ */ jsx26("span", { className: "fd-csi-hero-num", style: { color: mark }, children: crp !== void 0 && crp !== null ? formatCrp(crp) : "" }),
|
|
1364
1374
|
/* @__PURE__ */ jsx26("span", { className: "fd-label-lg", style: { color: "var(--text-2)" }, children: label || b.label }),
|
|
1365
1375
|
/* @__PURE__ */ jsx26("span", { className: "fd-meter", style: { gap: 3, color: mark, width: 120 }, children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx26("span", { className: "fd-meter-seg" + (i <= b.n ? " is-on" : ""), style: { height: 6, flex: 1 } }, i)) })
|
|
@@ -1367,7 +1377,7 @@ function CsiHero({ band = "weak", crp, label, className = "" }) {
|
|
|
1367
1377
|
}
|
|
1368
1378
|
|
|
1369
1379
|
// src/components/data/DataTable.tsx
|
|
1370
|
-
import { jsx as jsx27, jsxs as
|
|
1380
|
+
import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1371
1381
|
function DataTable({
|
|
1372
1382
|
columns = [],
|
|
1373
1383
|
rows = [],
|
|
@@ -1384,14 +1394,14 @@ function DataTable({
|
|
|
1384
1394
|
...rest
|
|
1385
1395
|
}) {
|
|
1386
1396
|
const stale = refreshing && !loading;
|
|
1387
|
-
return /* @__PURE__ */
|
|
1397
|
+
return /* @__PURE__ */ jsxs23("div", { className: "fd-table-host", children: [
|
|
1388
1398
|
/* @__PURE__ */ jsx27(
|
|
1389
1399
|
"div",
|
|
1390
1400
|
{
|
|
1391
1401
|
className: ["fd-table-wrap", className].filter(Boolean).join(" "),
|
|
1392
1402
|
"aria-busy": loading || refreshing ? "true" : void 0,
|
|
1393
1403
|
...rest,
|
|
1394
|
-
children: /* @__PURE__ */
|
|
1404
|
+
children: /* @__PURE__ */ jsxs23("table", { className: ["fd-table", compact3 ? "fd-table-compact" : ""].filter(Boolean).join(" "), children: [
|
|
1395
1405
|
/* @__PURE__ */ jsx27("thead", { children: /* @__PURE__ */ jsx27("tr", { children: columns.map((c) => /* @__PURE__ */ jsx27(
|
|
1396
1406
|
"th",
|
|
1397
1407
|
{
|
|
@@ -1399,7 +1409,7 @@ function DataTable({
|
|
|
1399
1409
|
style: { width: c.width },
|
|
1400
1410
|
className: [c.numeric ? "is-num" : "", sort && sort.key === c.key ? "is-sorted" : ""].filter(Boolean).join(" "),
|
|
1401
1411
|
"aria-sort": sort && sort.key === c.key ? sort.dir === "asc" ? "ascending" : "descending" : void 0,
|
|
1402
|
-
children: c.sortable && onSort ? /* @__PURE__ */
|
|
1412
|
+
children: c.sortable && onSort ? /* @__PURE__ */ jsxs23("button", { type: "button", onClick: () => onSort(c.key), children: [
|
|
1403
1413
|
c.label,
|
|
1404
1414
|
sort && sort.key === c.key ? /* @__PURE__ */ jsx27("i", { className: "ph fd-caret ph-caret-" + (sort.dir === "asc" ? "up" : "down") }) : null
|
|
1405
1415
|
] }) : c.label
|
|
@@ -1419,7 +1429,7 @@ function DataTable({
|
|
|
1419
1429
|
] })
|
|
1420
1430
|
}
|
|
1421
1431
|
),
|
|
1422
|
-
stale ? /* @__PURE__ */ jsx27("div", { className: "fd-table-stale", children: /* @__PURE__ */
|
|
1432
|
+
stale ? /* @__PURE__ */ jsx27("div", { className: "fd-table-stale", children: /* @__PURE__ */ jsxs23("span", { className: "fd-table-stale-pill", role: "status", children: [
|
|
1423
1433
|
/* @__PURE__ */ jsx27("span", { className: "fd-spinner", "aria-hidden": "true" }),
|
|
1424
1434
|
" Updating\u2026"
|
|
1425
1435
|
] }) }) : null
|
|
@@ -1427,17 +1437,19 @@ function DataTable({
|
|
|
1427
1437
|
}
|
|
1428
1438
|
|
|
1429
1439
|
// src/components/data/FilterBar.tsx
|
|
1430
|
-
import * as
|
|
1431
|
-
import { jsx as jsx28, jsxs as
|
|
1440
|
+
import * as React9 from "react";
|
|
1441
|
+
import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1442
|
+
var FILTER_BAR_BASE = 120;
|
|
1432
1443
|
var isSet = (v) => !(v == null || v === "" || v === false);
|
|
1433
1444
|
function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", className = "", ...rest }) {
|
|
1434
|
-
const [panel, setPanel] =
|
|
1435
|
-
const
|
|
1436
|
-
const
|
|
1437
|
-
const
|
|
1445
|
+
const [panel, setPanel] = React9.useState(null);
|
|
1446
|
+
const zIndex = useOverlayLayer(FILTER_BAR_BASE);
|
|
1447
|
+
const rootRef = React9.useRef(null);
|
|
1448
|
+
const textInputRef = React9.useRef(null);
|
|
1449
|
+
const optionsRef = React9.useRef(null);
|
|
1438
1450
|
const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
|
|
1439
1451
|
const dismissible = !!panel && (panel.kind === "add" || panel.kind === "edit" && editingField?.type === "select");
|
|
1440
|
-
|
|
1452
|
+
React9.useEffect(() => {
|
|
1441
1453
|
if (!dismissible) return;
|
|
1442
1454
|
const away = (e) => {
|
|
1443
1455
|
if (rootRef.current && !rootRef.current.contains(e.target)) setPanel(null);
|
|
@@ -1452,7 +1464,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1452
1464
|
document.removeEventListener("keydown", esc);
|
|
1453
1465
|
};
|
|
1454
1466
|
}, [dismissible]);
|
|
1455
|
-
|
|
1467
|
+
React9.useEffect(() => {
|
|
1456
1468
|
if (!panel || panel.kind !== "edit") return;
|
|
1457
1469
|
if (editingField?.type === "text") {
|
|
1458
1470
|
textInputRef.current?.focus();
|
|
@@ -1463,12 +1475,12 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1463
1475
|
}, [panel]);
|
|
1464
1476
|
const addableFields = fields.filter((f) => !isSet(filters[f.key]));
|
|
1465
1477
|
const startEditing = (key) => setPanel({ kind: "edit", key });
|
|
1466
|
-
return /* @__PURE__ */
|
|
1478
|
+
return /* @__PURE__ */ jsxs24("span", { className, style: { position: "relative", display: "inline-flex", flexWrap: "wrap", alignItems: "center", gap: 8 }, ref: rootRef, ...rest, children: [
|
|
1467
1479
|
fields.map((field) => {
|
|
1468
1480
|
const value = filters[field.key];
|
|
1469
1481
|
const editing = panel?.kind === "edit" && panel.key === field.key;
|
|
1470
1482
|
if (editing && field.type === "text") {
|
|
1471
|
-
return /* @__PURE__ */
|
|
1483
|
+
return /* @__PURE__ */ jsxs24(
|
|
1472
1484
|
"span",
|
|
1473
1485
|
{
|
|
1474
1486
|
className: "fd-tag",
|
|
@@ -1514,19 +1526,19 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1514
1526
|
}
|
|
1515
1527
|
if (editing && field.type === "select") {
|
|
1516
1528
|
const chosen = field.options.find((o) => o.value === value);
|
|
1517
|
-
return /* @__PURE__ */
|
|
1518
|
-
/* @__PURE__ */
|
|
1529
|
+
return /* @__PURE__ */ jsxs24("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1530
|
+
/* @__PURE__ */ jsxs24(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
|
|
1519
1531
|
if (isSet(value)) onFilterRemove(field.key);
|
|
1520
1532
|
setPanel(null);
|
|
1521
1533
|
}, children: [
|
|
1522
1534
|
field.label,
|
|
1523
1535
|
chosen ? ": " + chosen.label : ""
|
|
1524
1536
|
] }),
|
|
1525
|
-
/* @__PURE__ */ jsx28(
|
|
1537
|
+
/* @__PURE__ */ jsx28(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx28(
|
|
1526
1538
|
"span",
|
|
1527
1539
|
{
|
|
1528
1540
|
className: "fd-view-enter",
|
|
1529
|
-
style: { position: "absolute", top: "calc(100% + 6px)", left: 0, zIndex
|
|
1541
|
+
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 },
|
|
1530
1542
|
children: /* @__PURE__ */ jsx28("span", { className: "fd-stack", role: "listbox", "aria-label": field.label, ref: optionsRef, style: { gap: 2 }, children: field.options.map((o) => {
|
|
1531
1543
|
const on = o.value === value;
|
|
1532
1544
|
return /* @__PURE__ */ jsx28(
|
|
@@ -1547,13 +1559,13 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1547
1559
|
);
|
|
1548
1560
|
}) })
|
|
1549
1561
|
}
|
|
1550
|
-
)
|
|
1562
|
+
) })
|
|
1551
1563
|
] }, field.key);
|
|
1552
1564
|
}
|
|
1553
1565
|
if (isSet(value)) {
|
|
1554
1566
|
const chosen = field.type === "select" ? field.options.find((o) => o.value === value) : void 0;
|
|
1555
1567
|
const display = chosen ? chosen.label : String(value);
|
|
1556
|
-
return /* @__PURE__ */
|
|
1568
|
+
return /* @__PURE__ */ jsxs24(Tag, { selected: true, onClick: () => startEditing(field.key), onRemove: () => onFilterRemove(field.key), children: [
|
|
1557
1569
|
field.label,
|
|
1558
1570
|
": ",
|
|
1559
1571
|
display
|
|
@@ -1561,7 +1573,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1561
1573
|
}
|
|
1562
1574
|
return null;
|
|
1563
1575
|
}),
|
|
1564
|
-
addableFields.length > 0 ? /* @__PURE__ */
|
|
1576
|
+
addableFields.length > 0 ? /* @__PURE__ */ jsxs24("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1565
1577
|
/* @__PURE__ */ jsx28(
|
|
1566
1578
|
Button,
|
|
1567
1579
|
{
|
|
@@ -1574,12 +1586,12 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1574
1586
|
children: "Filter"
|
|
1575
1587
|
}
|
|
1576
1588
|
),
|
|
1577
|
-
panel?.kind === "add" ? /* @__PURE__ */ jsx28(
|
|
1589
|
+
panel?.kind === "add" ? /* @__PURE__ */ jsx28(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx28(
|
|
1578
1590
|
"span",
|
|
1579
1591
|
{
|
|
1580
1592
|
className: "fd-view-enter",
|
|
1581
|
-
style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex
|
|
1582
|
-
children: /* @__PURE__ */
|
|
1593
|
+
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 },
|
|
1594
|
+
children: /* @__PURE__ */ jsxs24("span", { className: "fd-stack", role: "menu", "aria-label": "Add filter", style: { gap: 2 }, children: [
|
|
1583
1595
|
/* @__PURE__ */ jsx28("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Add filter" }),
|
|
1584
1596
|
addableFields.map((f) => /* @__PURE__ */ jsx28(
|
|
1585
1597
|
"button",
|
|
@@ -1595,18 +1607,18 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
1595
1607
|
))
|
|
1596
1608
|
] })
|
|
1597
1609
|
}
|
|
1598
|
-
) : null
|
|
1610
|
+
) }) : null
|
|
1599
1611
|
] }) : null
|
|
1600
1612
|
] });
|
|
1601
1613
|
}
|
|
1602
1614
|
|
|
1603
1615
|
// src/components/data/StatTile.tsx
|
|
1604
|
-
import { jsx as jsx29, jsxs as
|
|
1616
|
+
import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1605
1617
|
function StatTile({ label, value, sub, delta, loading = false, compact: compact3 = false, className = "", ...rest }) {
|
|
1606
|
-
return /* @__PURE__ */
|
|
1607
|
-
loading ? /* @__PURE__ */ jsx29("span", { className: "fd-skel fd-skel-text", style: { display: "block", height: compact3 ? 20 : 28, width: "62%" } }) : /* @__PURE__ */
|
|
1618
|
+
return /* @__PURE__ */ jsxs25("div", { className: ["fd-stat", compact3 ? "fd-stat-compact" : "", className].filter(Boolean).join(" "), ...rest, children: [
|
|
1619
|
+
loading ? /* @__PURE__ */ jsx29("span", { className: "fd-skel fd-skel-text", style: { display: "block", height: compact3 ? 20 : 28, width: "62%" } }) : /* @__PURE__ */ jsxs25("span", { className: "fd-stat-top", children: [
|
|
1608
1620
|
/* @__PURE__ */ jsx29("span", { className: "fd-stat-figure", children: value }),
|
|
1609
|
-
delta ? /* @__PURE__ */
|
|
1621
|
+
delta ? /* @__PURE__ */ jsxs25("span", { className: delta.startsWith("-") ? "fd-stat-delta-down" : "fd-stat-delta-up", style: { fontWeight: 600, fontSize: "var(--body-sm-size)", flex: "none" }, children: [
|
|
1610
1622
|
/* @__PURE__ */ jsx29("i", { className: "ph ph-arrow-" + (delta.startsWith("-") ? "down" : "up") + "-right", "aria-hidden": "true" }),
|
|
1611
1623
|
" ",
|
|
1612
1624
|
delta
|
|
@@ -1618,8 +1630,8 @@ function StatTile({ label, value, sub, delta, loading = false, compact: compact3
|
|
|
1618
1630
|
}
|
|
1619
1631
|
|
|
1620
1632
|
// src/components/data/CodeBlock.tsx
|
|
1621
|
-
import * as
|
|
1622
|
-
import { Fragment as Fragment5, jsx as jsx30, jsxs as
|
|
1633
|
+
import * as React10 from "react";
|
|
1634
|
+
import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1623
1635
|
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)$/;
|
|
1624
1636
|
var RULES = {
|
|
1625
1637
|
js: [
|
|
@@ -1774,13 +1786,13 @@ function tokenize(src, lang) {
|
|
|
1774
1786
|
return out;
|
|
1775
1787
|
}
|
|
1776
1788
|
function Highlighted({ code, lang }) {
|
|
1777
|
-
const toks =
|
|
1789
|
+
const toks = React10.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
1778
1790
|
return /* @__PURE__ */ jsx30(Fragment5, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx30("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
|
|
1779
1791
|
}
|
|
1780
1792
|
function useCopy() {
|
|
1781
|
-
const [done, setDone] =
|
|
1782
|
-
const timer =
|
|
1783
|
-
|
|
1793
|
+
const [done, setDone] = React10.useState(false);
|
|
1794
|
+
const timer = React10.useRef(null);
|
|
1795
|
+
React10.useEffect(() => () => {
|
|
1784
1796
|
if (timer.current) clearTimeout(timer.current);
|
|
1785
1797
|
}, []);
|
|
1786
1798
|
const copy = (text) => {
|
|
@@ -1816,37 +1828,37 @@ function CodeBlock({
|
|
|
1816
1828
|
actions,
|
|
1817
1829
|
className = ""
|
|
1818
1830
|
}) {
|
|
1819
|
-
const [wrap, setWrap] =
|
|
1820
|
-
const [open, setOpen] =
|
|
1831
|
+
const [wrap, setWrap] = React10.useState(!!wrapDefault);
|
|
1832
|
+
const [open, setOpen] = React10.useState(false);
|
|
1821
1833
|
const [copied, copy] = useCopy();
|
|
1822
1834
|
const body = String(code).replace(/\n$/, "");
|
|
1823
1835
|
const lines = body.split("\n");
|
|
1824
1836
|
const foldable = collapseAfter > 0 && lines.length > collapseAfter + 6;
|
|
1825
1837
|
const shown = foldable && !open ? lines.slice(0, collapseAfter).join("\n") : body;
|
|
1826
|
-
return /* @__PURE__ */
|
|
1827
|
-
/* @__PURE__ */
|
|
1838
|
+
return /* @__PURE__ */ jsxs26("div", { className: ["fd-code", wrap ? "is-wrap" : "", className].filter(Boolean).join(" "), children: [
|
|
1839
|
+
/* @__PURE__ */ jsxs26("div", { className: "fd-code-head", children: [
|
|
1828
1840
|
filename ? /* @__PURE__ */ jsx30("span", { className: "fd-code-file", children: filename }) : null,
|
|
1829
1841
|
/* @__PURE__ */ jsx30("span", { className: "fd-code-lang", children: languageLabel(language) }),
|
|
1830
1842
|
/* @__PURE__ */ jsx30("span", { className: "fd-code-spacer" }),
|
|
1831
1843
|
actions,
|
|
1832
1844
|
/* @__PURE__ */ jsx30("button", { type: "button", className: "fd-code-act", onClick: () => setWrap((v) => !v), "aria-pressed": wrap, title: wrap ? "No wrap" : "Soft wrap", children: /* @__PURE__ */ jsx30("i", { className: "ph ph-text-" + (wrap ? "columns" : "align-left"), "aria-hidden": "true" }) }),
|
|
1833
|
-
copyable ? /* @__PURE__ */
|
|
1845
|
+
copyable ? /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(body), children: [
|
|
1834
1846
|
/* @__PURE__ */ jsx30("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
|
|
1835
1847
|
/* @__PURE__ */ jsx30("span", { children: copied ? "Copied" : "Copy" })
|
|
1836
1848
|
] }) : null
|
|
1837
1849
|
] }),
|
|
1838
|
-
/* @__PURE__ */
|
|
1850
|
+
/* @__PURE__ */ jsxs26("div", { className: "fd-code-body", children: [
|
|
1839
1851
|
lineNumbers ? /* @__PURE__ */ jsx30("pre", { className: "fd-code-gutter", "aria-hidden": "true", children: shown.split("\n").map((_, i) => i + 1 + "\n").join("") }) : null,
|
|
1840
1852
|
/* @__PURE__ */ jsx30("pre", { className: "fd-code-pre", tabIndex: 0, children: /* @__PURE__ */ jsx30("code", { children: /* @__PURE__ */ jsx30(Highlighted, { code: shown, lang: language }) }) })
|
|
1841
1853
|
] }),
|
|
1842
|
-
foldable ? /* @__PURE__ */
|
|
1854
|
+
foldable ? /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
1843
1855
|
/* @__PURE__ */ jsx30("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
|
|
1844
1856
|
open ? "Collapse" : "Show all " + lines.length + " lines"
|
|
1845
1857
|
] }) : null
|
|
1846
1858
|
] });
|
|
1847
1859
|
}
|
|
1848
1860
|
function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
|
|
1849
|
-
const [open, setOpen] =
|
|
1861
|
+
const [open, setOpen] = React10.useState(false);
|
|
1850
1862
|
const [copied, copy] = useCopy();
|
|
1851
1863
|
const raw = String(diff).replace(/\n$/, "");
|
|
1852
1864
|
const all = raw.split("\n").map((line) => {
|
|
@@ -1860,31 +1872,31 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
1860
1872
|
const dels = all.filter((l) => l.k === "del").length;
|
|
1861
1873
|
const foldable = collapseAfter > 0 && all.length > collapseAfter + 6;
|
|
1862
1874
|
const rows = foldable && !open ? all.slice(0, collapseAfter) : all;
|
|
1863
|
-
return /* @__PURE__ */
|
|
1864
|
-
/* @__PURE__ */
|
|
1875
|
+
return /* @__PURE__ */ jsxs26("div", { className: ["fd-code", "fd-diff", className].filter(Boolean).join(" "), children: [
|
|
1876
|
+
/* @__PURE__ */ jsxs26("div", { className: "fd-code-head", children: [
|
|
1865
1877
|
/* @__PURE__ */ jsx30("i", { className: "ph ph-git-diff fd-code-icon", "aria-hidden": "true" }),
|
|
1866
1878
|
filename ? /* @__PURE__ */ jsx30("span", { className: "fd-code-file", children: filename }) : /* @__PURE__ */ jsx30("span", { className: "fd-code-lang", children: "Diff" }),
|
|
1867
|
-
/* @__PURE__ */
|
|
1868
|
-
/* @__PURE__ */
|
|
1879
|
+
/* @__PURE__ */ jsxs26("span", { className: "fd-diff-stat fd-tabular", children: [
|
|
1880
|
+
/* @__PURE__ */ jsxs26("span", { className: "is-add", children: [
|
|
1869
1881
|
"+",
|
|
1870
1882
|
adds
|
|
1871
1883
|
] }),
|
|
1872
|
-
/* @__PURE__ */
|
|
1884
|
+
/* @__PURE__ */ jsxs26("span", { className: "is-del", children: [
|
|
1873
1885
|
"\u2212",
|
|
1874
1886
|
dels
|
|
1875
1887
|
] })
|
|
1876
1888
|
] }),
|
|
1877
1889
|
/* @__PURE__ */ jsx30("span", { className: "fd-code-spacer" }),
|
|
1878
|
-
/* @__PURE__ */
|
|
1890
|
+
/* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(raw), children: [
|
|
1879
1891
|
/* @__PURE__ */ jsx30("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
|
|
1880
1892
|
/* @__PURE__ */ jsx30("span", { children: copied ? "Copied" : "Copy" })
|
|
1881
1893
|
] })
|
|
1882
1894
|
] }),
|
|
1883
|
-
/* @__PURE__ */ jsx30("div", { className: "fd-diff-body", children: rows.map((r, i) => /* @__PURE__ */
|
|
1895
|
+
/* @__PURE__ */ jsx30("div", { className: "fd-diff-body", children: rows.map((r, i) => /* @__PURE__ */ jsxs26("div", { className: "fd-diff-line is-" + r.k, children: [
|
|
1884
1896
|
/* @__PURE__ */ jsx30("span", { className: "fd-diff-mark", "aria-hidden": "true", children: r.k === "add" ? "+" : r.k === "del" ? "\u2212" : "" }),
|
|
1885
1897
|
/* @__PURE__ */ jsx30("code", { children: r.k === "add" || r.k === "del" ? r.line.slice(1) : r.line })
|
|
1886
1898
|
] }, i)) }),
|
|
1887
|
-
foldable ? /* @__PURE__ */
|
|
1899
|
+
foldable ? /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
1888
1900
|
/* @__PURE__ */ jsx30("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
|
|
1889
1901
|
open ? "Collapse" : "Show all " + all.length + " lines"
|
|
1890
1902
|
] }) : null
|
|
@@ -1892,8 +1904,8 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
1892
1904
|
}
|
|
1893
1905
|
|
|
1894
1906
|
// src/components/data/Markdown.tsx
|
|
1895
|
-
import * as
|
|
1896
|
-
import { jsx as jsx31, jsxs as
|
|
1907
|
+
import * as React11 from "react";
|
|
1908
|
+
import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
1897
1909
|
var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
|
|
1898
1910
|
var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
|
|
1899
1911
|
var INLINE = [
|
|
@@ -1931,7 +1943,7 @@ function inlineNodes(src, ctx, keyBase) {
|
|
|
1931
1943
|
const href = safeHref(g(2));
|
|
1932
1944
|
out.push(href ? /* @__PURE__ */ jsx31("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__ */ jsx31("span", { children: g(1) }, key()));
|
|
1933
1945
|
} else if (kind === "cite") {
|
|
1934
|
-
out.push(ctx.renderCitation ? /* @__PURE__ */ jsx31(
|
|
1946
|
+
out.push(ctx.renderCitation ? /* @__PURE__ */ jsx31(React11.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx31("sup", { className: "fd-md-cite", children: g(1) }, key()));
|
|
1935
1947
|
} else if (kind === "strongem") out.push(/* @__PURE__ */ jsx31("strong", { children: /* @__PURE__ */ jsx31("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
|
|
1936
1948
|
else if (kind === "strong") out.push(/* @__PURE__ */ jsx31("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
1937
1949
|
else if (kind === "em") out.push(/* @__PURE__ */ jsx31("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
@@ -2071,13 +2083,13 @@ function renderBlocks(blocks, ctx, path) {
|
|
|
2071
2083
|
case "list": {
|
|
2072
2084
|
const Tag2 = b.ordered ? "ol" : "ul";
|
|
2073
2085
|
const isTask = b.items.some((it) => it.checked != null);
|
|
2074
|
-
return /* @__PURE__ */ jsx31(Tag2, { className: "fd-md-list" + (isTask ? " is-task" : ""), start: b.ordered && b.start !== 1 ? b.start : void 0, children: b.items.map((it, j) => /* @__PURE__ */
|
|
2086
|
+
return /* @__PURE__ */ jsx31(Tag2, { className: "fd-md-list" + (isTask ? " is-task" : ""), start: b.ordered && b.start !== 1 ? b.start : void 0, children: b.items.map((it, j) => /* @__PURE__ */ jsxs27("li", { className: it.checked != null ? it.checked ? "is-done" : "is-todo" : void 0, children: [
|
|
2075
2087
|
it.checked != null ? /* @__PURE__ */ jsx31("span", { className: "fd-md-task", "aria-hidden": "true", children: /* @__PURE__ */ jsx31("i", { className: "ph ph-" + (it.checked ? "check-square" : "square") }) }) : null,
|
|
2076
2088
|
/* @__PURE__ */ jsx31("span", { className: "fd-md-li", children: renderBlocks(it.children, ctx, k + "-" + j) })
|
|
2077
2089
|
] }, k + "-" + j)) }, k);
|
|
2078
2090
|
}
|
|
2079
2091
|
case "table":
|
|
2080
|
-
return /* @__PURE__ */ jsx31("div", { className: "fd-md-tablewrap", children: /* @__PURE__ */
|
|
2092
|
+
return /* @__PURE__ */ jsx31("div", { className: "fd-md-tablewrap", children: /* @__PURE__ */ jsxs27("table", { className: "fd-md-table", children: [
|
|
2081
2093
|
/* @__PURE__ */ jsx31("thead", { children: /* @__PURE__ */ jsx31("tr", { children: b.head.map((c, j) => /* @__PURE__ */ jsx31("th", { style: { textAlign: b.align[j] || "left" }, children: inlineNodes(c, ctx, k + "h" + j) }, j)) }) }),
|
|
2082
2094
|
/* @__PURE__ */ jsx31("tbody", { children: b.rows.map((r, ri) => /* @__PURE__ */ jsx31("tr", { children: b.head.map((_, ci) => /* @__PURE__ */ jsx31("td", { style: { textAlign: b.align[ci] || "left" }, children: inlineNodes(r[ci] || "", ctx, k + ri + "c" + ci) }, ci)) }, ri)) })
|
|
2083
2095
|
] }) }, k);
|
|
@@ -2096,7 +2108,7 @@ function Markdown({
|
|
|
2096
2108
|
onLinkClick
|
|
2097
2109
|
}) {
|
|
2098
2110
|
const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
|
|
2099
|
-
const blocks =
|
|
2111
|
+
const blocks = React11.useMemo(() => parseBlocks(source), [source]);
|
|
2100
2112
|
return /* @__PURE__ */ jsx31("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
|
|
2101
2113
|
}
|
|
2102
2114
|
function MarkdownInline({ source = "", className = "", onLinkClick }) {
|
|
@@ -2107,13 +2119,13 @@ function markdownToText(src) {
|
|
|
2107
2119
|
}
|
|
2108
2120
|
|
|
2109
2121
|
// src/components/data/Meter.tsx
|
|
2110
|
-
import { jsx as jsx32, jsxs as
|
|
2122
|
+
import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2111
2123
|
function Meter({ segments = [], unallocated = 0, height = 8, label, legend = false, className = "" }) {
|
|
2112
2124
|
const total = segments.reduce((s, x) => s + x.value, 0) + unallocated;
|
|
2113
2125
|
const pct = (v) => total ? v / total * 100 : 0;
|
|
2114
|
-
return /* @__PURE__ */
|
|
2126
|
+
return /* @__PURE__ */ jsxs28("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 8 }, children: [
|
|
2115
2127
|
label ? /* @__PURE__ */ jsx32("span", { className: "fd-label-lg fd-secondary", children: label }) : null,
|
|
2116
|
-
/* @__PURE__ */
|
|
2128
|
+
/* @__PURE__ */ jsxs28("div", { className: "fd-meterbar", style: { height }, children: [
|
|
2117
2129
|
segments.map((s, i) => /* @__PURE__ */ jsx32(
|
|
2118
2130
|
"span",
|
|
2119
2131
|
{
|
|
@@ -2125,12 +2137,12 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
|
|
|
2125
2137
|
)),
|
|
2126
2138
|
unallocated > 0 ? /* @__PURE__ */ jsx32("span", { className: "fd-meterbar-seg fd-meterbar-unallocated", title: "Unallocated", style: { width: pct(unallocated) + "%" } }) : null
|
|
2127
2139
|
] }),
|
|
2128
|
-
legend ? /* @__PURE__ */
|
|
2129
|
-
segments.map((s, i) => /* @__PURE__ */
|
|
2140
|
+
legend ? /* @__PURE__ */ jsxs28("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap" }, children: [
|
|
2141
|
+
segments.map((s, i) => /* @__PURE__ */ jsxs28("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
|
|
2130
2142
|
/* @__PURE__ */ jsx32("span", { style: { width: 9, height: 9, borderRadius: 2, background: s.color || "var(--chart-" + (i % 8 + 1) + ")" } }),
|
|
2131
2143
|
s.label
|
|
2132
2144
|
] }, i)),
|
|
2133
|
-
unallocated > 0 ? /* @__PURE__ */
|
|
2145
|
+
unallocated > 0 ? /* @__PURE__ */ jsxs28("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
|
|
2134
2146
|
/* @__PURE__ */ jsx32("span", { className: "fd-meterbar-unallocated", style: { width: 9, height: 9, borderRadius: 2 } }),
|
|
2135
2147
|
"Unallocated"
|
|
2136
2148
|
] }) : null
|
|
@@ -2139,7 +2151,7 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
|
|
|
2139
2151
|
}
|
|
2140
2152
|
|
|
2141
2153
|
// src/components/data/Pagination.tsx
|
|
2142
|
-
import { Fragment as Fragment7, jsx as jsx33, jsxs as
|
|
2154
|
+
import { Fragment as Fragment7, jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2143
2155
|
function Pagination({
|
|
2144
2156
|
page = 1,
|
|
2145
2157
|
pageSize = 25,
|
|
@@ -2164,12 +2176,12 @@ function Pagination({
|
|
|
2164
2176
|
if (i === 1 || i === totalPages || Math.abs(i - page) <= span) nums.push(i);
|
|
2165
2177
|
else if (nums[nums.length - 1] !== "\u2026") nums.push("\u2026");
|
|
2166
2178
|
}
|
|
2167
|
-
return /* @__PURE__ */
|
|
2168
|
-
/* @__PURE__ */ jsx33("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ jsx33("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */
|
|
2179
|
+
return /* @__PURE__ */ jsxs29("div", { className: ["fd-pag", className].filter(Boolean).join(" "), ...rest, children: [
|
|
2180
|
+
/* @__PURE__ */ jsx33("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ jsx33("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */ jsxs29(Fragment7, { children: [
|
|
2169
2181
|
"No ",
|
|
2170
2182
|
unit
|
|
2171
|
-
] }) : /* @__PURE__ */
|
|
2172
|
-
/* @__PURE__ */
|
|
2183
|
+
] }) : /* @__PURE__ */ jsxs29(Fragment7, { children: [
|
|
2184
|
+
/* @__PURE__ */ jsxs29("strong", { children: [
|
|
2173
2185
|
from.toLocaleString(),
|
|
2174
2186
|
"\u2013",
|
|
2175
2187
|
to.toLocaleString()
|
|
@@ -2179,11 +2191,11 @@ function Pagination({
|
|
|
2179
2191
|
" ",
|
|
2180
2192
|
unit
|
|
2181
2193
|
] }) }),
|
|
2182
|
-
onPageSizeChange ? /* @__PURE__ */
|
|
2194
|
+
onPageSizeChange ? /* @__PURE__ */ jsxs29("label", { className: "fd-pag-size", children: [
|
|
2183
2195
|
/* @__PURE__ */ jsx33("span", { children: "Rows" }),
|
|
2184
2196
|
/* @__PURE__ */ jsx33("select", { value: pageSize, onChange: (e) => onPageSizeChange(Number(e.target.value)), "aria-label": "Rows per page", children: pageSizes.map((n) => /* @__PURE__ */ jsx33("option", { value: n, children: n }, n)) })
|
|
2185
2197
|
] }) : null,
|
|
2186
|
-
/* @__PURE__ */
|
|
2198
|
+
/* @__PURE__ */ jsxs29("span", { className: "fd-pag-nav", children: [
|
|
2187
2199
|
/* @__PURE__ */ jsx33("button", { type: "button", onClick: () => go(1), disabled: page <= 1, "aria-label": "First page", children: /* @__PURE__ */ jsx33("i", { className: "ph ph-caret-double-left" }) }),
|
|
2188
2200
|
/* @__PURE__ */ jsx33("button", { type: "button", onClick: () => go(page - 1), disabled: page <= 1, "aria-label": "Previous page", children: /* @__PURE__ */ jsx33("i", { className: "ph ph-caret-left" }) }),
|
|
2189
2201
|
nums.map((n, i) => n === "\u2026" ? /* @__PURE__ */ jsx33("span", { className: "fd-pag-gap", "aria-hidden": "true", children: "\u2026" }, "e" + i) : /* @__PURE__ */ jsx33(
|
|
@@ -2204,8 +2216,8 @@ function Pagination({
|
|
|
2204
2216
|
}
|
|
2205
2217
|
|
|
2206
2218
|
// src/components/data/RelativeTime.tsx
|
|
2207
|
-
import * as
|
|
2208
|
-
import { jsxs as
|
|
2219
|
+
import * as React12 from "react";
|
|
2220
|
+
import { jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2209
2221
|
var MIN = 6e4;
|
|
2210
2222
|
var HOUR = 36e5;
|
|
2211
2223
|
var DAY = 864e5;
|
|
@@ -2256,9 +2268,9 @@ function formatDuration(ms) {
|
|
|
2256
2268
|
return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
|
|
2257
2269
|
}
|
|
2258
2270
|
function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
|
|
2259
|
-
const [, force] =
|
|
2271
|
+
const [, force] = React12.useState(0);
|
|
2260
2272
|
const t = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
2261
|
-
|
|
2273
|
+
React12.useEffect(() => {
|
|
2262
2274
|
if (!refresh2 || !t || isNaN(t)) return;
|
|
2263
2275
|
const abs = Math.abs(t - Date.now());
|
|
2264
2276
|
if (abs > DAY) return;
|
|
@@ -2267,17 +2279,17 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
|
|
|
2267
2279
|
return () => clearInterval(id);
|
|
2268
2280
|
}, [t, refresh2]);
|
|
2269
2281
|
if (!t || isNaN(t)) return null;
|
|
2270
|
-
return /* @__PURE__ */
|
|
2282
|
+
return /* @__PURE__ */ jsxs30("time", { className, dateTime: new Date(t).toISOString(), title: formatAbsolute(new Date(t)), ...rest, children: [
|
|
2271
2283
|
prefix ? prefix + " " : "",
|
|
2272
2284
|
formatRelative(new Date(t))
|
|
2273
2285
|
] });
|
|
2274
2286
|
}
|
|
2275
2287
|
|
|
2276
2288
|
// src/components/data/ScoreMeter.tsx
|
|
2277
|
-
import * as
|
|
2289
|
+
import * as React14 from "react";
|
|
2278
2290
|
|
|
2279
2291
|
// src/components/data/SegmentedMeter.tsx
|
|
2280
|
-
import * as
|
|
2292
|
+
import * as React13 from "react";
|
|
2281
2293
|
|
|
2282
2294
|
// src/kits/files.ts
|
|
2283
2295
|
function formatBytes(n) {
|
|
@@ -2437,7 +2449,7 @@ var FileKit = {
|
|
|
2437
2449
|
};
|
|
2438
2450
|
|
|
2439
2451
|
// src/components/data/SegmentedMeter.tsx
|
|
2440
|
-
import { jsx as jsx34, jsxs as
|
|
2452
|
+
import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2441
2453
|
var VARIANT_FILL = {
|
|
2442
2454
|
brand: "var(--brand)",
|
|
2443
2455
|
neutral: "var(--n-400)",
|
|
@@ -2482,16 +2494,16 @@ function SegmentedMeter({
|
|
|
2482
2494
|
const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
|
|
2483
2495
|
const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
|
|
2484
2496
|
const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
|
|
2485
|
-
const generatedId =
|
|
2497
|
+
const generatedId = React13.useId();
|
|
2486
2498
|
const uid2 = id || generatedId;
|
|
2487
|
-
return /* @__PURE__ */
|
|
2488
|
-
label || showTotal ? /* @__PURE__ */
|
|
2499
|
+
return /* @__PURE__ */ jsxs31("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
|
|
2500
|
+
label || showTotal ? /* @__PURE__ */ jsxs31("div", { className: "fd-segmeter-head", children: [
|
|
2489
2501
|
label ? /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-label", id: uid2 + "-l", children: label }) : /* @__PURE__ */ jsx34("span", {}),
|
|
2490
|
-
showTotal ? /* @__PURE__ */
|
|
2502
|
+
showTotal ? /* @__PURE__ */ jsxs31("span", { className: "fd-segmeter-total fd-tabular", children: [
|
|
2491
2503
|
format(used),
|
|
2492
2504
|
/* @__PURE__ */ jsx34("span", { className: "fd-segmeter-sep", children: " / " }),
|
|
2493
2505
|
safeTotal ? format(safeTotal) : "\u2014",
|
|
2494
|
-
showPercent ? /* @__PURE__ */
|
|
2506
|
+
showPercent ? /* @__PURE__ */ jsxs31("span", { className: "fd-segmeter-pct", children: [
|
|
2495
2507
|
" (",
|
|
2496
2508
|
pct,
|
|
2497
2509
|
"%)"
|
|
@@ -2521,13 +2533,13 @@ function SegmentedMeter({
|
|
|
2521
2533
|
))
|
|
2522
2534
|
}
|
|
2523
2535
|
),
|
|
2524
|
-
legend ? /* @__PURE__ */
|
|
2525
|
-
items.map((s, i) => /* @__PURE__ */
|
|
2536
|
+
legend ? /* @__PURE__ */ jsxs31("ul", { className: "fd-segmeter-legend", children: [
|
|
2537
|
+
items.map((s, i) => /* @__PURE__ */ jsxs31("li", { children: [
|
|
2526
2538
|
/* @__PURE__ */ jsx34("span", { className: "fd-segmeter-dot", style: { background: fill(s, i) }, "aria-hidden": "true" }),
|
|
2527
2539
|
/* @__PURE__ */ jsx34("span", { className: "fd-segmeter-key", children: s.label }),
|
|
2528
2540
|
/* @__PURE__ */ jsx34("span", { className: "fd-segmeter-val fd-tabular", children: format(s.value) })
|
|
2529
2541
|
] }, s.id || s.label || i)),
|
|
2530
|
-
safeTotal && used < safeTotal ? /* @__PURE__ */
|
|
2542
|
+
safeTotal && used < safeTotal ? /* @__PURE__ */ jsxs31("li", { className: "is-remainder", children: [
|
|
2531
2543
|
/* @__PURE__ */ jsx34("span", { className: "fd-segmeter-dot is-empty", "aria-hidden": "true" }),
|
|
2532
2544
|
/* @__PURE__ */ jsx34("span", { className: "fd-segmeter-key", children: remainderLabel }),
|
|
2533
2545
|
/* @__PURE__ */ jsx34("span", { className: "fd-segmeter-val fd-tabular", children: format(safeTotal - used) })
|
|
@@ -2538,11 +2550,11 @@ function SegmentedMeter({
|
|
|
2538
2550
|
function QuotaRow({ label, percent = 0, note, tone, className = "" }) {
|
|
2539
2551
|
const p = Math.max(0, Math.min(100, Math.round(Number(percent) || 0)));
|
|
2540
2552
|
const auto = p >= 90 ? "danger" : p >= 70 ? "warn" : "brand";
|
|
2541
|
-
return /* @__PURE__ */
|
|
2542
|
-
/* @__PURE__ */
|
|
2553
|
+
return /* @__PURE__ */ jsxs31("div", { className: ["fd-quota", className].filter(Boolean).join(" "), children: [
|
|
2554
|
+
/* @__PURE__ */ jsxs31("div", { className: "fd-quota-head", children: [
|
|
2543
2555
|
/* @__PURE__ */ jsx34("span", { className: "fd-quota-label", children: label }),
|
|
2544
2556
|
note ? /* @__PURE__ */ jsx34("span", { className: "fd-quota-note", children: note }) : null,
|
|
2545
|
-
/* @__PURE__ */
|
|
2557
|
+
/* @__PURE__ */ jsxs31("span", { className: "fd-quota-pct fd-tabular", children: [
|
|
2546
2558
|
p,
|
|
2547
2559
|
"%"
|
|
2548
2560
|
] })
|
|
@@ -2552,7 +2564,7 @@ function QuotaRow({ label, percent = 0, note, tone, className = "" }) {
|
|
|
2552
2564
|
}
|
|
2553
2565
|
|
|
2554
2566
|
// src/components/data/ScoreMeter.tsx
|
|
2555
|
-
import { jsx as jsx35, jsxs as
|
|
2567
|
+
import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2556
2568
|
function ScoreMeter({
|
|
2557
2569
|
score,
|
|
2558
2570
|
segments,
|
|
@@ -2566,10 +2578,10 @@ function ScoreMeter({
|
|
|
2566
2578
|
breakdownWidth = 280,
|
|
2567
2579
|
className = ""
|
|
2568
2580
|
}) {
|
|
2569
|
-
const [open, setOpen] =
|
|
2570
|
-
const ref =
|
|
2581
|
+
const [open, setOpen] = React14.useState(false);
|
|
2582
|
+
const ref = React14.useRef(null);
|
|
2571
2583
|
const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
2572
|
-
const body = /* @__PURE__ */
|
|
2584
|
+
const body = /* @__PURE__ */ jsxs32(React14.Fragment, { children: [
|
|
2573
2585
|
/* @__PURE__ */ jsx35("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ jsx35(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
|
|
2574
2586
|
showScore ? /* @__PURE__ */ jsx35("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
|
|
2575
2587
|
] });
|
|
@@ -2588,7 +2600,7 @@ function ScoreMeter({
|
|
|
2588
2600
|
}
|
|
2589
2601
|
);
|
|
2590
2602
|
}
|
|
2591
|
-
return /* @__PURE__ */
|
|
2603
|
+
return /* @__PURE__ */ jsxs32(React14.Fragment, { children: [
|
|
2592
2604
|
/* @__PURE__ */ jsx35(
|
|
2593
2605
|
"button",
|
|
2594
2606
|
{
|
|
@@ -2619,12 +2631,14 @@ function ScoreMeter({
|
|
|
2619
2631
|
}
|
|
2620
2632
|
|
|
2621
2633
|
// src/components/data/SortMenu.tsx
|
|
2622
|
-
import * as
|
|
2623
|
-
import { jsx as jsx36, jsxs as
|
|
2634
|
+
import * as React15 from "react";
|
|
2635
|
+
import { jsx as jsx36, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2636
|
+
var SORT_MENU_BASE = 120;
|
|
2624
2637
|
function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", className = "", ...rest }) {
|
|
2625
|
-
const [open, setOpen] =
|
|
2626
|
-
const
|
|
2627
|
-
|
|
2638
|
+
const [open, setOpen] = React15.useState(false);
|
|
2639
|
+
const zIndex = useOverlayLayer(SORT_MENU_BASE);
|
|
2640
|
+
const ref = React15.useRef(null);
|
|
2641
|
+
React15.useEffect(() => {
|
|
2628
2642
|
if (!open) return;
|
|
2629
2643
|
const away = (e) => {
|
|
2630
2644
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -2666,28 +2680,28 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
|
|
|
2666
2680
|
}
|
|
2667
2681
|
);
|
|
2668
2682
|
};
|
|
2669
|
-
return /* @__PURE__ */
|
|
2670
|
-
/* @__PURE__ */
|
|
2683
|
+
return /* @__PURE__ */ jsxs33("span", { className, style: { position: "relative", display: "inline-flex" }, ref, ...rest, children: [
|
|
2684
|
+
/* @__PURE__ */ jsxs33(Button, { size, variant: "secondary", icon: dir === "asc" ? "sort-ascending" : "sort-descending", onClick: () => setOpen(!open), children: [
|
|
2671
2685
|
cur ? cur.label : "Unsorted",
|
|
2672
2686
|
/* @__PURE__ */ jsx36("i", { className: "ph ph-" + (dir === "asc" ? "arrow-up" : "arrow-down"), style: { fontSize: 12, marginLeft: 6, opacity: 0.75 } })
|
|
2673
2687
|
] }),
|
|
2674
|
-
open ? /* @__PURE__ */ jsx36("span", { className: "fd-view-enter", style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex
|
|
2688
|
+
open ? /* @__PURE__ */ jsx36(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx36("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__ */ jsxs33("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
2675
2689
|
/* @__PURE__ */ jsx36("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Sort by" }),
|
|
2676
2690
|
fields.map((f) => {
|
|
2677
2691
|
const active = cur && cur.key === f.key;
|
|
2678
|
-
return /* @__PURE__ */
|
|
2692
|
+
return /* @__PURE__ */ jsxs33("span", { className: "fd-row", style: { gap: 8, padding: "4px 8px", borderRadius: 7, background: active ? "var(--surface-brand)" : "transparent" }, children: [
|
|
2679
2693
|
/* @__PURE__ */ jsx36("span", { className: "fd-body-sm", style: { flex: 1, fontWeight: active ? 700 : 500, color: active ? "var(--text-on-surface-brand)" : "var(--text)" }, children: f.label }),
|
|
2680
2694
|
arrow(f, "asc"),
|
|
2681
2695
|
arrow(f, "desc")
|
|
2682
2696
|
] }, f.key);
|
|
2683
2697
|
})
|
|
2684
|
-
] }) }) : null
|
|
2698
|
+
] }) }) }) : null
|
|
2685
2699
|
] });
|
|
2686
2700
|
}
|
|
2687
2701
|
|
|
2688
2702
|
// src/components/data/StepList.tsx
|
|
2689
|
-
import * as
|
|
2690
|
-
import { jsx as jsx37, jsxs as
|
|
2703
|
+
import * as React16 from "react";
|
|
2704
|
+
import { jsx as jsx37, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2691
2705
|
var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
|
|
2692
2706
|
function StepList({
|
|
2693
2707
|
steps = [],
|
|
@@ -2699,9 +2713,9 @@ function StepList({
|
|
|
2699
2713
|
dense = false,
|
|
2700
2714
|
className = ""
|
|
2701
2715
|
}) {
|
|
2702
|
-
const [openState, setOpenState] =
|
|
2716
|
+
const [openState, setOpenState] = React16.useState(defaultOpen);
|
|
2703
2717
|
const open = openProp == null ? openState : openProp;
|
|
2704
|
-
const [expanded, setExpanded] =
|
|
2718
|
+
const [expanded, setExpanded] = React16.useState({});
|
|
2705
2719
|
if (!steps.length) return null;
|
|
2706
2720
|
const running = steps.some((s) => s.status === "running");
|
|
2707
2721
|
const failed = steps.filter((s) => s.status === "error").length;
|
|
@@ -2713,15 +2727,15 @@ function StepList({
|
|
|
2713
2727
|
if (openProp == null) setOpenState(next);
|
|
2714
2728
|
onToggle && onToggle(next);
|
|
2715
2729
|
};
|
|
2716
|
-
return /* @__PURE__ */
|
|
2717
|
-
/* @__PURE__ */
|
|
2730
|
+
return /* @__PURE__ */ jsxs34("div", { className: ["fd-steps", dense ? "is-dense" : "", open ? "is-open" : "", className].filter(Boolean).join(" "), children: [
|
|
2731
|
+
/* @__PURE__ */ jsxs34("button", { type: "button", className: "fd-steps-head", onClick: toggle, "aria-expanded": open, children: [
|
|
2718
2732
|
running ? /* @__PURE__ */ jsx37("span", { className: "fd-steps-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx37("i", { className: "ph ph-" + (failed ? "warning-circle" : "check-circle"), "aria-hidden": "true" }),
|
|
2719
2733
|
/* @__PURE__ */ jsx37("span", { className: "fd-steps-title", children: summary }),
|
|
2720
|
-
/* @__PURE__ */
|
|
2734
|
+
/* @__PURE__ */ jsxs34("span", { className: "fd-steps-count fd-tabular", children: [
|
|
2721
2735
|
steps.length,
|
|
2722
2736
|
" step",
|
|
2723
2737
|
steps.length === 1 ? "" : "s",
|
|
2724
|
-
failed ? /* @__PURE__ */
|
|
2738
|
+
failed ? /* @__PURE__ */ jsxs34("span", { className: "fd-steps-failed", children: [
|
|
2725
2739
|
" \xB7 ",
|
|
2726
2740
|
failed,
|
|
2727
2741
|
" failed"
|
|
@@ -2733,10 +2747,10 @@ function StepList({
|
|
|
2733
2747
|
const id = s.id || i;
|
|
2734
2748
|
const isOpen = !!expanded[id];
|
|
2735
2749
|
const icon = KIND_ICON[s.kind || ""] || "dot-outline";
|
|
2736
|
-
return /* @__PURE__ */
|
|
2737
|
-
/* @__PURE__ */
|
|
2750
|
+
return /* @__PURE__ */ jsxs34("li", { className: "fd-step is-" + (s.status || "ok"), children: [
|
|
2751
|
+
/* @__PURE__ */ jsxs34("div", { className: "fd-step-row", children: [
|
|
2738
2752
|
/* @__PURE__ */ jsx37("span", { className: "fd-step-icon", "aria-hidden": "true", children: s.status === "running" ? /* @__PURE__ */ jsx37("span", { className: "fd-steps-spin" }) : /* @__PURE__ */ jsx37("i", { className: "ph ph-" + icon }) }),
|
|
2739
|
-
s.detail ? /* @__PURE__ */
|
|
2753
|
+
s.detail ? /* @__PURE__ */ jsxs34(
|
|
2740
2754
|
"button",
|
|
2741
2755
|
{
|
|
2742
2756
|
type: "button",
|
|
@@ -2759,8 +2773,8 @@ function StepList({
|
|
|
2759
2773
|
}
|
|
2760
2774
|
|
|
2761
2775
|
// src/components/data/VirtualList.tsx
|
|
2762
|
-
import * as
|
|
2763
|
-
import { jsx as jsx38, jsxs as
|
|
2776
|
+
import * as React17 from "react";
|
|
2777
|
+
import { jsx as jsx38, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
2764
2778
|
var VIRTUAL_LIST_BUFFER_ROWS = 20;
|
|
2765
2779
|
var VIRTUAL_LIST_ROW_GAP = 6;
|
|
2766
2780
|
function computeVirtualWindow(opts) {
|
|
@@ -2811,35 +2825,35 @@ function VirtualList({
|
|
|
2811
2825
|
className = "",
|
|
2812
2826
|
style
|
|
2813
2827
|
}) {
|
|
2814
|
-
const [scrollTop, setScrollTop] =
|
|
2815
|
-
const loaded =
|
|
2828
|
+
const [scrollTop, setScrollTop] = React17.useState(0);
|
|
2829
|
+
const loaded = React17.useMemo(
|
|
2816
2830
|
() => ({ firstItemIndex, count: items.length }),
|
|
2817
2831
|
[firstItemIndex, items.length]
|
|
2818
2832
|
);
|
|
2819
2833
|
const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
|
|
2820
2834
|
const bandKey = firstItemIndex + ":" + items.length;
|
|
2821
|
-
const win =
|
|
2835
|
+
const win = React17.useMemo(
|
|
2822
2836
|
() => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
|
|
2823
2837
|
[scrollTop, height, itemHeight, total, loaded]
|
|
2824
2838
|
);
|
|
2825
|
-
const need =
|
|
2839
|
+
const need = React17.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
|
|
2826
2840
|
const wantStart = need.start && hasMore?.start !== false;
|
|
2827
2841
|
const wantEnd = need.end && hasMore?.end !== false;
|
|
2828
2842
|
const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
|
|
2829
2843
|
const askKey = bandKey + "@" + bucket2;
|
|
2830
|
-
const asked =
|
|
2831
|
-
|
|
2844
|
+
const asked = React17.useRef({ start: null, end: null });
|
|
2845
|
+
React17.useEffect(() => {
|
|
2832
2846
|
if (loading || !wantStart || asked.current.start === askKey) return;
|
|
2833
2847
|
asked.current.start = askKey;
|
|
2834
2848
|
onNeedMore("start", win);
|
|
2835
2849
|
}, [wantStart, loading, askKey, onNeedMore, win]);
|
|
2836
|
-
|
|
2850
|
+
React17.useEffect(() => {
|
|
2837
2851
|
if (loading || !wantEnd || asked.current.end === askKey) return;
|
|
2838
2852
|
asked.current.end = askKey;
|
|
2839
2853
|
onNeedMore("end", win);
|
|
2840
2854
|
}, [wantEnd, loading, askKey, onNeedMore, win]);
|
|
2841
|
-
const lastKeysRef =
|
|
2842
|
-
const newKeys =
|
|
2855
|
+
const lastKeysRef = React17.useRef(null);
|
|
2856
|
+
const newKeys = React17.useMemo(() => {
|
|
2843
2857
|
const prev = lastKeysRef.current;
|
|
2844
2858
|
if (!prev) return /* @__PURE__ */ new Set();
|
|
2845
2859
|
const fresh = /* @__PURE__ */ new Set();
|
|
@@ -2849,7 +2863,7 @@ function VirtualList({
|
|
|
2849
2863
|
}
|
|
2850
2864
|
return fresh;
|
|
2851
2865
|
}, [items]);
|
|
2852
|
-
|
|
2866
|
+
React17.useEffect(() => {
|
|
2853
2867
|
lastKeysRef.current = new Set(items.map(keyOf));
|
|
2854
2868
|
}, [items]);
|
|
2855
2869
|
const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
|
|
@@ -2873,8 +2887,8 @@ function VirtualList({
|
|
|
2873
2887
|
)
|
|
2874
2888
|
);
|
|
2875
2889
|
}
|
|
2876
|
-
return /* @__PURE__ */
|
|
2877
|
-
/* @__PURE__ */
|
|
2890
|
+
return /* @__PURE__ */ jsxs35("div", { className: ["fd-vlist-wrap", className].filter(Boolean).join(" "), style: { height, position: "relative", ...gapStyle, ...style }, children: [
|
|
2891
|
+
/* @__PURE__ */ jsxs35(
|
|
2878
2892
|
"div",
|
|
2879
2893
|
{
|
|
2880
2894
|
className: "fd-vlist fd-scrollbar",
|
|
@@ -2886,7 +2900,7 @@ function VirtualList({
|
|
|
2886
2900
|
]
|
|
2887
2901
|
}
|
|
2888
2902
|
),
|
|
2889
|
-
refreshing ? /* @__PURE__ */ jsx38("div", { className: "fd-vlist-refresh-scrim", children: /* @__PURE__ */
|
|
2903
|
+
refreshing ? /* @__PURE__ */ jsx38("div", { className: "fd-vlist-refresh-scrim", children: /* @__PURE__ */ jsxs35("div", { className: "fd-vlist-refresh-card", children: [
|
|
2890
2904
|
/* @__PURE__ */ jsx38("span", { className: "fd-spinner", "aria-hidden": "true" }),
|
|
2891
2905
|
/* @__PURE__ */ jsx38("span", { className: "fd-body-sm", children: refreshingLabel })
|
|
2892
2906
|
] }) }) : null
|
|
@@ -2894,8 +2908,8 @@ function VirtualList({
|
|
|
2894
2908
|
}
|
|
2895
2909
|
|
|
2896
2910
|
// src/components/data/EntityRow.tsx
|
|
2897
|
-
import * as
|
|
2898
|
-
import { jsx as jsx39, jsxs as
|
|
2911
|
+
import * as React18 from "react";
|
|
2912
|
+
import { jsx as jsx39, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
2899
2913
|
var ENTITY_ROW_METRIC_WIDTH = 74;
|
|
2900
2914
|
var METRIC_TONE_COLOR = {
|
|
2901
2915
|
default: "var(--text-2)",
|
|
@@ -2907,7 +2921,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
|
|
|
2907
2921
|
const key = m.id || m.label || i;
|
|
2908
2922
|
const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
|
|
2909
2923
|
const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
|
|
2910
|
-
const content = /* @__PURE__ */
|
|
2924
|
+
const content = /* @__PURE__ */ jsxs36(React18.Fragment, { children: [
|
|
2911
2925
|
m.icon ? /* @__PURE__ */ jsx39("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
|
|
2912
2926
|
/* @__PURE__ */ jsx39("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
|
|
2913
2927
|
/* @__PURE__ */ jsx39("span", { className: "fd-sr", children: " " + m.label })
|
|
@@ -2928,7 +2942,7 @@ function EntityRow({
|
|
|
2928
2942
|
className = ""
|
|
2929
2943
|
}) {
|
|
2930
2944
|
const hasStrip = metrics && metrics.length > 0 || accessory != null;
|
|
2931
|
-
return /* @__PURE__ */
|
|
2945
|
+
return /* @__PURE__ */ jsxs36(
|
|
2932
2946
|
"div",
|
|
2933
2947
|
{
|
|
2934
2948
|
onPointerDown,
|
|
@@ -2947,12 +2961,12 @@ function EntityRow({
|
|
|
2947
2961
|
},
|
|
2948
2962
|
children: [
|
|
2949
2963
|
draggable ? /* @__PURE__ */ jsx39("i", { className: "ph ph-dots-six-vertical", "aria-hidden": "true", style: { fontSize: 14, flex: "none", color: "var(--text-muted)" } }) : null,
|
|
2950
|
-
/* @__PURE__ */
|
|
2951
|
-
/* @__PURE__ */
|
|
2964
|
+
/* @__PURE__ */ jsxs36("span", { className: "fd-erow-body", children: [
|
|
2965
|
+
/* @__PURE__ */ jsxs36("span", { className: "fd-erow-titleline", children: [
|
|
2952
2966
|
/* @__PURE__ */ jsx39("span", { className: "fd-erow-title fd-body-sm", children: title }),
|
|
2953
2967
|
meta ? /* @__PURE__ */ jsx39("span", { className: "fd-erow-meta", children: meta }) : null
|
|
2954
2968
|
] }),
|
|
2955
|
-
hasStrip ? /* @__PURE__ */
|
|
2969
|
+
hasStrip ? /* @__PURE__ */ jsxs36("span", { className: "fd-erow-strip", children: [
|
|
2956
2970
|
metrics && metrics.length ? /* @__PURE__ */ jsx39(EntityRowMetrics, { metrics }) : null,
|
|
2957
2971
|
accessory ? /* @__PURE__ */ jsx39("span", { className: "fd-erow-accessory", children: accessory }) : null
|
|
2958
2972
|
] }) : null
|
|
@@ -2975,18 +2989,18 @@ function EntityRow({
|
|
|
2975
2989
|
}
|
|
2976
2990
|
|
|
2977
2991
|
// src/components/data/TransferList.tsx
|
|
2978
|
-
import * as
|
|
2992
|
+
import * as React20 from "react";
|
|
2979
2993
|
import { createPortal as createPortal4 } from "react-dom";
|
|
2980
2994
|
|
|
2981
2995
|
// src/components/forms/field.tsx
|
|
2982
|
-
import * as
|
|
2983
|
-
import { jsx as jsx40, jsxs as
|
|
2996
|
+
import * as React19 from "react";
|
|
2997
|
+
import { jsx as jsx40, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
2984
2998
|
function useFieldId(id) {
|
|
2985
|
-
const generated =
|
|
2999
|
+
const generated = React19.useId();
|
|
2986
3000
|
return id || generated;
|
|
2987
3001
|
}
|
|
2988
3002
|
function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
|
|
2989
|
-
return /* @__PURE__ */
|
|
3003
|
+
return /* @__PURE__ */ jsxs37("label", { className: "fd-field-label", htmlFor, id, onClick, children: [
|
|
2990
3004
|
children,
|
|
2991
3005
|
required ? /* @__PURE__ */ jsx40("span", { className: "fd-field-req", "aria-hidden": "true", children: "*" }) : null
|
|
2992
3006
|
] });
|
|
@@ -2998,7 +3012,7 @@ function useTriggerLabelling(label, id) {
|
|
|
2998
3012
|
}
|
|
2999
3013
|
|
|
3000
3014
|
// src/components/forms/Input.tsx
|
|
3001
|
-
import { jsx as jsx41, jsxs as
|
|
3015
|
+
import { jsx as jsx41, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3002
3016
|
function Input({
|
|
3003
3017
|
label,
|
|
3004
3018
|
help,
|
|
@@ -3025,16 +3039,16 @@ function Input({
|
|
|
3025
3039
|
disabled ? "fd-input-disabled" : "",
|
|
3026
3040
|
size === "lg" ? "fd-input-lg" : ""
|
|
3027
3041
|
].filter(Boolean).join(" ");
|
|
3028
|
-
return /* @__PURE__ */
|
|
3042
|
+
return /* @__PURE__ */ jsxs38("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
|
|
3029
3043
|
label ? /* @__PURE__ */ jsx41(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
|
|
3030
|
-
/* @__PURE__ */
|
|
3044
|
+
/* @__PURE__ */ jsxs38("div", { className: box, children: [
|
|
3031
3045
|
icon ? /* @__PURE__ */ jsx41("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx41("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) }) : null,
|
|
3032
3046
|
prefix ? /* @__PURE__ */ jsx41("span", { className: "fd-input-affix", children: prefix }) : null,
|
|
3033
3047
|
/* @__PURE__ */ jsx41("input", { id: fieldId, disabled, style: inputStyle, "aria-invalid": error ? "true" : void 0, ...rest }),
|
|
3034
3048
|
loading ? /* @__PURE__ */ jsx41("span", { className: "fd-spinner", style: { color: "var(--text-muted)" }, "aria-label": "Loading" }) : null,
|
|
3035
3049
|
suffix && !loading ? /* @__PURE__ */ jsx41("span", { className: "fd-input-affix", children: suffix }) : null
|
|
3036
3050
|
] }),
|
|
3037
|
-
error ? /* @__PURE__ */
|
|
3051
|
+
error ? /* @__PURE__ */ jsxs38("span", { className: "fd-field-error", children: [
|
|
3038
3052
|
/* @__PURE__ */ jsx41("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
3039
3053
|
error
|
|
3040
3054
|
] }) : help ? /* @__PURE__ */ jsx41("span", { className: "fd-field-help", children: help }) : null
|
|
@@ -3086,7 +3100,7 @@ function SearchField({
|
|
|
3086
3100
|
}
|
|
3087
3101
|
|
|
3088
3102
|
// src/components/data/TransferList.tsx
|
|
3089
|
-
import { jsx as jsx43, jsxs as
|
|
3103
|
+
import { jsx as jsx43, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3090
3104
|
var emptyHasMore = {};
|
|
3091
3105
|
var DRAG_THRESHOLD_PX = 5;
|
|
3092
3106
|
function TransferList({
|
|
@@ -3100,12 +3114,12 @@ function TransferList({
|
|
|
3100
3114
|
listHeight = 440,
|
|
3101
3115
|
className = ""
|
|
3102
3116
|
}) {
|
|
3103
|
-
const [drag, setDrag] =
|
|
3104
|
-
const [dragOverSide, setDragOverSide] =
|
|
3105
|
-
const dragRef =
|
|
3106
|
-
const armedRef =
|
|
3107
|
-
const sideRefs =
|
|
3108
|
-
const hitTestSide =
|
|
3117
|
+
const [drag, setDrag] = React20.useState(null);
|
|
3118
|
+
const [dragOverSide, setDragOverSide] = React20.useState(null);
|
|
3119
|
+
const dragRef = React20.useRef(null);
|
|
3120
|
+
const armedRef = React20.useRef(null);
|
|
3121
|
+
const sideRefs = React20.useRef({ left: null, right: null });
|
|
3122
|
+
const hitTestSide = React20.useCallback((x, y) => {
|
|
3109
3123
|
for (const side of ["left", "right"]) {
|
|
3110
3124
|
const el = sideRefs.current[side];
|
|
3111
3125
|
if (!el) continue;
|
|
@@ -3114,7 +3128,7 @@ function TransferList({
|
|
|
3114
3128
|
}
|
|
3115
3129
|
return null;
|
|
3116
3130
|
}, []);
|
|
3117
|
-
const findItem =
|
|
3131
|
+
const findItem = React20.useCallback(
|
|
3118
3132
|
(side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
|
|
3119
3133
|
[left.items, right.items, keyOf]
|
|
3120
3134
|
);
|
|
@@ -3136,7 +3150,7 @@ function TransferList({
|
|
|
3136
3150
|
height: rect.height
|
|
3137
3151
|
};
|
|
3138
3152
|
};
|
|
3139
|
-
|
|
3153
|
+
React20.useEffect(() => {
|
|
3140
3154
|
const onMovePointer = (e) => {
|
|
3141
3155
|
const armed = armedRef.current;
|
|
3142
3156
|
if (!armed || e.pointerId !== armed.pointerId) return;
|
|
@@ -3189,7 +3203,7 @@ function TransferList({
|
|
|
3189
3203
|
window.removeEventListener("pointercancel", endDrag);
|
|
3190
3204
|
};
|
|
3191
3205
|
}, [hitTestSide, findItem, onMove]);
|
|
3192
|
-
|
|
3206
|
+
React20.useEffect(() => {
|
|
3193
3207
|
if (!drag || typeof document === "undefined") return;
|
|
3194
3208
|
const prev = document.body.style.userSelect;
|
|
3195
3209
|
document.body.style.userSelect = "none";
|
|
@@ -3199,7 +3213,7 @@ function TransferList({
|
|
|
3199
3213
|
}, [drag]);
|
|
3200
3214
|
const renderSide = (side, cfg, opposite) => {
|
|
3201
3215
|
const showOverlay = drag != null && dragOverSide === side;
|
|
3202
|
-
return /* @__PURE__ */
|
|
3216
|
+
return /* @__PURE__ */ jsxs39(
|
|
3203
3217
|
"div",
|
|
3204
3218
|
{
|
|
3205
3219
|
ref: (el) => {
|
|
@@ -3207,12 +3221,12 @@ function TransferList({
|
|
|
3207
3221
|
},
|
|
3208
3222
|
className: ["fd-tlist-side", dragOverSide === side ? "is-drop-target" : ""].filter(Boolean).join(" "),
|
|
3209
3223
|
children: [
|
|
3210
|
-
cfg.label ? /* @__PURE__ */
|
|
3224
|
+
cfg.label ? /* @__PURE__ */ jsxs39("span", { className: "fd-overline fd-muted", children: [
|
|
3211
3225
|
cfg.label,
|
|
3212
3226
|
cfg.total != null ? " (" + cfg.total.toLocaleString() + ")" : ""
|
|
3213
3227
|
] }) : null,
|
|
3214
3228
|
cfg.header ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-header", children: cfg.header }) : null,
|
|
3215
|
-
/* @__PURE__ */
|
|
3229
|
+
/* @__PURE__ */ jsxs39("span", { className: "fd-row", style: { gap: 8 }, children: [
|
|
3216
3230
|
/* @__PURE__ */ jsx43(SearchField, { value: cfg.search, onChange: cfg.onSearchChange, placeholder: "Search", "aria-label": (cfg.label || side) + " search", style: { flex: 1 } }),
|
|
3217
3231
|
/* @__PURE__ */ jsx43(SortMenu, { fields: cfg.sortFields, sort: cfg.sort, onSort: cfg.onSort, align: side === "left" ? "left" : "right" })
|
|
3218
3232
|
] }),
|
|
@@ -3259,7 +3273,7 @@ function TransferList({
|
|
|
3259
3273
|
}
|
|
3260
3274
|
),
|
|
3261
3275
|
cfg.footer ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-footer", children: cfg.footer }) : null,
|
|
3262
|
-
showOverlay ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-drop-overlay", "aria-hidden": "true", children: /* @__PURE__ */
|
|
3276
|
+
showOverlay ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-drop-overlay", "aria-hidden": "true", children: /* @__PURE__ */ jsxs39("span", { className: "fd-tlist-drop-card", children: [
|
|
3263
3277
|
/* @__PURE__ */ jsx43("i", { className: "ph ph-tray-arrow-down", style: { fontSize: 18 }, "aria-hidden": "true" }),
|
|
3264
3278
|
/* @__PURE__ */ jsx43("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: cfg.dropLabel || "Drop here" + (cfg.label ? " \u2014 " + cfg.label : "") })
|
|
3265
3279
|
] }) }) : null
|
|
@@ -3267,8 +3281,8 @@ function TransferList({
|
|
|
3267
3281
|
}
|
|
3268
3282
|
);
|
|
3269
3283
|
};
|
|
3270
|
-
return /* @__PURE__ */
|
|
3271
|
-
/* @__PURE__ */
|
|
3284
|
+
return /* @__PURE__ */ jsxs39("div", { className: ["fd-tlist", className].filter(Boolean).join(" "), children: [
|
|
3285
|
+
/* @__PURE__ */ jsxs39("div", { className: "fd-tlist-panes", children: [
|
|
3272
3286
|
renderSide("left", left, "right"),
|
|
3273
3287
|
renderSide("right", right, "left")
|
|
3274
3288
|
] }),
|
|
@@ -3297,19 +3311,19 @@ function TransferList({
|
|
|
3297
3311
|
}
|
|
3298
3312
|
|
|
3299
3313
|
// src/components/forms/Checkbox.tsx
|
|
3300
|
-
import * as
|
|
3301
|
-
import { jsx as jsx44, jsxs as
|
|
3314
|
+
import * as React21 from "react";
|
|
3315
|
+
import { jsx as jsx44, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3302
3316
|
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
3303
|
-
const ref =
|
|
3304
|
-
|
|
3317
|
+
const ref = React21.useRef(null);
|
|
3318
|
+
React21.useEffect(() => {
|
|
3305
3319
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
3306
3320
|
}, [indeterminate]);
|
|
3307
|
-
return /* @__PURE__ */
|
|
3308
|
-
/* @__PURE__ */
|
|
3321
|
+
return /* @__PURE__ */ jsxs40("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
3322
|
+
/* @__PURE__ */ jsxs40("span", { className: "fd-choice-input", children: [
|
|
3309
3323
|
/* @__PURE__ */ jsx44("input", { ref, type: "checkbox", ...rest }),
|
|
3310
3324
|
/* @__PURE__ */ jsx44("span", { className: "fd-choice-box", "aria-hidden": "true", children: /* @__PURE__ */ jsx44("i", { className: indeterminate ? "ph ph-minus" : "ph ph-check" }) })
|
|
3311
3325
|
] }),
|
|
3312
|
-
/* @__PURE__ */
|
|
3326
|
+
/* @__PURE__ */ jsxs40("span", { className: "fd-choice-text", children: [
|
|
3313
3327
|
/* @__PURE__ */ jsx44("span", { className: "fd-choice-title", children: label }),
|
|
3314
3328
|
description ? /* @__PURE__ */ jsx44("span", { className: "fd-choice-desc", children: description }) : null
|
|
3315
3329
|
] })
|
|
@@ -3317,14 +3331,14 @@ function Checkbox({ label, description, card = false, indeterminate = false, cla
|
|
|
3317
3331
|
}
|
|
3318
3332
|
|
|
3319
3333
|
// src/components/forms/Radio.tsx
|
|
3320
|
-
import { jsx as jsx45, jsxs as
|
|
3334
|
+
import { jsx as jsx45, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
3321
3335
|
function Radio({ label, description, card = false, className = "", ...rest }) {
|
|
3322
|
-
return /* @__PURE__ */
|
|
3323
|
-
/* @__PURE__ */
|
|
3336
|
+
return /* @__PURE__ */ jsxs41("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
3337
|
+
/* @__PURE__ */ jsxs41("span", { className: "fd-choice-input", children: [
|
|
3324
3338
|
/* @__PURE__ */ jsx45("input", { type: "radio", ...rest }),
|
|
3325
3339
|
/* @__PURE__ */ jsx45("span", { className: "fd-choice-box fd-choice-box-round", "aria-hidden": "true", children: /* @__PURE__ */ jsx45("span", { className: "fd-choice-dot" }) })
|
|
3326
3340
|
] }),
|
|
3327
|
-
/* @__PURE__ */
|
|
3341
|
+
/* @__PURE__ */ jsxs41("span", { className: "fd-choice-text", children: [
|
|
3328
3342
|
/* @__PURE__ */ jsx45("span", { className: "fd-choice-title", children: label }),
|
|
3329
3343
|
description ? /* @__PURE__ */ jsx45("span", { className: "fd-choice-desc", children: description }) : null
|
|
3330
3344
|
] })
|
|
@@ -3332,12 +3346,12 @@ function Radio({ label, description, card = false, className = "", ...rest }) {
|
|
|
3332
3346
|
}
|
|
3333
3347
|
|
|
3334
3348
|
// src/components/forms/Switch.tsx
|
|
3335
|
-
import { jsx as jsx46, jsxs as
|
|
3349
|
+
import { jsx as jsx46, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
3336
3350
|
function Switch({ label, description, className = "", ...rest }) {
|
|
3337
|
-
return /* @__PURE__ */
|
|
3351
|
+
return /* @__PURE__ */ jsxs42("label", { className: ["fd-switch", className].filter(Boolean).join(" "), children: [
|
|
3338
3352
|
/* @__PURE__ */ jsx46("input", { type: "checkbox", role: "switch", ...rest }),
|
|
3339
3353
|
/* @__PURE__ */ jsx46("span", { className: "fd-switch-track", children: /* @__PURE__ */ jsx46("span", { className: "fd-switch-thumb" }) }),
|
|
3340
|
-
label ? /* @__PURE__ */
|
|
3354
|
+
label ? /* @__PURE__ */ jsxs42("span", { className: "fd-choice-text", children: [
|
|
3341
3355
|
/* @__PURE__ */ jsx46("span", { className: "fd-switch-label", children: label }),
|
|
3342
3356
|
description ? /* @__PURE__ */ jsx46("span", { className: "fd-choice-desc", children: description }) : null
|
|
3343
3357
|
] }) : null
|
|
@@ -3345,14 +3359,14 @@ function Switch({ label, description, className = "", ...rest }) {
|
|
|
3345
3359
|
}
|
|
3346
3360
|
|
|
3347
3361
|
// src/components/forms/Textarea.tsx
|
|
3348
|
-
import { jsx as jsx47, jsxs as
|
|
3362
|
+
import { jsx as jsx47, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
3349
3363
|
function Textarea({ label, help, error, required = false, rows = 4, disabled = false, id, className = "", style, ...rest }) {
|
|
3350
3364
|
const fieldId = useFieldId(id);
|
|
3351
3365
|
const box = ["fd-input", "fd-input-textarea", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
|
|
3352
|
-
return /* @__PURE__ */
|
|
3366
|
+
return /* @__PURE__ */ jsxs43("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
|
|
3353
3367
|
label ? /* @__PURE__ */ jsx47(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
|
|
3354
3368
|
/* @__PURE__ */ jsx47("div", { className: box, children: /* @__PURE__ */ jsx47("textarea", { id: fieldId, rows, disabled, "aria-invalid": error ? "true" : void 0, ...rest }) }),
|
|
3355
|
-
error ? /* @__PURE__ */
|
|
3369
|
+
error ? /* @__PURE__ */ jsxs43("span", { className: "fd-field-error", children: [
|
|
3356
3370
|
/* @__PURE__ */ jsx47("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
3357
3371
|
error
|
|
3358
3372
|
] }) : help ? /* @__PURE__ */ jsx47("span", { className: "fd-field-help", children: help }) : null
|
|
@@ -3360,8 +3374,8 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
|
|
|
3360
3374
|
}
|
|
3361
3375
|
|
|
3362
3376
|
// src/components/forms/NumberInput.tsx
|
|
3363
|
-
import * as
|
|
3364
|
-
import { jsx as jsx48, jsxs as
|
|
3377
|
+
import * as React22 from "react";
|
|
3378
|
+
import { jsx as jsx48, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
3365
3379
|
function NumberInput({
|
|
3366
3380
|
label,
|
|
3367
3381
|
help,
|
|
@@ -3388,10 +3402,10 @@ function NumberInput({
|
|
|
3388
3402
|
const n = Number(String(v == null ? "" : v).replace(/[^0-9.-]/g, ""));
|
|
3389
3403
|
return isNaN(n) ? null : n;
|
|
3390
3404
|
};
|
|
3391
|
-
const [text, setText] =
|
|
3392
|
-
const [editing, setEditing] =
|
|
3393
|
-
const timer =
|
|
3394
|
-
|
|
3405
|
+
const [text, setText] = React22.useState(value == null || value === "" ? "" : String(value));
|
|
3406
|
+
const [editing, setEditing] = React22.useState(false);
|
|
3407
|
+
const timer = React22.useRef(null);
|
|
3408
|
+
React22.useEffect(() => {
|
|
3395
3409
|
if (!editing) setText(value == null || value === "" ? "" : String(value));
|
|
3396
3410
|
}, [value, editing]);
|
|
3397
3411
|
const clamp = (n) => Math.min(max, Math.max(min, n));
|
|
@@ -3415,7 +3429,7 @@ function NumberInput({
|
|
|
3415
3429
|
const release = () => {
|
|
3416
3430
|
if (timer.current) clearTimeout(timer.current);
|
|
3417
3431
|
};
|
|
3418
|
-
|
|
3432
|
+
React22.useEffect(() => () => {
|
|
3419
3433
|
if (timer.current) clearTimeout(timer.current);
|
|
3420
3434
|
}, []);
|
|
3421
3435
|
const shown = editing ? text : (() => {
|
|
@@ -3425,9 +3439,9 @@ function NumberInput({
|
|
|
3425
3439
|
const box = ["fd-input", "fd-input-num", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
|
|
3426
3440
|
const fieldName = label || ariaLabel;
|
|
3427
3441
|
const stepperName = (verb) => fieldName ? verb + " " + fieldName : verb;
|
|
3428
|
-
return /* @__PURE__ */
|
|
3442
|
+
return /* @__PURE__ */ jsxs44("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
|
|
3429
3443
|
label ? /* @__PURE__ */ jsx48(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
|
|
3430
|
-
/* @__PURE__ */
|
|
3444
|
+
/* @__PURE__ */ jsxs44("div", { className: box, style: { gap: 8 }, children: [
|
|
3431
3445
|
prefix ? /* @__PURE__ */ jsx48("span", { className: "fd-input-affix", children: prefix }) : null,
|
|
3432
3446
|
/* @__PURE__ */ jsx48(
|
|
3433
3447
|
"input",
|
|
@@ -3465,7 +3479,7 @@ function NumberInput({
|
|
|
3465
3479
|
}
|
|
3466
3480
|
),
|
|
3467
3481
|
suffix ? /* @__PURE__ */ jsx48("span", { className: "fd-input-affix", children: suffix }) : null,
|
|
3468
|
-
/* @__PURE__ */
|
|
3482
|
+
/* @__PURE__ */ jsxs44("span", { className: "fd-row", style: { gap: 4, flex: "none" }, children: [
|
|
3469
3483
|
/* @__PURE__ */ jsx48(
|
|
3470
3484
|
"button",
|
|
3471
3485
|
{
|
|
@@ -3494,7 +3508,7 @@ function NumberInput({
|
|
|
3494
3508
|
)
|
|
3495
3509
|
] })
|
|
3496
3510
|
] }),
|
|
3497
|
-
error ? /* @__PURE__ */
|
|
3511
|
+
error ? /* @__PURE__ */ jsxs44("span", { className: "fd-field-error", children: [
|
|
3498
3512
|
/* @__PURE__ */ jsx48("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
3499
3513
|
error
|
|
3500
3514
|
] }) : help ? /* @__PURE__ */ jsx48("span", { className: "fd-field-help", children: help }) : null
|
|
@@ -3502,8 +3516,8 @@ function NumberInput({
|
|
|
3502
3516
|
}
|
|
3503
3517
|
|
|
3504
3518
|
// src/components/forms/Select.tsx
|
|
3505
|
-
import * as
|
|
3506
|
-
import { jsx as jsx49, jsxs as
|
|
3519
|
+
import * as React23 from "react";
|
|
3520
|
+
import { jsx as jsx49, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
3507
3521
|
var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
|
|
3508
3522
|
function Select({
|
|
3509
3523
|
label,
|
|
@@ -3529,13 +3543,13 @@ function Select({
|
|
|
3529
3543
|
const isOn = (v) => multiple ? vals.includes(v) : v === value;
|
|
3530
3544
|
const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
|
|
3531
3545
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
3532
|
-
const [open, setOpen] =
|
|
3533
|
-
const [q, setQ] =
|
|
3534
|
-
const [active, setActive] =
|
|
3535
|
-
const rootRef =
|
|
3536
|
-
const boxRef =
|
|
3537
|
-
const listRef =
|
|
3538
|
-
const typeBuf =
|
|
3546
|
+
const [open, setOpen] = React23.useState(false);
|
|
3547
|
+
const [q, setQ] = React23.useState("");
|
|
3548
|
+
const [active, setActive] = React23.useState(-1);
|
|
3549
|
+
const rootRef = React23.useRef(null);
|
|
3550
|
+
const boxRef = React23.useRef(null);
|
|
3551
|
+
const listRef = React23.useRef(null);
|
|
3552
|
+
const typeBuf = React23.useRef({ s: "", t: 0 });
|
|
3539
3553
|
const selected = multiple ? null : opts.find((o) => o.value === value);
|
|
3540
3554
|
const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
|
|
3541
3555
|
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;
|
|
@@ -3560,7 +3574,7 @@ function Select({
|
|
|
3560
3574
|
}
|
|
3561
3575
|
setOpen(!open);
|
|
3562
3576
|
};
|
|
3563
|
-
|
|
3577
|
+
React23.useEffect(() => {
|
|
3564
3578
|
if (!open || active < 0 || !listRef.current) return;
|
|
3565
3579
|
const el = listRef.current.querySelector('[data-i="' + active + '"]');
|
|
3566
3580
|
if (el) {
|
|
@@ -3613,10 +3627,10 @@ function Select({
|
|
|
3613
3627
|
else last.items.push({ o, i });
|
|
3614
3628
|
});
|
|
3615
3629
|
const box = ["fd-input", "fd-select", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
|
|
3616
|
-
return /* @__PURE__ */
|
|
3630
|
+
return /* @__PURE__ */ jsxs45("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
|
|
3617
3631
|
label ? /* @__PURE__ */ jsx49(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
|
|
3618
|
-
/* @__PURE__ */
|
|
3619
|
-
/* @__PURE__ */
|
|
3632
|
+
/* @__PURE__ */ jsxs45("div", { className: box, style: { cursor: disabled ? "not-allowed" : "pointer" }, ref: boxRef, children: [
|
|
3633
|
+
/* @__PURE__ */ jsxs45(
|
|
3620
3634
|
"button",
|
|
3621
3635
|
{
|
|
3622
3636
|
type: "button",
|
|
@@ -3664,7 +3678,7 @@ function Select({
|
|
|
3664
3678
|
minWidth: 260,
|
|
3665
3679
|
role: "presentation",
|
|
3666
3680
|
style: { maxWidth: 380 },
|
|
3667
|
-
header: hasSearch ? /* @__PURE__ */
|
|
3681
|
+
header: hasSearch ? /* @__PURE__ */ jsxs45("div", { className: "fd-pop-search", children: [
|
|
3668
3682
|
/* @__PURE__ */ jsx49("i", { className: "ph ph-magnifying-glass", style: { color: "var(--text-muted)", fontSize: 14 } }),
|
|
3669
3683
|
/* @__PURE__ */ jsx49(
|
|
3670
3684
|
"input",
|
|
@@ -3681,7 +3695,7 @@ function Select({
|
|
|
3681
3695
|
),
|
|
3682
3696
|
q ? /* @__PURE__ */ jsx49("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
|
|
3683
3697
|
] }) : void 0,
|
|
3684
|
-
footer: multiple ? /* @__PURE__ */
|
|
3698
|
+
footer: multiple ? /* @__PURE__ */ jsxs45(React23.Fragment, { children: [
|
|
3685
3699
|
/* @__PURE__ */ jsx49(
|
|
3686
3700
|
"button",
|
|
3687
3701
|
{
|
|
@@ -3692,7 +3706,7 @@ function Select({
|
|
|
3692
3706
|
}
|
|
3693
3707
|
),
|
|
3694
3708
|
/* @__PURE__ */ jsx49("span", { style: { flex: 1 } }),
|
|
3695
|
-
/* @__PURE__ */
|
|
3709
|
+
/* @__PURE__ */ jsxs45("span", { className: "fd-body-sm fd-muted", children: [
|
|
3696
3710
|
vals.length,
|
|
3697
3711
|
" of ",
|
|
3698
3712
|
opts.length
|
|
@@ -3708,13 +3722,13 @@ function Select({
|
|
|
3708
3722
|
}
|
|
3709
3723
|
)
|
|
3710
3724
|
] }) : void 0,
|
|
3711
|
-
children: /* @__PURE__ */ jsx49("div", { className: "fd-pop-list", role: "listbox", "aria-multiselectable": multiple || void 0, ref: listRef, children: visible.length === 0 ? /* @__PURE__ */
|
|
3725
|
+
children: /* @__PURE__ */ jsx49("div", { className: "fd-pop-list", role: "listbox", "aria-multiselectable": multiple || void 0, ref: listRef, children: visible.length === 0 ? /* @__PURE__ */ jsxs45("div", { className: "fd-pop-empty", children: [
|
|
3712
3726
|
'Nothing matches "',
|
|
3713
3727
|
q,
|
|
3714
3728
|
'".'
|
|
3715
|
-
] }) : groups.map((grp) => /* @__PURE__ */
|
|
3729
|
+
] }) : groups.map((grp) => /* @__PURE__ */ jsxs45(React23.Fragment, { children: [
|
|
3716
3730
|
grp.g ? /* @__PURE__ */ jsx49("div", { className: "fd-pop-group", children: grp.g }) : null,
|
|
3717
|
-
grp.items.map(({ o, i }) => /* @__PURE__ */
|
|
3731
|
+
grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs45(
|
|
3718
3732
|
"button",
|
|
3719
3733
|
{
|
|
3720
3734
|
type: "button",
|
|
@@ -3728,7 +3742,7 @@ function Select({
|
|
|
3728
3742
|
children: [
|
|
3729
3743
|
multiple ? /* @__PURE__ */ jsx49("span", { "aria-hidden": "true", style: { flex: "none", display: "grid", placeItems: "center", width: 16, height: 16, borderRadius: 4, border: "1.5px solid " + (isOn(o.value) ? "var(--brand)" : "var(--border-strong, var(--border))"), background: isOn(o.value) ? "var(--brand)" : "var(--surface)", color: "#fff" }, children: isOn(o.value) ? /* @__PURE__ */ jsx49("i", { className: "ph ph-check", style: { fontSize: 11 } }) : null }) : null,
|
|
3730
3744
|
o.icon ? /* @__PURE__ */ jsx49("span", { className: "fd-opt-icon", children: /* @__PURE__ */ jsx49("i", { className: "ph ph-" + o.icon }) }) : null,
|
|
3731
|
-
/* @__PURE__ */
|
|
3745
|
+
/* @__PURE__ */ jsxs45("span", { style: { flex: 1, minWidth: 0 }, children: [
|
|
3732
3746
|
/* @__PURE__ */ jsx49("span", { className: "fd-opt-label", children: o.label }),
|
|
3733
3747
|
o.description ? /* @__PURE__ */ jsx49("span", { className: "fd-opt-desc", children: o.description }) : null
|
|
3734
3748
|
] }),
|
|
@@ -3741,7 +3755,7 @@ function Select({
|
|
|
3741
3755
|
] }, grp.g || "_")) })
|
|
3742
3756
|
}
|
|
3743
3757
|
),
|
|
3744
|
-
error ? /* @__PURE__ */
|
|
3758
|
+
error ? /* @__PURE__ */ jsxs45("span", { className: "fd-field-error", children: [
|
|
3745
3759
|
/* @__PURE__ */ jsx49("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
3746
3760
|
error
|
|
3747
3761
|
] }) : help ? /* @__PURE__ */ jsx49("span", { className: "fd-field-help", children: help }) : null
|
|
@@ -3749,8 +3763,8 @@ function Select({
|
|
|
3749
3763
|
}
|
|
3750
3764
|
|
|
3751
3765
|
// src/components/forms/DatePicker.tsx
|
|
3752
|
-
import * as
|
|
3753
|
-
import { jsx as jsx50, jsxs as
|
|
3766
|
+
import * as React24 from "react";
|
|
3767
|
+
import { jsx as jsx50, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
3754
3768
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
3755
3769
|
var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
3756
3770
|
var iso = (d) => d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
|
|
@@ -3767,10 +3781,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3767
3781
|
const today = /* @__PURE__ */ new Date();
|
|
3768
3782
|
const sel = range ? value || {} : { start: value, end: value };
|
|
3769
3783
|
const anchor = parse(sel.start) || parse(initialMonth) || today;
|
|
3770
|
-
const [vy, setVy] =
|
|
3771
|
-
const [vm, setVm] =
|
|
3772
|
-
const [mode2, setMode] =
|
|
3773
|
-
const [hover, setHover] =
|
|
3784
|
+
const [vy, setVy] = React24.useState(anchor.getFullYear());
|
|
3785
|
+
const [vm, setVm] = React24.useState(anchor.getMonth());
|
|
3786
|
+
const [mode2, setMode] = React24.useState("days");
|
|
3787
|
+
const [hover, setHover] = React24.useState(null);
|
|
3774
3788
|
const s = parse(sel.start), e = parse(sel.end);
|
|
3775
3789
|
const hoverEnd = range && s && !e && hover ? parse(hover) : null;
|
|
3776
3790
|
const inRange = (d) => {
|
|
@@ -3807,7 +3821,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3807
3821
|
const startPad = new Date(y, m, 1).getDay();
|
|
3808
3822
|
const cells = [];
|
|
3809
3823
|
for (let i = 0; i < 42; i++) cells.push(new Date(y, m, i - startPad + 1));
|
|
3810
|
-
return /* @__PURE__ */
|
|
3824
|
+
return /* @__PURE__ */ jsxs46("div", { className: "fd-cal-grid", style: { width: months > 1 ? 252 : "auto", flex: "none" }, onMouseLeave: () => setHover(null), children: [
|
|
3811
3825
|
DOW.map((d) => /* @__PURE__ */ jsx50("span", { className: "fd-cal-dow", children: d }, d)),
|
|
3812
3826
|
cells.map((d, i) => /* @__PURE__ */ jsx50(
|
|
3813
3827
|
"button",
|
|
@@ -3823,17 +3837,17 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3823
3837
|
] });
|
|
3824
3838
|
};
|
|
3825
3839
|
const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
|
|
3826
|
-
return /* @__PURE__ */
|
|
3827
|
-
/* @__PURE__ */
|
|
3840
|
+
return /* @__PURE__ */ jsxs46("div", { className: "fd-cal", style: { width: months > 1 && mode2 === "days" ? "auto" : void 0 }, children: [
|
|
3841
|
+
/* @__PURE__ */ jsxs46("div", { className: "fd-cal-head", children: [
|
|
3828
3842
|
/* @__PURE__ */ jsx50("button", { type: "button", className: "fd-btn-icon", "aria-label": "Previous", onClick: () => mode2 === "years" ? setVy(vy - 12) : mode2 === "months" ? setVy(vy - 1) : nav(-1), children: /* @__PURE__ */ jsx50("i", { className: "ph ph-caret-left" }) }),
|
|
3829
|
-
/* @__PURE__ */
|
|
3843
|
+
/* @__PURE__ */ jsxs46("button", { type: "button", className: "fd-cal-title", onClick: () => setMode(mode2 === "days" ? "months" : mode2 === "months" ? "years" : "days"), children: [
|
|
3830
3844
|
mode2 === "days" ? MONTHS[vm] + " " + vy : mode2 === "months" ? vy : vy - 5 + " \u2013 " + (vy + 6),
|
|
3831
3845
|
/* @__PURE__ */ jsx50("i", { className: "ph ph-caret-down", style: { fontSize: 10, marginLeft: 6, color: "var(--text-muted)" } })
|
|
3832
3846
|
] }),
|
|
3833
3847
|
months > 1 && mode2 === "days" ? /* @__PURE__ */ jsx50("span", { className: "fd-cal-title", style: { cursor: "default", background: "none" }, children: MONTHS[nextM] + " " + nextY }) : null,
|
|
3834
3848
|
/* @__PURE__ */ jsx50("button", { type: "button", className: "fd-btn-icon", "aria-label": "Next", onClick: () => mode2 === "years" ? setVy(vy + 12) : mode2 === "months" ? setVy(vy + 1) : nav(1), children: /* @__PURE__ */ jsx50("i", { className: "ph ph-caret-right" }) })
|
|
3835
3849
|
] }),
|
|
3836
|
-
mode2 === "days" ? /* @__PURE__ */
|
|
3850
|
+
mode2 === "days" ? /* @__PURE__ */ jsxs46("div", { style: { display: "flex", gap: 18 }, children: [
|
|
3837
3851
|
monthGrid(vy, vm),
|
|
3838
3852
|
months > 1 ? monthGrid(nextY, nextM) : null
|
|
3839
3853
|
] }) : mode2 === "months" ? /* @__PURE__ */ jsx50("div", { className: "fd-cal-grid-months", children: MONTHS.map((m, i) => /* @__PURE__ */ jsx50(
|
|
@@ -3861,7 +3875,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3861
3875
|
},
|
|
3862
3876
|
y
|
|
3863
3877
|
)) }),
|
|
3864
|
-
/* @__PURE__ */
|
|
3878
|
+
/* @__PURE__ */ jsxs46("div", { className: "fd-cal-foot", children: [
|
|
3865
3879
|
/* @__PURE__ */ jsx50(
|
|
3866
3880
|
"button",
|
|
3867
3881
|
{
|
|
@@ -3877,7 +3891,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3877
3891
|
}
|
|
3878
3892
|
),
|
|
3879
3893
|
/* @__PURE__ */ jsx50("span", { style: { flex: 1 } }),
|
|
3880
|
-
range && sel.start ? /* @__PURE__ */
|
|
3894
|
+
range && sel.start ? /* @__PURE__ */ jsxs46("span", { className: "fd-body-sm fd-muted", children: [
|
|
3881
3895
|
fmt(sel.start),
|
|
3882
3896
|
sel.end ? " \u2192 " + fmt(sel.end) : " \u2192 pick an end"
|
|
3883
3897
|
] }) : null
|
|
@@ -3886,16 +3900,16 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3886
3900
|
}
|
|
3887
3901
|
function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, ...rest }) {
|
|
3888
3902
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
3889
|
-
const [open, setOpen] =
|
|
3890
|
-
const rootRef =
|
|
3891
|
-
const boxRef =
|
|
3903
|
+
const [open, setOpen] = React24.useState(false);
|
|
3904
|
+
const rootRef = React24.useRef(null);
|
|
3905
|
+
const boxRef = React24.useRef(null);
|
|
3892
3906
|
const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
|
|
3893
3907
|
const toggle = () => {
|
|
3894
3908
|
if (!disabled) setOpen(!open);
|
|
3895
3909
|
};
|
|
3896
|
-
return /* @__PURE__ */
|
|
3910
|
+
return /* @__PURE__ */ jsxs46("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
|
|
3897
3911
|
label ? /* @__PURE__ */ jsx50(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
|
|
3898
|
-
/* @__PURE__ */
|
|
3912
|
+
/* @__PURE__ */ jsxs46("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
|
|
3899
3913
|
/* @__PURE__ */ jsx50("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx50("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }) }),
|
|
3900
3914
|
/* @__PURE__ */ jsx50(
|
|
3901
3915
|
"button",
|
|
@@ -3942,7 +3956,7 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
|
|
|
3942
3956
|
)
|
|
3943
3957
|
}
|
|
3944
3958
|
),
|
|
3945
|
-
error ? /* @__PURE__ */
|
|
3959
|
+
error ? /* @__PURE__ */ jsxs46("span", { className: "fd-field-error", children: [
|
|
3946
3960
|
/* @__PURE__ */ jsx50("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
3947
3961
|
error
|
|
3948
3962
|
] }) : help ? /* @__PURE__ */ jsx50("span", { className: "fd-field-help", children: help }) : null
|
|
@@ -3950,8 +3964,8 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
|
|
|
3950
3964
|
}
|
|
3951
3965
|
|
|
3952
3966
|
// src/components/forms/TimePicker.tsx
|
|
3953
|
-
import * as
|
|
3954
|
-
import { jsx as jsx51, jsxs as
|
|
3967
|
+
import * as React25 from "react";
|
|
3968
|
+
import { jsx as jsx51, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
3955
3969
|
var pad = (n) => String(n).padStart(2, "0");
|
|
3956
3970
|
function ClockFace({ value = "09:00", onChange }) {
|
|
3957
3971
|
let [h24, m] = value.split(":").map(Number);
|
|
@@ -3959,9 +3973,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
3959
3973
|
if (isNaN(m)) m = 0;
|
|
3960
3974
|
const pm = h24 >= 12;
|
|
3961
3975
|
const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
|
|
3962
|
-
const [mode2, setMode] =
|
|
3963
|
-
const faceRef =
|
|
3964
|
-
const dragging =
|
|
3976
|
+
const [mode2, setMode] = React25.useState("h");
|
|
3977
|
+
const faceRef = React25.useRef(null);
|
|
3978
|
+
const dragging = React25.useRef(false);
|
|
3965
3979
|
const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
|
|
3966
3980
|
const R = 108, NR = 80;
|
|
3967
3981
|
const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
|
|
@@ -3996,8 +4010,8 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
3996
4010
|
};
|
|
3997
4011
|
const handAngle = mode2 === "h" ? h12 % 12 * 30 : m * 6;
|
|
3998
4012
|
const minuteOff = mode2 === "m" && m % 5 !== 0;
|
|
3999
|
-
return /* @__PURE__ */
|
|
4000
|
-
/* @__PURE__ */
|
|
4013
|
+
return /* @__PURE__ */ jsxs47("div", { style: { padding: "4px 14px 14px" }, children: [
|
|
4014
|
+
/* @__PURE__ */ jsxs47("div", { className: "fd-clock-digits", children: [
|
|
4001
4015
|
/* @__PURE__ */ jsx51("button", { type: "button", className: "fd-clock-digit" + (mode2 === "h" ? " is-active" : ""), onClick: () => setMode("h"), children: pad(h12) }),
|
|
4002
4016
|
/* @__PURE__ */ jsx51("span", { style: { fontSize: 24, fontWeight: 700, color: "var(--text-muted)" }, children: ":" }),
|
|
4003
4017
|
/* @__PURE__ */ jsx51("button", { type: "button", className: "fd-clock-digit" + (mode2 === "m" ? " is-active" : ""), onClick: () => setMode("m"), children: pad(m) }),
|
|
@@ -4012,7 +4026,7 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
4012
4026
|
ap
|
|
4013
4027
|
)) })
|
|
4014
4028
|
] }),
|
|
4015
|
-
/* @__PURE__ */
|
|
4029
|
+
/* @__PURE__ */ jsxs47("div", { className: "fd-clock", ref: faceRef, onPointerDown: down, onPointerMove: move, onPointerUp: upH, children: [
|
|
4016
4030
|
/* @__PURE__ */ jsx51("span", { className: "fd-clock-hand", style: { height: NR - (minuteOff ? 14 : 16), transform: "translateX(-50%) rotate(" + handAngle + "deg)", bottom: "50%" } }),
|
|
4017
4031
|
/* @__PURE__ */ jsx51("span", { className: "fd-clock-pivot" }),
|
|
4018
4032
|
minuteOff ? /* @__PURE__ */ jsx51("span", { style: { position: "absolute", left: "50%", top: "50%", width: 10, height: 10, margin: -5, borderRadius: "50%", border: "2px solid var(--brand)", background: "var(--surface)", transform: "rotate(" + handAngle + "deg) translateY(-" + (NR - 6) + "px)", transformOrigin: "center", pointerEvents: "none" } }) : null,
|
|
@@ -4034,9 +4048,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
4034
4048
|
}
|
|
4035
4049
|
function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
|
|
4036
4050
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
4037
|
-
const [open, setOpen] =
|
|
4038
|
-
const rootRef =
|
|
4039
|
-
const boxRef =
|
|
4051
|
+
const [open, setOpen] = React25.useState(false);
|
|
4052
|
+
const rootRef = React25.useRef(null);
|
|
4053
|
+
const boxRef = React25.useRef(null);
|
|
4040
4054
|
const disp = () => {
|
|
4041
4055
|
if (!value) return "";
|
|
4042
4056
|
const [h, m] = value.split(":").map(Number);
|
|
@@ -4045,9 +4059,9 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
4045
4059
|
const toggle = () => {
|
|
4046
4060
|
if (!disabled) setOpen(!open);
|
|
4047
4061
|
};
|
|
4048
|
-
return /* @__PURE__ */
|
|
4062
|
+
return /* @__PURE__ */ jsxs47("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
|
|
4049
4063
|
label ? /* @__PURE__ */ jsx51(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
|
|
4050
|
-
/* @__PURE__ */
|
|
4064
|
+
/* @__PURE__ */ jsxs47("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
|
|
4051
4065
|
/* @__PURE__ */ jsx51("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx51("i", { className: "ph ph-clock", "aria-hidden": "true" }) }),
|
|
4052
4066
|
/* @__PURE__ */ jsx51(
|
|
4053
4067
|
"button",
|
|
@@ -4079,7 +4093,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
4079
4093
|
offset: 6,
|
|
4080
4094
|
width: 262,
|
|
4081
4095
|
role: "presentation",
|
|
4082
|
-
footer: /* @__PURE__ */
|
|
4096
|
+
footer: /* @__PURE__ */ jsxs47(React25.Fragment, { children: [
|
|
4083
4097
|
/* @__PURE__ */ jsx51(
|
|
4084
4098
|
"button",
|
|
4085
4099
|
{
|
|
@@ -4099,7 +4113,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
4099
4113
|
children: /* @__PURE__ */ jsx51(ClockFace, { value: value || "09:00", onChange: (v) => onChange && onChange({ target: { value: v } }) })
|
|
4100
4114
|
}
|
|
4101
4115
|
),
|
|
4102
|
-
error ? /* @__PURE__ */
|
|
4116
|
+
error ? /* @__PURE__ */ jsxs47("span", { className: "fd-field-error", children: [
|
|
4103
4117
|
/* @__PURE__ */ jsx51("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
4104
4118
|
error
|
|
4105
4119
|
] }) : help ? /* @__PURE__ */ jsx51("span", { className: "fd-field-help", children: help }) : null
|
|
@@ -4107,8 +4121,8 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
4107
4121
|
}
|
|
4108
4122
|
|
|
4109
4123
|
// src/components/forms/Slider.tsx
|
|
4110
|
-
import * as
|
|
4111
|
-
import { jsx as jsx52, jsxs as
|
|
4124
|
+
import * as React26 from "react";
|
|
4125
|
+
import { jsx as jsx52, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
4112
4126
|
function Slider({
|
|
4113
4127
|
label,
|
|
4114
4128
|
min = 0,
|
|
@@ -4125,15 +4139,15 @@ function Slider({
|
|
|
4125
4139
|
...rest
|
|
4126
4140
|
}) {
|
|
4127
4141
|
const fieldId = useFieldId(id);
|
|
4128
|
-
const [dragging, setDragging] =
|
|
4142
|
+
const [dragging, setDragging] = React26.useState(false);
|
|
4129
4143
|
const v = value === void 0 ? min : Number(value);
|
|
4130
4144
|
const pct = max === min ? 0 : (v - min) / (max - min) * 100;
|
|
4131
|
-
return /* @__PURE__ */
|
|
4132
|
-
label ? /* @__PURE__ */
|
|
4145
|
+
return /* @__PURE__ */ jsxs48("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
|
|
4146
|
+
label ? /* @__PURE__ */ jsxs48("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
|
|
4133
4147
|
/* @__PURE__ */ jsx52(FieldLabel, { htmlFor: fieldId, children: label }),
|
|
4134
4148
|
/* @__PURE__ */ jsx52("span", { className: "fd-num", style: { color: "var(--text-2)" }, children: format(v) })
|
|
4135
4149
|
] }) : null,
|
|
4136
|
-
/* @__PURE__ */
|
|
4150
|
+
/* @__PURE__ */ jsxs48("div", { className: "fd-slider", children: [
|
|
4137
4151
|
/* @__PURE__ */ jsx52("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
|
|
4138
4152
|
showChip && dragging ? /* @__PURE__ */ jsx52("span", { className: "fd-slider-chip", style: { left: pct + "%" }, children: format(v) }) : null,
|
|
4139
4153
|
/* @__PURE__ */ jsx52(
|
|
@@ -4159,8 +4173,8 @@ function Slider({
|
|
|
4159
4173
|
}
|
|
4160
4174
|
|
|
4161
4175
|
// src/components/forms/RangeSlider.tsx
|
|
4162
|
-
import * as
|
|
4163
|
-
import { jsx as jsx53, jsxs as
|
|
4176
|
+
import * as React27 from "react";
|
|
4177
|
+
import { jsx as jsx53, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
4164
4178
|
function RangeSlider({
|
|
4165
4179
|
label,
|
|
4166
4180
|
min = 0,
|
|
@@ -4179,9 +4193,9 @@ function RangeSlider({
|
|
|
4179
4193
|
}) {
|
|
4180
4194
|
const fmt2 = format || ((v) => String(v));
|
|
4181
4195
|
const [a, b] = value || [min, max];
|
|
4182
|
-
const [drag, setDrag] =
|
|
4183
|
-
const [focus, setFocus] =
|
|
4184
|
-
const railRef =
|
|
4196
|
+
const [drag, setDrag] = React27.useState(null);
|
|
4197
|
+
const [focus, setFocus] = React27.useState(null);
|
|
4198
|
+
const railRef = React27.useRef(null);
|
|
4185
4199
|
const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
|
|
4186
4200
|
const clampPair = (i, v) => {
|
|
4187
4201
|
v = Math.min(max, Math.max(min, Math.round(v / step) * step));
|
|
@@ -4196,7 +4210,7 @@ function RangeSlider({
|
|
|
4196
4210
|
const r = railRef.current.getBoundingClientRect();
|
|
4197
4211
|
return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
|
|
4198
4212
|
};
|
|
4199
|
-
|
|
4213
|
+
React27.useEffect(() => {
|
|
4200
4214
|
if (drag === null) return;
|
|
4201
4215
|
const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
|
|
4202
4216
|
const upH = () => setDrag(null);
|
|
@@ -4265,19 +4279,19 @@ function RangeSlider({
|
|
|
4265
4279
|
};
|
|
4266
4280
|
const showChip = (i) => drag === i || focus === i;
|
|
4267
4281
|
const hasLabels = marks.some((m) => m.label);
|
|
4268
|
-
return /* @__PURE__ */
|
|
4269
|
-
label ? /* @__PURE__ */
|
|
4282
|
+
return /* @__PURE__ */ jsxs49("div", { className: ["fd-field", className].filter(Boolean).join(" "), ...rest, children: [
|
|
4283
|
+
label ? /* @__PURE__ */ jsxs49("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
|
|
4270
4284
|
/* @__PURE__ */ jsx53("span", { className: "fd-field-label", children: label }),
|
|
4271
|
-
/* @__PURE__ */
|
|
4285
|
+
/* @__PURE__ */ jsxs49("span", { className: "fd-num", style: { color: "var(--text-2)" }, children: [
|
|
4272
4286
|
fmt2(a),
|
|
4273
4287
|
" \u2013 ",
|
|
4274
4288
|
fmt2(b)
|
|
4275
4289
|
] })
|
|
4276
4290
|
] }) : null,
|
|
4277
|
-
/* @__PURE__ */
|
|
4291
|
+
/* @__PURE__ */ jsxs49("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
|
|
4278
4292
|
/* @__PURE__ */ jsx53("span", { className: "fd-range-rail", ref: railRef }),
|
|
4279
4293
|
/* @__PURE__ */ jsx53("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
|
|
4280
|
-
marks.map((m) => /* @__PURE__ */
|
|
4294
|
+
marks.map((m) => /* @__PURE__ */ jsxs49(React27.Fragment, { children: [
|
|
4281
4295
|
/* @__PURE__ */ jsx53("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
|
|
4282
4296
|
m.label ? /* @__PURE__ */ jsx53("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
|
|
4283
4297
|
] }, m.value)),
|
|
@@ -4306,8 +4320,8 @@ function RangeSlider({
|
|
|
4306
4320
|
}
|
|
4307
4321
|
|
|
4308
4322
|
// src/components/forms/Dropzone.tsx
|
|
4309
|
-
import * as
|
|
4310
|
-
import { jsx as jsx54, jsxs as
|
|
4323
|
+
import * as React28 from "react";
|
|
4324
|
+
import { jsx as jsx54, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
4311
4325
|
function Dropzone({
|
|
4312
4326
|
onFiles,
|
|
4313
4327
|
onReject,
|
|
@@ -4321,8 +4335,8 @@ function Dropzone({
|
|
|
4321
4335
|
className = "",
|
|
4322
4336
|
style
|
|
4323
4337
|
}) {
|
|
4324
|
-
const [over, setOver] =
|
|
4325
|
-
const depth =
|
|
4338
|
+
const [over, setOver] = React28.useState(false);
|
|
4339
|
+
const depth = React28.useRef(0);
|
|
4326
4340
|
const has = (e) => {
|
|
4327
4341
|
const dt = e.dataTransfer;
|
|
4328
4342
|
if (!dt) return false;
|
|
@@ -4352,7 +4366,7 @@ function Dropzone({
|
|
|
4352
4366
|
if (rejected.length && onReject) onReject(rejected);
|
|
4353
4367
|
if (accepted.length && onFiles) onFiles(accepted);
|
|
4354
4368
|
};
|
|
4355
|
-
return /* @__PURE__ */
|
|
4369
|
+
return /* @__PURE__ */ jsxs50(
|
|
4356
4370
|
"div",
|
|
4357
4371
|
{
|
|
4358
4372
|
className: ["fd-dropzone", over ? "is-over" : "", className].filter(Boolean).join(" "),
|
|
@@ -4363,7 +4377,7 @@ function Dropzone({
|
|
|
4363
4377
|
onDrop: drop,
|
|
4364
4378
|
children: [
|
|
4365
4379
|
children,
|
|
4366
|
-
over ? /* @__PURE__ */ jsx54("div", { className: "fd-dropzone-veil", "aria-hidden": "true", children: /* @__PURE__ */
|
|
4380
|
+
over ? /* @__PURE__ */ jsx54("div", { className: "fd-dropzone-veil", "aria-hidden": "true", children: /* @__PURE__ */ jsxs50("div", { className: "fd-dropzone-card", children: [
|
|
4367
4381
|
/* @__PURE__ */ jsx54("i", { className: "ph ph-tray-arrow-down" }),
|
|
4368
4382
|
/* @__PURE__ */ jsx54("span", { className: "fd-dropzone-label", children: label }),
|
|
4369
4383
|
hint ? /* @__PURE__ */ jsx54("span", { className: "fd-dropzone-hint", children: hint }) : null
|
|
@@ -4384,8 +4398,8 @@ function FilePickButton({
|
|
|
4384
4398
|
className = "",
|
|
4385
4399
|
children
|
|
4386
4400
|
}) {
|
|
4387
|
-
const ref =
|
|
4388
|
-
return /* @__PURE__ */
|
|
4401
|
+
const ref = React28.useRef(null);
|
|
4402
|
+
return /* @__PURE__ */ jsxs50(React28.Fragment, { children: [
|
|
4389
4403
|
/* @__PURE__ */ jsx54(
|
|
4390
4404
|
"button",
|
|
4391
4405
|
{
|
|
@@ -4418,10 +4432,10 @@ function FilePickButton({
|
|
|
4418
4432
|
}
|
|
4419
4433
|
function useStagedFiles(upload, opts) {
|
|
4420
4434
|
const o = opts || {};
|
|
4421
|
-
const [items, setItems] =
|
|
4422
|
-
const controllers =
|
|
4435
|
+
const [items, setItems] = React28.useState([]);
|
|
4436
|
+
const controllers = React28.useRef({});
|
|
4423
4437
|
const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
|
|
4424
|
-
const run =
|
|
4438
|
+
const run = React28.useCallback((att) => {
|
|
4425
4439
|
if (!upload) return;
|
|
4426
4440
|
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
4427
4441
|
controllers.current[att.id] = ac;
|
|
@@ -4438,14 +4452,14 @@ function useStagedFiles(upload, opts) {
|
|
|
4438
4452
|
delete controllers.current[att.id];
|
|
4439
4453
|
});
|
|
4440
4454
|
}, [upload]);
|
|
4441
|
-
const add =
|
|
4455
|
+
const add = React28.useCallback((files) => {
|
|
4442
4456
|
if (!upload) return [];
|
|
4443
4457
|
const atts = Array.from(files).map((f) => toAttachment(f));
|
|
4444
4458
|
setItems((list) => list.concat(atts));
|
|
4445
4459
|
atts.forEach(run);
|
|
4446
4460
|
return atts;
|
|
4447
4461
|
}, [upload, run]);
|
|
4448
|
-
const remove =
|
|
4462
|
+
const remove = React28.useCallback((att) => {
|
|
4449
4463
|
const ac = controllers.current[att.id];
|
|
4450
4464
|
if (ac) {
|
|
4451
4465
|
try {
|
|
@@ -4456,10 +4470,10 @@ function useStagedFiles(upload, opts) {
|
|
|
4456
4470
|
}
|
|
4457
4471
|
setItems((list) => list.filter((f) => f.id !== att.id));
|
|
4458
4472
|
}, []);
|
|
4459
|
-
const retry =
|
|
4473
|
+
const retry = React28.useCallback((att) => {
|
|
4460
4474
|
run(att);
|
|
4461
4475
|
}, [run]);
|
|
4462
|
-
const clear =
|
|
4476
|
+
const clear = React28.useCallback(() => {
|
|
4463
4477
|
Object.values(controllers.current).forEach((ac) => {
|
|
4464
4478
|
try {
|
|
4465
4479
|
ac && ac.abort();
|
|
@@ -4475,7 +4489,7 @@ function useStagedFiles(upload, opts) {
|
|
|
4475
4489
|
var DropzoneKit = { useStagedFiles };
|
|
4476
4490
|
|
|
4477
4491
|
// src/components/forms/FileGrid.tsx
|
|
4478
|
-
import { jsx as jsx55, jsxs as
|
|
4492
|
+
import { jsx as jsx55, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
4479
4493
|
var truncateMiddle = (name, max = 34) => {
|
|
4480
4494
|
if (!name || name.length <= max) return name;
|
|
4481
4495
|
const ext = /\.[A-Za-z0-9]+$/.exec(name);
|
|
@@ -4493,8 +4507,8 @@ function FileChip({ file, onOpen, onRemove, onRetry, compact: compact3 = false,
|
|
|
4493
4507
|
const thumb = file.thumb && file.thumb.url || (image ? file.blobUrl || file.url : null);
|
|
4494
4508
|
const meta = file.meta || (file.size ? formatBytes(file.size) : "");
|
|
4495
4509
|
const clickable = !!onOpen && !uploading;
|
|
4496
|
-
return /* @__PURE__ */
|
|
4497
|
-
/* @__PURE__ */
|
|
4510
|
+
return /* @__PURE__ */ jsxs51("div", { className: ["fd-file", compact3 ? "is-compact" : "", file.error ? "is-error" : "", uploading ? "is-uploading" : "", className].filter(Boolean).join(" "), children: [
|
|
4511
|
+
/* @__PURE__ */ jsxs51(
|
|
4498
4512
|
"button",
|
|
4499
4513
|
{
|
|
4500
4514
|
type: "button",
|
|
@@ -4503,16 +4517,16 @@ function FileChip({ file, onOpen, onRemove, onRetry, compact: compact3 = false,
|
|
|
4503
4517
|
onClick: clickable ? () => onOpen(file) : void 0,
|
|
4504
4518
|
title: file.name + (meta ? " \xB7 " + meta : ""),
|
|
4505
4519
|
children: [
|
|
4506
|
-
/* @__PURE__ */
|
|
4520
|
+
/* @__PURE__ */ jsxs51("span", { className: "fd-file-icon", children: [
|
|
4507
4521
|
thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }),
|
|
4508
4522
|
(file.mime || "").startsWith("video/") ? /* @__PURE__ */ jsx55("i", { className: "ph ph-play fd-file-play", "aria-hidden": "true" }) : null
|
|
4509
4523
|
] }),
|
|
4510
|
-
/* @__PURE__ */
|
|
4524
|
+
/* @__PURE__ */ jsxs51("span", { className: "fd-file-text", children: [
|
|
4511
4525
|
/* @__PURE__ */ jsx55("span", { className: "fd-file-name", children: truncateMiddle(file.name, compact3 ? 26 : 40) }),
|
|
4512
|
-
/* @__PURE__ */ jsx55("span", { className: "fd-file-meta", children: file.error ? /* @__PURE__ */
|
|
4526
|
+
/* @__PURE__ */ jsx55("span", { className: "fd-file-meta", children: file.error ? /* @__PURE__ */ jsxs51("span", { className: "fd-file-err", children: [
|
|
4513
4527
|
/* @__PURE__ */ jsx55("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
4514
4528
|
file.error
|
|
4515
|
-
] }) : uploading ? /* @__PURE__ */
|
|
4529
|
+
] }) : uploading ? /* @__PURE__ */ jsxs51("span", { className: "fd-tabular", children: [
|
|
4516
4530
|
Math.round(file.progress),
|
|
4517
4531
|
"% uploaded"
|
|
4518
4532
|
] }) : meta })
|
|
@@ -4529,10 +4543,10 @@ function FileTile({ file, onOpen, onRemove, maxHeight = 200, className = "" }) {
|
|
|
4529
4543
|
if (!file) return null;
|
|
4530
4544
|
const src = file.thumb && file.thumb.url || file.blobUrl || file.url;
|
|
4531
4545
|
const uploading = file.progress != null && file.progress < 100 && !file.error;
|
|
4532
|
-
return /* @__PURE__ */
|
|
4546
|
+
return /* @__PURE__ */ jsxs51("figure", { className: ["fd-tile", uploading ? "is-uploading" : "", file.error ? "is-error" : "", className].filter(Boolean).join(" "), children: [
|
|
4533
4547
|
/* @__PURE__ */ jsx55("button", { type: "button", className: "fd-tile-btn", onClick: onOpen ? () => onOpen(file) : void 0, disabled: !onOpen, children: src ? /* @__PURE__ */ jsx55("img", { src, alt: file.name || "", style: { maxHeight }, loading: "lazy" }) : /* @__PURE__ */ jsx55("span", { className: "fd-tile-fallback", children: /* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }) }) }),
|
|
4534
4548
|
uploading ? /* @__PURE__ */ jsx55(Progress, { value: file.progress }) : null,
|
|
4535
|
-
file.error ? /* @__PURE__ */
|
|
4549
|
+
file.error ? /* @__PURE__ */ jsxs51("figcaption", { className: "fd-tile-err", children: [
|
|
4536
4550
|
/* @__PURE__ */ jsx55("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
4537
4551
|
file.error
|
|
4538
4552
|
] }) : null,
|
|
@@ -4556,9 +4570,9 @@ function FileCell({ file, onOpen, onRemove, onRetry }) {
|
|
|
4556
4570
|
const image = isImage(file.mime, file.name);
|
|
4557
4571
|
const thumb = file.thumb && file.thumb.url || (image ? file.blobUrl || file.url : null);
|
|
4558
4572
|
const label = file.name + (file.size ? " \xB7 " + formatBytes(file.size) : "");
|
|
4559
|
-
return /* @__PURE__ */
|
|
4560
|
-
/* @__PURE__ */
|
|
4561
|
-
thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */
|
|
4573
|
+
return /* @__PURE__ */ jsxs51("div", { className: ["fd-cell", file.error ? "is-error" : "", uploading ? "is-uploading" : ""].filter(Boolean).join(" "), title: file.error ? file.name + " \u2014 " + file.error : label, children: [
|
|
4574
|
+
/* @__PURE__ */ jsxs51("button", { type: "button", className: "fd-cell-main", onClick: onOpen ? () => onOpen(file) : void 0, disabled: !onOpen || uploading, "aria-label": "Open " + file.name, children: [
|
|
4575
|
+
thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsxs51("span", { className: "fd-cell-doc", children: [
|
|
4562
4576
|
/* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }),
|
|
4563
4577
|
/* @__PURE__ */ jsx55("span", { className: "fd-cell-name", children: shortName(file.name) }),
|
|
4564
4578
|
/* @__PURE__ */ jsx55("span", { className: "fd-cell-size", children: file.meta || formatBytes(file.size) })
|
|
@@ -4576,15 +4590,15 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
|
|
|
4576
4590
|
if (!list.length) return null;
|
|
4577
4591
|
const pics = tiles ? list.filter((f) => isImage(f.mime, f.name)) : [];
|
|
4578
4592
|
const rest = list.filter((f) => pics.indexOf(f) === -1);
|
|
4579
|
-
return /* @__PURE__ */
|
|
4593
|
+
return /* @__PURE__ */ jsxs51("div", { className: ["fd-filegrid", className].filter(Boolean).join(" "), children: [
|
|
4580
4594
|
pics.length ? /* @__PURE__ */ jsx55("div", { className: "fd-filegrid-tiles", children: pics.map((f) => /* @__PURE__ */ jsx55(FileTile, { file: f, onOpen, onRemove, maxHeight }, f.id || f.name)) }) : null,
|
|
4581
4595
|
rest.length ? /* @__PURE__ */ jsx55("div", { className: "fd-filegrid-chips", children: rest.map((f) => /* @__PURE__ */ jsx55(FileChip, { file: f, onOpen, onRemove, onRetry, compact: compact3 }, f.id || f.name)) }) : null
|
|
4582
4596
|
] });
|
|
4583
4597
|
}
|
|
4584
4598
|
|
|
4585
4599
|
// src/components/forms/MarkdownEditor.tsx
|
|
4586
|
-
import * as
|
|
4587
|
-
import { jsx as jsx56, jsxs as
|
|
4600
|
+
import * as React29 from "react";
|
|
4601
|
+
import { jsx as jsx56, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
4588
4602
|
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
|
|
4589
4603
|
var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
|
|
4590
4604
|
function inlineParts(text) {
|
|
@@ -4797,7 +4811,7 @@ function syncDom(root, value) {
|
|
|
4797
4811
|
while (root.children.length > lines.length) root.removeChild(root.lastChild);
|
|
4798
4812
|
}
|
|
4799
4813
|
var LIST_CONT = RE_LI;
|
|
4800
|
-
var MarkdownEditor =
|
|
4814
|
+
var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
|
|
4801
4815
|
value = "",
|
|
4802
4816
|
onChange,
|
|
4803
4817
|
onSubmit,
|
|
@@ -4816,10 +4830,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
|
|
|
4816
4830
|
className = "",
|
|
4817
4831
|
id
|
|
4818
4832
|
}, ref) {
|
|
4819
|
-
const boxRef =
|
|
4820
|
-
const composing =
|
|
4821
|
-
const pendingCaret =
|
|
4822
|
-
|
|
4833
|
+
const boxRef = React29.useRef(null);
|
|
4834
|
+
const composing = React29.useRef(false);
|
|
4835
|
+
const pendingCaret = React29.useRef(null);
|
|
4836
|
+
React29.useLayoutEffect(() => {
|
|
4823
4837
|
const root = boxRef.current;
|
|
4824
4838
|
if (!root || composing.current) return;
|
|
4825
4839
|
const active = document.activeElement === root || root.contains(document.activeElement);
|
|
@@ -4828,7 +4842,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
|
|
|
4828
4842
|
pendingCaret.current = null;
|
|
4829
4843
|
if (active && caret != null) placeCaret(root, caret);
|
|
4830
4844
|
}, [value]);
|
|
4831
|
-
|
|
4845
|
+
React29.useEffect(() => {
|
|
4832
4846
|
if (autoFocus && boxRef.current) boxRef.current.focus();
|
|
4833
4847
|
}, [autoFocus]);
|
|
4834
4848
|
const caretNow = () => {
|
|
@@ -4895,7 +4909,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
|
|
|
4895
4909
|
api.replaceRange(from, to, next, from + next.length);
|
|
4896
4910
|
}
|
|
4897
4911
|
};
|
|
4898
|
-
|
|
4912
|
+
React29.useImperativeHandle(ref, () => api);
|
|
4899
4913
|
function detect(text, caret) {
|
|
4900
4914
|
if (!onTrigger) return;
|
|
4901
4915
|
const upto = text.slice(0, caret);
|
|
@@ -5008,7 +5022,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
|
|
|
5008
5022
|
api.replaceRange(s.start, s.end, text.replace(/\r\n?/g, "\n"));
|
|
5009
5023
|
};
|
|
5010
5024
|
const lh = 1.55;
|
|
5011
|
-
return /* @__PURE__ */
|
|
5025
|
+
return /* @__PURE__ */ jsxs52("div", { className: ["fd-rme-wrap", disabled ? "is-disabled" : "", className].filter(Boolean).join(" "), children: [
|
|
5012
5026
|
/* @__PURE__ */ jsx56(
|
|
5013
5027
|
"div",
|
|
5014
5028
|
{
|
|
@@ -5047,10 +5061,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
|
|
|
5047
5061
|
});
|
|
5048
5062
|
|
|
5049
5063
|
// src/components/platform/AccountMenu.tsx
|
|
5050
|
-
import * as
|
|
5064
|
+
import * as React31 from "react";
|
|
5051
5065
|
|
|
5052
5066
|
// src/kits/session.ts
|
|
5053
|
-
import * as
|
|
5067
|
+
import * as React30 from "react";
|
|
5054
5068
|
var PERMISSION_CATALOG = [
|
|
5055
5069
|
{ group: "Plans", items: [
|
|
5056
5070
|
{ key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
|
|
@@ -6617,8 +6631,8 @@ function roadmap(overrides) {
|
|
|
6617
6631
|
};
|
|
6618
6632
|
}
|
|
6619
6633
|
function useSession() {
|
|
6620
|
-
const [s, setS] =
|
|
6621
|
-
|
|
6634
|
+
const [s, setS] = React30.useState(getSession);
|
|
6635
|
+
React30.useEffect(() => subscribe(setS), []);
|
|
6622
6636
|
return s;
|
|
6623
6637
|
}
|
|
6624
6638
|
var SessionKit = {
|
|
@@ -6651,7 +6665,7 @@ var SessionKit = {
|
|
|
6651
6665
|
};
|
|
6652
6666
|
|
|
6653
6667
|
// src/components/platform/AccountMenu.tsx
|
|
6654
|
-
import { Fragment as Fragment14, jsx as jsx57, jsxs as
|
|
6668
|
+
import { Fragment as Fragment14, jsx as jsx57, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
6655
6669
|
var DEFAULT_LINKS = [
|
|
6656
6670
|
{ id: "profile", label: "Your profile", icon: "user-circle", href: "../admin/index.html#profile" },
|
|
6657
6671
|
{ id: "preferences", label: "Preferences", icon: "sliders-horizontal", href: "../admin/index.html#preferences" }
|
|
@@ -6662,7 +6676,7 @@ var DEFAULT_ADMIN_LINKS = [
|
|
|
6662
6676
|
{ id: "flags", label: "Feature flags", icon: "toggle-right", href: "../admin/index.html#flags", perm: "flags.manage" }
|
|
6663
6677
|
];
|
|
6664
6678
|
function Item({ item, onPick }) {
|
|
6665
|
-
return /* @__PURE__ */
|
|
6679
|
+
return /* @__PURE__ */ jsxs53(
|
|
6666
6680
|
"button",
|
|
6667
6681
|
{
|
|
6668
6682
|
type: "button",
|
|
@@ -6688,9 +6702,9 @@ function AccountMenu({
|
|
|
6688
6702
|
...rest
|
|
6689
6703
|
}) {
|
|
6690
6704
|
const session = SessionKit.useSession();
|
|
6691
|
-
const [open, setOpen] =
|
|
6692
|
-
const [switching, setSwitching] =
|
|
6693
|
-
const ref =
|
|
6705
|
+
const [open, setOpen] = React31.useState(false);
|
|
6706
|
+
const [switching, setSwitching] = React31.useState(false);
|
|
6707
|
+
const ref = React31.useRef(null);
|
|
6694
6708
|
const user = session.user;
|
|
6695
6709
|
const visibleAdmin = adminLinks.filter((l) => !l.perm || SessionKit.can(l.perm));
|
|
6696
6710
|
const pick = (item) => {
|
|
@@ -6704,8 +6718,8 @@ function AccountMenu({
|
|
|
6704
6718
|
if (onSignOut) return onSignOut();
|
|
6705
6719
|
window.alert("Signed out. (Simulated \u2014 no auth provider is wired up.)");
|
|
6706
6720
|
};
|
|
6707
|
-
return /* @__PURE__ */
|
|
6708
|
-
/* @__PURE__ */
|
|
6721
|
+
return /* @__PURE__ */ jsxs53(Fragment14, { children: [
|
|
6722
|
+
/* @__PURE__ */ jsxs53(
|
|
6709
6723
|
"button",
|
|
6710
6724
|
{
|
|
6711
6725
|
type: "button",
|
|
@@ -6722,27 +6736,27 @@ function AccountMenu({
|
|
|
6722
6736
|
]
|
|
6723
6737
|
}
|
|
6724
6738
|
),
|
|
6725
|
-
/* @__PURE__ */ jsx57(Popover, { open, anchorRef: ref, onClose: () => setOpen(false), placement: "bottom-end", width: 272, children: /* @__PURE__ */
|
|
6726
|
-
/* @__PURE__ */
|
|
6739
|
+
/* @__PURE__ */ jsx57(Popover, { open, anchorRef: ref, onClose: () => setOpen(false), placement: "bottom-end", width: 272, children: /* @__PURE__ */ jsxs53("div", { role: "menu", className: "fd-stack", style: { gap: 0 }, children: [
|
|
6740
|
+
/* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
|
|
6727
6741
|
/* @__PURE__ */ jsx57(Avatar, { name: user.name }),
|
|
6728
|
-
/* @__PURE__ */
|
|
6742
|
+
/* @__PURE__ */ jsxs53("span", { className: "fd-stack", style: { gap: 1, minWidth: 0, flex: 1 }, children: [
|
|
6729
6743
|
/* @__PURE__ */ jsx57("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: user.name }),
|
|
6730
6744
|
/* @__PURE__ */ jsx57("span", { className: "fd-body-sm fd-muted fd-table-trunc", children: user.email })
|
|
6731
6745
|
] })
|
|
6732
6746
|
] }),
|
|
6733
6747
|
showRoles && session.roles.length ? /* @__PURE__ */ jsx57("div", { className: "fd-row", style: { gap: 6, padding: "10px 14px", flexWrap: "wrap", borderBottom: "1px solid var(--border)" }, children: session.roles.map((r) => /* @__PURE__ */ jsx57(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)) }) : null,
|
|
6734
6748
|
/* @__PURE__ */ jsx57("div", { className: "fd-acct-group", children: links.map((l) => /* @__PURE__ */ jsx57(Item, { item: l, onPick: pick }, l.id)) }),
|
|
6735
|
-
visibleAdmin.length ? /* @__PURE__ */
|
|
6749
|
+
visibleAdmin.length ? /* @__PURE__ */ jsxs53("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
|
|
6736
6750
|
/* @__PURE__ */ jsx57("span", { className: "fd-overline fd-muted", style: { padding: "8px 14px 4px", display: "block" }, children: "Administration" }),
|
|
6737
6751
|
visibleAdmin.map((l) => /* @__PURE__ */ jsx57(Item, { item: l, onPick: pick }, l.id))
|
|
6738
6752
|
] }) : null,
|
|
6739
|
-
allowUserSwitch ? /* @__PURE__ */
|
|
6740
|
-
/* @__PURE__ */
|
|
6753
|
+
allowUserSwitch ? /* @__PURE__ */ jsxs53("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
|
|
6754
|
+
/* @__PURE__ */ jsxs53("button", { type: "button", role: "menuitem", className: "fd-acct-item", onClick: () => setSwitching((s) => !s), children: [
|
|
6741
6755
|
/* @__PURE__ */ jsx57("i", { className: "ph ph-user-switch", "aria-hidden": "true" }),
|
|
6742
6756
|
/* @__PURE__ */ jsx57("span", { style: { flex: 1 }, children: "View as another member" }),
|
|
6743
6757
|
/* @__PURE__ */ jsx57("i", { className: "ph ph-caret-" + (switching ? "up" : "down"), "aria-hidden": "true", style: { fontSize: 11 } })
|
|
6744
6758
|
] }),
|
|
6745
|
-
switching ? /* @__PURE__ */ jsx57("div", { className: "fd-stack", style: { gap: 0 }, children: session.allUsers.filter((u) => u.status === "active").map((u) => /* @__PURE__ */
|
|
6759
|
+
switching ? /* @__PURE__ */ jsx57("div", { className: "fd-stack", style: { gap: 0 }, children: session.allUsers.filter((u) => u.status === "active").map((u) => /* @__PURE__ */ jsxs53(
|
|
6746
6760
|
"button",
|
|
6747
6761
|
{
|
|
6748
6762
|
type: "button",
|
|
@@ -6755,7 +6769,7 @@ function AccountMenu({
|
|
|
6755
6769
|
},
|
|
6756
6770
|
children: [
|
|
6757
6771
|
/* @__PURE__ */ jsx57(Avatar, { name: u.name, size: "sm" }),
|
|
6758
|
-
/* @__PURE__ */
|
|
6772
|
+
/* @__PURE__ */ jsxs53("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
|
|
6759
6773
|
/* @__PURE__ */ jsx57("span", { style: { fontWeight: u.id === user.id ? 700 : 500 }, children: u.name }),
|
|
6760
6774
|
/* @__PURE__ */ jsx57("span", { className: "fd-muted", style: { fontSize: 11.5 }, children: u.roles.join(", ") })
|
|
6761
6775
|
] }),
|
|
@@ -6765,7 +6779,7 @@ function AccountMenu({
|
|
|
6765
6779
|
u.id
|
|
6766
6780
|
)) }) : null
|
|
6767
6781
|
] }) : null,
|
|
6768
|
-
/* @__PURE__ */ jsx57("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: /* @__PURE__ */
|
|
6782
|
+
/* @__PURE__ */ jsx57("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: /* @__PURE__ */ jsxs53("button", { type: "button", role: "menuitem", className: "fd-acct-item", "data-danger": "true", onClick: signOut, children: [
|
|
6769
6783
|
/* @__PURE__ */ jsx57("i", { className: "ph ph-sign-out", "aria-hidden": "true" }),
|
|
6770
6784
|
/* @__PURE__ */ jsx57("span", { style: { flex: 1 }, children: "Sign out" })
|
|
6771
6785
|
] }) })
|
|
@@ -6774,14 +6788,14 @@ function AccountMenu({
|
|
|
6774
6788
|
}
|
|
6775
6789
|
|
|
6776
6790
|
// src/components/platform/ApiSpecBrowser.tsx
|
|
6777
|
-
import * as
|
|
6778
|
-
import { jsx as jsx58, jsxs as
|
|
6791
|
+
import * as React32 from "react";
|
|
6792
|
+
import { jsx as jsx58, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
6779
6793
|
var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
|
|
6780
6794
|
function Json({ obj }) {
|
|
6781
6795
|
return /* @__PURE__ */ jsx58("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
|
|
6782
6796
|
}
|
|
6783
6797
|
function Endpoint({ s, onRequest }) {
|
|
6784
|
-
const [tried, setTried] =
|
|
6798
|
+
const [tried, setTried] = React32.useState(null);
|
|
6785
6799
|
const run = async () => {
|
|
6786
6800
|
setTried("busy");
|
|
6787
6801
|
const t0 = (window.performance || Date).now();
|
|
@@ -6792,13 +6806,13 @@ function Endpoint({ s, onRequest }) {
|
|
|
6792
6806
|
setTried({ ms: Math.round((window.performance || Date).now() - t0), error: String(e && e.message || e) });
|
|
6793
6807
|
}
|
|
6794
6808
|
};
|
|
6795
|
-
return /* @__PURE__ */ jsx58(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */
|
|
6796
|
-
/* @__PURE__ */
|
|
6809
|
+
return /* @__PURE__ */ jsx58(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 0 }, children: [
|
|
6810
|
+
/* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 10, padding: "14px 18px", flexWrap: "wrap" }, children: [
|
|
6797
6811
|
/* @__PURE__ */ jsx58(Badge, { tone: METHOD_TONE[s.method] || "neutral", children: s.method }),
|
|
6798
6812
|
/* @__PURE__ */ jsx58("code", { className: "fd-mono", style: { fontSize: 12.5, fontWeight: 600, color: "var(--text)", wordBreak: "break-all" }, children: s.path }),
|
|
6799
6813
|
s.isList ? /* @__PURE__ */ jsx58(Badge, { tone: "neutral", icon: "rows", children: "Paged list" }) : null,
|
|
6800
6814
|
/* @__PURE__ */ jsx58("span", { style: { flex: 1 } }),
|
|
6801
|
-
/* @__PURE__ */
|
|
6815
|
+
/* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted fd-mono", children: [
|
|
6802
6816
|
s.latency[0],
|
|
6803
6817
|
"\u2013",
|
|
6804
6818
|
s.latency[1],
|
|
@@ -6806,31 +6820,31 @@ function Endpoint({ s, onRequest }) {
|
|
|
6806
6820
|
] }),
|
|
6807
6821
|
/* @__PURE__ */ jsx58(Button, { size: "sm", variant: "secondary", icon: "play", loading: tried === "busy", onClick: run, children: "Try it" })
|
|
6808
6822
|
] }),
|
|
6809
|
-
/* @__PURE__ */
|
|
6810
|
-
/* @__PURE__ */
|
|
6823
|
+
/* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 14, padding: "0 18px 16px" }, children: [
|
|
6824
|
+
/* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
6811
6825
|
/* @__PURE__ */ jsx58("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: s.title }),
|
|
6812
6826
|
/* @__PURE__ */ jsx58("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: s.purpose }),
|
|
6813
6827
|
s.usedBy && s.usedBy.length ? /* @__PURE__ */ jsx58("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: s.usedBy.map((u) => /* @__PURE__ */ jsx58(Tag, { children: u }, u)) }) : null
|
|
6814
6828
|
] }),
|
|
6815
|
-
/* @__PURE__ */
|
|
6816
|
-
s.request ? /* @__PURE__ */
|
|
6829
|
+
/* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 12, alignItems: "start" }, children: [
|
|
6830
|
+
s.request ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
6817
6831
|
/* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Request body" }),
|
|
6818
6832
|
/* @__PURE__ */ jsx58(Json, { obj: s.request })
|
|
6819
6833
|
] }) : null,
|
|
6820
|
-
s.query ? /* @__PURE__ */
|
|
6834
|
+
s.query ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
6821
6835
|
/* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Query" }),
|
|
6822
6836
|
/* @__PURE__ */ jsx58(Json, { obj: s.query })
|
|
6823
6837
|
] }) : null,
|
|
6824
|
-
/* @__PURE__ */
|
|
6838
|
+
/* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
6825
6839
|
/* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Response 200" }),
|
|
6826
6840
|
/* @__PURE__ */ jsx58(Json, { obj: s.response })
|
|
6827
6841
|
] })
|
|
6828
6842
|
] }),
|
|
6829
6843
|
s.notes ? /* @__PURE__ */ jsx58(Flag, { tone: "info", statement: "Implementation note", cost: s.notes, actions: null }) : null,
|
|
6830
|
-
tried && tried !== "busy" ? /* @__PURE__ */
|
|
6831
|
-
/* @__PURE__ */
|
|
6844
|
+
tried && tried !== "busy" ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
6845
|
+
/* @__PURE__ */ jsxs54("span", { className: "fd-row", style: { gap: 8 }, children: [
|
|
6832
6846
|
/* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Simulated response" }),
|
|
6833
|
-
/* @__PURE__ */
|
|
6847
|
+
/* @__PURE__ */ jsxs54(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
|
|
6834
6848
|
tried.ms,
|
|
6835
6849
|
"ms"
|
|
6836
6850
|
] })
|
|
@@ -6854,29 +6868,29 @@ function ApiSpecBrowser({
|
|
|
6854
6868
|
className = "",
|
|
6855
6869
|
...rest
|
|
6856
6870
|
}) {
|
|
6857
|
-
const [q, setQ] =
|
|
6858
|
-
const [method, setMethod] =
|
|
6859
|
-
const [mod, setMod] =
|
|
6860
|
-
const [listOnly, setListOnly] =
|
|
6871
|
+
const [q, setQ] = React32.useState("");
|
|
6872
|
+
const [method, setMethod] = React32.useState(null);
|
|
6873
|
+
const [mod, setMod] = React32.useState(null);
|
|
6874
|
+
const [listOnly, setListOnly] = React32.useState(false);
|
|
6861
6875
|
const activeModule = modules && modules.find((m) => m.id === mod);
|
|
6862
6876
|
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())));
|
|
6863
6877
|
const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
|
|
6864
6878
|
const methods = [...new Set(spec.map((s) => s.method))];
|
|
6865
6879
|
const listCount = spec.filter((s) => s.isList).length;
|
|
6866
|
-
return /* @__PURE__ */
|
|
6867
|
-
/* @__PURE__ */
|
|
6880
|
+
return /* @__PURE__ */ jsxs54("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 1100 }, ...rest, children: [
|
|
6881
|
+
/* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 10 }, children: [
|
|
6868
6882
|
kicker ? /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: kicker }) : null,
|
|
6869
6883
|
/* @__PURE__ */ jsx58("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
|
|
6870
6884
|
lede ? /* @__PURE__ */ jsx58("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: lede }) : null
|
|
6871
6885
|
] }),
|
|
6872
|
-
modules && modules.length ? /* @__PURE__ */
|
|
6886
|
+
modules && modules.length ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 8 }, children: [
|
|
6873
6887
|
/* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Filter by screen \u2014 every endpoint that screen depends on" }),
|
|
6874
|
-
/* @__PURE__ */
|
|
6875
|
-
/* @__PURE__ */
|
|
6888
|
+
/* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
|
|
6889
|
+
/* @__PURE__ */ jsxs54(Tag, { icon: "stack", selected: !mod, onClick: () => setMod(null), children: [
|
|
6876
6890
|
"All screens ",
|
|
6877
6891
|
/* @__PURE__ */ jsx58("span", { className: "fd-mono", children: spec.length })
|
|
6878
6892
|
] }),
|
|
6879
|
-
modules.map((m) => /* @__PURE__ */
|
|
6893
|
+
modules.map((m) => /* @__PURE__ */ jsxs54(Tag, { icon: m.icon, selected: mod === m.id, onClick: () => setMod(mod === m.id ? null : m.id), children: [
|
|
6880
6894
|
m.label,
|
|
6881
6895
|
" ",
|
|
6882
6896
|
/* @__PURE__ */ jsx58("span", { className: "fd-mono", children: m.endpoints.length })
|
|
@@ -6893,19 +6907,19 @@ function ApiSpecBrowser({
|
|
|
6893
6907
|
) : null
|
|
6894
6908
|
] }) : null,
|
|
6895
6909
|
sourceNote ? /* @__PURE__ */ jsx58(Flag, { tone: "info", statement: "Design-first: this page is the spec.", cost: sourceNote, actions: null }) : null,
|
|
6896
|
-
/* @__PURE__ */
|
|
6910
|
+
/* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
|
|
6897
6911
|
/* @__PURE__ */ jsx58(Input, { icon: "magnifying-glass", placeholder: "Find an endpoint, screen, or behavior", value: q, onChange: (e) => setQ(e.target.value), style: { width: 300 } }),
|
|
6898
|
-
methods.map((m) => /* @__PURE__ */
|
|
6912
|
+
methods.map((m) => /* @__PURE__ */ jsxs54(Tag, { selected: method === m, onClick: () => setMethod(method === m ? null : m), children: [
|
|
6899
6913
|
m,
|
|
6900
6914
|
" ",
|
|
6901
6915
|
/* @__PURE__ */ jsx58("span", { className: "fd-mono", children: spec.filter((s) => s.method === m).length })
|
|
6902
6916
|
] }, m)),
|
|
6903
|
-
listCount ? /* @__PURE__ */
|
|
6917
|
+
listCount ? /* @__PURE__ */ jsxs54(Tag, { icon: "rows", selected: listOnly, onClick: () => setListOnly(!listOnly), children: [
|
|
6904
6918
|
"Paged lists ",
|
|
6905
6919
|
/* @__PURE__ */ jsx58("span", { className: "fd-mono", children: listCount })
|
|
6906
6920
|
] }) : null,
|
|
6907
6921
|
/* @__PURE__ */ jsx58("span", { style: { flex: 1 } }),
|
|
6908
|
-
/* @__PURE__ */
|
|
6922
|
+
/* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
|
|
6909
6923
|
hits.length,
|
|
6910
6924
|
" of ",
|
|
6911
6925
|
spec.length,
|
|
@@ -6916,18 +6930,18 @@ function ApiSpecBrowser({
|
|
|
6916
6930
|
hits.length === 0 ? /* @__PURE__ */ jsx58(Card, { elevation: "flat", children: /* @__PURE__ */ jsx58("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: "No endpoint matches those filters." }) }) : effGroups.map(([g, ids]) => {
|
|
6917
6931
|
const items = hits.filter((s) => ids.indexOf(s.id) >= 0);
|
|
6918
6932
|
if (!items.length) return null;
|
|
6919
|
-
return /* @__PURE__ */
|
|
6933
|
+
return /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 12 }, children: [
|
|
6920
6934
|
/* @__PURE__ */ jsx58("span", { className: "fd-label-lg", children: g }),
|
|
6921
6935
|
items.map((s) => /* @__PURE__ */ jsx58(Endpoint, { s, onRequest }, s.id))
|
|
6922
6936
|
] }, g);
|
|
6923
6937
|
}),
|
|
6924
|
-
conventions && conventions.length ? /* @__PURE__ */ jsx58(Card, { title: "Cross-cutting conventions", elevation: "flat", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 10 }, children: conventions.map(([k, v]) => /* @__PURE__ */
|
|
6938
|
+
conventions && conventions.length ? /* @__PURE__ */ jsx58(Card, { title: "Cross-cutting conventions", elevation: "flat", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 10 }, children: conventions.map(([k, v]) => /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 12, alignItems: "flex-start" }, children: [
|
|
6925
6939
|
/* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", style: { width: 110, flex: "none", paddingTop: 2 }, children: k }),
|
|
6926
6940
|
/* @__PURE__ */ jsx58("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: v })
|
|
6927
6941
|
] }, k)) }) }) : null,
|
|
6928
|
-
openQuestions && openQuestions.length ? /* @__PURE__ */ jsx58(Collapsible, { icon: "list-checks", title: "Open questions before implementation", subtitle: openQuestions.length + " unresolved", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 8 }, children: openQuestions.map(([id, question, why]) => /* @__PURE__ */
|
|
6942
|
+
openQuestions && openQuestions.length ? /* @__PURE__ */ jsx58(Collapsible, { icon: "list-checks", title: "Open questions before implementation", subtitle: openQuestions.length + " unresolved", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 8 }, children: openQuestions.map(([id, question, why]) => /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start", padding: "8px 0", borderTop: "1px solid var(--border)" }, children: [
|
|
6929
6943
|
/* @__PURE__ */ jsx58(Badge, { tone: "danger", children: id }),
|
|
6930
|
-
/* @__PURE__ */
|
|
6944
|
+
/* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2, flex: 1 }, children: [
|
|
6931
6945
|
/* @__PURE__ */ jsx58("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: question }),
|
|
6932
6946
|
/* @__PURE__ */ jsx58("span", { className: "fd-body-sm fd-muted", children: why })
|
|
6933
6947
|
] })
|
|
@@ -6936,8 +6950,8 @@ function ApiSpecBrowser({
|
|
|
6936
6950
|
}
|
|
6937
6951
|
|
|
6938
6952
|
// src/components/platform/ProfilePage.tsx
|
|
6939
|
-
import * as
|
|
6940
|
-
import { jsx as jsx59, jsxs as
|
|
6953
|
+
import * as React33 from "react";
|
|
6954
|
+
import { jsx as jsx59, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
6941
6955
|
var TIMEZONES = ["America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles", "America/Anchorage", "Pacific/Honolulu", "Europe/London", "Europe/Berlin"];
|
|
6942
6956
|
var NOTIFY = [
|
|
6943
6957
|
{ key: "planShared", label: "A plan is shared with me", detail: "Someone sends you a plan or a client link." },
|
|
@@ -6949,7 +6963,7 @@ var NOTIFY = [
|
|
|
6949
6963
|
function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSessions = true, className = "", ...rest }) {
|
|
6950
6964
|
const session = SessionKit.useSession();
|
|
6951
6965
|
const user = userProp || session.user;
|
|
6952
|
-
const [draft, setDraft] =
|
|
6966
|
+
const [draft, setDraft] = React33.useState(() => ({
|
|
6953
6967
|
name: user.name || "",
|
|
6954
6968
|
title: user.title || "",
|
|
6955
6969
|
email: user.email || "",
|
|
@@ -6958,8 +6972,8 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
6958
6972
|
bio: user.bio || "",
|
|
6959
6973
|
notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true }
|
|
6960
6974
|
}));
|
|
6961
|
-
const [saving, setSaving] =
|
|
6962
|
-
const [saved, setSaved] =
|
|
6975
|
+
const [saving, setSaving] = React33.useState(false);
|
|
6976
|
+
const [saved, setSaved] = React33.useState(false);
|
|
6963
6977
|
const set = (k, v) => {
|
|
6964
6978
|
setDraft((d) => Object.assign({}, d, { [k]: v }));
|
|
6965
6979
|
setSaved(false);
|
|
@@ -6981,22 +6995,22 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
6981
6995
|
{ id: "s2", device: "iPhone 15 \xB7 Safari", where: "Denver, CO", when: "2 hours ago" },
|
|
6982
6996
|
{ id: "s3", device: "Windows \xB7 Edge", where: "Chicago, IL", when: "Aug 12" }
|
|
6983
6997
|
];
|
|
6984
|
-
return /* @__PURE__ */
|
|
6985
|
-
/* @__PURE__ */
|
|
6998
|
+
return /* @__PURE__ */ jsxs55("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, ...rest, children: [
|
|
6999
|
+
/* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 10 }, children: [
|
|
6986
7000
|
/* @__PURE__ */ jsx59("span", { className: "fd-overline fd-muted", children: "Account" }),
|
|
6987
7001
|
/* @__PURE__ */ jsx59("h1", { className: "fd-h1", style: { margin: 0 }, children: "Your profile" }),
|
|
6988
7002
|
/* @__PURE__ */ jsx59("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: "How you appear to colleagues and clients across every flytedesk app, and what we send you." })
|
|
6989
7003
|
] }),
|
|
6990
|
-
/* @__PURE__ */ jsx59(Card, { elevation: "flat", children: /* @__PURE__ */
|
|
7004
|
+
/* @__PURE__ */ jsx59(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap", alignItems: "flex-start" }, children: [
|
|
6991
7005
|
/* @__PURE__ */ jsx59(Avatar, { name: draft.name || user.name, size: "lg" }),
|
|
6992
|
-
/* @__PURE__ */
|
|
7006
|
+
/* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
|
|
6993
7007
|
/* @__PURE__ */ jsx59("span", { className: "fd-h3", style: { margin: 0 }, children: draft.name || user.name }),
|
|
6994
|
-
/* @__PURE__ */
|
|
7008
|
+
/* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
|
|
6995
7009
|
draft.title || "No title set",
|
|
6996
7010
|
" \xB7 ",
|
|
6997
7011
|
user.team || "No team"
|
|
6998
7012
|
] }),
|
|
6999
|
-
/* @__PURE__ */
|
|
7013
|
+
/* @__PURE__ */ jsxs55("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 4 }, children: [
|
|
7000
7014
|
session.roles.map((r) => /* @__PURE__ */ jsx59(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)),
|
|
7001
7015
|
user.sso ? /* @__PURE__ */ jsx59(Badge, { tone: "info", icon: "shield-check", children: "SSO" }) : null
|
|
7002
7016
|
] })
|
|
@@ -7006,17 +7020,17 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7006
7020
|
/* @__PURE__ */ jsx59(
|
|
7007
7021
|
Card,
|
|
7008
7022
|
{
|
|
7009
|
-
title: /* @__PURE__ */
|
|
7023
|
+
title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
7010
7024
|
/* @__PURE__ */ jsx59("span", { children: "Identity" }),
|
|
7011
7025
|
/* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "Name and title appear on plans you share" })
|
|
7012
7026
|
] }),
|
|
7013
7027
|
elevation: "flat",
|
|
7014
|
-
children: /* @__PURE__ */
|
|
7015
|
-
/* @__PURE__ */
|
|
7028
|
+
children: /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 14 }, children: [
|
|
7029
|
+
/* @__PURE__ */ jsxs55("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
|
|
7016
7030
|
/* @__PURE__ */ jsx59(Input, { label: "Full name", value: draft.name, onChange: (e) => set("name", e.target.value) }),
|
|
7017
7031
|
/* @__PURE__ */ jsx59(Input, { label: "Job title", value: draft.title, onChange: (e) => set("title", e.target.value), placeholder: "e.g. Senior media planner" })
|
|
7018
7032
|
] }),
|
|
7019
|
-
/* @__PURE__ */
|
|
7033
|
+
/* @__PURE__ */ jsxs55("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
|
|
7020
7034
|
/* @__PURE__ */ jsx59(
|
|
7021
7035
|
Input,
|
|
7022
7036
|
{
|
|
@@ -7043,7 +7057,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7043
7057
|
] })
|
|
7044
7058
|
}
|
|
7045
7059
|
),
|
|
7046
|
-
/* @__PURE__ */ jsx59(Card, { title: "Working preferences", elevation: "flat", children: /* @__PURE__ */
|
|
7060
|
+
/* @__PURE__ */ jsx59(Card, { title: "Working preferences", elevation: "flat", children: /* @__PURE__ */ jsxs55("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
|
|
7047
7061
|
/* @__PURE__ */ jsx59(
|
|
7048
7062
|
Select,
|
|
7049
7063
|
{
|
|
@@ -7059,7 +7073,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7059
7073
|
/* @__PURE__ */ jsx59(
|
|
7060
7074
|
Card,
|
|
7061
7075
|
{
|
|
7062
|
-
title: /* @__PURE__ */
|
|
7076
|
+
title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
7063
7077
|
/* @__PURE__ */ jsx59("span", { children: "Notifications" }),
|
|
7064
7078
|
/* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "Email only for now \u2014 in-app notifications are on the roadmap" })
|
|
7065
7079
|
] }),
|
|
@@ -7067,10 +7081,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7067
7081
|
children: /* @__PURE__ */ jsx59("div", { className: "fd-stack", style: { gap: 14 }, children: NOTIFY.map((n) => /* @__PURE__ */ jsx59(Switch, { checked: !!draft.notify[n.key], onChange: () => setNotify(n.key), label: n.label, description: n.detail }, n.key)) })
|
|
7068
7082
|
}
|
|
7069
7083
|
),
|
|
7070
|
-
/* @__PURE__ */
|
|
7084
|
+
/* @__PURE__ */ jsxs55(
|
|
7071
7085
|
Card,
|
|
7072
7086
|
{
|
|
7073
|
-
title: /* @__PURE__ */
|
|
7087
|
+
title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
7074
7088
|
/* @__PURE__ */ jsx59("span", { children: "Access" }),
|
|
7075
7089
|
/* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "What your roles grant you" })
|
|
7076
7090
|
] }),
|
|
@@ -7086,9 +7100,9 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7086
7100
|
}
|
|
7087
7101
|
),
|
|
7088
7102
|
children: [
|
|
7089
|
-
/* @__PURE__ */
|
|
7103
|
+
/* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 0 }, children: [
|
|
7090
7104
|
/* @__PURE__ */ jsx59(CardRow, { label: "Roles", children: session.roles.map((r) => r.name).join(", ") || "None" }),
|
|
7091
|
-
/* @__PURE__ */
|
|
7105
|
+
/* @__PURE__ */ jsxs55(CardRow, { label: "Permissions", children: [
|
|
7092
7106
|
session.permissions.length,
|
|
7093
7107
|
" granted"
|
|
7094
7108
|
] }),
|
|
@@ -7104,11 +7118,11 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7104
7118
|
title: "Signed-in devices",
|
|
7105
7119
|
elevation: "flat",
|
|
7106
7120
|
action: /* @__PURE__ */ jsx59(Button, { size: "sm", variant: "ghost", icon: "sign-out", children: "Sign out everywhere" }),
|
|
7107
|
-
children: /* @__PURE__ */ jsx59("div", { className: "fd-stack", style: { gap: 0 }, children: liveSessions.map((s) => /* @__PURE__ */
|
|
7121
|
+
children: /* @__PURE__ */ jsx59("div", { className: "fd-stack", style: { gap: 0 }, children: liveSessions.map((s) => /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 12, padding: "10px 0", borderTop: "1px solid var(--border)", flexWrap: "wrap" }, children: [
|
|
7108
7122
|
/* @__PURE__ */ jsx59("i", { className: "ph ph-device-mobile", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
|
|
7109
|
-
/* @__PURE__ */
|
|
7123
|
+
/* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
|
|
7110
7124
|
/* @__PURE__ */ jsx59("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: s.device }),
|
|
7111
|
-
/* @__PURE__ */
|
|
7125
|
+
/* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
|
|
7112
7126
|
s.where,
|
|
7113
7127
|
" \xB7 ",
|
|
7114
7128
|
s.when
|
|
@@ -7118,7 +7132,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7118
7132
|
] }, s.id)) })
|
|
7119
7133
|
}
|
|
7120
7134
|
) : null,
|
|
7121
|
-
/* @__PURE__ */
|
|
7135
|
+
/* @__PURE__ */ jsxs55("div", { className: "fd-row", style: {
|
|
7122
7136
|
gap: 10,
|
|
7123
7137
|
flexWrap: "wrap",
|
|
7124
7138
|
position: "sticky",
|
|
@@ -7149,10 +7163,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
7149
7163
|
}
|
|
7150
7164
|
|
|
7151
7165
|
// src/components/platform/RoadmapTimeline.tsx
|
|
7152
|
-
import * as
|
|
7166
|
+
import * as React35 from "react";
|
|
7153
7167
|
|
|
7154
7168
|
// src/kits/runtime.ts
|
|
7155
|
-
import * as
|
|
7169
|
+
import * as React34 from "react";
|
|
7156
7170
|
var WIRED_ENDPOINTS = [
|
|
7157
7171
|
// Nothing yet. Every id below would come from a real service:
|
|
7158
7172
|
// "plan.get", "placements.list", …
|
|
@@ -7323,8 +7337,8 @@ var RuntimeKit = {
|
|
|
7323
7337
|
};
|
|
7324
7338
|
RuntimeKit.declare(FEATURE_NEEDS);
|
|
7325
7339
|
function useRuntimeMode() {
|
|
7326
|
-
const [m, setM] =
|
|
7327
|
-
|
|
7340
|
+
const [m, setM] = React34.useState(RuntimeKit.getMode());
|
|
7341
|
+
React34.useEffect(() => RuntimeKit.subscribe(setM), []);
|
|
7328
7342
|
return m;
|
|
7329
7343
|
}
|
|
7330
7344
|
function useFeatureStatus(key) {
|
|
@@ -7343,7 +7357,7 @@ var UseRuntimeMode = useRuntimeMode;
|
|
|
7343
7357
|
var UseFeatureStatus = useFeatureStatus;
|
|
7344
7358
|
|
|
7345
7359
|
// src/components/platform/RoadmapTimeline.tsx
|
|
7346
|
-
import { jsx as jsx60, jsxs as
|
|
7360
|
+
import { jsx as jsx60, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
7347
7361
|
var STATUS = {
|
|
7348
7362
|
shipped: { tone: "success", icon: "check-circle", label: "Wired" },
|
|
7349
7363
|
next: { tone: "warning", icon: "traffic-cone", label: "Not wired" },
|
|
@@ -7358,24 +7372,24 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
7358
7372
|
const s = STATUS[item.status] || STATUS.planned;
|
|
7359
7373
|
const deps = (item.dependsOn || []).map((k) => byKey[k]).filter(Boolean);
|
|
7360
7374
|
const blocking = deps.filter((d) => !d.implemented);
|
|
7361
|
-
return /* @__PURE__ */ jsx60(Card, { elevation: "flat", children: /* @__PURE__ */
|
|
7362
|
-
/* @__PURE__ */
|
|
7375
|
+
return /* @__PURE__ */ jsx60(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs56("div", { className: "fd-stack", style: { gap: 10 }, children: [
|
|
7376
|
+
/* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
|
|
7363
7377
|
/* @__PURE__ */ jsx60("span", { className: "fd-body", style: { fontWeight: 700, flex: 1, minWidth: 140 }, children: item.label }),
|
|
7364
7378
|
/* @__PURE__ */ jsx60(Badge, { tone: "neutral", icon: PROJECT_ICON[item.project] || "squares-four", children: item.project }),
|
|
7365
7379
|
/* @__PURE__ */ jsx60(Badge, { tone: s.tone, icon: s.icon, children: s.label })
|
|
7366
7380
|
] }),
|
|
7367
7381
|
/* @__PURE__ */ jsx60("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: item.description }),
|
|
7368
|
-
item.backend ? /* @__PURE__ */
|
|
7382
|
+
item.backend ? /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
|
|
7369
7383
|
/* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", style: { width: 62, flex: "none", paddingTop: 2 }, children: "Backend" }),
|
|
7370
7384
|
/* @__PURE__ */ jsx60("span", { className: "fd-body-sm", style: { flex: 1, textWrap: "pretty" }, children: item.backend })
|
|
7371
7385
|
] }) : null,
|
|
7372
|
-
/* @__PURE__ */
|
|
7373
|
-
item.effort ? /* @__PURE__ */
|
|
7386
|
+
/* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
|
|
7387
|
+
item.effort ? /* @__PURE__ */ jsxs56("span", { className: "fd-body-sm fd-muted", children: [
|
|
7374
7388
|
/* @__PURE__ */ jsx60("i", { className: "ph ph-hourglass-medium" }),
|
|
7375
7389
|
" ",
|
|
7376
7390
|
item.effort
|
|
7377
7391
|
] }) : null,
|
|
7378
|
-
/* @__PURE__ */
|
|
7392
|
+
/* @__PURE__ */ jsxs56("span", { className: "fd-body-sm fd-muted", children: [
|
|
7379
7393
|
/* @__PURE__ */ jsx60("i", { className: "ph ph-user" }),
|
|
7380
7394
|
" ",
|
|
7381
7395
|
item.owner
|
|
@@ -7392,11 +7406,11 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
7392
7406
|
}
|
|
7393
7407
|
)
|
|
7394
7408
|
] }),
|
|
7395
|
-
deps.length ? /* @__PURE__ */
|
|
7409
|
+
deps.length ? /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
|
|
7396
7410
|
/* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", style: { paddingTop: 3 }, children: "After" }),
|
|
7397
7411
|
deps.map((d) => /* @__PURE__ */ jsx60(Tag, { icon: d.implemented ? "check" : "clock", children: d.label }, d.key))
|
|
7398
7412
|
] }) : null,
|
|
7399
|
-
blocking.length && !item.implemented ? /* @__PURE__ */
|
|
7413
|
+
blocking.length && !item.implemented ? /* @__PURE__ */ jsxs56("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
|
|
7400
7414
|
"Blocked until ",
|
|
7401
7415
|
blocking.map((d) => d.label).join(" and "),
|
|
7402
7416
|
" ",
|
|
@@ -7407,12 +7421,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
7407
7421
|
}
|
|
7408
7422
|
function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
7409
7423
|
const session = SessionKit.useSession();
|
|
7410
|
-
const [project, setProject] =
|
|
7411
|
-
const [q, setQ] =
|
|
7412
|
-
const scrollRef =
|
|
7413
|
-
const nowRef =
|
|
7414
|
-
const rm =
|
|
7415
|
-
const byKey =
|
|
7424
|
+
const [project, setProject] = React35.useState("");
|
|
7425
|
+
const [q, setQ] = React35.useState("");
|
|
7426
|
+
const scrollRef = React35.useRef(null);
|
|
7427
|
+
const nowRef = React35.useRef(null);
|
|
7428
|
+
const rm = React35.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
|
|
7429
|
+
const byKey = React35.useMemo(() => {
|
|
7416
7430
|
const m = {};
|
|
7417
7431
|
rm.items.forEach((i) => {
|
|
7418
7432
|
m[i.key] = i;
|
|
@@ -7421,7 +7435,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
7421
7435
|
}, [rm]);
|
|
7422
7436
|
const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
|
|
7423
7437
|
const projects = [...new Set(rm.items.map((i) => i.project))];
|
|
7424
|
-
|
|
7438
|
+
React35.useEffect(() => {
|
|
7425
7439
|
let raf1 = 0, raf2 = 0;
|
|
7426
7440
|
const place = () => {
|
|
7427
7441
|
const box = scrollRef.current, mark = nowRef.current;
|
|
@@ -7449,19 +7463,19 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
7449
7463
|
}, 0);
|
|
7450
7464
|
const nextPhase = items.find((i) => !i.implemented);
|
|
7451
7465
|
let lastPhase = null;
|
|
7452
|
-
return /* @__PURE__ */
|
|
7453
|
-
/* @__PURE__ */
|
|
7466
|
+
return /* @__PURE__ */ jsxs56("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
|
|
7467
|
+
/* @__PURE__ */ jsxs56("div", { className: "fd-stack", style: { gap: 10 }, children: [
|
|
7454
7468
|
/* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", children: "Architecture" }),
|
|
7455
7469
|
/* @__PURE__ */ jsx60("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
|
|
7456
7470
|
/* @__PURE__ */ jsx60("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: lede || "Every screen and feature in these tools is already designed and working against a simulated backend. This is the plan for connecting them to the real one \u2014 so the only work described here is server work." })
|
|
7457
7471
|
] }),
|
|
7458
|
-
/* @__PURE__ */
|
|
7472
|
+
/* @__PURE__ */ jsxs56("div", { className: "fd-grid-stats is-thin", children: [
|
|
7459
7473
|
/* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Wired", value: String(rm.shipped), sub: "of " + rm.items.length + " features" }),
|
|
7460
7474
|
/* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Remaining", value: String(rm.remaining), sub: "backend work" }),
|
|
7461
7475
|
/* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Est. effort", value: days ? days + " days" : "\u2014", sub: "sum of estimates, not calendar" }),
|
|
7462
7476
|
/* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Up next", value: nextPhase ? "Phase " + nextPhase.phase : "\u2014", sub: nextPhase ? nextPhase.phaseName : "all wired" })
|
|
7463
7477
|
] }),
|
|
7464
|
-
/* @__PURE__ */
|
|
7478
|
+
/* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
|
|
7465
7479
|
/* @__PURE__ */ jsx60(Input, { icon: "magnifying-glass", placeholder: "Find a feature or a piece of backend work", value: q, onChange: (e) => setQ(e.target.value), style: { width: 300 } }),
|
|
7466
7480
|
/* @__PURE__ */ jsx60(Select, { placeholder: "All projects", value: project, onChange: (e) => setProject(e.target.value), options: projects, style: { width: 190 } }),
|
|
7467
7481
|
/* @__PURE__ */ jsx60("span", { style: { flex: 1 } }),
|
|
@@ -7488,23 +7502,23 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
7488
7502
|
actions: null
|
|
7489
7503
|
}
|
|
7490
7504
|
),
|
|
7491
|
-
/* @__PURE__ */ jsx60("div", { className: "fd-rm", children: /* @__PURE__ */ jsx60("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */
|
|
7505
|
+
/* @__PURE__ */ jsx60("div", { className: "fd-rm", children: /* @__PURE__ */ jsx60("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs56("div", { className: "fd-rm-track", children: [
|
|
7492
7506
|
/* @__PURE__ */ jsx60("span", { className: "fd-rm-spine", children: /* @__PURE__ */ jsx60("span", { className: "fd-rm-spine-done", style: { height: items.length ? 100 * shippedShown / items.length + "%" : "0%" } }) }),
|
|
7493
7507
|
items.map((item, n) => {
|
|
7494
7508
|
const showPhase = item.phase !== lastPhase;
|
|
7495
7509
|
lastPhase = item.phase;
|
|
7496
7510
|
const inPhase = items.filter((i) => i.phase === item.phase).length;
|
|
7497
7511
|
const isBoundary = n === firstPending;
|
|
7498
|
-
return /* @__PURE__ */
|
|
7499
|
-
showPhase ? /* @__PURE__ */
|
|
7500
|
-
/* @__PURE__ */
|
|
7512
|
+
return /* @__PURE__ */ jsxs56(React35.Fragment, { children: [
|
|
7513
|
+
showPhase ? /* @__PURE__ */ jsxs56("div", { className: "fd-rm-era", children: [
|
|
7514
|
+
/* @__PURE__ */ jsxs56("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
|
|
7501
7515
|
/* @__PURE__ */ jsx60("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
|
|
7502
|
-
item.phase === 0 ? null : /* @__PURE__ */
|
|
7516
|
+
item.phase === 0 ? null : /* @__PURE__ */ jsxs56("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
|
|
7503
7517
|
fmtDate(item.phaseStart),
|
|
7504
7518
|
" \u2013 ",
|
|
7505
7519
|
fmtDate(item.date)
|
|
7506
7520
|
] }),
|
|
7507
|
-
/* @__PURE__ */
|
|
7521
|
+
/* @__PURE__ */ jsxs56("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
|
|
7508
7522
|
"\xB7 ",
|
|
7509
7523
|
inPhase,
|
|
7510
7524
|
" feature",
|
|
@@ -7513,13 +7527,13 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
7513
7527
|
] }),
|
|
7514
7528
|
item.phaseWhy ? /* @__PURE__ */ jsx60("p", { className: "fd-rm-era-why", children: item.phaseWhy }) : null
|
|
7515
7529
|
] }) : null,
|
|
7516
|
-
isBoundary ? /* @__PURE__ */ jsx60("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */
|
|
7530
|
+
isBoundary ? /* @__PURE__ */ jsx60("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs56("span", { className: "fd-rm-now-pill", children: [
|
|
7517
7531
|
/* @__PURE__ */ jsx60("i", { className: "ph ph-map-pin" }),
|
|
7518
7532
|
" You are here \u2014 everything above is wired"
|
|
7519
7533
|
] }) }) : null,
|
|
7520
|
-
/* @__PURE__ */
|
|
7534
|
+
/* @__PURE__ */ jsxs56("div", { className: "fd-rm-row", children: [
|
|
7521
7535
|
/* @__PURE__ */ jsx60("span", { className: "fd-rm-dot " + (item.implemented ? "is-shipped" : item.status === "next" ? "is-next" : "") }),
|
|
7522
|
-
/* @__PURE__ */
|
|
7536
|
+
/* @__PURE__ */ jsxs56("div", { className: "fd-rm-date", children: [
|
|
7523
7537
|
fmtDate(item.date),
|
|
7524
7538
|
/* @__PURE__ */ jsx60("br", {}),
|
|
7525
7539
|
/* @__PURE__ */ jsx60("span", { style: { opacity: 0.75 }, children: item.implemented ? "shipped" : "phase " + item.phase })
|
|
@@ -7530,7 +7544,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
7530
7544
|
}),
|
|
7531
7545
|
!items.length ? /* @__PURE__ */ jsx60("p", { className: "fd-body-sm fd-muted", children: "Nothing matches that filter." }) : null
|
|
7532
7546
|
] }) }) }),
|
|
7533
|
-
/* @__PURE__ */
|
|
7547
|
+
/* @__PURE__ */ jsxs56("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
|
|
7534
7548
|
"Derived from the feature-flag registry \u2014 each entry's status is its flag's ",
|
|
7535
7549
|
/* @__PURE__ */ jsx60("code", { className: "fd-mono", children: "implemented" }),
|
|
7536
7550
|
" field, so this page cannot drift from what the apps actually do."
|
|
@@ -7539,9 +7553,10 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
7539
7553
|
}
|
|
7540
7554
|
|
|
7541
7555
|
// src/components/platform/ComingSoon.tsx
|
|
7542
|
-
import * as
|
|
7556
|
+
import * as React36 from "react";
|
|
7543
7557
|
import { createPortal as createPortal5 } from "react-dom";
|
|
7544
|
-
import { Fragment as Fragment16, jsx as jsx61, jsxs as
|
|
7558
|
+
import { Fragment as Fragment16, jsx as jsx61, jsxs as jsxs57 } from "react/jsx-runtime";
|
|
7559
|
+
var SOON_HOVERCARD_BASE = 220;
|
|
7545
7560
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
7546
7561
|
function readBypassed() {
|
|
7547
7562
|
try {
|
|
@@ -7557,8 +7572,8 @@ function writeBypassed(list) {
|
|
|
7557
7572
|
}
|
|
7558
7573
|
}
|
|
7559
7574
|
function useBypass(key) {
|
|
7560
|
-
const [on, setOn] =
|
|
7561
|
-
|
|
7575
|
+
const [on, setOn] = React36.useState(() => !!key && readBypassed().indexOf(key) >= 0);
|
|
7576
|
+
React36.useEffect(() => {
|
|
7562
7577
|
setOn(!!key && readBypassed().indexOf(key) >= 0);
|
|
7563
7578
|
}, [key]);
|
|
7564
7579
|
const set = (next) => {
|
|
@@ -7571,43 +7586,43 @@ function useBypass(key) {
|
|
|
7571
7586
|
return [on, set];
|
|
7572
7587
|
}
|
|
7573
7588
|
function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }) {
|
|
7574
|
-
return /* @__PURE__ */
|
|
7575
|
-
/* @__PURE__ */
|
|
7589
|
+
return /* @__PURE__ */ jsxs57(Fragment16, { children: [
|
|
7590
|
+
/* @__PURE__ */ jsxs57("span", { className: "fd-soon-badge", children: [
|
|
7576
7591
|
/* @__PURE__ */ jsx61("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
|
|
7577
7592
|
label
|
|
7578
7593
|
] }),
|
|
7579
7594
|
detail ? /* @__PURE__ */ jsx61("span", { className: "fd-soon-detail", children: detail }) : null,
|
|
7580
|
-
backend ? /* @__PURE__ */
|
|
7595
|
+
backend ? /* @__PURE__ */ jsxs57("span", { className: "fd-soon-backend", children: [
|
|
7581
7596
|
/* @__PURE__ */ jsx61("span", { className: "fd-overline", children: "Needs" }),
|
|
7582
7597
|
" ",
|
|
7583
7598
|
backend
|
|
7584
7599
|
] }) : null,
|
|
7585
|
-
eta || effort || onRoadmap ? /* @__PURE__ */
|
|
7586
|
-
eta ? /* @__PURE__ */
|
|
7600
|
+
eta || effort || onRoadmap ? /* @__PURE__ */ jsxs57("span", { className: "fd-soon-meta", children: [
|
|
7601
|
+
eta ? /* @__PURE__ */ jsxs57("span", { children: [
|
|
7587
7602
|
/* @__PURE__ */ jsx61("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }),
|
|
7588
7603
|
" ",
|
|
7589
7604
|
eta
|
|
7590
7605
|
] }) : null,
|
|
7591
|
-
effort ? /* @__PURE__ */
|
|
7606
|
+
effort ? /* @__PURE__ */ jsxs57("span", { children: [
|
|
7592
7607
|
/* @__PURE__ */ jsx61("i", { className: "ph ph-hourglass-medium", "aria-hidden": "true" }),
|
|
7593
7608
|
" ",
|
|
7594
7609
|
effort
|
|
7595
7610
|
] }) : null,
|
|
7596
|
-
onRoadmap ? /* @__PURE__ */
|
|
7611
|
+
onRoadmap ? /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
|
|
7597
7612
|
"See the roadmap ",
|
|
7598
7613
|
/* @__PURE__ */ jsx61("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
|
|
7599
7614
|
] }) : null
|
|
7600
7615
|
] }) : null,
|
|
7601
|
-
allowed ? /* @__PURE__ */
|
|
7616
|
+
allowed ? /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
|
|
7602
7617
|
/* @__PURE__ */ jsx61("i", { className: "ph ph-eye", "aria-hidden": "true" }),
|
|
7603
7618
|
" View and use it anyway"
|
|
7604
7619
|
] }) : null
|
|
7605
7620
|
] });
|
|
7606
7621
|
}
|
|
7607
7622
|
function useHoverCard(open) {
|
|
7608
|
-
const anchor =
|
|
7609
|
-
const [pos, setPos] =
|
|
7610
|
-
|
|
7623
|
+
const anchor = React36.useRef(null);
|
|
7624
|
+
const [pos, setPos] = React36.useState(null);
|
|
7625
|
+
React36.useLayoutEffect(() => {
|
|
7611
7626
|
if (!open || !anchor.current) {
|
|
7612
7627
|
setPos(null);
|
|
7613
7628
|
return;
|
|
@@ -7659,7 +7674,7 @@ function ComingSoon({
|
|
|
7659
7674
|
const tip = [label, detail, backend ? "Needs " + backend : null, eta ? "ETA " + eta : null, effort].filter(Boolean).join(" \xB7 ");
|
|
7660
7675
|
if (inline) {
|
|
7661
7676
|
if (allowed && bypassed) {
|
|
7662
|
-
return /* @__PURE__ */
|
|
7677
|
+
return /* @__PURE__ */ jsxs57("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
|
|
7663
7678
|
children,
|
|
7664
7679
|
/* @__PURE__ */ jsx61(
|
|
7665
7680
|
"button",
|
|
@@ -7694,19 +7709,19 @@ function ComingSoon({
|
|
|
7694
7709
|
);
|
|
7695
7710
|
}
|
|
7696
7711
|
if (allowed && bypassed) {
|
|
7697
|
-
return /* @__PURE__ */
|
|
7698
|
-
/* @__PURE__ */
|
|
7699
|
-
/* @__PURE__ */
|
|
7712
|
+
return /* @__PURE__ */ jsxs57("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
|
|
7713
|
+
/* @__PURE__ */ jsxs57("div", { className: "fd-soon-bar", role: "status", children: [
|
|
7714
|
+
/* @__PURE__ */ jsxs57("span", { className: "fd-soon-badge", children: [
|
|
7700
7715
|
/* @__PURE__ */ jsx61("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
|
|
7701
7716
|
"Unwired feature \u2014 you are using it anyway"
|
|
7702
7717
|
] }),
|
|
7703
7718
|
/* @__PURE__ */ jsx61("span", { className: "fd-soon-bar-detail", children: "Every action here writes to the simulated backend, so nothing you do persists beyond this session." }),
|
|
7704
|
-
/* @__PURE__ */
|
|
7705
|
-
onRoadmap ? /* @__PURE__ */
|
|
7719
|
+
/* @__PURE__ */ jsxs57("span", { className: "fd-soon-bar-actions", children: [
|
|
7720
|
+
onRoadmap ? /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
|
|
7706
7721
|
"Roadmap ",
|
|
7707
7722
|
/* @__PURE__ */ jsx61("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
|
|
7708
7723
|
] }) : null,
|
|
7709
|
-
/* @__PURE__ */
|
|
7724
|
+
/* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
|
|
7710
7725
|
/* @__PURE__ */ jsx61("i", { className: "ph ph-eye-slash", "aria-hidden": "true" }),
|
|
7711
7726
|
" Re-blur"
|
|
7712
7727
|
] })
|
|
@@ -7715,7 +7730,7 @@ function ComingSoon({
|
|
|
7715
7730
|
children
|
|
7716
7731
|
] });
|
|
7717
7732
|
}
|
|
7718
|
-
return /* @__PURE__ */
|
|
7733
|
+
return /* @__PURE__ */ jsxs57("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
|
|
7719
7734
|
/* @__PURE__ */ jsx61("div", { className: "fd-soon-under", style: { filter: "blur(" + blur + "px) saturate(.62)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
|
|
7720
7735
|
/* @__PURE__ */ jsx61("div", { className: "fd-soon-veil" }),
|
|
7721
7736
|
/* @__PURE__ */ jsx61("div", { className: "fd-soon-note", role: "note", children: /* @__PURE__ */ jsx61(
|
|
@@ -7734,9 +7749,10 @@ function ComingSoon({
|
|
|
7734
7749
|
] });
|
|
7735
7750
|
}
|
|
7736
7751
|
function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
|
|
7737
|
-
const [open, setOpen] =
|
|
7752
|
+
const [open, setOpen] = React36.useState(false);
|
|
7738
7753
|
const [anchor, pos] = useHoverCard(open);
|
|
7739
|
-
const
|
|
7754
|
+
const zIndex = useOverlayLayer(SOON_HOVERCARD_BASE);
|
|
7755
|
+
const close = React36.useRef(null);
|
|
7740
7756
|
const show = () => {
|
|
7741
7757
|
if (close.current) {
|
|
7742
7758
|
clearTimeout(close.current);
|
|
@@ -7752,10 +7768,10 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
7752
7768
|
setOpen(false);
|
|
7753
7769
|
}, 140);
|
|
7754
7770
|
};
|
|
7755
|
-
|
|
7771
|
+
React36.useEffect(() => () => {
|
|
7756
7772
|
if (close.current) clearTimeout(close.current);
|
|
7757
7773
|
}, []);
|
|
7758
|
-
return /* @__PURE__ */
|
|
7774
|
+
return /* @__PURE__ */ jsxs57(
|
|
7759
7775
|
"span",
|
|
7760
7776
|
{
|
|
7761
7777
|
ref: anchor,
|
|
@@ -7782,12 +7798,12 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
7782
7798
|
}
|
|
7783
7799
|
),
|
|
7784
7800
|
open && pos ? createPortal5(
|
|
7785
|
-
/* @__PURE__ */ jsx61(
|
|
7801
|
+
/* @__PURE__ */ jsx61(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx61(
|
|
7786
7802
|
"div",
|
|
7787
7803
|
{
|
|
7788
7804
|
className: "fd-soon-note fd-soon-hovercard",
|
|
7789
7805
|
role: "tooltip",
|
|
7790
|
-
style: { position: "fixed", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width },
|
|
7806
|
+
style: { position: "fixed", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width, zIndex },
|
|
7791
7807
|
onMouseEnter: show,
|
|
7792
7808
|
onMouseLeave: hide,
|
|
7793
7809
|
children: /* @__PURE__ */ jsx61(
|
|
@@ -7804,7 +7820,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
7804
7820
|
}
|
|
7805
7821
|
)
|
|
7806
7822
|
}
|
|
7807
|
-
),
|
|
7823
|
+
) }),
|
|
7808
7824
|
document.body
|
|
7809
7825
|
) : null
|
|
7810
7826
|
]
|
|
@@ -7820,10 +7836,10 @@ function formatEta(iso2) {
|
|
|
7820
7836
|
var FormatEta = formatEta;
|
|
7821
7837
|
|
|
7822
7838
|
// src/components/platform/Gate.tsx
|
|
7823
|
-
import { jsx as jsx62, jsxs as
|
|
7839
|
+
import { jsx as jsx62, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
7824
7840
|
function PermissionDenied({ permission, title, detail, compact: compact3 = false, className = "", ...rest }) {
|
|
7825
7841
|
const need = Array.isArray(permission) ? permission : [permission].filter(Boolean);
|
|
7826
|
-
return /* @__PURE__ */
|
|
7842
|
+
return /* @__PURE__ */ jsxs58(
|
|
7827
7843
|
"div",
|
|
7828
7844
|
{
|
|
7829
7845
|
className: ["fd-stack", className].filter(Boolean).join(" "),
|
|
@@ -7839,12 +7855,12 @@ function PermissionDenied({ permission, title, detail, compact: compact3 = false
|
|
|
7839
7855
|
},
|
|
7840
7856
|
...rest,
|
|
7841
7857
|
children: [
|
|
7842
|
-
/* @__PURE__ */
|
|
7858
|
+
/* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 8 }, children: [
|
|
7843
7859
|
/* @__PURE__ */ jsx62("i", { className: "ph ph-lock-simple", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
|
|
7844
7860
|
/* @__PURE__ */ jsx62("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: title || "You do not have access to this" })
|
|
7845
7861
|
] }),
|
|
7846
7862
|
/* @__PURE__ */ jsx62("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: detail || "Your roles do not grant this. An administrator can change that from Admin \u2192 Users." }),
|
|
7847
|
-
need.length ? /* @__PURE__ */
|
|
7863
|
+
need.length ? /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
|
|
7848
7864
|
/* @__PURE__ */ jsx62("span", { className: "fd-overline fd-muted", children: "Requires" }),
|
|
7849
7865
|
need.map((p) => /* @__PURE__ */ jsx62("code", { className: "fd-mono", style: {
|
|
7850
7866
|
fontSize: 11.5,
|
|
@@ -7921,13 +7937,15 @@ function PermissionHint({ perm, children }) {
|
|
|
7921
7937
|
}
|
|
7922
7938
|
|
|
7923
7939
|
// src/components/platform/ModeSwitch.tsx
|
|
7924
|
-
import * as
|
|
7925
|
-
import { Fragment as Fragment17, jsx as jsx63, jsxs as
|
|
7940
|
+
import * as React37 from "react";
|
|
7941
|
+
import { Fragment as Fragment17, jsx as jsx63, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
7942
|
+
var MODE_SWITCH_BASE = 140;
|
|
7926
7943
|
function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
|
|
7927
7944
|
const mode2 = useRuntimeMode();
|
|
7928
|
-
const [open, setOpen] =
|
|
7929
|
-
const
|
|
7930
|
-
|
|
7945
|
+
const [open, setOpen] = React37.useState(false);
|
|
7946
|
+
const zIndex = useOverlayLayer(MODE_SWITCH_BASE);
|
|
7947
|
+
const ref = React37.useRef(null);
|
|
7948
|
+
React37.useEffect(() => {
|
|
7931
7949
|
if (!open) return;
|
|
7932
7950
|
const away = (e) => {
|
|
7933
7951
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -7949,8 +7967,8 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
7949
7967
|
RuntimeKit.setMode(next);
|
|
7950
7968
|
setOpen(false);
|
|
7951
7969
|
};
|
|
7952
|
-
return /* @__PURE__ */
|
|
7953
|
-
/* @__PURE__ */
|
|
7970
|
+
return /* @__PURE__ */ jsxs59("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
|
|
7971
|
+
/* @__PURE__ */ jsxs59(
|
|
7954
7972
|
"button",
|
|
7955
7973
|
{
|
|
7956
7974
|
type: "button",
|
|
@@ -7965,13 +7983,13 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
7965
7983
|
]
|
|
7966
7984
|
}
|
|
7967
7985
|
),
|
|
7968
|
-
open ? /* @__PURE__ */
|
|
7969
|
-
/* @__PURE__ */
|
|
7970
|
-
/* @__PURE__ */
|
|
7986
|
+
open ? /* @__PURE__ */ jsx63(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs59("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
|
|
7987
|
+
/* @__PURE__ */ jsxs59("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
|
|
7988
|
+
/* @__PURE__ */ jsxs59("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
|
|
7971
7989
|
/* @__PURE__ */ jsx63("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
|
|
7972
7990
|
test ? "Test mode" : "Live mode"
|
|
7973
7991
|
] }),
|
|
7974
|
-
test ? /* @__PURE__ */
|
|
7992
|
+
test ? /* @__PURE__ */ jsxs59("span", { className: "fd-body-sm fd-muted fd-mono", children: [
|
|
7975
7993
|
requestCount,
|
|
7976
7994
|
" simulated request",
|
|
7977
7995
|
requestCount === 1 ? "" : "s"
|
|
@@ -7979,10 +7997,10 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
7979
7997
|
/* @__PURE__ */ jsx63("span", { style: { flex: 1 } }),
|
|
7980
7998
|
test && onClearLog ? /* @__PURE__ */ jsx63("button", { type: "button", className: "fd-soon-link", onClick: onClearLog, children: "Clear" }) : null
|
|
7981
7999
|
] }),
|
|
7982
|
-
/* @__PURE__ */
|
|
8000
|
+
/* @__PURE__ */ jsxs59("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
|
|
7983
8001
|
/* @__PURE__ */ jsx63("span", { className: "fd-body-sm fd-secondary", style: { display: "block", textWrap: "pretty" }, children: test ? "Every feature is usable and nothing is obstructed, but no response comes from a real service \u2014 nothing you do here persists. Use this to review and demo the design." : "This is what a user would see today. " + s.incomplete + " of " + s.total + " features depend on backend work that is not wired yet, so they render under construction." }),
|
|
7984
|
-
/* @__PURE__ */
|
|
7985
|
-
/* @__PURE__ */
|
|
8002
|
+
/* @__PURE__ */ jsxs59("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
|
|
8003
|
+
/* @__PURE__ */ jsxs59("span", { className: "fd-body-sm fd-muted fd-mono", children: [
|
|
7986
8004
|
s.endpointsWired,
|
|
7987
8005
|
" endpoint",
|
|
7988
8006
|
s.endpointsWired === 1 ? "" : "s",
|
|
@@ -7992,9 +8010,9 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
7992
8010
|
s.total,
|
|
7993
8011
|
" features complete"
|
|
7994
8012
|
] }),
|
|
7995
|
-
onOpenSpec ? /* @__PURE__ */
|
|
8013
|
+
onOpenSpec ? /* @__PURE__ */ jsxs59(Fragment17, { children: [
|
|
7996
8014
|
/* @__PURE__ */ jsx63("span", { style: { flex: 1 } }),
|
|
7997
|
-
/* @__PURE__ */
|
|
8015
|
+
/* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-soon-link", onClick: () => {
|
|
7998
8016
|
setOpen(false);
|
|
7999
8017
|
onOpenSpec();
|
|
8000
8018
|
}, children: [
|
|
@@ -8004,18 +8022,18 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
8004
8022
|
] }) : null
|
|
8005
8023
|
] })
|
|
8006
8024
|
] }),
|
|
8007
|
-
/* @__PURE__ */
|
|
8008
|
-
/* @__PURE__ */
|
|
8025
|
+
/* @__PURE__ */ jsxs59("span", { className: "fd-mode-choice", children: [
|
|
8026
|
+
/* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
|
|
8009
8027
|
/* @__PURE__ */ jsx63("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
|
|
8010
|
-
/* @__PURE__ */
|
|
8028
|
+
/* @__PURE__ */ jsxs59("span", { className: "fd-mode-opt-text", children: [
|
|
8011
8029
|
/* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-title", children: "Live mode" }),
|
|
8012
8030
|
/* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-desc", children: "Incomplete features under construction" })
|
|
8013
8031
|
] }),
|
|
8014
8032
|
!test ? /* @__PURE__ */ jsx63("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
|
|
8015
8033
|
] }),
|
|
8016
|
-
/* @__PURE__ */
|
|
8034
|
+
/* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
|
|
8017
8035
|
/* @__PURE__ */ jsx63("i", { className: "ph ph-flask", "aria-hidden": "true" }),
|
|
8018
|
-
/* @__PURE__ */
|
|
8036
|
+
/* @__PURE__ */ jsxs59("span", { className: "fd-mode-opt-text", children: [
|
|
8019
8037
|
/* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-title", children: "Test mode" }),
|
|
8020
8038
|
/* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-desc", children: "Everything usable, all data simulated" })
|
|
8021
8039
|
] }),
|
|
@@ -8023,19 +8041,19 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
8023
8041
|
] })
|
|
8024
8042
|
] }),
|
|
8025
8043
|
test && renderLog ? /* @__PURE__ */ jsx63("span", { style: { display: "block", maxHeight: 340, overflowY: "auto", borderTop: "1px solid var(--border)" }, children: renderLog() }) : null
|
|
8026
|
-
] }) : null
|
|
8044
|
+
] }) }) : null
|
|
8027
8045
|
] });
|
|
8028
8046
|
}
|
|
8029
8047
|
function TestModeBar({ onExit }) {
|
|
8030
8048
|
const mode2 = useRuntimeMode();
|
|
8031
8049
|
if (mode2 !== "test") return null;
|
|
8032
|
-
return /* @__PURE__ */
|
|
8033
|
-
/* @__PURE__ */
|
|
8050
|
+
return /* @__PURE__ */ jsxs59("div", { className: "fd-testbar", role: "status", children: [
|
|
8051
|
+
/* @__PURE__ */ jsxs59("span", { className: "fd-badge fd-badge-warning", children: [
|
|
8034
8052
|
/* @__PURE__ */ jsx63("i", { className: "ph ph-flask", "aria-hidden": "true" }),
|
|
8035
8053
|
"Test mode"
|
|
8036
8054
|
] }),
|
|
8037
8055
|
/* @__PURE__ */ jsx63("span", { className: "fd-testbar-detail", children: "Every feature is unlocked and every response is simulated \u2014 nothing here persists." }),
|
|
8038
|
-
/* @__PURE__ */
|
|
8056
|
+
/* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
|
|
8039
8057
|
/* @__PURE__ */ jsx63("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
|
|
8040
8058
|
" Back to live mode"
|
|
8041
8059
|
] })
|
|
@@ -8043,7 +8061,7 @@ function TestModeBar({ onExit }) {
|
|
|
8043
8061
|
}
|
|
8044
8062
|
|
|
8045
8063
|
// src/components/planner/ChannelMeta.tsx
|
|
8046
|
-
import { jsx as jsx64, jsxs as
|
|
8064
|
+
import { jsx as jsx64, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
8047
8065
|
var CHANNEL_WEIGHTS = {
|
|
8048
8066
|
"OOH": 50,
|
|
8049
8067
|
"DOOH": 50,
|
|
@@ -8098,7 +8116,7 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
|
|
|
8098
8116
|
if (dot) {
|
|
8099
8117
|
return /* @__PURE__ */ jsx64("span", { className: ["fd-chan-dot", className].filter(Boolean).join(" "), title: m.name, style: { background: m.color }, ...rest });
|
|
8100
8118
|
}
|
|
8101
|
-
return /* @__PURE__ */
|
|
8119
|
+
return /* @__PURE__ */ jsxs60(
|
|
8102
8120
|
"span",
|
|
8103
8121
|
{
|
|
8104
8122
|
className: ["fd-chan", size === "sm" ? "fd-chan-sm" : "", className].filter(Boolean).join(" "),
|
|
@@ -8115,7 +8133,7 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
|
|
|
8115
8133
|
}
|
|
8116
8134
|
|
|
8117
8135
|
// src/components/planner/SaturationDistribution.tsx
|
|
8118
|
-
import { jsx as jsx65, jsxs as
|
|
8136
|
+
import { jsx as jsx65, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
8119
8137
|
var BANDS2 = [
|
|
8120
8138
|
{ key: "weak", label: "Weak", n: 1, range: "< 50" },
|
|
8121
8139
|
{ key: "adequate", label: "Adequate", n: 2, range: "50\u2013100" },
|
|
@@ -8126,11 +8144,11 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
8126
8144
|
const grouped = BANDS2.map((b) => ({ ...b, items: campuses.filter((c) => c.band === b.key) }));
|
|
8127
8145
|
const tallest = Math.max(1, ...grouped.map((g) => g.items.length));
|
|
8128
8146
|
const floor = BANDS2.find((b) => b.key === floorBand) || BANDS2[0];
|
|
8129
|
-
return /* @__PURE__ */
|
|
8147
|
+
return /* @__PURE__ */ jsxs61("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
|
|
8130
8148
|
/* @__PURE__ */ jsx65("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 12, alignItems: "end" }, children: grouped.map((g) => {
|
|
8131
8149
|
const mark = "var(--csi-" + g.n + "-mark)";
|
|
8132
8150
|
const active = selectedBand === g.key;
|
|
8133
|
-
return /* @__PURE__ */
|
|
8151
|
+
return /* @__PURE__ */ jsxs61(
|
|
8134
8152
|
"button",
|
|
8135
8153
|
{
|
|
8136
8154
|
type: "button",
|
|
@@ -8146,13 +8164,13 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
8146
8164
|
},
|
|
8147
8165
|
c.name
|
|
8148
8166
|
)) }),
|
|
8149
|
-
/* @__PURE__ */
|
|
8167
|
+
/* @__PURE__ */ jsxs61("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
|
|
8150
8168
|
/* @__PURE__ */ jsx65("span", { className: "fd-num-hero", style: { fontSize: 30, color: g.items.length ? "var(--text)" : "var(--text-disabled)" }, children: loading ? "\u2013" : g.items.length }),
|
|
8151
8169
|
/* @__PURE__ */ jsx65("span", { className: "fd-meter", style: { gap: 2, color: mark }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx65("span", { className: "fd-meter-seg" + (i <= g.n ? " is-on" : ""), style: { width: 4, height: 9 } }, i)) })
|
|
8152
8170
|
] }),
|
|
8153
|
-
/* @__PURE__ */
|
|
8171
|
+
/* @__PURE__ */ jsxs61("span", { className: "fd-stack", style: { gap: 1 }, children: [
|
|
8154
8172
|
/* @__PURE__ */ jsx65("span", { className: "fd-label-lg", children: g.label }),
|
|
8155
|
-
/* @__PURE__ */
|
|
8173
|
+
/* @__PURE__ */ jsxs61("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
|
|
8156
8174
|
"CRP ",
|
|
8157
8175
|
g.range
|
|
8158
8176
|
] })
|
|
@@ -8162,10 +8180,10 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
8162
8180
|
g.key
|
|
8163
8181
|
);
|
|
8164
8182
|
}) }),
|
|
8165
|
-
floorBand ? /* @__PURE__ */
|
|
8183
|
+
floorBand ? /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderRadius: "var(--r-md)", background: "var(--surface-2)", border: "1px solid var(--border)", flexWrap: "wrap" }, children: [
|
|
8166
8184
|
/* @__PURE__ */ jsx65("span", { className: "fd-meter", style: { gap: 2, color: "var(--csi-" + floor.n + "-mark)" }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx65("span", { className: "fd-meter-seg" + (i <= floor.n ? " is-on" : ""), style: { width: 5, height: 12 } }, i)) }),
|
|
8167
|
-
/* @__PURE__ */
|
|
8168
|
-
/* @__PURE__ */
|
|
8185
|
+
/* @__PURE__ */ jsxs61("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
|
|
8186
|
+
/* @__PURE__ */ jsxs61("strong", { style: { color: "var(--text)" }, children: [
|
|
8169
8187
|
"Plan floor ",
|
|
8170
8188
|
floorScore
|
|
8171
8189
|
] }),
|
|
@@ -8176,8 +8194,8 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
8176
8194
|
}
|
|
8177
8195
|
|
|
8178
8196
|
// src/components/planner/MixGap.tsx
|
|
8179
|
-
import * as
|
|
8180
|
-
import { Fragment as Fragment18, jsx as jsx66, jsxs as
|
|
8197
|
+
import * as React38 from "react";
|
|
8198
|
+
import { Fragment as Fragment18, jsx as jsx66, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
8181
8199
|
var MIX_GAP_LAYOUT = {
|
|
8182
8200
|
trackHeight: 30,
|
|
8183
8201
|
barHeight: 20,
|
|
@@ -8191,18 +8209,18 @@ function mixGapOffset(value, max) {
|
|
|
8191
8209
|
}
|
|
8192
8210
|
function MixGap({ rows = [], loading = false, className = "" }) {
|
|
8193
8211
|
const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
|
|
8194
|
-
const [hover, setHover] =
|
|
8212
|
+
const [hover, setHover] = React38.useState(null);
|
|
8195
8213
|
const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
|
|
8196
8214
|
const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
|
|
8197
8215
|
const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
|
|
8198
8216
|
const barTop = (trackHeight - barHeight) / 2;
|
|
8199
|
-
return /* @__PURE__ */
|
|
8200
|
-
/* @__PURE__ */
|
|
8201
|
-
[["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */
|
|
8217
|
+
return /* @__PURE__ */ jsxs62("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
|
|
8218
|
+
/* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
|
|
8219
|
+
[["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs62("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
|
|
8202
8220
|
/* @__PURE__ */ jsx66("span", { style: { width: 14, height: 9, borderRadius: 2, background: c } }),
|
|
8203
8221
|
l
|
|
8204
8222
|
] }, l)),
|
|
8205
|
-
/* @__PURE__ */
|
|
8223
|
+
/* @__PURE__ */ jsxs62("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
|
|
8206
8224
|
/* @__PURE__ */ jsx66("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
|
|
8207
8225
|
"Target"
|
|
8208
8226
|
] })
|
|
@@ -8212,7 +8230,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
|
|
|
8212
8230
|
const tone = toneOf(gap);
|
|
8213
8231
|
const tip = "Realized " + r.realized + "% vs " + r.target + "% target" + (gap < -1 ? " \xB7 " + Math.abs(gap).toFixed(0) + " pts short" : gap > 1 ? " \xB7 " + gap.toFixed(0) + " pts over" : " \xB7 on target") + (r.note ? " \u2014 " + r.note : "");
|
|
8214
8232
|
const labelLeft = r.realized > r.target ? `calc(${mixGapOffset(r.realized, max)} + ${labelGap}px)` : `calc(${mixGapOffset(r.target, max)} + ${targetWidth / 2 + labelGap}px)`;
|
|
8215
|
-
return /* @__PURE__ */
|
|
8233
|
+
return /* @__PURE__ */ jsxs62(
|
|
8216
8234
|
"div",
|
|
8217
8235
|
{
|
|
8218
8236
|
className: "fd-row",
|
|
@@ -8221,10 +8239,10 @@ function MixGap({ rows = [], loading = false, className = "" }) {
|
|
|
8221
8239
|
onMouseLeave: () => setHover(null),
|
|
8222
8240
|
children: [
|
|
8223
8241
|
/* @__PURE__ */ jsx66("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx66(ChannelTag, { channel: r.channel, size: "sm" }) }),
|
|
8224
|
-
/* @__PURE__ */ jsx66("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx66("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */
|
|
8242
|
+
/* @__PURE__ */ jsx66("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx66("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs62(Fragment18, { children: [
|
|
8225
8243
|
/* @__PURE__ */ jsx66("span", { "data-mixgap-bar": "", style: { position: "absolute", left: 0, top: barTop, height: barHeight, width: mixGapOffset(r.realized, max), background: TONE[tone], borderRadius: "2px 3px 3px 2px", transition: "width var(--dur-slow) var(--ease), background var(--dur-base) var(--ease)" } }),
|
|
8226
8244
|
/* @__PURE__ */ jsx66("span", { "data-mixgap-target": "", style: { position: "absolute", left: `calc(${mixGapOffset(r.target, max)} - ${targetWidth / 2}px)`, top: 0, width: targetWidth, height: trackHeight, background: MIX_GAP_TARGET_STRIPE, borderRadius: 1 } }),
|
|
8227
|
-
/* @__PURE__ */
|
|
8245
|
+
/* @__PURE__ */ jsxs62("span", { "data-mixgap-label": "", className: "fd-num", style: { position: "absolute", left: labelLeft, top: "50%", transform: "translateY(-50%)", fontSize: 12, color: "var(--text-muted)", whiteSpace: "nowrap" }, children: [
|
|
8228
8246
|
r.realized,
|
|
8229
8247
|
"%"
|
|
8230
8248
|
] }),
|
|
@@ -8239,7 +8257,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
|
|
|
8239
8257
|
}
|
|
8240
8258
|
|
|
8241
8259
|
// src/components/planner/ChannelContribution.tsx
|
|
8242
|
-
import { jsx as jsx67, jsxs as
|
|
8260
|
+
import { jsx as jsx67, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
8243
8261
|
var money = (n) => "$" + Math.round(n).toLocaleString();
|
|
8244
8262
|
function ChannelContribution({
|
|
8245
8263
|
channels = [],
|
|
@@ -8255,8 +8273,8 @@ function ChannelContribution({
|
|
|
8255
8273
|
const grand = total !== void 0 ? total : base + bonus;
|
|
8256
8274
|
const pct = (v) => grand ? v / grand * 100 : 0;
|
|
8257
8275
|
const spendTotal = channels.reduce((s, c) => s + Number(String(c.spend || 0).replace(/[^0-9.]/g, "")), 0);
|
|
8258
|
-
return /* @__PURE__ */
|
|
8259
|
-
loading ? /* @__PURE__ */ jsx67("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */
|
|
8276
|
+
return /* @__PURE__ */ jsxs63("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
|
|
8277
|
+
loading ? /* @__PURE__ */ jsx67("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */ jsxs63("div", { className: "fd-row", style: { height: 34, borderRadius: "var(--r-sm)", overflow: "hidden", gap: 2, background: "var(--surface-3)" }, children: [
|
|
8260
8278
|
channels.map((c) => /* @__PURE__ */ jsx67(
|
|
8261
8279
|
"span",
|
|
8262
8280
|
{
|
|
@@ -8275,16 +8293,16 @@ function ChannelContribution({
|
|
|
8275
8293
|
}
|
|
8276
8294
|
) : null
|
|
8277
8295
|
] }),
|
|
8278
|
-
showTable ? /* @__PURE__ */
|
|
8279
|
-
/* @__PURE__ */ jsx67("thead", { children: /* @__PURE__ */
|
|
8296
|
+
showTable ? /* @__PURE__ */ jsxs63("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
|
|
8297
|
+
/* @__PURE__ */ jsx67("thead", { children: /* @__PURE__ */ jsxs63("tr", { children: [
|
|
8280
8298
|
/* @__PURE__ */ jsx67("th", { style: { width: "34%" }, children: "Channel" }),
|
|
8281
8299
|
/* @__PURE__ */ jsx67("th", { style: { width: "16%" }, children: "Weight" }),
|
|
8282
8300
|
/* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "16%" }, children: "Spend" }),
|
|
8283
8301
|
/* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "17%" }, children: "CRP" }),
|
|
8284
8302
|
/* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "17%" }, children: "Share" })
|
|
8285
8303
|
] }) }),
|
|
8286
|
-
/* @__PURE__ */
|
|
8287
|
-
channels.map((c) => /* @__PURE__ */
|
|
8304
|
+
/* @__PURE__ */ jsxs63("tbody", { children: [
|
|
8305
|
+
channels.map((c) => /* @__PURE__ */ jsxs63("tr", { children: [
|
|
8288
8306
|
/* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsx67(ChannelTag, { channel: c.name, size: "sm" }) }),
|
|
8289
8307
|
/* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsx67(
|
|
8290
8308
|
"span",
|
|
@@ -8297,17 +8315,17 @@ function ChannelContribution({
|
|
|
8297
8315
|
) }),
|
|
8298
8316
|
/* @__PURE__ */ jsx67("td", { className: "is-num", children: c.spend }),
|
|
8299
8317
|
/* @__PURE__ */ jsx67("td", { className: "is-num", children: c.crp.toFixed(1) }),
|
|
8300
|
-
/* @__PURE__ */
|
|
8318
|
+
/* @__PURE__ */ jsxs63("td", { className: "is-num", children: [
|
|
8301
8319
|
pct(c.crp).toFixed(0),
|
|
8302
8320
|
"%"
|
|
8303
8321
|
] })
|
|
8304
8322
|
] }, c.name)),
|
|
8305
|
-
bonus > 0 ? /* @__PURE__ */
|
|
8306
|
-
/* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */
|
|
8323
|
+
bonus > 0 ? /* @__PURE__ */ jsxs63("tr", { children: [
|
|
8324
|
+
/* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs63("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
|
|
8307
8325
|
/* @__PURE__ */ jsx67("span", { style: { width: 9, height: 9, borderRadius: 2, background: "repeating-linear-gradient(135deg,var(--csi-3-mark) 0 3px,var(--csi-2-mark) 3px 6px)", flex: "none" } }),
|
|
8308
8326
|
"Surround-sound bonus"
|
|
8309
8327
|
] }) }),
|
|
8310
|
-
/* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */
|
|
8328
|
+
/* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs63("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
|
|
8311
8329
|
"+",
|
|
8312
8330
|
bonusPct,
|
|
8313
8331
|
"% of +",
|
|
@@ -8316,12 +8334,12 @@ function ChannelContribution({
|
|
|
8316
8334
|
] }) }),
|
|
8317
8335
|
/* @__PURE__ */ jsx67("td", { className: "is-num fd-muted", children: "\u2014" }),
|
|
8318
8336
|
/* @__PURE__ */ jsx67("td", { className: "is-num", children: bonus.toFixed(1) }),
|
|
8319
|
-
/* @__PURE__ */
|
|
8337
|
+
/* @__PURE__ */ jsxs63("td", { className: "is-num", children: [
|
|
8320
8338
|
pct(bonus).toFixed(0),
|
|
8321
8339
|
"%"
|
|
8322
8340
|
] })
|
|
8323
8341
|
] }) : null,
|
|
8324
|
-
/* @__PURE__ */
|
|
8342
|
+
/* @__PURE__ */ jsxs63("tr", { style: { background: "var(--surface-2)" }, children: [
|
|
8325
8343
|
/* @__PURE__ */ jsx67("td", { style: { fontWeight: 700 }, children: "Campus total" }),
|
|
8326
8344
|
/* @__PURE__ */ jsx67("td", {}),
|
|
8327
8345
|
/* @__PURE__ */ jsx67("td", { className: "is-num", style: { fontWeight: 700 }, children: money(spendTotal) }),
|
|
@@ -8334,8 +8352,8 @@ function ChannelContribution({
|
|
|
8334
8352
|
}
|
|
8335
8353
|
|
|
8336
8354
|
// src/components/planner/BudgetReallocator.tsx
|
|
8337
|
-
import * as
|
|
8338
|
-
import { Fragment as Fragment19, jsx as jsx68, jsxs as
|
|
8355
|
+
import * as React39 from "react";
|
|
8356
|
+
import { Fragment as Fragment19, jsx as jsx68, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
8339
8357
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
8340
8358
|
function BudgetReallocator({
|
|
8341
8359
|
campus,
|
|
@@ -8350,8 +8368,8 @@ function BudgetReallocator({
|
|
|
8350
8368
|
onCancel,
|
|
8351
8369
|
className = ""
|
|
8352
8370
|
}) {
|
|
8353
|
-
const [draft, setDraft] =
|
|
8354
|
-
|
|
8371
|
+
const [draft, setDraft] = React39.useState(spend);
|
|
8372
|
+
React39.useEffect(() => setDraft(spend), [spend]);
|
|
8355
8373
|
const dirty = draft !== spend;
|
|
8356
8374
|
const nextCrp = scoreFor ? scoreFor(draft) : crp;
|
|
8357
8375
|
const nextBand = bandFor(nextCrp);
|
|
@@ -8366,21 +8384,21 @@ function BudgetReallocator({
|
|
|
8366
8384
|
setDraft(spend);
|
|
8367
8385
|
if (onCancel) onCancel();
|
|
8368
8386
|
};
|
|
8369
|
-
return /* @__PURE__ */
|
|
8387
|
+
return /* @__PURE__ */ jsxs64(
|
|
8370
8388
|
"div",
|
|
8371
8389
|
{
|
|
8372
8390
|
className: ["fd-stack", className].filter(Boolean).join(" "),
|
|
8373
8391
|
style: { gap: 14, padding: 18, border: "1px solid " + (dirty ? "var(--border-brand)" : "var(--border)"), borderRadius: "var(--r-lg)", background: dirty ? "var(--surface-brand)" : "var(--surface)", color: "var(--text)", transition: "background var(--dur-base) var(--ease),border-color var(--dur-base) var(--ease)" },
|
|
8374
8392
|
children: [
|
|
8375
|
-
/* @__PURE__ */
|
|
8393
|
+
/* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
|
|
8376
8394
|
/* @__PURE__ */ jsx68("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
|
|
8377
8395
|
/* @__PURE__ */ jsx68(CsiBadge, { band: nowBand, crp, size: "medium" }),
|
|
8378
|
-
dirty ? /* @__PURE__ */
|
|
8396
|
+
dirty ? /* @__PURE__ */ jsxs64(Fragment19, { children: [
|
|
8379
8397
|
/* @__PURE__ */ jsx68("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
|
|
8380
8398
|
/* @__PURE__ */ jsx68(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
|
|
8381
8399
|
] }) : null
|
|
8382
8400
|
] }),
|
|
8383
|
-
/* @__PURE__ */
|
|
8401
|
+
/* @__PURE__ */ jsxs64("div", { className: "fd-slider", children: [
|
|
8384
8402
|
/* @__PURE__ */ jsx68("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
|
|
8385
8403
|
dirty ? /* @__PURE__ */ jsx68("span", { className: "fd-slider-chip", style: { left: pct + "%", background: delta < 0 ? "var(--danger-solid)" : "var(--ok-solid)" }, children: (delta < 0 ? "\u2212$" : "+$") + Math.abs(delta).toLocaleString() }) : null,
|
|
8386
8404
|
/* @__PURE__ */ jsx68(
|
|
@@ -8399,8 +8417,8 @@ function BudgetReallocator({
|
|
|
8399
8417
|
}
|
|
8400
8418
|
)
|
|
8401
8419
|
] }),
|
|
8402
|
-
/* @__PURE__ */
|
|
8403
|
-
/* @__PURE__ */
|
|
8420
|
+
/* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
|
|
8421
|
+
/* @__PURE__ */ jsxs64("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
|
|
8404
8422
|
/* @__PURE__ */ jsx68("span", { className: "fd-num", style: { fontSize: 19, fontWeight: 700 }, children: "$" + draft.toLocaleString() }),
|
|
8405
8423
|
/* @__PURE__ */ jsx68("span", { className: "fd-body-sm fd-muted", children: "Arrow keys step $100, shift+arrow $1,000. Escape reverts." })
|
|
8406
8424
|
] }),
|
|
@@ -8424,7 +8442,7 @@ function BudgetReallocator({
|
|
|
8424
8442
|
}
|
|
8425
8443
|
|
|
8426
8444
|
// src/components/planner/SurroundSound.tsx
|
|
8427
|
-
import { jsx as jsx69, jsxs as
|
|
8445
|
+
import { jsx as jsx69, jsxs as jsxs65 } from "react/jsx-runtime";
|
|
8428
8446
|
var CATEGORIES = [
|
|
8429
8447
|
{ key: "ooh", label: "OOH", icon: "flag-banner", color: "var(--ch-ooh)" },
|
|
8430
8448
|
{ key: "transit", label: "Transit", icon: "bus", color: "var(--ch-transit)" },
|
|
@@ -8436,10 +8454,10 @@ var CATEGORIES = [
|
|
|
8436
8454
|
function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost, className = "" }) {
|
|
8437
8455
|
const earned = Math.max(0, Math.min(1, bonusPct / bonusMax));
|
|
8438
8456
|
const single = present.length <= 2;
|
|
8439
|
-
return /* @__PURE__ */
|
|
8457
|
+
return /* @__PURE__ */ jsxs65("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
|
|
8440
8458
|
/* @__PURE__ */ jsx69("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: CATEGORIES.map((c) => {
|
|
8441
8459
|
const on = present.includes(c.key);
|
|
8442
|
-
return /* @__PURE__ */
|
|
8460
|
+
return /* @__PURE__ */ jsxs65(
|
|
8443
8461
|
"span",
|
|
8444
8462
|
{
|
|
8445
8463
|
title: c.label + (on ? " \u2014 present" : " \u2014 not bought"),
|
|
@@ -8452,10 +8470,10 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
|
|
|
8452
8470
|
c.key
|
|
8453
8471
|
);
|
|
8454
8472
|
}) }),
|
|
8455
|
-
/* @__PURE__ */
|
|
8456
|
-
/* @__PURE__ */
|
|
8473
|
+
/* @__PURE__ */ jsxs65("div", { className: "fd-stack", style: { gap: 8 }, children: [
|
|
8474
|
+
/* @__PURE__ */ jsxs65("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
|
|
8457
8475
|
/* @__PURE__ */ jsx69("span", { className: "fd-label-lg", children: "Surround-sound bonus earned" }),
|
|
8458
|
-
/* @__PURE__ */
|
|
8476
|
+
/* @__PURE__ */ jsxs65("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
|
|
8459
8477
|
"+",
|
|
8460
8478
|
bonusPct,
|
|
8461
8479
|
"% of +",
|
|
@@ -8464,7 +8482,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
|
|
|
8464
8482
|
] })
|
|
8465
8483
|
] }),
|
|
8466
8484
|
/* @__PURE__ */ jsx69("div", { style: { height: 8, borderRadius: "var(--r-xs)", background: "var(--surface-3)", overflow: "hidden" }, children: /* @__PURE__ */ jsx69("div", { style: { height: "100%", width: earned * 100 + "%", background: "var(--csi-3-mark)", borderRadius: "inherit", transition: "width var(--dur-slow) var(--ease)" } }) }),
|
|
8467
|
-
/* @__PURE__ */
|
|
8485
|
+
/* @__PURE__ */ jsxs65("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
|
|
8468
8486
|
present.length,
|
|
8469
8487
|
" of 6 channel categories present.",
|
|
8470
8488
|
" ",
|
|
@@ -8476,7 +8494,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
|
|
|
8476
8494
|
}
|
|
8477
8495
|
|
|
8478
8496
|
// src/components/planner/Importance.tsx
|
|
8479
|
-
import { jsx as jsx70, jsxs as
|
|
8497
|
+
import { jsx as jsx70, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
8480
8498
|
var IMPORTANCE_LEVELS = [
|
|
8481
8499
|
{ id: "nudge", rank: 1, label: "Nudge", icon: "feather", description: "Breaks a tie, nothing more." },
|
|
8482
8500
|
{ id: "lean", rank: 2, label: "Lean", icon: "arrow-bend-up-right", description: "A mild preference between otherwise equal options." },
|
|
@@ -8506,7 +8524,7 @@ function importanceTokens(id) {
|
|
|
8506
8524
|
function ImportanceTag({ level, showLabel = true, size = "sm", className = "" }) {
|
|
8507
8525
|
const lvl = importanceLevel(level);
|
|
8508
8526
|
const t = importanceTokens(level);
|
|
8509
|
-
return /* @__PURE__ */
|
|
8527
|
+
return /* @__PURE__ */ jsxs66(
|
|
8510
8528
|
"span",
|
|
8511
8529
|
{
|
|
8512
8530
|
className: ["fd-imp-tag", size === "md" ? "is-md" : "", className].filter(Boolean).join(" "),
|
|
@@ -8521,8 +8539,8 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "" })
|
|
|
8521
8539
|
}
|
|
8522
8540
|
|
|
8523
8541
|
// src/components/planner/PreferenceMeter.tsx
|
|
8524
|
-
import * as
|
|
8525
|
-
import { jsx as jsx71, jsxs as
|
|
8542
|
+
import * as React40 from "react";
|
|
8543
|
+
import { jsx as jsx71, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
8526
8544
|
function preferenceScore(criteria) {
|
|
8527
8545
|
const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
|
|
8528
8546
|
const weight = criteria.reduce((n, c) => n + (Number(c.weight) || 0), 0);
|
|
@@ -8551,7 +8569,7 @@ function PreferenceMeter({
|
|
|
8551
8569
|
className = ""
|
|
8552
8570
|
}) {
|
|
8553
8571
|
const value = score == null ? preferenceScore(criteria) : score;
|
|
8554
|
-
const segments =
|
|
8572
|
+
const segments = React40.useMemo(() => preferenceSegments(criteria), [criteria]);
|
|
8555
8573
|
return /* @__PURE__ */ jsx71(
|
|
8556
8574
|
ScoreMeter,
|
|
8557
8575
|
{
|
|
@@ -8564,20 +8582,20 @@ function PreferenceMeter({
|
|
|
8564
8582
|
placement,
|
|
8565
8583
|
className,
|
|
8566
8584
|
breakdownLabel: breakdownTitle,
|
|
8567
|
-
breakdown: /* @__PURE__ */
|
|
8568
|
-
/* @__PURE__ */
|
|
8585
|
+
breakdown: /* @__PURE__ */ jsxs67("div", { className: "fd-prefbreak", children: [
|
|
8586
|
+
/* @__PURE__ */ jsxs67("div", { className: "fd-prefbreak-head", children: [
|
|
8569
8587
|
/* @__PURE__ */ jsx71("span", { className: "fd-label-lg", children: breakdownTitle }),
|
|
8570
8588
|
/* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-score fd-tabular", children: Math.round(value) })
|
|
8571
8589
|
] }),
|
|
8572
8590
|
/* @__PURE__ */ jsx71("ul", { className: "fd-prefbreak-list", children: criteria.map((c) => {
|
|
8573
8591
|
const pct = c.weight > 0 ? Math.round((Number(c.earned) || 0) / c.weight * 100) : 0;
|
|
8574
|
-
return /* @__PURE__ */
|
|
8592
|
+
return /* @__PURE__ */ jsxs67("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
|
|
8575
8593
|
/* @__PURE__ */ jsx71(ImportanceTag, { level: c.importance }),
|
|
8576
|
-
/* @__PURE__ */
|
|
8594
|
+
/* @__PURE__ */ jsxs67("span", { className: "fd-prefbreak-text", children: [
|
|
8577
8595
|
/* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-label", children: c.label }),
|
|
8578
8596
|
c.note ? /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-note", children: c.note }) : null
|
|
8579
8597
|
] }),
|
|
8580
|
-
/* @__PURE__ */
|
|
8598
|
+
/* @__PURE__ */ jsxs67("span", { className: "fd-prefbreak-val fd-tabular", children: [
|
|
8581
8599
|
Math.round(Number(c.earned) || 0),
|
|
8582
8600
|
/* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-sep", children: "/" }),
|
|
8583
8601
|
Math.round(c.weight)
|
|
@@ -8590,10 +8608,10 @@ function PreferenceMeter({
|
|
|
8590
8608
|
}
|
|
8591
8609
|
|
|
8592
8610
|
// src/components/chat/AgentChatPanel.tsx
|
|
8593
|
-
import * as
|
|
8611
|
+
import * as React46 from "react";
|
|
8594
8612
|
|
|
8595
8613
|
// src/components/chat/chatEngine.ts
|
|
8596
|
-
import * as
|
|
8614
|
+
import * as React41 from "react";
|
|
8597
8615
|
var CHAT_UNAVAILABLE = "chat_unavailable";
|
|
8598
8616
|
var JOB_PENDING = ["queued", "running"];
|
|
8599
8617
|
var JOB_SUCCESS = ["completed", "recovered"];
|
|
@@ -8647,22 +8665,22 @@ function useChatEngine(opts) {
|
|
|
8647
8665
|
onClear,
|
|
8648
8666
|
onFeedback
|
|
8649
8667
|
} = opts || {};
|
|
8650
|
-
const [status, setStatus] =
|
|
8651
|
-
const [threadId, setThreadId] =
|
|
8652
|
-
const [messages, setMessages] =
|
|
8653
|
-
const [queue, setQueue] =
|
|
8654
|
-
const [fatal, setFatal] =
|
|
8655
|
-
const [busy, setBusy] =
|
|
8656
|
-
const [turnStartedAt, setTurnStartedAt] =
|
|
8657
|
-
const listRef =
|
|
8658
|
-
const queueRef =
|
|
8659
|
-
const busyRef =
|
|
8660
|
-
const stoppedRef =
|
|
8661
|
-
const abortRef =
|
|
8662
|
-
const serverCount =
|
|
8663
|
-
const threadRef =
|
|
8664
|
-
const mounted =
|
|
8665
|
-
|
|
8668
|
+
const [status, setStatus] = React41.useState("idle");
|
|
8669
|
+
const [threadId, setThreadId] = React41.useState(null);
|
|
8670
|
+
const [messages, setMessages] = React41.useState([]);
|
|
8671
|
+
const [queue, setQueue] = React41.useState([]);
|
|
8672
|
+
const [fatal, setFatal] = React41.useState(null);
|
|
8673
|
+
const [busy, setBusy] = React41.useState(false);
|
|
8674
|
+
const [turnStartedAt, setTurnStartedAt] = React41.useState(null);
|
|
8675
|
+
const listRef = React41.useRef([]);
|
|
8676
|
+
const queueRef = React41.useRef([]);
|
|
8677
|
+
const busyRef = React41.useRef(false);
|
|
8678
|
+
const stoppedRef = React41.useRef(false);
|
|
8679
|
+
const abortRef = React41.useRef(null);
|
|
8680
|
+
const serverCount = React41.useRef(0);
|
|
8681
|
+
const threadRef = React41.useRef(null);
|
|
8682
|
+
const mounted = React41.useRef(true);
|
|
8683
|
+
React41.useEffect(() => {
|
|
8666
8684
|
mounted.current = true;
|
|
8667
8685
|
return () => {
|
|
8668
8686
|
mounted.current = false;
|
|
@@ -8684,14 +8702,14 @@ function useChatEngine(opts) {
|
|
|
8684
8702
|
}
|
|
8685
8703
|
return false;
|
|
8686
8704
|
};
|
|
8687
|
-
const loadThread =
|
|
8705
|
+
const loadThread = React41.useCallback(async (id) => {
|
|
8688
8706
|
const data = await apiAdapter.getThread(id);
|
|
8689
8707
|
const list = [...data && data.messages || []];
|
|
8690
8708
|
serverCount.current = list.length;
|
|
8691
8709
|
commit(list);
|
|
8692
8710
|
return list;
|
|
8693
8711
|
}, [apiAdapter]);
|
|
8694
|
-
|
|
8712
|
+
React41.useEffect(() => {
|
|
8695
8713
|
if (!apiAdapter) {
|
|
8696
8714
|
setStatus("idle");
|
|
8697
8715
|
setFatal(null);
|
|
@@ -8904,7 +8922,7 @@ function useChatEngine(opts) {
|
|
|
8904
8922
|
await dispatchTurn(turn);
|
|
8905
8923
|
}
|
|
8906
8924
|
}
|
|
8907
|
-
const send =
|
|
8925
|
+
const send = React41.useCallback((text, attachments) => {
|
|
8908
8926
|
const body = (text || "").trim();
|
|
8909
8927
|
if (!body && !(attachments && attachments.length)) return;
|
|
8910
8928
|
if (status === "disconnected") return;
|
|
@@ -8914,7 +8932,7 @@ function useChatEngine(opts) {
|
|
|
8914
8932
|
stoppedRef.current = false;
|
|
8915
8933
|
drain();
|
|
8916
8934
|
}, [status]);
|
|
8917
|
-
const stop =
|
|
8935
|
+
const stop = React41.useCallback(() => {
|
|
8918
8936
|
stoppedRef.current = true;
|
|
8919
8937
|
const ac = abortRef.current;
|
|
8920
8938
|
if (ac) {
|
|
@@ -8933,11 +8951,11 @@ function useChatEngine(opts) {
|
|
|
8933
8951
|
store.del(STORAGE_PREFIX + threadRef.current);
|
|
8934
8952
|
}
|
|
8935
8953
|
}, [apiAdapter]);
|
|
8936
|
-
const removeQueued =
|
|
8954
|
+
const removeQueued = React41.useCallback((id) => {
|
|
8937
8955
|
queueRef.current = queueRef.current.filter((t) => t.id !== id);
|
|
8938
8956
|
setQueue(queueRef.current.slice());
|
|
8939
8957
|
}, []);
|
|
8940
|
-
const retry =
|
|
8958
|
+
const retry = React41.useCallback(() => {
|
|
8941
8959
|
const list = listRef.current;
|
|
8942
8960
|
let at = -1;
|
|
8943
8961
|
for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
|
|
@@ -8953,19 +8971,19 @@ function useChatEngine(opts) {
|
|
|
8953
8971
|
setQueue(queueRef.current.slice());
|
|
8954
8972
|
drain();
|
|
8955
8973
|
}, []);
|
|
8956
|
-
const clear =
|
|
8974
|
+
const clear = React41.useCallback(() => {
|
|
8957
8975
|
commit([]);
|
|
8958
8976
|
serverCount.current = 0;
|
|
8959
8977
|
queueRef.current = [];
|
|
8960
8978
|
setQueue([]);
|
|
8961
8979
|
onClear && onClear();
|
|
8962
8980
|
}, [onClear]);
|
|
8963
|
-
const setFeedback =
|
|
8981
|
+
const setFeedback = React41.useCallback((id, value) => {
|
|
8964
8982
|
patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
|
|
8965
8983
|
const msg = listRef.current.find((m) => m.id === id);
|
|
8966
8984
|
onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
|
|
8967
8985
|
}, [onFeedback]);
|
|
8968
|
-
const reload =
|
|
8986
|
+
const reload = React41.useCallback(async () => {
|
|
8969
8987
|
if (!threadRef.current) return;
|
|
8970
8988
|
setStatus("loading");
|
|
8971
8989
|
try {
|
|
@@ -9003,11 +9021,11 @@ var ChatKit = {
|
|
|
9003
9021
|
};
|
|
9004
9022
|
|
|
9005
9023
|
// src/components/chat/ChatTranscript.tsx
|
|
9006
|
-
import * as
|
|
9024
|
+
import * as React43 from "react";
|
|
9007
9025
|
|
|
9008
9026
|
// src/components/chat/ChatTurn.tsx
|
|
9009
|
-
import * as
|
|
9010
|
-
import { jsx as jsx72, jsxs as
|
|
9027
|
+
import * as React42 from "react";
|
|
9028
|
+
import { jsx as jsx72, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
9011
9029
|
function JsonView({ value }) {
|
|
9012
9030
|
let text;
|
|
9013
9031
|
try {
|
|
@@ -9022,20 +9040,20 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
|
9022
9040
|
const s = schema || {};
|
|
9023
9041
|
const invalid = packet.valid === false;
|
|
9024
9042
|
const title = s.heading || packet.type;
|
|
9025
|
-
return /* @__PURE__ */
|
|
9026
|
-
/* @__PURE__ */
|
|
9043
|
+
return /* @__PURE__ */ jsxs68("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
|
|
9044
|
+
/* @__PURE__ */ jsxs68("header", { className: "fdc-packet-head", children: [
|
|
9027
9045
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-" + (s.icon || "package"), "aria-hidden": "true" }),
|
|
9028
9046
|
/* @__PURE__ */ jsx72("span", { className: "fdc-packet-title", children: title }),
|
|
9029
9047
|
packet.repaired ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-badge", children: "Repaired" }) : null,
|
|
9030
9048
|
invalid ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-badge is-danger", children: "Invalid" }) : null
|
|
9031
9049
|
] }),
|
|
9032
|
-
invalid ? /* @__PURE__ */
|
|
9050
|
+
invalid ? /* @__PURE__ */ jsxs68("div", { className: "fdc-packet-alert", role: "alert", children: [
|
|
9033
9051
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
9034
9052
|
/* @__PURE__ */ jsx72("span", { children: packet.error || "This result failed validation and can\u2019t be applied." })
|
|
9035
9053
|
] }) : /* @__PURE__ */ jsx72("div", { className: "fdc-packet-body", children: render ? render(packet) : /* @__PURE__ */ jsx72(JsonView, { value: packet.payload }) }),
|
|
9036
|
-
!invalid && onApply ? /* @__PURE__ */
|
|
9054
|
+
!invalid && onApply ? /* @__PURE__ */ jsxs68("footer", { className: "fdc-packet-foot", children: [
|
|
9037
9055
|
packet.repaired ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-note", children: "Corrected by the backend after a first attempt." }) : /* @__PURE__ */ jsx72("span", {}),
|
|
9038
|
-
/* @__PURE__ */
|
|
9056
|
+
/* @__PURE__ */ jsxs68("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
|
|
9039
9057
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-" + (applied ? "check" : "arrow-square-in"), "aria-hidden": "true" }),
|
|
9040
9058
|
applied ? "Applied" : s.applyLabel || "Apply"
|
|
9041
9059
|
] })
|
|
@@ -9043,13 +9061,13 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
|
9043
9061
|
] });
|
|
9044
9062
|
}
|
|
9045
9063
|
function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
9046
|
-
const [open, setOpen] =
|
|
9064
|
+
const [open, setOpen] = React42.useState(defaultOpen);
|
|
9047
9065
|
if (!text) return null;
|
|
9048
|
-
return /* @__PURE__ */
|
|
9049
|
-
/* @__PURE__ */
|
|
9066
|
+
return /* @__PURE__ */ jsxs68("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
|
|
9067
|
+
/* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
9050
9068
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-brain", "aria-hidden": "true" }),
|
|
9051
9069
|
/* @__PURE__ */ jsx72("span", { children: streaming ? "Thinking" : durationMs ? "Thought for " + formatDuration(durationMs) : "Thought process" }),
|
|
9052
|
-
streaming ? /* @__PURE__ */
|
|
9070
|
+
streaming ? /* @__PURE__ */ jsxs68("span", { className: "fdc-dots", "aria-hidden": "true", children: [
|
|
9053
9071
|
/* @__PURE__ */ jsx72("span", {}),
|
|
9054
9072
|
/* @__PURE__ */ jsx72("span", {}),
|
|
9055
9073
|
/* @__PURE__ */ jsx72("span", {})
|
|
@@ -9060,19 +9078,19 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
|
9060
9078
|
] });
|
|
9061
9079
|
}
|
|
9062
9080
|
function Citations({ items = [], onOpen }) {
|
|
9063
|
-
const [open, setOpen] =
|
|
9081
|
+
const [open, setOpen] = React42.useState(false);
|
|
9064
9082
|
if (!items.length) return null;
|
|
9065
|
-
return /* @__PURE__ */
|
|
9066
|
-
/* @__PURE__ */
|
|
9083
|
+
return /* @__PURE__ */ jsxs68("div", { className: "fdc-cites", children: [
|
|
9084
|
+
/* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
9067
9085
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-quotes", "aria-hidden": "true" }),
|
|
9068
|
-
/* @__PURE__ */
|
|
9086
|
+
/* @__PURE__ */ jsxs68("span", { children: [
|
|
9069
9087
|
items.length,
|
|
9070
9088
|
" source",
|
|
9071
9089
|
items.length === 1 ? "" : "s"
|
|
9072
9090
|
] }),
|
|
9073
9091
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" })
|
|
9074
9092
|
] }),
|
|
9075
|
-
open ? /* @__PURE__ */ jsx72("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */
|
|
9093
|
+
open ? /* @__PURE__ */ jsx72("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs68("li", { children: [
|
|
9076
9094
|
/* @__PURE__ */ jsx72("span", { className: "fdc-cite-n fd-tabular", children: c.marker || i + 1 }),
|
|
9077
9095
|
c.url ? /* @__PURE__ */ jsx72("a", { href: c.url, target: "_blank", rel: "noopener noreferrer", onClick: onOpen ? (e) => onOpen(c, e) : void 0, children: c.title || c.url }) : /* @__PURE__ */ jsx72("span", { children: c.title || "Source" }),
|
|
9078
9096
|
c.detail ? /* @__PURE__ */ jsx72("span", { className: "fdc-cite-detail", children: c.detail }) : null
|
|
@@ -9086,24 +9104,24 @@ function clampText(text, max) {
|
|
|
9086
9104
|
return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
9087
9105
|
}
|
|
9088
9106
|
function MessageBody({ message: m, ctx }) {
|
|
9089
|
-
const [expanded, setExpanded] =
|
|
9107
|
+
const [expanded, setExpanded] = React42.useState(false);
|
|
9090
9108
|
const isUser = m.role === "user";
|
|
9091
9109
|
const raw = m.text || "";
|
|
9092
9110
|
const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
|
|
9093
9111
|
const body = clamped != null ? clamped : raw;
|
|
9094
9112
|
const showMd = ctx.markdown && !isUser;
|
|
9095
|
-
return /* @__PURE__ */
|
|
9113
|
+
return /* @__PURE__ */ jsxs68("div", { className: "fdc-body", children: [
|
|
9096
9114
|
m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx72(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
|
|
9097
9115
|
m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx72(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), dense: true }) : null,
|
|
9098
|
-
body ? /* @__PURE__ */
|
|
9116
|
+
body ? /* @__PURE__ */ jsxs68("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
|
|
9099
9117
|
showMd ? /* @__PURE__ */ jsx72(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx72("div", { className: "fdc-plain", children: body }),
|
|
9100
9118
|
m.streaming ? /* @__PURE__ */ jsx72("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
|
|
9101
9119
|
] }) : null,
|
|
9102
|
-
clamped != null ? /* @__PURE__ */
|
|
9120
|
+
clamped != null ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
|
|
9103
9121
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-caret-down", "aria-hidden": "true" }),
|
|
9104
9122
|
"Show more",
|
|
9105
9123
|
/* @__PURE__ */ jsx72("span", { className: "fdc-more-len fd-tabular", children: raw.length < 2e3 ? raw.length.toLocaleString() + " characters" : Math.round(raw.length / 100) / 10 + "k characters" })
|
|
9106
|
-
] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */
|
|
9124
|
+
] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
|
|
9107
9125
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-caret-up", "aria-hidden": "true" }),
|
|
9108
9126
|
"Show less"
|
|
9109
9127
|
] }) : null,
|
|
@@ -9119,33 +9137,33 @@ function MessageBody({ message: m, ctx }) {
|
|
|
9119
9137
|
}
|
|
9120
9138
|
) : null,
|
|
9121
9139
|
m.citations && m.citations.length ? /* @__PURE__ */ jsx72(Citations, { items: m.citations, onOpen: ctx.onOpenCitation }) : null,
|
|
9122
|
-
m.working ? /* @__PURE__ */
|
|
9123
|
-
/* @__PURE__ */
|
|
9140
|
+
m.working ? /* @__PURE__ */ jsxs68("div", { className: "fdc-working", role: "status", children: [
|
|
9141
|
+
/* @__PURE__ */ jsxs68("span", { className: "fdc-dots", "aria-hidden": "true", children: [
|
|
9124
9142
|
/* @__PURE__ */ jsx72("span", {}),
|
|
9125
9143
|
/* @__PURE__ */ jsx72("span", {}),
|
|
9126
9144
|
/* @__PURE__ */ jsx72("span", {})
|
|
9127
9145
|
] }),
|
|
9128
|
-
/* @__PURE__ */
|
|
9146
|
+
/* @__PURE__ */ jsxs68("span", { className: "fdc-working-label", children: [
|
|
9129
9147
|
m.resumed ? "Resuming" : "Working",
|
|
9130
|
-
m.job && m.job.status ? /* @__PURE__ */
|
|
9148
|
+
m.job && m.job.status ? /* @__PURE__ */ jsxs68("span", { className: "fdc-working-job", children: [
|
|
9131
9149
|
" \xB7 ",
|
|
9132
9150
|
m.job.status
|
|
9133
9151
|
] }) : null,
|
|
9134
|
-
m.job && m.job.detail ? /* @__PURE__ */
|
|
9152
|
+
m.job && m.job.detail ? /* @__PURE__ */ jsxs68("span", { className: "fdc-working-job", children: [
|
|
9135
9153
|
" \xB7 ",
|
|
9136
9154
|
m.job.detail
|
|
9137
9155
|
] }) : null
|
|
9138
9156
|
] }),
|
|
9139
9157
|
m.jobId ? /* @__PURE__ */ jsx72("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
|
|
9140
9158
|
] }) : null,
|
|
9141
|
-
m.stopped ? /* @__PURE__ */
|
|
9159
|
+
m.stopped ? /* @__PURE__ */ jsxs68("div", { className: "fdc-stopped", children: [
|
|
9142
9160
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
|
|
9143
9161
|
"Stopped"
|
|
9144
9162
|
] }) : null,
|
|
9145
|
-
m.error ? /* @__PURE__ */
|
|
9163
|
+
m.error ? /* @__PURE__ */ jsxs68("div", { className: "fdc-error", role: "alert", children: [
|
|
9146
9164
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
9147
9165
|
/* @__PURE__ */ jsx72("span", { className: "fdc-error-text", children: ctx.errorCopy ? ctx.errorCopy(m.error) : m.error }),
|
|
9148
|
-
m.retryable && ctx.onRetry ? /* @__PURE__ */
|
|
9166
|
+
m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
|
|
9149
9167
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
|
|
9150
9168
|
"Retry"
|
|
9151
9169
|
] }) : null
|
|
@@ -9153,9 +9171,9 @@ function MessageBody({ message: m, ctx }) {
|
|
|
9153
9171
|
] });
|
|
9154
9172
|
}
|
|
9155
9173
|
function useCopyRun() {
|
|
9156
|
-
const [done, setDone] =
|
|
9157
|
-
const t =
|
|
9158
|
-
|
|
9174
|
+
const [done, setDone] = React42.useState(false);
|
|
9175
|
+
const t = React42.useRef(null);
|
|
9176
|
+
React42.useEffect(() => () => {
|
|
9159
9177
|
if (t.current) clearTimeout(t.current);
|
|
9160
9178
|
}, []);
|
|
9161
9179
|
return [done, (text) => {
|
|
@@ -9175,14 +9193,14 @@ function RunActions({ group, ctx }) {
|
|
|
9175
9193
|
const isAssistant = group.role === "assistant";
|
|
9176
9194
|
const fb = last.feedback;
|
|
9177
9195
|
if (!ctx.messageActions) return null;
|
|
9178
|
-
return /* @__PURE__ */
|
|
9179
|
-
/* @__PURE__ */
|
|
9196
|
+
return /* @__PURE__ */ jsxs68("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
|
|
9197
|
+
/* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
|
|
9180
9198
|
/* @__PURE__ */ jsx72("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
|
|
9181
9199
|
/* @__PURE__ */ jsx72("span", { className: "fdc-act-label", children: copied ? "Copied" : "Copy" })
|
|
9182
9200
|
] }),
|
|
9183
9201
|
isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx72("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx72("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
|
|
9184
9202
|
group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx72("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx72("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
|
|
9185
|
-
isAssistant && ctx.onFeedback ? /* @__PURE__ */
|
|
9203
|
+
isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs68(React42.Fragment, { children: [
|
|
9186
9204
|
/* @__PURE__ */ jsx72("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__ */ jsx72("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
|
|
9187
9205
|
/* @__PURE__ */ jsx72("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__ */ jsx72("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
|
|
9188
9206
|
] }) : null,
|
|
@@ -9194,14 +9212,14 @@ function ChatTurn({ group, ctx }) {
|
|
|
9194
9212
|
const name = isUser ? ctx.userName : group.author || ctx.assistantName;
|
|
9195
9213
|
const avatar = isUser ? ctx.userAvatar : ctx.assistantAvatar;
|
|
9196
9214
|
const stamp = group.messages[0].timestamp;
|
|
9197
|
-
return /* @__PURE__ */
|
|
9198
|
-
/* @__PURE__ */
|
|
9215
|
+
return /* @__PURE__ */ jsxs68("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
|
|
9216
|
+
/* @__PURE__ */ jsxs68("div", { className: "fdc-turn-head", children: [
|
|
9199
9217
|
ctx.showAvatars ? /* @__PURE__ */ jsx72("span", { className: "fdc-avatar is-" + group.role, "aria-hidden": "true", children: avatar ? /* @__PURE__ */ jsx72("img", { src: avatar, alt: "" }) : isUser ? /* @__PURE__ */ jsx72("span", { className: "fdc-avatar-txt", children: (name || "You").slice(0, 1).toUpperCase() }) : /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (ctx.assistantIcon || "sparkle") }) }) : null,
|
|
9200
9218
|
/* @__PURE__ */ jsx72("span", { className: "fdc-who", children: name }),
|
|
9201
9219
|
stamp ? /* @__PURE__ */ jsx72(RelativeTime, { className: "fdc-when", value: stamp }) : null,
|
|
9202
9220
|
group.messages.some((m) => m.model) ? /* @__PURE__ */ jsx72("span", { className: "fdc-turn-model", children: group.messages.find((m) => m.model).model }) : null
|
|
9203
9221
|
] }),
|
|
9204
|
-
/* @__PURE__ */
|
|
9222
|
+
/* @__PURE__ */ jsxs68("div", { className: "fdc-turn-body", children: [
|
|
9205
9223
|
group.messages.map((m) => /* @__PURE__ */ jsx72("div", { className: "fdc-msg" + (m.pending ? " is-pending" : ""), children: /* @__PURE__ */ jsx72(MessageBody, { message: m, ctx }) }, m.id)),
|
|
9206
9224
|
/* @__PURE__ */ jsx72(RunActions, { group, ctx })
|
|
9207
9225
|
] })
|
|
@@ -9209,7 +9227,7 @@ function ChatTurn({ group, ctx }) {
|
|
|
9209
9227
|
}
|
|
9210
9228
|
|
|
9211
9229
|
// src/components/chat/ChatTranscript.tsx
|
|
9212
|
-
import { jsx as jsx73, jsxs as
|
|
9230
|
+
import { jsx as jsx73, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
9213
9231
|
var GROUP_WINDOW = 6e4;
|
|
9214
9232
|
var STICK_PX = 100;
|
|
9215
9233
|
function groupMessages(list) {
|
|
@@ -9244,9 +9262,9 @@ function Suggestions({ items = [], onPick }) {
|
|
|
9244
9262
|
if (!items.length) return null;
|
|
9245
9263
|
return /* @__PURE__ */ jsx73("div", { className: "fdc-suggest", children: items.map((s, i) => {
|
|
9246
9264
|
const it = typeof s === "string" ? { label: s, text: s } : s;
|
|
9247
|
-
return /* @__PURE__ */
|
|
9265
|
+
return /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
|
|
9248
9266
|
it.icon ? /* @__PURE__ */ jsx73("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) : null,
|
|
9249
|
-
/* @__PURE__ */
|
|
9267
|
+
/* @__PURE__ */ jsxs69("span", { className: "fdc-suggest-text", children: [
|
|
9250
9268
|
/* @__PURE__ */ jsx73("span", { className: "fdc-suggest-label", children: it.label }),
|
|
9251
9269
|
it.description ? /* @__PURE__ */ jsx73("span", { className: "fdc-suggest-desc", children: it.description }) : null
|
|
9252
9270
|
] }),
|
|
@@ -9255,9 +9273,9 @@ function Suggestions({ items = [], onPick }) {
|
|
|
9255
9273
|
}) });
|
|
9256
9274
|
}
|
|
9257
9275
|
function LoadingTurns() {
|
|
9258
|
-
return /* @__PURE__ */ jsx73("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */
|
|
9276
|
+
return /* @__PURE__ */ jsx73("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs69("div", { className: "fdc-skel-turn", children: [
|
|
9259
9277
|
/* @__PURE__ */ jsx73("div", { className: "fd-skel fd-skel-circle", style: { width: 22, height: 22 } }),
|
|
9260
|
-
/* @__PURE__ */
|
|
9278
|
+
/* @__PURE__ */ jsxs69("div", { className: "fdc-skel-lines", children: [
|
|
9261
9279
|
/* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "62%" : "44%", height: 11 } }),
|
|
9262
9280
|
/* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "94%" : "78%", height: 11 } }),
|
|
9263
9281
|
/* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "71%" : "56%", height: 11 } })
|
|
@@ -9277,10 +9295,10 @@ function ChatTranscript({
|
|
|
9277
9295
|
renderEmpty,
|
|
9278
9296
|
className = ""
|
|
9279
9297
|
}) {
|
|
9280
|
-
const scroller =
|
|
9281
|
-
const stick =
|
|
9282
|
-
const [pill, setPill] =
|
|
9283
|
-
const seen =
|
|
9298
|
+
const scroller = React43.useRef(null);
|
|
9299
|
+
const stick = React43.useRef(true);
|
|
9300
|
+
const [pill, setPill] = React43.useState(0);
|
|
9301
|
+
const seen = React43.useRef(0);
|
|
9284
9302
|
const toBottom = (smooth) => {
|
|
9285
9303
|
const el = scroller.current;
|
|
9286
9304
|
if (!el) return;
|
|
@@ -9299,7 +9317,7 @@ function ChatTranscript({
|
|
|
9299
9317
|
seen.current = messages.length;
|
|
9300
9318
|
}
|
|
9301
9319
|
};
|
|
9302
|
-
|
|
9320
|
+
React43.useLayoutEffect(() => {
|
|
9303
9321
|
const el = scroller.current;
|
|
9304
9322
|
if (!el) return;
|
|
9305
9323
|
if (stick.current) {
|
|
@@ -9307,7 +9325,7 @@ function ChatTranscript({
|
|
|
9307
9325
|
seen.current = messages.length;
|
|
9308
9326
|
} else setPill(Math.max(0, messages.length - seen.current));
|
|
9309
9327
|
}, [messages]);
|
|
9310
|
-
|
|
9328
|
+
React43.useEffect(() => {
|
|
9311
9329
|
const el = scroller.current;
|
|
9312
9330
|
const inner = el && el.firstChild;
|
|
9313
9331
|
if (!el || !inner || typeof ResizeObserver === "undefined") return;
|
|
@@ -9317,21 +9335,21 @@ function ChatTranscript({
|
|
|
9317
9335
|
ro.observe(inner);
|
|
9318
9336
|
return () => ro.disconnect();
|
|
9319
9337
|
}, []);
|
|
9320
|
-
const groups =
|
|
9338
|
+
const groups = React43.useMemo(() => groupMessages(messages), [messages]);
|
|
9321
9339
|
const empty = !messages.length && status === "ready";
|
|
9322
|
-
return /* @__PURE__ */
|
|
9323
|
-
/* @__PURE__ */
|
|
9340
|
+
return /* @__PURE__ */ jsxs69("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
|
|
9341
|
+
/* @__PURE__ */ jsxs69("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
|
|
9324
9342
|
status === "loading" || status === "resolving" ? /* @__PURE__ */ jsx73(LoadingTurns, {}) : null,
|
|
9325
|
-
status === "disconnected" ? /* @__PURE__ */
|
|
9343
|
+
status === "disconnected" ? /* @__PURE__ */ jsxs69("div", { className: "fdc-dead", children: [
|
|
9326
9344
|
/* @__PURE__ */ jsx73("span", { className: "fdc-dead-icon", children: /* @__PURE__ */ jsx73("i", { className: "ph ph-plugs", "aria-hidden": "true" }) }),
|
|
9327
9345
|
/* @__PURE__ */ jsx73("h3", { className: "fdc-dead-title", children: ctx.deadTitle || "The assistant isn\u2019t reachable" }),
|
|
9328
9346
|
/* @__PURE__ */ jsx73("p", { className: "fdc-dead-body", children: fatal === "chat_unavailable" ? "The service reported chat_unavailable. Nothing you type will be lost \u2014 reopen the panel once it\u2019s back." : "The thread couldn\u2019t be resolved" + (fatal ? " (" + fatal + ")" : "") + ". The composer stays disabled until it resolves." }),
|
|
9329
|
-
ctx.onReconnect ? /* @__PURE__ */
|
|
9347
|
+
ctx.onReconnect ? /* @__PURE__ */ jsxs69("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
|
|
9330
9348
|
/* @__PURE__ */ jsx73("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
|
|
9331
9349
|
"Try again"
|
|
9332
9350
|
] }) : null
|
|
9333
9351
|
] }) : null,
|
|
9334
|
-
empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */
|
|
9352
|
+
empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs69("div", { className: "fdc-empty", children: [
|
|
9335
9353
|
/* @__PURE__ */ jsx73("span", { className: "fdc-empty-icon", children: /* @__PURE__ */ jsx73("i", { className: "ph ph-" + emptyIcon, "aria-hidden": "true" }) }),
|
|
9336
9354
|
/* @__PURE__ */ jsx73("h3", { className: "fdc-empty-title", children: emptyTitle }),
|
|
9337
9355
|
emptyDescription ? /* @__PURE__ */ jsx73("p", { className: "fdc-empty-body", children: emptyDescription }) : null,
|
|
@@ -9341,13 +9359,13 @@ function ChatTranscript({
|
|
|
9341
9359
|
const prev = groups[i - 1];
|
|
9342
9360
|
const k = dayKey(g.messages[0].timestamp);
|
|
9343
9361
|
const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
|
|
9344
|
-
return /* @__PURE__ */
|
|
9362
|
+
return /* @__PURE__ */ jsxs69(React43.Fragment, { children: [
|
|
9345
9363
|
showDay ? /* @__PURE__ */ jsx73("div", { className: "fdc-day", children: /* @__PURE__ */ jsx73("span", { children: dayLabel(k) }) }) : null,
|
|
9346
9364
|
/* @__PURE__ */ jsx73(ChatTurn, { group: g, ctx })
|
|
9347
9365
|
] }, g.key || i);
|
|
9348
9366
|
})
|
|
9349
9367
|
] }),
|
|
9350
|
-
pill ? /* @__PURE__ */
|
|
9368
|
+
pill ? /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
|
|
9351
9369
|
/* @__PURE__ */ jsx73("i", { className: "ph ph-arrow-down", "aria-hidden": "true" }),
|
|
9352
9370
|
pill,
|
|
9353
9371
|
" new message",
|
|
@@ -9358,8 +9376,8 @@ function ChatTranscript({
|
|
|
9358
9376
|
var TranscriptKit = { groupMessages };
|
|
9359
9377
|
|
|
9360
9378
|
// src/components/chat/ChatComposer.tsx
|
|
9361
|
-
import * as
|
|
9362
|
-
import { jsx as jsx74, jsxs as
|
|
9379
|
+
import * as React44 from "react";
|
|
9380
|
+
import { jsx as jsx74, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
9363
9381
|
function ChatComposer({
|
|
9364
9382
|
onSubmit,
|
|
9365
9383
|
onStop,
|
|
@@ -9386,17 +9404,17 @@ function ChatComposer({
|
|
|
9386
9404
|
onReject,
|
|
9387
9405
|
onOpenAttachment
|
|
9388
9406
|
}) {
|
|
9389
|
-
const [text, setText] =
|
|
9390
|
-
const [trigger, setTrigger] =
|
|
9391
|
-
const [mentionItems, setMentionItems] =
|
|
9392
|
-
const [listening, setListening] =
|
|
9393
|
-
const [notice, setNotice] =
|
|
9394
|
-
const editor =
|
|
9395
|
-
const wrap =
|
|
9396
|
-
const stopVoice =
|
|
9407
|
+
const [text, setText] = React44.useState(draft || "");
|
|
9408
|
+
const [trigger, setTrigger] = React44.useState(null);
|
|
9409
|
+
const [mentionItems, setMentionItems] = React44.useState([]);
|
|
9410
|
+
const [listening, setListening] = React44.useState(false);
|
|
9411
|
+
const [notice, setNotice] = React44.useState(null);
|
|
9412
|
+
const editor = React44.useRef(null);
|
|
9413
|
+
const wrap = React44.useRef(null);
|
|
9414
|
+
const stopVoice = React44.useRef(null);
|
|
9397
9415
|
const staged = useStagedFiles(fileUploadHandler, { onError: () => {
|
|
9398
9416
|
} });
|
|
9399
|
-
|
|
9417
|
+
React44.useEffect(() => {
|
|
9400
9418
|
if (draft != null && draft !== text) setText(draft);
|
|
9401
9419
|
}, [draft]);
|
|
9402
9420
|
const change = (v) => {
|
|
@@ -9430,7 +9448,7 @@ function ChatComposer({
|
|
|
9430
9448
|
e.preventDefault();
|
|
9431
9449
|
staged.add(found.files);
|
|
9432
9450
|
};
|
|
9433
|
-
|
|
9451
|
+
React44.useEffect(() => {
|
|
9434
9452
|
if (!trigger || trigger.type !== "mention" || !mentionSources) {
|
|
9435
9453
|
setMentionItems([]);
|
|
9436
9454
|
return;
|
|
@@ -9448,7 +9466,7 @@ function ChatComposer({
|
|
|
9448
9466
|
const q = (trigger.query || "").toLowerCase();
|
|
9449
9467
|
setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
|
|
9450
9468
|
}, [trigger, mentionSources]);
|
|
9451
|
-
const slashItems =
|
|
9469
|
+
const slashItems = React44.useMemo(() => {
|
|
9452
9470
|
if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
|
|
9453
9471
|
const q = (trigger.query || "").toLowerCase();
|
|
9454
9472
|
return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
|
|
@@ -9525,8 +9543,8 @@ function ChatComposer({
|
|
|
9525
9543
|
stopVoice.current = typeof res === "function" ? res : () => {
|
|
9526
9544
|
};
|
|
9527
9545
|
};
|
|
9528
|
-
return /* @__PURE__ */
|
|
9529
|
-
queue.length ? /* @__PURE__ */ jsx74("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */
|
|
9546
|
+
return /* @__PURE__ */ jsxs70("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
|
|
9547
|
+
queue.length ? /* @__PURE__ */ jsx74("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs70("div", { className: "fdc-queue-row", children: [
|
|
9530
9548
|
/* @__PURE__ */ jsx74("i", { className: "ph ph-clock-countdown", "aria-hidden": "true" }),
|
|
9531
9549
|
/* @__PURE__ */ jsx74("span", { className: "fdc-queue-text", children: q.text || (q.attachments ? q.attachments.length + " file(s)" : "") }),
|
|
9532
9550
|
onRemoveQueued ? /* @__PURE__ */ jsx74("button", { type: "button", className: "fdc-queue-x", onClick: () => onRemoveQueued(q.id), "aria-label": "Remove queued message", children: /* @__PURE__ */ jsx74("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
|
|
@@ -9546,7 +9564,7 @@ function ChatComposer({
|
|
|
9546
9564
|
disabled: !fileUploadHandler || disabled,
|
|
9547
9565
|
label: "Drop to attach",
|
|
9548
9566
|
hint: acceptFiles ? acceptFiles.replace(/,/g, " \xB7 ") : void 0,
|
|
9549
|
-
children: /* @__PURE__ */
|
|
9567
|
+
children: /* @__PURE__ */ jsxs70("div", { ref: wrap, className: "fdc-field-inner", children: [
|
|
9550
9568
|
staged.items.length ? /* @__PURE__ */ jsx74("div", { className: "fdc-staged", children: /* @__PURE__ */ jsx74(FileStrip, { files: staged.items, size: narrow ? 60 : 68, onRemove: staged.remove, onRetry: staged.retry, onOpen: onOpenAttachment }) }) : null,
|
|
9551
9569
|
/* @__PURE__ */ jsx74(
|
|
9552
9570
|
MarkdownEditor,
|
|
@@ -9567,20 +9585,20 @@ function ChatComposer({
|
|
|
9567
9585
|
ariaLabel: "Message"
|
|
9568
9586
|
}
|
|
9569
9587
|
),
|
|
9570
|
-
/* @__PURE__ */
|
|
9588
|
+
/* @__PURE__ */ jsxs70("div", { className: "fdc-tools", children: [
|
|
9571
9589
|
fileUploadHandler ? /* @__PURE__ */ jsx74(FilePickButton, { onFiles: staged.add, onReject: (r) => flash(r[0].message), accept: acceptFiles, maxFileSize, label: "Attach files", icon: "plus" }) : null,
|
|
9572
9590
|
voiceHandler ? /* @__PURE__ */ jsx74("button", { type: "button", className: "fd-attachbtn" + (listening ? " is-live" : ""), onClick: voice, "aria-pressed": listening, "aria-label": listening ? "Stop dictation" : "Dictate", children: /* @__PURE__ */ jsx74("i", { className: "ph ph-" + (listening ? "waveform" : "microphone"), "aria-hidden": "true" }) }) : null,
|
|
9573
9591
|
toolbarExtras,
|
|
9574
9592
|
/* @__PURE__ */ jsx74("span", { className: "fdc-tools-gap" }),
|
|
9575
|
-
maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */
|
|
9593
|
+
maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs70("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
|
|
9576
9594
|
text.length,
|
|
9577
9595
|
"/",
|
|
9578
9596
|
maxLength
|
|
9579
9597
|
] }) : null,
|
|
9580
|
-
busy ? /* @__PURE__ */
|
|
9598
|
+
busy ? /* @__PURE__ */ jsxs70("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
|
|
9581
9599
|
/* @__PURE__ */ jsx74("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
|
|
9582
9600
|
/* @__PURE__ */ jsx74("span", { children: "Stop" })
|
|
9583
|
-
] }) : /* @__PURE__ */
|
|
9601
|
+
] }) : /* @__PURE__ */ jsxs70("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
|
|
9584
9602
|
/* @__PURE__ */ jsx74("i", { className: "ph ph-paper-plane-right", "aria-hidden": "true" }),
|
|
9585
9603
|
/* @__PURE__ */ jsx74("span", { className: "fdc-send-label", children: "Send" })
|
|
9586
9604
|
] })
|
|
@@ -9588,7 +9606,7 @@ function ChatComposer({
|
|
|
9588
9606
|
] })
|
|
9589
9607
|
}
|
|
9590
9608
|
),
|
|
9591
|
-
notice ? /* @__PURE__ */
|
|
9609
|
+
notice ? /* @__PURE__ */ jsxs70("div", { className: "fdc-notice", role: "status", children: [
|
|
9592
9610
|
/* @__PURE__ */ jsx74("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
9593
9611
|
notice
|
|
9594
9612
|
] }) : null,
|
|
@@ -9622,12 +9640,12 @@ function ChatComposer({
|
|
|
9622
9640
|
}
|
|
9623
9641
|
|
|
9624
9642
|
// src/components/chat/ChatSessionBar.tsx
|
|
9625
|
-
import * as
|
|
9626
|
-
import { jsx as jsx75, jsxs as
|
|
9643
|
+
import * as React45 from "react";
|
|
9644
|
+
import { jsx as jsx75, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
9627
9645
|
var compact2 = meterFormats.compact;
|
|
9628
9646
|
function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
|
|
9629
|
-
const [open, setOpen] =
|
|
9630
|
-
const anchor =
|
|
9647
|
+
const [open, setOpen] = React45.useState(false);
|
|
9648
|
+
const anchor = React45.useRef(null);
|
|
9631
9649
|
const stats = sessionStats || null;
|
|
9632
9650
|
const cu = contextUsage || null;
|
|
9633
9651
|
const limits = usageLimits || null;
|
|
@@ -9642,9 +9660,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
9642
9660
|
if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
|
|
9643
9661
|
if (cu) bits.push(pct + "% context");
|
|
9644
9662
|
const expandable = !!(cu || limits);
|
|
9645
|
-
return /* @__PURE__ */
|
|
9646
|
-
/* @__PURE__ */
|
|
9647
|
-
/* @__PURE__ */
|
|
9663
|
+
return /* @__PURE__ */ jsxs71(React45.Fragment, { children: [
|
|
9664
|
+
/* @__PURE__ */ jsxs71("div", { className: "fdc-bar", children: [
|
|
9665
|
+
/* @__PURE__ */ jsxs71(
|
|
9648
9666
|
"button",
|
|
9649
9667
|
{
|
|
9650
9668
|
type: "button",
|
|
@@ -9674,14 +9692,14 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
9674
9692
|
maxHeight: 460,
|
|
9675
9693
|
padded: true,
|
|
9676
9694
|
label: "Usage",
|
|
9677
|
-
footer: onClear ? /* @__PURE__ */
|
|
9695
|
+
footer: onClear ? /* @__PURE__ */ jsxs71("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
|
|
9678
9696
|
setOpen(false);
|
|
9679
9697
|
onClear();
|
|
9680
9698
|
}, children: [
|
|
9681
9699
|
/* @__PURE__ */ jsx75("i", { className: "ph ph-trash", "aria-hidden": "true" }),
|
|
9682
9700
|
"Clear conversation"
|
|
9683
9701
|
] }) : void 0,
|
|
9684
|
-
children: /* @__PURE__ */
|
|
9702
|
+
children: /* @__PURE__ */ jsxs71("div", { className: "fdc-usage", children: [
|
|
9685
9703
|
cu ? /* @__PURE__ */ jsx75("section", { className: "fdc-usage-sec", children: /* @__PURE__ */ jsx75(
|
|
9686
9704
|
SegmentedMeter,
|
|
9687
9705
|
{
|
|
@@ -9694,7 +9712,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
9694
9712
|
remainderLabel: "Free"
|
|
9695
9713
|
}
|
|
9696
9714
|
) }) : null,
|
|
9697
|
-
limits && limits.length ? /* @__PURE__ */
|
|
9715
|
+
limits && limits.length ? /* @__PURE__ */ jsxs71("section", { className: "fdc-usage-sec", children: [
|
|
9698
9716
|
/* @__PURE__ */ jsx75("h4", { className: "fdc-usage-h", children: "Usage limits" }),
|
|
9699
9717
|
/* @__PURE__ */ jsx75("div", { className: "fdc-usage-rows", children: limits.map((l) => /* @__PURE__ */ jsx75(
|
|
9700
9718
|
QuotaRow,
|
|
@@ -9706,23 +9724,23 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
9706
9724
|
l.id
|
|
9707
9725
|
)) })
|
|
9708
9726
|
] }) : null,
|
|
9709
|
-
stats ? /* @__PURE__ */
|
|
9710
|
-
stats.elapsedMs ? /* @__PURE__ */
|
|
9727
|
+
stats ? /* @__PURE__ */ jsxs71("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
|
|
9728
|
+
stats.elapsedMs ? /* @__PURE__ */ jsxs71("div", { children: [
|
|
9711
9729
|
/* @__PURE__ */ jsx75("span", { children: "Session" }),
|
|
9712
9730
|
/* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: formatDuration(stats.elapsedMs) })
|
|
9713
9731
|
] }) : null,
|
|
9714
|
-
stats.tokens ? /* @__PURE__ */
|
|
9732
|
+
stats.tokens ? /* @__PURE__ */ jsxs71("div", { children: [
|
|
9715
9733
|
/* @__PURE__ */ jsx75("span", { children: "Tokens" }),
|
|
9716
9734
|
/* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: stats.tokens.toLocaleString() })
|
|
9717
9735
|
] }) : null,
|
|
9718
|
-
stats.costUsd != null ? /* @__PURE__ */
|
|
9736
|
+
stats.costUsd != null ? /* @__PURE__ */ jsxs71("div", { children: [
|
|
9719
9737
|
/* @__PURE__ */ jsx75("span", { children: "Cost" }),
|
|
9720
|
-
/* @__PURE__ */
|
|
9738
|
+
/* @__PURE__ */ jsxs71("b", { className: "fd-tabular", children: [
|
|
9721
9739
|
"$",
|
|
9722
9740
|
Number(stats.costUsd).toFixed(3)
|
|
9723
9741
|
] })
|
|
9724
9742
|
] }) : null,
|
|
9725
|
-
stats.turns ? /* @__PURE__ */
|
|
9743
|
+
stats.turns ? /* @__PURE__ */ jsxs71("div", { children: [
|
|
9726
9744
|
/* @__PURE__ */ jsx75("span", { children: "Turns" }),
|
|
9727
9745
|
/* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: stats.turns })
|
|
9728
9746
|
] }) : null
|
|
@@ -9776,14 +9794,14 @@ function ModelControls({
|
|
|
9776
9794
|
items.push({ kind: "section", label: "Fast mode" });
|
|
9777
9795
|
items.push({
|
|
9778
9796
|
kind: "custom",
|
|
9779
|
-
render: () => /* @__PURE__ */
|
|
9797
|
+
render: () => /* @__PURE__ */ jsxs71("label", { className: "fdc-switchrow", children: [
|
|
9780
9798
|
/* @__PURE__ */ jsx75("span", { children: fastModeLabel }),
|
|
9781
9799
|
/* @__PURE__ */ jsx75("input", { type: "checkbox", className: "fd-sr", checked: !!fastMode, onChange: (e) => onFastModeChange(e.target.checked) }),
|
|
9782
9800
|
/* @__PURE__ */ jsx75("span", { className: "fd-switch-track" + (fastMode ? " is-on" : ""), "aria-hidden": "true", children: /* @__PURE__ */ jsx75("span", { className: "fd-switch-thumb" }) })
|
|
9783
9801
|
] })
|
|
9784
9802
|
});
|
|
9785
9803
|
}
|
|
9786
|
-
return /* @__PURE__ */
|
|
9804
|
+
return /* @__PURE__ */ jsxs71(React45.Fragment, { children: [
|
|
9787
9805
|
/* @__PURE__ */ jsx75(
|
|
9788
9806
|
MenuButton,
|
|
9789
9807
|
{
|
|
@@ -9816,7 +9834,7 @@ function ModelControls({
|
|
|
9816
9834
|
}
|
|
9817
9835
|
|
|
9818
9836
|
// src/components/chat/AgentChatPanel.tsx
|
|
9819
|
-
import { jsx as jsx76, jsxs as
|
|
9837
|
+
import { jsx as jsx76, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
9820
9838
|
var SURFACES = { sidebar: "is-sidebar", inline: "is-inline", page: "is-page", modal: "is-modal", sheet: "is-sheet" };
|
|
9821
9839
|
function AgentChatPanel({
|
|
9822
9840
|
/* required */
|
|
@@ -9900,11 +9918,11 @@ function AgentChatPanel({
|
|
|
9900
9918
|
onFeedback,
|
|
9901
9919
|
onEditMessage
|
|
9902
9920
|
}) {
|
|
9903
|
-
const [panelWidth, setPanelWidth] =
|
|
9904
|
-
const [applied, setApplied] =
|
|
9905
|
-
const [draft, setDraft] =
|
|
9906
|
-
const dragging =
|
|
9907
|
-
|
|
9921
|
+
const [panelWidth, setPanelWidth] = React46.useState(width);
|
|
9922
|
+
const [applied, setApplied] = React46.useState({});
|
|
9923
|
+
const [draft, setDraft] = React46.useState("");
|
|
9924
|
+
const dragging = React46.useRef(null);
|
|
9925
|
+
React46.useEffect(() => setPanelWidth(width), [width]);
|
|
9908
9926
|
const engine = useChatEngine({
|
|
9909
9927
|
contextType,
|
|
9910
9928
|
contextId,
|
|
@@ -10021,7 +10039,7 @@ function AgentChatPanel({
|
|
|
10021
10039
|
})))
|
|
10022
10040
|
}
|
|
10023
10041
|
) : null;
|
|
10024
|
-
return /* @__PURE__ */
|
|
10042
|
+
return /* @__PURE__ */ jsxs72(
|
|
10025
10043
|
"aside",
|
|
10026
10044
|
{
|
|
10027
10045
|
className: ["fdc-panel", SURFACES[surface] || SURFACES.sidebar, narrow ? "is-narrow" : "", className].filter(Boolean).join(" "),
|
|
@@ -10047,13 +10065,13 @@ function AgentChatPanel({
|
|
|
10047
10065
|
}
|
|
10048
10066
|
}
|
|
10049
10067
|
) : null,
|
|
10050
|
-
showHeader ? /* @__PURE__ */
|
|
10068
|
+
showHeader ? /* @__PURE__ */ jsxs72("header", { className: "fdc-head", children: [
|
|
10051
10069
|
/* @__PURE__ */ jsx76("span", { className: "fdc-head-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx76("i", { className: "ph ph-" + assistantIcon }) }),
|
|
10052
|
-
/* @__PURE__ */
|
|
10070
|
+
/* @__PURE__ */ jsxs72("span", { className: "fdc-head-titles", children: [
|
|
10053
10071
|
/* @__PURE__ */ jsx76("span", { className: "fdc-head-title", children: title }),
|
|
10054
10072
|
subtitle ? /* @__PURE__ */ jsx76("span", { className: "fdc-head-sub", children: subtitle }) : null
|
|
10055
10073
|
] }),
|
|
10056
|
-
/* @__PURE__ */
|
|
10074
|
+
/* @__PURE__ */ jsxs72("span", { className: "fdc-head-acts", children: [
|
|
10057
10075
|
headerActions,
|
|
10058
10076
|
threadMenu,
|
|
10059
10077
|
onNewThread ? /* @__PURE__ */ jsx76("button", { type: "button", className: "fdc-iconbtn", onClick: onNewThread, "aria-label": "New conversation", title: "New conversation", children: /* @__PURE__ */ jsx76("i", { className: "ph ph-plus", "aria-hidden": "true" }) }) : null,
|
|
@@ -10108,7 +10126,7 @@ function AgentChatPanel({
|
|
|
10108
10126
|
}
|
|
10109
10127
|
|
|
10110
10128
|
// src/kits/query.ts
|
|
10111
|
-
import * as
|
|
10129
|
+
import * as React47 from "react";
|
|
10112
10130
|
function eqFilter(get2) {
|
|
10113
10131
|
return (row, value) => Array.isArray(value) ? value.includes(get2(row)) : get2(row) === value;
|
|
10114
10132
|
}
|
|
@@ -10140,22 +10158,22 @@ function compare(a, b, dir) {
|
|
|
10140
10158
|
var API = null;
|
|
10141
10159
|
var PREFS = null;
|
|
10142
10160
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
|
|
10143
|
-
const [query, setQuery] =
|
|
10161
|
+
const [query, setQuery] = React47.useState(() => {
|
|
10144
10162
|
const store = PREFS || window.PlannerPrefs;
|
|
10145
10163
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
10146
10164
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
10147
10165
|
});
|
|
10148
|
-
const savePref =
|
|
10166
|
+
const savePref = React47.useCallback((patch2) => {
|
|
10149
10167
|
const store = PREFS || window.PlannerPrefs;
|
|
10150
10168
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
10151
10169
|
}, [prefsKey]);
|
|
10152
|
-
const [res, setRes] =
|
|
10153
|
-
const [loading, setLoading] =
|
|
10154
|
-
const seq2 =
|
|
10170
|
+
const [res, setRes] = React47.useState(null);
|
|
10171
|
+
const [loading, setLoading] = React47.useState(true);
|
|
10172
|
+
const seq2 = React47.useRef(0);
|
|
10155
10173
|
const depKey = (deps || []).join("|");
|
|
10156
10174
|
const paramKey = JSON.stringify(params || {});
|
|
10157
10175
|
const queryKey = JSON.stringify(query);
|
|
10158
|
-
|
|
10176
|
+
React47.useEffect(() => {
|
|
10159
10177
|
const id = ++seq2.current;
|
|
10160
10178
|
setLoading(true);
|
|
10161
10179
|
const t = setTimeout(() => {
|