wcz-layout
Version:
2,092 lines • 64.3 kB
JavaScript
import { d as sanitizeReturnTo, m as loginProvidersQueryOptions } from "./utils-obBGIuT3.mjs";
import { n as RouterIconButton, t as RouterListItemButton } from "./RouterListItemButton-B-cQ1XwU.mjs";
import { a as fileQueryOptions, i as fileMetasQueryOptions, n as deleteFileMutationOptions, o as fileThumbnailQueryOptions, r as downloadFileMutationOptions, s as openFileMutationOptions } from "./file-CwumKq_P.mjs";
import { T as useDialogs, a as columnAlign, c as hasColumnLabel, f as pinnedClass, g as DEFAULT_PAGE_SIZE_OPTIONS, h as toClipboardText, i as classNames, l as layoutTableClasses, o as columnFlex, p as pinnedSx, r as cellSelectionSx, t as AggregatedCell, u as lookaheadRange } from "./AggregatedCell-3CIdlmt6.mjs";
import { c } from "react/compiler-runtime";
import { Box, Button, ButtonBase, Card, CardContent, CircularProgress, Dialog, Divider, Fab, IconButton, ImageListItem, ImageListItemBar, Link, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Menu, MenuItem, Paper, Skeleton, Stack, Tab, Table, TableBody, TableCell, TableContainer, TableFooter, TableHead, TableRow, Tooltip, Typography, alpha, useTheme } from "@mui/material";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import React, { Fragment, createContext, useContext, useEffect, useEffectEvent, useLayoutEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { manifest } from "virtual:wcz-layout";
import { createLink, rootRouteId, useLocation, useMatch } from "@tanstack/react-router";
import ChevronRight from "@mui/icons-material/ChevronRight";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import Close from "@mui/icons-material/Close";
import CloudQueue from "@mui/icons-material/CloudQueue";
import Microsoft from "@mui/icons-material/Microsoft";
import CloudUpload from "@mui/icons-material/CloudUpload";
import { useDropzone } from "react-dropzone";
import MoreVert from "@mui/icons-material/MoreVert";
import { grey } from "@mui/material/colors";
import { useInView } from "react-intersection-observer";
import Delete from "@mui/icons-material/Delete";
import FileDownload from "@mui/icons-material/FileDownload";
import AttachFile from "@mui/icons-material/AttachFile";
import Image from "@mui/icons-material/Image";
import SmartDisplay from "@mui/icons-material/SmartDisplay";
import ChevronLeft from "@mui/icons-material/ChevronLeft";
import { useHotkeys } from "@tanstack/react-hotkeys";
import { useVirtualizer } from "@tanstack/react-virtual";
// src/components/core/account/LoginForm.tsx
const LAST_PROVIDER_KEY = "auth-provider";
const PROVIDER_ICON = {
entra: /* @__PURE__ */ jsx(Microsoft, {}),
aws: /* @__PURE__ */ jsx(CloudQueue, {})
};
/**
* The provider chooser card. Mount it at `/login` — `requireAuth` redirects there,
* and it reads `?returnTo` from the URL itself, so it takes no props.
*/
const LoginForm = () => {
const $ = c(36);
if ($[0] !== "5f14f2dd7f994bdd88840e3f375e9ee4b049c4d266a9eaf4b3e2533ff17cc7c6") {
for (let $i = 0; $i < 36; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "5f14f2dd7f994bdd88840e3f375e9ee4b049c4d266a9eaf4b3e2533ff17cc7c6";
}
const { data: t0 } = useQuery(loginProvidersQueryOptions);
let t1;
if ($[1] !== t0) {
t1 = t0 === void 0 ? [] : t0;
$[1] = t0;
$[2] = t1;
} else t1 = $[2];
const providers = t1;
let t2;
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
t2 = { select: _temp$2 };
$[3] = t2;
} else t2 = $[3];
const search = useLocation(t2);
let t3;
if ($[4] !== search.returnTo) {
t3 = sanitizeReturnTo(search.returnTo);
$[4] = search.returnTo;
$[5] = t3;
} else t3 = $[5];
const returnTo = t3;
const { t } = useTranslation();
const [lastProvider, setLastProvider] = useState(null);
let t4;
let t5;
if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
t4 = () => setLastProvider(localStorage.getItem(LAST_PROVIDER_KEY));
t5 = [];
$[6] = t4;
$[7] = t5;
} else {
t4 = $[6];
t5 = $[7];
}
useEffect(t4, t5);
const preferred = lastProvider ?? (providers.length === 1 ? providers[0].id : null);
let t6;
if ($[8] !== returnTo) {
t6 = (provider) => () => {
localStorage.setItem(LAST_PROVIDER_KEY, provider);
location.href = `/auth/login?provider=${provider}&returnTo=${encodeURIComponent(returnTo)}`;
};
$[8] = returnTo;
$[9] = t6;
} else t6 = $[9];
const signIn = t6;
let t7;
if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
t7 = {
minHeight: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
px: 2,
py: 6
};
$[10] = t7;
} else t7 = $[10];
let t8;
if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
t8 = [_temp2, _temp3];
$[11] = t8;
} else t8 = $[11];
let t9;
if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
t9 = { p: {
xs: 3,
sm: 4
} };
$[12] = t9;
} else t9 = $[12];
let t10;
let t11;
if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
t10 = { alignItems: "center" };
t11 = /* @__PURE__ */ jsx(Box, {
component: "img",
src: "/android-chrome-192x192.png",
alt: "",
width: 48,
height: 48
});
$[13] = t10;
$[14] = t11;
} else {
t10 = $[13];
t11 = $[14];
}
let t12;
if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
t12 = /* @__PURE__ */ jsx(Typography, {
variant: "body2",
color: "text.secondary",
sx: { fontWeight: 600 },
children: manifest.name
});
$[15] = t12;
} else t12 = $[15];
let t13;
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
t13 = { fontWeight: 700 };
$[16] = t13;
} else t13 = $[16];
let t14;
if ($[17] !== t) {
t14 = t("Layout.LogIn");
$[17] = t;
$[18] = t14;
} else t14 = $[18];
let t15;
if ($[19] !== t14) {
t15 = /* @__PURE__ */ jsxs(Stack, {
direction: "row",
spacing: 2,
sx: t10,
children: [t11, /* @__PURE__ */ jsxs(Stack, {
spacing: .25,
children: [t12, /* @__PURE__ */ jsx(Typography, {
variant: "h5",
component: "h1",
sx: t13,
children: t14
})]
})]
});
$[19] = t14;
$[20] = t15;
} else t15 = $[20];
let t16;
if ($[21] === Symbol.for("react.memo_cache_sentinel")) {
t16 = /* @__PURE__ */ jsx(Divider, { sx: { my: 3 } });
$[21] = t16;
} else t16 = $[21];
let t17;
if ($[22] !== preferred || $[23] !== providers || $[24] !== signIn || $[25] !== t) {
let t18;
if ($[27] !== preferred || $[28] !== signIn || $[29] !== t) {
t18 = (t19) => {
const { id, label } = t19;
return /* @__PURE__ */ jsx(Button, {
fullWidth: true,
size: "large",
startIcon: PROVIDER_ICON[id],
variant: id === preferred ? "contained" : "outlined",
onClick: signIn(id),
sx: {
minHeight: 52,
px: 2,
borderRadius: 1,
fontWeight: 600,
textTransform: "none",
boxShadow: "none"
},
children: t("Layout.ContinueWith", { provider: label })
}, id);
};
$[27] = preferred;
$[28] = signIn;
$[29] = t;
$[30] = t18;
} else t18 = $[30];
t17 = providers.map(t18);
$[22] = preferred;
$[23] = providers;
$[24] = signIn;
$[25] = t;
$[26] = t17;
} else t17 = $[26];
let t18;
if ($[31] !== t17) {
t18 = /* @__PURE__ */ jsx(Stack, {
spacing: 1.5,
children: t17
});
$[31] = t17;
$[32] = t18;
} else t18 = $[32];
let t19;
if ($[33] !== t15 || $[34] !== t18) {
t19 = /* @__PURE__ */ jsx(Box, {
sx: t7,
children: /* @__PURE__ */ jsx(Card, {
variant: "outlined",
sx: t8,
children: /* @__PURE__ */ jsxs(CardContent, {
sx: t9,
children: [
t15,
t16,
t18
]
})
})
});
$[33] = t15;
$[34] = t18;
$[35] = t19;
} else t19 = $[35];
return t19;
};
function _temp$2(location) {
return location.search;
}
function _temp2(theme) {
return {
width: "100%",
maxWidth: 440,
borderColor: alpha(theme.palette.primary.main, .2),
borderRadius: 1,
boxShadow: `0 20px 50px ${alpha(theme.palette.common.black, .08)}`
};
}
function _temp3(theme_0) {
return theme_0.applyStyles("dark", {
borderColor: alpha(theme_0.palette.primary.main, .28),
boxShadow: `0 20px 50px ${alpha(theme_0.palette.common.black, .28)}`
});
}
// src/components/core/Fullscreen.tsx
const isScrollContainer = (element) => /auto|scroll|overlay/.test(getComputedStyle(element).overflowY);
/** Ancestors up to and including the nearest scroll container (or the root element). */
const getAncestors = (element) => {
const ancestors = [];
let parent = element.parentElement;
while (parent && parent !== document.body && parent !== document.documentElement) {
ancestors.push(parent);
if (isScrollContainer(parent)) return ancestors;
parent = parent.parentElement;
}
ancestors.push(document.documentElement);
return ancestors;
};
const px = (value) => Number.parseFloat(value) || 0;
const Fullscreen = (t0) => {
const $ = c(16);
if ($[0] !== "8cbf7a32d40cad26f487ed7c5e0b8451044a6d7e404e9591bd3919c6daa7488f") {
for (let $i = 0; $i < 16; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "8cbf7a32d40cad26f487ed7c5e0b8451044a6d7e404e9591bd3919c6daa7488f";
}
let children;
let props;
let sx;
if ($[1] !== t0) {
({children, sx, ...props} = t0);
$[1] = t0;
$[2] = children;
$[3] = props;
$[4] = sx;
} else {
children = $[2];
props = $[3];
sx = $[4];
}
const reference = useRef(null);
const [height, setHeight] = useState();
let t1;
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
t1 = () => {
const element = reference.current;
if (!element) return;
const ancestors = getAncestors(element);
const container = ancestors.at(-1);
const isRoot = container === document.documentElement;
const top = element.getBoundingClientRect().top;
const offsetTop = isRoot ? top + window.scrollY : top - container.getBoundingClientRect().top - container.clientTop + container.scrollTop;
const containerHeight = isRoot ? window.visualViewport?.height ?? window.innerHeight : container.clientHeight;
let trailing = px(getComputedStyle(element).marginBottom);
for (const ancestor of ancestors) {
const style = getComputedStyle(ancestor);
trailing = trailing + px(style.paddingBottom);
if (ancestor === container) break;
trailing = trailing + (px(style.borderBottomWidth) + px(style.marginBottom));
}
setHeight(Math.max(0, Math.floor(containerHeight - offsetTop - trailing)));
};
$[5] = t1;
} else t1 = $[5];
const recompute = useEffectEvent(t1);
let t2;
if ($[6] !== recompute) {
t2 = () => {
const element_0 = reference.current;
if (!element_0) return;
recompute();
window.addEventListener("resize", recompute);
window.visualViewport?.addEventListener("resize", recompute);
const ro = new ResizeObserver(() => recompute());
ro.observe(element_0);
for (const ancestor_0 of getAncestors(element_0)) ro.observe(ancestor_0);
return () => {
window.removeEventListener("resize", recompute);
window.visualViewport?.removeEventListener("resize", recompute);
ro.disconnect();
};
};
$[6] = recompute;
$[7] = t2;
} else t2 = $[7];
let t3;
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
t3 = [];
$[8] = t3;
} else t3 = $[8];
useLayoutEffect(t2, t3);
let t4;
if ($[9] !== height || $[10] !== sx) {
t4 = {
display: "flex",
flexDirection: "column",
boxSizing: "border-box",
minHeight: 0,
width: "100%",
overflow: "auto",
height,
...sx
};
$[9] = height;
$[10] = sx;
$[11] = t4;
} else t4 = $[11];
let t5;
if ($[12] !== children || $[13] !== props || $[14] !== t4) {
t5 = /* @__PURE__ */ jsx(Box, {
ref: reference,
sx: t4,
...props,
children
});
$[12] = children;
$[13] = props;
$[14] = t4;
$[15] = t5;
} else t5 = $[15];
return t5;
};
// src/components/file/Dropzone.tsx
const baseStyle = {
flex: 1,
display: "flex",
flexDirection: "column",
alignItems: "center",
padding: "20px",
borderWidth: 2,
borderRadius: 2,
borderStyle: "dashed",
transition: "border-color .24s ease-in-out",
cursor: "pointer"
};
const Dropzone = (t0) => {
const $ = c(33);
if ($[0] !== "5f7e412e732333f86e343ff1dbc3882283622c609fd4ce6a961ebef933e25fd9") {
for (let $i = 0; $i < 33; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "5f7e412e732333f86e343ff1dbc3882283622c609fd4ce6a961ebef933e25fd9";
}
let progress;
let props;
let sx;
if ($[1] !== t0) {
({sx, progress, ...props} = t0);
$[1] = t0;
$[2] = progress;
$[3] = props;
$[4] = sx;
} else {
progress = $[2];
props = $[3];
sx = $[4];
}
const { getRootProps, getInputProps, isFocused, isDragAccept, isDragReject } = useDropzone(props);
const { t } = useTranslation();
const theme = useTheme();
const t1 = progress ? "progress" : props.disabled ? "not-allowed" : "pointer";
const t2 = theme.vars || theme;
let T0;
let t3;
if ($[5] !== getRootProps || $[6] !== isDragAccept || $[7] !== isDragReject || $[8] !== isFocused || $[9] !== props.disabled || $[10] !== t1 || $[11] !== t2.palette.text.disabled || $[12] !== theme) {
const style = {
...baseStyle,
cursor: t1,
borderColor: t2.palette.text.disabled,
...isFocused ? { borderColor: (theme.vars || theme).palette.primary.main } : {},
...isDragAccept ? { borderColor: (theme.vars || theme).palette.success.main } : {},
...isDragReject ? { borderColor: (theme.vars || theme).palette.error.main } : {}
};
T0 = Box;
t3 = getRootProps({
style,
role: "button",
"aria-disabled": props.disabled || void 0
});
$[5] = getRootProps;
$[6] = isDragAccept;
$[7] = isDragReject;
$[8] = isFocused;
$[9] = props.disabled;
$[10] = t1;
$[11] = t2.palette.text.disabled;
$[12] = theme;
$[13] = T0;
$[14] = t3;
} else {
T0 = $[13];
t3 = $[14];
}
let t4;
if ($[15] !== getInputProps) {
t4 = getInputProps();
$[15] = getInputProps;
$[16] = t4;
} else t4 = $[16];
let t5;
if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
t5 = { display: "none" };
$[17] = t5;
} else t5 = $[17];
let t6;
if ($[18] !== t4) {
t6 = /* @__PURE__ */ jsx("input", {
...t4,
style: t5
});
$[18] = t4;
$[19] = t6;
} else t6 = $[19];
let t7;
if ($[20] !== progress) {
t7 = progress ? /* @__PURE__ */ jsx(CircularProgress, {
size: 24,
variant: "determinate",
value: progress,
"aria-label": "Uploading"
}) : /* @__PURE__ */ jsx(CloudUpload, {});
$[20] = progress;
$[21] = t7;
} else t7 = $[21];
let t8;
if ($[22] !== t) {
t8 = t("Layout.File.DragSomeFilesHereOrClickToSelectThem");
$[22] = t;
$[23] = t8;
} else t8 = $[23];
let t9;
if ($[24] !== t8) {
t9 = /* @__PURE__ */ jsx(Typography, { children: t8 });
$[24] = t8;
$[25] = t9;
} else t9 = $[25];
let t10;
if ($[26] !== T0 || $[27] !== sx || $[28] !== t3 || $[29] !== t6 || $[30] !== t7 || $[31] !== t9) {
t10 = /* @__PURE__ */ jsxs(T0, {
...t3,
sx,
children: [
t6,
t7,
t9
]
});
$[26] = T0;
$[27] = sx;
$[28] = t3;
$[29] = t6;
$[30] = t7;
$[31] = t9;
$[32] = t10;
} else t10 = $[32];
return t10;
};
// src/contexts/FileContext.ts
const FileContext = createContext(null);
const useFile = () => {
const $ = c(1);
if ($[0] !== "a9a469a99242723a03ab2ab21b9513f8d7f393e7a397296039721f8243a94fd9") {
for (let $i = 0; $i < 1; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "a9a469a99242723a03ab2ab21b9513f8d7f393e7a397296039721f8243a94fd9";
}
const context = useContext(FileContext);
if (!context) throw new Error("FileViewer components must be used within FileViewer");
return context;
};
// src/components/file/fileViewer/common/ActionsMenu.tsx
const ActionsMenu = (t0) => {
const $ = c(38);
if ($[0] !== "7ed2ca73a1b83560ce36924119f722bc2853d54808eacf915e739dac0ddf031e") {
for (let $i = 0; $i < 38; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "7ed2ca73a1b83560ce36924119f722bc2853d54808eacf915e739dac0ddf031e";
}
const { meta, anchorEl, onClose } = t0;
const { t } = useTranslation();
const { fileMetas, onDelete, actions, appName } = useFile();
const { alert, confirm } = useDialogs();
let t1;
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
t1 = { from: rootRouteId };
$[1] = t1;
} else t1 = $[1];
const queryClient = useMatch(t1).context.queryClient;
let t2;
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
t2 = downloadFileMutationOptions();
$[2] = t2;
} else t2 = $[2];
const { mutate: download, isPending: isDownloading } = useMutation(t2);
let t3;
if ($[3] !== queryClient) {
t3 = deleteFileMutationOptions({ queryClient });
$[3] = queryClient;
$[4] = t3;
} else t3 = $[4];
const { mutateAsync: deleteFile, isPending: isDeleting } = useMutation(t3);
let t4;
if ($[5] !== appName || $[6] !== download || $[7] !== meta.fileExtension || $[8] !== meta.fileName || $[9] !== meta.id || $[10] !== onClose) {
t4 = () => {
onClose();
download({
id: meta.id,
appName,
fileName: meta.fileName,
fileExtension: meta.fileExtension
});
};
$[5] = appName;
$[6] = download;
$[7] = meta.fileExtension;
$[8] = meta.fileName;
$[9] = meta.id;
$[10] = onClose;
$[11] = t4;
} else t4 = $[11];
const handleOnDownload = t4;
let t5;
if ($[12] !== alert || $[13] !== appName || $[14] !== confirm || $[15] !== deleteFile || $[16] !== fileMetas || $[17] !== meta || $[18] !== onClose || $[19] !== onDelete || $[20] !== t) {
t5 = async () => {
onClose();
if (!await confirm(t("Layout.File.AreYouSureYouWantToDelete", { name: meta.fileName }), {
title: t("Layout.File.Delete"),
confirmText: t("Layout.File.Delete")
})) return;
try {
await deleteFile({
id: meta.id,
appName
});
} catch (t6) {
const error = t6;
await alert(error instanceof Error ? error.message : String(error));
return;
}
onDelete?.({
remainingFileMetas: fileMetas.filter((m) => m.id !== meta.id),
deletedFileMeta: meta
});
};
$[12] = alert;
$[13] = appName;
$[14] = confirm;
$[15] = deleteFile;
$[16] = fileMetas;
$[17] = meta;
$[18] = onClose;
$[19] = onDelete;
$[20] = t;
$[21] = t5;
} else t5 = $[21];
const handleOnDelete = t5;
const t6 = !!anchorEl;
let t7;
if ($[22] !== actions?.download || $[23] !== handleOnDownload || $[24] !== isDownloading || $[25] !== t) {
t7 = actions?.download !== false && /* @__PURE__ */ jsxs(MenuItem, {
onClick: handleOnDownload,
disabled: isDownloading,
children: [/* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(FileDownload, {}) }), /* @__PURE__ */ jsx(ListItemText, { children: t("Layout.File.Download") })]
});
$[22] = actions?.download;
$[23] = handleOnDownload;
$[24] = isDownloading;
$[25] = t;
$[26] = t7;
} else t7 = $[26];
let t8;
if ($[27] !== actions?.delete || $[28] !== handleOnDelete || $[29] !== isDeleting || $[30] !== t) {
t8 = actions?.delete !== false && /* @__PURE__ */ jsxs(MenuItem, {
onClick: handleOnDelete,
disabled: isDeleting,
children: [/* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(Delete, {}) }), /* @__PURE__ */ jsx(ListItemText, { children: t("Layout.File.Delete") })]
});
$[27] = actions?.delete;
$[28] = handleOnDelete;
$[29] = isDeleting;
$[30] = t;
$[31] = t8;
} else t8 = $[31];
let t9;
if ($[32] !== anchorEl || $[33] !== onClose || $[34] !== t6 || $[35] !== t7 || $[36] !== t8) {
t9 = /* @__PURE__ */ jsxs(Menu, {
anchorEl,
open: t6,
onClose,
children: [t7, t8]
});
$[32] = anchorEl;
$[33] = onClose;
$[34] = t6;
$[35] = t7;
$[36] = t8;
$[37] = t9;
} else t9 = $[37];
return t9;
};
// src/components/file/fileViewer/FileViewerGrid.tsx
const IMAGE_SIZE = 150;
const FileViewerGrid = (t0) => {
const $ = c(13);
if ($[0] !== "d34a3a98fae1ee0c7bd956efc6c660c0dd0cdc0eff211c4027f8000d5ce89d2b") {
for (let $i = 0; $i < 13; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "d34a3a98fae1ee0c7bd956efc6c660c0dd0cdc0eff211c4027f8000d5ce89d2b";
}
const { sx, size, itemBar } = t0;
const { fileMetas } = useFile();
let t1;
if ($[1] !== sx) {
t1 = {
overflow: "auto",
...sx
};
$[1] = sx;
$[2] = t1;
} else t1 = $[2];
let t2;
if ($[3] !== fileMetas || $[4] !== itemBar || $[5] !== size) {
let t3;
if ($[7] !== itemBar || $[8] !== size) {
t3 = (fileMeta) => /* @__PURE__ */ jsx(GridFileViewerItem, {
meta: fileMeta,
size,
itemBar
}, fileMeta.id);
$[7] = itemBar;
$[8] = size;
$[9] = t3;
} else t3 = $[9];
t2 = fileMetas.map(t3);
$[3] = fileMetas;
$[4] = itemBar;
$[5] = size;
$[6] = t2;
} else t2 = $[6];
let t3;
if ($[10] !== t1 || $[11] !== t2) {
t3 = /* @__PURE__ */ jsx(Stack, {
direction: "row",
spacing: 1,
sx: t1,
children: t2
});
$[10] = t1;
$[11] = t2;
$[12] = t3;
} else t3 = $[12];
return t3;
};
const GridFileViewerItem = ({ meta, size, itemBar }) => {
const { setImageId, actions, appName } = useFile();
const [hovered, setHovered] = useState(false);
const [focused, setFocused] = useState(false);
const [menuAnchor, setMenuAnchor] = useState(null);
const { ref, inView } = useInView({ triggerOnce: true });
const queryClient = useQueryClient();
const target = useRef(null);
const side = size ?? IMAGE_SIZE;
const fileName = `${meta.fileName}.${meta.fileExtension}`;
const hasActions = actions?.download !== false || actions.delete !== false;
const showItemBar = itemBar === "always" || itemBar !== "hidden" && (hovered || focused || !!menuAnchor);
const { data: source, isPending } = useQuery({
...fileThumbnailQueryOptions({
id: meta.id,
appName
}),
enabled: inView
});
const { mutate: openFile } = useMutation(openFileMutationOptions({ target }));
const { mutate: download } = useMutation(downloadFileMutationOptions());
const prefetch = () => queryClient.prefetchQuery(fileQueryOptions({
id: meta.id,
appName
}));
const onClick = () => {
switch (meta.mediaType) {
case "image": return setImageId(meta.id);
case "application":
case "video":
target.current = window.open("about:blank", "_blank");
return openFile({
id: meta.id,
appName
});
default: return download({
id: meta.id,
appName,
fileName: meta.fileName,
fileExtension: meta.fileExtension
});
}
};
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(ImageListItem, {
sx: {
width: side,
height: side
},
onMouseEnter: () => setHovered(true),
onMouseLeave: () => setHovered(false),
onFocus: () => setFocused(true),
onBlur: (event) => {
if (!event.currentTarget.contains(event.relatedTarget)) setFocused(false);
},
ref,
children: [isPending ? /* @__PURE__ */ jsx(Skeleton, {
variant: "rectangular",
width: side,
height: side
}) : /* @__PURE__ */ jsx(ButtonBase, {
onClick,
onMouseEnter: prefetch,
onFocus: prefetch,
"aria-label": `Open ${fileName}`,
sx: {
width: side,
height: side,
"&.Mui-focusVisible": {
outline: "2px solid",
outlineColor: "primary.main",
outlineOffset: -2
}
},
children: /* @__PURE__ */ jsx(Box, {
component: "img",
src: source,
loading: "lazy",
alt: "",
sx: {
objectFit: "contain",
width: side,
height: side
}
})
}), showItemBar && /* @__PURE__ */ jsx(ImageListItemBar, {
title: /* @__PURE__ */ jsx(Tooltip, {
title: fileName,
children: /* @__PURE__ */ jsx(Box, { children: meta.fileName })
}),
actionIcon: hasActions && /* @__PURE__ */ jsx(IconButton, {
sx: { color: grey[100] },
onClick: (event_0) => setMenuAnchor(event_0.currentTarget),
"aria-label": `Actions for ${fileName}`,
"aria-haspopup": "menu",
children: /* @__PURE__ */ jsx(MoreVert, {})
})
})]
}), hasActions && /* @__PURE__ */ jsx(ActionsMenu, {
meta,
anchorEl: menuAnchor,
onClose: () => setMenuAnchor(null)
})] });
};
// src/components/file/fileViewer/FileViewerList.tsx
const FileViewerList = (t0) => {
const $ = c(6);
if ($[0] !== "def12bfee125db96c0e25478a726cf153aa928252368ec27de2bcba8f364adae") {
for (let $i = 0; $i < 6; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "def12bfee125db96c0e25478a726cf153aa928252368ec27de2bcba8f364adae";
}
const { sx } = t0;
const { fileMetas } = useFile();
let t1;
if ($[1] !== fileMetas) {
t1 = fileMetas.map(_temp$1);
$[1] = fileMetas;
$[2] = t1;
} else t1 = $[2];
let t2;
if ($[3] !== sx || $[4] !== t1) {
t2 = /* @__PURE__ */ jsx(List, {
dense: true,
sx,
children: t1
});
$[3] = sx;
$[4] = t1;
$[5] = t2;
} else t2 = $[5];
return t2;
};
const ListFileViewerItem = ({ meta }) => {
const { setImageId, actions, appName } = useFile();
const [menuAnchor, setMenuAnchor] = useState(null);
const queryClient = useQueryClient();
const target = useRef(null);
const fileName = `${meta.fileName}.${meta.fileExtension}`;
const hasActions = actions?.download !== false || actions.delete !== false;
const { mutate: openFile } = useMutation(openFileMutationOptions({ target }));
const { mutate: download } = useMutation(downloadFileMutationOptions());
const onClick = () => {
switch (meta.mediaType) {
case "image": return setImageId(meta.id);
case "application":
case "video":
target.current = window.open("about:blank", "_blank");
return openFile({
id: meta.id,
appName
});
default: return download({
id: meta.id,
appName,
fileName: meta.fileName,
fileExtension: meta.fileExtension
});
}
};
const icon = () => {
switch (meta.mediaType) {
case "image": return /* @__PURE__ */ jsx(Image, {});
case "video": return /* @__PURE__ */ jsx(SmartDisplay, {});
default: return /* @__PURE__ */ jsx(AttachFile, {});
}
};
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ListItem, {
disablePadding: true,
secondaryAction: hasActions && /* @__PURE__ */ jsx(IconButton, {
edge: "end",
onClick: (event) => setMenuAnchor(event.currentTarget),
"aria-label": `Actions for ${fileName}`,
"aria-haspopup": "menu",
children: /* @__PURE__ */ jsx(MoreVert, {})
}),
children: /* @__PURE__ */ jsxs(ListItemButton, {
onClick,
onMouseEnter: () => queryClient.prefetchQuery(fileQueryOptions({
id: meta.id,
appName
})),
children: [/* @__PURE__ */ jsx(ListItemIcon, { children: icon() }), /* @__PURE__ */ jsx(ListItemText, { primary: fileName })]
})
}), hasActions && /* @__PURE__ */ jsx(ActionsMenu, {
meta,
anchorEl: menuAnchor,
onClose: () => setMenuAnchor(null)
})] });
};
function _temp$1(fileMeta) {
return /* @__PURE__ */ jsx(ListFileViewerItem, { meta: fileMeta }, fileMeta.id);
}
// src/components/file/fileViewer/ImageViewer.tsx
const ImageViewer = (t0) => {
const $ = c(56);
if ($[0] !== "c362b5d42dedaecf837e96525daab6341b34e31726fb1413e37d4a5eb8122071") {
for (let $i = 0; $i < 56; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "c362b5d42dedaecf837e96525daab6341b34e31726fb1413e37d4a5eb8122071";
}
const { metaId } = t0;
const { fileMetas, setImageId, appName } = useFile();
let meta;
let next;
let previous;
let t1;
let t2;
if ($[1] !== appName || $[2] !== fileMetas || $[3] !== metaId) {
let t3;
if ($[9] !== metaId) {
t3 = (m) => m.id === metaId;
$[9] = metaId;
$[10] = t3;
} else t3 = $[10];
meta = fileMetas.find(t3);
let images;
let t4;
if ($[11] !== fileMetas || $[12] !== metaId) {
images = fileMetas.filter(_temp);
let t5;
if ($[15] !== metaId) {
t5 = (m_1) => m_1.id === metaId;
$[15] = metaId;
$[16] = t5;
} else t5 = $[16];
t4 = images.findIndex(t5);
$[11] = fileMetas;
$[12] = metaId;
$[13] = images;
$[14] = t4;
} else {
images = $[13];
t4 = $[14];
}
const index = t4;
previous = index > 0 ? images[index - 1] : void 0;
next = index >= 0 && index < images.length - 1 ? images[index + 1] : void 0;
t2 = useQuery;
t1 = fileQueryOptions({
id: meta?.id ?? "",
appName
});
$[1] = appName;
$[2] = fileMetas;
$[3] = metaId;
$[4] = meta;
$[5] = next;
$[6] = previous;
$[7] = t1;
$[8] = t2;
} else {
meta = $[4];
next = $[5];
previous = $[6];
t1 = $[7];
t2 = $[8];
}
const t3 = !!meta;
let t4;
if ($[17] !== t1 || $[18] !== t3) {
t4 = {
...t1,
enabled: t3
};
$[17] = t1;
$[18] = t3;
$[19] = t4;
} else t4 = $[19];
const { data: source, isPending } = t2(t4);
let t5;
if ($[20] !== setImageId) {
t5 = () => setImageId("");
$[20] = setImageId;
$[21] = t5;
} else t5 = $[21];
const onClose = t5;
let t6;
if ($[22] !== metaId || $[23] !== next || $[24] !== onClose || $[25] !== previous || $[26] !== setImageId) {
t6 = () => {
if (!metaId) return;
const handleOnKeydown = (event) => {
switch (event.key) {
case "ArrowLeft": return previous && setImageId(previous.id);
case "ArrowRight": return next && setImageId(next.id);
case "Backspace":
case "Escape":
event.preventDefault();
return onClose();
}
};
globalThis.addEventListener("keydown", handleOnKeydown);
return () => globalThis.removeEventListener("keydown", handleOnKeydown);
};
$[22] = metaId;
$[23] = next;
$[24] = onClose;
$[25] = previous;
$[26] = setImageId;
$[27] = t6;
} else t6 = $[27];
let t7;
if ($[28] !== metaId || $[29] !== next || $[30] !== previous) {
t7 = [
metaId,
previous,
next
];
$[28] = metaId;
$[29] = next;
$[30] = previous;
$[31] = t7;
} else t7 = $[31];
useEffect(t6, t7);
if (!meta) return null;
let t8;
if ($[32] === Symbol.for("react.memo_cache_sentinel")) {
t8 = {
position: "fixed",
top: "50%",
transform: "translateY(-50%)"
};
$[32] = t8;
} else t8 = $[32];
const navSx = t8;
let t9;
if ($[33] !== meta.fileName) {
t9 = { paper: { "aria-label": meta.fileName } };
$[33] = meta.fileName;
$[34] = t9;
} else t9 = $[34];
let t10;
if ($[35] !== isPending || $[36] !== meta.fileName || $[37] !== source) {
t10 = isPending ? /* @__PURE__ */ jsx(Skeleton, {
variant: "rectangular",
sx: {
width: {
xs: "100vw",
sm: 600
},
height: {
xs: "calc(100vh - 56px)",
sm: "calc(100vh - 64px)"
}
}
}) : /* @__PURE__ */ jsx(Box, {
component: "img",
src: source,
alt: meta.fileName,
sx: {
maxWidth: "100vw",
maxHeight: {
xs: "calc(100vh - 56px)",
sm: "calc(100vh - 64px)"
}
}
});
$[35] = isPending;
$[36] = meta.fileName;
$[37] = source;
$[38] = t10;
} else t10 = $[38];
let t11;
if ($[39] !== previous || $[40] !== setImageId) {
t11 = previous && /* @__PURE__ */ jsx(Fab, {
size: "medium",
onClick: () => setImageId(previous.id),
"aria-label": "Previous",
sx: {
...navSx,
left: 8
},
children: /* @__PURE__ */ jsx(ChevronLeft, {})
});
$[39] = previous;
$[40] = setImageId;
$[41] = t11;
} else t11 = $[41];
let t12;
if ($[42] !== next || $[43] !== setImageId) {
t12 = next && /* @__PURE__ */ jsx(Fab, {
size: "medium",
onClick: () => setImageId(next.id),
"aria-label": "Next",
sx: {
...navSx,
right: 8
},
children: /* @__PURE__ */ jsx(ChevronRight, {})
});
$[42] = next;
$[43] = setImageId;
$[44] = t12;
} else t12 = $[44];
let t13;
let t14;
if ($[45] === Symbol.for("react.memo_cache_sentinel")) {
t13 = {
position: "fixed",
top: 8,
right: 8
};
t14 = /* @__PURE__ */ jsx(Close, {});
$[45] = t13;
$[46] = t14;
} else {
t13 = $[45];
t14 = $[46];
}
let t15;
if ($[47] !== onClose) {
t15 = /* @__PURE__ */ jsx(Fab, {
size: "medium",
onClick: onClose,
"aria-label": "Close",
sx: t13,
children: t14
});
$[47] = onClose;
$[48] = t15;
} else t15 = $[48];
let t16;
if ($[49] !== onClose || $[50] !== t10 || $[51] !== t11 || $[52] !== t12 || $[53] !== t15 || $[54] !== t9) {
t16 = /* @__PURE__ */ jsxs(Dialog, {
open: true,
onClose,
maxWidth: "xl",
slotProps: t9,
children: [
t10,
t11,
t12,
t15
]
});
$[49] = onClose;
$[50] = t10;
$[51] = t11;
$[52] = t12;
$[53] = t15;
$[54] = t9;
$[55] = t16;
} else t16 = $[55];
return t16;
};
function _temp(m_0) {
return m_0.mediaType === "image";
}
// src/components/file/FileViewer.tsx
const FileViewer = (t0) => {
const $ = c(22);
if ($[0] !== "f20716e955e976c65e4217e568b647786c1c8599751fff5b227781489170527e") {
for (let $i = 0; $i < 22; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "f20716e955e976c65e4217e568b647786c1c8599751fff5b227781489170527e";
}
const { appName, subId, onDelete, actions, children } = t0;
let t1;
if ($[1] !== appName || $[2] !== subId) {
t1 = fileMetasQueryOptions({
appName,
subId
});
$[1] = appName;
$[2] = subId;
$[3] = t1;
} else t1 = $[3];
const t2 = !!subId;
let t3;
if ($[4] !== t1 || $[5] !== t2) {
t3 = {
...t1,
enabled: t2
};
$[4] = t1;
$[5] = t2;
$[6] = t3;
} else t3 = $[6];
const { data: t4 } = useQuery(t3);
let t5;
if ($[7] !== t4) {
t5 = t4 === void 0 ? [] : t4;
$[7] = t4;
$[8] = t5;
} else t5 = $[8];
const fileMetas = t5;
const [imageId, setImageId] = useState("");
if (fileMetas.length === 0) return null;
let t6;
if ($[9] !== actions || $[10] !== appName || $[11] !== fileMetas || $[12] !== onDelete) {
t6 = {
appName,
fileMetas,
onDelete,
actions,
setImageId
};
$[9] = actions;
$[10] = appName;
$[11] = fileMetas;
$[12] = onDelete;
$[13] = t6;
} else t6 = $[13];
let t7;
if ($[14] !== children) {
t7 = children({
Grid: FileViewerGrid,
List: FileViewerList
});
$[14] = children;
$[15] = t7;
} else t7 = $[15];
let t8;
if ($[16] !== imageId) {
t8 = /* @__PURE__ */ jsx(ImageViewer, { metaId: imageId });
$[16] = imageId;
$[17] = t8;
} else t8 = $[17];
let t9;
if ($[18] !== t6 || $[19] !== t7 || $[20] !== t8) {
t9 = /* @__PURE__ */ jsxs(FileContext.Provider, {
value: t6,
children: [t7, t8]
});
$[18] = t6;
$[19] = t7;
$[20] = t8;
$[21] = t9;
} else t9 = $[21];
return t9;
};
// src/components/router/RouterButton.tsx
const Component$3 = React.forwardRef(function ButtonComponent(props, reference) {
const $ = c(4);
if ($[0] !== "ac6204c9fa419bc8efad3ebea0df725f19f2cc476a09c695e535caec26527133") {
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "ac6204c9fa419bc8efad3ebea0df725f19f2cc476a09c695e535caec26527133";
}
let t0;
if ($[1] !== props || $[2] !== reference) {
t0 = /* @__PURE__ */ jsx(Button, {
ref: reference,
component: "a",
...props
});
$[1] = props;
$[2] = reference;
$[3] = t0;
} else t0 = $[3];
return t0;
});
const CreatedComponent$3 = createLink(Component$3);
const RouterButton = (props) => {
const $ = c(3);
if ($[0] !== "ac6204c9fa419bc8efad3ebea0df725f19f2cc476a09c695e535caec26527133") {
for (let $i = 0; $i < 3; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "ac6204c9fa419bc8efad3ebea0df725f19f2cc476a09c695e535caec26527133";
}
let t0;
if ($[1] !== props) {
t0 = /* @__PURE__ */ jsx(CreatedComponent$3, { ...props });
$[1] = props;
$[2] = t0;
} else t0 = $[2];
return t0;
};
// src/components/router/RouterFab.tsx
const Component$2 = React.forwardRef(function FabComponent(props, reference) {
const $ = c(4);
if ($[0] !== "ecf406c2f1df75bd8d4f8cc1e2a0841119cda75e807b28c7c03400a2d927c16b") {
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "ecf406c2f1df75bd8d4f8cc1e2a0841119cda75e807b28c7c03400a2d927c16b";
}
let t0;
if ($[1] !== props || $[2] !== reference) {
t0 = /* @__PURE__ */ jsx(Fab, {
ref: reference,
component: "a",
...props
});
$[1] = props;
$[2] = reference;
$[3] = t0;
} else t0 = $[3];
return t0;
});
const CreatedComponent$2 = createLink(Component$2);
const RouterFab = (props) => {
const $ = c(3);
if ($[0] !== "ecf406c2f1df75bd8d4f8cc1e2a0841119cda75e807b28c7c03400a2d927c16b") {
for (let $i = 0; $i < 3; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "ecf406c2f1df75bd8d4f8cc1e2a0841119cda75e807b28c7c03400a2d927c16b";
}
let t0;
if ($[1] !== props) {
t0 = /* @__PURE__ */ jsx(CreatedComponent$2, { ...props });
$[1] = props;
$[2] = t0;
} else t0 = $[2];
return t0;
};
// src/components/router/RouterLink.tsx
const Component$1 = React.forwardRef(function LinkComponent(props, reference) {
const $ = c(4);
if ($[0] !== "b12e87e18a050ab0e29a4efcc3bd2a9fa6915db983e56ea2dc68853a7dc4b979") {
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "b12e87e18a050ab0e29a4efcc3bd2a9fa6915db983e56ea2dc68853a7dc4b979";
}
let t0;
if ($[1] !== props || $[2] !== reference) {
t0 = /* @__PURE__ */ jsx(Link, {
ref: reference,
...props
});
$[1] = props;
$[2] = reference;
$[3] = t0;
} else t0 = $[3];
return t0;
});
const CreatedComponent$1 = createLink(Component$1);
const RouterLink = (props) => {
const $ = c(3);
if ($[0] !== "b12e87e18a050ab0e29a4efcc3bd2a9fa6915db983e56ea2dc68853a7dc4b979") {
for (let $i = 0; $i < 3; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "b12e87e18a050ab0e29a4efcc3bd2a9fa6915db983e56ea2dc68853a7dc4b979";
}
let t0;
if ($[1] !== props) {
t0 = /* @__PURE__ */ jsx(CreatedComponent$1, { ...props });
$[1] = props;
$[2] = t0;
} else t0 = $[2];
return t0;
};
// src/components/router/RouterTab.tsx
const Component = React.forwardRef(function TabComponent(props, reference) {
const $ = c(4);
if ($[0] !== "219e07108be3e229bc6eb53840beb65505cbaaf46f02d872937e7895165a73de") {
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "219e07108be3e229bc6eb53840beb65505cbaaf46f02d872937e7895165a73de";
}
let t0;
if ($[1] !== props || $[2] !== reference) {
t0 = /* @__PURE__ */ jsx(Tab, {
ref: reference,
component: "a",
...props
});
$[1] = props;
$[2] = reference;
$[3] = t0;
} else t0 = $[3];
return t0;
});
const CreatedComponent = createLink(Component);
const RouterTab = (props) => {
const $ = c(3);
if ($[0] !== "219e07108be3e229bc6eb53840beb65505cbaaf46f02d872937e7895165a73de") {
for (let $i = 0; $i < 3; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "219e07108be3e229bc6eb53840beb65505cbaaf46f02d872937e7895165a73de";
}
let t0;
if ($[1] !== props) {
t0 = /* @__PURE__ */ jsx(CreatedComponent, { ...props });
$[1] = props;
$[2] = t0;
} else t0 = $[2];
return t0;
};
// src/components/router/RouterNotFound.tsx
function RouterNotFound() {
const $ = c(9);
if ($[0] !== "b85bee0f4f29e1fb858e96e13dc2fcbb04a6bbd08c5b88b6d4df66a8869ddb03") {
for (let $i = 0; $i < 9; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "b85bee0f4f29e1fb858e96e13dc2fcbb04a6bbd08c5b88b6d4df66a8869ddb03";
}
const { t } = useTranslation();
let t0;
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
t0 = {
alignItems: "center",
justifyContent: "center",
px: 2
};
$[1] = t0;
} else t0 = $[1];
let t1;
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
t1 = {
display: "flex",
alignItems: "center",
m: 0,
mb: 4
};
$[2] = t1;
} else t1 = $[2];
let t2;
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
t2 = /* @__PURE__ */ jsx(Typography, {
variant: "h3",
component: "span",
sx: {
fontWeight: 500,
lineHeight: 1
},
children: "404"
});
$[3] = t2;
} else t2 = $[3];
let t3;
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
t3 = /* @__PURE__ */ jsx(Divider, {
component: "span",
role: "presentation",
orientation: "vertical",
flexItem: true,
sx: { mx: 3 }
});
$[4] = t3;
} else t3 = $[4];
let t4;
if ($[5] !== t) {
t4 = t("Layout.ThisPageCouldNotBeFound");
$[5] = t;
$[6] = t4;
} else t4 = $[6];
let t5;
if ($[7] !== t4) {
t5 = /* @__PURE__ */ jsx(Fullscreen, {
sx: t0,
children: /* @__PURE__ */ jsxs(Box, {
component: "h1",
sx: t1,
children: [
t2,
t3,
/* @__PURE__ */ jsx(Typography, {
variant: "h5",
component: "span",
children: t4
})
]
})
});
$[7] = t4;
$[8] = t5;
} else t5 = $[8];
return t5;
}
// src/components/router/RouterError.tsx
const RouterError = (t0) => {
const $ = c(12);
if ($[0] !== "99b46ee567229b93d88dd5dde9a07d2a370c1710d4e834f04c33ae486b9ec8a5") {
for (let $i = 0; $i < 12; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
$[0] = "99b46ee567229b93d88dd5dde9a07d2a370c1710d4e834f04c33ae486b9ec8a5";
}
const { error } = t0;
const isError = error instanceof Error;
let t1;
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
t1 = {
alignItems: "center",
justifyContent: "center",
px: 2
};
$[1] = t1;
} else t1 = $[1];
let t2;
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
t2 = {
display: "flex",
alignItems: "center",
m: 0,
mb: 4
};
$[2] = t2;
} else t2 = $[2];
let t3;
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
t3 = {
fontWeight: 500,
lineHeight: 1
};
$[3] = t3;
} else t3 = $[3];
const t4 = isError && error.name || "500";
let t5;
if ($[4] !== t4) {
t5 = /* @__PURE__ */ jsx(Typography, {
variant: "h3",
component: "span",
sx: t3,
children: t4
});
$[4] = t4;
$[5] = t5;
} else t5 = $[5];
let t6;
if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
t6 = /* @__PURE__ */ jsx(Divider, {
component: "span",
role: "presentation",
orientation: "vertical",
flexItem: true,
sx: { mx: 3 }
});
$[6] = t6;
} else t6 = $[6];
const t7 = isError ? error.message : String(error);
let t8;
if ($[7] !== t7) {
t8 = /* @__PURE__ */ jsx(Typography, {
variant: "h5",
component: "span",
children: t7
});
$[7] = t7;
$[8] = t8;
} else t8 = $[8];
let t9;
if ($[9] !== t5 || $[10] !== t8) {
t9 = /* @__PURE__ */ jsx(Fullscreen, {
sx: t1,
children: /* @__PURE__ */ jsxs(Box, {
component: "h1",
sx: t2,
children: [
t5,
t6,
t8
]
})
});
$[9] = t5;
$[10] = t8;
$[11] = t9;
} else t9 = $[11];
return t9;
};
// src/components/table/LayoutTable.tsx
const ROW_HEIGHT = 52;
const COLUMN_HEADER_HEIGHT = 56;
/** Rows and columns kept mounted past the viewport edge so scrolling never shows a gap. */
const ROW_OVERSCAN = 6;
const ROW_LOOKAHEAD = 15;
const COLUMN_OVERSCAN = 3;
const JUSTIFY = {
left: "flex-start",
center: "center",
right: "flex-end"
};
const CELL_SX = {
py: 0,
px: "10px"
};
const UTILITY_SX = {
py: 0,
px: .5
};
/** Pins the aggregation row to the bottom of the scroll area, like the sticky header. */
const FOOTER_SX = {
position: "sticky",
bottom: 0,
zIndex: 3,
bgcolor: "background.paper",
borderTop: 1,
borderTopStyle: "solid",
borderColor: "divider"
};
const pinnedWidth = (columns) => columns.reduce((total, column) => total + column.getSize(), 0);
/**
* Gives an ellipsized value (the cell itself or a noWrap Typography in it) a native
* tooltip with its full text. Checked on hover, so it follows resizes and new data.
*/
const titleIfTruncated = (event) => {
const element = event.target;
if (getComputedStyle(element).textOverflow !== "ellipsis") return;
element.title = element.scrollWidth > element.clientWidth ? element.textContent ?? "" : "";
};
function LayoutTable({ table, loading = false, pagination = false, pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS, showToolbar = false, disableColumnMenu = false, onRowClick, onRowDoubleClick, sx, ...toolbar }) {
"use no memo";
const { t } = useTranslation();
const containerRef = useRef(null);
const headerGroups = table.getHeaderGroups();
const headerHeight = headerGroups.length * COLUMN_HEADER_HEIGHT;
const visibleColumnCount = table.getVisibleLeafColumns().length;
const hasFooter = table.getAllLeafColumns().some((column) => column.columnDef.footer);
const { top, bottom } = table.state.rowPinning;
const pinnedIds = /* @__PURE__ */ new Set([...top, ...bottom]);
const centerRows = (pagination ? table.getRowModel() : table.getPrePaginatedRowModel()).rows.filter((row) => !pinnedIds.has(row.id));
const rows = [
...table.getTopRows(),
...centerRows,
...table.getBottomRows()
];
const isEmpty = !loading && !rows.length;
const pageSize = table.state.pagination.pageSize;
const pageSizeOffered = pageSizeOptions.includes(pageSize);
const pagerStarted = useRef(false);
useLayoutEffect(() => {
if (!pagination) {
if (pageSize !== rows.length) table.setPageSize(Math.max(rows.length, 1));
return;
}
const appSetSize = pagerStarted.current || !!(table.options.state?.pagination ?? table.options.initialState?.pagination);
pagerStarted.current = true;
if (!appSetSize || !pageSizeOffered) table.setPagination({
pageIndex: 0,
pageSize: Math.min(...pageSizeOptions)
});
}, [
pagination,
pageSize,
pageSizeOffered,
pageSizeOptions,
rows.length,
table
]);
const startColumns = table.getStartVisibleLeafColumns();
const endColumns = table.getEndVisibleLeafColumns();
const centerColumns = table.getCenterVisibleLeafColumns();
const startPinnedWidth = pinnedWidth(startColumns);
const endPinnedWidth = pinnedWidth(endColumns);
const [containerWidth, setContainerWidth] = useState(0);
useLayoutEffect(() => {
const container = containerRef.current;
if (!container) return;
setContainerWidth(container.clientWidth - 1);
const observer = new ResizeObserver(([entry]) => setContainerWidth(Math.floor(entry.contentRect.width)));
observer.observe(container);
return () => observer.disconnect();
}, []);
const flexColumns = table.getVisibleLeafColumns().filter((column_0) => columnFlex(column_0) > 0);
const totalFlex = flexColumns.reduce((total, column_1) => total + columnFlex(column_1), 0);
const flexSpace = containerWidth - table.getTotalSize();
const flexDeltas = flexColumns.map((column_2) => [column_2.id, Math.floor(flexSpace * columnFlex(column_2) / totalFlex)]);
const flexFits = flexColumns.every((column_3, index) => column_3.getSize() + flexDeltas[index][1] >= (column_3.columnDef.minSize ?? 20));
const flexWidths = new Map(flexFits ? flexDeltas : []);
const tableWidth = [...flexWidths.values()].reduce((total_0, delta) => total_0 + delta, table.getTotalSize());
const renderedWidth = (column_4) => column_4.getSize() + (flexWidths.get(column_4.id) ?? 0);
const headerWidth = (header) => header.column.getLeafColumns().reduce((width, column_5) => width + (flexWidths.get(column_5.id) ?? 0), header.getSize());
const virtualizeColumns = headerGroups.length === 1 && !loading;
const rowVirtualizer = useVirtualizer({
count: rows.length,
getScrollElement: () => containerRef.current,
estimateSize: () => ROW_HEIGHT,
measureElement: (element) => element.getBoundingClientRect().height,
getItemKey: (index_0) => rows[index_0].id,
overscan: ROW_OVERSCAN,
rangeExtractor: (range) => lookaheadRange(range, rowVirtualizer.scrollDirection, ROW_LOOKAHEAD),
scrollMargin: headerHeight,
scrollPaddingStart: headerHeight
});
const columnVirtualizer = useVirtualizer({
count: virtualizeColumns ? centerColumns.length : 0,
getScrollElement: () => containerRef.current,
estimateSize: (index_1) => renderedWidth(centerColumns[index_1]),
getItemKey: (index_2) => centerColumns[index_2].id,
horizontal: true,
overscan: COLUMN_OVERSCAN,
scrollPaddingStart: startPinnedWidth,
scrollPaddingEnd: endPinnedWidth
});
const columnSizing = table.state.columnSizing;
useEffect(() => {
columnVirtualizer.measure();
}, [
columnVirtualizer,
columnSizing,
containerWidth
]);
const focusedCell = table.getFocusedCell();
const focusedRowId = focusedCell?.row.id;
const focusedColumnId = focusedCell?.column.id;
useEffect(() => {
const cell = containerRef.current?.querySelector("tbody td[tabindex='0']");
if (cell) {
cell.scrollIntoView({
block: "nearest",
inline: "nearest"
});
return;
}
const rowIndex = rows.findIndex((row_0) => row_0.id === focusedRowId);
if (rowIndex >= 0) rowVirtualizer.scrollToIndex(rowIndex);
const columnIndex = centerColumns.findIndex((column_6) => column_6.id === focusedColumnId);
if (columnIndex >= 0) columnVirtualizer.scrollToIndex(columnIndex);
}, [focusedRowId, focusedColumnId]);
const hasCellSelection = table.state.cellSelection.length > 0;
const copySelection = () => {
const text = toClipboardText(table.getSelectedCellRangesData());
if (text) navigator.clipboard.writeText(text);
};
useHotkeys([
{
hotkey: "ArrowUp",
callback: () => table.moveCellSelection("up")
},
{
hotkey: "ArrowDown",
callback: () => table.moveCellSelection("down")
},
{
hotkey: "ArrowLeft",
callback: () => table.moveCellSelection("left")
},
{
hotkey: "ArrowRight",
callback: () => table.moveCellSelection("right")
},
{
hotkey: "Shift+ArrowUp",
callback: () => table.extendCellSelection("up")
},
{
hotkey: "Shift+ArrowDown",
callback: () => table.extendCellSelection("down")
},
{
hotkey: "Shift+ArrowLeft",
callback: () => table.extendCellSelection("left")
},
{
hotkey: "Shift+ArrowRight",
callback: () => table.extendCellSelection("right")
},
{
hotkey: "Mod+C",
callback: copySelection
},
{
hotkey: "Escape",
callback: () => table.resetCellSelection(true)
},
{
hotkey: "Mod+A",
callback: () => table.selectAllCells(),
options: { enabled: true }
}
], {
target: containerRef,
enabled: hasCellSelection
});
const virtualRows = rowVirtualizer.getVirtualItems();
const paddingTop = virtualRows.length ? virtualRows[0].start - headerHeight : 0;
const paddingBottom = virtualRows.length ? rowVirtualizer.getTotalSize() - virtualRows[virtualRows.length - 1].end + headerHeight : 0;
const virtualColumns = columnVirtualizer.getVirtualItems();
const firstColumn = virtualColumns.length ? virtualColumns[0] : void 0;
const lastColumn = virtualColumns.length ? virtualColumns[virtualColumns.length - 1] : void 0;
const paddingStart = firstColumn ? firstColumn.start : 0;
const paddingEnd = lastColumn ? columnVirtualizer.getTotalSize() - lastColumn.end : 0;
/**
* Splits a display-ordered leaf array — a header row, a footer row or a row's
* cells, which TanStack all orders start-pinned, centre, end-pinned — into the
* pinned regions, which always render, and the virtualized centre window.
*/
const windowColumns = (all) => firstColumn && lastColumn ? {
start: all.slice(0, startColumns.length),
center: all.slice(startColumns.length + firstColumn.index, startColumns.length + lastColumn.index + 1),
end: endColumns.length ? all.slice(all.length - endColumns.length) : []
} : {
start: all,
center: [],
end: []
};
/** Absorbs the width of the columns the centre window skipped. */
const skippedColumns = (width_0) => width_0 > 0 ? /* @__PURE__ */ jsx(TableCell, {
"aria-hidden": true,
className: layoutTableClasses.cellOffset,
style: { width: width_0 },
sx: { p: 0 }
}) : null;
const renderHeader = (h, groupIndex) => /* @__PURE__ */ jsx(table.AppHeader, {
header: h,
children: (header_0) => {
const align = columnAlign(header_0.column);
const labelled = hasColumnLabel(header_0.column);
return /* @__PURE__ */ jsxs(TableCell, {
className: classNames(layoutTableClasses.columnHeader, header_0.column.getCanSort() && layoutTableClasses["columnHeader--sortable"], header_0.column.getIsSorted() && layoutTableClasses["columnHeader--sorted"], header_0.column.getIsFiltered() && layoutTableClasses["columnHeader--filtered"], pinnedClass(header_0.column, "columnHeader")),
colSpan: header_0.colSpan,
align,
sortDirection: header_0.column.getIsSorted(),
sx: {
position: "sticky",
top: groupIndex * COLUMN_HEADER_HEIGHT,
zIndex: 3,
bgcolor: "background.paper",
width: headerWidth(header_0),
whiteSpace: "nowrap",
overflow: "hidden",
...labelled ? CELL_SX : UTILITY_SX,
...pinnedSx(header_0.column, true)
},
children: [header_0.isPlaceholder ? null : /* @__PURE__ */ jsxs(Box, {
className: layoutTableClasses.columnHeaderContent,
sx: {
display: "flex",
alignItems: "center",
minWidth: 0,
justifyContent: JUSTIFY[align]
},
children: [/* @__PURE__ */ jsx(Box, {
className: layoutTableClasses.columnHeaderTitleContainer,
sx: {
flex: labelled ? 1 : "0 1 auto",
minWidth: 0,
display: "flex",
justifyContent: JUSTIFY[align],
overflow: "hidden",
"& .MuiTableSortLabel-root": { minWidth: 0 },
"& .MuiTableSortLabel-root > *:first-of-type": {
overflow: "hidden",
textOverflow: "ellipsis"
}
},
children: /* @__PURE__ */ jsx(header_0.HeaderSortLabel, { children: /* @__PURE__ */ jsx(header_0.FlexRender, {}) })
}), !disableColumnMenu && /* @__PURE__ */ jsx(header_0.HeaderMenu, { disableGrouping: pagination })]
}), /* @__PURE__ */ jsx(header_0.HeaderResizeHandle, {})]
});
}
}, h.id);
const cellClassName = (cell_0) => classNames(layoutTableClasses.cell, cell_0.getIsSelected() && layoutTableClasses["cell--selected"], cell_0.getIsGrouped() && layoutTableClasses["cell--grouped"], cell_0.getIsAggregated() && layoutTableClasses["cell--aggregated"], pinnedClass(cell_0.column, "cell"));
const renderCell = (c) => /* @__PURE__ */ jsx(table.AppCell, {
cell: c,
children: (cell_1) => cell_1.getIsCovered() ? null : /* @__PURE__ */ jsx(TableCell, {
className: cellClassName(cell_1),
align: columnAlign(cell_1.column),
rowSpan: cell_1.getRowSpan(),
colSpan: cell_1.getColSpan(),
tabIndex: cell_1.getCanSelect() ? cell_1.getTabIndex() : void 0,
onMouseDown: cell_1.getSelectionStartHandler(),
onMouseEnter: cell_1.getSelectionExtendHandler(),
onMouseOver: titleIfTruncated,
sx: {
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
userSelect: cell_1.getCanSelect() ? "none" : void 0,
...hasColumnLabel(cell_1.column) ? CELL_SX : UTILITY_SX,
...pinnedSx(cell_1.column),
...cellSelectionSx(cell_1)
},
children: cell_1.getIsGrouped() ? /* @__PURE__ */ jsx(cell_1.GroupCell, {}) : cell_1.row.getIsGrouped() && !cell_1.getIsAggregated() ? null : /* @__PURE__ */ jsx(cell_1.FlexRender, {})
})
}, c.id);
const renderFooter = (f) => /* @__PURE__ */ jsx(table.AppFooter, {
header: f,
children: (footer) => /* @__PURE__ */ jsx(TableCell, {
className: classNames(layoutTableClasses.footerCell, pinnedClass(footer.column, "cell")),
colSpan: footer.colSpan,
align: columnAlign(footer.column),
sx: {
...hasColumnLabel(footer.column) ? CELL_SX : UTILITY_SX,
...pinnedSx(footer.column),
...FOOTER_SX
},
children: footer.isPlaceholder ? null : /* @__PURE__ */ jsx(footer.FlexRender, {})
})
}, f.id);
const rowAction = onRowClick ?? onRowDoubleClick;
const renderRow = (row_1, index_3) => {
const cells = windowColumns(row_1.getVisibleCells());
const focusableCells = row_1.getVisibleCells().some((cell_2) => cell_2.getCanSelect());
return /* @__PURE__ */ jsxs(TableRow, {
className: classNames(layoutTableClasses.row, row_1.getIsGrouped() && layoutTableClasses["row--grouped"], row_1.getIsExpanded() && layoutTableClasses["row--expanded"], row_1.getIsPinned() && layoutTableClasses["row--pinned"]),
ref: rowVirtualizer.measureElement,
"data-index": index_3,
hover: true,
selected: row_1.getIsSelected(),
tabIndex: rowAction && !focusableCells ? 0 : void 0,
onClick: onRowClick && (() => onRowClick(row_1)),
onDoubleClick: onRowDoubleClick && (() => onRowDoubleClick(row_1)),
onKeyDown: rowAction && ((event) => {
const target = event.target;
if (event.key === "Enter" && (target === event.currentTarget || target.tagName === "TD")) rowAction(row_1);
}),
sx: {
height: ROW_HEIGHT,
cursor: onRowClick || onRowDoubleClick ? "pointer" : void 0
},
children: [
cells.start.map(renderCell),
skippedColumns(paddingStart),
cells.center.map(renderCell),
skippedColumns(paddingEnd),
cells.end.map(renderCell),
/* @__PURE__ */ jsx(TableCell, {
"aria-hidden": true,
className: layoutTableClasses.filler,
sx: { p: 0 }
})
]
}, row_1.id);
};
const rowCache = useMemo(() => ({ current: /* @__PURE__ */ new Map() }), [
table,
firstColumn?.index,
lastColumn?.index,
paddingStart,
paddingEnd
]);
const cacheKey = (index_4) => `${index_4}:${rows[index_4].id}`;
const bodyRows = virtualRows.map(({ index: index_5 }) => rowCache.current.get(cacheKey(index_5)) ?? renderRow(rows[index_5], index_5));
rowCache.current = new Map(virtualRows.map(({ index: index_6 }, i) => [cacheKey(index_6), bodyRows[i]]));
/** Reserves the scroll height of the rows outside the virtual window. */
const skippedRows = (height) => height > 0 ? /* @__PURE__ */ jsx(TableRow, {
"aria-hidden": true,
className: layoutTableClasses.rowOffset,
style: { height },
children: /* @__PURE__ */ jsx(TableCell, {
colSpan: visibleColumnCount + 1,
sx: {
p: 0,
border: 0
}
})
}) : null;
return /* @__PURE__ */ jsx(table.AppTable, { children: /* @__PURE__ */ jsxs(Paper, {
variant: "outlined",
className: layoutTableClasses.root,
sx: [{
display: "flex",
flexDirection: "column",
height: "100%",
minHeight: 0,
overflow: "hidden"
}, ...Array.isArray(sx) ? sx : [sx]],
children: [
showToolbar && /* @__PURE__ */ jsx(table.Toolbar, { ...toolbar }),
/* @__PURE__ */ jsx(TableContainer, {
ref: containerRef,
className: layoutTableClasses.main,
sx: {
flex: 1,
minHeight: 0,
position: "relative",
scrollPaddingBlockStart: `${headerHeight}px`,
scrollPaddingInlineStart: `${startPinnedWidth}px`,
scrollPaddingInlineEnd: `${endPinnedWidth}px`
},
children: /* @__PURE__ */ jsxs(Table, {
className: layoutTableClasses.table,
stickyHeader: true,
size: "small",
"aria-busy": loading,
"aria-label": typeof toolbar.title === "string" ? toolbar.title : void 0,
sx: {
tableLayout: "fixed",
width: tableWidth,
minWidth: "100%",
"& tbody .MuiTableRow-root:last-of-type .MuiTableCell-root": { borderBottom: 0 },
"& .MuiTableCell-root:focus, & .MuiTableRow-root:focus-visible": {
outline: "1px solid",
outlineColor: "primary.main",
outlineOffset: -1
}
},
children: [
/* @__PURE__ */ jsx(TableHead, {
className: layoutTableClasses.columnHeaders,
children: headerGroups.map((headerGroup, groupIndex_0) => {
const headers = windowColumns(headerGroup.headers.filter((header_1) => header_1.column.getIsVisible()));
return /* @__PURE__ */ jsxs(TableRow, {
className: layoutTableClasses.columnHeaderRow,
sx: { height: COLUMN_HEADER_HEIGHT },
children: [
headers.start.map((h_0) => renderHeader(h_0, groupIndex_0)),
skippedColumns(paddingStart),
headers.center.map((h_1) => renderHeader(h_1, groupIndex_0)),
skippedColumns(paddingEnd),
headers.end.map((h_2) => renderHeader(h_2, groupIndex_0)),
/* @__PURE__ */ jsx(TableCell, {
"aria-hidden": true,
className: layoutTableClasses.filler,
sx: {
p: 0,
position: "sticky",
top: groupIndex_0 * COLUMN_HEADER_HEIGHT,
zIndex: 3,
bgcolor: "background.paper"
}
})
]
}, headerGroup.id);
})
}),
/* @__PURE__ */ jsxs(TableBody, {
className: layoutTableClasses.body,
children: [loading ? /* @__PURE__ */ jsx(table.Skeleton, { rowHeight: ROW_HEIGHT }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
skippedRows(paddingTop),
bodyRows,
skippedRows(paddingBottom)
] }), isEmpty && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, {
colSpan: visibleColumnCount + 1,
sx: {
border: 0,
p: 0
},
children: /* @__PURE__ */ jsx(Box, {
className: layoutTableClasses.overlay,
sx: {
position: "absolute",
top: headerHeight,
left: 0,
bottom: 0,
width: Math.max(tableWidth, containerWidth),
color: "text.secondary",
bgcolor: "background.paper",
"& .no-rows-primary": { opacity: .7 },
"& .no-rows-secondary": { opacity: .3 }
},
children: /* @__PURE__ */ jsxs(Box, {
sx: {
position: "sticky",
left: 0,
width: containerWidth,
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
gap: 1
},
children: [/* @__PURE__ */ jsxs("svg", {
fill: "currentColor",
width: 96,
viewBox: "0 0 452 257",
"aria-hidden": true,
focusable: "false",
children: [
/* @__PURE__ */ jsx("path", {
className: "no-rows-primary",
d: "M348 69c-46.392 0-84 37.608-84 84s37.608 84 84 84 84-37.608 84-84-37.608-84-84-84Zm-104 84c0-57.438 46.562-104 104-104s104 46.562 104 104-46.562 104-104 104-104-46.562-104-104Z"
}),
/* @__PURE__ */ jsx("path", {
className: "no-rows-primary",
d: "M308.929 113.929c3.905-3.905 10.237-3.905 14.142 0l63.64 63.64c3.905 3.905 3.905 10.236 0 14.142-3.906 3.905-10.237 3.905-14.142 0l-63.64-63.64c-3.905-3.905-3.905-10.237 0-14.142Z"
}),
/* @__PURE__ */ jsx("path", {
className: "no-rows-primary",
d: "M308.929 191.711c-3.905-3.906-3.905-10.237 0-14.142l63.64-63.64c3.905-3.905 10.236-3.905 14.142 0 3.905 3.905 3.905 10.237 0 14.142l-63.64 63.64c-3.905 3.905-10.237 3.905-14.142 0Z"
}),
/* @__PURE__ */ jsx("path", {
className: "no-rows-secondary",
d: "M0 10C0 4.477 4.477 0 10 0h380c5.523 0 10 4.477 10 10s-4.477 10-10 10H10C4.477 20 0 15.523 0 10ZM0 59c0-5.523 4.477-10 10-10h231c5.523 0 10 4.477 10 10s-4.477 10-10 10H10C4.477 69 0 64.523 0 59ZM0 106c0-5.523 4.477-10 10-10h203c5.523 0 10 4.477 10 10s-4.477 10-10 10H10c-5.523 0-10-4.477-10-10ZM0 153c0-5.523 4.477-10 10-10h195.5c5.523 0 10 4.477 10 10s-4.477 10-10 10H10c-5.523 0-10-4.477-10-10ZM0 200c0-5.523 4.477-10 10-10h203c5.523 0 10 4.477 10 10s-4.477 10-10 10H10c-5.523 0-10-4.477-10-10ZM0 247c0-5.523 4.477-10 10-10h231c5.523 0 10 4.477 10 10s-4.477 10-10 10H10c-5.523 0-10-4.477-10-10Z"
})
]
}), /* @__PURE__ */ jsx(Box, { children: t("Layout.Table.NoRows") })]
})
})
}) })]
}),
hasFooter && /* @__PURE__ */ jsx(TableFooter, {
className: layoutTableClasses.footer,
children: table.getFooterGroups().map((footerGroup) => {
const footers = windowColumns(footerGroup.headers.filter((header_2) => header_2.column.getIsVisible()));
return /* @__PURE__ */ jsxs(TableRow, {
className: layoutTableClasses.footerRow,
children: [
footers.start.map(renderFooter),
skippedColumns(paddingStart),
footers.center.map(renderFooter),
skippedColumns(paddingEnd),
footers.end.map(renderFooter),
/* @__PURE__ */ jsx(TableCell, {
"aria-hidden": true,
className: layoutTableClasses.filler,
sx: {
p: 0,
...FOOTER_SX
}
})
]
}, footerGroup.id);
})
})
]
})
}),
pagination && pageSizeOffered && /* @__PURE__ */ jsx(table.Pagination, {
className: layoutTableClasses.pagination,
pageSizeOptions
})
]
}) });
}
export { AggregatedCell, Dropzone, FileViewer, Fullscreen, LayoutTable, LoginForm, RouterButton, RouterError, RouterFab, RouterIconButton, RouterLink, RouterListItemButton, RouterNotFound, RouterTab, layoutTableClasses };
//# sourceMappingURL=components.mjs.map