@flytedan/flytebot-design-system 0.48.1 → 0.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1250 -993
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -1
- package/dist/index.d.ts +85 -1
- package/dist/index.js +1244 -993
- package/dist/index.js.map +1 -1
- package/package.json +7 -1
- package/styles/components.css +69 -0
package/dist/index.js
CHANGED
|
@@ -202,6 +202,8 @@ function open(layer) {
|
|
|
202
202
|
layer.order = ++lastOrder;
|
|
203
203
|
lastClosed = null;
|
|
204
204
|
if (layer.options.trap && !contains(scopeOf(layer), document.activeElement)) focusInto(layer);
|
|
205
|
+
zIndexVersion++;
|
|
206
|
+
notifyZIndexListeners();
|
|
205
207
|
}
|
|
206
208
|
function close(layer) {
|
|
207
209
|
openLayers.delete(layer);
|
|
@@ -212,7 +214,53 @@ function close(layer) {
|
|
|
212
214
|
document.removeEventListener("keydown", onKeydown);
|
|
213
215
|
pendingEscape = null;
|
|
214
216
|
}
|
|
217
|
+
zIndexVersion++;
|
|
218
|
+
notifyZIndexListeners();
|
|
215
219
|
}
|
|
220
|
+
var LAYER_STEP = 10;
|
|
221
|
+
var ROOT_STEP = 100;
|
|
222
|
+
var OVERLAY_CEILING = 1e4;
|
|
223
|
+
var zIndexListeners = /* @__PURE__ */ new Set();
|
|
224
|
+
var notifyZIndexListeners = () => {
|
|
225
|
+
zIndexListeners.forEach((listener) => listener());
|
|
226
|
+
};
|
|
227
|
+
var subscribeZIndex = (listener) => {
|
|
228
|
+
zIndexListeners.add(listener);
|
|
229
|
+
return () => {
|
|
230
|
+
zIndexListeners.delete(listener);
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
var zIndexVersion = 0;
|
|
234
|
+
var getZIndexVersion = () => zIndexVersion;
|
|
235
|
+
function openSiblingsOf(layer) {
|
|
236
|
+
const siblings = [];
|
|
237
|
+
for (const l of openLayers) if (l.parent === layer.parent) siblings.push(l);
|
|
238
|
+
return siblings.sort((a, b) => a.order - b.order);
|
|
239
|
+
}
|
|
240
|
+
function computeZIndex(layer) {
|
|
241
|
+
const path = [];
|
|
242
|
+
for (let l = layer; l; l = l.parent) path.push(l);
|
|
243
|
+
path.reverse();
|
|
244
|
+
let z = 0;
|
|
245
|
+
for (const l of path) {
|
|
246
|
+
const siblings = openSiblingsOf(l);
|
|
247
|
+
const index = Math.max(0, siblings.indexOf(l));
|
|
248
|
+
z = l.parent === null ? (index + 1) * ROOT_STEP : z + LAYER_STEP + index;
|
|
249
|
+
}
|
|
250
|
+
return z;
|
|
251
|
+
}
|
|
252
|
+
function useLayerZIndex(layer) {
|
|
253
|
+
React2.useSyncExternalStore(subscribeZIndex, getZIndexVersion, getZIndexVersion);
|
|
254
|
+
const l = layer;
|
|
255
|
+
return l.order > 0 ? computeZIndex(l) : 0;
|
|
256
|
+
}
|
|
257
|
+
var __resetLayerStackForTests = () => {
|
|
258
|
+
openLayers.clear();
|
|
259
|
+
lastOrder = 0;
|
|
260
|
+
pendingEscape = null;
|
|
261
|
+
lastClosed = null;
|
|
262
|
+
notifyZIndexListeners();
|
|
263
|
+
};
|
|
216
264
|
function returnFocus(layer) {
|
|
217
265
|
if (layer.options.returnFocus === false) return;
|
|
218
266
|
const current2 = document.activeElement;
|
|
@@ -369,50 +417,6 @@ var portal = (node) => {
|
|
|
369
417
|
if (typeof document !== "undefined") return createPortal(node, document.body);
|
|
370
418
|
return node;
|
|
371
419
|
};
|
|
372
|
-
var ROOT_LAYER = 0;
|
|
373
|
-
var LAYER_STEP = 10;
|
|
374
|
-
var ROOT_STEP = 100;
|
|
375
|
-
var OVERLAY_CEILING = 1e4;
|
|
376
|
-
var LayerContext2 = React3.createContext(ROOT_LAYER);
|
|
377
|
-
var openRootIds = [];
|
|
378
|
-
var rootListeners = /* @__PURE__ */ new Set();
|
|
379
|
-
var notifyRootListeners = () => {
|
|
380
|
-
rootListeners.forEach((listener) => listener());
|
|
381
|
-
};
|
|
382
|
-
var subscribeRootOverlays = (listener) => {
|
|
383
|
-
rootListeners.add(listener);
|
|
384
|
-
return () => {
|
|
385
|
-
rootListeners.delete(listener);
|
|
386
|
-
};
|
|
387
|
-
};
|
|
388
|
-
var getRootOverlaysSnapshot = () => openRootIds;
|
|
389
|
-
var registerRootOverlay = (id) => {
|
|
390
|
-
if (openRootIds.includes(id)) return;
|
|
391
|
-
openRootIds = [...openRootIds, id];
|
|
392
|
-
notifyRootListeners();
|
|
393
|
-
};
|
|
394
|
-
var unregisterRootOverlay = (id) => {
|
|
395
|
-
if (!openRootIds.includes(id)) return;
|
|
396
|
-
openRootIds = openRootIds.filter((existing) => existing !== id);
|
|
397
|
-
notifyRootListeners();
|
|
398
|
-
};
|
|
399
|
-
var useLayer = () => React3.useContext(LayerContext2);
|
|
400
|
-
var useOverlayLayer = (isOpen) => {
|
|
401
|
-
const parent = useLayer();
|
|
402
|
-
const isRoot = parent === ROOT_LAYER;
|
|
403
|
-
const id = React3.useId();
|
|
404
|
-
const openIds = React3.useSyncExternalStore(subscribeRootOverlays, getRootOverlaysSnapshot, getRootOverlaysSnapshot);
|
|
405
|
-
React3.useLayoutEffect(() => {
|
|
406
|
-
if (!isRoot || !isOpen) return;
|
|
407
|
-
registerRootOverlay(id);
|
|
408
|
-
return () => unregisterRootOverlay(id);
|
|
409
|
-
}, [isRoot, isOpen, id]);
|
|
410
|
-
if (!isRoot) return parent + LAYER_STEP;
|
|
411
|
-
if (!isOpen) return ROOT_LAYER;
|
|
412
|
-
const index = openIds.indexOf(id);
|
|
413
|
-
return index === -1 ? ROOT_LAYER : (index + 1) * ROOT_STEP;
|
|
414
|
-
};
|
|
415
|
-
var LayerProvider = ({ zIndex, children }) => /* @__PURE__ */ jsx4(LayerContext2.Provider, { value: zIndex, children });
|
|
416
420
|
function Popover({
|
|
417
421
|
open: open2,
|
|
418
422
|
anchorRef,
|
|
@@ -448,8 +452,8 @@ function Popover({
|
|
|
448
452
|
onDetach: onClose,
|
|
449
453
|
layerRef: ref
|
|
450
454
|
});
|
|
451
|
-
const zIndex = useOverlayLayer(!!open2);
|
|
452
455
|
const layer = useStackedLayer({ active: !!open2, containerRef: ref, onEscape: closeOnEscape ? onClose : void 0, returnFocus: returnFocus2 });
|
|
456
|
+
const zIndex = useLayerZIndex(layer);
|
|
453
457
|
React3.useEffect(() => {
|
|
454
458
|
if (!open2) return;
|
|
455
459
|
const away = (e) => {
|
|
@@ -465,7 +469,7 @@ function Popover({
|
|
|
465
469
|
}, [open2, closeOnOutside, onClose, anchorRef, triggerRef, layer]);
|
|
466
470
|
if (!open2 || !pos) return null;
|
|
467
471
|
return portal(
|
|
468
|
-
/* @__PURE__ */ jsx4(
|
|
472
|
+
/* @__PURE__ */ jsx4(StackedLayerProvider, { layer, children: /* @__PURE__ */ jsxs3(
|
|
469
473
|
"div",
|
|
470
474
|
{
|
|
471
475
|
ref,
|
|
@@ -508,7 +512,7 @@ function Popover({
|
|
|
508
512
|
footer != null ? /* @__PURE__ */ jsx4("div", { className: "fd-pop-footer", children: footer }) : null
|
|
509
513
|
]
|
|
510
514
|
}
|
|
511
|
-
) })
|
|
515
|
+
) })
|
|
512
516
|
);
|
|
513
517
|
}
|
|
514
518
|
var isItem = (it) => !!it && it.kind !== "separator" && it.kind !== "section" && it.kind !== "custom" && !it.disabled;
|
|
@@ -760,6 +764,7 @@ import { jsx as jsx6 } from "react/jsx-runtime";
|
|
|
760
764
|
function AnchoredPopover({ rect, width = 620, onClose, children }) {
|
|
761
765
|
const ref = React4.useRef(null);
|
|
762
766
|
const layer = useStackedLayer({ active: !!rect, containerRef: ref, onEscape: onClose });
|
|
767
|
+
const zIndex = useLayerZIndex(layer);
|
|
763
768
|
const w = Math.min(width, window.innerWidth - 32);
|
|
764
769
|
const [h, setH] = React4.useState(0);
|
|
765
770
|
React4.useLayoutEffect(() => {
|
|
@@ -801,7 +806,7 @@ function AnchoredPopover({ rect, width = 620, onClose, children }) {
|
|
|
801
806
|
left,
|
|
802
807
|
top,
|
|
803
808
|
width: w,
|
|
804
|
-
zIndex
|
|
809
|
+
zIndex,
|
|
805
810
|
maxHeight: `calc(100vh - ${PAD * 2}px)`,
|
|
806
811
|
overflowY: "auto",
|
|
807
812
|
background: "var(--surface)",
|
|
@@ -924,7 +929,6 @@ import * as React6 from "react";
|
|
|
924
929
|
import { createPortal as createPortal2 } from "react-dom";
|
|
925
930
|
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
926
931
|
function Drawer({ open: open2 = true, title, onClose, footer, children, className = "", ...rest }) {
|
|
927
|
-
const zIndex = useOverlayLayer(open2);
|
|
928
932
|
const asideRef = React6.useRef(null);
|
|
929
933
|
const [closing, setClosing] = React6.useState(false);
|
|
930
934
|
const close2 = React6.useCallback(() => {
|
|
@@ -933,9 +937,10 @@ function Drawer({ open: open2 = true, title, onClose, footer, children, classNam
|
|
|
933
937
|
setTimeout(onClose, 210);
|
|
934
938
|
}, [onClose]);
|
|
935
939
|
const layer = useStackedLayer({ active: !!open2, containerRef: asideRef, trap: true, onEscape: onClose ? close2 : void 0 });
|
|
940
|
+
const zIndex = useLayerZIndex(layer);
|
|
936
941
|
if (!open2) return null;
|
|
937
942
|
return createPortal2(
|
|
938
|
-
/* @__PURE__ */
|
|
943
|
+
/* @__PURE__ */ jsxs6(StackedLayerProvider, { layer, children: [
|
|
939
944
|
/* @__PURE__ */ jsx9("div", { className: "fd-scrim" + (closing ? " is-closing" : ""), style: { display: "block", zIndex: zIndex - LAYER_STEP }, onClick: close2 }),
|
|
940
945
|
/* @__PURE__ */ jsxs6("aside", { ref: asideRef, className: ["fd-drawer", closing ? "is-closing" : "", className].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", ...rest, style: { zIndex }, children: [
|
|
941
946
|
/* @__PURE__ */ jsxs6("div", { className: "fd-card-head", style: { flex: "none" }, children: [
|
|
@@ -945,7 +950,7 @@ function Drawer({ open: open2 = true, title, onClose, footer, children, classNam
|
|
|
945
950
|
/* @__PURE__ */ jsx9("div", { style: { flex: "1 1 auto", minHeight: 0, overflow: "auto", padding: 20 }, children }),
|
|
946
951
|
footer ? /* @__PURE__ */ jsx9("div", { className: "fd-card-foot", style: { flex: "none" }, children: typeof footer === "function" ? footer(close2) : footer }) : null
|
|
947
952
|
] })
|
|
948
|
-
] })
|
|
953
|
+
] }),
|
|
949
954
|
document.body
|
|
950
955
|
);
|
|
951
956
|
}
|
|
@@ -957,16 +962,16 @@ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
|
957
962
|
function Modal({ open: open2 = true, title, description, onClose, footer, wide = false, children, className = "", ...rest }) {
|
|
958
963
|
const [closing, setClosing] = React7.useState(false);
|
|
959
964
|
const boxRef = React7.useRef(null);
|
|
960
|
-
const zIndex = useOverlayLayer(!!open2);
|
|
961
965
|
const close2 = React7.useCallback(() => {
|
|
962
966
|
if (!onClose) return;
|
|
963
967
|
setClosing(true);
|
|
964
968
|
setTimeout(onClose, 190);
|
|
965
969
|
}, [onClose]);
|
|
966
970
|
const layer = useStackedLayer({ active: !!open2, containerRef: boxRef, trap: true, onEscape: onClose ? close2 : void 0 });
|
|
971
|
+
const zIndex = useLayerZIndex(layer);
|
|
967
972
|
if (!open2) return null;
|
|
968
973
|
return createPortal3(
|
|
969
|
-
/* @__PURE__ */ jsx10(
|
|
974
|
+
/* @__PURE__ */ jsx10(StackedLayerProvider, { layer, children: /* @__PURE__ */ jsx10(
|
|
970
975
|
"div",
|
|
971
976
|
{
|
|
972
977
|
className: "fd-scrim" + (closing ? " is-closing" : ""),
|
|
@@ -997,7 +1002,7 @@ function Modal({ open: open2 = true, title, description, onClose, footer, wide =
|
|
|
997
1002
|
}
|
|
998
1003
|
)
|
|
999
1004
|
}
|
|
1000
|
-
) })
|
|
1005
|
+
) }),
|
|
1001
1006
|
document.body
|
|
1002
1007
|
);
|
|
1003
1008
|
}
|
|
@@ -1860,8 +1865,8 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1860
1865
|
layerRef: bubbleRef,
|
|
1861
1866
|
onDetach: hide
|
|
1862
1867
|
});
|
|
1863
|
-
const
|
|
1864
|
-
|
|
1868
|
+
const layer = useStackedLayer({ active: open2, containerRef: bubbleRef, onEscape: hide, returnFocus: false });
|
|
1869
|
+
const zIndex = useLayerZIndex(layer);
|
|
1865
1870
|
React14.useEffect(() => {
|
|
1866
1871
|
if (!open2) return;
|
|
1867
1872
|
const away = (e) => {
|
|
@@ -4641,7 +4646,7 @@ function CodeBlock({
|
|
|
4641
4646
|
code = "",
|
|
4642
4647
|
language,
|
|
4643
4648
|
filename,
|
|
4644
|
-
lineNumbers = false,
|
|
4649
|
+
lineNumbers: lineNumbers2 = false,
|
|
4645
4650
|
wrap: wrapDefault = false,
|
|
4646
4651
|
collapseAfter = 26,
|
|
4647
4652
|
copyable = true,
|
|
@@ -4668,7 +4673,7 @@ function CodeBlock({
|
|
|
4668
4673
|
] }) : null
|
|
4669
4674
|
] }),
|
|
4670
4675
|
/* @__PURE__ */ jsxs41("div", { className: "fd-code-body", children: [
|
|
4671
|
-
|
|
4676
|
+
lineNumbers2 ? /* @__PURE__ */ jsx49("pre", { className: "fd-code-gutter", "aria-hidden": "true", children: shown.split("\n").map((_, i) => i + 1 + "\n").join("") }) : null,
|
|
4672
4677
|
/* @__PURE__ */ jsx49("pre", { className: "fd-code-pre", tabIndex: 0, children: /* @__PURE__ */ jsx49("code", { children: /* @__PURE__ */ jsx49(Highlighted, { code: shown, lang: language }) }) })
|
|
4673
4678
|
] }),
|
|
4674
4679
|
foldable ? /* @__PURE__ */ jsxs41("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -5184,9 +5189,9 @@ import * as React31 from "react";
|
|
|
5184
5189
|
import { jsx as jsx54 } from "react/jsx-runtime";
|
|
5185
5190
|
function useInlinePanel() {
|
|
5186
5191
|
const [open2, setOpen] = React31.useState(false);
|
|
5187
|
-
const zIndex = useOverlayLayer(open2);
|
|
5188
5192
|
const ref = React31.useRef(null);
|
|
5189
5193
|
const layer = useStackedLayer({ active: open2, containerRef: ref, onEscape: () => setOpen(false) });
|
|
5194
|
+
const zIndex = useLayerZIndex(layer);
|
|
5190
5195
|
React31.useEffect(() => {
|
|
5191
5196
|
if (!open2) return;
|
|
5192
5197
|
const away = (e) => {
|
|
@@ -5198,7 +5203,7 @@ function useInlinePanel() {
|
|
|
5198
5203
|
return { open: open2, setOpen, ref, zIndex, layer };
|
|
5199
5204
|
}
|
|
5200
5205
|
function InlinePanelLayers({ panel, children }) {
|
|
5201
|
-
return /* @__PURE__ */ jsx54(
|
|
5206
|
+
return /* @__PURE__ */ jsx54(StackedLayerProvider, { layer: panel.layer, children });
|
|
5202
5207
|
}
|
|
5203
5208
|
|
|
5204
5209
|
// src/components/data/SortMenu.tsx
|
|
@@ -7251,17 +7256,254 @@ var MarkdownEditor = React42.forwardRef(function MarkdownEditor2({
|
|
|
7251
7256
|
] });
|
|
7252
7257
|
});
|
|
7253
7258
|
|
|
7259
|
+
// src/components/forms/CodeEditor.tsx
|
|
7260
|
+
import * as React43 from "react";
|
|
7261
|
+
import { EditorView, keymap, lineNumbers, placeholder as cmPlaceholder, drawSelection, Decoration } from "@codemirror/view";
|
|
7262
|
+
import { EditorState, StateEffect, StateField, Compartment } from "@codemirror/state";
|
|
7263
|
+
import { defaultKeymap, history, historyKeymap, indentMore, indentLess } from "@codemirror/commands";
|
|
7264
|
+
import { sql as sqlLang } from "@codemirror/lang-sql";
|
|
7265
|
+
import { syntaxHighlighting, HighlightStyle, indentOnInput, bracketMatching } from "@codemirror/language";
|
|
7266
|
+
import { tags } from "@lezer/highlight";
|
|
7267
|
+
import { jsx as jsx72, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
7268
|
+
function clampOffset(state, line, column) {
|
|
7269
|
+
const total = state.doc.lines;
|
|
7270
|
+
const ln = state.doc.line(Math.min(Math.max(1, line), total));
|
|
7271
|
+
const col = Math.max(0, (column || 1) - 1);
|
|
7272
|
+
return Math.min(ln.from + col, ln.to);
|
|
7273
|
+
}
|
|
7274
|
+
function toCmDiagnostics(state, diags) {
|
|
7275
|
+
return diags.map((d) => {
|
|
7276
|
+
const from = clampOffset(state, d.line, d.column ?? 1);
|
|
7277
|
+
const endLine = d.endLine ?? d.line;
|
|
7278
|
+
const endColumn = d.endColumn ?? state.doc.line(Math.min(Math.max(1, endLine), state.doc.lines)).length + 1;
|
|
7279
|
+
let to = clampOffset(state, endLine, endColumn);
|
|
7280
|
+
if (to <= from) to = Math.min(from + 1, state.doc.length);
|
|
7281
|
+
return { from, to, severity: d.severity || "error", message: d.message, source: void 0 };
|
|
7282
|
+
});
|
|
7283
|
+
}
|
|
7284
|
+
var setDiagnosticsEffect = StateEffect.define();
|
|
7285
|
+
var diagnosticsField = StateField.define({
|
|
7286
|
+
create: () => [],
|
|
7287
|
+
update(value, tr) {
|
|
7288
|
+
for (const e of tr.effects) if (e.is(setDiagnosticsEffect)) return e.value;
|
|
7289
|
+
if (!tr.docChanged) return value;
|
|
7290
|
+
return value.map((d) => ({ ...d, from: tr.changes.mapPos(d.from), to: tr.changes.mapPos(d.to) }));
|
|
7291
|
+
}
|
|
7292
|
+
});
|
|
7293
|
+
var tokenHighlight = HighlightStyle.define([
|
|
7294
|
+
{ tag: tags.keyword, class: "tok-kw" },
|
|
7295
|
+
{ tag: tags.string, class: "tok-str" },
|
|
7296
|
+
{ tag: [tags.number, tags.bool], class: "tok-num" },
|
|
7297
|
+
{ tag: tags.comment, class: "tok-com" },
|
|
7298
|
+
{ tag: [tags.function(tags.variableName), tags.function(tags.propertyName)], class: "tok-fn" },
|
|
7299
|
+
{ tag: tags.typeName, class: "tok-type" },
|
|
7300
|
+
{ tag: tags.propertyName, class: "tok-prop" },
|
|
7301
|
+
{ tag: tags.null, class: "tok-lit" },
|
|
7302
|
+
{ tag: [tags.punctuation, tags.paren, tags.bracket], class: "tok-pun" },
|
|
7303
|
+
{ tag: tags.operator, class: "tok-op" }
|
|
7304
|
+
]);
|
|
7305
|
+
var editorTheme = EditorView.theme({
|
|
7306
|
+
"&": {
|
|
7307
|
+
fontFamily: "var(--font-mono)",
|
|
7308
|
+
fontSize: "12.5px",
|
|
7309
|
+
color: "var(--text)",
|
|
7310
|
+
backgroundColor: "transparent",
|
|
7311
|
+
height: "100%"
|
|
7312
|
+
},
|
|
7313
|
+
".cm-content": { padding: "10px 12px", caretColor: "var(--text)" },
|
|
7314
|
+
".cm-scroller": { fontFamily: "var(--font-mono)", lineHeight: "1.62" },
|
|
7315
|
+
".cm-gutters": {
|
|
7316
|
+
backgroundColor: "transparent",
|
|
7317
|
+
color: "var(--text-disabled)",
|
|
7318
|
+
border: "0",
|
|
7319
|
+
borderRight: "1px solid var(--chat-code-border)"
|
|
7320
|
+
},
|
|
7321
|
+
".cm-lineNumbers .cm-gutterElement": { padding: "0 8px 0 12px" },
|
|
7322
|
+
".cm-activeLine": { backgroundColor: "var(--surface-2)" },
|
|
7323
|
+
".cm-activeLineGutter": { backgroundColor: "var(--surface-2)", color: "var(--text-2)" },
|
|
7324
|
+
"&.cm-focused": { outline: "none" },
|
|
7325
|
+
".cm-cursor": { borderLeftColor: "var(--text)" },
|
|
7326
|
+
".cm-selectionBackground, &.cm-focused .cm-selectionBackground": { backgroundColor: "var(--blue-100) !important" },
|
|
7327
|
+
".cm-placeholder": { color: "var(--text-disabled)" },
|
|
7328
|
+
".fd-cm-diag-error": { textDecoration: "underline wavy var(--danger-solid)", textUnderlineOffset: "3px" },
|
|
7329
|
+
".fd-cm-diag-warning": { textDecoration: "underline wavy var(--warn-solid)", textUnderlineOffset: "3px" },
|
|
7330
|
+
".fd-cm-diag-info": { textDecoration: "underline wavy var(--info-solid)", textUnderlineOffset: "3px" }
|
|
7331
|
+
}, { dark: false });
|
|
7332
|
+
function severityClass(sev) {
|
|
7333
|
+
return sev === "warning" ? "fd-cm-diag-warning" : sev === "info" ? "fd-cm-diag-info" : "fd-cm-diag-error";
|
|
7334
|
+
}
|
|
7335
|
+
function decorationsFromDiagnostics() {
|
|
7336
|
+
return EditorView.decorations.compute([diagnosticsField], (state) => {
|
|
7337
|
+
const diags = state.field(diagnosticsField);
|
|
7338
|
+
if (!diags.length) return Decoration.none;
|
|
7339
|
+
const marks = diags.filter((d) => d.from < d.to).sort((a, b) => a.from - b.from).map((d) => Decoration.mark({ class: severityClass(d.severity) }).range(d.from, d.to));
|
|
7340
|
+
return Decoration.set(marks, true);
|
|
7341
|
+
});
|
|
7342
|
+
}
|
|
7343
|
+
function CodeEditor({
|
|
7344
|
+
value,
|
|
7345
|
+
onChange,
|
|
7346
|
+
label,
|
|
7347
|
+
help,
|
|
7348
|
+
error,
|
|
7349
|
+
required = false,
|
|
7350
|
+
disabled = false,
|
|
7351
|
+
readOnly = false,
|
|
7352
|
+
placeholder: placeholderText = "",
|
|
7353
|
+
diagnostics = [],
|
|
7354
|
+
showEscapeHint = true,
|
|
7355
|
+
minHeight = 160,
|
|
7356
|
+
id,
|
|
7357
|
+
className = "",
|
|
7358
|
+
style,
|
|
7359
|
+
autoFocus = false
|
|
7360
|
+
}) {
|
|
7361
|
+
const fieldId = useFieldId(id);
|
|
7362
|
+
const descId = fieldId + "-desc";
|
|
7363
|
+
const liveId = fieldId + "-live";
|
|
7364
|
+
const hostRef = React43.useRef(null);
|
|
7365
|
+
const viewRef = React43.useRef(null);
|
|
7366
|
+
const valueRef = React43.useRef(value);
|
|
7367
|
+
const onChangeRef = React43.useRef(onChange);
|
|
7368
|
+
onChangeRef.current = onChange;
|
|
7369
|
+
const editableCompartment = React43.useRef(new Compartment()).current;
|
|
7370
|
+
const attributesCompartment = React43.useRef(new Compartment()).current;
|
|
7371
|
+
const errorRef = React43.useRef(error);
|
|
7372
|
+
errorRef.current = error;
|
|
7373
|
+
const diagnosticsCountRef = React43.useRef(diagnostics.length);
|
|
7374
|
+
diagnosticsCountRef.current = diagnostics.length;
|
|
7375
|
+
function contentAttributes() {
|
|
7376
|
+
return {
|
|
7377
|
+
id: fieldId,
|
|
7378
|
+
"aria-describedby": descId + " " + liveId,
|
|
7379
|
+
"aria-invalid": errorRef.current || diagnosticsCountRef.current ? "true" : "false",
|
|
7380
|
+
...label ? { "aria-label": label } : {}
|
|
7381
|
+
};
|
|
7382
|
+
}
|
|
7383
|
+
React43.useEffect(() => {
|
|
7384
|
+
const host = hostRef.current;
|
|
7385
|
+
if (!host) return;
|
|
7386
|
+
const updateListener = EditorView.updateListener.of((update) => {
|
|
7387
|
+
if (!update.docChanged) return;
|
|
7388
|
+
const next = update.state.doc.toString();
|
|
7389
|
+
valueRef.current = next;
|
|
7390
|
+
onChangeRef.current && onChangeRef.current(next);
|
|
7391
|
+
});
|
|
7392
|
+
const state = EditorState.create({
|
|
7393
|
+
doc: value,
|
|
7394
|
+
extensions: [
|
|
7395
|
+
lineNumbers(),
|
|
7396
|
+
history(),
|
|
7397
|
+
drawSelection(),
|
|
7398
|
+
indentOnInput(),
|
|
7399
|
+
bracketMatching(),
|
|
7400
|
+
sqlLang(),
|
|
7401
|
+
syntaxHighlighting(tokenHighlight),
|
|
7402
|
+
diagnosticsField,
|
|
7403
|
+
decorationsFromDiagnostics(),
|
|
7404
|
+
editorTheme,
|
|
7405
|
+
cmPlaceholder(placeholderText),
|
|
7406
|
+
keymap.of([
|
|
7407
|
+
{ key: "Tab", run: indentMore, shift: indentLess },
|
|
7408
|
+
...defaultKeymap,
|
|
7409
|
+
...historyKeymap
|
|
7410
|
+
]),
|
|
7411
|
+
editableCompartment.of(EditorView.editable.of(!disabled)),
|
|
7412
|
+
EditorState.readOnly.of(readOnly),
|
|
7413
|
+
updateListener,
|
|
7414
|
+
attributesCompartment.of(EditorView.contentAttributes.of(contentAttributes()))
|
|
7415
|
+
]
|
|
7416
|
+
});
|
|
7417
|
+
const view = new EditorView({ state, parent: host });
|
|
7418
|
+
viewRef.current = view;
|
|
7419
|
+
if (autoFocus) view.focus();
|
|
7420
|
+
return () => {
|
|
7421
|
+
view.destroy();
|
|
7422
|
+
viewRef.current = null;
|
|
7423
|
+
};
|
|
7424
|
+
}, []);
|
|
7425
|
+
React43.useEffect(() => {
|
|
7426
|
+
const view = viewRef.current;
|
|
7427
|
+
if (!view) return;
|
|
7428
|
+
const current2 = view.state.doc.toString();
|
|
7429
|
+
if (current2 !== value) {
|
|
7430
|
+
view.dispatch({ changes: { from: 0, to: current2.length, insert: value } });
|
|
7431
|
+
}
|
|
7432
|
+
valueRef.current = value;
|
|
7433
|
+
}, [value]);
|
|
7434
|
+
React43.useEffect(() => {
|
|
7435
|
+
const view = viewRef.current;
|
|
7436
|
+
if (!view) return;
|
|
7437
|
+
view.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!disabled)) });
|
|
7438
|
+
}, [disabled, editableCompartment]);
|
|
7439
|
+
React43.useEffect(() => {
|
|
7440
|
+
const view = viewRef.current;
|
|
7441
|
+
if (!view) return;
|
|
7442
|
+
view.dispatch({
|
|
7443
|
+
effects: [
|
|
7444
|
+
setDiagnosticsEffect.of(toCmDiagnostics(view.state, diagnostics)),
|
|
7445
|
+
attributesCompartment.reconfigure(EditorView.contentAttributes.of(contentAttributes()))
|
|
7446
|
+
]
|
|
7447
|
+
});
|
|
7448
|
+
}, [diagnostics, error]);
|
|
7449
|
+
const box = ["fd-input", "fd-code-editor", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
|
|
7450
|
+
const announce = diagnostics.length ? diagnostics.length + (diagnostics.length === 1 ? " problem: " : " problems: ") + diagnostics.map((d) => "line " + d.line + (d.column ? ", column " + d.column : "") + ": " + d.message).join("; ") : "";
|
|
7451
|
+
return /* @__PURE__ */ jsxs63("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
|
|
7452
|
+
label ? /* @__PURE__ */ jsx72(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
|
|
7453
|
+
/* @__PURE__ */ jsx72(
|
|
7454
|
+
"div",
|
|
7455
|
+
{
|
|
7456
|
+
className: box,
|
|
7457
|
+
style: { minHeight },
|
|
7458
|
+
children: /* @__PURE__ */ jsx72(
|
|
7459
|
+
"div",
|
|
7460
|
+
{
|
|
7461
|
+
ref: hostRef,
|
|
7462
|
+
className: "fd-code-editor-host",
|
|
7463
|
+
style: { minHeight }
|
|
7464
|
+
}
|
|
7465
|
+
)
|
|
7466
|
+
}
|
|
7467
|
+
),
|
|
7468
|
+
/* @__PURE__ */ jsxs63("span", { id: descId, className: "fd-sr", children: [
|
|
7469
|
+
help ? help + ". " : "",
|
|
7470
|
+
showEscapeHint ? "Tab indents. Press Escape, then Tab, to move focus out of the editor." : ""
|
|
7471
|
+
] }),
|
|
7472
|
+
/* @__PURE__ */ jsx72("div", { id: liveId, className: "fd-sr", role: "status", "aria-live": "polite", children: announce }),
|
|
7473
|
+
diagnostics.length ? /* @__PURE__ */ jsx72("ul", { className: "fd-code-editor-diagnostics", children: diagnostics.map((d, i) => /* @__PURE__ */ jsxs63("li", { className: "fd-code-editor-diag is-" + (d.severity || "error"), children: [
|
|
7474
|
+
/* @__PURE__ */ jsx72(
|
|
7475
|
+
"i",
|
|
7476
|
+
{
|
|
7477
|
+
className: "ph ph-" + (d.severity === "warning" ? "warning" : d.severity === "info" ? "info" : "warning-circle"),
|
|
7478
|
+
"aria-hidden": "true"
|
|
7479
|
+
}
|
|
7480
|
+
),
|
|
7481
|
+
/* @__PURE__ */ jsxs63("span", { className: "fd-code-editor-diag-loc", children: [
|
|
7482
|
+
"Line ",
|
|
7483
|
+
d.line,
|
|
7484
|
+
d.column ? ":" + d.column : ""
|
|
7485
|
+
] }),
|
|
7486
|
+
/* @__PURE__ */ jsx72("span", { children: d.message })
|
|
7487
|
+
] }, i)) }) : null,
|
|
7488
|
+
error ? /* @__PURE__ */ jsxs63("span", { className: "fd-field-error", children: [
|
|
7489
|
+
/* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
7490
|
+
error
|
|
7491
|
+
] }) : !diagnostics.length && help ? /* @__PURE__ */ jsx72("span", { className: "fd-field-help", children: help }) : null,
|
|
7492
|
+
showEscapeHint ? /* @__PURE__ */ jsx72("span", { className: "fd-field-help fd-code-editor-hint", children: "Tab indents. Escape, then Tab, moves focus out." }) : null
|
|
7493
|
+
] });
|
|
7494
|
+
}
|
|
7495
|
+
|
|
7254
7496
|
// src/components/platform/AccountMenu.tsx
|
|
7255
|
-
import * as
|
|
7497
|
+
import * as React45 from "react";
|
|
7256
7498
|
|
|
7257
7499
|
// src/kits/sessionContext.tsx
|
|
7258
|
-
import * as
|
|
7259
|
-
var SessionContext =
|
|
7500
|
+
import * as React44 from "react";
|
|
7501
|
+
var SessionContext = React44.createContext(null);
|
|
7260
7502
|
function SessionProvider({ value, children }) {
|
|
7261
|
-
return
|
|
7503
|
+
return React44.createElement(SessionContext.Provider, { value }, children);
|
|
7262
7504
|
}
|
|
7263
7505
|
function useSessionContext() {
|
|
7264
|
-
const ctx =
|
|
7506
|
+
const ctx = React44.useContext(SessionContext);
|
|
7265
7507
|
if (!ctx) {
|
|
7266
7508
|
throw new Error(
|
|
7267
7509
|
"useSessionContext() was called outside a <SessionProvider>. Wrap your app root in <SessionProvider value={...}> with your real session, or \u2014 in the docs site or a demo \u2014 in <DemoSessionProvider>, before rendering AccountMenu, Gate, ProfilePage or AppSwitcher."
|
|
@@ -7271,11 +7513,11 @@ function useSessionContext() {
|
|
|
7271
7513
|
}
|
|
7272
7514
|
|
|
7273
7515
|
// src/components/platform/AccountMenu.tsx
|
|
7274
|
-
import { Fragment as Fragment16, jsx as
|
|
7516
|
+
import { Fragment as Fragment16, jsx as jsx73, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
7275
7517
|
var DEFAULT_LINKS = [];
|
|
7276
7518
|
var DEFAULT_GROUPS = [];
|
|
7277
7519
|
function Item({ item, onPick }) {
|
|
7278
|
-
return /* @__PURE__ */
|
|
7520
|
+
return /* @__PURE__ */ jsxs64(
|
|
7279
7521
|
"button",
|
|
7280
7522
|
{
|
|
7281
7523
|
type: "button",
|
|
@@ -7283,9 +7525,9 @@ function Item({ item, onPick }) {
|
|
|
7283
7525
|
className: "fd-acct-item",
|
|
7284
7526
|
onClick: () => onPick(item),
|
|
7285
7527
|
children: [
|
|
7286
|
-
item.icon ? /* @__PURE__ */
|
|
7287
|
-
/* @__PURE__ */
|
|
7288
|
-
item.badge ? /* @__PURE__ */
|
|
7528
|
+
item.icon ? /* @__PURE__ */ jsx73("i", { className: "ph ph-" + item.icon, "aria-hidden": "true" }) : null,
|
|
7529
|
+
/* @__PURE__ */ jsx73("span", { style: { flex: 1 }, children: item.label }),
|
|
7530
|
+
item.badge ? /* @__PURE__ */ jsx73(Badge, { tone: "neutral", children: item.badge }) : null
|
|
7289
7531
|
]
|
|
7290
7532
|
}
|
|
7291
7533
|
);
|
|
@@ -7301,11 +7543,11 @@ function AccountMenu({
|
|
|
7301
7543
|
...rest
|
|
7302
7544
|
}) {
|
|
7303
7545
|
const { user, roles, can: can2, signOut: ctxSignOut, demo, pending } = useSessionContext();
|
|
7304
|
-
const [open2, setOpen] =
|
|
7305
|
-
const [switching, setSwitching] =
|
|
7306
|
-
const [signingOut, setSigningOut] =
|
|
7307
|
-
const [signOutError, setSignOutError] =
|
|
7308
|
-
const ref =
|
|
7546
|
+
const [open2, setOpen] = React45.useState(false);
|
|
7547
|
+
const [switching, setSwitching] = React45.useState(false);
|
|
7548
|
+
const [signingOut, setSigningOut] = React45.useState(false);
|
|
7549
|
+
const [signOutError, setSignOutError] = React45.useState(null);
|
|
7550
|
+
const ref = React45.useRef(null);
|
|
7309
7551
|
const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
|
|
7310
7552
|
const visibleGroups = groups.map((g) => ({ label: g.label, links: g.links.filter((l) => !l.perm || !pending && can2(l.perm)) })).filter((g) => g.links.length);
|
|
7311
7553
|
const closeMenu = () => {
|
|
@@ -7333,8 +7575,8 @@ function AccountMenu({
|
|
|
7333
7575
|
}
|
|
7334
7576
|
};
|
|
7335
7577
|
const showSwitcher = allowUserSwitch && !!demo;
|
|
7336
|
-
return /* @__PURE__ */
|
|
7337
|
-
/* @__PURE__ */
|
|
7578
|
+
return /* @__PURE__ */ jsxs64(Fragment16, { children: [
|
|
7579
|
+
/* @__PURE__ */ jsxs64(
|
|
7338
7580
|
"button",
|
|
7339
7581
|
{
|
|
7340
7582
|
type: "button",
|
|
@@ -7346,12 +7588,12 @@ function AccountMenu({
|
|
|
7346
7588
|
onClick: () => open2 ? closeMenu() : setOpen(true),
|
|
7347
7589
|
...rest,
|
|
7348
7590
|
children: [
|
|
7349
|
-
/* @__PURE__ */
|
|
7350
|
-
/* @__PURE__ */
|
|
7591
|
+
/* @__PURE__ */ jsx73(Avatar, { name: user.name, size: "sm" }),
|
|
7592
|
+
/* @__PURE__ */ jsx73("i", { className: "ph ph-caret-down", "aria-hidden": "true", style: { fontSize: 11, color: "var(--text-muted)" } })
|
|
7351
7593
|
]
|
|
7352
7594
|
}
|
|
7353
7595
|
),
|
|
7354
|
-
/* @__PURE__ */
|
|
7596
|
+
/* @__PURE__ */ jsx73(
|
|
7355
7597
|
Popover,
|
|
7356
7598
|
{
|
|
7357
7599
|
open: open2,
|
|
@@ -7359,27 +7601,27 @@ function AccountMenu({
|
|
|
7359
7601
|
onClose: closeMenu,
|
|
7360
7602
|
placement: "bottom-end",
|
|
7361
7603
|
width: 272,
|
|
7362
|
-
children: /* @__PURE__ */
|
|
7363
|
-
/* @__PURE__ */
|
|
7364
|
-
/* @__PURE__ */
|
|
7365
|
-
/* @__PURE__ */
|
|
7366
|
-
/* @__PURE__ */
|
|
7367
|
-
/* @__PURE__ */
|
|
7604
|
+
children: /* @__PURE__ */ jsxs64("div", { role: "menu", className: "fd-stack", style: { gap: 0 }, children: [
|
|
7605
|
+
/* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
|
|
7606
|
+
/* @__PURE__ */ jsx73(Avatar, { name: user.name }),
|
|
7607
|
+
/* @__PURE__ */ jsxs64("span", { className: "fd-stack", style: { gap: 1, minWidth: 0, flex: 1 }, children: [
|
|
7608
|
+
/* @__PURE__ */ jsx73("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: user.name }),
|
|
7609
|
+
/* @__PURE__ */ jsx73("span", { className: "fd-body-sm fd-muted fd-table-trunc", title: truncationTitle(user.email), children: user.email })
|
|
7368
7610
|
] })
|
|
7369
7611
|
] }),
|
|
7370
|
-
showRoles && roles.length ? /* @__PURE__ */
|
|
7371
|
-
visibleLinks.length ? /* @__PURE__ */
|
|
7372
|
-
visibleGroups.map((g) => /* @__PURE__ */
|
|
7373
|
-
/* @__PURE__ */
|
|
7374
|
-
g.links.map((l) => /* @__PURE__ */
|
|
7612
|
+
showRoles && roles.length ? /* @__PURE__ */ jsx73("div", { className: "fd-row", style: { gap: 6, padding: "10px 14px", flexWrap: "wrap", borderBottom: "1px solid var(--border)" }, children: roles.map((r) => /* @__PURE__ */ jsx73(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)) }) : null,
|
|
7613
|
+
visibleLinks.length ? /* @__PURE__ */ jsx73("div", { className: "fd-acct-group", children: visibleLinks.map((l) => /* @__PURE__ */ jsx73(Item, { item: l, onPick: pick }, l.id)) }) : null,
|
|
7614
|
+
visibleGroups.map((g) => /* @__PURE__ */ jsxs64("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
|
|
7615
|
+
/* @__PURE__ */ jsx73("span", { className: "fd-overline fd-muted", style: { padding: "8px 14px 4px", display: "block" }, children: g.label }),
|
|
7616
|
+
g.links.map((l) => /* @__PURE__ */ jsx73(Item, { item: l, onPick: pick }, l.id))
|
|
7375
7617
|
] }, g.label)),
|
|
7376
|
-
showSwitcher && demo ? /* @__PURE__ */
|
|
7377
|
-
/* @__PURE__ */
|
|
7378
|
-
/* @__PURE__ */
|
|
7379
|
-
/* @__PURE__ */
|
|
7380
|
-
/* @__PURE__ */
|
|
7618
|
+
showSwitcher && demo ? /* @__PURE__ */ jsxs64("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
|
|
7619
|
+
/* @__PURE__ */ jsxs64("button", { type: "button", role: "menuitem", className: "fd-acct-item", onClick: () => setSwitching((s) => !s), children: [
|
|
7620
|
+
/* @__PURE__ */ jsx73("i", { className: "ph ph-user-switch", "aria-hidden": "true" }),
|
|
7621
|
+
/* @__PURE__ */ jsx73("span", { style: { flex: 1 }, children: "View as another member" }),
|
|
7622
|
+
/* @__PURE__ */ jsx73("i", { className: "ph ph-caret-" + (switching ? "up" : "down"), "aria-hidden": "true", style: { fontSize: 11 } })
|
|
7381
7623
|
] }),
|
|
7382
|
-
switching ? /* @__PURE__ */
|
|
7624
|
+
switching ? /* @__PURE__ */ jsx73("div", { className: "fd-stack", style: { gap: 0 }, children: demo.allUsers.map((u) => /* @__PURE__ */ jsxs64(
|
|
7383
7625
|
"button",
|
|
7384
7626
|
{
|
|
7385
7627
|
type: "button",
|
|
@@ -7391,19 +7633,19 @@ function AccountMenu({
|
|
|
7391
7633
|
setSwitching(false);
|
|
7392
7634
|
},
|
|
7393
7635
|
children: [
|
|
7394
|
-
/* @__PURE__ */
|
|
7395
|
-
/* @__PURE__ */
|
|
7396
|
-
/* @__PURE__ */
|
|
7397
|
-
u.roles ? /* @__PURE__ */
|
|
7636
|
+
/* @__PURE__ */ jsx73(Avatar, { name: u.name, size: "sm" }),
|
|
7637
|
+
/* @__PURE__ */ jsxs64("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
|
|
7638
|
+
/* @__PURE__ */ jsx73("span", { style: { fontWeight: u.id === user.id ? 700 : 500 }, children: u.name }),
|
|
7639
|
+
u.roles ? /* @__PURE__ */ jsx73("span", { className: "fd-muted", style: { fontSize: 11.5 }, children: u.roles.join(", ") }) : null
|
|
7398
7640
|
] }),
|
|
7399
|
-
u.id === user.id ? /* @__PURE__ */
|
|
7641
|
+
u.id === user.id ? /* @__PURE__ */ jsx73("i", { className: "ph ph-check", "aria-hidden": "true", style: { color: "var(--ok-text)" } }) : null
|
|
7400
7642
|
]
|
|
7401
7643
|
},
|
|
7402
7644
|
u.id
|
|
7403
7645
|
)) }) : null
|
|
7404
7646
|
] }) : null,
|
|
7405
|
-
/* @__PURE__ */
|
|
7406
|
-
/* @__PURE__ */
|
|
7647
|
+
/* @__PURE__ */ jsxs64("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
|
|
7648
|
+
/* @__PURE__ */ jsxs64(
|
|
7407
7649
|
"button",
|
|
7408
7650
|
{
|
|
7409
7651
|
type: "button",
|
|
@@ -7413,14 +7655,14 @@ function AccountMenu({
|
|
|
7413
7655
|
disabled: signingOut,
|
|
7414
7656
|
onClick: signOut,
|
|
7415
7657
|
children: [
|
|
7416
|
-
signingOut ? /* @__PURE__ */
|
|
7417
|
-
/* @__PURE__ */
|
|
7658
|
+
signingOut ? /* @__PURE__ */ jsx73(Spinner, { size: "sm" }) : /* @__PURE__ */ jsx73("i", { className: "ph ph-sign-out", "aria-hidden": "true" }),
|
|
7659
|
+
/* @__PURE__ */ jsx73("span", { style: { flex: 1 }, children: signingOut ? "Signing out\u2026" : "Sign out" })
|
|
7418
7660
|
]
|
|
7419
7661
|
}
|
|
7420
7662
|
),
|
|
7421
|
-
signOutError ? /* @__PURE__ */
|
|
7422
|
-
/* @__PURE__ */
|
|
7423
|
-
/* @__PURE__ */
|
|
7663
|
+
signOutError ? /* @__PURE__ */ jsxs64("div", { role: "alert", className: "fd-body-sm", style: { padding: "0 14px 12px" }, children: [
|
|
7664
|
+
/* @__PURE__ */ jsx73("span", { style: { display: "block", color: "var(--danger-text)", marginBottom: 6 }, children: signOutError }),
|
|
7665
|
+
/* @__PURE__ */ jsx73("button", { type: "button", className: "fd-soon-link", disabled: signingOut, onClick: signOut, children: "Retry" })
|
|
7424
7666
|
] }) : null
|
|
7425
7667
|
] })
|
|
7426
7668
|
] })
|
|
@@ -7430,13 +7672,13 @@ function AccountMenu({
|
|
|
7430
7672
|
}
|
|
7431
7673
|
|
|
7432
7674
|
// src/components/platform/AppSwitcher.tsx
|
|
7433
|
-
import * as
|
|
7434
|
-
import { jsx as
|
|
7675
|
+
import * as React46 from "react";
|
|
7676
|
+
import { jsx as jsx74, jsxs as jsxs65 } from "react/jsx-runtime";
|
|
7435
7677
|
function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
7436
7678
|
const { apps: contextApps } = useSessionContext();
|
|
7437
7679
|
const apps = appsProp ?? contextApps ?? [];
|
|
7438
|
-
const [open2, setOpen] =
|
|
7439
|
-
const anchorRef =
|
|
7680
|
+
const [open2, setOpen] = React46.useState(false);
|
|
7681
|
+
const anchorRef = React46.useRef(null);
|
|
7440
7682
|
if (!apps.length) return null;
|
|
7441
7683
|
const items = apps.map((app) => ({
|
|
7442
7684
|
id: app.key,
|
|
@@ -7450,8 +7692,8 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
7450
7692
|
window.location.href = app.url;
|
|
7451
7693
|
}
|
|
7452
7694
|
}));
|
|
7453
|
-
return /* @__PURE__ */
|
|
7454
|
-
/* @__PURE__ */
|
|
7695
|
+
return /* @__PURE__ */ jsxs65(React46.Fragment, { children: [
|
|
7696
|
+
/* @__PURE__ */ jsx74("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx74(
|
|
7455
7697
|
IconButton,
|
|
7456
7698
|
{
|
|
7457
7699
|
icon: "squares-four",
|
|
@@ -7461,7 +7703,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
7461
7703
|
onClick: () => setOpen((v) => !v)
|
|
7462
7704
|
}
|
|
7463
7705
|
) }),
|
|
7464
|
-
/* @__PURE__ */
|
|
7706
|
+
/* @__PURE__ */ jsx74(
|
|
7465
7707
|
Popover,
|
|
7466
7708
|
{
|
|
7467
7709
|
open: open2,
|
|
@@ -7472,17 +7714,17 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
7472
7714
|
label: "All flytedesk apps",
|
|
7473
7715
|
width: 240,
|
|
7474
7716
|
maxHeight: 360,
|
|
7475
|
-
children: /* @__PURE__ */
|
|
7717
|
+
children: /* @__PURE__ */ jsx74(Menu, { items, onClose: () => setOpen(false) })
|
|
7476
7718
|
}
|
|
7477
7719
|
)
|
|
7478
7720
|
] });
|
|
7479
7721
|
}
|
|
7480
7722
|
|
|
7481
7723
|
// src/components/platform/AppearanceMenu.tsx
|
|
7482
|
-
import * as
|
|
7724
|
+
import * as React48 from "react";
|
|
7483
7725
|
|
|
7484
7726
|
// src/kits/appearance.ts
|
|
7485
|
-
import * as
|
|
7727
|
+
import * as React47 from "react";
|
|
7486
7728
|
var DEFAULT_STORAGE_KEY = "fd-appearance";
|
|
7487
7729
|
var DEFAULT_PREFS = {
|
|
7488
7730
|
theme: "system",
|
|
@@ -7577,11 +7819,11 @@ function applyPrefs(prefs, root = document.documentElement) {
|
|
|
7577
7819
|
else root.removeAttribute("data-motion");
|
|
7578
7820
|
}
|
|
7579
7821
|
function useAppearancePrefs(store) {
|
|
7580
|
-
const prefs =
|
|
7581
|
-
|
|
7822
|
+
const prefs = React47.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
7823
|
+
React47.useEffect(() => {
|
|
7582
7824
|
applyPrefs(prefs);
|
|
7583
7825
|
}, [prefs]);
|
|
7584
|
-
|
|
7826
|
+
React47.useEffect(() => {
|
|
7585
7827
|
if (prefs.theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
7586
7828
|
return;
|
|
7587
7829
|
}
|
|
@@ -7590,7 +7832,7 @@ function useAppearancePrefs(store) {
|
|
|
7590
7832
|
mq.addEventListener("change", onChange);
|
|
7591
7833
|
return () => mq.removeEventListener("change", onChange);
|
|
7592
7834
|
}, [prefs]);
|
|
7593
|
-
const update =
|
|
7835
|
+
const update = React47.useCallback(
|
|
7594
7836
|
(patch) => {
|
|
7595
7837
|
store.write({ ...store.getSnapshot(), ...patch });
|
|
7596
7838
|
},
|
|
@@ -7600,7 +7842,7 @@ function useAppearancePrefs(store) {
|
|
|
7600
7842
|
}
|
|
7601
7843
|
|
|
7602
7844
|
// src/components/platform/AppearanceMenu.tsx
|
|
7603
|
-
import { jsx as
|
|
7845
|
+
import { jsx as jsx75, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
7604
7846
|
var THEME_OPTIONS = [
|
|
7605
7847
|
{ value: "light", label: "Light" },
|
|
7606
7848
|
{ value: "dark", label: "Dark" },
|
|
@@ -7613,16 +7855,16 @@ var TEXT_SCALE_OPTIONS = [
|
|
|
7613
7855
|
{ value: "xl", label: "XL" }
|
|
7614
7856
|
];
|
|
7615
7857
|
function AppearanceMenu({ className = "", store: storeProp, storageKey, storage, defaults }) {
|
|
7616
|
-
const store =
|
|
7858
|
+
const store = React48.useMemo(
|
|
7617
7859
|
() => storeProp ?? createLocalStorageAppearanceStore({ storageKey, storage, defaults }),
|
|
7618
7860
|
[storeProp, storageKey, storage, defaults]
|
|
7619
7861
|
);
|
|
7620
7862
|
const [prefs, update] = useAppearancePrefs(store);
|
|
7621
|
-
const [open2, setOpen] =
|
|
7622
|
-
const anchorRef =
|
|
7863
|
+
const [open2, setOpen] = React48.useState(false);
|
|
7864
|
+
const anchorRef = React48.useRef(null);
|
|
7623
7865
|
const patch = (p) => update(p);
|
|
7624
|
-
return /* @__PURE__ */
|
|
7625
|
-
/* @__PURE__ */
|
|
7866
|
+
return /* @__PURE__ */ jsxs66(React48.Fragment, { children: [
|
|
7867
|
+
/* @__PURE__ */ jsx75("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx75(
|
|
7626
7868
|
IconButton,
|
|
7627
7869
|
{
|
|
7628
7870
|
icon: "circle-half",
|
|
@@ -7630,7 +7872,7 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
|
|
|
7630
7872
|
onClick: () => setOpen((v) => !v)
|
|
7631
7873
|
}
|
|
7632
7874
|
) }),
|
|
7633
|
-
/* @__PURE__ */
|
|
7875
|
+
/* @__PURE__ */ jsx75(
|
|
7634
7876
|
Popover,
|
|
7635
7877
|
{
|
|
7636
7878
|
open: open2,
|
|
@@ -7640,10 +7882,10 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
|
|
|
7640
7882
|
padded: true,
|
|
7641
7883
|
width: 260,
|
|
7642
7884
|
label: "Appearance settings",
|
|
7643
|
-
children: /* @__PURE__ */
|
|
7644
|
-
/* @__PURE__ */
|
|
7645
|
-
/* @__PURE__ */
|
|
7646
|
-
/* @__PURE__ */
|
|
7885
|
+
children: /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
|
|
7886
|
+
/* @__PURE__ */ jsxs66("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
7887
|
+
/* @__PURE__ */ jsx75("span", { className: "fd-field-label", children: "Theme" }),
|
|
7888
|
+
/* @__PURE__ */ jsx75(
|
|
7647
7889
|
SegmentedControl,
|
|
7648
7890
|
{
|
|
7649
7891
|
options: THEME_OPTIONS,
|
|
@@ -7653,9 +7895,9 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
|
|
|
7653
7895
|
}
|
|
7654
7896
|
)
|
|
7655
7897
|
] }),
|
|
7656
|
-
/* @__PURE__ */
|
|
7657
|
-
/* @__PURE__ */
|
|
7658
|
-
/* @__PURE__ */
|
|
7898
|
+
/* @__PURE__ */ jsxs66("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
7899
|
+
/* @__PURE__ */ jsx75("span", { className: "fd-field-label", children: "Text size" }),
|
|
7900
|
+
/* @__PURE__ */ jsx75(
|
|
7659
7901
|
SegmentedControl,
|
|
7660
7902
|
{
|
|
7661
7903
|
options: TEXT_SCALE_OPTIONS,
|
|
@@ -7665,7 +7907,7 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
|
|
|
7665
7907
|
}
|
|
7666
7908
|
)
|
|
7667
7909
|
] }),
|
|
7668
|
-
/* @__PURE__ */
|
|
7910
|
+
/* @__PURE__ */ jsx75(
|
|
7669
7911
|
Switch,
|
|
7670
7912
|
{
|
|
7671
7913
|
label: "High contrast",
|
|
@@ -7674,7 +7916,7 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
|
|
|
7674
7916
|
onChange: (e) => patch({ highContrast: e.target.checked })
|
|
7675
7917
|
}
|
|
7676
7918
|
),
|
|
7677
|
-
/* @__PURE__ */
|
|
7919
|
+
/* @__PURE__ */ jsx75(
|
|
7678
7920
|
Switch,
|
|
7679
7921
|
{
|
|
7680
7922
|
label: "Reduce motion",
|
|
@@ -7690,14 +7932,14 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
|
|
|
7690
7932
|
}
|
|
7691
7933
|
|
|
7692
7934
|
// src/components/platform/ApiSpecBrowser.tsx
|
|
7693
|
-
import * as
|
|
7694
|
-
import { jsx as
|
|
7935
|
+
import * as React49 from "react";
|
|
7936
|
+
import { jsx as jsx76, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
7695
7937
|
var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
|
|
7696
7938
|
function Json({ obj }) {
|
|
7697
|
-
return /* @__PURE__ */
|
|
7939
|
+
return /* @__PURE__ */ jsx76("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
|
|
7698
7940
|
}
|
|
7699
7941
|
function Endpoint({ s, onRequest }) {
|
|
7700
|
-
const [tried, setTried] =
|
|
7942
|
+
const [tried, setTried] = React49.useState(null);
|
|
7701
7943
|
const run = async () => {
|
|
7702
7944
|
setTried("busy");
|
|
7703
7945
|
const t0 = (window.performance || Date).now();
|
|
@@ -7708,50 +7950,50 @@ function Endpoint({ s, onRequest }) {
|
|
|
7708
7950
|
setTried({ ms: Math.round((window.performance || Date).now() - t0), error: String(e && e.message || e) });
|
|
7709
7951
|
}
|
|
7710
7952
|
};
|
|
7711
|
-
return /* @__PURE__ */
|
|
7712
|
-
/* @__PURE__ */
|
|
7713
|
-
/* @__PURE__ */
|
|
7714
|
-
/* @__PURE__ */
|
|
7715
|
-
s.isList ? /* @__PURE__ */
|
|
7716
|
-
/* @__PURE__ */
|
|
7717
|
-
/* @__PURE__ */
|
|
7953
|
+
return /* @__PURE__ */ jsx76(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 0 }, children: [
|
|
7954
|
+
/* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 10, padding: "14px 18px", flexWrap: "wrap" }, children: [
|
|
7955
|
+
/* @__PURE__ */ jsx76(Badge, { tone: METHOD_TONE[s.method] || "neutral", children: s.method }),
|
|
7956
|
+
/* @__PURE__ */ jsx76("code", { className: "fd-mono", style: { fontSize: 12.5, fontWeight: 600, color: "var(--text)", wordBreak: "break-all" }, children: s.path }),
|
|
7957
|
+
s.isList ? /* @__PURE__ */ jsx76(Badge, { tone: "neutral", icon: "rows", children: "Paged list" }) : null,
|
|
7958
|
+
/* @__PURE__ */ jsx76("span", { style: { flex: 1 } }),
|
|
7959
|
+
/* @__PURE__ */ jsxs67("span", { className: "fd-body-sm fd-muted fd-mono", children: [
|
|
7718
7960
|
s.latency[0],
|
|
7719
7961
|
"\u2013",
|
|
7720
7962
|
s.latency[1],
|
|
7721
7963
|
"ms"
|
|
7722
7964
|
] }),
|
|
7723
|
-
/* @__PURE__ */
|
|
7965
|
+
/* @__PURE__ */ jsx76(Button, { size: "sm", variant: "secondary", icon: "play", loading: tried === "busy", onClick: run, children: "Try it" })
|
|
7724
7966
|
] }),
|
|
7725
|
-
/* @__PURE__ */
|
|
7726
|
-
/* @__PURE__ */
|
|
7727
|
-
/* @__PURE__ */
|
|
7728
|
-
/* @__PURE__ */
|
|
7729
|
-
s.usedBy && s.usedBy.length ? /* @__PURE__ */
|
|
7967
|
+
/* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 14, padding: "0 18px 16px" }, children: [
|
|
7968
|
+
/* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
7969
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: s.title }),
|
|
7970
|
+
/* @__PURE__ */ jsx76("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: s.purpose }),
|
|
7971
|
+
s.usedBy && s.usedBy.length ? /* @__PURE__ */ jsx76("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: s.usedBy.map((u) => /* @__PURE__ */ jsx76(Tag, { children: u }, u)) }) : null
|
|
7730
7972
|
] }),
|
|
7731
|
-
/* @__PURE__ */
|
|
7732
|
-
s.request ? /* @__PURE__ */
|
|
7733
|
-
/* @__PURE__ */
|
|
7734
|
-
/* @__PURE__ */
|
|
7973
|
+
/* @__PURE__ */ jsxs67("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 12, alignItems: "start" }, children: [
|
|
7974
|
+
s.request ? /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
7975
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Request body" }),
|
|
7976
|
+
/* @__PURE__ */ jsx76(Json, { obj: s.request })
|
|
7735
7977
|
] }) : null,
|
|
7736
|
-
s.query ? /* @__PURE__ */
|
|
7737
|
-
/* @__PURE__ */
|
|
7738
|
-
/* @__PURE__ */
|
|
7978
|
+
s.query ? /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
7979
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Query" }),
|
|
7980
|
+
/* @__PURE__ */ jsx76(Json, { obj: s.query })
|
|
7739
7981
|
] }) : null,
|
|
7740
|
-
/* @__PURE__ */
|
|
7741
|
-
/* @__PURE__ */
|
|
7742
|
-
/* @__PURE__ */
|
|
7982
|
+
/* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
7983
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Response 200" }),
|
|
7984
|
+
/* @__PURE__ */ jsx76(Json, { obj: s.response })
|
|
7743
7985
|
] })
|
|
7744
7986
|
] }),
|
|
7745
|
-
s.notes ? /* @__PURE__ */
|
|
7746
|
-
tried && tried !== "busy" ? /* @__PURE__ */
|
|
7747
|
-
/* @__PURE__ */
|
|
7748
|
-
/* @__PURE__ */
|
|
7749
|
-
/* @__PURE__ */
|
|
7987
|
+
s.notes ? /* @__PURE__ */ jsx76(Flag, { tone: "info", statement: "Implementation note", cost: s.notes, actions: null }) : null,
|
|
7988
|
+
tried && tried !== "busy" ? /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
|
|
7989
|
+
/* @__PURE__ */ jsxs67("span", { className: "fd-row", style: { gap: 8 }, children: [
|
|
7990
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Simulated response" }),
|
|
7991
|
+
/* @__PURE__ */ jsxs67(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
|
|
7750
7992
|
tried.ms,
|
|
7751
7993
|
"ms"
|
|
7752
7994
|
] })
|
|
7753
7995
|
] }),
|
|
7754
|
-
/* @__PURE__ */
|
|
7996
|
+
/* @__PURE__ */ jsx76(Json, { obj: tried.error ? { error: tried.error } : tried.data })
|
|
7755
7997
|
] }) : null
|
|
7756
7998
|
] })
|
|
7757
7999
|
] }) });
|
|
@@ -7770,58 +8012,58 @@ function ApiSpecBrowser({
|
|
|
7770
8012
|
className = "",
|
|
7771
8013
|
...rest
|
|
7772
8014
|
}) {
|
|
7773
|
-
const [q, setQ] =
|
|
7774
|
-
const [method, setMethod] =
|
|
7775
|
-
const [mod, setMod] =
|
|
7776
|
-
const [listOnly, setListOnly] =
|
|
8015
|
+
const [q, setQ] = React49.useState("");
|
|
8016
|
+
const [method, setMethod] = React49.useState(null);
|
|
8017
|
+
const [mod, setMod] = React49.useState(null);
|
|
8018
|
+
const [listOnly, setListOnly] = React49.useState(false);
|
|
7777
8019
|
const activeModule = modules && modules.find((m) => m.id === mod);
|
|
7778
8020
|
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())));
|
|
7779
8021
|
const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
|
|
7780
8022
|
const methods = [...new Set(spec.map((s) => s.method))];
|
|
7781
8023
|
const listCount = spec.filter((s) => s.isList).length;
|
|
7782
|
-
return /* @__PURE__ */
|
|
7783
|
-
/* @__PURE__ */
|
|
7784
|
-
kicker ? /* @__PURE__ */
|
|
7785
|
-
/* @__PURE__ */
|
|
7786
|
-
lede ? /* @__PURE__ */
|
|
8024
|
+
return /* @__PURE__ */ jsxs67("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 1100 }, ...rest, children: [
|
|
8025
|
+
/* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 10 }, children: [
|
|
8026
|
+
kicker ? /* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: kicker }) : null,
|
|
8027
|
+
/* @__PURE__ */ jsx76("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
|
|
8028
|
+
lede ? /* @__PURE__ */ jsx76("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: lede }) : null
|
|
7787
8029
|
] }),
|
|
7788
|
-
modules && modules.length ? /* @__PURE__ */
|
|
7789
|
-
/* @__PURE__ */
|
|
7790
|
-
/* @__PURE__ */
|
|
7791
|
-
/* @__PURE__ */
|
|
8030
|
+
modules && modules.length ? /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 8 }, children: [
|
|
8031
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Filter by screen \u2014 every endpoint that screen depends on" }),
|
|
8032
|
+
/* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
|
|
8033
|
+
/* @__PURE__ */ jsxs67(Tag, { icon: "stack", selected: !mod, onClick: () => setMod(null), children: [
|
|
7792
8034
|
"All screens ",
|
|
7793
|
-
/* @__PURE__ */
|
|
8035
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-mono", children: spec.length })
|
|
7794
8036
|
] }),
|
|
7795
|
-
modules.map((m) => /* @__PURE__ */
|
|
8037
|
+
modules.map((m) => /* @__PURE__ */ jsxs67(Tag, { icon: m.icon, selected: mod === m.id, onClick: () => setMod(mod === m.id ? null : m.id), children: [
|
|
7796
8038
|
m.label,
|
|
7797
8039
|
" ",
|
|
7798
|
-
/* @__PURE__ */
|
|
8040
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-mono", children: m.endpoints.length })
|
|
7799
8041
|
] }, m.id))
|
|
7800
8042
|
] }),
|
|
7801
|
-
activeModule ? /* @__PURE__ */
|
|
8043
|
+
activeModule ? /* @__PURE__ */ jsx76(
|
|
7802
8044
|
Flag,
|
|
7803
8045
|
{
|
|
7804
8046
|
tone: "info",
|
|
7805
8047
|
statement: activeModule.label + " calls " + activeModule.endpoints.length + " endpoints.",
|
|
7806
8048
|
cost: "Integration checklist for this screen: " + activeModule.endpoints.join(", ") + ". Wire these and the screen is done.",
|
|
7807
|
-
actions: /* @__PURE__ */
|
|
8049
|
+
actions: /* @__PURE__ */ jsx76(Button, { size: "sm", variant: "ghost", icon: "x", onClick: () => setMod(null), children: "Show all screens" })
|
|
7808
8050
|
}
|
|
7809
8051
|
) : null
|
|
7810
8052
|
] }) : null,
|
|
7811
|
-
sourceNote ? /* @__PURE__ */
|
|
7812
|
-
/* @__PURE__ */
|
|
7813
|
-
/* @__PURE__ */
|
|
7814
|
-
methods.map((m) => /* @__PURE__ */
|
|
8053
|
+
sourceNote ? /* @__PURE__ */ jsx76(Flag, { tone: "info", statement: "Design-first: this page is the spec.", cost: sourceNote, actions: null }) : null,
|
|
8054
|
+
/* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
|
|
8055
|
+
/* @__PURE__ */ jsx76(Input, { icon: "magnifying-glass", placeholder: "Find an endpoint, screen, or behavior", value: q, onChange: (e) => setQ(e.target.value), style: { width: 300 } }),
|
|
8056
|
+
methods.map((m) => /* @__PURE__ */ jsxs67(Tag, { selected: method === m, onClick: () => setMethod(method === m ? null : m), children: [
|
|
7815
8057
|
m,
|
|
7816
8058
|
" ",
|
|
7817
|
-
/* @__PURE__ */
|
|
8059
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-mono", children: spec.filter((s) => s.method === m).length })
|
|
7818
8060
|
] }, m)),
|
|
7819
|
-
listCount ? /* @__PURE__ */
|
|
8061
|
+
listCount ? /* @__PURE__ */ jsxs67(Tag, { icon: "rows", selected: listOnly, onClick: () => setListOnly(!listOnly), children: [
|
|
7820
8062
|
"Paged lists ",
|
|
7821
|
-
/* @__PURE__ */
|
|
8063
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-mono", children: listCount })
|
|
7822
8064
|
] }) : null,
|
|
7823
|
-
/* @__PURE__ */
|
|
7824
|
-
/* @__PURE__ */
|
|
8065
|
+
/* @__PURE__ */ jsx76("span", { style: { flex: 1 } }),
|
|
8066
|
+
/* @__PURE__ */ jsxs67("span", { className: "fd-body-sm fd-muted", children: [
|
|
7825
8067
|
hits.length,
|
|
7826
8068
|
" of ",
|
|
7827
8069
|
spec.length,
|
|
@@ -7829,31 +8071,31 @@ function ApiSpecBrowser({
|
|
|
7829
8071
|
listCount ? " \xB7 " + listCount + " paged" : ""
|
|
7830
8072
|
] })
|
|
7831
8073
|
] }),
|
|
7832
|
-
hits.length === 0 ? /* @__PURE__ */
|
|
8074
|
+
hits.length === 0 ? /* @__PURE__ */ jsx76(Card, { elevation: "flat", children: /* @__PURE__ */ jsx76("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: "No endpoint matches those filters." }) }) : effGroups.map(([g, ids]) => {
|
|
7833
8075
|
const items = hits.filter((s) => ids.indexOf(s.id) >= 0);
|
|
7834
8076
|
if (!items.length) return null;
|
|
7835
|
-
return /* @__PURE__ */
|
|
7836
|
-
/* @__PURE__ */
|
|
7837
|
-
items.map((s) => /* @__PURE__ */
|
|
8077
|
+
return /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 12 }, children: [
|
|
8078
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-label-lg", children: g }),
|
|
8079
|
+
items.map((s) => /* @__PURE__ */ jsx76(Endpoint, { s, onRequest }, s.id))
|
|
7838
8080
|
] }, g);
|
|
7839
8081
|
}),
|
|
7840
|
-
conventions && conventions.length ? /* @__PURE__ */
|
|
7841
|
-
/* @__PURE__ */
|
|
7842
|
-
/* @__PURE__ */
|
|
8082
|
+
conventions && conventions.length ? /* @__PURE__ */ jsx76(Card, { title: "Cross-cutting conventions", elevation: "flat", children: /* @__PURE__ */ jsx76("div", { className: "fd-stack", style: { gap: 10 }, children: conventions.map(([k, v]) => /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 12, alignItems: "flex-start" }, children: [
|
|
8083
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", style: { width: 110, flex: "none", paddingTop: 2 }, children: k }),
|
|
8084
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: v })
|
|
7843
8085
|
] }, k)) }) }) : null,
|
|
7844
|
-
openQuestions && openQuestions.length ? /* @__PURE__ */
|
|
7845
|
-
/* @__PURE__ */
|
|
7846
|
-
/* @__PURE__ */
|
|
7847
|
-
/* @__PURE__ */
|
|
7848
|
-
/* @__PURE__ */
|
|
8086
|
+
openQuestions && openQuestions.length ? /* @__PURE__ */ jsx76(Collapsible, { icon: "list-checks", title: "Open questions before implementation", subtitle: openQuestions.length + " unresolved", children: /* @__PURE__ */ jsx76("div", { className: "fd-stack", style: { gap: 8 }, children: openQuestions.map(([id, question, why]) => /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start", padding: "8px 0", borderTop: "1px solid var(--border)" }, children: [
|
|
8087
|
+
/* @__PURE__ */ jsx76(Badge, { tone: "danger", children: id }),
|
|
8088
|
+
/* @__PURE__ */ jsxs67("span", { className: "fd-stack", style: { gap: 2, flex: 1 }, children: [
|
|
8089
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: question }),
|
|
8090
|
+
/* @__PURE__ */ jsx76("span", { className: "fd-body-sm fd-muted", children: why })
|
|
7849
8091
|
] })
|
|
7850
8092
|
] }, id)) }) }) : null
|
|
7851
8093
|
] });
|
|
7852
8094
|
}
|
|
7853
8095
|
|
|
7854
8096
|
// src/components/platform/ProfilePage.tsx
|
|
7855
|
-
import * as
|
|
7856
|
-
import { jsx as
|
|
8097
|
+
import * as React50 from "react";
|
|
8098
|
+
import { jsx as jsx77, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
7857
8099
|
function fieldInitialValue(field, user) {
|
|
7858
8100
|
if (field.value) return field.value(user);
|
|
7859
8101
|
const raw = user[field.key];
|
|
@@ -7888,21 +8130,21 @@ function ProfilePage({
|
|
|
7888
8130
|
}) {
|
|
7889
8131
|
const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
|
|
7890
8132
|
const user = userProp || sessionUser;
|
|
7891
|
-
const initialFieldValues =
|
|
8133
|
+
const initialFieldValues = React50.useMemo(() => {
|
|
7892
8134
|
const values2 = {};
|
|
7893
8135
|
for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
|
|
7894
8136
|
return values2;
|
|
7895
8137
|
}, [user.id, fields]);
|
|
7896
|
-
const initialNotify =
|
|
8138
|
+
const initialNotify = React50.useMemo(() => {
|
|
7897
8139
|
const values2 = {};
|
|
7898
8140
|
for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
|
|
7899
8141
|
return values2;
|
|
7900
8142
|
}, [user.id, notifications]);
|
|
7901
|
-
const [values, setValues] =
|
|
7902
|
-
const [notify, setNotify] =
|
|
7903
|
-
const [saving, setSaving] =
|
|
7904
|
-
const [saved, setSaved] =
|
|
7905
|
-
const [prevUserId, setPrevUserId] =
|
|
8143
|
+
const [values, setValues] = React50.useState(initialFieldValues);
|
|
8144
|
+
const [notify, setNotify] = React50.useState(initialNotify);
|
|
8145
|
+
const [saving, setSaving] = React50.useState(false);
|
|
8146
|
+
const [saved, setSaved] = React50.useState(false);
|
|
8147
|
+
const [prevUserId, setPrevUserId] = React50.useState(user.id);
|
|
7906
8148
|
if (user.id !== prevUserId) {
|
|
7907
8149
|
setPrevUserId(user.id);
|
|
7908
8150
|
setValues(initialFieldValues);
|
|
@@ -7939,37 +8181,37 @@ function ProfilePage({
|
|
|
7939
8181
|
};
|
|
7940
8182
|
const displayName = fields.some((f) => f.key === "name") ? values.name || user.name : user.name;
|
|
7941
8183
|
const fieldGroups = groupFields(fields);
|
|
7942
|
-
return /* @__PURE__ */
|
|
7943
|
-
/* @__PURE__ */
|
|
7944
|
-
/* @__PURE__ */
|
|
7945
|
-
/* @__PURE__ */
|
|
7946
|
-
/* @__PURE__ */
|
|
8184
|
+
return /* @__PURE__ */ jsxs68("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, children: [
|
|
8185
|
+
/* @__PURE__ */ jsxs68("div", { className: "fd-stack", style: { gap: 10 }, children: [
|
|
8186
|
+
/* @__PURE__ */ jsx77("span", { className: "fd-overline fd-muted", children: "Account" }),
|
|
8187
|
+
/* @__PURE__ */ jsx77("h1", { className: "fd-h1", style: { margin: 0 }, children: "Your profile" }),
|
|
8188
|
+
/* @__PURE__ */ jsx77("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." })
|
|
7947
8189
|
] }),
|
|
7948
|
-
/* @__PURE__ */
|
|
7949
|
-
/* @__PURE__ */
|
|
7950
|
-
/* @__PURE__ */
|
|
7951
|
-
/* @__PURE__ */
|
|
7952
|
-
/* @__PURE__ */
|
|
7953
|
-
roles.map((r) => /* @__PURE__ */
|
|
7954
|
-
user.sso ? /* @__PURE__ */
|
|
8190
|
+
/* @__PURE__ */ jsx77(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs68("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap", alignItems: "flex-start" }, children: [
|
|
8191
|
+
/* @__PURE__ */ jsx77(Avatar, { name: displayName, size: "lg" }),
|
|
8192
|
+
/* @__PURE__ */ jsxs68("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
|
|
8193
|
+
/* @__PURE__ */ jsx77("span", { className: "fd-h3", style: { margin: 0 }, children: displayName }),
|
|
8194
|
+
/* @__PURE__ */ jsxs68("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 4 }, children: [
|
|
8195
|
+
roles.map((r) => /* @__PURE__ */ jsx77(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)),
|
|
8196
|
+
user.sso ? /* @__PURE__ */ jsx77(Badge, { tone: "info", icon: "shield-check", children: "SSO" }) : null
|
|
7955
8197
|
] })
|
|
7956
8198
|
] }),
|
|
7957
|
-
onChangePhoto ? /* @__PURE__ */
|
|
8199
|
+
onChangePhoto ? /* @__PURE__ */ jsx77(Button, { variant: "secondary", size: "sm", icon: "image", onClick: onChangePhoto, children: "Change photo" }) : null
|
|
7958
8200
|
] }) }),
|
|
7959
|
-
fieldGroups.map(({ group, description, fields: groupFieldDefs }) => /* @__PURE__ */
|
|
8201
|
+
fieldGroups.map(({ group, description, fields: groupFieldDefs }) => /* @__PURE__ */ jsx77(
|
|
7960
8202
|
Card,
|
|
7961
8203
|
{
|
|
7962
|
-
title: description ? /* @__PURE__ */
|
|
7963
|
-
/* @__PURE__ */
|
|
7964
|
-
/* @__PURE__ */
|
|
8204
|
+
title: description ? /* @__PURE__ */ jsxs68("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
8205
|
+
/* @__PURE__ */ jsx77("span", { children: group }),
|
|
8206
|
+
/* @__PURE__ */ jsx77("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: description })
|
|
7965
8207
|
] }) : group,
|
|
7966
8208
|
elevation: "flat",
|
|
7967
|
-
children: /* @__PURE__ */
|
|
7968
|
-
/* @__PURE__ */
|
|
8209
|
+
children: /* @__PURE__ */ jsxs68("div", { className: "fd-stack", style: { gap: 14 }, children: [
|
|
8210
|
+
/* @__PURE__ */ jsx77("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: groupFieldDefs.filter((f) => f.type !== "textarea").map((field) => {
|
|
7969
8211
|
const help = typeof field.help === "function" ? field.help(user) : field.help;
|
|
7970
8212
|
const readOnly = field.readOnly || field.type === "readonly";
|
|
7971
8213
|
if (field.type === "select") {
|
|
7972
|
-
return /* @__PURE__ */
|
|
8214
|
+
return /* @__PURE__ */ jsx77(
|
|
7973
8215
|
Select,
|
|
7974
8216
|
{
|
|
7975
8217
|
label: field.label,
|
|
@@ -7983,7 +8225,7 @@ function ProfilePage({
|
|
|
7983
8225
|
field.key
|
|
7984
8226
|
);
|
|
7985
8227
|
}
|
|
7986
|
-
return /* @__PURE__ */
|
|
8228
|
+
return /* @__PURE__ */ jsx77(
|
|
7987
8229
|
Input,
|
|
7988
8230
|
{
|
|
7989
8231
|
label: field.label,
|
|
@@ -7999,7 +8241,7 @@ function ProfilePage({
|
|
|
7999
8241
|
}) }),
|
|
8000
8242
|
groupFieldDefs.filter((f) => f.type === "textarea").map((field) => {
|
|
8001
8243
|
const help = typeof field.help === "function" ? field.help(user) : field.help;
|
|
8002
|
-
return /* @__PURE__ */
|
|
8244
|
+
return /* @__PURE__ */ jsx77(
|
|
8003
8245
|
Textarea,
|
|
8004
8246
|
{
|
|
8005
8247
|
label: field.label,
|
|
@@ -8019,16 +8261,16 @@ function ProfilePage({
|
|
|
8019
8261
|
group
|
|
8020
8262
|
)),
|
|
8021
8263
|
extra,
|
|
8022
|
-
notifications.length > 0 ? /* @__PURE__ */
|
|
8023
|
-
/* @__PURE__ */
|
|
8264
|
+
notifications.length > 0 ? /* @__PURE__ */ jsx77(Card, { title: "Notifications", elevation: "flat", children: /* @__PURE__ */ jsx77("div", { className: "fd-stack", style: { gap: 14 }, children: notifications.map((n) => /* @__PURE__ */ jsx77(Switch, { checked: !!notify[n.key], onChange: () => toggleNotify(n.key), label: n.label, description: n.description }, n.key)) }) }) : null,
|
|
8265
|
+
/* @__PURE__ */ jsxs68(
|
|
8024
8266
|
Card,
|
|
8025
8267
|
{
|
|
8026
|
-
title: /* @__PURE__ */
|
|
8027
|
-
/* @__PURE__ */
|
|
8028
|
-
/* @__PURE__ */
|
|
8268
|
+
title: /* @__PURE__ */ jsxs68("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
8269
|
+
/* @__PURE__ */ jsx77("span", { children: "Access" }),
|
|
8270
|
+
/* @__PURE__ */ jsx77("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "What your roles grant you" })
|
|
8029
8271
|
] }),
|
|
8030
8272
|
elevation: "flat",
|
|
8031
|
-
action: /* @__PURE__ */
|
|
8273
|
+
action: /* @__PURE__ */ jsx77(
|
|
8032
8274
|
Button,
|
|
8033
8275
|
{
|
|
8034
8276
|
size: "sm",
|
|
@@ -8039,39 +8281,39 @@ function ProfilePage({
|
|
|
8039
8281
|
}
|
|
8040
8282
|
),
|
|
8041
8283
|
children: [
|
|
8042
|
-
/* @__PURE__ */
|
|
8043
|
-
/* @__PURE__ */
|
|
8044
|
-
/* @__PURE__ */
|
|
8284
|
+
/* @__PURE__ */ jsxs68("div", { className: "fd-stack", style: { gap: 0 }, children: [
|
|
8285
|
+
/* @__PURE__ */ jsx77(CardRow, { label: "Roles", children: roles.map((r) => r.name).join(", ") || "None" }),
|
|
8286
|
+
/* @__PURE__ */ jsxs68(CardRow, { label: "Permissions", children: [
|
|
8045
8287
|
permissions.length,
|
|
8046
8288
|
" granted"
|
|
8047
8289
|
] }),
|
|
8048
|
-
/* @__PURE__ */
|
|
8290
|
+
/* @__PURE__ */ jsx77(CardRow, { label: "Member since", children: user.joined || "\u2014" })
|
|
8049
8291
|
] }),
|
|
8050
|
-
/* @__PURE__ */
|
|
8292
|
+
/* @__PURE__ */ jsx77("p", { className: "fd-body-sm fd-muted", style: { margin: "12px 0 0" }, children: "You cannot change your own roles \u2014 that is the point of them. An administrator manages roles from Admin \u2192 Users." })
|
|
8051
8293
|
]
|
|
8052
8294
|
}
|
|
8053
8295
|
),
|
|
8054
|
-
sessions ? /* @__PURE__ */
|
|
8296
|
+
sessions ? /* @__PURE__ */ jsx77(
|
|
8055
8297
|
Card,
|
|
8056
8298
|
{
|
|
8057
8299
|
title: "Signed-in devices",
|
|
8058
8300
|
elevation: "flat",
|
|
8059
|
-
action: /* @__PURE__ */
|
|
8060
|
-
children: /* @__PURE__ */
|
|
8061
|
-
/* @__PURE__ */
|
|
8062
|
-
/* @__PURE__ */
|
|
8063
|
-
/* @__PURE__ */
|
|
8064
|
-
/* @__PURE__ */
|
|
8301
|
+
action: /* @__PURE__ */ jsx77(Button, { size: "sm", variant: "ghost", icon: "sign-out", onClick: onSignOutEverywhere, children: "Sign out everywhere" }),
|
|
8302
|
+
children: /* @__PURE__ */ jsx77("div", { className: "fd-stack", style: { gap: 0 }, children: sessions.length === 0 ? /* @__PURE__ */ jsx77("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: "No other signed-in devices." }) : sessions.map((s) => /* @__PURE__ */ jsxs68("div", { className: "fd-row", style: { gap: 12, padding: "10px 0", borderTop: "1px solid var(--border)", flexWrap: "wrap" }, children: [
|
|
8303
|
+
/* @__PURE__ */ jsx77("i", { className: "ph ph-device-mobile", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
|
|
8304
|
+
/* @__PURE__ */ jsxs68("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
|
|
8305
|
+
/* @__PURE__ */ jsx77("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: s.device }),
|
|
8306
|
+
/* @__PURE__ */ jsxs68("span", { className: "fd-body-sm fd-muted", children: [
|
|
8065
8307
|
s.where,
|
|
8066
8308
|
" \xB7 ",
|
|
8067
8309
|
s.when
|
|
8068
8310
|
] })
|
|
8069
8311
|
] }),
|
|
8070
|
-
s.current ? /* @__PURE__ */
|
|
8312
|
+
s.current ? /* @__PURE__ */ jsx77(Badge, { tone: "success", dot: true, children: "This device" }) : /* @__PURE__ */ jsx77(Button, { size: "sm", variant: "ghost", children: "Revoke" })
|
|
8071
8313
|
] }, s.id)) })
|
|
8072
8314
|
}
|
|
8073
8315
|
) : null,
|
|
8074
|
-
/* @__PURE__ */
|
|
8316
|
+
/* @__PURE__ */ jsxs68("div", { className: "fd-row", style: {
|
|
8075
8317
|
gap: 10,
|
|
8076
8318
|
flexWrap: "wrap",
|
|
8077
8319
|
position: "sticky",
|
|
@@ -8082,19 +8324,19 @@ function ProfilePage({
|
|
|
8082
8324
|
border: "1px solid var(--border)",
|
|
8083
8325
|
boxShadow: "0 -4px 16px rgba(11,13,17,.06)"
|
|
8084
8326
|
}, children: [
|
|
8085
|
-
/* @__PURE__ */
|
|
8086
|
-
/* @__PURE__ */
|
|
8087
|
-
/* @__PURE__ */
|
|
8327
|
+
/* @__PURE__ */ jsx77("span", { className: "fd-body-sm", style: { fontWeight: 600, flex: 1 }, children: saved ? "Saved." : dirty ? "Unsaved changes" : "No pending changes" }),
|
|
8328
|
+
/* @__PURE__ */ jsx77(Button, { size: "sm", variant: "ghost", disabled: !dirty || saving, onClick: discard, children: "Discard" }),
|
|
8329
|
+
/* @__PURE__ */ jsx77(Button, { size: "sm", icon: "check", disabled: !dirty || !canSave, loading: saving, onClick: save, children: "Save changes" })
|
|
8088
8330
|
] })
|
|
8089
8331
|
] });
|
|
8090
8332
|
}
|
|
8091
8333
|
|
|
8092
8334
|
// src/components/platform/SignInPage.tsx
|
|
8093
|
-
import * as
|
|
8094
|
-
import { Fragment as Fragment19, jsx as
|
|
8335
|
+
import * as React51 from "react";
|
|
8336
|
+
import { Fragment as Fragment19, jsx as jsx78, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
8095
8337
|
function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
8096
|
-
const [signingIn, setSigningIn] =
|
|
8097
|
-
const [resuming, setResuming] =
|
|
8338
|
+
const [signingIn, setSigningIn] = React51.useState(false);
|
|
8339
|
+
const [resuming, setResuming] = React51.useState(false);
|
|
8098
8340
|
function handleSignIn() {
|
|
8099
8341
|
setSigningIn(true);
|
|
8100
8342
|
onSignIn();
|
|
@@ -8103,7 +8345,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8103
8345
|
setResuming(true);
|
|
8104
8346
|
continueAs.onContinue().finally(() => setResuming(false));
|
|
8105
8347
|
}
|
|
8106
|
-
return /* @__PURE__ */
|
|
8348
|
+
return /* @__PURE__ */ jsxs69(
|
|
8107
8349
|
"div",
|
|
8108
8350
|
{
|
|
8109
8351
|
style: {
|
|
@@ -8117,7 +8359,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8117
8359
|
background: "radial-gradient(circle at 15% 15%, var(--blue-700) 0%, transparent 45%), radial-gradient(circle at 85% 85%, var(--blue-600) 0%, transparent 40%), linear-gradient(160deg, var(--navy) 0%, var(--blue-950) 55%, var(--blue-900) 100%)"
|
|
8118
8360
|
},
|
|
8119
8361
|
children: [
|
|
8120
|
-
/* @__PURE__ */
|
|
8362
|
+
/* @__PURE__ */ jsx78(
|
|
8121
8363
|
"div",
|
|
8122
8364
|
{
|
|
8123
8365
|
"aria-hidden": true,
|
|
@@ -8130,7 +8372,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8130
8372
|
}
|
|
8131
8373
|
}
|
|
8132
8374
|
),
|
|
8133
|
-
/* @__PURE__ */
|
|
8375
|
+
/* @__PURE__ */ jsxs69(
|
|
8134
8376
|
"div",
|
|
8135
8377
|
{
|
|
8136
8378
|
style: {
|
|
@@ -8142,8 +8384,8 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8142
8384
|
alignItems: "center"
|
|
8143
8385
|
},
|
|
8144
8386
|
children: [
|
|
8145
|
-
/* @__PURE__ */
|
|
8146
|
-
/* @__PURE__ */
|
|
8387
|
+
/* @__PURE__ */ jsx78("div", { style: { marginBottom: "var(--s-32)" }, "data-theme": "dark", children: /* @__PURE__ */ jsx78(FlytedeskMark, { size: "lg" }) }),
|
|
8388
|
+
/* @__PURE__ */ jsxs69(
|
|
8147
8389
|
"div",
|
|
8148
8390
|
{
|
|
8149
8391
|
style: {
|
|
@@ -8153,7 +8395,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8153
8395
|
boxShadow: "0 24px 64px -12px rgba(2, 8, 20, 0.55), 0 2px 8px rgba(2, 8, 20, 0.3)"
|
|
8154
8396
|
},
|
|
8155
8397
|
children: [
|
|
8156
|
-
/* @__PURE__ */
|
|
8398
|
+
/* @__PURE__ */ jsx78(
|
|
8157
8399
|
"div",
|
|
8158
8400
|
{
|
|
8159
8401
|
style: {
|
|
@@ -8162,7 +8404,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8162
8404
|
}
|
|
8163
8405
|
}
|
|
8164
8406
|
),
|
|
8165
|
-
/* @__PURE__ */
|
|
8407
|
+
/* @__PURE__ */ jsx78(Card, { children: /* @__PURE__ */ jsxs69(
|
|
8166
8408
|
"div",
|
|
8167
8409
|
{
|
|
8168
8410
|
style: {
|
|
@@ -8174,13 +8416,13 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8174
8416
|
padding: "var(--s-8) 0"
|
|
8175
8417
|
},
|
|
8176
8418
|
children: [
|
|
8177
|
-
/* @__PURE__ */
|
|
8178
|
-
/* @__PURE__ */
|
|
8179
|
-
/* @__PURE__ */
|
|
8419
|
+
/* @__PURE__ */ jsxs69("div", { children: [
|
|
8420
|
+
/* @__PURE__ */ jsx78("h1", { className: "fd-h3", style: { color: "var(--navy)" }, children: productName }),
|
|
8421
|
+
/* @__PURE__ */ jsx78("p", { className: "fd-body-sm fd-muted", style: { marginTop: "var(--s-4)" }, children: continueAs ? "Your session timed out, but you're likely still signed in" : "Sign in with your flytedesk workspace account" })
|
|
8180
8422
|
] }),
|
|
8181
|
-
error ? /* @__PURE__ */
|
|
8182
|
-
continueAs ? /* @__PURE__ */
|
|
8183
|
-
/* @__PURE__ */
|
|
8423
|
+
error ? /* @__PURE__ */ jsx78("div", { role: "alert", style: { width: "100%" }, children: /* @__PURE__ */ jsx78(Banner, { tone: "danger", title: error }) }) : null,
|
|
8424
|
+
continueAs ? /* @__PURE__ */ jsxs69(Fragment19, { children: [
|
|
8425
|
+
/* @__PURE__ */ jsx78(
|
|
8184
8426
|
Button,
|
|
8185
8427
|
{
|
|
8186
8428
|
variant: "primary",
|
|
@@ -8191,7 +8433,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8191
8433
|
children: resuming ? "Resuming\u2026" : `Continue as ${continueAs.name}`
|
|
8192
8434
|
}
|
|
8193
8435
|
),
|
|
8194
|
-
/* @__PURE__ */
|
|
8436
|
+
/* @__PURE__ */ jsx78(
|
|
8195
8437
|
"button",
|
|
8196
8438
|
{
|
|
8197
8439
|
type: "button",
|
|
@@ -8208,7 +8450,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8208
8450
|
children: "Not you? Sign in with flytedesk ID"
|
|
8209
8451
|
}
|
|
8210
8452
|
)
|
|
8211
|
-
] }) : /* @__PURE__ */
|
|
8453
|
+
] }) : /* @__PURE__ */ jsx78(
|
|
8212
8454
|
Button,
|
|
8213
8455
|
{
|
|
8214
8456
|
variant: "primary",
|
|
@@ -8216,7 +8458,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8216
8458
|
loading: signingIn,
|
|
8217
8459
|
disabled: signingIn,
|
|
8218
8460
|
onClick: handleSignIn,
|
|
8219
|
-
children: /* @__PURE__ */
|
|
8461
|
+
children: /* @__PURE__ */ jsxs69(
|
|
8220
8462
|
"span",
|
|
8221
8463
|
{
|
|
8222
8464
|
style: {
|
|
@@ -8228,14 +8470,14 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8228
8470
|
flexWrap: "nowrap"
|
|
8229
8471
|
},
|
|
8230
8472
|
children: [
|
|
8231
|
-
/* @__PURE__ */
|
|
8232
|
-
/* @__PURE__ */
|
|
8473
|
+
/* @__PURE__ */ jsx78(GoogleGlyph, {}),
|
|
8474
|
+
/* @__PURE__ */ jsx78("span", { children: signingIn ? "Signing in\u2026" : "Sign in with flytedesk ID" })
|
|
8233
8475
|
]
|
|
8234
8476
|
}
|
|
8235
8477
|
)
|
|
8236
8478
|
}
|
|
8237
8479
|
),
|
|
8238
|
-
/* @__PURE__ */
|
|
8480
|
+
/* @__PURE__ */ jsx78("p", { className: "fd-body-sm fd-muted", style: { fontSize: "12px" }, children: "One account, every flytedesk app." })
|
|
8239
8481
|
]
|
|
8240
8482
|
}
|
|
8241
8483
|
) })
|
|
@@ -8250,29 +8492,29 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8250
8492
|
);
|
|
8251
8493
|
}
|
|
8252
8494
|
function GoogleGlyph() {
|
|
8253
|
-
return /* @__PURE__ */
|
|
8254
|
-
/* @__PURE__ */
|
|
8495
|
+
return /* @__PURE__ */ jsxs69("svg", { width: "18", height: "18", viewBox: "0 0 18 18", "aria-hidden": true, children: [
|
|
8496
|
+
/* @__PURE__ */ jsx78(
|
|
8255
8497
|
"path",
|
|
8256
8498
|
{
|
|
8257
8499
|
fill: "#4285F4",
|
|
8258
8500
|
d: "M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.87 2.68-6.62Z"
|
|
8259
8501
|
}
|
|
8260
8502
|
),
|
|
8261
|
-
/* @__PURE__ */
|
|
8503
|
+
/* @__PURE__ */ jsx78(
|
|
8262
8504
|
"path",
|
|
8263
8505
|
{
|
|
8264
8506
|
fill: "#34A853",
|
|
8265
8507
|
d: "M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.81.54-1.84.87-3.04.87-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18Z"
|
|
8266
8508
|
}
|
|
8267
8509
|
),
|
|
8268
|
-
/* @__PURE__ */
|
|
8510
|
+
/* @__PURE__ */ jsx78(
|
|
8269
8511
|
"path",
|
|
8270
8512
|
{
|
|
8271
8513
|
fill: "#FBBC05",
|
|
8272
8514
|
d: "M3.97 10.73A5.4 5.4 0 0 1 3.68 9c0-.6.1-1.19.29-1.73V4.94H.96A9 9 0 0 0 0 9c0 1.45.35 2.83.96 4.06l3.01-2.33Z"
|
|
8273
8515
|
}
|
|
8274
8516
|
),
|
|
8275
|
-
/* @__PURE__ */
|
|
8517
|
+
/* @__PURE__ */ jsx78(
|
|
8276
8518
|
"path",
|
|
8277
8519
|
{
|
|
8278
8520
|
fill: "#EA4335",
|
|
@@ -8283,10 +8525,10 @@ function GoogleGlyph() {
|
|
|
8283
8525
|
}
|
|
8284
8526
|
|
|
8285
8527
|
// src/components/platform/RoadmapTimeline.tsx
|
|
8286
|
-
import * as
|
|
8528
|
+
import * as React54 from "react";
|
|
8287
8529
|
|
|
8288
8530
|
// src/kits/session.ts
|
|
8289
|
-
import * as
|
|
8531
|
+
import * as React52 from "react";
|
|
8290
8532
|
var PERMISSION_CATALOG = [
|
|
8291
8533
|
{ group: "Plans", items: [
|
|
8292
8534
|
{ key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
|
|
@@ -9853,8 +10095,8 @@ function roadmap(overrides) {
|
|
|
9853
10095
|
};
|
|
9854
10096
|
}
|
|
9855
10097
|
function useSession() {
|
|
9856
|
-
const [s, setS] =
|
|
9857
|
-
|
|
10098
|
+
const [s, setS] = React52.useState(getSession);
|
|
10099
|
+
React52.useEffect(() => subscribe(setS), []);
|
|
9858
10100
|
return s;
|
|
9859
10101
|
}
|
|
9860
10102
|
var SessionKit = {
|
|
@@ -9887,7 +10129,7 @@ var SessionKit = {
|
|
|
9887
10129
|
};
|
|
9888
10130
|
function DemoSessionProvider({ children }) {
|
|
9889
10131
|
const session = useSession();
|
|
9890
|
-
const value =
|
|
10132
|
+
const value = React52.useMemo(
|
|
9891
10133
|
() => ({
|
|
9892
10134
|
user: session.user,
|
|
9893
10135
|
roles: session.roles,
|
|
@@ -9903,11 +10145,11 @@ function DemoSessionProvider({ children }) {
|
|
|
9903
10145
|
}),
|
|
9904
10146
|
[session]
|
|
9905
10147
|
);
|
|
9906
|
-
return
|
|
10148
|
+
return React52.createElement(SessionProvider, { value }, children);
|
|
9907
10149
|
}
|
|
9908
10150
|
|
|
9909
10151
|
// src/kits/runtime.ts
|
|
9910
|
-
import * as
|
|
10152
|
+
import * as React53 from "react";
|
|
9911
10153
|
var WIRED_ENDPOINTS = [
|
|
9912
10154
|
// Nothing yet. Every id below would come from a real service:
|
|
9913
10155
|
// "plan.get", "placements.list", …
|
|
@@ -10078,8 +10320,8 @@ var RuntimeKit = {
|
|
|
10078
10320
|
};
|
|
10079
10321
|
RuntimeKit.declare(FEATURE_NEEDS);
|
|
10080
10322
|
function useRuntimeMode() {
|
|
10081
|
-
const [m, setM] =
|
|
10082
|
-
|
|
10323
|
+
const [m, setM] = React53.useState(RuntimeKit.getMode());
|
|
10324
|
+
React53.useEffect(() => RuntimeKit.subscribe(setM), []);
|
|
10083
10325
|
return m;
|
|
10084
10326
|
}
|
|
10085
10327
|
function useFeatureStatus(key) {
|
|
@@ -10098,7 +10340,7 @@ var UseRuntimeMode = useRuntimeMode;
|
|
|
10098
10340
|
var UseFeatureStatus = useFeatureStatus;
|
|
10099
10341
|
|
|
10100
10342
|
// src/components/platform/RoadmapTimeline.tsx
|
|
10101
|
-
import { jsx as
|
|
10343
|
+
import { jsx as jsx79, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
10102
10344
|
var STATUS = {
|
|
10103
10345
|
shipped: { tone: "success", icon: "check-circle", label: "Wired" },
|
|
10104
10346
|
next: { tone: "warning", icon: "traffic-cone", label: "Not wired" },
|
|
@@ -10113,45 +10355,45 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
10113
10355
|
const s = STATUS[item.status] || STATUS.planned;
|
|
10114
10356
|
const deps = (item.dependsOn || []).map((k) => byKey[k]).filter(Boolean);
|
|
10115
10357
|
const blocking = deps.filter((d) => !d.implemented);
|
|
10116
|
-
return /* @__PURE__ */
|
|
10117
|
-
/* @__PURE__ */
|
|
10118
|
-
/* @__PURE__ */
|
|
10119
|
-
/* @__PURE__ */
|
|
10120
|
-
/* @__PURE__ */
|
|
10358
|
+
return /* @__PURE__ */ jsx79(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs70("div", { className: "fd-stack", style: { gap: 10 }, children: [
|
|
10359
|
+
/* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
|
|
10360
|
+
/* @__PURE__ */ jsx79("span", { className: "fd-body", style: { fontWeight: 700, flex: 1, minWidth: 140 }, children: item.label }),
|
|
10361
|
+
/* @__PURE__ */ jsx79(Badge, { tone: "neutral", icon: PROJECT_ICON[item.project] || "squares-four", children: item.project }),
|
|
10362
|
+
/* @__PURE__ */ jsx79(Badge, { tone: s.tone, icon: s.icon, children: s.label })
|
|
10121
10363
|
] }),
|
|
10122
|
-
/* @__PURE__ */
|
|
10123
|
-
item.backend ? /* @__PURE__ */
|
|
10124
|
-
/* @__PURE__ */
|
|
10125
|
-
/* @__PURE__ */
|
|
10364
|
+
/* @__PURE__ */ jsx79("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: item.description }),
|
|
10365
|
+
item.backend ? /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
|
|
10366
|
+
/* @__PURE__ */ jsx79("span", { className: "fd-overline fd-muted", style: { width: 62, flex: "none", paddingTop: 2 }, children: "Backend" }),
|
|
10367
|
+
/* @__PURE__ */ jsx79("span", { className: "fd-body-sm", style: { flex: 1, textWrap: "pretty" }, children: item.backend })
|
|
10126
10368
|
] }) : null,
|
|
10127
|
-
/* @__PURE__ */
|
|
10128
|
-
item.effort ? /* @__PURE__ */
|
|
10129
|
-
/* @__PURE__ */
|
|
10369
|
+
/* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
|
|
10370
|
+
item.effort ? /* @__PURE__ */ jsxs70("span", { className: "fd-body-sm fd-muted", children: [
|
|
10371
|
+
/* @__PURE__ */ jsx79("i", { className: "ph ph-hourglass-medium" }),
|
|
10130
10372
|
" ",
|
|
10131
10373
|
item.effort
|
|
10132
10374
|
] }) : null,
|
|
10133
|
-
/* @__PURE__ */
|
|
10134
|
-
/* @__PURE__ */
|
|
10375
|
+
/* @__PURE__ */ jsxs70("span", { className: "fd-body-sm fd-muted", children: [
|
|
10376
|
+
/* @__PURE__ */ jsx79("i", { className: "ph ph-user" }),
|
|
10135
10377
|
" ",
|
|
10136
10378
|
item.owner
|
|
10137
10379
|
] }),
|
|
10138
|
-
item.screen ? /* @__PURE__ */
|
|
10139
|
-
/* @__PURE__ */
|
|
10140
|
-
/* @__PURE__ */
|
|
10380
|
+
item.screen ? /* @__PURE__ */ jsx79(Badge, { tone: "neutral", icon: "browser", children: "screen" }) : null,
|
|
10381
|
+
/* @__PURE__ */ jsx79("span", { style: { flex: 1 } }),
|
|
10382
|
+
/* @__PURE__ */ jsx79(
|
|
10141
10383
|
"button",
|
|
10142
10384
|
{
|
|
10143
10385
|
type: "button",
|
|
10144
10386
|
onClick: () => onOpenFlag && onOpenFlag(item.key),
|
|
10145
10387
|
style: { all: "unset", cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 5 },
|
|
10146
|
-
children: /* @__PURE__ */
|
|
10388
|
+
children: /* @__PURE__ */ jsx79("code", { className: "fd-mono", style: { fontSize: 11, color: "var(--brand)" }, children: item.key })
|
|
10147
10389
|
}
|
|
10148
10390
|
)
|
|
10149
10391
|
] }),
|
|
10150
|
-
deps.length ? /* @__PURE__ */
|
|
10151
|
-
/* @__PURE__ */
|
|
10152
|
-
deps.map((d) => /* @__PURE__ */
|
|
10392
|
+
deps.length ? /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
|
|
10393
|
+
/* @__PURE__ */ jsx79("span", { className: "fd-overline fd-muted", style: { paddingTop: 3 }, children: "After" }),
|
|
10394
|
+
deps.map((d) => /* @__PURE__ */ jsx79(Tag, { icon: d.implemented ? "check" : "clock", children: d.label }, d.key))
|
|
10153
10395
|
] }) : null,
|
|
10154
|
-
blocking.length && !item.implemented ? /* @__PURE__ */
|
|
10396
|
+
blocking.length && !item.implemented ? /* @__PURE__ */ jsxs70("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
|
|
10155
10397
|
"Blocked until ",
|
|
10156
10398
|
blocking.map((d) => d.label).join(" and "),
|
|
10157
10399
|
" ",
|
|
@@ -10162,12 +10404,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
10162
10404
|
}
|
|
10163
10405
|
function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
10164
10406
|
const session = SessionKit.useSession();
|
|
10165
|
-
const [project, setProject] =
|
|
10166
|
-
const [q, setQ] =
|
|
10167
|
-
const scrollRef =
|
|
10168
|
-
const nowRef =
|
|
10169
|
-
const rm =
|
|
10170
|
-
const byKey =
|
|
10407
|
+
const [project, setProject] = React54.useState("");
|
|
10408
|
+
const [q, setQ] = React54.useState("");
|
|
10409
|
+
const scrollRef = React54.useRef(null);
|
|
10410
|
+
const nowRef = React54.useRef(null);
|
|
10411
|
+
const rm = React54.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
|
|
10412
|
+
const byKey = React54.useMemo(() => {
|
|
10171
10413
|
const m = {};
|
|
10172
10414
|
rm.items.forEach((i) => {
|
|
10173
10415
|
m[i.key] = i;
|
|
@@ -10176,7 +10418,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10176
10418
|
}, [rm]);
|
|
10177
10419
|
const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
|
|
10178
10420
|
const projects = [...new Set(rm.items.map((i) => i.project))];
|
|
10179
|
-
|
|
10421
|
+
React54.useEffect(() => {
|
|
10180
10422
|
let raf1 = 0, raf2 = 0;
|
|
10181
10423
|
const place = () => {
|
|
10182
10424
|
const box = scrollRef.current, mark = nowRef.current;
|
|
@@ -10204,23 +10446,23 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10204
10446
|
}, 0);
|
|
10205
10447
|
const nextPhase = items.find((i) => !i.implemented);
|
|
10206
10448
|
let lastPhase = null;
|
|
10207
|
-
return /* @__PURE__ */
|
|
10208
|
-
/* @__PURE__ */
|
|
10209
|
-
/* @__PURE__ */
|
|
10210
|
-
/* @__PURE__ */
|
|
10211
|
-
/* @__PURE__ */
|
|
10449
|
+
return /* @__PURE__ */ jsxs70("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
|
|
10450
|
+
/* @__PURE__ */ jsxs70("div", { className: "fd-stack", style: { gap: 10 }, children: [
|
|
10451
|
+
/* @__PURE__ */ jsx79("span", { className: "fd-overline fd-muted", children: "Architecture" }),
|
|
10452
|
+
/* @__PURE__ */ jsx79("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
|
|
10453
|
+
/* @__PURE__ */ jsx79("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." })
|
|
10212
10454
|
] }),
|
|
10213
|
-
/* @__PURE__ */
|
|
10214
|
-
/* @__PURE__ */
|
|
10215
|
-
/* @__PURE__ */
|
|
10216
|
-
/* @__PURE__ */
|
|
10217
|
-
/* @__PURE__ */
|
|
10455
|
+
/* @__PURE__ */ jsxs70("div", { className: "fd-grid-stats is-thin", children: [
|
|
10456
|
+
/* @__PURE__ */ jsx79(StatTile, { compact: true, label: "Wired", value: String(rm.shipped), sub: "of " + rm.items.length + " features" }),
|
|
10457
|
+
/* @__PURE__ */ jsx79(StatTile, { compact: true, label: "Remaining", value: String(rm.remaining), sub: "backend work" }),
|
|
10458
|
+
/* @__PURE__ */ jsx79(StatTile, { compact: true, label: "Est. effort", value: days ? days + " days" : "\u2014", sub: "sum of estimates, not calendar" }),
|
|
10459
|
+
/* @__PURE__ */ jsx79(StatTile, { compact: true, label: "Up next", value: nextPhase ? "Phase " + nextPhase.phase : "\u2014", sub: nextPhase ? nextPhase.phaseName : "all wired" })
|
|
10218
10460
|
] }),
|
|
10219
|
-
/* @__PURE__ */
|
|
10220
|
-
/* @__PURE__ */
|
|
10221
|
-
/* @__PURE__ */
|
|
10222
|
-
/* @__PURE__ */
|
|
10223
|
-
/* @__PURE__ */
|
|
10461
|
+
/* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
|
|
10462
|
+
/* @__PURE__ */ jsx79(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 } }),
|
|
10463
|
+
/* @__PURE__ */ jsx79(Select, { placeholder: "All projects", value: project, onChange: (e) => setProject(e.target.value), options: projects, style: { width: 190 } }),
|
|
10464
|
+
/* @__PURE__ */ jsx79("span", { style: { flex: 1 } }),
|
|
10465
|
+
/* @__PURE__ */ jsx79(
|
|
10224
10466
|
Button,
|
|
10225
10467
|
{
|
|
10226
10468
|
size: "sm",
|
|
@@ -10234,7 +10476,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10234
10476
|
}
|
|
10235
10477
|
)
|
|
10236
10478
|
] }),
|
|
10237
|
-
/* @__PURE__ */
|
|
10479
|
+
/* @__PURE__ */ jsx79(
|
|
10238
10480
|
Flag,
|
|
10239
10481
|
{
|
|
10240
10482
|
tone: "info",
|
|
@@ -10243,60 +10485,60 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10243
10485
|
actions: null
|
|
10244
10486
|
}
|
|
10245
10487
|
),
|
|
10246
|
-
/* @__PURE__ */
|
|
10247
|
-
/* @__PURE__ */
|
|
10488
|
+
/* @__PURE__ */ jsx79("div", { className: "fd-rm", children: /* @__PURE__ */ jsx79("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs70("div", { className: "fd-rm-track", children: [
|
|
10489
|
+
/* @__PURE__ */ jsx79("span", { className: "fd-rm-spine", children: /* @__PURE__ */ jsx79("span", { className: "fd-rm-spine-done", style: { height: items.length ? 100 * shippedShown / items.length + "%" : "0%" } }) }),
|
|
10248
10490
|
items.map((item, n) => {
|
|
10249
10491
|
const showPhase = item.phase !== lastPhase;
|
|
10250
10492
|
lastPhase = item.phase;
|
|
10251
10493
|
const inPhase = items.filter((i) => i.phase === item.phase).length;
|
|
10252
10494
|
const isBoundary = n === firstPending;
|
|
10253
|
-
return /* @__PURE__ */
|
|
10254
|
-
showPhase ? /* @__PURE__ */
|
|
10255
|
-
/* @__PURE__ */
|
|
10256
|
-
/* @__PURE__ */
|
|
10257
|
-
item.phase === 0 ? null : /* @__PURE__ */
|
|
10495
|
+
return /* @__PURE__ */ jsxs70(React54.Fragment, { children: [
|
|
10496
|
+
showPhase ? /* @__PURE__ */ jsxs70("div", { className: "fd-rm-era", children: [
|
|
10497
|
+
/* @__PURE__ */ jsxs70("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
|
|
10498
|
+
/* @__PURE__ */ jsx79("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
|
|
10499
|
+
item.phase === 0 ? null : /* @__PURE__ */ jsxs70("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
|
|
10258
10500
|
fmtDate(item.phaseStart),
|
|
10259
10501
|
" \u2013 ",
|
|
10260
10502
|
fmtDate(item.date)
|
|
10261
10503
|
] }),
|
|
10262
|
-
/* @__PURE__ */
|
|
10504
|
+
/* @__PURE__ */ jsxs70("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
|
|
10263
10505
|
"\xB7 ",
|
|
10264
10506
|
inPhase,
|
|
10265
10507
|
" feature",
|
|
10266
10508
|
inPhase === 1 ? "" : "s"
|
|
10267
10509
|
] })
|
|
10268
10510
|
] }),
|
|
10269
|
-
item.phaseWhy ? /* @__PURE__ */
|
|
10511
|
+
item.phaseWhy ? /* @__PURE__ */ jsx79("p", { className: "fd-rm-era-why", children: item.phaseWhy }) : null
|
|
10270
10512
|
] }) : null,
|
|
10271
|
-
isBoundary ? /* @__PURE__ */
|
|
10272
|
-
/* @__PURE__ */
|
|
10513
|
+
isBoundary ? /* @__PURE__ */ jsx79("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs70("span", { className: "fd-rm-now-pill", children: [
|
|
10514
|
+
/* @__PURE__ */ jsx79("i", { className: "ph ph-map-pin" }),
|
|
10273
10515
|
" You are here \u2014 everything above is wired"
|
|
10274
10516
|
] }) }) : null,
|
|
10275
|
-
/* @__PURE__ */
|
|
10276
|
-
/* @__PURE__ */
|
|
10277
|
-
/* @__PURE__ */
|
|
10517
|
+
/* @__PURE__ */ jsxs70("div", { className: "fd-rm-row", children: [
|
|
10518
|
+
/* @__PURE__ */ jsx79("span", { className: "fd-rm-dot " + (item.implemented ? "is-shipped" : item.status === "next" ? "is-next" : "") }),
|
|
10519
|
+
/* @__PURE__ */ jsxs70("div", { className: "fd-rm-date", children: [
|
|
10278
10520
|
fmtDate(item.date),
|
|
10279
|
-
/* @__PURE__ */
|
|
10280
|
-
/* @__PURE__ */
|
|
10521
|
+
/* @__PURE__ */ jsx79("br", {}),
|
|
10522
|
+
/* @__PURE__ */ jsx79("span", { style: { opacity: 0.75 }, children: item.implemented ? "shipped" : "phase " + item.phase })
|
|
10281
10523
|
] }),
|
|
10282
|
-
/* @__PURE__ */
|
|
10524
|
+
/* @__PURE__ */ jsx79(RoadmapCard, { item, byKey, onOpenFlag })
|
|
10283
10525
|
] })
|
|
10284
10526
|
] }, item.key);
|
|
10285
10527
|
}),
|
|
10286
|
-
!items.length ? /* @__PURE__ */
|
|
10528
|
+
!items.length ? /* @__PURE__ */ jsx79("p", { className: "fd-body-sm fd-muted", children: "Nothing matches that filter." }) : null
|
|
10287
10529
|
] }) }) }),
|
|
10288
|
-
/* @__PURE__ */
|
|
10530
|
+
/* @__PURE__ */ jsxs70("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
|
|
10289
10531
|
"Derived from the feature-flag registry \u2014 each entry's status is its flag's ",
|
|
10290
|
-
/* @__PURE__ */
|
|
10532
|
+
/* @__PURE__ */ jsx79("code", { className: "fd-mono", children: "implemented" }),
|
|
10291
10533
|
" field, so this page cannot drift from what the apps actually do."
|
|
10292
10534
|
] })
|
|
10293
10535
|
] });
|
|
10294
10536
|
}
|
|
10295
10537
|
|
|
10296
10538
|
// src/components/platform/ComingSoon.tsx
|
|
10297
|
-
import * as
|
|
10539
|
+
import * as React55 from "react";
|
|
10298
10540
|
import { createPortal as createPortal5 } from "react-dom";
|
|
10299
|
-
import { Fragment as Fragment21, jsx as
|
|
10541
|
+
import { Fragment as Fragment21, jsx as jsx80, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
10300
10542
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
10301
10543
|
function readBypassed() {
|
|
10302
10544
|
try {
|
|
@@ -10312,8 +10554,8 @@ function writeBypassed(list) {
|
|
|
10312
10554
|
}
|
|
10313
10555
|
}
|
|
10314
10556
|
function useBypass(key) {
|
|
10315
|
-
const [on, setOn] =
|
|
10316
|
-
|
|
10557
|
+
const [on, setOn] = React55.useState(() => !!key && readBypassed().indexOf(key) >= 0);
|
|
10558
|
+
React55.useEffect(() => {
|
|
10317
10559
|
setOn(!!key && readBypassed().indexOf(key) >= 0);
|
|
10318
10560
|
}, [key]);
|
|
10319
10561
|
const set = (next) => {
|
|
@@ -10326,43 +10568,43 @@ function useBypass(key) {
|
|
|
10326
10568
|
return [on, set];
|
|
10327
10569
|
}
|
|
10328
10570
|
function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }) {
|
|
10329
|
-
return /* @__PURE__ */
|
|
10330
|
-
/* @__PURE__ */
|
|
10331
|
-
/* @__PURE__ */
|
|
10571
|
+
return /* @__PURE__ */ jsxs71(Fragment21, { children: [
|
|
10572
|
+
/* @__PURE__ */ jsxs71("span", { className: "fd-soon-badge", children: [
|
|
10573
|
+
/* @__PURE__ */ jsx80("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
|
|
10332
10574
|
label
|
|
10333
10575
|
] }),
|
|
10334
|
-
detail ? /* @__PURE__ */
|
|
10335
|
-
backend ? /* @__PURE__ */
|
|
10336
|
-
/* @__PURE__ */
|
|
10576
|
+
detail ? /* @__PURE__ */ jsx80("span", { className: "fd-soon-detail", children: detail }) : null,
|
|
10577
|
+
backend ? /* @__PURE__ */ jsxs71("span", { className: "fd-soon-backend", children: [
|
|
10578
|
+
/* @__PURE__ */ jsx80("span", { className: "fd-overline", children: "Needs" }),
|
|
10337
10579
|
" ",
|
|
10338
10580
|
backend
|
|
10339
10581
|
] }) : null,
|
|
10340
|
-
eta || effort || onRoadmap ? /* @__PURE__ */
|
|
10341
|
-
eta ? /* @__PURE__ */
|
|
10342
|
-
/* @__PURE__ */
|
|
10582
|
+
eta || effort || onRoadmap ? /* @__PURE__ */ jsxs71("span", { className: "fd-soon-meta", children: [
|
|
10583
|
+
eta ? /* @__PURE__ */ jsxs71("span", { children: [
|
|
10584
|
+
/* @__PURE__ */ jsx80("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }),
|
|
10343
10585
|
" ",
|
|
10344
10586
|
eta
|
|
10345
10587
|
] }) : null,
|
|
10346
|
-
effort ? /* @__PURE__ */
|
|
10347
|
-
/* @__PURE__ */
|
|
10588
|
+
effort ? /* @__PURE__ */ jsxs71("span", { children: [
|
|
10589
|
+
/* @__PURE__ */ jsx80("i", { className: "ph ph-hourglass-medium", "aria-hidden": "true" }),
|
|
10348
10590
|
" ",
|
|
10349
10591
|
effort
|
|
10350
10592
|
] }) : null,
|
|
10351
|
-
onRoadmap ? /* @__PURE__ */
|
|
10593
|
+
onRoadmap ? /* @__PURE__ */ jsxs71("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
|
|
10352
10594
|
"See the roadmap ",
|
|
10353
|
-
/* @__PURE__ */
|
|
10595
|
+
/* @__PURE__ */ jsx80("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
|
|
10354
10596
|
] }) : null
|
|
10355
10597
|
] }) : null,
|
|
10356
|
-
allowed ? /* @__PURE__ */
|
|
10357
|
-
/* @__PURE__ */
|
|
10598
|
+
allowed ? /* @__PURE__ */ jsxs71("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
|
|
10599
|
+
/* @__PURE__ */ jsx80("i", { className: "ph ph-eye", "aria-hidden": "true" }),
|
|
10358
10600
|
" View and use it anyway"
|
|
10359
10601
|
] }) : null
|
|
10360
10602
|
] });
|
|
10361
10603
|
}
|
|
10362
10604
|
function useHoverCard(open2) {
|
|
10363
|
-
const anchor =
|
|
10364
|
-
const [pos, setPos] =
|
|
10365
|
-
|
|
10605
|
+
const anchor = React55.useRef(null);
|
|
10606
|
+
const [pos, setPos] = React55.useState(null);
|
|
10607
|
+
React55.useLayoutEffect(() => {
|
|
10366
10608
|
if (!open2 || !anchor.current) {
|
|
10367
10609
|
setPos(null);
|
|
10368
10610
|
return;
|
|
@@ -10414,9 +10656,9 @@ function ComingSoon({
|
|
|
10414
10656
|
const tip = [label, detail, backend ? "Needs " + backend : null, eta ? "ETA " + eta : null, effort].filter(Boolean).join(" \xB7 ");
|
|
10415
10657
|
if (inline) {
|
|
10416
10658
|
if (allowed && bypassed) {
|
|
10417
|
-
return /* @__PURE__ */
|
|
10659
|
+
return /* @__PURE__ */ jsxs71("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
|
|
10418
10660
|
children,
|
|
10419
|
-
/* @__PURE__ */
|
|
10661
|
+
/* @__PURE__ */ jsx80(
|
|
10420
10662
|
"button",
|
|
10421
10663
|
{
|
|
10422
10664
|
type: "button",
|
|
@@ -10424,12 +10666,12 @@ function ComingSoon({
|
|
|
10424
10666
|
title: "Unwired \u2014 writes go to the simulated backend. " + tip + " Click to re-blur.",
|
|
10425
10667
|
onClick: () => setBypassed(false),
|
|
10426
10668
|
"aria-label": "Re-blur this unwired feature",
|
|
10427
|
-
children: /* @__PURE__ */
|
|
10669
|
+
children: /* @__PURE__ */ jsx80("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
|
|
10428
10670
|
}
|
|
10429
10671
|
)
|
|
10430
10672
|
] });
|
|
10431
10673
|
}
|
|
10432
|
-
return /* @__PURE__ */
|
|
10674
|
+
return /* @__PURE__ */ jsx80(
|
|
10433
10675
|
InlineSoon,
|
|
10434
10676
|
{
|
|
10435
10677
|
label,
|
|
@@ -10449,20 +10691,20 @@ function ComingSoon({
|
|
|
10449
10691
|
);
|
|
10450
10692
|
}
|
|
10451
10693
|
if (allowed && bypassed) {
|
|
10452
|
-
return /* @__PURE__ */
|
|
10453
|
-
/* @__PURE__ */
|
|
10454
|
-
/* @__PURE__ */
|
|
10455
|
-
/* @__PURE__ */
|
|
10694
|
+
return /* @__PURE__ */ jsxs71("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
|
|
10695
|
+
/* @__PURE__ */ jsxs71("div", { className: "fd-soon-bar", role: "status", children: [
|
|
10696
|
+
/* @__PURE__ */ jsxs71("span", { className: "fd-soon-badge", children: [
|
|
10697
|
+
/* @__PURE__ */ jsx80("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
|
|
10456
10698
|
"Unwired feature \u2014 you are using it anyway"
|
|
10457
10699
|
] }),
|
|
10458
|
-
/* @__PURE__ */
|
|
10459
|
-
/* @__PURE__ */
|
|
10460
|
-
onRoadmap ? /* @__PURE__ */
|
|
10700
|
+
/* @__PURE__ */ jsx80("span", { className: "fd-soon-bar-detail", children: "Every action here writes to the simulated backend, so nothing you do persists beyond this session." }),
|
|
10701
|
+
/* @__PURE__ */ jsxs71("span", { className: "fd-soon-bar-actions", children: [
|
|
10702
|
+
onRoadmap ? /* @__PURE__ */ jsxs71("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
|
|
10461
10703
|
"Roadmap ",
|
|
10462
|
-
/* @__PURE__ */
|
|
10704
|
+
/* @__PURE__ */ jsx80("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
|
|
10463
10705
|
] }) : null,
|
|
10464
|
-
/* @__PURE__ */
|
|
10465
|
-
/* @__PURE__ */
|
|
10706
|
+
/* @__PURE__ */ jsxs71("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
|
|
10707
|
+
/* @__PURE__ */ jsx80("i", { className: "ph ph-eye-slash", "aria-hidden": "true" }),
|
|
10466
10708
|
" Re-blur"
|
|
10467
10709
|
] })
|
|
10468
10710
|
] })
|
|
@@ -10470,10 +10712,10 @@ function ComingSoon({
|
|
|
10470
10712
|
children
|
|
10471
10713
|
] });
|
|
10472
10714
|
}
|
|
10473
|
-
return /* @__PURE__ */
|
|
10474
|
-
/* @__PURE__ */
|
|
10475
|
-
/* @__PURE__ */
|
|
10476
|
-
/* @__PURE__ */
|
|
10715
|
+
return /* @__PURE__ */ jsxs71("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
|
|
10716
|
+
/* @__PURE__ */ jsx80("div", { className: "fd-soon-under", style: { filter: "blur(" + blur + "px) saturate(.62)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
|
|
10717
|
+
/* @__PURE__ */ jsx80("div", { className: "fd-soon-veil" }),
|
|
10718
|
+
/* @__PURE__ */ jsx80("div", { className: "fd-soon-note", role: "note", children: /* @__PURE__ */ jsx80(
|
|
10477
10719
|
SoonCard,
|
|
10478
10720
|
{
|
|
10479
10721
|
label,
|
|
@@ -10489,10 +10731,12 @@ function ComingSoon({
|
|
|
10489
10731
|
] });
|
|
10490
10732
|
}
|
|
10491
10733
|
function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
|
|
10492
|
-
const [open2, setOpen] =
|
|
10734
|
+
const [open2, setOpen] = React55.useState(false);
|
|
10493
10735
|
const [anchor, pos] = useHoverCard(open2);
|
|
10494
|
-
const
|
|
10495
|
-
const
|
|
10736
|
+
const hoverCardRef = React55.useRef(null);
|
|
10737
|
+
const hoverLayer = useStackedLayer({ active: open2, containerRef: hoverCardRef, returnFocus: false });
|
|
10738
|
+
const zIndex = useLayerZIndex(hoverLayer);
|
|
10739
|
+
const close2 = React55.useRef(null);
|
|
10496
10740
|
const show = () => {
|
|
10497
10741
|
if (close2.current) {
|
|
10498
10742
|
clearTimeout(close2.current);
|
|
@@ -10508,10 +10752,10 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
10508
10752
|
setOpen(false);
|
|
10509
10753
|
}, 140);
|
|
10510
10754
|
};
|
|
10511
|
-
|
|
10755
|
+
React55.useEffect(() => () => {
|
|
10512
10756
|
if (close2.current) clearTimeout(close2.current);
|
|
10513
10757
|
}, []);
|
|
10514
|
-
return /* @__PURE__ */
|
|
10758
|
+
return /* @__PURE__ */ jsxs71(
|
|
10515
10759
|
"span",
|
|
10516
10760
|
{
|
|
10517
10761
|
ref: anchor,
|
|
@@ -10522,8 +10766,8 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
10522
10766
|
onBlur: hide,
|
|
10523
10767
|
...rest,
|
|
10524
10768
|
children: [
|
|
10525
|
-
/* @__PURE__ */
|
|
10526
|
-
/* @__PURE__ */
|
|
10769
|
+
/* @__PURE__ */ jsx80("span", { className: "fd-soon-under", style: { filter: "blur(" + Math.min(blur, 1.1) + "px) saturate(.66)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
|
|
10770
|
+
/* @__PURE__ */ jsx80(
|
|
10527
10771
|
"button",
|
|
10528
10772
|
{
|
|
10529
10773
|
type: "button",
|
|
@@ -10534,19 +10778,20 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
10534
10778
|
onFocus: show,
|
|
10535
10779
|
onBlur: hide,
|
|
10536
10780
|
onClick: () => open2 ? setOpen(false) : show(),
|
|
10537
|
-
children: /* @__PURE__ */
|
|
10781
|
+
children: /* @__PURE__ */ jsx80("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
|
|
10538
10782
|
}
|
|
10539
10783
|
),
|
|
10540
10784
|
open2 && pos ? createPortal5(
|
|
10541
|
-
/* @__PURE__ */
|
|
10785
|
+
/* @__PURE__ */ jsx80(
|
|
10542
10786
|
"div",
|
|
10543
10787
|
{
|
|
10788
|
+
ref: hoverCardRef,
|
|
10544
10789
|
className: "fd-soon-note fd-soon-hovercard",
|
|
10545
10790
|
role: "tooltip",
|
|
10546
10791
|
style: { position: "fixed", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width, zIndex },
|
|
10547
10792
|
onMouseEnter: show,
|
|
10548
10793
|
onMouseLeave: hide,
|
|
10549
|
-
children: /* @__PURE__ */
|
|
10794
|
+
children: /* @__PURE__ */ jsx80(
|
|
10550
10795
|
SoonCard,
|
|
10551
10796
|
{
|
|
10552
10797
|
label,
|
|
@@ -10560,7 +10805,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
10560
10805
|
}
|
|
10561
10806
|
)
|
|
10562
10807
|
}
|
|
10563
|
-
)
|
|
10808
|
+
),
|
|
10564
10809
|
document.body
|
|
10565
10810
|
) : null
|
|
10566
10811
|
]
|
|
@@ -10576,10 +10821,10 @@ function formatEta(iso2) {
|
|
|
10576
10821
|
var FormatEta = formatEta;
|
|
10577
10822
|
|
|
10578
10823
|
// src/components/platform/Gate.tsx
|
|
10579
|
-
import { jsx as
|
|
10824
|
+
import { jsx as jsx81, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
10580
10825
|
function PermissionDenied({ permission, title, detail, compact: compact3 = false, className = "", ...rest }) {
|
|
10581
10826
|
const need = Array.isArray(permission) ? permission : [permission].filter(Boolean);
|
|
10582
|
-
return /* @__PURE__ */
|
|
10827
|
+
return /* @__PURE__ */ jsxs72(
|
|
10583
10828
|
"div",
|
|
10584
10829
|
{
|
|
10585
10830
|
className: ["fd-stack", className].filter(Boolean).join(" "),
|
|
@@ -10595,14 +10840,14 @@ function PermissionDenied({ permission, title, detail, compact: compact3 = false
|
|
|
10595
10840
|
},
|
|
10596
10841
|
...rest,
|
|
10597
10842
|
children: [
|
|
10598
|
-
/* @__PURE__ */
|
|
10599
|
-
/* @__PURE__ */
|
|
10600
|
-
/* @__PURE__ */
|
|
10843
|
+
/* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 8 }, children: [
|
|
10844
|
+
/* @__PURE__ */ jsx81("i", { className: "ph ph-lock-simple", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
|
|
10845
|
+
/* @__PURE__ */ jsx81("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: title || "You do not have access to this" })
|
|
10601
10846
|
] }),
|
|
10602
|
-
/* @__PURE__ */
|
|
10603
|
-
need.length ? /* @__PURE__ */
|
|
10604
|
-
/* @__PURE__ */
|
|
10605
|
-
need.map((p) => /* @__PURE__ */
|
|
10847
|
+
/* @__PURE__ */ jsx81("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." }),
|
|
10848
|
+
need.length ? /* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
|
|
10849
|
+
/* @__PURE__ */ jsx81("span", { className: "fd-overline fd-muted", children: "Requires" }),
|
|
10850
|
+
need.map((p) => /* @__PURE__ */ jsx81("code", { className: "fd-mono", style: {
|
|
10606
10851
|
fontSize: 11.5,
|
|
10607
10852
|
padding: "2px 7px",
|
|
10608
10853
|
borderRadius: 5,
|
|
@@ -10615,7 +10860,7 @@ function PermissionDenied({ permission, title, detail, compact: compact3 = false
|
|
|
10615
10860
|
);
|
|
10616
10861
|
}
|
|
10617
10862
|
function GatePending({ compact: compact3 = false, className = "" }) {
|
|
10618
|
-
return /* @__PURE__ */
|
|
10863
|
+
return /* @__PURE__ */ jsxs72(
|
|
10619
10864
|
"div",
|
|
10620
10865
|
{
|
|
10621
10866
|
className: ["fd-stack", className].filter(Boolean).join(" "),
|
|
@@ -10631,11 +10876,11 @@ function GatePending({ compact: compact3 = false, className = "" }) {
|
|
|
10631
10876
|
textAlign: "left"
|
|
10632
10877
|
},
|
|
10633
10878
|
children: [
|
|
10634
|
-
/* @__PURE__ */
|
|
10635
|
-
/* @__PURE__ */
|
|
10636
|
-
/* @__PURE__ */
|
|
10879
|
+
/* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 8 }, children: [
|
|
10880
|
+
/* @__PURE__ */ jsx81("i", { className: "ph ph-arrows-clockwise", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
|
|
10881
|
+
/* @__PURE__ */ jsx81("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: "Reconnecting\u2026" })
|
|
10637
10882
|
] }),
|
|
10638
|
-
/* @__PURE__ */
|
|
10883
|
+
/* @__PURE__ */ jsx81("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: "Your access can't be verified right now. This will resolve on its own once the connection is back." })
|
|
10639
10884
|
]
|
|
10640
10885
|
}
|
|
10641
10886
|
);
|
|
@@ -10645,7 +10890,7 @@ function Gate({ perm, anyOf, role, silent = false, fallback, pendingFallback, co
|
|
|
10645
10890
|
if (pending) {
|
|
10646
10891
|
if (pendingFallback !== void 0) return pendingFallback;
|
|
10647
10892
|
if (silent) return null;
|
|
10648
|
-
return /* @__PURE__ */
|
|
10893
|
+
return /* @__PURE__ */ jsx81(GatePending, { compact: compact3 });
|
|
10649
10894
|
}
|
|
10650
10895
|
let ok = true;
|
|
10651
10896
|
if (perm) ok = ok && can2(perm);
|
|
@@ -10654,7 +10899,7 @@ function Gate({ perm, anyOf, role, silent = false, fallback, pendingFallback, co
|
|
|
10654
10899
|
if (ok) return children;
|
|
10655
10900
|
if (fallback !== void 0) return fallback;
|
|
10656
10901
|
if (silent) return null;
|
|
10657
|
-
return /* @__PURE__ */
|
|
10902
|
+
return /* @__PURE__ */ jsx81(PermissionDenied, { permission: perm || anyOf, compact: compact3 });
|
|
10658
10903
|
}
|
|
10659
10904
|
function FeatureGate({
|
|
10660
10905
|
flag,
|
|
@@ -10677,7 +10922,7 @@ function FeatureGate({
|
|
|
10677
10922
|
const f = SessionKit.findFlag(flag) || {};
|
|
10678
10923
|
const missing = rt.missing || [];
|
|
10679
10924
|
const canBypass = pending ? false : bypassPerm === null ? false : !bypassPerm || can2(bypassPerm);
|
|
10680
|
-
return /* @__PURE__ */
|
|
10925
|
+
return /* @__PURE__ */ jsx81(
|
|
10681
10926
|
ComingSoon,
|
|
10682
10927
|
{
|
|
10683
10928
|
label: label || (variant === "inline" ? f.label || "Not wired yet" : "Designed \u2014 backend not wired yet"),
|
|
@@ -10698,22 +10943,22 @@ function FeatureGate({
|
|
|
10698
10943
|
function PermissionHint({ perm, children }) {
|
|
10699
10944
|
const { can: can2, pending } = useSessionContext();
|
|
10700
10945
|
if (pending) {
|
|
10701
|
-
return /* @__PURE__ */
|
|
10946
|
+
return /* @__PURE__ */ jsx81("span", { title: "Access can't be verified right now", style: { display: "inline-flex", opacity: 0.45, cursor: "not-allowed" }, "aria-disabled": "true", children: /* @__PURE__ */ jsx81("span", { style: { pointerEvents: "none" }, children }) });
|
|
10702
10947
|
}
|
|
10703
10948
|
if (can2(perm)) return children;
|
|
10704
|
-
return /* @__PURE__ */
|
|
10949
|
+
return /* @__PURE__ */ jsx81(
|
|
10705
10950
|
"span",
|
|
10706
10951
|
{
|
|
10707
10952
|
title: "Requires " + (Array.isArray(perm) ? perm.join(", ") : perm),
|
|
10708
10953
|
style: { display: "inline-flex", opacity: 0.45, cursor: "not-allowed" },
|
|
10709
10954
|
"aria-disabled": "true",
|
|
10710
|
-
children: /* @__PURE__ */
|
|
10955
|
+
children: /* @__PURE__ */ jsx81("span", { style: { pointerEvents: "none" }, children })
|
|
10711
10956
|
}
|
|
10712
10957
|
);
|
|
10713
10958
|
}
|
|
10714
10959
|
|
|
10715
10960
|
// src/components/platform/ModeSwitch.tsx
|
|
10716
|
-
import { Fragment as Fragment22, jsx as
|
|
10961
|
+
import { Fragment as Fragment22, jsx as jsx82, jsxs as jsxs73 } from "react/jsx-runtime";
|
|
10717
10962
|
function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
|
|
10718
10963
|
const mode2 = useRuntimeMode();
|
|
10719
10964
|
const panel = useInlinePanel();
|
|
@@ -10725,8 +10970,8 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
10725
10970
|
RuntimeKit.setMode(next);
|
|
10726
10971
|
setOpen(false);
|
|
10727
10972
|
};
|
|
10728
|
-
return /* @__PURE__ */
|
|
10729
|
-
/* @__PURE__ */
|
|
10973
|
+
return /* @__PURE__ */ jsxs73("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
|
|
10974
|
+
/* @__PURE__ */ jsxs73(
|
|
10730
10975
|
"button",
|
|
10731
10976
|
{
|
|
10732
10977
|
type: "button",
|
|
@@ -10736,29 +10981,29 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
10736
10981
|
title: test ? "Test mode \u2014 every response is simulated. Click to inspect requests or return to live mode." : "Live mode \u2014 incomplete features are shown under construction. Click for test mode.",
|
|
10737
10982
|
className: "fd-mode-btn" + (test ? " is-test" : "") + (open2 ? " is-open" : ""),
|
|
10738
10983
|
children: [
|
|
10739
|
-
/* @__PURE__ */
|
|
10740
|
-
test && requestCount ? /* @__PURE__ */
|
|
10984
|
+
/* @__PURE__ */ jsx82("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), style: { fontSize: 17 } }),
|
|
10985
|
+
test && requestCount ? /* @__PURE__ */ jsx82("span", { className: "fd-mono fd-mode-count", children: requestCount > 99 ? "99+" : requestCount }, requestCount) : null
|
|
10741
10986
|
]
|
|
10742
10987
|
}
|
|
10743
10988
|
),
|
|
10744
|
-
open2 ? /* @__PURE__ */
|
|
10745
|
-
/* @__PURE__ */
|
|
10746
|
-
/* @__PURE__ */
|
|
10747
|
-
/* @__PURE__ */
|
|
10989
|
+
open2 ? /* @__PURE__ */ jsx82(InlinePanelLayers, { panel, children: /* @__PURE__ */ jsxs73("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
|
|
10990
|
+
/* @__PURE__ */ jsxs73("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
|
|
10991
|
+
/* @__PURE__ */ jsxs73("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
|
|
10992
|
+
/* @__PURE__ */ jsx82("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
|
|
10748
10993
|
test ? "Test mode" : "Live mode"
|
|
10749
10994
|
] }),
|
|
10750
|
-
test ? /* @__PURE__ */
|
|
10995
|
+
test ? /* @__PURE__ */ jsxs73("span", { className: "fd-body-sm fd-muted fd-mono", children: [
|
|
10751
10996
|
requestCount,
|
|
10752
10997
|
" simulated request",
|
|
10753
10998
|
requestCount === 1 ? "" : "s"
|
|
10754
10999
|
] }) : null,
|
|
10755
|
-
/* @__PURE__ */
|
|
10756
|
-
test && onClearLog ? /* @__PURE__ */
|
|
11000
|
+
/* @__PURE__ */ jsx82("span", { style: { flex: 1 } }),
|
|
11001
|
+
test && onClearLog ? /* @__PURE__ */ jsx82("button", { type: "button", className: "fd-soon-link", onClick: onClearLog, children: "Clear" }) : null
|
|
10757
11002
|
] }),
|
|
10758
|
-
/* @__PURE__ */
|
|
10759
|
-
/* @__PURE__ */
|
|
10760
|
-
/* @__PURE__ */
|
|
10761
|
-
/* @__PURE__ */
|
|
11003
|
+
/* @__PURE__ */ jsxs73("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
|
|
11004
|
+
/* @__PURE__ */ jsx82("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." }),
|
|
11005
|
+
/* @__PURE__ */ jsxs73("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
|
|
11006
|
+
/* @__PURE__ */ jsxs73("span", { className: "fd-body-sm fd-muted fd-mono", children: [
|
|
10762
11007
|
s.endpointsWired,
|
|
10763
11008
|
" endpoint",
|
|
10764
11009
|
s.endpointsWired === 1 ? "" : "s",
|
|
@@ -10768,58 +11013,58 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
10768
11013
|
s.total,
|
|
10769
11014
|
" features complete"
|
|
10770
11015
|
] }),
|
|
10771
|
-
onOpenSpec ? /* @__PURE__ */
|
|
10772
|
-
/* @__PURE__ */
|
|
10773
|
-
/* @__PURE__ */
|
|
11016
|
+
onOpenSpec ? /* @__PURE__ */ jsxs73(Fragment22, { children: [
|
|
11017
|
+
/* @__PURE__ */ jsx82("span", { style: { flex: 1 } }),
|
|
11018
|
+
/* @__PURE__ */ jsxs73("button", { type: "button", className: "fd-soon-link", onClick: () => {
|
|
10774
11019
|
setOpen(false);
|
|
10775
11020
|
onOpenSpec();
|
|
10776
11021
|
}, children: [
|
|
10777
11022
|
"API spec ",
|
|
10778
|
-
/* @__PURE__ */
|
|
11023
|
+
/* @__PURE__ */ jsx82("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
|
|
10779
11024
|
] })
|
|
10780
11025
|
] }) : null
|
|
10781
11026
|
] })
|
|
10782
11027
|
] }),
|
|
10783
|
-
/* @__PURE__ */
|
|
10784
|
-
/* @__PURE__ */
|
|
10785
|
-
/* @__PURE__ */
|
|
10786
|
-
/* @__PURE__ */
|
|
10787
|
-
/* @__PURE__ */
|
|
10788
|
-
/* @__PURE__ */
|
|
11028
|
+
/* @__PURE__ */ jsxs73("span", { className: "fd-mode-choice", children: [
|
|
11029
|
+
/* @__PURE__ */ jsxs73("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
|
|
11030
|
+
/* @__PURE__ */ jsx82("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
|
|
11031
|
+
/* @__PURE__ */ jsxs73("span", { className: "fd-mode-opt-text", children: [
|
|
11032
|
+
/* @__PURE__ */ jsx82("span", { className: "fd-mode-opt-title", children: "Live mode" }),
|
|
11033
|
+
/* @__PURE__ */ jsx82("span", { className: "fd-mode-opt-desc", children: "Incomplete features under construction" })
|
|
10789
11034
|
] }),
|
|
10790
|
-
!test ? /* @__PURE__ */
|
|
11035
|
+
!test ? /* @__PURE__ */ jsx82("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
|
|
10791
11036
|
] }),
|
|
10792
|
-
/* @__PURE__ */
|
|
10793
|
-
/* @__PURE__ */
|
|
10794
|
-
/* @__PURE__ */
|
|
10795
|
-
/* @__PURE__ */
|
|
10796
|
-
/* @__PURE__ */
|
|
11037
|
+
/* @__PURE__ */ jsxs73("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
|
|
11038
|
+
/* @__PURE__ */ jsx82("i", { className: "ph ph-flask", "aria-hidden": "true" }),
|
|
11039
|
+
/* @__PURE__ */ jsxs73("span", { className: "fd-mode-opt-text", children: [
|
|
11040
|
+
/* @__PURE__ */ jsx82("span", { className: "fd-mode-opt-title", children: "Test mode" }),
|
|
11041
|
+
/* @__PURE__ */ jsx82("span", { className: "fd-mode-opt-desc", children: "Everything usable, all data simulated" })
|
|
10797
11042
|
] }),
|
|
10798
|
-
test ? /* @__PURE__ */
|
|
11043
|
+
test ? /* @__PURE__ */ jsx82("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
|
|
10799
11044
|
] })
|
|
10800
11045
|
] }),
|
|
10801
|
-
test && renderLog ? /* @__PURE__ */
|
|
11046
|
+
test && renderLog ? /* @__PURE__ */ jsx82("span", { style: { display: "block", maxHeight: 340, overflowY: "auto", borderTop: "1px solid var(--border)" }, children: renderLog() }) : null
|
|
10802
11047
|
] }) }) : null
|
|
10803
11048
|
] });
|
|
10804
11049
|
}
|
|
10805
11050
|
function TestModeBar({ onExit }) {
|
|
10806
11051
|
const mode2 = useRuntimeMode();
|
|
10807
11052
|
if (mode2 !== "test") return null;
|
|
10808
|
-
return /* @__PURE__ */
|
|
10809
|
-
/* @__PURE__ */
|
|
10810
|
-
/* @__PURE__ */
|
|
11053
|
+
return /* @__PURE__ */ jsxs73("div", { className: "fd-testbar", role: "status", children: [
|
|
11054
|
+
/* @__PURE__ */ jsxs73("span", { className: "fd-badge fd-badge-warning", children: [
|
|
11055
|
+
/* @__PURE__ */ jsx82("i", { className: "ph ph-flask", "aria-hidden": "true" }),
|
|
10811
11056
|
"Test mode"
|
|
10812
11057
|
] }),
|
|
10813
|
-
/* @__PURE__ */
|
|
10814
|
-
/* @__PURE__ */
|
|
10815
|
-
/* @__PURE__ */
|
|
11058
|
+
/* @__PURE__ */ jsx82("span", { className: "fd-testbar-detail", children: "Every feature is unlocked and every response is simulated \u2014 nothing here persists." }),
|
|
11059
|
+
/* @__PURE__ */ jsxs73("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
|
|
11060
|
+
/* @__PURE__ */ jsx82("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
|
|
10816
11061
|
" Back to live mode"
|
|
10817
11062
|
] })
|
|
10818
11063
|
] });
|
|
10819
11064
|
}
|
|
10820
11065
|
|
|
10821
11066
|
// src/components/planner/ChannelMeta.tsx
|
|
10822
|
-
import { jsx as
|
|
11067
|
+
import { jsx as jsx83, jsxs as jsxs74 } from "react/jsx-runtime";
|
|
10823
11068
|
var CHANNEL_WEIGHTS = {
|
|
10824
11069
|
"OOH": 50,
|
|
10825
11070
|
"DOOH": 50,
|
|
@@ -10872,9 +11117,9 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
|
|
|
10872
11117
|
const m = ChannelMeta(channel);
|
|
10873
11118
|
const wt = channelWeightOf(channel || "");
|
|
10874
11119
|
if (dot) {
|
|
10875
|
-
return /* @__PURE__ */
|
|
11120
|
+
return /* @__PURE__ */ jsx83("span", { className: ["fd-chan-dot", className].filter(Boolean).join(" "), title: m.name, style: { background: m.color }, ...rest });
|
|
10876
11121
|
}
|
|
10877
|
-
return /* @__PURE__ */
|
|
11122
|
+
return /* @__PURE__ */ jsxs74(
|
|
10878
11123
|
"span",
|
|
10879
11124
|
{
|
|
10880
11125
|
className: ["fd-chan", size === "sm" ? "fd-chan-sm" : "", className].filter(Boolean).join(" "),
|
|
@@ -10882,16 +11127,16 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
|
|
|
10882
11127
|
style: { "--chan": m.color },
|
|
10883
11128
|
...rest,
|
|
10884
11129
|
children: [
|
|
10885
|
-
/* @__PURE__ */
|
|
10886
|
-
showLabel ? /* @__PURE__ */
|
|
10887
|
-
weight ? /* @__PURE__ */
|
|
11130
|
+
/* @__PURE__ */ jsx83("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }),
|
|
11131
|
+
showLabel ? /* @__PURE__ */ jsx83("span", { className: "fd-chan-label", children: m.label }) : null,
|
|
11132
|
+
weight ? /* @__PURE__ */ jsx83("span", { className: "fd-chan-weight", children: wt || 0 }) : null
|
|
10888
11133
|
]
|
|
10889
11134
|
}
|
|
10890
11135
|
);
|
|
10891
11136
|
}
|
|
10892
11137
|
|
|
10893
11138
|
// src/components/planner/SaturationDistribution.tsx
|
|
10894
|
-
import { jsx as
|
|
11139
|
+
import { jsx as jsx84, jsxs as jsxs75 } from "react/jsx-runtime";
|
|
10895
11140
|
var BANDS2 = [
|
|
10896
11141
|
{ key: "weak", label: "Weak", n: 1, range: "< 50" },
|
|
10897
11142
|
{ key: "adequate", label: "Adequate", n: 2, range: "50\u2013100" },
|
|
@@ -10902,24 +11147,24 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
10902
11147
|
const grouped = BANDS2.map((b) => ({ ...b, items: campuses.filter((c) => c.band === b.key) }));
|
|
10903
11148
|
const tallest = Math.max(1, ...grouped.map((g) => g.items.length));
|
|
10904
11149
|
const floor = BANDS2.find((b) => b.key === floorBand) || BANDS2[0];
|
|
10905
|
-
return /* @__PURE__ */
|
|
10906
|
-
/* @__PURE__ */
|
|
11150
|
+
return /* @__PURE__ */ jsxs75("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
|
|
11151
|
+
/* @__PURE__ */ jsx84("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,minmax(0,1fr))", gap: 12, alignItems: "end" }, children: grouped.map((g) => {
|
|
10907
11152
|
const mark = "var(--csi-" + g.n + "-mark)";
|
|
10908
11153
|
const active = selectedBand === g.key;
|
|
10909
|
-
return /* @__PURE__ */
|
|
11154
|
+
return /* @__PURE__ */ jsxs75(
|
|
10910
11155
|
"button",
|
|
10911
11156
|
{
|
|
10912
11157
|
type: "button",
|
|
10913
11158
|
onClick: onSelectBand ? () => onSelectBand(active ? null : g.key) : void 0,
|
|
10914
11159
|
style: { display: "flex", flexDirection: "column", justifyContent: "flex-end", gap: 10, padding: 12, border: "1px solid " + (active ? "var(--border-strong)" : "var(--border)"), borderRadius: "var(--r-lg)", background: active ? "var(--surface-2)" : "var(--surface)", cursor: onSelectBand ? "pointer" : "default", textAlign: "left", minHeight: 190, minWidth: 0, transition: "background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)" },
|
|
10915
11160
|
children: [
|
|
10916
|
-
/* @__PURE__ */
|
|
11161
|
+
/* @__PURE__ */ jsx84("span", { style: { display: "flex", flexDirection: "column-reverse", gap: 4, minHeight: tallest * 24, minWidth: 0 }, children: loading ? Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx84("span", { className: "fd-skel", style: { height: 16, borderRadius: 4 } }, i)) : g.items.map((c) => (
|
|
10917
11162
|
// `overflow: hidden` + `white-space: nowrap` only clips once the span
|
|
10918
11163
|
// actually HAS a bounded width to clip against (see the grid/flex
|
|
10919
11164
|
// `minWidth: 0` chain above) — `textOverflow: ellipsis` then makes
|
|
10920
11165
|
// that clip readable instead of a hard cut mid-letter; the full name
|
|
10921
11166
|
// is still one hover away via `title`.
|
|
10922
|
-
/* @__PURE__ */
|
|
11167
|
+
/* @__PURE__ */ jsx84(
|
|
10923
11168
|
"span",
|
|
10924
11169
|
{
|
|
10925
11170
|
title: c.name + " \xB7 " + c.crp,
|
|
@@ -10929,13 +11174,13 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
10929
11174
|
c.name
|
|
10930
11175
|
)
|
|
10931
11176
|
)) }),
|
|
10932
|
-
/* @__PURE__ */
|
|
10933
|
-
/* @__PURE__ */
|
|
10934
|
-
/* @__PURE__ */
|
|
11177
|
+
/* @__PURE__ */ jsxs75("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
|
|
11178
|
+
/* @__PURE__ */ jsx84("span", { className: "fd-num-hero", style: { fontSize: 30, color: g.items.length ? "var(--text)" : "var(--text-disabled)" }, children: loading ? "\u2013" : g.items.length }),
|
|
11179
|
+
/* @__PURE__ */ jsx84("span", { className: "fd-meter", style: { gap: 2, color: mark }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx84("span", { className: "fd-meter-seg" + (i <= g.n ? " is-on" : ""), style: { width: 4, height: 9 } }, i)) })
|
|
10935
11180
|
] }),
|
|
10936
|
-
/* @__PURE__ */
|
|
10937
|
-
/* @__PURE__ */
|
|
10938
|
-
/* @__PURE__ */
|
|
11181
|
+
/* @__PURE__ */ jsxs75("span", { className: "fd-stack", style: { gap: 1 }, children: [
|
|
11182
|
+
/* @__PURE__ */ jsx84("span", { className: "fd-label-lg", children: g.label }),
|
|
11183
|
+
/* @__PURE__ */ jsxs75("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
|
|
10939
11184
|
"CRP ",
|
|
10940
11185
|
g.range
|
|
10941
11186
|
] })
|
|
@@ -10945,10 +11190,10 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
10945
11190
|
g.key
|
|
10946
11191
|
);
|
|
10947
11192
|
}) }),
|
|
10948
|
-
floorBand ? /* @__PURE__ */
|
|
10949
|
-
/* @__PURE__ */
|
|
10950
|
-
/* @__PURE__ */
|
|
10951
|
-
/* @__PURE__ */
|
|
11193
|
+
floorBand ? /* @__PURE__ */ jsxs75("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: [
|
|
11194
|
+
/* @__PURE__ */ jsx84("span", { className: "fd-meter", style: { gap: 2, color: "var(--csi-" + floor.n + "-mark)" }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx84("span", { className: "fd-meter-seg" + (i <= floor.n ? " is-on" : ""), style: { width: 5, height: 12 } }, i)) }),
|
|
11195
|
+
/* @__PURE__ */ jsxs75("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
|
|
11196
|
+
/* @__PURE__ */ jsxs75("strong", { style: { color: "var(--text)" }, children: [
|
|
10952
11197
|
"Plan floor ",
|
|
10953
11198
|
floorScore
|
|
10954
11199
|
] }),
|
|
@@ -10959,8 +11204,8 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
10959
11204
|
}
|
|
10960
11205
|
|
|
10961
11206
|
// src/components/planner/MixGap.tsx
|
|
10962
|
-
import * as
|
|
10963
|
-
import { Fragment as Fragment23, jsx as
|
|
11207
|
+
import * as React56 from "react";
|
|
11208
|
+
import { Fragment as Fragment23, jsx as jsx85, jsxs as jsxs76 } from "react/jsx-runtime";
|
|
10964
11209
|
var MIX_GAP_LAYOUT = {
|
|
10965
11210
|
trackHeight: 30,
|
|
10966
11211
|
barHeight: 20,
|
|
@@ -10974,19 +11219,19 @@ function mixGapOffset(value, max) {
|
|
|
10974
11219
|
}
|
|
10975
11220
|
function MixGap({ rows = [], loading = false, className = "" }) {
|
|
10976
11221
|
const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
|
|
10977
|
-
const [hover, setHover] =
|
|
11222
|
+
const [hover, setHover] = React56.useState(null);
|
|
10978
11223
|
const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
|
|
10979
11224
|
const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
|
|
10980
11225
|
const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
|
|
10981
11226
|
const barTop = (trackHeight - barHeight) / 2;
|
|
10982
|
-
return /* @__PURE__ */
|
|
10983
|
-
/* @__PURE__ */
|
|
10984
|
-
[["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */
|
|
10985
|
-
/* @__PURE__ */
|
|
11227
|
+
return /* @__PURE__ */ jsxs76("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
|
|
11228
|
+
/* @__PURE__ */ jsxs76("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
|
|
11229
|
+
[["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs76("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
|
|
11230
|
+
/* @__PURE__ */ jsx85("span", { style: { width: 14, height: 9, borderRadius: 2, background: c } }),
|
|
10986
11231
|
l
|
|
10987
11232
|
] }, l)),
|
|
10988
|
-
/* @__PURE__ */
|
|
10989
|
-
/* @__PURE__ */
|
|
11233
|
+
/* @__PURE__ */ jsxs76("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
|
|
11234
|
+
/* @__PURE__ */ jsx85("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
|
|
10990
11235
|
"Target"
|
|
10991
11236
|
] })
|
|
10992
11237
|
] }),
|
|
@@ -10995,7 +11240,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
|
|
|
10995
11240
|
const tone = toneOf(gap);
|
|
10996
11241
|
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 : "");
|
|
10997
11242
|
const labelLeft = r.realized > r.target ? `calc(${mixGapOffset(r.realized, max)} + ${labelGap}px)` : `calc(${mixGapOffset(r.target, max)} + ${targetWidth / 2 + labelGap}px)`;
|
|
10998
|
-
return /* @__PURE__ */
|
|
11243
|
+
return /* @__PURE__ */ jsxs76(
|
|
10999
11244
|
"div",
|
|
11000
11245
|
{
|
|
11001
11246
|
className: "fd-row",
|
|
@@ -11003,15 +11248,15 @@ function MixGap({ rows = [], loading = false, className = "" }) {
|
|
|
11003
11248
|
onMouseEnter: () => setHover(r.channel),
|
|
11004
11249
|
onMouseLeave: () => setHover(null),
|
|
11005
11250
|
children: [
|
|
11006
|
-
/* @__PURE__ */
|
|
11007
|
-
/* @__PURE__ */
|
|
11008
|
-
/* @__PURE__ */
|
|
11009
|
-
/* @__PURE__ */
|
|
11010
|
-
/* @__PURE__ */
|
|
11251
|
+
/* @__PURE__ */ jsx85("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx85(ChannelTag, { channel: r.channel, size: "sm" }) }),
|
|
11252
|
+
/* @__PURE__ */ jsx85("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx85("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs76(Fragment23, { children: [
|
|
11253
|
+
/* @__PURE__ */ jsx85("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)" } }),
|
|
11254
|
+
/* @__PURE__ */ jsx85("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 } }),
|
|
11255
|
+
/* @__PURE__ */ jsxs76("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: [
|
|
11011
11256
|
r.realized,
|
|
11012
11257
|
"%"
|
|
11013
11258
|
] }),
|
|
11014
|
-
hover === r.channel ? /* @__PURE__ */
|
|
11259
|
+
hover === r.channel ? /* @__PURE__ */ jsx85("span", { className: "fd-tooltip", role: "tooltip", style: { position: "absolute", left: 0, right: "auto", bottom: trackHeight + 4, maxWidth: "min(340px, 100%)", whiteSpace: "normal", textAlign: "left", width: "max-content" }, children: tip }) : null
|
|
11015
11260
|
] }) })
|
|
11016
11261
|
]
|
|
11017
11262
|
},
|
|
@@ -11022,7 +11267,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
|
|
|
11022
11267
|
}
|
|
11023
11268
|
|
|
11024
11269
|
// src/components/planner/ChannelContribution.tsx
|
|
11025
|
-
import { jsx as
|
|
11270
|
+
import { jsx as jsx86, jsxs as jsxs77 } from "react/jsx-runtime";
|
|
11026
11271
|
var money = (n) => "$" + Math.round(n).toLocaleString();
|
|
11027
11272
|
function ChannelContribution({
|
|
11028
11273
|
channels = [],
|
|
@@ -11038,9 +11283,9 @@ function ChannelContribution({
|
|
|
11038
11283
|
const grand = total !== void 0 ? total : base + bonus;
|
|
11039
11284
|
const pct = (v) => grand ? v / grand * 100 : 0;
|
|
11040
11285
|
const spendTotal = channels.reduce((s, c) => s + Number(String(c.spend || 0).replace(/[^0-9.]/g, "")), 0);
|
|
11041
|
-
return /* @__PURE__ */
|
|
11042
|
-
loading ? /* @__PURE__ */
|
|
11043
|
-
channels.map((c) => /* @__PURE__ */
|
|
11286
|
+
return /* @__PURE__ */ jsxs77("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
|
|
11287
|
+
loading ? /* @__PURE__ */ jsx86("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */ jsxs77("div", { className: "fd-row", style: { height: 34, borderRadius: "var(--r-sm)", overflow: "hidden", gap: 2, background: "var(--surface-3)" }, children: [
|
|
11288
|
+
channels.map((c) => /* @__PURE__ */ jsx86(
|
|
11044
11289
|
"span",
|
|
11045
11290
|
{
|
|
11046
11291
|
title: c.name + " \xB7 " + c.crp.toFixed(1) + " CRP",
|
|
@@ -11049,7 +11294,7 @@ function ChannelContribution({
|
|
|
11049
11294
|
},
|
|
11050
11295
|
c.name
|
|
11051
11296
|
)),
|
|
11052
|
-
bonus > 0 ? /* @__PURE__ */
|
|
11297
|
+
bonus > 0 ? /* @__PURE__ */ jsx86(
|
|
11053
11298
|
"span",
|
|
11054
11299
|
{
|
|
11055
11300
|
title: "Surround-sound bonus +" + bonusPct + "%",
|
|
@@ -11058,18 +11303,18 @@ function ChannelContribution({
|
|
|
11058
11303
|
}
|
|
11059
11304
|
) : null
|
|
11060
11305
|
] }),
|
|
11061
|
-
showTable ? /* @__PURE__ */
|
|
11062
|
-
/* @__PURE__ */
|
|
11063
|
-
/* @__PURE__ */
|
|
11064
|
-
/* @__PURE__ */
|
|
11065
|
-
/* @__PURE__ */
|
|
11066
|
-
/* @__PURE__ */
|
|
11067
|
-
/* @__PURE__ */
|
|
11306
|
+
showTable ? /* @__PURE__ */ jsxs77("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
|
|
11307
|
+
/* @__PURE__ */ jsx86("thead", { children: /* @__PURE__ */ jsxs77("tr", { children: [
|
|
11308
|
+
/* @__PURE__ */ jsx86("th", { style: { width: "34%" }, children: "Channel" }),
|
|
11309
|
+
/* @__PURE__ */ jsx86("th", { style: { width: "16%" }, children: "Weight" }),
|
|
11310
|
+
/* @__PURE__ */ jsx86("th", { className: "is-num", style: { width: "16%" }, children: "Spend" }),
|
|
11311
|
+
/* @__PURE__ */ jsx86("th", { className: "is-num", style: { width: "17%" }, children: "CRP" }),
|
|
11312
|
+
/* @__PURE__ */ jsx86("th", { className: "is-num", style: { width: "17%" }, children: "Share" })
|
|
11068
11313
|
] }) }),
|
|
11069
|
-
/* @__PURE__ */
|
|
11070
|
-
channels.map((c) => /* @__PURE__ */
|
|
11071
|
-
/* @__PURE__ */
|
|
11072
|
-
/* @__PURE__ */
|
|
11314
|
+
/* @__PURE__ */ jsxs77("tbody", { children: [
|
|
11315
|
+
channels.map((c) => /* @__PURE__ */ jsxs77("tr", { children: [
|
|
11316
|
+
/* @__PURE__ */ jsx86("td", { children: /* @__PURE__ */ jsx86(ChannelTag, { channel: c.name, size: "sm" }) }),
|
|
11317
|
+
/* @__PURE__ */ jsx86("td", { children: /* @__PURE__ */ jsx86(
|
|
11073
11318
|
"span",
|
|
11074
11319
|
{
|
|
11075
11320
|
className: "fd-badge fd-badge-neutral",
|
|
@@ -11078,38 +11323,38 @@ function ChannelContribution({
|
|
|
11078
11323
|
children: "weight " + (channelWeightOf(c.name) || 0)
|
|
11079
11324
|
}
|
|
11080
11325
|
) }),
|
|
11081
|
-
/* @__PURE__ */
|
|
11082
|
-
/* @__PURE__ */
|
|
11083
|
-
/* @__PURE__ */
|
|
11326
|
+
/* @__PURE__ */ jsx86("td", { className: "is-num", children: c.spend }),
|
|
11327
|
+
/* @__PURE__ */ jsx86("td", { className: "is-num", children: c.crp.toFixed(1) }),
|
|
11328
|
+
/* @__PURE__ */ jsxs77("td", { className: "is-num", children: [
|
|
11084
11329
|
pct(c.crp).toFixed(0),
|
|
11085
11330
|
"%"
|
|
11086
11331
|
] })
|
|
11087
11332
|
] }, c.name)),
|
|
11088
|
-
bonus > 0 ? /* @__PURE__ */
|
|
11089
|
-
/* @__PURE__ */
|
|
11090
|
-
/* @__PURE__ */
|
|
11333
|
+
bonus > 0 ? /* @__PURE__ */ jsxs77("tr", { children: [
|
|
11334
|
+
/* @__PURE__ */ jsx86("td", { children: /* @__PURE__ */ jsxs77("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
|
|
11335
|
+
/* @__PURE__ */ jsx86("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" } }),
|
|
11091
11336
|
"Surround-sound bonus"
|
|
11092
11337
|
] }) }),
|
|
11093
|
-
/* @__PURE__ */
|
|
11338
|
+
/* @__PURE__ */ jsx86("td", { children: /* @__PURE__ */ jsxs77("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
|
|
11094
11339
|
"+",
|
|
11095
11340
|
bonusPct,
|
|
11096
11341
|
"% of +",
|
|
11097
11342
|
bonusMax,
|
|
11098
11343
|
"%"
|
|
11099
11344
|
] }) }),
|
|
11100
|
-
/* @__PURE__ */
|
|
11101
|
-
/* @__PURE__ */
|
|
11102
|
-
/* @__PURE__ */
|
|
11345
|
+
/* @__PURE__ */ jsx86("td", { className: "is-num fd-muted", children: "\u2014" }),
|
|
11346
|
+
/* @__PURE__ */ jsx86("td", { className: "is-num", children: bonus.toFixed(1) }),
|
|
11347
|
+
/* @__PURE__ */ jsxs77("td", { className: "is-num", children: [
|
|
11103
11348
|
pct(bonus).toFixed(0),
|
|
11104
11349
|
"%"
|
|
11105
11350
|
] })
|
|
11106
11351
|
] }) : null,
|
|
11107
|
-
/* @__PURE__ */
|
|
11108
|
-
/* @__PURE__ */
|
|
11109
|
-
/* @__PURE__ */
|
|
11110
|
-
/* @__PURE__ */
|
|
11111
|
-
/* @__PURE__ */
|
|
11112
|
-
/* @__PURE__ */
|
|
11352
|
+
/* @__PURE__ */ jsxs77("tr", { style: { background: "var(--surface-2)" }, children: [
|
|
11353
|
+
/* @__PURE__ */ jsx86("td", { style: { fontWeight: 700 }, children: "Campus total" }),
|
|
11354
|
+
/* @__PURE__ */ jsx86("td", {}),
|
|
11355
|
+
/* @__PURE__ */ jsx86("td", { className: "is-num", style: { fontWeight: 700 }, children: money(spendTotal) }),
|
|
11356
|
+
/* @__PURE__ */ jsx86("td", { className: "is-num", style: { fontWeight: 700 }, children: grand.toFixed(1) }),
|
|
11357
|
+
/* @__PURE__ */ jsx86("td", { className: "is-num", style: { fontWeight: 700 }, children: "100%" })
|
|
11113
11358
|
] })
|
|
11114
11359
|
] })
|
|
11115
11360
|
] }) : null
|
|
@@ -11117,8 +11362,8 @@ function ChannelContribution({
|
|
|
11117
11362
|
}
|
|
11118
11363
|
|
|
11119
11364
|
// src/components/planner/BudgetReallocator.tsx
|
|
11120
|
-
import * as
|
|
11121
|
-
import { Fragment as Fragment24, jsx as
|
|
11365
|
+
import * as React57 from "react";
|
|
11366
|
+
import { Fragment as Fragment24, jsx as jsx87, jsxs as jsxs78 } from "react/jsx-runtime";
|
|
11122
11367
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
11123
11368
|
function BudgetReallocator({
|
|
11124
11369
|
campus,
|
|
@@ -11133,8 +11378,8 @@ function BudgetReallocator({
|
|
|
11133
11378
|
onCancel,
|
|
11134
11379
|
className = ""
|
|
11135
11380
|
}) {
|
|
11136
|
-
const [draft, setDraft] =
|
|
11137
|
-
|
|
11381
|
+
const [draft, setDraft] = React57.useState(spend);
|
|
11382
|
+
React57.useEffect(() => setDraft(spend), [spend]);
|
|
11138
11383
|
const dirty = draft !== spend;
|
|
11139
11384
|
const nextCrp = scoreFor ? scoreFor(draft) : crp;
|
|
11140
11385
|
const nextBand = bandFor(nextCrp);
|
|
@@ -11149,10 +11394,10 @@ function BudgetReallocator({
|
|
|
11149
11394
|
setDraft(spend);
|
|
11150
11395
|
if (onCancel) onCancel();
|
|
11151
11396
|
};
|
|
11152
|
-
const trackRef =
|
|
11153
|
-
const chipRef =
|
|
11154
|
-
const [chipLeft, setChipLeft] =
|
|
11155
|
-
|
|
11397
|
+
const trackRef = React57.useRef(null);
|
|
11398
|
+
const chipRef = React57.useRef(null);
|
|
11399
|
+
const [chipLeft, setChipLeft] = React57.useState(null);
|
|
11400
|
+
React57.useLayoutEffect(() => {
|
|
11156
11401
|
const track = trackRef.current;
|
|
11157
11402
|
if (!dirty || !track) {
|
|
11158
11403
|
setChipLeft(null);
|
|
@@ -11173,23 +11418,23 @@ function BudgetReallocator({
|
|
|
11173
11418
|
ro.observe(track);
|
|
11174
11419
|
return () => ro.disconnect();
|
|
11175
11420
|
}, [dirty, pct]);
|
|
11176
|
-
return /* @__PURE__ */
|
|
11421
|
+
return /* @__PURE__ */ jsxs78(
|
|
11177
11422
|
"div",
|
|
11178
11423
|
{
|
|
11179
11424
|
className: ["fd-stack", className].filter(Boolean).join(" "),
|
|
11180
11425
|
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)" },
|
|
11181
11426
|
children: [
|
|
11182
|
-
/* @__PURE__ */
|
|
11183
|
-
/* @__PURE__ */
|
|
11184
|
-
/* @__PURE__ */
|
|
11185
|
-
dirty ? /* @__PURE__ */
|
|
11186
|
-
/* @__PURE__ */
|
|
11187
|
-
/* @__PURE__ */
|
|
11427
|
+
/* @__PURE__ */ jsxs78("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
|
|
11428
|
+
/* @__PURE__ */ jsx87("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
|
|
11429
|
+
/* @__PURE__ */ jsx87(CsiBadge, { band: nowBand, crp, size: "medium" }),
|
|
11430
|
+
dirty ? /* @__PURE__ */ jsxs78(Fragment24, { children: [
|
|
11431
|
+
/* @__PURE__ */ jsx87("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
|
|
11432
|
+
/* @__PURE__ */ jsx87(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
|
|
11188
11433
|
] }) : null
|
|
11189
11434
|
] }),
|
|
11190
|
-
/* @__PURE__ */
|
|
11191
|
-
/* @__PURE__ */
|
|
11192
|
-
dirty ? /* @__PURE__ */
|
|
11435
|
+
/* @__PURE__ */ jsxs78("div", { className: "fd-slider", ref: trackRef, children: [
|
|
11436
|
+
/* @__PURE__ */ jsx87("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
|
|
11437
|
+
dirty ? /* @__PURE__ */ jsx87(
|
|
11193
11438
|
"span",
|
|
11194
11439
|
{
|
|
11195
11440
|
ref: chipRef,
|
|
@@ -11201,7 +11446,7 @@ function BudgetReallocator({
|
|
|
11201
11446
|
children: (delta < 0 ? "\u2212$" : "+$") + Math.abs(delta).toLocaleString()
|
|
11202
11447
|
}
|
|
11203
11448
|
) : null,
|
|
11204
|
-
/* @__PURE__ */
|
|
11449
|
+
/* @__PURE__ */ jsx87(
|
|
11205
11450
|
"input",
|
|
11206
11451
|
{
|
|
11207
11452
|
type: "range",
|
|
@@ -11217,13 +11462,13 @@ function BudgetReallocator({
|
|
|
11217
11462
|
}
|
|
11218
11463
|
)
|
|
11219
11464
|
] }),
|
|
11220
|
-
/* @__PURE__ */
|
|
11221
|
-
/* @__PURE__ */
|
|
11222
|
-
/* @__PURE__ */
|
|
11223
|
-
/* @__PURE__ */
|
|
11465
|
+
/* @__PURE__ */ jsxs78("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
|
|
11466
|
+
/* @__PURE__ */ jsxs78("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
|
|
11467
|
+
/* @__PURE__ */ jsx87("span", { className: "fd-num", style: { fontSize: 19, fontWeight: 700 }, children: "$" + draft.toLocaleString() }),
|
|
11468
|
+
/* @__PURE__ */ jsx87("span", { className: "fd-body-sm fd-muted", children: "Arrow keys step $100, shift+arrow $1,000. Escape reverts." })
|
|
11224
11469
|
] }),
|
|
11225
|
-
/* @__PURE__ */
|
|
11226
|
-
/* @__PURE__ */
|
|
11470
|
+
/* @__PURE__ */ jsx87("button", { type: "button", className: "fd-btn fd-btn-ghost", disabled: !dirty, onClick: revert, children: "Cancel" }),
|
|
11471
|
+
/* @__PURE__ */ jsx87(
|
|
11227
11472
|
"button",
|
|
11228
11473
|
{
|
|
11229
11474
|
type: "button",
|
|
@@ -11242,7 +11487,7 @@ function BudgetReallocator({
|
|
|
11242
11487
|
}
|
|
11243
11488
|
|
|
11244
11489
|
// src/components/planner/SurroundSound.tsx
|
|
11245
|
-
import { jsx as
|
|
11490
|
+
import { jsx as jsx88, jsxs as jsxs79 } from "react/jsx-runtime";
|
|
11246
11491
|
var CATEGORIES = [
|
|
11247
11492
|
{ key: "ooh", label: "OOH", icon: "flag-banner", color: "var(--ch-ooh)" },
|
|
11248
11493
|
{ key: "transit", label: "Transit", icon: "bus", color: "var(--ch-transit)" },
|
|
@@ -11254,26 +11499,26 @@ var CATEGORIES = [
|
|
|
11254
11499
|
function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost, className = "" }) {
|
|
11255
11500
|
const earned = Math.max(0, Math.min(1, bonusPct / bonusMax));
|
|
11256
11501
|
const single = present.length <= 2;
|
|
11257
|
-
return /* @__PURE__ */
|
|
11258
|
-
/* @__PURE__ */
|
|
11502
|
+
return /* @__PURE__ */ jsxs79("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
|
|
11503
|
+
/* @__PURE__ */ jsx88("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: CATEGORIES.map((c) => {
|
|
11259
11504
|
const on = present.includes(c.key);
|
|
11260
|
-
return /* @__PURE__ */
|
|
11505
|
+
return /* @__PURE__ */ jsxs79(
|
|
11261
11506
|
"span",
|
|
11262
11507
|
{
|
|
11263
11508
|
title: c.label + (on ? " \u2014 present" : " \u2014 not bought"),
|
|
11264
11509
|
style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 5, width: 62, padding: "10px 0", borderRadius: "var(--r-md)", border: "1px solid " + (on ? "var(--csi-2-edge)" : "var(--border)"), background: on ? "var(--csi-2-fill)" : "var(--surface-2)", color: on ? "var(--csi-2-text)" : "var(--text-disabled)" },
|
|
11265
11510
|
children: [
|
|
11266
|
-
/* @__PURE__ */
|
|
11267
|
-
/* @__PURE__ */
|
|
11511
|
+
/* @__PURE__ */ jsx88("i", { className: "ph ph-" + c.icon, style: { fontSize: 19, color: on ? c.color : "var(--text-muted)" }, "aria-hidden": "true" }),
|
|
11512
|
+
/* @__PURE__ */ jsx88("span", { style: { fontSize: 10.5, fontWeight: 700 }, children: c.label })
|
|
11268
11513
|
]
|
|
11269
11514
|
},
|
|
11270
11515
|
c.key
|
|
11271
11516
|
);
|
|
11272
11517
|
}) }),
|
|
11273
|
-
/* @__PURE__ */
|
|
11274
|
-
/* @__PURE__ */
|
|
11275
|
-
/* @__PURE__ */
|
|
11276
|
-
/* @__PURE__ */
|
|
11518
|
+
/* @__PURE__ */ jsxs79("div", { className: "fd-stack", style: { gap: 8 }, children: [
|
|
11519
|
+
/* @__PURE__ */ jsxs79("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
|
|
11520
|
+
/* @__PURE__ */ jsx88("span", { className: "fd-label-lg", children: "Surround-sound bonus earned" }),
|
|
11521
|
+
/* @__PURE__ */ jsxs79("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
|
|
11277
11522
|
"+",
|
|
11278
11523
|
bonusPct,
|
|
11279
11524
|
"% of +",
|
|
@@ -11281,8 +11526,8 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
|
|
|
11281
11526
|
"%"
|
|
11282
11527
|
] })
|
|
11283
11528
|
] }),
|
|
11284
|
-
/* @__PURE__ */
|
|
11285
|
-
/* @__PURE__ */
|
|
11529
|
+
/* @__PURE__ */ jsx88("div", { style: { height: 8, borderRadius: "var(--r-xs)", background: "var(--surface-3)", overflow: "hidden" }, children: /* @__PURE__ */ jsx88("div", { style: { height: "100%", width: earned * 100 + "%", background: "var(--csi-3-mark)", borderRadius: "inherit", transition: "width var(--dur-slow) var(--ease)" } }) }),
|
|
11530
|
+
/* @__PURE__ */ jsxs79("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
|
|
11286
11531
|
present.length,
|
|
11287
11532
|
" of 6 channel categories present.",
|
|
11288
11533
|
" ",
|
|
@@ -11294,7 +11539,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
|
|
|
11294
11539
|
}
|
|
11295
11540
|
|
|
11296
11541
|
// src/components/planner/Importance.tsx
|
|
11297
|
-
import { jsx as
|
|
11542
|
+
import { jsx as jsx89, jsxs as jsxs80 } from "react/jsx-runtime";
|
|
11298
11543
|
var IMPORTANCE_LEVELS = [
|
|
11299
11544
|
{ id: "nudge", rank: 1, label: "Nudge", icon: "feather", description: "Breaks a tie, nothing more." },
|
|
11300
11545
|
{ id: "lean", rank: 2, label: "Lean", icon: "arrow-bend-up-right", description: "A mild preference between otherwise equal options." },
|
|
@@ -11324,7 +11569,7 @@ function importanceTokens(id) {
|
|
|
11324
11569
|
function ImportanceTag({ level, showLabel = true, size = "sm", className = "", disabled = false }) {
|
|
11325
11570
|
const lvl = importanceLevel(level);
|
|
11326
11571
|
const t = importanceTokens(level);
|
|
11327
|
-
return /* @__PURE__ */
|
|
11572
|
+
return /* @__PURE__ */ jsxs80(
|
|
11328
11573
|
"span",
|
|
11329
11574
|
{
|
|
11330
11575
|
className: ["fd-imp-tag", size === "md" ? "is-md" : "", disabled ? "is-disabled" : "", className].filter(Boolean).join(" "),
|
|
@@ -11332,16 +11577,16 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
|
|
|
11332
11577
|
title: lvl.label + " \u2014 " + lvl.description,
|
|
11333
11578
|
"aria-disabled": disabled ? "true" : void 0,
|
|
11334
11579
|
children: [
|
|
11335
|
-
/* @__PURE__ */
|
|
11336
|
-
showLabel ? lvl.label : /* @__PURE__ */
|
|
11580
|
+
/* @__PURE__ */ jsx89("i", { className: "ph ph-" + lvl.icon, "aria-hidden": "true" }),
|
|
11581
|
+
showLabel ? lvl.label : /* @__PURE__ */ jsx89("span", { className: "fd-sr", children: lvl.label })
|
|
11337
11582
|
]
|
|
11338
11583
|
}
|
|
11339
11584
|
);
|
|
11340
11585
|
}
|
|
11341
11586
|
|
|
11342
11587
|
// src/components/planner/PreferenceMeter.tsx
|
|
11343
|
-
import * as
|
|
11344
|
-
import { jsx as
|
|
11588
|
+
import * as React58 from "react";
|
|
11589
|
+
import { jsx as jsx90, jsxs as jsxs81 } from "react/jsx-runtime";
|
|
11345
11590
|
function preferenceScore(criteria) {
|
|
11346
11591
|
const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
|
|
11347
11592
|
const weight = criteria.reduce((n, c) => n + (Number(c.weight) || 0), 0);
|
|
@@ -11370,8 +11615,8 @@ function PreferenceMeter({
|
|
|
11370
11615
|
className = ""
|
|
11371
11616
|
}) {
|
|
11372
11617
|
const value = score == null ? preferenceScore(criteria) : score;
|
|
11373
|
-
const segments =
|
|
11374
|
-
return /* @__PURE__ */
|
|
11618
|
+
const segments = React58.useMemo(() => preferenceSegments(criteria), [criteria]);
|
|
11619
|
+
return /* @__PURE__ */ jsx90(
|
|
11375
11620
|
ScoreMeter,
|
|
11376
11621
|
{
|
|
11377
11622
|
score: value,
|
|
@@ -11383,22 +11628,22 @@ function PreferenceMeter({
|
|
|
11383
11628
|
placement,
|
|
11384
11629
|
className,
|
|
11385
11630
|
breakdownLabel: breakdownTitle,
|
|
11386
|
-
breakdown: /* @__PURE__ */
|
|
11387
|
-
/* @__PURE__ */
|
|
11388
|
-
/* @__PURE__ */
|
|
11389
|
-
/* @__PURE__ */
|
|
11631
|
+
breakdown: /* @__PURE__ */ jsxs81("div", { className: "fd-prefbreak", children: [
|
|
11632
|
+
/* @__PURE__ */ jsxs81("div", { className: "fd-prefbreak-head", children: [
|
|
11633
|
+
/* @__PURE__ */ jsx90("span", { className: "fd-label-lg", children: breakdownTitle }),
|
|
11634
|
+
/* @__PURE__ */ jsx90("span", { className: "fd-prefbreak-score fd-tabular", children: Math.round(value) })
|
|
11390
11635
|
] }),
|
|
11391
|
-
/* @__PURE__ */
|
|
11636
|
+
/* @__PURE__ */ jsx90("ul", { className: "fd-prefbreak-list", children: criteria.map((c) => {
|
|
11392
11637
|
const pct = c.weight > 0 ? Math.round((Number(c.earned) || 0) / c.weight * 100) : 0;
|
|
11393
|
-
return /* @__PURE__ */
|
|
11394
|
-
/* @__PURE__ */
|
|
11395
|
-
/* @__PURE__ */
|
|
11396
|
-
/* @__PURE__ */
|
|
11397
|
-
c.note ? /* @__PURE__ */
|
|
11638
|
+
return /* @__PURE__ */ jsxs81("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
|
|
11639
|
+
/* @__PURE__ */ jsx90(ImportanceTag, { level: c.importance }),
|
|
11640
|
+
/* @__PURE__ */ jsxs81("span", { className: "fd-prefbreak-text", children: [
|
|
11641
|
+
/* @__PURE__ */ jsx90("span", { className: "fd-prefbreak-label", children: c.label }),
|
|
11642
|
+
c.note ? /* @__PURE__ */ jsx90("span", { className: "fd-prefbreak-note", children: c.note }) : null
|
|
11398
11643
|
] }),
|
|
11399
|
-
/* @__PURE__ */
|
|
11644
|
+
/* @__PURE__ */ jsxs81("span", { className: "fd-prefbreak-val fd-tabular", children: [
|
|
11400
11645
|
Math.round(Number(c.earned) || 0),
|
|
11401
|
-
/* @__PURE__ */
|
|
11646
|
+
/* @__PURE__ */ jsx90("span", { className: "fd-prefbreak-sep", children: "/" }),
|
|
11402
11647
|
Math.round(c.weight)
|
|
11403
11648
|
] })
|
|
11404
11649
|
] }, c.id);
|
|
@@ -11409,10 +11654,10 @@ function PreferenceMeter({
|
|
|
11409
11654
|
}
|
|
11410
11655
|
|
|
11411
11656
|
// src/components/chat/AgentChatPanel.tsx
|
|
11412
|
-
import * as
|
|
11657
|
+
import * as React64 from "react";
|
|
11413
11658
|
|
|
11414
11659
|
// src/components/chat/chatEngine.ts
|
|
11415
|
-
import * as
|
|
11660
|
+
import * as React59 from "react";
|
|
11416
11661
|
var CHAT_UNAVAILABLE = "chat_unavailable";
|
|
11417
11662
|
var JOB_PENDING = ["queued", "running"];
|
|
11418
11663
|
var JOB_SUCCESS = ["completed", "recovered"];
|
|
@@ -11466,22 +11711,22 @@ function useChatEngine(opts) {
|
|
|
11466
11711
|
onClear,
|
|
11467
11712
|
onFeedback
|
|
11468
11713
|
} = opts || {};
|
|
11469
|
-
const [status, setStatus] =
|
|
11470
|
-
const [threadId, setThreadId] =
|
|
11471
|
-
const [messages, setMessages] =
|
|
11472
|
-
const [queue, setQueue] =
|
|
11473
|
-
const [fatal, setFatal] =
|
|
11474
|
-
const [busy, setBusy] =
|
|
11475
|
-
const [turnStartedAt, setTurnStartedAt] =
|
|
11476
|
-
const listRef =
|
|
11477
|
-
const queueRef =
|
|
11478
|
-
const busyRef =
|
|
11479
|
-
const stoppedRef =
|
|
11480
|
-
const abortRef =
|
|
11481
|
-
const serverCount =
|
|
11482
|
-
const threadRef =
|
|
11483
|
-
const mounted =
|
|
11484
|
-
|
|
11714
|
+
const [status, setStatus] = React59.useState("idle");
|
|
11715
|
+
const [threadId, setThreadId] = React59.useState(null);
|
|
11716
|
+
const [messages, setMessages] = React59.useState([]);
|
|
11717
|
+
const [queue, setQueue] = React59.useState([]);
|
|
11718
|
+
const [fatal, setFatal] = React59.useState(null);
|
|
11719
|
+
const [busy, setBusy] = React59.useState(false);
|
|
11720
|
+
const [turnStartedAt, setTurnStartedAt] = React59.useState(null);
|
|
11721
|
+
const listRef = React59.useRef([]);
|
|
11722
|
+
const queueRef = React59.useRef([]);
|
|
11723
|
+
const busyRef = React59.useRef(false);
|
|
11724
|
+
const stoppedRef = React59.useRef(false);
|
|
11725
|
+
const abortRef = React59.useRef(null);
|
|
11726
|
+
const serverCount = React59.useRef(0);
|
|
11727
|
+
const threadRef = React59.useRef(null);
|
|
11728
|
+
const mounted = React59.useRef(true);
|
|
11729
|
+
React59.useEffect(() => {
|
|
11485
11730
|
mounted.current = true;
|
|
11486
11731
|
return () => {
|
|
11487
11732
|
mounted.current = false;
|
|
@@ -11503,14 +11748,14 @@ function useChatEngine(opts) {
|
|
|
11503
11748
|
}
|
|
11504
11749
|
return false;
|
|
11505
11750
|
};
|
|
11506
|
-
const loadThread =
|
|
11751
|
+
const loadThread = React59.useCallback(async (id) => {
|
|
11507
11752
|
const data = await apiAdapter.getThread(id);
|
|
11508
11753
|
const list = [...data && data.messages || []];
|
|
11509
11754
|
serverCount.current = list.length;
|
|
11510
11755
|
commit(list);
|
|
11511
11756
|
return list;
|
|
11512
11757
|
}, [apiAdapter]);
|
|
11513
|
-
|
|
11758
|
+
React59.useEffect(() => {
|
|
11514
11759
|
if (!apiAdapter) {
|
|
11515
11760
|
setStatus("idle");
|
|
11516
11761
|
setFatal(null);
|
|
@@ -11723,7 +11968,7 @@ function useChatEngine(opts) {
|
|
|
11723
11968
|
await dispatchTurn(turn);
|
|
11724
11969
|
}
|
|
11725
11970
|
}
|
|
11726
|
-
const send =
|
|
11971
|
+
const send = React59.useCallback((text, attachments) => {
|
|
11727
11972
|
const body = (text || "").trim();
|
|
11728
11973
|
if (!body && !(attachments && attachments.length)) return;
|
|
11729
11974
|
if (status === "disconnected") return;
|
|
@@ -11733,7 +11978,7 @@ function useChatEngine(opts) {
|
|
|
11733
11978
|
stoppedRef.current = false;
|
|
11734
11979
|
drain();
|
|
11735
11980
|
}, [status]);
|
|
11736
|
-
const stop =
|
|
11981
|
+
const stop = React59.useCallback(() => {
|
|
11737
11982
|
stoppedRef.current = true;
|
|
11738
11983
|
const ac = abortRef.current;
|
|
11739
11984
|
if (ac) {
|
|
@@ -11752,11 +11997,11 @@ function useChatEngine(opts) {
|
|
|
11752
11997
|
store.del(STORAGE_PREFIX + threadRef.current);
|
|
11753
11998
|
}
|
|
11754
11999
|
}, [apiAdapter]);
|
|
11755
|
-
const removeQueued =
|
|
12000
|
+
const removeQueued = React59.useCallback((id) => {
|
|
11756
12001
|
queueRef.current = queueRef.current.filter((t) => t.id !== id);
|
|
11757
12002
|
setQueue(queueRef.current.slice());
|
|
11758
12003
|
}, []);
|
|
11759
|
-
const retry =
|
|
12004
|
+
const retry = React59.useCallback(() => {
|
|
11760
12005
|
const list = listRef.current;
|
|
11761
12006
|
let at = -1;
|
|
11762
12007
|
for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
|
|
@@ -11772,19 +12017,19 @@ function useChatEngine(opts) {
|
|
|
11772
12017
|
setQueue(queueRef.current.slice());
|
|
11773
12018
|
drain();
|
|
11774
12019
|
}, []);
|
|
11775
|
-
const clear =
|
|
12020
|
+
const clear = React59.useCallback(() => {
|
|
11776
12021
|
commit([]);
|
|
11777
12022
|
serverCount.current = 0;
|
|
11778
12023
|
queueRef.current = [];
|
|
11779
12024
|
setQueue([]);
|
|
11780
12025
|
onClear && onClear();
|
|
11781
12026
|
}, [onClear]);
|
|
11782
|
-
const setFeedback =
|
|
12027
|
+
const setFeedback = React59.useCallback((id, value) => {
|
|
11783
12028
|
patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
|
|
11784
12029
|
const msg = listRef.current.find((m) => m.id === id);
|
|
11785
12030
|
onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
|
|
11786
12031
|
}, [onFeedback]);
|
|
11787
|
-
const reload =
|
|
12032
|
+
const reload = React59.useCallback(async () => {
|
|
11788
12033
|
if (!threadRef.current) return;
|
|
11789
12034
|
setStatus("loading");
|
|
11790
12035
|
try {
|
|
@@ -11822,11 +12067,11 @@ var ChatKit = {
|
|
|
11822
12067
|
};
|
|
11823
12068
|
|
|
11824
12069
|
// src/components/chat/ChatTranscript.tsx
|
|
11825
|
-
import * as
|
|
12070
|
+
import * as React61 from "react";
|
|
11826
12071
|
|
|
11827
12072
|
// src/components/chat/ChatTurn.tsx
|
|
11828
|
-
import * as
|
|
11829
|
-
import { jsx as
|
|
12073
|
+
import * as React60 from "react";
|
|
12074
|
+
import { jsx as jsx91, jsxs as jsxs82 } from "react/jsx-runtime";
|
|
11830
12075
|
function JsonView({ value }) {
|
|
11831
12076
|
let text;
|
|
11832
12077
|
try {
|
|
@@ -11834,67 +12079,67 @@ function JsonView({ value }) {
|
|
|
11834
12079
|
} catch (e) {
|
|
11835
12080
|
text = String(value);
|
|
11836
12081
|
}
|
|
11837
|
-
return /* @__PURE__ */
|
|
12082
|
+
return /* @__PURE__ */ jsx91(CodeBlock, { code: text, language: "json", collapseAfter: 18 });
|
|
11838
12083
|
}
|
|
11839
12084
|
function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
11840
12085
|
if (!packet) return null;
|
|
11841
12086
|
const s = schema || {};
|
|
11842
12087
|
const invalid = packet.valid === false;
|
|
11843
12088
|
const title = s.heading || packet.type;
|
|
11844
|
-
return /* @__PURE__ */
|
|
11845
|
-
/* @__PURE__ */
|
|
11846
|
-
/* @__PURE__ */
|
|
11847
|
-
/* @__PURE__ */
|
|
11848
|
-
packet.repaired ? /* @__PURE__ */
|
|
11849
|
-
invalid ? /* @__PURE__ */
|
|
12089
|
+
return /* @__PURE__ */ jsxs82("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
|
|
12090
|
+
/* @__PURE__ */ jsxs82("header", { className: "fdc-packet-head", children: [
|
|
12091
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-" + (s.icon || "package"), "aria-hidden": "true" }),
|
|
12092
|
+
/* @__PURE__ */ jsx91("span", { className: "fdc-packet-title", title: truncationTitle(title), children: title }),
|
|
12093
|
+
packet.repaired ? /* @__PURE__ */ jsx91("span", { className: "fdc-packet-badge", children: "Repaired" }) : null,
|
|
12094
|
+
invalid ? /* @__PURE__ */ jsx91("span", { className: "fdc-packet-badge is-danger", children: "Invalid" }) : null
|
|
11850
12095
|
] }),
|
|
11851
|
-
invalid ? /* @__PURE__ */
|
|
11852
|
-
/* @__PURE__ */
|
|
11853
|
-
/* @__PURE__ */
|
|
11854
|
-
] }) : /* @__PURE__ */
|
|
11855
|
-
!invalid && onApply ? /* @__PURE__ */
|
|
11856
|
-
packet.repaired ? /* @__PURE__ */
|
|
11857
|
-
/* @__PURE__ */
|
|
11858
|
-
/* @__PURE__ */
|
|
12096
|
+
invalid ? /* @__PURE__ */ jsxs82("div", { className: "fdc-packet-alert", role: "alert", children: [
|
|
12097
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
12098
|
+
/* @__PURE__ */ jsx91("span", { children: packet.error || "This result failed validation and can\u2019t be applied." })
|
|
12099
|
+
] }) : /* @__PURE__ */ jsx91("div", { className: "fdc-packet-body", children: render ? render(packet) : /* @__PURE__ */ jsx91(JsonView, { value: packet.payload }) }),
|
|
12100
|
+
!invalid && onApply ? /* @__PURE__ */ jsxs82("footer", { className: "fdc-packet-foot", children: [
|
|
12101
|
+
packet.repaired ? /* @__PURE__ */ jsx91("span", { className: "fdc-packet-note", children: "Corrected by the backend after a first attempt." }) : /* @__PURE__ */ jsx91("span", {}),
|
|
12102
|
+
/* @__PURE__ */ jsxs82("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
|
|
12103
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-" + (applied ? "check" : "arrow-square-in"), "aria-hidden": "true" }),
|
|
11859
12104
|
applied ? "Applied" : s.applyLabel || "Apply"
|
|
11860
12105
|
] })
|
|
11861
12106
|
] }) : null
|
|
11862
12107
|
] });
|
|
11863
12108
|
}
|
|
11864
12109
|
function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
11865
|
-
const [open2, setOpen] =
|
|
12110
|
+
const [open2, setOpen] = React60.useState(defaultOpen);
|
|
11866
12111
|
if (!text) return null;
|
|
11867
|
-
return /* @__PURE__ */
|
|
11868
|
-
/* @__PURE__ */
|
|
11869
|
-
/* @__PURE__ */
|
|
11870
|
-
/* @__PURE__ */
|
|
11871
|
-
streaming ? /* @__PURE__ */
|
|
11872
|
-
/* @__PURE__ */
|
|
11873
|
-
/* @__PURE__ */
|
|
11874
|
-
/* @__PURE__ */
|
|
12112
|
+
return /* @__PURE__ */ jsxs82("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
|
|
12113
|
+
/* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
12114
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-brain", "aria-hidden": "true" }),
|
|
12115
|
+
/* @__PURE__ */ jsx91("span", { children: streaming ? "Thinking" : durationMs ? "Thought for " + formatDuration(durationMs) : "Thought process" }),
|
|
12116
|
+
streaming ? /* @__PURE__ */ jsxs82("span", { className: "fdc-dots", "aria-hidden": "true", children: [
|
|
12117
|
+
/* @__PURE__ */ jsx91("span", {}),
|
|
12118
|
+
/* @__PURE__ */ jsx91("span", {}),
|
|
12119
|
+
/* @__PURE__ */ jsx91("span", {})
|
|
11875
12120
|
] }) : null,
|
|
11876
|
-
/* @__PURE__ */
|
|
12121
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-caret-" + (open2 ? "up" : "down"), "aria-hidden": "true" })
|
|
11877
12122
|
] }),
|
|
11878
|
-
open2 ? /* @__PURE__ */
|
|
12123
|
+
open2 ? /* @__PURE__ */ jsx91("div", { className: "fdc-think-body", children: text }) : null
|
|
11879
12124
|
] });
|
|
11880
12125
|
}
|
|
11881
12126
|
function Citations({ items = [], onOpen }) {
|
|
11882
|
-
const [open2, setOpen] =
|
|
12127
|
+
const [open2, setOpen] = React60.useState(false);
|
|
11883
12128
|
if (!items.length) return null;
|
|
11884
|
-
return /* @__PURE__ */
|
|
11885
|
-
/* @__PURE__ */
|
|
11886
|
-
/* @__PURE__ */
|
|
11887
|
-
/* @__PURE__ */
|
|
12129
|
+
return /* @__PURE__ */ jsxs82("div", { className: "fdc-cites", children: [
|
|
12130
|
+
/* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
12131
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-quotes", "aria-hidden": "true" }),
|
|
12132
|
+
/* @__PURE__ */ jsxs82("span", { children: [
|
|
11888
12133
|
items.length,
|
|
11889
12134
|
" source",
|
|
11890
12135
|
items.length === 1 ? "" : "s"
|
|
11891
12136
|
] }),
|
|
11892
|
-
/* @__PURE__ */
|
|
12137
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-caret-" + (open2 ? "up" : "down"), "aria-hidden": "true" })
|
|
11893
12138
|
] }),
|
|
11894
|
-
open2 ? /* @__PURE__ */
|
|
11895
|
-
/* @__PURE__ */
|
|
11896
|
-
c.url ? /* @__PURE__ */
|
|
11897
|
-
c.detail ? /* @__PURE__ */
|
|
12139
|
+
open2 ? /* @__PURE__ */ jsx91("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs82("li", { children: [
|
|
12140
|
+
/* @__PURE__ */ jsx91("span", { className: "fdc-cite-n fd-tabular", children: c.marker || i + 1 }),
|
|
12141
|
+
c.url ? /* @__PURE__ */ jsx91("a", { href: c.url, target: "_blank", rel: "noopener noreferrer", onClick: onOpen ? (e) => onOpen(c, e) : void 0, children: c.title || c.url }) : /* @__PURE__ */ jsx91("span", { children: c.title || "Source" }),
|
|
12142
|
+
c.detail ? /* @__PURE__ */ jsx91("span", { className: "fdc-cite-detail", children: c.detail }) : null
|
|
11898
12143
|
] }, c.id || i)) }) : null
|
|
11899
12144
|
] });
|
|
11900
12145
|
}
|
|
@@ -11905,29 +12150,29 @@ function clampText(text, max) {
|
|
|
11905
12150
|
return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
11906
12151
|
}
|
|
11907
12152
|
function MessageBody({ message: m, ctx }) {
|
|
11908
|
-
const [expanded, setExpanded] =
|
|
12153
|
+
const [expanded, setExpanded] = React60.useState(false);
|
|
11909
12154
|
const isUser = m.role === "user";
|
|
11910
12155
|
const raw = m.text || "";
|
|
11911
12156
|
const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
|
|
11912
12157
|
const body = clamped != null ? clamped : raw;
|
|
11913
12158
|
const showMd = ctx.markdown && !isUser;
|
|
11914
|
-
return /* @__PURE__ */
|
|
11915
|
-
m.thinking && ctx.showThinking ? /* @__PURE__ */
|
|
11916
|
-
m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */
|
|
11917
|
-
body ? /* @__PURE__ */
|
|
11918
|
-
showMd ? /* @__PURE__ */
|
|
11919
|
-
m.streaming ? /* @__PURE__ */
|
|
12159
|
+
return /* @__PURE__ */ jsxs82("div", { className: "fdc-body", children: [
|
|
12160
|
+
m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx91(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
|
|
12161
|
+
m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx91(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), dense: true }) : null,
|
|
12162
|
+
body ? /* @__PURE__ */ jsxs82("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
|
|
12163
|
+
showMd ? /* @__PURE__ */ jsx91(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx91("div", { className: "fdc-plain", children: body }),
|
|
12164
|
+
m.streaming ? /* @__PURE__ */ jsx91("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
|
|
11920
12165
|
] }) : null,
|
|
11921
|
-
clamped != null ? /* @__PURE__ */
|
|
11922
|
-
/* @__PURE__ */
|
|
12166
|
+
clamped != null ? /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
|
|
12167
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-caret-down", "aria-hidden": "true" }),
|
|
11923
12168
|
"Show more",
|
|
11924
|
-
/* @__PURE__ */
|
|
11925
|
-
] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */
|
|
11926
|
-
/* @__PURE__ */
|
|
12169
|
+
/* @__PURE__ */ jsx91("span", { className: "fdc-more-len fd-tabular", children: raw.length < 2e3 ? raw.length.toLocaleString() + " characters" : Math.round(raw.length / 100) / 10 + "k characters" })
|
|
12170
|
+
] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
|
|
12171
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-caret-up", "aria-hidden": "true" }),
|
|
11927
12172
|
"Show less"
|
|
11928
12173
|
] }) : null,
|
|
11929
|
-
m.attachments && m.attachments.length ? /* @__PURE__ */
|
|
11930
|
-
m.packet ? /* @__PURE__ */
|
|
12174
|
+
m.attachments && m.attachments.length ? /* @__PURE__ */ jsx91(FileGrid, { files: m.attachments, onOpen: ctx.onOpenAttachment, tiles: true, maxHeight: ctx.attachmentHeight || 220, compact: ctx.narrow }) : null,
|
|
12175
|
+
m.packet ? /* @__PURE__ */ jsx91(
|
|
11931
12176
|
PacketCard,
|
|
11932
12177
|
{
|
|
11933
12178
|
packet: m.packet,
|
|
@@ -11937,44 +12182,44 @@ function MessageBody({ message: m, ctx }) {
|
|
|
11937
12182
|
applied: ctx.appliedPackets && ctx.appliedPackets[m.id]
|
|
11938
12183
|
}
|
|
11939
12184
|
) : null,
|
|
11940
|
-
m.citations && m.citations.length ? /* @__PURE__ */
|
|
11941
|
-
m.working ? /* @__PURE__ */
|
|
11942
|
-
/* @__PURE__ */
|
|
11943
|
-
/* @__PURE__ */
|
|
11944
|
-
/* @__PURE__ */
|
|
11945
|
-
/* @__PURE__ */
|
|
12185
|
+
m.citations && m.citations.length ? /* @__PURE__ */ jsx91(Citations, { items: m.citations, onOpen: ctx.onOpenCitation }) : null,
|
|
12186
|
+
m.working ? /* @__PURE__ */ jsxs82("div", { className: "fdc-working", role: "status", children: [
|
|
12187
|
+
/* @__PURE__ */ jsxs82("span", { className: "fdc-dots", "aria-hidden": "true", children: [
|
|
12188
|
+
/* @__PURE__ */ jsx91("span", {}),
|
|
12189
|
+
/* @__PURE__ */ jsx91("span", {}),
|
|
12190
|
+
/* @__PURE__ */ jsx91("span", {})
|
|
11946
12191
|
] }),
|
|
11947
|
-
/* @__PURE__ */
|
|
12192
|
+
/* @__PURE__ */ jsxs82("span", { className: "fdc-working-label", children: [
|
|
11948
12193
|
m.resumed ? "Resuming" : "Working",
|
|
11949
|
-
m.job && m.job.status ? /* @__PURE__ */
|
|
12194
|
+
m.job && m.job.status ? /* @__PURE__ */ jsxs82("span", { className: "fdc-working-job", children: [
|
|
11950
12195
|
" \xB7 ",
|
|
11951
12196
|
m.job.status
|
|
11952
12197
|
] }) : null,
|
|
11953
|
-
m.job && m.job.detail ? /* @__PURE__ */
|
|
12198
|
+
m.job && m.job.detail ? /* @__PURE__ */ jsxs82("span", { className: "fdc-working-job", children: [
|
|
11954
12199
|
" \xB7 ",
|
|
11955
12200
|
m.job.detail
|
|
11956
12201
|
] }) : null
|
|
11957
12202
|
] }),
|
|
11958
|
-
m.jobId ? /* @__PURE__ */
|
|
12203
|
+
m.jobId ? /* @__PURE__ */ jsx91("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
|
|
11959
12204
|
] }) : null,
|
|
11960
|
-
m.stopped ? /* @__PURE__ */
|
|
11961
|
-
/* @__PURE__ */
|
|
12205
|
+
m.stopped ? /* @__PURE__ */ jsxs82("div", { className: "fdc-stopped", children: [
|
|
12206
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
|
|
11962
12207
|
"Stopped"
|
|
11963
12208
|
] }) : null,
|
|
11964
|
-
m.error ? /* @__PURE__ */
|
|
11965
|
-
/* @__PURE__ */
|
|
11966
|
-
/* @__PURE__ */
|
|
11967
|
-
m.retryable && ctx.onRetry ? /* @__PURE__ */
|
|
11968
|
-
/* @__PURE__ */
|
|
12209
|
+
m.error ? /* @__PURE__ */ jsxs82("div", { className: "fdc-error", role: "alert", children: [
|
|
12210
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
12211
|
+
/* @__PURE__ */ jsx91("span", { className: "fdc-error-text", children: ctx.errorCopy ? ctx.errorCopy(m.error) : m.error }),
|
|
12212
|
+
m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
|
|
12213
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
|
|
11969
12214
|
"Retry"
|
|
11970
12215
|
] }) : null
|
|
11971
12216
|
] }) : null
|
|
11972
12217
|
] });
|
|
11973
12218
|
}
|
|
11974
12219
|
function useCopyRun() {
|
|
11975
|
-
const [done, setDone] =
|
|
11976
|
-
const t =
|
|
11977
|
-
|
|
12220
|
+
const [done, setDone] = React60.useState(false);
|
|
12221
|
+
const t = React60.useRef(null);
|
|
12222
|
+
React60.useEffect(() => () => {
|
|
11978
12223
|
if (t.current) clearTimeout(t.current);
|
|
11979
12224
|
}, []);
|
|
11980
12225
|
return [done, (text) => {
|
|
@@ -11994,16 +12239,16 @@ function RunActions({ group, ctx }) {
|
|
|
11994
12239
|
const isAssistant = group.role === "assistant";
|
|
11995
12240
|
const fb = last.feedback;
|
|
11996
12241
|
if (!ctx.messageActions) return null;
|
|
11997
|
-
return /* @__PURE__ */
|
|
11998
|
-
/* @__PURE__ */
|
|
11999
|
-
/* @__PURE__ */
|
|
12000
|
-
/* @__PURE__ */
|
|
12242
|
+
return /* @__PURE__ */ jsxs82("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
|
|
12243
|
+
/* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
|
|
12244
|
+
/* @__PURE__ */ jsx91("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
|
|
12245
|
+
/* @__PURE__ */ jsx91("span", { className: "fdc-act-label", children: copied ? "Copied" : "Copy" })
|
|
12001
12246
|
] }),
|
|
12002
|
-
isAssistant && ctx.onRetry ? /* @__PURE__ */
|
|
12003
|
-
group.role === "user" && ctx.onEdit ? /* @__PURE__ */
|
|
12004
|
-
isAssistant && ctx.onFeedback ? /* @__PURE__ */
|
|
12005
|
-
/* @__PURE__ */
|
|
12006
|
-
/* @__PURE__ */
|
|
12247
|
+
isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx91("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx91("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
|
|
12248
|
+
group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx91("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx91("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
|
|
12249
|
+
isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs82(React60.Fragment, { children: [
|
|
12250
|
+
/* @__PURE__ */ jsx91("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__ */ jsx91("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
|
|
12251
|
+
/* @__PURE__ */ jsx91("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__ */ jsx91("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
|
|
12007
12252
|
] }) : null,
|
|
12008
12253
|
ctx.extraActions ? ctx.extraActions(group) : null
|
|
12009
12254
|
] });
|
|
@@ -12013,22 +12258,22 @@ function ChatTurn({ group, ctx }) {
|
|
|
12013
12258
|
const name = isUser ? ctx.userName : group.author || ctx.assistantName;
|
|
12014
12259
|
const avatar = isUser ? ctx.userAvatar : ctx.assistantAvatar;
|
|
12015
12260
|
const stamp = group.messages[0].timestamp;
|
|
12016
|
-
return /* @__PURE__ */
|
|
12017
|
-
/* @__PURE__ */
|
|
12018
|
-
ctx.showAvatars ? /* @__PURE__ */
|
|
12019
|
-
/* @__PURE__ */
|
|
12020
|
-
stamp ? /* @__PURE__ */
|
|
12021
|
-
group.messages.some((m) => m.model) ? /* @__PURE__ */
|
|
12261
|
+
return /* @__PURE__ */ jsxs82("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
|
|
12262
|
+
/* @__PURE__ */ jsxs82("div", { className: "fdc-turn-head", children: [
|
|
12263
|
+
ctx.showAvatars ? /* @__PURE__ */ jsx91("span", { className: "fdc-avatar is-" + group.role, "aria-hidden": "true", children: avatar ? /* @__PURE__ */ jsx91("img", { src: avatar, alt: "" }) : isUser ? /* @__PURE__ */ jsx91("span", { className: "fdc-avatar-txt", children: (name || "You").slice(0, 1).toUpperCase() }) : /* @__PURE__ */ jsx91("i", { className: "ph ph-" + (ctx.assistantIcon || "sparkle") }) }) : null,
|
|
12264
|
+
/* @__PURE__ */ jsx91("span", { className: "fdc-who", children: name }),
|
|
12265
|
+
stamp ? /* @__PURE__ */ jsx91(RelativeTime, { className: "fdc-when", value: stamp }) : null,
|
|
12266
|
+
group.messages.some((m) => m.model) ? /* @__PURE__ */ jsx91("span", { className: "fdc-turn-model", children: group.messages.find((m) => m.model).model }) : null
|
|
12022
12267
|
] }),
|
|
12023
|
-
/* @__PURE__ */
|
|
12024
|
-
group.messages.map((m) => /* @__PURE__ */
|
|
12025
|
-
/* @__PURE__ */
|
|
12268
|
+
/* @__PURE__ */ jsxs82("div", { className: "fdc-turn-body", children: [
|
|
12269
|
+
group.messages.map((m) => /* @__PURE__ */ jsx91("div", { className: "fdc-msg" + (m.pending ? " is-pending" : ""), children: /* @__PURE__ */ jsx91(MessageBody, { message: m, ctx }) }, m.id)),
|
|
12270
|
+
/* @__PURE__ */ jsx91(RunActions, { group, ctx })
|
|
12026
12271
|
] })
|
|
12027
12272
|
] });
|
|
12028
12273
|
}
|
|
12029
12274
|
|
|
12030
12275
|
// src/components/chat/ChatTranscript.tsx
|
|
12031
|
-
import { jsx as
|
|
12276
|
+
import { jsx as jsx92, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
12032
12277
|
var GROUP_WINDOW = 6e4;
|
|
12033
12278
|
var STICK_PX = 100;
|
|
12034
12279
|
function groupMessages(list) {
|
|
@@ -12061,25 +12306,25 @@ function dayLabel(key) {
|
|
|
12061
12306
|
}
|
|
12062
12307
|
function Suggestions({ items = [], onPick }) {
|
|
12063
12308
|
if (!items.length) return null;
|
|
12064
|
-
return /* @__PURE__ */
|
|
12309
|
+
return /* @__PURE__ */ jsx92("div", { className: "fdc-suggest", children: items.map((s, i) => {
|
|
12065
12310
|
const it = typeof s === "string" ? { label: s, text: s } : s;
|
|
12066
|
-
return /* @__PURE__ */
|
|
12067
|
-
it.icon ? /* @__PURE__ */
|
|
12068
|
-
/* @__PURE__ */
|
|
12069
|
-
/* @__PURE__ */
|
|
12070
|
-
it.description ? /* @__PURE__ */
|
|
12311
|
+
return /* @__PURE__ */ jsxs83("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
|
|
12312
|
+
it.icon ? /* @__PURE__ */ jsx92("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) : null,
|
|
12313
|
+
/* @__PURE__ */ jsxs83("span", { className: "fdc-suggest-text", children: [
|
|
12314
|
+
/* @__PURE__ */ jsx92("span", { className: "fdc-suggest-label", children: it.label }),
|
|
12315
|
+
it.description ? /* @__PURE__ */ jsx92("span", { className: "fdc-suggest-desc", children: it.description }) : null
|
|
12071
12316
|
] }),
|
|
12072
|
-
/* @__PURE__ */
|
|
12317
|
+
/* @__PURE__ */ jsx92("i", { className: "ph ph-arrow-up-right fdc-suggest-go", "aria-hidden": "true" })
|
|
12073
12318
|
] }, it.id || i);
|
|
12074
12319
|
}) });
|
|
12075
12320
|
}
|
|
12076
12321
|
function LoadingTurns() {
|
|
12077
|
-
return /* @__PURE__ */
|
|
12078
|
-
/* @__PURE__ */
|
|
12079
|
-
/* @__PURE__ */
|
|
12080
|
-
/* @__PURE__ */
|
|
12081
|
-
/* @__PURE__ */
|
|
12082
|
-
/* @__PURE__ */
|
|
12322
|
+
return /* @__PURE__ */ jsx92("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs83("div", { className: "fdc-skel-turn", children: [
|
|
12323
|
+
/* @__PURE__ */ jsx92("div", { className: "fd-skel fd-skel-circle", style: { width: 22, height: 22 } }),
|
|
12324
|
+
/* @__PURE__ */ jsxs83("div", { className: "fdc-skel-lines", children: [
|
|
12325
|
+
/* @__PURE__ */ jsx92("div", { className: "fd-skel", style: { width: i ? "62%" : "44%", height: 11 } }),
|
|
12326
|
+
/* @__PURE__ */ jsx92("div", { className: "fd-skel", style: { width: i ? "94%" : "78%", height: 11 } }),
|
|
12327
|
+
/* @__PURE__ */ jsx92("div", { className: "fd-skel", style: { width: i ? "71%" : "56%", height: 11 } })
|
|
12083
12328
|
] })
|
|
12084
12329
|
] }, i)) });
|
|
12085
12330
|
}
|
|
@@ -12096,10 +12341,10 @@ function ChatTranscript({
|
|
|
12096
12341
|
renderEmpty,
|
|
12097
12342
|
className = ""
|
|
12098
12343
|
}) {
|
|
12099
|
-
const scroller =
|
|
12100
|
-
const stick =
|
|
12101
|
-
const [pill, setPill] =
|
|
12102
|
-
const seen =
|
|
12344
|
+
const scroller = React61.useRef(null);
|
|
12345
|
+
const stick = React61.useRef(true);
|
|
12346
|
+
const [pill, setPill] = React61.useState(0);
|
|
12347
|
+
const seen = React61.useRef(0);
|
|
12103
12348
|
const toBottom = (smooth) => {
|
|
12104
12349
|
const el = scroller.current;
|
|
12105
12350
|
if (!el) return;
|
|
@@ -12118,7 +12363,7 @@ function ChatTranscript({
|
|
|
12118
12363
|
seen.current = messages.length;
|
|
12119
12364
|
}
|
|
12120
12365
|
};
|
|
12121
|
-
|
|
12366
|
+
React61.useLayoutEffect(() => {
|
|
12122
12367
|
const el = scroller.current;
|
|
12123
12368
|
if (!el) return;
|
|
12124
12369
|
if (stick.current) {
|
|
@@ -12126,7 +12371,7 @@ function ChatTranscript({
|
|
|
12126
12371
|
seen.current = messages.length;
|
|
12127
12372
|
} else setPill(Math.max(0, messages.length - seen.current));
|
|
12128
12373
|
}, [messages]);
|
|
12129
|
-
|
|
12374
|
+
React61.useEffect(() => {
|
|
12130
12375
|
const el = scroller.current;
|
|
12131
12376
|
const inner = el && el.firstChild;
|
|
12132
12377
|
if (!el || !inner || typeof ResizeObserver === "undefined") return;
|
|
@@ -12136,38 +12381,38 @@ function ChatTranscript({
|
|
|
12136
12381
|
ro.observe(inner);
|
|
12137
12382
|
return () => ro.disconnect();
|
|
12138
12383
|
}, []);
|
|
12139
|
-
const groups =
|
|
12384
|
+
const groups = React61.useMemo(() => groupMessages(messages), [messages]);
|
|
12140
12385
|
const empty = !messages.length && status === "ready";
|
|
12141
|
-
return /* @__PURE__ */
|
|
12142
|
-
/* @__PURE__ */
|
|
12143
|
-
status === "loading" || status === "resolving" ? /* @__PURE__ */
|
|
12144
|
-
status === "disconnected" ? /* @__PURE__ */
|
|
12145
|
-
/* @__PURE__ */
|
|
12146
|
-
/* @__PURE__ */
|
|
12147
|
-
/* @__PURE__ */
|
|
12148
|
-
ctx.onReconnect ? /* @__PURE__ */
|
|
12149
|
-
/* @__PURE__ */
|
|
12386
|
+
return /* @__PURE__ */ jsxs83("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
|
|
12387
|
+
/* @__PURE__ */ jsxs83("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
|
|
12388
|
+
status === "loading" || status === "resolving" ? /* @__PURE__ */ jsx92(LoadingTurns, {}) : null,
|
|
12389
|
+
status === "disconnected" ? /* @__PURE__ */ jsxs83("div", { className: "fdc-dead", children: [
|
|
12390
|
+
/* @__PURE__ */ jsx92("span", { className: "fdc-dead-icon", children: /* @__PURE__ */ jsx92("i", { className: "ph ph-plugs", "aria-hidden": "true" }) }),
|
|
12391
|
+
/* @__PURE__ */ jsx92("h3", { className: "fdc-dead-title", children: ctx.deadTitle || "The assistant isn\u2019t reachable" }),
|
|
12392
|
+
/* @__PURE__ */ jsx92("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." }),
|
|
12393
|
+
ctx.onReconnect ? /* @__PURE__ */ jsxs83("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
|
|
12394
|
+
/* @__PURE__ */ jsx92("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
|
|
12150
12395
|
"Try again"
|
|
12151
12396
|
] }) : null
|
|
12152
12397
|
] }) : null,
|
|
12153
|
-
empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */
|
|
12154
|
-
/* @__PURE__ */
|
|
12155
|
-
/* @__PURE__ */
|
|
12156
|
-
emptyDescription ? /* @__PURE__ */
|
|
12157
|
-
/* @__PURE__ */
|
|
12398
|
+
empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs83("div", { className: "fdc-empty", children: [
|
|
12399
|
+
/* @__PURE__ */ jsx92("span", { className: "fdc-empty-icon", children: /* @__PURE__ */ jsx92("i", { className: "ph ph-" + emptyIcon, "aria-hidden": "true" }) }),
|
|
12400
|
+
/* @__PURE__ */ jsx92("h3", { className: "fdc-empty-title", children: emptyTitle }),
|
|
12401
|
+
emptyDescription ? /* @__PURE__ */ jsx92("p", { className: "fdc-empty-body", children: emptyDescription }) : null,
|
|
12402
|
+
/* @__PURE__ */ jsx92(Suggestions, { items: suggestions, onPick })
|
|
12158
12403
|
] }) : null,
|
|
12159
12404
|
groups.map((g, i) => {
|
|
12160
12405
|
const prev = groups[i - 1];
|
|
12161
12406
|
const k = dayKey(g.messages[0].timestamp);
|
|
12162
12407
|
const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
|
|
12163
|
-
return /* @__PURE__ */
|
|
12164
|
-
showDay ? /* @__PURE__ */
|
|
12165
|
-
/* @__PURE__ */
|
|
12408
|
+
return /* @__PURE__ */ jsxs83(React61.Fragment, { children: [
|
|
12409
|
+
showDay ? /* @__PURE__ */ jsx92("div", { className: "fdc-day", children: /* @__PURE__ */ jsx92("span", { children: dayLabel(k) }) }) : null,
|
|
12410
|
+
/* @__PURE__ */ jsx92(ChatTurn, { group: g, ctx })
|
|
12166
12411
|
] }, g.key || i);
|
|
12167
12412
|
})
|
|
12168
12413
|
] }),
|
|
12169
|
-
pill ? /* @__PURE__ */
|
|
12170
|
-
/* @__PURE__ */
|
|
12414
|
+
pill ? /* @__PURE__ */ jsxs83("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
|
|
12415
|
+
/* @__PURE__ */ jsx92("i", { className: "ph ph-arrow-down", "aria-hidden": "true" }),
|
|
12171
12416
|
pill,
|
|
12172
12417
|
" new message",
|
|
12173
12418
|
pill === 1 ? "" : "s"
|
|
@@ -12177,8 +12422,8 @@ function ChatTranscript({
|
|
|
12177
12422
|
var TranscriptKit = { groupMessages };
|
|
12178
12423
|
|
|
12179
12424
|
// src/components/chat/ChatComposer.tsx
|
|
12180
|
-
import * as
|
|
12181
|
-
import { jsx as
|
|
12425
|
+
import * as React62 from "react";
|
|
12426
|
+
import { jsx as jsx93, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
12182
12427
|
function ChatComposer({
|
|
12183
12428
|
onSubmit,
|
|
12184
12429
|
onStop,
|
|
@@ -12205,17 +12450,17 @@ function ChatComposer({
|
|
|
12205
12450
|
onReject,
|
|
12206
12451
|
onOpenAttachment
|
|
12207
12452
|
}) {
|
|
12208
|
-
const [text, setText] =
|
|
12209
|
-
const [trigger, setTrigger] =
|
|
12210
|
-
const [mentionItems, setMentionItems] =
|
|
12211
|
-
const [listening, setListening] =
|
|
12212
|
-
const [notice, setNotice] =
|
|
12213
|
-
const editor =
|
|
12214
|
-
const wrap =
|
|
12215
|
-
const stopVoice =
|
|
12453
|
+
const [text, setText] = React62.useState(draft || "");
|
|
12454
|
+
const [trigger, setTrigger] = React62.useState(null);
|
|
12455
|
+
const [mentionItems, setMentionItems] = React62.useState([]);
|
|
12456
|
+
const [listening, setListening] = React62.useState(false);
|
|
12457
|
+
const [notice, setNotice] = React62.useState(null);
|
|
12458
|
+
const editor = React62.useRef(null);
|
|
12459
|
+
const wrap = React62.useRef(null);
|
|
12460
|
+
const stopVoice = React62.useRef(null);
|
|
12216
12461
|
const staged = useStagedFiles(fileUploadHandler, { onError: () => {
|
|
12217
12462
|
} });
|
|
12218
|
-
|
|
12463
|
+
React62.useEffect(() => {
|
|
12219
12464
|
if (draft != null && draft !== text) setText(draft);
|
|
12220
12465
|
}, [draft]);
|
|
12221
12466
|
const change = (v) => {
|
|
@@ -12251,7 +12496,7 @@ function ChatComposer({
|
|
|
12251
12496
|
e.preventDefault();
|
|
12252
12497
|
staged.add(found.files);
|
|
12253
12498
|
};
|
|
12254
|
-
|
|
12499
|
+
React62.useEffect(() => {
|
|
12255
12500
|
if (!trigger || trigger.type !== "mention" || !mentionSources) {
|
|
12256
12501
|
setMentionItems([]);
|
|
12257
12502
|
return;
|
|
@@ -12269,7 +12514,7 @@ function ChatComposer({
|
|
|
12269
12514
|
const q = (trigger.query || "").toLowerCase();
|
|
12270
12515
|
setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
|
|
12271
12516
|
}, [trigger, mentionSources]);
|
|
12272
|
-
const slashItems =
|
|
12517
|
+
const slashItems = React62.useMemo(() => {
|
|
12273
12518
|
if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
|
|
12274
12519
|
const q = (trigger.query || "").toLowerCase();
|
|
12275
12520
|
return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
|
|
@@ -12283,7 +12528,7 @@ function ChatComposer({
|
|
|
12283
12528
|
description: it.description,
|
|
12284
12529
|
icon: it.icon,
|
|
12285
12530
|
meta: mention.meta,
|
|
12286
|
-
shortcut: slash.shortcut ? /* @__PURE__ */
|
|
12531
|
+
shortcut: slash.shortcut ? /* @__PURE__ */ jsx93(KeyHint, { keys: slash.shortcut, size: "sm" }) : void 0,
|
|
12287
12532
|
onSelect: () => {
|
|
12288
12533
|
const insert = trigger.type === "slash" ? slash.immediate ? "/" + slash.id : "/" + slash.id + " " : "@" + (mention.value || mention.label) + " ";
|
|
12289
12534
|
editor.current && editor.current.replaceRange(trigger.from, trigger.to, insert);
|
|
@@ -12342,14 +12587,14 @@ function ChatComposer({
|
|
|
12342
12587
|
stopVoice.current = typeof res === "function" ? res : () => {
|
|
12343
12588
|
};
|
|
12344
12589
|
};
|
|
12345
|
-
return /* @__PURE__ */
|
|
12346
|
-
queue.length ? /* @__PURE__ */
|
|
12347
|
-
/* @__PURE__ */
|
|
12348
|
-
/* @__PURE__ */
|
|
12349
|
-
onRemoveQueued ? /* @__PURE__ */
|
|
12590
|
+
return /* @__PURE__ */ jsxs84("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
|
|
12591
|
+
queue.length ? /* @__PURE__ */ jsx93("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs84("div", { className: "fdc-queue-row", children: [
|
|
12592
|
+
/* @__PURE__ */ jsx93("i", { className: "ph ph-clock-countdown", "aria-hidden": "true" }),
|
|
12593
|
+
/* @__PURE__ */ jsx93("span", { className: "fdc-queue-text", title: truncationTitle(q.text || (q.attachments ? q.attachments.length + " file(s)" : "")), children: q.text || (q.attachments ? q.attachments.length + " file(s)" : "") }),
|
|
12594
|
+
onRemoveQueued ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-queue-x", onClick: () => onRemoveQueued(q.id), "aria-label": "Remove queued message", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
|
|
12350
12595
|
] }, q.id)) }) : null,
|
|
12351
12596
|
sessionBar,
|
|
12352
|
-
/* @__PURE__ */
|
|
12597
|
+
/* @__PURE__ */ jsx93(
|
|
12353
12598
|
Dropzone,
|
|
12354
12599
|
{
|
|
12355
12600
|
className: "fdc-field",
|
|
@@ -12363,9 +12608,9 @@ function ChatComposer({
|
|
|
12363
12608
|
disabled: !fileUploadHandler || disabled,
|
|
12364
12609
|
label: "Drop to attach",
|
|
12365
12610
|
hint: acceptFiles ? acceptFiles.replace(/,/g, " \xB7 ") : void 0,
|
|
12366
|
-
children: /* @__PURE__ */
|
|
12367
|
-
staged.items.length ? /* @__PURE__ */
|
|
12368
|
-
/* @__PURE__ */
|
|
12611
|
+
children: /* @__PURE__ */ jsxs84("div", { ref: wrap, className: "fdc-field-inner", children: [
|
|
12612
|
+
staged.items.length ? /* @__PURE__ */ jsx93("div", { className: "fdc-staged", children: /* @__PURE__ */ jsx93(FileStrip, { files: staged.items, size: narrow ? 60 : 68, onRemove: staged.remove, onRetry: staged.retry, onOpen: onOpenAttachment }) }) : null,
|
|
12613
|
+
/* @__PURE__ */ jsx93(
|
|
12369
12614
|
MarkdownEditor,
|
|
12370
12615
|
{
|
|
12371
12616
|
ref: editor,
|
|
@@ -12384,33 +12629,33 @@ function ChatComposer({
|
|
|
12384
12629
|
ariaLabel: "Message"
|
|
12385
12630
|
}
|
|
12386
12631
|
),
|
|
12387
|
-
/* @__PURE__ */
|
|
12388
|
-
fileUploadHandler ? /* @__PURE__ */
|
|
12389
|
-
voiceHandler ? /* @__PURE__ */
|
|
12632
|
+
/* @__PURE__ */ jsxs84("div", { className: "fdc-tools", children: [
|
|
12633
|
+
fileUploadHandler ? /* @__PURE__ */ jsx93(FilePickButton, { onFiles: staged.add, onReject: (r) => flash(r[0].message), accept: acceptFiles, maxFileSize, label: "Attach files", icon: "plus" }) : null,
|
|
12634
|
+
voiceHandler ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fd-attachbtn" + (listening ? " is-live" : ""), onClick: voice, "aria-pressed": listening, "aria-label": listening ? "Stop dictation" : "Dictate", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-" + (listening ? "waveform" : "microphone"), "aria-hidden": "true" }) }) : null,
|
|
12390
12635
|
toolbarExtras,
|
|
12391
|
-
/* @__PURE__ */
|
|
12392
|
-
maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */
|
|
12636
|
+
/* @__PURE__ */ jsx93("span", { className: "fdc-tools-gap" }),
|
|
12637
|
+
maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs84("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
|
|
12393
12638
|
text.length,
|
|
12394
12639
|
"/",
|
|
12395
12640
|
maxLength
|
|
12396
12641
|
] }) : null,
|
|
12397
|
-
busy ? /* @__PURE__ */
|
|
12398
|
-
/* @__PURE__ */
|
|
12399
|
-
/* @__PURE__ */
|
|
12400
|
-
] }) : /* @__PURE__ */
|
|
12401
|
-
/* @__PURE__ */
|
|
12402
|
-
/* @__PURE__ */
|
|
12642
|
+
busy ? /* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
|
|
12643
|
+
/* @__PURE__ */ jsx93("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
|
|
12644
|
+
/* @__PURE__ */ jsx93("span", { children: "Stop" })
|
|
12645
|
+
] }) : /* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
|
|
12646
|
+
/* @__PURE__ */ jsx93("i", { className: "ph ph-paper-plane-right", "aria-hidden": "true" }),
|
|
12647
|
+
/* @__PURE__ */ jsx93("span", { className: "fdc-send-label", children: "Send" })
|
|
12403
12648
|
] })
|
|
12404
12649
|
] })
|
|
12405
12650
|
] })
|
|
12406
12651
|
}
|
|
12407
12652
|
),
|
|
12408
|
-
notice ? /* @__PURE__ */
|
|
12409
|
-
/* @__PURE__ */
|
|
12653
|
+
notice ? /* @__PURE__ */ jsxs84("div", { className: "fdc-notice", role: "status", children: [
|
|
12654
|
+
/* @__PURE__ */ jsx93("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
12410
12655
|
notice
|
|
12411
12656
|
] }) : null,
|
|
12412
|
-
hint && !notice ? /* @__PURE__ */
|
|
12413
|
-
/* @__PURE__ */
|
|
12657
|
+
hint && !notice ? /* @__PURE__ */ jsx93("div", { className: "fdc-hint", children: hint }) : null,
|
|
12658
|
+
/* @__PURE__ */ jsx93(
|
|
12414
12659
|
Popover,
|
|
12415
12660
|
{
|
|
12416
12661
|
open: menuOpen,
|
|
@@ -12424,12 +12669,12 @@ function ChatComposer({
|
|
|
12424
12669
|
returnFocus: false,
|
|
12425
12670
|
closeOnOutside: true,
|
|
12426
12671
|
label: trigger && trigger.type === "slash" ? "Commands" : "Mentions",
|
|
12427
|
-
children: /* @__PURE__ */
|
|
12672
|
+
children: /* @__PURE__ */ jsx93(
|
|
12428
12673
|
Menu,
|
|
12429
12674
|
{
|
|
12430
12675
|
items: menuItems,
|
|
12431
12676
|
autoFocus: false,
|
|
12432
|
-
header: /* @__PURE__ */
|
|
12677
|
+
header: /* @__PURE__ */ jsx93("div", { className: "fd-pop-group", children: trigger && trigger.type === "slash" ? "Commands" : "Attach context" }),
|
|
12433
12678
|
onClose: () => setTrigger(null)
|
|
12434
12679
|
}
|
|
12435
12680
|
)
|
|
@@ -12439,12 +12684,12 @@ function ChatComposer({
|
|
|
12439
12684
|
}
|
|
12440
12685
|
|
|
12441
12686
|
// src/components/chat/ChatSessionBar.tsx
|
|
12442
|
-
import * as
|
|
12443
|
-
import { jsx as
|
|
12687
|
+
import * as React63 from "react";
|
|
12688
|
+
import { jsx as jsx94, jsxs as jsxs85 } from "react/jsx-runtime";
|
|
12444
12689
|
var compact2 = meterFormats.compact;
|
|
12445
12690
|
function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
|
|
12446
|
-
const [open2, setOpen] =
|
|
12447
|
-
const anchor =
|
|
12691
|
+
const [open2, setOpen] = React63.useState(false);
|
|
12692
|
+
const anchor = React63.useRef(null);
|
|
12448
12693
|
const stats = sessionStats || null;
|
|
12449
12694
|
const cu = contextUsage || null;
|
|
12450
12695
|
const limits = usageLimits || null;
|
|
@@ -12459,9 +12704,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
12459
12704
|
if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
|
|
12460
12705
|
if (cu) bits.push(pct + "% context");
|
|
12461
12706
|
const expandable = !!(cu || limits);
|
|
12462
|
-
return /* @__PURE__ */
|
|
12463
|
-
/* @__PURE__ */
|
|
12464
|
-
/* @__PURE__ */
|
|
12707
|
+
return /* @__PURE__ */ jsxs85(React63.Fragment, { children: [
|
|
12708
|
+
/* @__PURE__ */ jsxs85("div", { className: "fdc-bar", children: [
|
|
12709
|
+
/* @__PURE__ */ jsxs85(
|
|
12465
12710
|
"button",
|
|
12466
12711
|
{
|
|
12467
12712
|
type: "button",
|
|
@@ -12472,15 +12717,15 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
12472
12717
|
"aria-expanded": expandable ? open2 : void 0,
|
|
12473
12718
|
"aria-label": expandable ? "Usage details" : void 0,
|
|
12474
12719
|
children: [
|
|
12475
|
-
cu ? /* @__PURE__ */
|
|
12476
|
-
/* @__PURE__ */
|
|
12477
|
-
expandable ? /* @__PURE__ */
|
|
12720
|
+
cu ? /* @__PURE__ */ jsx94("span", { className: "fdc-bar-mini", "aria-hidden": "true", children: /* @__PURE__ */ jsx94(SegmentedMeter, { total, segments: cu.segments, height: 4, showTotal: false }) }) : null,
|
|
12721
|
+
/* @__PURE__ */ jsx94("span", { className: "fdc-bar-text", title: truncationTitle(bits.join(" \xB7 ")), children: bits.join(" \xB7 ") }),
|
|
12722
|
+
expandable ? /* @__PURE__ */ jsx94("i", { className: "ph ph-caret-right fdc-bar-caret", "aria-hidden": "true" }) : null
|
|
12478
12723
|
]
|
|
12479
12724
|
}
|
|
12480
12725
|
),
|
|
12481
12726
|
extras
|
|
12482
12727
|
] }),
|
|
12483
|
-
/* @__PURE__ */
|
|
12728
|
+
/* @__PURE__ */ jsx94(
|
|
12484
12729
|
Popover,
|
|
12485
12730
|
{
|
|
12486
12731
|
open: open2,
|
|
@@ -12491,15 +12736,15 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
12491
12736
|
maxHeight: 460,
|
|
12492
12737
|
padded: true,
|
|
12493
12738
|
label: "Usage",
|
|
12494
|
-
footer: onClear ? /* @__PURE__ */
|
|
12739
|
+
footer: onClear ? /* @__PURE__ */ jsxs85("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
|
|
12495
12740
|
setOpen(false);
|
|
12496
12741
|
onClear();
|
|
12497
12742
|
}, children: [
|
|
12498
|
-
/* @__PURE__ */
|
|
12743
|
+
/* @__PURE__ */ jsx94("i", { className: "ph ph-trash", "aria-hidden": "true" }),
|
|
12499
12744
|
"Clear conversation"
|
|
12500
12745
|
] }) : void 0,
|
|
12501
|
-
children: /* @__PURE__ */
|
|
12502
|
-
cu ? /* @__PURE__ */
|
|
12746
|
+
children: /* @__PURE__ */ jsxs85("div", { className: "fdc-usage", children: [
|
|
12747
|
+
cu ? /* @__PURE__ */ jsx94("section", { className: "fdc-usage-sec", children: /* @__PURE__ */ jsx94(
|
|
12503
12748
|
SegmentedMeter,
|
|
12504
12749
|
{
|
|
12505
12750
|
total,
|
|
@@ -12511,9 +12756,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
12511
12756
|
remainderLabel: "Free"
|
|
12512
12757
|
}
|
|
12513
12758
|
) }) : null,
|
|
12514
|
-
limits && limits.length ? /* @__PURE__ */
|
|
12515
|
-
/* @__PURE__ */
|
|
12516
|
-
/* @__PURE__ */
|
|
12759
|
+
limits && limits.length ? /* @__PURE__ */ jsxs85("section", { className: "fdc-usage-sec", children: [
|
|
12760
|
+
/* @__PURE__ */ jsx94("h4", { className: "fdc-usage-h", children: "Usage limits" }),
|
|
12761
|
+
/* @__PURE__ */ jsx94("div", { className: "fdc-usage-rows", children: limits.map((l) => /* @__PURE__ */ jsx94(
|
|
12517
12762
|
QuotaRow,
|
|
12518
12763
|
{
|
|
12519
12764
|
label: l.label,
|
|
@@ -12523,25 +12768,25 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
12523
12768
|
l.id
|
|
12524
12769
|
)) })
|
|
12525
12770
|
] }) : null,
|
|
12526
|
-
stats ? /* @__PURE__ */
|
|
12527
|
-
stats.elapsedMs ? /* @__PURE__ */
|
|
12528
|
-
/* @__PURE__ */
|
|
12529
|
-
/* @__PURE__ */
|
|
12771
|
+
stats ? /* @__PURE__ */ jsxs85("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
|
|
12772
|
+
stats.elapsedMs ? /* @__PURE__ */ jsxs85("div", { children: [
|
|
12773
|
+
/* @__PURE__ */ jsx94("span", { children: "Session" }),
|
|
12774
|
+
/* @__PURE__ */ jsx94("b", { className: "fd-tabular", children: formatDuration(stats.elapsedMs) })
|
|
12530
12775
|
] }) : null,
|
|
12531
|
-
stats.tokens ? /* @__PURE__ */
|
|
12532
|
-
/* @__PURE__ */
|
|
12533
|
-
/* @__PURE__ */
|
|
12776
|
+
stats.tokens ? /* @__PURE__ */ jsxs85("div", { children: [
|
|
12777
|
+
/* @__PURE__ */ jsx94("span", { children: "Tokens" }),
|
|
12778
|
+
/* @__PURE__ */ jsx94("b", { className: "fd-tabular", children: stats.tokens.toLocaleString() })
|
|
12534
12779
|
] }) : null,
|
|
12535
|
-
stats.costUsd != null ? /* @__PURE__ */
|
|
12536
|
-
/* @__PURE__ */
|
|
12537
|
-
/* @__PURE__ */
|
|
12780
|
+
stats.costUsd != null ? /* @__PURE__ */ jsxs85("div", { children: [
|
|
12781
|
+
/* @__PURE__ */ jsx94("span", { children: "Cost" }),
|
|
12782
|
+
/* @__PURE__ */ jsxs85("b", { className: "fd-tabular", children: [
|
|
12538
12783
|
"$",
|
|
12539
12784
|
Number(stats.costUsd).toFixed(3)
|
|
12540
12785
|
] })
|
|
12541
12786
|
] }) : null,
|
|
12542
|
-
stats.turns ? /* @__PURE__ */
|
|
12543
|
-
/* @__PURE__ */
|
|
12544
|
-
/* @__PURE__ */
|
|
12787
|
+
stats.turns ? /* @__PURE__ */ jsxs85("div", { children: [
|
|
12788
|
+
/* @__PURE__ */ jsx94("span", { children: "Turns" }),
|
|
12789
|
+
/* @__PURE__ */ jsx94("b", { className: "fd-tabular", children: stats.turns })
|
|
12545
12790
|
] }) : null
|
|
12546
12791
|
] }) : null
|
|
12547
12792
|
] })
|
|
@@ -12580,7 +12825,7 @@ function ModelControls({
|
|
|
12580
12825
|
disabled: m.disabled,
|
|
12581
12826
|
checked: m.id === (current2 && current2.id),
|
|
12582
12827
|
meta: m.meta,
|
|
12583
|
-
shortcut: m.shortcut ? /* @__PURE__ */
|
|
12828
|
+
shortcut: m.shortcut ? /* @__PURE__ */ jsx94(KeyHint, { keys: m.shortcut, size: "sm" }) : void 0,
|
|
12584
12829
|
onSelect: () => onModelChange && onModelChange(m.id)
|
|
12585
12830
|
});
|
|
12586
12831
|
const items = [{ kind: "section", label: "Models" }].concat(flat.map(item));
|
|
@@ -12593,15 +12838,15 @@ function ModelControls({
|
|
|
12593
12838
|
items.push({ kind: "section", label: "Fast mode" });
|
|
12594
12839
|
items.push({
|
|
12595
12840
|
kind: "custom",
|
|
12596
|
-
render: () => /* @__PURE__ */
|
|
12597
|
-
/* @__PURE__ */
|
|
12598
|
-
/* @__PURE__ */
|
|
12599
|
-
/* @__PURE__ */
|
|
12841
|
+
render: () => /* @__PURE__ */ jsxs85("label", { className: "fdc-switchrow", children: [
|
|
12842
|
+
/* @__PURE__ */ jsx94("span", { children: fastModeLabel }),
|
|
12843
|
+
/* @__PURE__ */ jsx94("input", { type: "checkbox", className: "fd-sr", checked: !!fastMode, onChange: (e) => onFastModeChange(e.target.checked) }),
|
|
12844
|
+
/* @__PURE__ */ jsx94("span", { className: "fd-switch-track" + (fastMode ? " is-on" : ""), "aria-hidden": "true", children: /* @__PURE__ */ jsx94("span", { className: "fd-switch-thumb" }) })
|
|
12600
12845
|
] })
|
|
12601
12846
|
});
|
|
12602
12847
|
}
|
|
12603
|
-
return /* @__PURE__ */
|
|
12604
|
-
/* @__PURE__ */
|
|
12848
|
+
return /* @__PURE__ */ jsxs85(React63.Fragment, { children: [
|
|
12849
|
+
/* @__PURE__ */ jsx94(
|
|
12605
12850
|
MenuButton,
|
|
12606
12851
|
{
|
|
12607
12852
|
items,
|
|
@@ -12612,7 +12857,7 @@ function ModelControls({
|
|
|
12612
12857
|
title: "Choose a model"
|
|
12613
12858
|
}
|
|
12614
12859
|
),
|
|
12615
|
-
effortLevels && effortLevels.length ? /* @__PURE__ */
|
|
12860
|
+
effortLevels && effortLevels.length ? /* @__PURE__ */ jsx94(
|
|
12616
12861
|
MenuButton,
|
|
12617
12862
|
{
|
|
12618
12863
|
placement: "top-end",
|
|
@@ -12633,7 +12878,7 @@ function ModelControls({
|
|
|
12633
12878
|
}
|
|
12634
12879
|
|
|
12635
12880
|
// src/components/chat/AgentChatPanel.tsx
|
|
12636
|
-
import { jsx as
|
|
12881
|
+
import { jsx as jsx95, jsxs as jsxs86 } from "react/jsx-runtime";
|
|
12637
12882
|
var SURFACES = { sidebar: "is-sidebar", inline: "is-inline", page: "is-page", modal: "is-modal", sheet: "is-sheet" };
|
|
12638
12883
|
function AgentChatPanel({
|
|
12639
12884
|
/* required */
|
|
@@ -12717,11 +12962,11 @@ function AgentChatPanel({
|
|
|
12717
12962
|
onFeedback,
|
|
12718
12963
|
onEditMessage
|
|
12719
12964
|
}) {
|
|
12720
|
-
const [panelWidth, setPanelWidth] =
|
|
12721
|
-
const [applied, setApplied] =
|
|
12722
|
-
const [draft, setDraft] =
|
|
12723
|
-
const dragging =
|
|
12724
|
-
|
|
12965
|
+
const [panelWidth, setPanelWidth] = React64.useState(width);
|
|
12966
|
+
const [applied, setApplied] = React64.useState({});
|
|
12967
|
+
const [draft, setDraft] = React64.useState("");
|
|
12968
|
+
const dragging = React64.useRef(null);
|
|
12969
|
+
React64.useEffect(() => setPanelWidth(width), [width]);
|
|
12725
12970
|
const engine = useChatEngine({
|
|
12726
12971
|
contextType,
|
|
12727
12972
|
contextId,
|
|
@@ -12787,7 +13032,7 @@ function AgentChatPanel({
|
|
|
12787
13032
|
onReconnect: engine.reload,
|
|
12788
13033
|
deadTitle: "The assistant isn\u2019t reachable"
|
|
12789
13034
|
};
|
|
12790
|
-
const sessionBar = /* @__PURE__ */
|
|
13035
|
+
const sessionBar = /* @__PURE__ */ jsx95(
|
|
12791
13036
|
ChatSessionBar,
|
|
12792
13037
|
{
|
|
12793
13038
|
sessionStats,
|
|
@@ -12796,7 +13041,7 @@ function AgentChatPanel({
|
|
|
12796
13041
|
onClear: engine.visible.length ? engine.clear : void 0
|
|
12797
13042
|
}
|
|
12798
13043
|
);
|
|
12799
|
-
const modelControls = /* @__PURE__ */
|
|
13044
|
+
const modelControls = /* @__PURE__ */ jsx95(
|
|
12800
13045
|
ModelControls,
|
|
12801
13046
|
{
|
|
12802
13047
|
models,
|
|
@@ -12811,7 +13056,7 @@ function AgentChatPanel({
|
|
|
12811
13056
|
narrow
|
|
12812
13057
|
}
|
|
12813
13058
|
);
|
|
12814
|
-
const threadMenu = threads && threads.length ? /* @__PURE__ */
|
|
13059
|
+
const threadMenu = threads && threads.length ? /* @__PURE__ */ jsx95(
|
|
12815
13060
|
MenuButton,
|
|
12816
13061
|
{
|
|
12817
13062
|
variant: "ghost",
|
|
@@ -12838,7 +13083,7 @@ function AgentChatPanel({
|
|
|
12838
13083
|
})))
|
|
12839
13084
|
}
|
|
12840
13085
|
) : null;
|
|
12841
|
-
return /* @__PURE__ */
|
|
13086
|
+
return /* @__PURE__ */ jsxs86(
|
|
12842
13087
|
"aside",
|
|
12843
13088
|
{
|
|
12844
13089
|
className: ["fdc-panel", SURFACES[surface] || SURFACES.sidebar, narrow ? "is-narrow" : "", className].filter(Boolean).join(" "),
|
|
@@ -12849,7 +13094,7 @@ function AgentChatPanel({
|
|
|
12849
13094
|
},
|
|
12850
13095
|
"aria-label": title,
|
|
12851
13096
|
children: [
|
|
12852
|
-
surface === "sidebar" && resizable ? /* @__PURE__ */
|
|
13097
|
+
surface === "sidebar" && resizable ? /* @__PURE__ */ jsx95(
|
|
12853
13098
|
"div",
|
|
12854
13099
|
{
|
|
12855
13100
|
className: "fdc-grip",
|
|
@@ -12864,20 +13109,20 @@ function AgentChatPanel({
|
|
|
12864
13109
|
}
|
|
12865
13110
|
}
|
|
12866
13111
|
) : null,
|
|
12867
|
-
showHeader ? /* @__PURE__ */
|
|
12868
|
-
/* @__PURE__ */
|
|
12869
|
-
/* @__PURE__ */
|
|
12870
|
-
/* @__PURE__ */
|
|
12871
|
-
subtitle ? /* @__PURE__ */
|
|
13112
|
+
showHeader ? /* @__PURE__ */ jsxs86("header", { className: "fdc-head", children: [
|
|
13113
|
+
/* @__PURE__ */ jsx95("span", { className: "fdc-head-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx95("i", { className: "ph ph-" + assistantIcon }) }),
|
|
13114
|
+
/* @__PURE__ */ jsxs86("span", { className: "fdc-head-titles", children: [
|
|
13115
|
+
/* @__PURE__ */ jsx95("span", { className: "fdc-head-title", title: truncationTitle(title), children: title }),
|
|
13116
|
+
subtitle ? /* @__PURE__ */ jsx95("span", { className: "fdc-head-sub", title: truncationTitle(subtitle), children: subtitle }) : null
|
|
12872
13117
|
] }),
|
|
12873
|
-
/* @__PURE__ */
|
|
13118
|
+
/* @__PURE__ */ jsxs86("span", { className: "fdc-head-acts", children: [
|
|
12874
13119
|
headerActions,
|
|
12875
13120
|
threadMenu,
|
|
12876
|
-
onNewThread ? /* @__PURE__ */
|
|
12877
|
-
onClose ? /* @__PURE__ */
|
|
13121
|
+
onNewThread ? /* @__PURE__ */ jsx95("button", { type: "button", className: "fdc-iconbtn", onClick: onNewThread, "aria-label": "New conversation", title: "New conversation", children: /* @__PURE__ */ jsx95("i", { className: "ph ph-plus", "aria-hidden": "true" }) }) : null,
|
|
13122
|
+
onClose ? /* @__PURE__ */ jsx95("button", { type: "button", className: "fdc-iconbtn", onClick: onClose, "aria-label": "Close panel", title: "Close", children: /* @__PURE__ */ jsx95("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
|
|
12878
13123
|
] })
|
|
12879
13124
|
] }) : null,
|
|
12880
|
-
/* @__PURE__ */
|
|
13125
|
+
/* @__PURE__ */ jsx95(
|
|
12881
13126
|
ChatTranscript,
|
|
12882
13127
|
{
|
|
12883
13128
|
messages: engine.visible,
|
|
@@ -12892,7 +13137,7 @@ function AgentChatPanel({
|
|
|
12892
13137
|
renderEmpty
|
|
12893
13138
|
}
|
|
12894
13139
|
),
|
|
12895
|
-
/* @__PURE__ */
|
|
13140
|
+
/* @__PURE__ */ jsx95(
|
|
12896
13141
|
ChatComposer,
|
|
12897
13142
|
{
|
|
12898
13143
|
onSubmit: (text, atts) => engine.send(text, atts),
|
|
@@ -12925,8 +13170,8 @@ function AgentChatPanel({
|
|
|
12925
13170
|
}
|
|
12926
13171
|
|
|
12927
13172
|
// src/components/files/FileViewer.tsx
|
|
12928
|
-
import * as
|
|
12929
|
-
import { jsx as
|
|
13173
|
+
import * as React65 from "react";
|
|
13174
|
+
import { jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
12930
13175
|
function previewKindOf(file) {
|
|
12931
13176
|
const mime = (file.mime || "").toLowerCase();
|
|
12932
13177
|
const ext = extensionOf(file.name || "");
|
|
@@ -12982,13 +13227,13 @@ function parseDelimited(text, delimiter) {
|
|
|
12982
13227
|
return rows;
|
|
12983
13228
|
}
|
|
12984
13229
|
function usePreview(file, kind, resolveUrl) {
|
|
12985
|
-
const [state, setState] =
|
|
12986
|
-
const [attempt, setAttempt] =
|
|
12987
|
-
const resolveRef =
|
|
12988
|
-
|
|
13230
|
+
const [state, setState] = React65.useState({ status: "loading" });
|
|
13231
|
+
const [attempt, setAttempt] = React65.useState(0);
|
|
13232
|
+
const resolveRef = React65.useRef(resolveUrl);
|
|
13233
|
+
React65.useEffect(() => {
|
|
12989
13234
|
resolveRef.current = resolveUrl;
|
|
12990
13235
|
}, [resolveUrl]);
|
|
12991
|
-
|
|
13236
|
+
React65.useEffect(() => {
|
|
12992
13237
|
if (kind === "none") {
|
|
12993
13238
|
setState({ status: "ready" });
|
|
12994
13239
|
return;
|
|
@@ -13018,19 +13263,19 @@ function usePreview(file, kind, resolveUrl) {
|
|
|
13018
13263
|
if (ac) ac.abort();
|
|
13019
13264
|
};
|
|
13020
13265
|
}, [file.id, kind, attempt]);
|
|
13021
|
-
return { ...state, retry:
|
|
13266
|
+
return { ...state, retry: React65.useCallback(() => setAttempt((a) => a + 1), []) };
|
|
13022
13267
|
}
|
|
13023
13268
|
function PreviewBody({ file, kind, state }) {
|
|
13024
|
-
if (kind === "image") return /* @__PURE__ */
|
|
13025
|
-
if (kind === "pdf") return /* @__PURE__ */
|
|
13026
|
-
if (kind === "markdown") return /* @__PURE__ */
|
|
13269
|
+
if (kind === "image") return /* @__PURE__ */ jsx96("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
|
|
13270
|
+
if (kind === "pdf") return /* @__PURE__ */ jsx96("iframe", { className: "fd-fv-pdf", src: state.url, title: file.name || "PDF preview" });
|
|
13271
|
+
if (kind === "markdown") return /* @__PURE__ */ jsx96(Markdown, { className: "fd-fv-markdown", source: state.text || "" });
|
|
13027
13272
|
if (kind === "json") {
|
|
13028
13273
|
let pretty = state.text || "";
|
|
13029
13274
|
try {
|
|
13030
13275
|
pretty = JSON.stringify(JSON.parse(pretty), null, 2);
|
|
13031
13276
|
} catch {
|
|
13032
13277
|
}
|
|
13033
|
-
return /* @__PURE__ */
|
|
13278
|
+
return /* @__PURE__ */ jsx96(CodeBlock, { code: pretty, language: "json" });
|
|
13034
13279
|
}
|
|
13035
13280
|
if (kind === "csv") {
|
|
13036
13281
|
const tsv = extensionOf(file.name || "") === "tsv" || (file.mime || "").toLowerCase().includes("tab-separated");
|
|
@@ -13038,12 +13283,12 @@ function PreviewBody({ file, kind, state }) {
|
|
|
13038
13283
|
const head = rows[0] || [];
|
|
13039
13284
|
const dataRows = rows.slice(1);
|
|
13040
13285
|
const shown = dataRows.slice(0, FILE_VIEWER_CSV_ROW_LIMIT);
|
|
13041
|
-
return /* @__PURE__ */
|
|
13042
|
-
/* @__PURE__ */
|
|
13043
|
-
/* @__PURE__ */
|
|
13044
|
-
/* @__PURE__ */
|
|
13286
|
+
return /* @__PURE__ */ jsxs87("div", { className: "fd-fv-csv", children: [
|
|
13287
|
+
/* @__PURE__ */ jsxs87("table", { className: "fd-fv-csv-table", children: [
|
|
13288
|
+
/* @__PURE__ */ jsx96("thead", { children: /* @__PURE__ */ jsx96("tr", { children: head.map((c, i) => /* @__PURE__ */ jsx96("th", { children: c }, i)) }) }),
|
|
13289
|
+
/* @__PURE__ */ jsx96("tbody", { children: shown.map((r, ri) => /* @__PURE__ */ jsx96("tr", { children: head.map((_, ci) => /* @__PURE__ */ jsx96("td", { children: r[ci] ?? "" }, ci)) }, ri)) })
|
|
13045
13290
|
] }),
|
|
13046
|
-
dataRows.length > FILE_VIEWER_CSV_ROW_LIMIT ? /* @__PURE__ */
|
|
13291
|
+
dataRows.length > FILE_VIEWER_CSV_ROW_LIMIT ? /* @__PURE__ */ jsxs87("p", { className: "fd-fv-csv-note fd-body-sm fd-muted", children: [
|
|
13047
13292
|
"Showing the first ",
|
|
13048
13293
|
FILE_VIEWER_CSV_ROW_LIMIT.toLocaleString(),
|
|
13049
13294
|
" of ",
|
|
@@ -13052,24 +13297,24 @@ function PreviewBody({ file, kind, state }) {
|
|
|
13052
13297
|
] }) : null
|
|
13053
13298
|
] });
|
|
13054
13299
|
}
|
|
13055
|
-
if (kind === "text") return /* @__PURE__ */
|
|
13056
|
-
return /* @__PURE__ */
|
|
13057
|
-
/* @__PURE__ */
|
|
13058
|
-
/* @__PURE__ */
|
|
13059
|
-
/* @__PURE__ */
|
|
13300
|
+
if (kind === "text") return /* @__PURE__ */ jsx96(CodeBlock, { code: state.text || "", language: extensionOf(file.name || "") || void 0 });
|
|
13301
|
+
return /* @__PURE__ */ jsxs87("div", { className: "fd-fv-fallback", children: [
|
|
13302
|
+
/* @__PURE__ */ jsx96("span", { className: "fd-fv-fallback-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx96("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
|
|
13303
|
+
/* @__PURE__ */ jsx96("span", { className: "fd-fv-fallback-title", children: "No preview available" }),
|
|
13304
|
+
/* @__PURE__ */ jsxs87("span", { className: "fd-fv-fallback-meta", children: [
|
|
13060
13305
|
file.mime || "Unknown type",
|
|
13061
13306
|
file.size ? " \xB7 " + formatBytes(file.size) : ""
|
|
13062
13307
|
] })
|
|
13063
13308
|
] });
|
|
13064
13309
|
}
|
|
13065
13310
|
function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
|
|
13066
|
-
const kind =
|
|
13311
|
+
const kind = React65.useMemo(() => previewKindOf(file), [file]);
|
|
13067
13312
|
const preview = usePreview(file, kind, resolveUrl);
|
|
13068
|
-
const [tab, setTab] =
|
|
13069
|
-
const [downloading, setDownloading] =
|
|
13070
|
-
const [downloadError, setDownloadError] =
|
|
13313
|
+
const [tab, setTab] = React65.useState("preview");
|
|
13314
|
+
const [downloading, setDownloading] = React65.useState(false);
|
|
13315
|
+
const [downloadError, setDownloadError] = React65.useState(null);
|
|
13071
13316
|
const hasSide = sidePanel != null;
|
|
13072
|
-
|
|
13317
|
+
React65.useEffect(() => {
|
|
13073
13318
|
setTab("preview");
|
|
13074
13319
|
}, [file.id]);
|
|
13075
13320
|
const download = () => {
|
|
@@ -13085,29 +13330,29 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
13085
13330
|
a.remove();
|
|
13086
13331
|
}).catch((err) => setDownloadError(err && err.message || "Download failed.")).finally(() => setDownloading(false));
|
|
13087
13332
|
};
|
|
13088
|
-
return /* @__PURE__ */
|
|
13333
|
+
return /* @__PURE__ */ jsxs87(
|
|
13089
13334
|
"section",
|
|
13090
13335
|
{
|
|
13091
13336
|
className: ["fd-fv", hasSide && tab === "side" ? "is-tab-side" : "is-tab-preview", className].filter(Boolean).join(" "),
|
|
13092
13337
|
"aria-label": file.name || "File",
|
|
13093
13338
|
children: [
|
|
13094
|
-
/* @__PURE__ */
|
|
13095
|
-
/* @__PURE__ */
|
|
13096
|
-
/* @__PURE__ */
|
|
13097
|
-
/* @__PURE__ */
|
|
13098
|
-
/* @__PURE__ */
|
|
13339
|
+
/* @__PURE__ */ jsxs87("header", { className: "fd-fv-head", children: [
|
|
13340
|
+
/* @__PURE__ */ jsx96("span", { className: "fd-fv-head-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx96("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
|
|
13341
|
+
/* @__PURE__ */ jsxs87("span", { className: "fd-fv-head-titles", children: [
|
|
13342
|
+
/* @__PURE__ */ jsx96("span", { className: "fd-fv-head-title", title: file.name, children: file.name }),
|
|
13343
|
+
/* @__PURE__ */ jsxs87("span", { className: "fd-fv-head-meta", children: [
|
|
13099
13344
|
file.mime || "Unknown type",
|
|
13100
13345
|
file.size ? " \xB7 " + formatBytes(file.size) : ""
|
|
13101
13346
|
] })
|
|
13102
13347
|
] }),
|
|
13103
|
-
/* @__PURE__ */
|
|
13348
|
+
/* @__PURE__ */ jsxs87("span", { className: "fd-fv-head-actions", children: [
|
|
13104
13349
|
actions,
|
|
13105
|
-
/* @__PURE__ */
|
|
13106
|
-
onClose ? /* @__PURE__ */
|
|
13350
|
+
/* @__PURE__ */ jsx96(Button, { variant: "secondary", size: "sm", icon: "download-simple", loading: downloading, onClick: download, children: "Download" }),
|
|
13351
|
+
onClose ? /* @__PURE__ */ jsx96(IconButton, { icon: "x", label: "Close", onClick: onClose }) : null
|
|
13107
13352
|
] })
|
|
13108
13353
|
] }),
|
|
13109
|
-
downloadError ? /* @__PURE__ */
|
|
13110
|
-
hasSide ? /* @__PURE__ */
|
|
13354
|
+
downloadError ? /* @__PURE__ */ jsx96("div", { className: "fd-fv-download-error", role: "alert", children: downloadError }) : null,
|
|
13355
|
+
hasSide ? /* @__PURE__ */ jsx96(
|
|
13111
13356
|
Tabs,
|
|
13112
13357
|
{
|
|
13113
13358
|
className: "fd-fv-tabs",
|
|
@@ -13116,19 +13361,19 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
13116
13361
|
onChange: (v) => setTab(v)
|
|
13117
13362
|
}
|
|
13118
13363
|
) : null,
|
|
13119
|
-
/* @__PURE__ */
|
|
13120
|
-
/* @__PURE__ */
|
|
13364
|
+
/* @__PURE__ */ jsxs87("div", { className: "fd-fv-body", children: [
|
|
13365
|
+
/* @__PURE__ */ jsx96("div", { className: "fd-fv-preview", role: "region", "aria-label": "Preview of " + (file.name || "file"), children: /* @__PURE__ */ jsx96(
|
|
13121
13366
|
LoadingRegion,
|
|
13122
13367
|
{
|
|
13123
13368
|
state: preview.status === "loading" ? "loading" : preview.status === "error" ? "error" : "ready",
|
|
13124
13369
|
error: preview.error,
|
|
13125
13370
|
label: "Loading preview of " + (file.name || "file"),
|
|
13126
13371
|
onRetry: preview.status === "error" ? preview.retry : void 0,
|
|
13127
|
-
skeleton: /* @__PURE__ */
|
|
13128
|
-
children: /* @__PURE__ */
|
|
13372
|
+
skeleton: /* @__PURE__ */ jsx96(Skeleton, { shape: "card", h: 220 }),
|
|
13373
|
+
children: /* @__PURE__ */ jsx96(PreviewBody, { file, kind, state: preview })
|
|
13129
13374
|
}
|
|
13130
13375
|
) }),
|
|
13131
|
-
hasSide ? /* @__PURE__ */
|
|
13376
|
+
hasSide ? /* @__PURE__ */ jsx96("div", { className: "fd-fv-side", role: "region", "aria-label": sidePanelLabel, children: sidePanel }) : null
|
|
13132
13377
|
] })
|
|
13133
13378
|
]
|
|
13134
13379
|
}
|
|
@@ -13136,8 +13381,8 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
13136
13381
|
}
|
|
13137
13382
|
|
|
13138
13383
|
// src/components/files/FileBrowser.tsx
|
|
13139
|
-
import * as
|
|
13140
|
-
import { Fragment as Fragment28, jsx as
|
|
13384
|
+
import * as React66 from "react";
|
|
13385
|
+
import { Fragment as Fragment28, jsx as jsx97, jsxs as jsxs88 } from "react/jsx-runtime";
|
|
13141
13386
|
function childrenOf(folders, parentId) {
|
|
13142
13387
|
return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
|
|
13143
13388
|
}
|
|
@@ -13209,8 +13454,8 @@ function FolderPickerMenu({
|
|
|
13209
13454
|
}) {
|
|
13210
13455
|
const panel = useInlinePanel();
|
|
13211
13456
|
const { open: open2, setOpen, ref, zIndex } = panel;
|
|
13212
|
-
return /* @__PURE__ */
|
|
13213
|
-
/* @__PURE__ */
|
|
13457
|
+
return /* @__PURE__ */ jsxs88("span", { className: "fd-fb-menu-anchor", ref, children: [
|
|
13458
|
+
/* @__PURE__ */ jsx97(
|
|
13214
13459
|
IconButton,
|
|
13215
13460
|
{
|
|
13216
13461
|
icon: "arrows-out-cardinal",
|
|
@@ -13222,9 +13467,9 @@ function FolderPickerMenu({
|
|
|
13222
13467
|
onClick: () => setOpen((v) => !v)
|
|
13223
13468
|
}
|
|
13224
13469
|
),
|
|
13225
|
-
open2 ? /* @__PURE__ */
|
|
13226
|
-
/* @__PURE__ */
|
|
13227
|
-
destinations.map((d) => /* @__PURE__ */
|
|
13470
|
+
open2 ? /* @__PURE__ */ jsx97(InlinePanelLayers, { panel, children: /* @__PURE__ */ jsxs88("div", { className: "fd-fb-menu", role: "menu", "aria-label": label, style: { zIndex }, children: [
|
|
13471
|
+
/* @__PURE__ */ jsx97("span", { className: "fd-overline fd-muted fd-fb-menu-title", children: "Move to\u2026" }),
|
|
13472
|
+
destinations.map((d) => /* @__PURE__ */ jsxs88(
|
|
13228
13473
|
"button",
|
|
13229
13474
|
{
|
|
13230
13475
|
type: "button",
|
|
@@ -13236,7 +13481,7 @@ function FolderPickerMenu({
|
|
|
13236
13481
|
setOpen(false);
|
|
13237
13482
|
},
|
|
13238
13483
|
children: [
|
|
13239
|
-
/* @__PURE__ */
|
|
13484
|
+
/* @__PURE__ */ jsx97("i", { className: "ph ph-" + (d.id == null ? "house-simple" : "folder-simple"), "aria-hidden": "true" }),
|
|
13240
13485
|
d.name
|
|
13241
13486
|
]
|
|
13242
13487
|
},
|
|
@@ -13246,8 +13491,8 @@ function FolderPickerMenu({
|
|
|
13246
13491
|
] });
|
|
13247
13492
|
}
|
|
13248
13493
|
function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
|
|
13249
|
-
const [over, setOver] =
|
|
13250
|
-
const dragCounter =
|
|
13494
|
+
const [over, setOver] = React66.useState(false);
|
|
13495
|
+
const dragCounter = React66.useRef(0);
|
|
13251
13496
|
const dropHandlers = isDropTarget ? {
|
|
13252
13497
|
onDragEnter: (e) => {
|
|
13253
13498
|
if (!hasInternalPayload(e)) return;
|
|
@@ -13272,8 +13517,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
|
|
|
13272
13517
|
if (payload && onDropPayload) onDropPayload(payload);
|
|
13273
13518
|
}
|
|
13274
13519
|
} : {};
|
|
13275
|
-
return /* @__PURE__ */
|
|
13276
|
-
/* @__PURE__ */
|
|
13520
|
+
return /* @__PURE__ */ jsxs88("div", { className: ["fd-fb-row", over ? "is-drop-target" : "", className].filter(Boolean).join(" "), ...dropHandlers, children: [
|
|
13521
|
+
/* @__PURE__ */ jsxs88(
|
|
13277
13522
|
"button",
|
|
13278
13523
|
{
|
|
13279
13524
|
type: "button",
|
|
@@ -13282,26 +13527,26 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
|
|
|
13282
13527
|
draggable: !!draggableId,
|
|
13283
13528
|
onDragStart: draggableId ? (e) => writeDragPayload(e, draggableId) : void 0,
|
|
13284
13529
|
children: [
|
|
13285
|
-
/* @__PURE__ */
|
|
13286
|
-
/* @__PURE__ */
|
|
13287
|
-
/* @__PURE__ */
|
|
13288
|
-
meta ? /* @__PURE__ */
|
|
13530
|
+
/* @__PURE__ */ jsx97("span", { className: "fd-fb-row-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx97("i", { className: "ph ph-" + icon }) }),
|
|
13531
|
+
/* @__PURE__ */ jsxs88("span", { className: "fd-fb-row-text", children: [
|
|
13532
|
+
/* @__PURE__ */ jsx97("span", { className: "fd-fb-row-name", title: name, children: name }),
|
|
13533
|
+
meta ? /* @__PURE__ */ jsx97("span", { className: "fd-fb-row-meta", children: meta }) : null
|
|
13289
13534
|
] })
|
|
13290
13535
|
]
|
|
13291
13536
|
}
|
|
13292
13537
|
),
|
|
13293
|
-
actions ? /* @__PURE__ */
|
|
13538
|
+
actions ? /* @__PURE__ */ jsx97("span", { className: "fd-fb-row-actions", children: actions }) : null
|
|
13294
13539
|
] });
|
|
13295
13540
|
}
|
|
13296
13541
|
function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
|
|
13297
13542
|
const kids = childrenOf(folders, folder.id);
|
|
13298
|
-
const [expanded, setExpanded] =
|
|
13299
|
-
|
|
13543
|
+
const [expanded, setExpanded] = React66.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
|
|
13544
|
+
React66.useEffect(() => {
|
|
13300
13545
|
if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
|
|
13301
13546
|
}, [currentFolderId, folder.id, folders]);
|
|
13302
13547
|
const isCurrent = folder.id === currentFolderId;
|
|
13303
|
-
return /* @__PURE__ */
|
|
13304
|
-
/* @__PURE__ */
|
|
13548
|
+
return /* @__PURE__ */ jsxs88("div", { className: "fd-fb-tree-node", children: [
|
|
13549
|
+
/* @__PURE__ */ jsx97(
|
|
13305
13550
|
RowShell,
|
|
13306
13551
|
{
|
|
13307
13552
|
icon: folder.id === currentFolderId ? "folder-open" : "folder-simple",
|
|
@@ -13311,7 +13556,7 @@ function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveI
|
|
|
13311
13556
|
isDropTarget: canMove,
|
|
13312
13557
|
onDropPayload: (payload) => onMoveInto(payload, folder.id),
|
|
13313
13558
|
className: ["fd-fb-tree-row", isCurrent ? "is-current" : ""].filter(Boolean).join(" "),
|
|
13314
|
-
actions: kids.length ? /* @__PURE__ */
|
|
13559
|
+
actions: kids.length ? /* @__PURE__ */ jsx97(
|
|
13315
13560
|
IconButton,
|
|
13316
13561
|
{
|
|
13317
13562
|
icon: expanded ? "caret-down" : "caret-right",
|
|
@@ -13323,7 +13568,7 @@ function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveI
|
|
|
13323
13568
|
) : void 0
|
|
13324
13569
|
}
|
|
13325
13570
|
),
|
|
13326
|
-
expanded && kids.length ? /* @__PURE__ */
|
|
13571
|
+
expanded && kids.length ? /* @__PURE__ */ jsx97("div", { className: "fd-fb-tree-children", style: { paddingLeft: 14 }, children: kids.map((k) => /* @__PURE__ */ jsx97(
|
|
13327
13572
|
TreeNode,
|
|
13328
13573
|
{
|
|
13329
13574
|
folder: k,
|
|
@@ -13362,15 +13607,15 @@ function FileBrowser({
|
|
|
13362
13607
|
const canUpload = perm.canUpload !== false && !!onUpload;
|
|
13363
13608
|
const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
|
|
13364
13609
|
const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
|
|
13365
|
-
const [createOpen, setCreateOpen] =
|
|
13366
|
-
const [createName, setCreateName] =
|
|
13367
|
-
const [renameTarget, setRenameTarget] =
|
|
13368
|
-
const [renameValue, setRenameValue] =
|
|
13369
|
-
const [deleteTarget, setDeleteTarget] =
|
|
13370
|
-
const uploadInputRef =
|
|
13371
|
-
const crumbFolders =
|
|
13372
|
-
const subfolders =
|
|
13373
|
-
const currentFiles =
|
|
13610
|
+
const [createOpen, setCreateOpen] = React66.useState(false);
|
|
13611
|
+
const [createName, setCreateName] = React66.useState("");
|
|
13612
|
+
const [renameTarget, setRenameTarget] = React66.useState(null);
|
|
13613
|
+
const [renameValue, setRenameValue] = React66.useState("");
|
|
13614
|
+
const [deleteTarget, setDeleteTarget] = React66.useState(null);
|
|
13615
|
+
const uploadInputRef = React66.useRef(null);
|
|
13616
|
+
const crumbFolders = React66.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
13617
|
+
const subfolders = React66.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
13618
|
+
const currentFiles = React66.useMemo(
|
|
13374
13619
|
() => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
|
|
13375
13620
|
[files, currentFolderId]
|
|
13376
13621
|
);
|
|
@@ -13409,10 +13654,10 @@ function FileBrowser({
|
|
|
13409
13654
|
if (deleteTarget && onDeleteFolder) onDeleteFolder(deleteTarget);
|
|
13410
13655
|
setDeleteTarget(null);
|
|
13411
13656
|
};
|
|
13412
|
-
const content = /* @__PURE__ */
|
|
13413
|
-
/* @__PURE__ */
|
|
13414
|
-
/* @__PURE__ */
|
|
13415
|
-
/* @__PURE__ */
|
|
13657
|
+
const content = /* @__PURE__ */ jsxs88("div", { className: ["fd-fb", className].filter(Boolean).join(" "), children: [
|
|
13658
|
+
/* @__PURE__ */ jsxs88("div", { className: "fd-fb-head", children: [
|
|
13659
|
+
/* @__PURE__ */ jsxs88("nav", { className: "fd-fb-crumbs", "aria-label": "Folder path", children: [
|
|
13660
|
+
/* @__PURE__ */ jsx97(
|
|
13416
13661
|
BreadcrumbCrumb,
|
|
13417
13662
|
{
|
|
13418
13663
|
label: "Home",
|
|
@@ -13422,7 +13667,7 @@ function FileBrowser({
|
|
|
13422
13667
|
onDropPayload: (p) => moveIntoFolder(p, null)
|
|
13423
13668
|
}
|
|
13424
13669
|
),
|
|
13425
|
-
crumbFolders.map((f, i) => /* @__PURE__ */
|
|
13670
|
+
crumbFolders.map((f, i) => /* @__PURE__ */ jsx97(
|
|
13426
13671
|
BreadcrumbCrumb,
|
|
13427
13672
|
{
|
|
13428
13673
|
label: f.name,
|
|
@@ -13434,11 +13679,11 @@ function FileBrowser({
|
|
|
13434
13679
|
f.id
|
|
13435
13680
|
))
|
|
13436
13681
|
] }),
|
|
13437
|
-
/* @__PURE__ */
|
|
13438
|
-
canCreateFolder ? /* @__PURE__ */
|
|
13439
|
-
canUpload ? /* @__PURE__ */
|
|
13440
|
-
/* @__PURE__ */
|
|
13441
|
-
/* @__PURE__ */
|
|
13682
|
+
/* @__PURE__ */ jsxs88("span", { className: "fd-fb-actions", children: [
|
|
13683
|
+
canCreateFolder ? /* @__PURE__ */ jsx97(Button, { variant: "secondary", size: "sm", icon: "folder-simple-plus", onClick: openCreate, children: "New folder" }) : null,
|
|
13684
|
+
canUpload ? /* @__PURE__ */ jsxs88(Fragment28, { children: [
|
|
13685
|
+
/* @__PURE__ */ jsx97(Button, { variant: "secondary", size: "sm", icon: "upload-simple", onClick: () => uploadInputRef.current && uploadInputRef.current.click(), children: "Upload" }),
|
|
13686
|
+
/* @__PURE__ */ jsx97(
|
|
13442
13687
|
"input",
|
|
13443
13688
|
{
|
|
13444
13689
|
ref: uploadInputRef,
|
|
@@ -13456,9 +13701,9 @@ function FileBrowser({
|
|
|
13456
13701
|
] }) : null
|
|
13457
13702
|
] })
|
|
13458
13703
|
] }),
|
|
13459
|
-
/* @__PURE__ */
|
|
13460
|
-
/* @__PURE__ */
|
|
13461
|
-
/* @__PURE__ */
|
|
13704
|
+
/* @__PURE__ */ jsxs88("div", { className: "fd-fb-body", children: [
|
|
13705
|
+
/* @__PURE__ */ jsxs88("div", { className: "fd-fb-tree", role: "region", "aria-label": "Folder tree", children: [
|
|
13706
|
+
/* @__PURE__ */ jsx97(
|
|
13462
13707
|
RowShell,
|
|
13463
13708
|
{
|
|
13464
13709
|
icon: "house-simple",
|
|
@@ -13469,7 +13714,7 @@ function FileBrowser({
|
|
|
13469
13714
|
className: ["fd-fb-tree-row", currentFolderId == null ? "is-current" : ""].filter(Boolean).join(" ")
|
|
13470
13715
|
}
|
|
13471
13716
|
),
|
|
13472
|
-
childrenOf(folders, null).map((f) => /* @__PURE__ */
|
|
13717
|
+
childrenOf(folders, null).map((f) => /* @__PURE__ */ jsx97(
|
|
13473
13718
|
TreeNode,
|
|
13474
13719
|
{
|
|
13475
13720
|
folder: f,
|
|
@@ -13483,18 +13728,18 @@ function FileBrowser({
|
|
|
13483
13728
|
f.id
|
|
13484
13729
|
))
|
|
13485
13730
|
] }),
|
|
13486
|
-
/* @__PURE__ */
|
|
13731
|
+
/* @__PURE__ */ jsx97("div", { className: "fd-fb-main", role: "region", "aria-label": "Folder contents", children: /* @__PURE__ */ jsx97(
|
|
13487
13732
|
LoadingRegion,
|
|
13488
13733
|
{
|
|
13489
13734
|
state: loading ? "loading" : "ready",
|
|
13490
13735
|
label: "Loading folder contents",
|
|
13491
|
-
skeleton: /* @__PURE__ */
|
|
13492
|
-
/* @__PURE__ */
|
|
13493
|
-
/* @__PURE__ */
|
|
13494
|
-
/* @__PURE__ */
|
|
13736
|
+
skeleton: /* @__PURE__ */ jsxs88("div", { className: "fd-stack", style: { gap: 8, padding: 12 }, children: [
|
|
13737
|
+
/* @__PURE__ */ jsx97(Skeleton, { h: 44, radius: "10px" }),
|
|
13738
|
+
/* @__PURE__ */ jsx97(Skeleton, { h: 44, radius: "10px" }),
|
|
13739
|
+
/* @__PURE__ */ jsx97(Skeleton, { h: 44, radius: "10px" })
|
|
13495
13740
|
] }),
|
|
13496
|
-
children: isEmpty ? /* @__PURE__ */
|
|
13497
|
-
subfolders.map((f) => /* @__PURE__ */
|
|
13741
|
+
children: isEmpty ? /* @__PURE__ */ jsx97(EmptyState, { icon: "folder-open", title: "This folder is empty", children: canUpload ? "Drop files here, or use Upload above." : "Nothing has been filed here yet." }) : /* @__PURE__ */ jsxs88("div", { className: "fd-fb-list", children: [
|
|
13742
|
+
subfolders.map((f) => /* @__PURE__ */ jsx97(
|
|
13498
13743
|
RowShell,
|
|
13499
13744
|
{
|
|
13500
13745
|
icon: "folder-simple",
|
|
@@ -13503,9 +13748,9 @@ function FileBrowser({
|
|
|
13503
13748
|
draggableId: canMove ? { kind: "folder", id: f.id } : void 0,
|
|
13504
13749
|
isDropTarget: canMove,
|
|
13505
13750
|
onDropPayload: (p) => moveIntoFolder(p, f.id),
|
|
13506
|
-
actions: /* @__PURE__ */
|
|
13507
|
-
canRenameFolder ? /* @__PURE__ */
|
|
13508
|
-
canMove ? /* @__PURE__ */
|
|
13751
|
+
actions: /* @__PURE__ */ jsxs88(Fragment28, { children: [
|
|
13752
|
+
canRenameFolder ? /* @__PURE__ */ jsx97(IconButton, { icon: "pencil-simple", label: "Rename " + f.name, size: "sm", variant: "ghost", onClick: () => openRename(f) }) : null,
|
|
13753
|
+
canMove ? /* @__PURE__ */ jsx97(
|
|
13509
13754
|
FolderPickerMenu,
|
|
13510
13755
|
{
|
|
13511
13756
|
label: "Move " + f.name,
|
|
@@ -13513,12 +13758,12 @@ function FileBrowser({
|
|
|
13513
13758
|
onPick: (target) => moveIntoFolder({ kind: "folder", id: f.id }, target)
|
|
13514
13759
|
}
|
|
13515
13760
|
) : null,
|
|
13516
|
-
canDeleteFolder ? /* @__PURE__ */
|
|
13761
|
+
canDeleteFolder ? /* @__PURE__ */ jsx97(IconButton, { icon: "trash-simple", label: "Delete " + f.name, size: "sm", variant: "ghost", onClick: () => openDelete(f) }) : null
|
|
13517
13762
|
] })
|
|
13518
13763
|
},
|
|
13519
13764
|
f.id
|
|
13520
13765
|
)),
|
|
13521
|
-
currentFiles.map((file) => /* @__PURE__ */
|
|
13766
|
+
currentFiles.map((file) => /* @__PURE__ */ jsx97(
|
|
13522
13767
|
RowShell,
|
|
13523
13768
|
{
|
|
13524
13769
|
icon: iconForMime(file.mime, file.name),
|
|
@@ -13526,8 +13771,8 @@ function FileBrowser({
|
|
|
13526
13771
|
meta: file.size ? formatBytes(file.size) : void 0,
|
|
13527
13772
|
onOpen: onOpenFile ? () => onOpenFile(file) : void 0,
|
|
13528
13773
|
draggableId: canMove ? { kind: "file", id: file.id } : void 0,
|
|
13529
|
-
actions: /* @__PURE__ */
|
|
13530
|
-
canMove ? /* @__PURE__ */
|
|
13774
|
+
actions: /* @__PURE__ */ jsxs88(Fragment28, { children: [
|
|
13775
|
+
canMove ? /* @__PURE__ */ jsx97(
|
|
13531
13776
|
FolderPickerMenu,
|
|
13532
13777
|
{
|
|
13533
13778
|
label: "Move " + file.name,
|
|
@@ -13535,7 +13780,7 @@ function FileBrowser({
|
|
|
13535
13780
|
onPick: (target) => onMoveFile && onMoveFile(file.id, target)
|
|
13536
13781
|
}
|
|
13537
13782
|
) : null,
|
|
13538
|
-
canRemoveFile ? /* @__PURE__ */
|
|
13783
|
+
canRemoveFile ? /* @__PURE__ */ jsx97(IconButton, { icon: "trash-simple", label: "Remove " + file.name, size: "sm", variant: "ghost", onClick: () => onRemoveFile && onRemoveFile(file) }) : null
|
|
13539
13784
|
] })
|
|
13540
13785
|
},
|
|
13541
13786
|
file.id
|
|
@@ -13544,10 +13789,10 @@ function FileBrowser({
|
|
|
13544
13789
|
}
|
|
13545
13790
|
) })
|
|
13546
13791
|
] }),
|
|
13547
|
-
/* @__PURE__ */
|
|
13548
|
-
/* @__PURE__ */
|
|
13549
|
-
/* @__PURE__ */
|
|
13550
|
-
] }), children: /* @__PURE__ */
|
|
13792
|
+
/* @__PURE__ */ jsx97(Modal, { open: createOpen, title: "New folder", onClose: () => setCreateOpen(false), footer: /* @__PURE__ */ jsxs88(Fragment28, { children: [
|
|
13793
|
+
/* @__PURE__ */ jsx97(Button, { variant: "secondary", onClick: () => setCreateOpen(false), children: "Cancel" }),
|
|
13794
|
+
/* @__PURE__ */ jsx97(Button, { onClick: submitCreate, disabled: !createName.trim(), children: "Create" })
|
|
13795
|
+
] }), children: /* @__PURE__ */ jsx97(
|
|
13551
13796
|
"input",
|
|
13552
13797
|
{
|
|
13553
13798
|
className: "fd-fb-input",
|
|
@@ -13561,10 +13806,10 @@ function FileBrowser({
|
|
|
13561
13806
|
autoFocus: true
|
|
13562
13807
|
}
|
|
13563
13808
|
) }),
|
|
13564
|
-
/* @__PURE__ */
|
|
13565
|
-
/* @__PURE__ */
|
|
13566
|
-
/* @__PURE__ */
|
|
13567
|
-
] }), children: /* @__PURE__ */
|
|
13809
|
+
/* @__PURE__ */ jsx97(Modal, { open: renameTarget != null, title: "Rename folder", onClose: () => setRenameTarget(null), footer: /* @__PURE__ */ jsxs88(Fragment28, { children: [
|
|
13810
|
+
/* @__PURE__ */ jsx97(Button, { variant: "secondary", onClick: () => setRenameTarget(null), children: "Cancel" }),
|
|
13811
|
+
/* @__PURE__ */ jsx97(Button, { onClick: submitRename, disabled: !renameValue.trim(), children: "Save" })
|
|
13812
|
+
] }), children: /* @__PURE__ */ jsx97(
|
|
13568
13813
|
"input",
|
|
13569
13814
|
{
|
|
13570
13815
|
className: "fd-fb-input",
|
|
@@ -13578,22 +13823,22 @@ function FileBrowser({
|
|
|
13578
13823
|
autoFocus: true
|
|
13579
13824
|
}
|
|
13580
13825
|
) }),
|
|
13581
|
-
/* @__PURE__ */
|
|
13826
|
+
/* @__PURE__ */ jsx97(
|
|
13582
13827
|
Modal,
|
|
13583
13828
|
{
|
|
13584
13829
|
open: deleteTarget != null,
|
|
13585
13830
|
title: deleteTarget ? "Delete \u201C" + deleteTarget.name + "\u201D?" : "Delete folder?",
|
|
13586
13831
|
description: "This can't be undone. The folder must be empty.",
|
|
13587
13832
|
onClose: () => setDeleteTarget(null),
|
|
13588
|
-
footer: /* @__PURE__ */
|
|
13589
|
-
/* @__PURE__ */
|
|
13590
|
-
/* @__PURE__ */
|
|
13833
|
+
footer: /* @__PURE__ */ jsxs88(Fragment28, { children: [
|
|
13834
|
+
/* @__PURE__ */ jsx97(Button, { variant: "secondary", onClick: () => setDeleteTarget(null), children: "Cancel" }),
|
|
13835
|
+
/* @__PURE__ */ jsx97(Button, { variant: "danger", onClick: confirmDelete, children: "Delete" })
|
|
13591
13836
|
] })
|
|
13592
13837
|
}
|
|
13593
13838
|
)
|
|
13594
13839
|
] });
|
|
13595
13840
|
if (!canUpload) return content;
|
|
13596
|
-
return /* @__PURE__ */
|
|
13841
|
+
return /* @__PURE__ */ jsx97(Dropzone, { className: "fd-fb-dropzone", onFiles: (picked) => onUpload && onUpload(picked, currentFolderId), label: "Drop files to upload", children: content });
|
|
13597
13842
|
}
|
|
13598
13843
|
function BreadcrumbCrumb({
|
|
13599
13844
|
label,
|
|
@@ -13602,8 +13847,8 @@ function BreadcrumbCrumb({
|
|
|
13602
13847
|
isDropTarget,
|
|
13603
13848
|
onDropPayload
|
|
13604
13849
|
}) {
|
|
13605
|
-
const [over, setOver] =
|
|
13606
|
-
const dragCounter =
|
|
13850
|
+
const [over, setOver] = React66.useState(false);
|
|
13851
|
+
const dragCounter = React66.useRef(0);
|
|
13607
13852
|
const dropHandlers = isDropTarget ? {
|
|
13608
13853
|
onDragEnter: (e) => {
|
|
13609
13854
|
if (!hasInternalPayload(e)) return;
|
|
@@ -13628,11 +13873,11 @@ function BreadcrumbCrumb({
|
|
|
13628
13873
|
if (payload && onDropPayload) onDropPayload(payload);
|
|
13629
13874
|
}
|
|
13630
13875
|
} : {};
|
|
13631
|
-
return /* @__PURE__ */
|
|
13876
|
+
return /* @__PURE__ */ jsx97("span", { className: ["fd-fb-crumb", over ? "is-drop-target" : ""].filter(Boolean).join(" "), ...dropHandlers, children: isCurrent ? /* @__PURE__ */ jsx97("span", { className: "fd-fb-crumb-current", "aria-current": "page", children: label }) : /* @__PURE__ */ jsx97("button", { type: "button", className: "fd-fb-crumb-link", onClick, children: label }) });
|
|
13632
13877
|
}
|
|
13633
13878
|
|
|
13634
13879
|
// src/kits/query.ts
|
|
13635
|
-
import * as
|
|
13880
|
+
import * as React67 from "react";
|
|
13636
13881
|
var isMultiSelectShaped = (v) => !!v && typeof v === "object" && Array.isArray(v.values);
|
|
13637
13882
|
var isRangeShaped = (v) => !!v && typeof v === "object" && ("min" in v || "max" in v);
|
|
13638
13883
|
var isDateShaped = (v) => !!v && typeof v === "object" && "kind" in v;
|
|
@@ -13687,22 +13932,22 @@ function compare(a, b, dir) {
|
|
|
13687
13932
|
var API = null;
|
|
13688
13933
|
var PREFS = null;
|
|
13689
13934
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
|
|
13690
|
-
const [query, setQuery] =
|
|
13935
|
+
const [query, setQuery] = React67.useState(() => {
|
|
13691
13936
|
const store = PREFS || window.PlannerPrefs;
|
|
13692
13937
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
13693
13938
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
13694
13939
|
});
|
|
13695
|
-
const savePref =
|
|
13940
|
+
const savePref = React67.useCallback((patch2) => {
|
|
13696
13941
|
const store = PREFS || window.PlannerPrefs;
|
|
13697
13942
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
13698
13943
|
}, [prefsKey]);
|
|
13699
|
-
const [res, setRes] =
|
|
13700
|
-
const [loading, setLoading] =
|
|
13701
|
-
const seq2 =
|
|
13944
|
+
const [res, setRes] = React67.useState(null);
|
|
13945
|
+
const [loading, setLoading] = React67.useState(true);
|
|
13946
|
+
const seq2 = React67.useRef(0);
|
|
13702
13947
|
const depKey = (deps || []).join("|");
|
|
13703
13948
|
const paramKey = JSON.stringify(params || {});
|
|
13704
13949
|
const queryKey = JSON.stringify(query);
|
|
13705
|
-
|
|
13950
|
+
React67.useEffect(() => {
|
|
13706
13951
|
const id = ++seq2.current;
|
|
13707
13952
|
setLoading(true);
|
|
13708
13953
|
const t = setTimeout(() => {
|
|
@@ -14021,12 +14266,12 @@ function createVersionStore(initialState, options) {
|
|
|
14021
14266
|
}
|
|
14022
14267
|
|
|
14023
14268
|
// src/kits/documentTitle.ts
|
|
14024
|
-
import * as
|
|
14269
|
+
import * as React68 from "react";
|
|
14025
14270
|
function formatDocumentTitle(routeTitle, appName) {
|
|
14026
14271
|
return [routeTitle, appName, "Flytedesk"].filter((part) => !!part && part.length > 0).join(" \xB7 ");
|
|
14027
14272
|
}
|
|
14028
14273
|
function useDocumentTitle(routeTitle, appName) {
|
|
14029
|
-
|
|
14274
|
+
React68.useEffect(() => {
|
|
14030
14275
|
if (typeof document === "undefined") return;
|
|
14031
14276
|
document.title = formatDocumentTitle(routeTitle, appName);
|
|
14032
14277
|
}, [routeTitle, appName]);
|
|
@@ -14068,6 +14313,7 @@ export {
|
|
|
14068
14313
|
Clamp,
|
|
14069
14314
|
ClockFace,
|
|
14070
14315
|
CodeBlock,
|
|
14316
|
+
CodeEditor,
|
|
14071
14317
|
Collapsible,
|
|
14072
14318
|
ComingSoon,
|
|
14073
14319
|
CsiBadge,
|
|
@@ -14113,6 +14359,7 @@ export {
|
|
|
14113
14359
|
JobTray,
|
|
14114
14360
|
Json,
|
|
14115
14361
|
KeyHint,
|
|
14362
|
+
LAYER_STEP,
|
|
14116
14363
|
LoadingRegion,
|
|
14117
14364
|
Markdown,
|
|
14118
14365
|
MarkdownEditor,
|
|
@@ -14127,6 +14374,7 @@ export {
|
|
|
14127
14374
|
ModeSwitch,
|
|
14128
14375
|
ModelControls,
|
|
14129
14376
|
NumberInput,
|
|
14377
|
+
OVERLAY_CEILING,
|
|
14130
14378
|
POPOVER_BODY_MIN,
|
|
14131
14379
|
PacketCard,
|
|
14132
14380
|
Pagination,
|
|
@@ -14139,6 +14387,7 @@ export {
|
|
|
14139
14387
|
ProgressBar,
|
|
14140
14388
|
QueryKit,
|
|
14141
14389
|
QuotaRow,
|
|
14390
|
+
ROOT_STEP,
|
|
14142
14391
|
Radio,
|
|
14143
14392
|
RangeSlider,
|
|
14144
14393
|
RelativeTime,
|
|
@@ -14183,6 +14432,7 @@ export {
|
|
|
14183
14432
|
VIRTUAL_LIST_BUFFER_ROWS,
|
|
14184
14433
|
VIRTUAL_LIST_ROW_GAP,
|
|
14185
14434
|
VirtualList,
|
|
14435
|
+
__resetLayerStackForTests,
|
|
14186
14436
|
acceptMatches,
|
|
14187
14437
|
anyOfFilter,
|
|
14188
14438
|
applyPrefs,
|
|
@@ -14232,6 +14482,7 @@ export {
|
|
|
14232
14482
|
useChatEngine,
|
|
14233
14483
|
useDocumentTitle,
|
|
14234
14484
|
useFeatureStatus,
|
|
14485
|
+
useLayerZIndex,
|
|
14235
14486
|
usePopoverPosition,
|
|
14236
14487
|
useResponsiveRail,
|
|
14237
14488
|
useRuntimeMode,
|