@flytedan/flytebot-design-system 0.12.11 → 0.12.13
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 +250 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -9
- package/dist/index.d.ts +57 -9
- package/dist/index.js +246 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components.css +236 -9
- package/styles/tokens.css +22 -6
package/dist/index.cjs
CHANGED
|
@@ -73,6 +73,8 @@ __export(index_exports, {
|
|
|
73
73
|
EmptyState: () => EmptyState,
|
|
74
74
|
EntityRow: () => EntityRow,
|
|
75
75
|
EntityRowMetrics: () => EntityRowMetrics,
|
|
76
|
+
FILE_VIEWER_CSV_ROW_LIMIT: () => FILE_VIEWER_CSV_ROW_LIMIT,
|
|
77
|
+
FILE_VIEWER_TEXT_LIMIT: () => FILE_VIEWER_TEXT_LIMIT,
|
|
76
78
|
FeatureGate: () => FeatureGate,
|
|
77
79
|
FileChip: () => FileChip,
|
|
78
80
|
FileGrid: () => FileGrid,
|
|
@@ -80,6 +82,7 @@ __export(index_exports, {
|
|
|
80
82
|
FilePickButton: () => FilePickButton,
|
|
81
83
|
FileStrip: () => FileStrip,
|
|
82
84
|
FileTile: () => FileTile,
|
|
85
|
+
FileViewer: () => FileViewer,
|
|
83
86
|
FilterBar: () => FilterBar,
|
|
84
87
|
Flag: () => Flag,
|
|
85
88
|
FlytedeskBrand: () => FlytedeskBrand,
|
|
@@ -184,6 +187,7 @@ __export(index_exports, {
|
|
|
184
187
|
markdownToText: () => markdownToText,
|
|
185
188
|
meterFormats: () => meterFormats,
|
|
186
189
|
modifierLabel: () => modifierLabel,
|
|
190
|
+
parseDelimited: () => parseDelimited,
|
|
187
191
|
pastedTextName: () => pastedTextName,
|
|
188
192
|
pluralizeUnit: () => pluralizeUnit,
|
|
189
193
|
preferenceScore: () => preferenceScore,
|
|
@@ -772,6 +776,11 @@ function SegmentedControl({ options = [], value, onChange, className = "", ...re
|
|
|
772
776
|
}) });
|
|
773
777
|
}
|
|
774
778
|
|
|
779
|
+
// src/components/textExposure.ts
|
|
780
|
+
function truncationTitle(content) {
|
|
781
|
+
return typeof content === "string" || typeof content === "number" ? String(content) : void 0;
|
|
782
|
+
}
|
|
783
|
+
|
|
775
784
|
// src/components/surfaces/Card.tsx
|
|
776
785
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
777
786
|
function Card({
|
|
@@ -793,7 +802,7 @@ function Card({
|
|
|
793
802
|
].filter(Boolean).join(" ");
|
|
794
803
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cls, ...rest, children: [
|
|
795
804
|
title ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "fd-card-head", children: [
|
|
796
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "fd-card-head-title", children: title }),
|
|
805
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "fd-card-head-title", title: truncationTitle(title), children: title }),
|
|
797
806
|
action
|
|
798
807
|
] }) : null,
|
|
799
808
|
padded ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "fd-card-body", children }) : children,
|
|
@@ -869,7 +878,7 @@ function Drawer({ open = true, title, onClose, footer, children, className = "",
|
|
|
869
878
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "fd-scrim" + (closing ? " is-closing" : ""), style: { display: "block", zIndex: zIndex - LAYER_STEP }, onClick: close }),
|
|
870
879
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("aside", { className: ["fd-drawer", closing ? "is-closing" : "", className].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", ...rest, style: { zIndex }, children: [
|
|
871
880
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "fd-card-head", style: { flex: "none" }, children: [
|
|
872
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "fd-card-head-title", children: title }),
|
|
881
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "fd-card-head-title", title: truncationTitle(title), children: title }),
|
|
873
882
|
onClose ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Close", onClick: close, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("i", { className: "ph ph-x" }) }) : null
|
|
874
883
|
] }),
|
|
875
884
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: "1 1 auto", minHeight: 0, overflow: "auto", padding: 20 }, children }),
|
|
@@ -1151,7 +1160,12 @@ function Topbar({
|
|
|
1151
1160
|
onMenu ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("i", { className: "ph ph-list" }) }) : null,
|
|
1152
1161
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React6.Fragment, { children: [
|
|
1153
1162
|
i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
|
|
1154
|
-
i === crumbs.length - 1 ?
|
|
1163
|
+
i === crumbs.length - 1 ? (
|
|
1164
|
+
// MP-141: the current crumb mixes a static route label with (usually) a
|
|
1165
|
+
// user-entered campaign name and is single-line by design — exposure,
|
|
1166
|
+
// not wrapping, is the fix here, same rule as every other identifier.
|
|
1167
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fd-crumb-current", title: truncationTitle(c.label), children: c.label })
|
|
1168
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1155
1169
|
"a",
|
|
1156
1170
|
{
|
|
1157
1171
|
href: c.href || "#",
|
|
@@ -2746,12 +2760,12 @@ function SegmentedMeter({
|
|
|
2746
2760
|
legend ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("ul", { className: "fd-segmeter-legend", children: [
|
|
2747
2761
|
items.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("li", { children: [
|
|
2748
2762
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fd-segmeter-dot", style: { background: fill(s, i) }, "aria-hidden": "true" }),
|
|
2749
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fd-segmeter-key", children: s.label }),
|
|
2763
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fd-segmeter-key", title: truncationTitle(s.label), children: s.label }),
|
|
2750
2764
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fd-segmeter-val fd-tabular", children: format(s.value) })
|
|
2751
2765
|
] }, s.id || s.label || i)),
|
|
2752
2766
|
safeTotal && used < safeTotal ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("li", { className: "is-remainder", children: [
|
|
2753
2767
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fd-segmeter-dot is-empty", "aria-hidden": "true" }),
|
|
2754
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fd-segmeter-key", children: remainderLabel }),
|
|
2768
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fd-segmeter-key", title: truncationTitle(remainderLabel), children: remainderLabel }),
|
|
2755
2769
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fd-segmeter-val fd-tabular", children: format(safeTotal - used) })
|
|
2756
2770
|
] }) : null
|
|
2757
2771
|
] }) : null
|
|
@@ -3193,7 +3207,11 @@ function EntityRow({
|
|
|
3193
3207
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "fd-erow-title fd-body-sm", children: title })
|
|
3194
3208
|
]
|
|
3195
3209
|
}
|
|
3196
|
-
) }) :
|
|
3210
|
+
) }) : (
|
|
3211
|
+
// MP-141: dense-row identifier, no Tooltip wrapper in this branch — a native
|
|
3212
|
+
// `title` is the exposure mechanism, same rule as every other identifier.
|
|
3213
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "fd-erow-title fd-body-sm", title: truncationTitle(title), children: title })
|
|
3214
|
+
),
|
|
3197
3215
|
meta ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "fd-erow-meta", children: meta }) : null
|
|
3198
3216
|
] }),
|
|
3199
3217
|
hasStrip ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "fd-erow-strip", children: [
|
|
@@ -4672,7 +4690,7 @@ function useStagedFiles(upload, opts) {
|
|
|
4672
4690
|
patch(att.id, { progress: 0, error: void 0 });
|
|
4673
4691
|
Promise.resolve().then(() => upload(att.file, (p) => patch(att.id, { progress: Math.max(0, Math.min(99, p)) }), ac ? ac.signal : void 0)).then((res) => {
|
|
4674
4692
|
const r = res || {};
|
|
4675
|
-
patch(att.id, {
|
|
4693
|
+
patch(att.id, Object.assign({}, r, { id: r.id || att.id, progress: 100, error: void 0 }));
|
|
4676
4694
|
o.onUploaded && o.onUploaded(att);
|
|
4677
4695
|
}).catch((err) => {
|
|
4678
4696
|
if (ac && ac.signal.aborted) return;
|
|
@@ -9668,7 +9686,9 @@ function ChatComposer({
|
|
|
9668
9686
|
const submit = () => {
|
|
9669
9687
|
if (!canSend) return;
|
|
9670
9688
|
onSubmit(text.trim(), staged.items.map((f) => {
|
|
9671
|
-
const { file
|
|
9689
|
+
const { file, blobUrl, ...rest } = f;
|
|
9690
|
+
void file;
|
|
9691
|
+
void blobUrl;
|
|
9672
9692
|
return rest;
|
|
9673
9693
|
}));
|
|
9674
9694
|
change("");
|
|
@@ -10363,8 +10383,219 @@ function AgentChatPanel({
|
|
|
10363
10383
|
);
|
|
10364
10384
|
}
|
|
10365
10385
|
|
|
10366
|
-
// src/
|
|
10386
|
+
// src/components/files/FileViewer.tsx
|
|
10367
10387
|
var React47 = __toESM(require("react"), 1);
|
|
10388
|
+
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
10389
|
+
function previewKindOf(file) {
|
|
10390
|
+
const mime = (file.mime || "").toLowerCase();
|
|
10391
|
+
const ext = extensionOf(file.name || "");
|
|
10392
|
+
if (isImage(mime, file.name)) return "image";
|
|
10393
|
+
if (mime === "application/pdf" || ext === "pdf") return "pdf";
|
|
10394
|
+
if (mime === "text/markdown" || ext === "md" || ext === "markdown") return "markdown";
|
|
10395
|
+
if (mime === "application/json" || ext === "json") return "json";
|
|
10396
|
+
if (mime === "text/csv" || mime === "text/tab-separated-values" || ext === "csv" || ext === "tsv") return "csv";
|
|
10397
|
+
if (mime.startsWith("text/") || ext === "txt" || ext === "log") return "text";
|
|
10398
|
+
return "none";
|
|
10399
|
+
}
|
|
10400
|
+
var FILE_VIEWER_TEXT_LIMIT = 5e5;
|
|
10401
|
+
var FILE_VIEWER_CSV_ROW_LIMIT = 500;
|
|
10402
|
+
function parseDelimited(text, delimiter) {
|
|
10403
|
+
const rows = [];
|
|
10404
|
+
let row = [];
|
|
10405
|
+
let field = "";
|
|
10406
|
+
let inQuotes = false;
|
|
10407
|
+
for (let i = 0; i < text.length; i++) {
|
|
10408
|
+
const c = text[i];
|
|
10409
|
+
if (inQuotes) {
|
|
10410
|
+
if (c === '"') {
|
|
10411
|
+
if (text[i + 1] === '"') {
|
|
10412
|
+
field += '"';
|
|
10413
|
+
i++;
|
|
10414
|
+
} else inQuotes = false;
|
|
10415
|
+
} else field += c;
|
|
10416
|
+
continue;
|
|
10417
|
+
}
|
|
10418
|
+
if (c === '"') {
|
|
10419
|
+
inQuotes = true;
|
|
10420
|
+
continue;
|
|
10421
|
+
}
|
|
10422
|
+
if (c === delimiter) {
|
|
10423
|
+
row.push(field);
|
|
10424
|
+
field = "";
|
|
10425
|
+
continue;
|
|
10426
|
+
}
|
|
10427
|
+
if (c === "\n") {
|
|
10428
|
+
row.push(field);
|
|
10429
|
+
rows.push(row);
|
|
10430
|
+
row = [];
|
|
10431
|
+
field = "";
|
|
10432
|
+
continue;
|
|
10433
|
+
}
|
|
10434
|
+
if (c === "\r") continue;
|
|
10435
|
+
field += c;
|
|
10436
|
+
}
|
|
10437
|
+
if (field.length || row.length) {
|
|
10438
|
+
row.push(field);
|
|
10439
|
+
rows.push(row);
|
|
10440
|
+
}
|
|
10441
|
+
return rows;
|
|
10442
|
+
}
|
|
10443
|
+
function usePreview(file, kind, resolveUrl) {
|
|
10444
|
+
const [state, setState] = React47.useState({ status: "loading" });
|
|
10445
|
+
const [attempt, setAttempt] = React47.useState(0);
|
|
10446
|
+
const resolveRef = React47.useRef(resolveUrl);
|
|
10447
|
+
React47.useEffect(() => {
|
|
10448
|
+
resolveRef.current = resolveUrl;
|
|
10449
|
+
}, [resolveUrl]);
|
|
10450
|
+
React47.useEffect(() => {
|
|
10451
|
+
if (kind === "none") {
|
|
10452
|
+
setState({ status: "ready" });
|
|
10453
|
+
return;
|
|
10454
|
+
}
|
|
10455
|
+
let dead = false;
|
|
10456
|
+
const ac = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
10457
|
+
setState({ status: "loading" });
|
|
10458
|
+
resolveRef.current("inline").then((url) => {
|
|
10459
|
+
if (dead) return void 0;
|
|
10460
|
+
if (kind === "image" || kind === "pdf") {
|
|
10461
|
+
setState({ status: "ready", url });
|
|
10462
|
+
return void 0;
|
|
10463
|
+
}
|
|
10464
|
+
return fetch(url, ac ? { signal: ac.signal } : void 0).then((res) => {
|
|
10465
|
+
if (!res.ok) throw new Error("The preview didn't load (" + res.status + ").");
|
|
10466
|
+
return res.text();
|
|
10467
|
+
}).then((body) => {
|
|
10468
|
+
if (dead) return;
|
|
10469
|
+
setState({ status: "ready", url, text: body.length > FILE_VIEWER_TEXT_LIMIT ? body.slice(0, FILE_VIEWER_TEXT_LIMIT) : body });
|
|
10470
|
+
});
|
|
10471
|
+
}).catch((err) => {
|
|
10472
|
+
if (dead || ac && ac.signal.aborted) return;
|
|
10473
|
+
setState({ status: "error", error: err && err.message || "The preview didn't load." });
|
|
10474
|
+
});
|
|
10475
|
+
return () => {
|
|
10476
|
+
dead = true;
|
|
10477
|
+
if (ac) ac.abort();
|
|
10478
|
+
};
|
|
10479
|
+
}, [file.id, kind, attempt]);
|
|
10480
|
+
return { ...state, retry: React47.useCallback(() => setAttempt((a) => a + 1), []) };
|
|
10481
|
+
}
|
|
10482
|
+
function PreviewBody({ file, kind, state }) {
|
|
10483
|
+
if (kind === "image") return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
|
|
10484
|
+
if (kind === "pdf") return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("iframe", { className: "fd-fv-pdf", src: state.url, title: file.name || "PDF preview" });
|
|
10485
|
+
if (kind === "markdown") return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Markdown, { className: "fd-fv-markdown", source: state.text || "" });
|
|
10486
|
+
if (kind === "json") {
|
|
10487
|
+
let pretty = state.text || "";
|
|
10488
|
+
try {
|
|
10489
|
+
pretty = JSON.stringify(JSON.parse(pretty), null, 2);
|
|
10490
|
+
} catch {
|
|
10491
|
+
}
|
|
10492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(CodeBlock, { code: pretty, language: "json" });
|
|
10493
|
+
}
|
|
10494
|
+
if (kind === "csv") {
|
|
10495
|
+
const tsv = extensionOf(file.name || "") === "tsv" || (file.mime || "").toLowerCase().includes("tab-separated");
|
|
10496
|
+
const rows = parseDelimited(state.text || "", tsv ? " " : ",").filter((r) => r.length > 1 || r[0] !== "");
|
|
10497
|
+
const head = rows[0] || [];
|
|
10498
|
+
const dataRows = rows.slice(1);
|
|
10499
|
+
const shown = dataRows.slice(0, FILE_VIEWER_CSV_ROW_LIMIT);
|
|
10500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "fd-fv-csv", children: [
|
|
10501
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("table", { className: "fd-fv-csv-table", children: [
|
|
10502
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("tr", { children: head.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("th", { children: c }, i)) }) }),
|
|
10503
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("tbody", { children: shown.map((r, ri) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("tr", { children: head.map((_, ci) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("td", { children: r[ci] ?? "" }, ci)) }, ri)) })
|
|
10504
|
+
] }),
|
|
10505
|
+
dataRows.length > FILE_VIEWER_CSV_ROW_LIMIT ? /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("p", { className: "fd-fv-csv-note fd-body-sm fd-muted", children: [
|
|
10506
|
+
"Showing the first ",
|
|
10507
|
+
FILE_VIEWER_CSV_ROW_LIMIT.toLocaleString(),
|
|
10508
|
+
" of ",
|
|
10509
|
+
dataRows.length.toLocaleString(),
|
|
10510
|
+
" rows."
|
|
10511
|
+
] }) : null
|
|
10512
|
+
] });
|
|
10513
|
+
}
|
|
10514
|
+
if (kind === "text") return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(CodeBlock, { code: state.text || "", language: extensionOf(file.name || "") || void 0 });
|
|
10515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "fd-fv-fallback", children: [
|
|
10516
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "fd-fv-fallback-icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
|
|
10517
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "fd-fv-fallback-title", children: "No preview available" }),
|
|
10518
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "fd-fv-fallback-meta", children: [
|
|
10519
|
+
file.mime || "Unknown type",
|
|
10520
|
+
file.size ? " \xB7 " + formatBytes(file.size) : ""
|
|
10521
|
+
] })
|
|
10522
|
+
] });
|
|
10523
|
+
}
|
|
10524
|
+
function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
|
|
10525
|
+
const kind = React47.useMemo(() => previewKindOf(file), [file]);
|
|
10526
|
+
const preview = usePreview(file, kind, resolveUrl);
|
|
10527
|
+
const [tab, setTab] = React47.useState("preview");
|
|
10528
|
+
const [downloading, setDownloading] = React47.useState(false);
|
|
10529
|
+
const [downloadError, setDownloadError] = React47.useState(null);
|
|
10530
|
+
const hasSide = sidePanel != null;
|
|
10531
|
+
React47.useEffect(() => {
|
|
10532
|
+
setTab("preview");
|
|
10533
|
+
}, [file.id]);
|
|
10534
|
+
const download = () => {
|
|
10535
|
+
setDownloading(true);
|
|
10536
|
+
setDownloadError(null);
|
|
10537
|
+
resolveUrl("attachment").then((url) => {
|
|
10538
|
+
const a = document.createElement("a");
|
|
10539
|
+
a.href = url;
|
|
10540
|
+
a.rel = "noopener";
|
|
10541
|
+
a.download = file.name || "";
|
|
10542
|
+
document.body.appendChild(a);
|
|
10543
|
+
a.click();
|
|
10544
|
+
a.remove();
|
|
10545
|
+
}).catch((err) => setDownloadError(err && err.message || "Download failed.")).finally(() => setDownloading(false));
|
|
10546
|
+
};
|
|
10547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
|
|
10548
|
+
"section",
|
|
10549
|
+
{
|
|
10550
|
+
className: ["fd-fv", hasSide && tab === "side" ? "is-tab-side" : "is-tab-preview", className].filter(Boolean).join(" "),
|
|
10551
|
+
"aria-label": file.name || "File",
|
|
10552
|
+
children: [
|
|
10553
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("header", { className: "fd-fv-head", children: [
|
|
10554
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "fd-fv-head-icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
|
|
10555
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "fd-fv-head-titles", children: [
|
|
10556
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "fd-fv-head-title", title: file.name, children: file.name }),
|
|
10557
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "fd-fv-head-meta", children: [
|
|
10558
|
+
file.mime || "Unknown type",
|
|
10559
|
+
file.size ? " \xB7 " + formatBytes(file.size) : ""
|
|
10560
|
+
] })
|
|
10561
|
+
] }),
|
|
10562
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "fd-fv-head-actions", children: [
|
|
10563
|
+
actions,
|
|
10564
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Button, { variant: "secondary", size: "sm", icon: "download-simple", loading: downloading, onClick: download, children: "Download" }),
|
|
10565
|
+
onClose ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(IconButton, { icon: "x", label: "Close", onClick: onClose }) : null
|
|
10566
|
+
] })
|
|
10567
|
+
] }),
|
|
10568
|
+
downloadError ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "fd-fv-download-error", role: "alert", children: downloadError }) : null,
|
|
10569
|
+
hasSide ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
10570
|
+
Tabs,
|
|
10571
|
+
{
|
|
10572
|
+
className: "fd-fv-tabs",
|
|
10573
|
+
tabs: [{ value: "preview", label: "Preview" }, { value: "side", label: sidePanelLabel }],
|
|
10574
|
+
value: tab,
|
|
10575
|
+
onChange: (v) => setTab(v)
|
|
10576
|
+
}
|
|
10577
|
+
) : null,
|
|
10578
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "fd-fv-body", children: [
|
|
10579
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "fd-fv-preview", role: "region", "aria-label": "Preview of " + (file.name || "file"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
10580
|
+
LoadingRegion,
|
|
10581
|
+
{
|
|
10582
|
+
state: preview.status === "loading" ? "loading" : preview.status === "error" ? "error" : "ready",
|
|
10583
|
+
error: preview.error,
|
|
10584
|
+
label: "Loading preview of " + (file.name || "file"),
|
|
10585
|
+
onRetry: preview.status === "error" ? preview.retry : void 0,
|
|
10586
|
+
skeleton: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Skeleton, { shape: "card", h: 220 }),
|
|
10587
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(PreviewBody, { file, kind, state: preview })
|
|
10588
|
+
}
|
|
10589
|
+
) }),
|
|
10590
|
+
hasSide ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "fd-fv-side", role: "region", "aria-label": sidePanelLabel, children: sidePanel }) : null
|
|
10591
|
+
] })
|
|
10592
|
+
]
|
|
10593
|
+
}
|
|
10594
|
+
);
|
|
10595
|
+
}
|
|
10596
|
+
|
|
10597
|
+
// src/kits/query.ts
|
|
10598
|
+
var React48 = __toESM(require("react"), 1);
|
|
10368
10599
|
function eqFilter(get2) {
|
|
10369
10600
|
return (row, value) => Array.isArray(value) ? value.includes(get2(row)) : get2(row) === value;
|
|
10370
10601
|
}
|
|
@@ -10396,22 +10627,22 @@ function compare(a, b, dir) {
|
|
|
10396
10627
|
var API = null;
|
|
10397
10628
|
var PREFS = null;
|
|
10398
10629
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
|
|
10399
|
-
const [query, setQuery] =
|
|
10630
|
+
const [query, setQuery] = React48.useState(() => {
|
|
10400
10631
|
const store = PREFS || window.PlannerPrefs;
|
|
10401
10632
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
10402
10633
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
10403
10634
|
});
|
|
10404
|
-
const savePref =
|
|
10635
|
+
const savePref = React48.useCallback((patch2) => {
|
|
10405
10636
|
const store = PREFS || window.PlannerPrefs;
|
|
10406
10637
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
10407
10638
|
}, [prefsKey]);
|
|
10408
|
-
const [res, setRes] =
|
|
10409
|
-
const [loading, setLoading] =
|
|
10410
|
-
const seq2 =
|
|
10639
|
+
const [res, setRes] = React48.useState(null);
|
|
10640
|
+
const [loading, setLoading] = React48.useState(true);
|
|
10641
|
+
const seq2 = React48.useRef(0);
|
|
10411
10642
|
const depKey = (deps || []).join("|");
|
|
10412
10643
|
const paramKey = JSON.stringify(params || {});
|
|
10413
10644
|
const queryKey = JSON.stringify(query);
|
|
10414
|
-
|
|
10645
|
+
React48.useEffect(() => {
|
|
10415
10646
|
const id = ++seq2.current;
|
|
10416
10647
|
setLoading(true);
|
|
10417
10648
|
const t = setTimeout(() => {
|
|
@@ -10753,6 +10984,8 @@ function createVersionStore(initialState, options) {
|
|
|
10753
10984
|
EmptyState,
|
|
10754
10985
|
EntityRow,
|
|
10755
10986
|
EntityRowMetrics,
|
|
10987
|
+
FILE_VIEWER_CSV_ROW_LIMIT,
|
|
10988
|
+
FILE_VIEWER_TEXT_LIMIT,
|
|
10756
10989
|
FeatureGate,
|
|
10757
10990
|
FileChip,
|
|
10758
10991
|
FileGrid,
|
|
@@ -10760,6 +10993,7 @@ function createVersionStore(initialState, options) {
|
|
|
10760
10993
|
FilePickButton,
|
|
10761
10994
|
FileStrip,
|
|
10762
10995
|
FileTile,
|
|
10996
|
+
FileViewer,
|
|
10763
10997
|
FilterBar,
|
|
10764
10998
|
Flag,
|
|
10765
10999
|
FlytedeskBrand,
|
|
@@ -10864,6 +11098,7 @@ function createVersionStore(initialState, options) {
|
|
|
10864
11098
|
markdownToText,
|
|
10865
11099
|
meterFormats,
|
|
10866
11100
|
modifierLabel,
|
|
11101
|
+
parseDelimited,
|
|
10867
11102
|
pastedTextName,
|
|
10868
11103
|
pluralizeUnit,
|
|
10869
11104
|
preferenceScore,
|