wcz-test 3.2.0 → 3.3.0

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.js CHANGED
@@ -206,7 +206,7 @@ var require_react_is_development = __commonJS({
206
206
  var ContextProvider = REACT_PROVIDER_TYPE;
207
207
  var Element = REACT_ELEMENT_TYPE;
208
208
  var ForwardRef = REACT_FORWARD_REF_TYPE;
209
- var Fragment2 = REACT_FRAGMENT_TYPE;
209
+ var Fragment6 = REACT_FRAGMENT_TYPE;
210
210
  var Lazy = REACT_LAZY_TYPE;
211
211
  var Memo = REACT_MEMO_TYPE;
212
212
  var Portal = REACT_PORTAL_TYPE;
@@ -265,7 +265,7 @@ var require_react_is_development = __commonJS({
265
265
  exports.ContextProvider = ContextProvider;
266
266
  exports.Element = Element;
267
267
  exports.ForwardRef = ForwardRef;
268
- exports.Fragment = Fragment2;
268
+ exports.Fragment = Fragment6;
269
269
  exports.Lazy = Lazy;
270
270
  exports.Memo = Memo;
271
271
  exports.Portal = Portal;
@@ -1040,68 +1040,672 @@ var TypographyWithIcon = ({ startIcon, endIcon, children, sx, gutterBottom, ...p
1040
1040
  ] });
1041
1041
  };
1042
1042
 
1043
- // src/index.ts
1044
- import { PageHeader } from "@toolpad/core/PageContainer";
1045
-
1046
- // src/components/core/PageContainer.tsx
1047
- import { Container } from "@mui/material";
1043
+ // src/components/core/PageHeader.tsx
1044
+ import { CardHeader, Typography as Typography2 } from "@mui/material";
1048
1045
  import { jsx as jsx2 } from "react/jsx-runtime";
1049
- var PageContainer = (props) => {
1050
- return /* @__PURE__ */ jsx2(
1051
- Container,
1046
+ var PageHeader = ({ title, action, sx }) => {
1047
+ return /* @__PURE__ */ jsx2(CardHeader, { title: /* @__PURE__ */ jsx2(Typography2, { variant: "h4", fontWeight: 600, children: title }), action, sx: { px: 0, ...sx } });
1048
+ };
1049
+
1050
+ // src/components/core/TableContainer.tsx
1051
+ import { Box } from "@mui/material";
1052
+ import { useEffect, useRef, useState } from "react";
1053
+ import { jsx as jsx3 } from "react/jsx-runtime";
1054
+ var TableContainer = ({ children, className, sx }) => {
1055
+ const reference = useRef(null);
1056
+ const [height, setHeight] = useState(null);
1057
+ useEffect(() => {
1058
+ const element = reference.current;
1059
+ if (!element) return;
1060
+ const recompute = () => {
1061
+ if (!reference.current) return;
1062
+ const top = Math.ceil(reference.current.getBoundingClientRect().top);
1063
+ const avail = Math.max(0, window.innerHeight - top);
1064
+ setHeight(avail);
1065
+ };
1066
+ recompute();
1067
+ window.addEventListener("resize", recompute);
1068
+ const ro = new ResizeObserver(recompute);
1069
+ ro.observe(document.documentElement);
1070
+ ro.observe(document.body);
1071
+ ro.observe(element);
1072
+ return () => {
1073
+ window.removeEventListener("resize", recompute);
1074
+ ro.disconnect();
1075
+ };
1076
+ }, []);
1077
+ const style = height == null ? { height: "100%" } : { height };
1078
+ return /* @__PURE__ */ jsx3(
1079
+ Box,
1052
1080
  {
1081
+ ref: reference,
1082
+ className,
1053
1083
  sx: {
1054
1084
  display: "flex",
1055
1085
  flexDirection: "column",
1056
- height: "100vh",
1057
- my: 1,
1058
- ...props.sx
1086
+ minHeight: 0,
1087
+ width: "100%",
1088
+ ...sx
1059
1089
  },
1060
- ...props,
1061
- children: props.children
1090
+ style,
1091
+ children: /* @__PURE__ */ jsx3(Box, { sx: { flex: 1, minHeight: 0, height: "100%" }, children })
1092
+ }
1093
+ );
1094
+ };
1095
+
1096
+ // src/components/file/Dropzone.tsx
1097
+ import CloudUpload from "@mui/icons-material/CloudUpload";
1098
+ import { Paper, Typography as Typography3, useTheme } from "@mui/material";
1099
+ import { useDropzone } from "react-dropzone";
1100
+ import { useTranslation } from "react-i18next";
1101
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
1102
+ var baseStyle = {
1103
+ flex: 1,
1104
+ display: "flex",
1105
+ flexDirection: "column",
1106
+ alignItems: "center",
1107
+ padding: "20px",
1108
+ borderWidth: 2,
1109
+ borderRadius: 2,
1110
+ borderStyle: "dashed",
1111
+ outline: "none",
1112
+ transition: "border .24s ease-in-out",
1113
+ cursor: "pointer"
1114
+ };
1115
+ var Dropzone = ({ sx, ...props }) => {
1116
+ const { getRootProps, getInputProps, isFocused, isDragAccept, isDragReject } = useDropzone(props);
1117
+ const { t: t2 } = useTranslation();
1118
+ const theme = useTheme();
1119
+ const style = {
1120
+ ...baseStyle,
1121
+ ...isFocused ? { borderColor: theme.palette.primary.main } : {},
1122
+ ...isDragAccept ? { borderColor: theme.palette.success.main } : {},
1123
+ ...isDragReject ? { borderColor: theme.palette.error.main } : {}
1124
+ };
1125
+ return /* @__PURE__ */ jsxs2(Paper, { variant: "outlined", ...getRootProps({ style }), sx, children: [
1126
+ /* @__PURE__ */ jsx4("input", { ...getInputProps(), style: { display: "none" } }),
1127
+ /* @__PURE__ */ jsx4(CloudUpload, {}),
1128
+ /* @__PURE__ */ jsx4(Typography3, { children: t2("Layout.File.DragSomeFilesHereOrClickToSelectThem") })
1129
+ ] });
1130
+ };
1131
+
1132
+ // src/components/file/FileViewer.tsx
1133
+ import { useState as useState5 } from "react";
1134
+
1135
+ // src/contexts/FileContext.ts
1136
+ import { createContext, useContext } from "react";
1137
+ var FileContext = createContext(null);
1138
+ var useFile = () => {
1139
+ const context = useContext(FileContext);
1140
+ if (!context) {
1141
+ throw new Error("FileViewer components must be used within FileViewer");
1142
+ }
1143
+ return context;
1144
+ };
1145
+
1146
+ // src/hooks/FileHooks.ts
1147
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
1148
+ import saveAs from "file-saver";
1149
+ import { useState as useState2 } from "react";
1150
+ import { Upload as TusUpload } from "tus-js-client";
1151
+ import { uuidv7 } from "uuidv7";
1152
+
1153
+ // src/components/core/AppTitle.tsx
1154
+ import { Chip, Stack as Stack2, Typography as Typography4 } from "@mui/material";
1155
+ import { useRouterState } from "@tanstack/react-router";
1156
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1157
+ var AppTitle = () => {
1158
+ const title = useAppTitle();
1159
+ return /* @__PURE__ */ jsxs3(Stack2, { direction: "row", alignItems: "center", spacing: 2, flexGrow: 1, children: [
1160
+ /* @__PURE__ */ jsx5("img", { src: "/favicon-32x32.png", alt: "app-logo", loading: "lazy" }),
1161
+ /* @__PURE__ */ jsx5(Typography4, { variant: "h6", children: title }),
1162
+ import.meta.env.DEV && /* @__PURE__ */ jsx5(Chip, { size: "small", label: "TEST", color: "info" })
1163
+ ] });
1164
+ };
1165
+ var useAppTitle = () => {
1166
+ const rootRouterState = useRouterState({ select: (s) => s.matches[0] });
1167
+ return rootRouterState.meta?.find((meta) => meta?.title)?.title;
1168
+ };
1169
+
1170
+ // src/utils/ClientUtils.ts
1171
+ import axios from "axios";
1172
+ var Platform = class {
1173
+ static get isAndroid() {
1174
+ return /android/i.test(this.userAgent);
1175
+ }
1176
+ static get isIOS() {
1177
+ return /iPad|iPhone|iPod/.test(this.userAgent);
1178
+ }
1179
+ static get isWindows() {
1180
+ return /windows/i.test(this.userAgent);
1181
+ }
1182
+ static get isMacOS() {
1183
+ return /Macintosh|MacIntel|MacPPC|Mac68K/.test(this.userAgent);
1184
+ }
1185
+ static get userAgent() {
1186
+ return typeof navigator === "undefined" ? "" : navigator.userAgent;
1187
+ }
1188
+ };
1189
+ var rootRouteHead = ({ title }) => () => ({
1190
+ meta: [
1191
+ { charSet: "utf-8" },
1192
+ { name: "viewport", content: "width=device-width, initial-scale=1" },
1193
+ { title },
1194
+ { name: "og:type", content: "website" },
1195
+ { name: "og:title", content: title },
1196
+ { name: "og:image", content: "/favicon-32x32.png" }
1197
+ ],
1198
+ links: [
1199
+ { rel: "apple-touch-icon", sizes: "180x180", href: "/apple-touch-icon.png" },
1200
+ { rel: "icon", type: "image/png", sizes: "32x32", href: "/favicon-32x32.png" },
1201
+ { rel: "icon", type: "image/png", sizes: "16x16", href: "/favicon-16x16.png" },
1202
+ { rel: "manifest", href: "/site.webmanifest" },
1203
+ { rel: "icon", href: "/favicon.ico" }
1204
+ ]
1205
+ });
1206
+ var wczApiClient = axios.create();
1207
+
1208
+ // src/hooks/FileHooks.ts
1209
+ var BASE_URL = import.meta.env.VITE_FILE_API_BASE_URL;
1210
+ var QUERY_KEY = "Files";
1211
+ var HOUR = 1e3 * 60 * 60;
1212
+ var useGetFileMetas = (subId, options) => {
1213
+ const appTitle = useAppTitle();
1214
+ return useQuery({
1215
+ ...options,
1216
+ queryKey: [QUERY_KEY, "meta", subId, appTitle],
1217
+ queryFn: ({ signal }) => wczApiClient.request({
1218
+ url: `${BASE_URL}/v1/meta?appName=${appTitle}&subId=${subId}`,
1219
+ method: "GET",
1220
+ signal
1221
+ }),
1222
+ staleTime: HOUR,
1223
+ gcTime: HOUR,
1224
+ refetchOnWindowFocus: false
1225
+ });
1226
+ };
1227
+ var useGetFileThumbnail = (meta, options) => {
1228
+ const appTitle = useAppTitle();
1229
+ return useQuery({
1230
+ ...options,
1231
+ queryKey: [QUERY_KEY, "thumbnail", meta?.id, appTitle],
1232
+ queryFn: ({ signal }) => wczApiClient.request({
1233
+ url: `${BASE_URL}/v1/thumbnail?appName=${appTitle}&id=${meta?.id}`,
1234
+ method: "GET",
1235
+ signal,
1236
+ responseType: "blob"
1237
+ }),
1238
+ select: (data) => URL.createObjectURL(data),
1239
+ staleTime: HOUR,
1240
+ gcTime: HOUR,
1241
+ refetchOnWindowFocus: false,
1242
+ enabled: !!meta?.id && options?.enabled
1243
+ });
1244
+ };
1245
+ var useGetFile = (meta, options) => {
1246
+ const appTitle = useAppTitle();
1247
+ return useQuery({
1248
+ ...options,
1249
+ queryKey: [QUERY_KEY, meta?.id, appTitle],
1250
+ queryFn: ({ signal }) => wczApiClient.request({
1251
+ url: `${BASE_URL}/v1?appName=${appTitle}&id=${meta?.id}`,
1252
+ method: "GET",
1253
+ signal,
1254
+ responseType: "blob"
1255
+ }),
1256
+ select: (data) => URL.createObjectURL(data),
1257
+ staleTime: HOUR,
1258
+ gcTime: HOUR,
1259
+ refetchOnWindowFocus: false,
1260
+ enabled: !!meta?.id && options?.enabled
1261
+ });
1262
+ };
1263
+ var useDownloadFile = (options) => {
1264
+ const appTitle = useAppTitle();
1265
+ return useMutation({
1266
+ ...options,
1267
+ mutationFn: (meta) => wczApiClient.request({
1268
+ url: `${BASE_URL}/v1/download?appName=${appTitle}&id=${meta.id}`,
1269
+ method: "GET",
1270
+ responseType: "blob"
1271
+ }),
1272
+ onSuccess: (data, variables) => saveAs(data, `${variables.fileName}.${variables.fileExtension}`)
1273
+ });
1274
+ };
1275
+ var useOpenFile = (options) => {
1276
+ const appTitle = useAppTitle();
1277
+ return useMutation({
1278
+ ...options,
1279
+ mutationFn: (meta) => wczApiClient.request({
1280
+ url: `${BASE_URL}/v1?appName=${appTitle}&id=${meta.id}`,
1281
+ method: "GET",
1282
+ responseType: "blob"
1283
+ }),
1284
+ onSuccess: (data) => {
1285
+ window.open(URL.createObjectURL(data));
1286
+ }
1287
+ });
1288
+ };
1289
+ var useUpdateFileMeta = (options) => {
1290
+ const appTitle = useAppTitle();
1291
+ const queryClient = useQueryClient();
1292
+ return useMutation({
1293
+ ...options,
1294
+ mutationFn: (meta) => wczApiClient.request({
1295
+ url: `${BASE_URL}/v1/meta?appName=${appTitle}&id=${meta.id}`,
1296
+ method: "PUT",
1297
+ data: meta
1298
+ }),
1299
+ onSettled: () => queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false })
1300
+ });
1301
+ };
1302
+ var useDeleteFile = (options) => {
1303
+ const appTitle = useAppTitle();
1304
+ const queryClient = useQueryClient();
1305
+ return useMutation({
1306
+ ...options,
1307
+ mutationFn: (meta) => wczApiClient.request({
1308
+ url: `${BASE_URL}/v1?appName=${appTitle}&id=${meta.id}`,
1309
+ method: "DELETE"
1310
+ }),
1311
+ onSettled: () => queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false })
1312
+ });
1313
+ };
1314
+ var useDeleteFiles = (options) => {
1315
+ const appTitle = useAppTitle();
1316
+ const queryClient = useQueryClient();
1317
+ return useMutation({
1318
+ ...options,
1319
+ mutationFn: (subId) => wczApiClient.request({
1320
+ url: `${BASE_URL}/v1?appName=${appTitle}&subId=${subId}`,
1321
+ method: "DELETE"
1322
+ }),
1323
+ onSettled: () => queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false })
1324
+ });
1325
+ };
1326
+ var useUploadFile = ({ subId, onSuccess, onError }) => {
1327
+ const appTitle = useAppTitle();
1328
+ const [progress, setProgress] = useState2(0);
1329
+ const queryClient = useQueryClient();
1330
+ const mutate = async (file) => {
1331
+ if (!subId) throw new Error("subId is required for file upload");
1332
+ if (!appTitle) throw new Error("appTitle is required for file upload");
1333
+ const metadata = {
1334
+ id: uuidv7(),
1335
+ appName: appTitle,
1336
+ subId,
1337
+ fileName: file.name
1338
+ };
1339
+ const upload = new TusUpload(file, {
1340
+ endpoint: `${BASE_URL}/v1/upload`,
1341
+ chunkSize: 1048576,
1342
+ // 1 MB
1343
+ metadata: {
1344
+ id: metadata.id,
1345
+ appName: metadata.appName,
1346
+ subId: metadata.subId,
1347
+ fileName: metadata.fileName,
1348
+ fileExtension: file.type
1349
+ },
1350
+ //headers: { "Authorization": `Bearer ${await getToken()}` }, //TODO: implement token retrieval
1351
+ onError: (error) => {
1352
+ setProgress(0);
1353
+ onError?.(error);
1354
+ },
1355
+ onProgress: (bytesUploaded, bytesTotal) => {
1356
+ setProgress(bytesUploaded / bytesTotal * 100);
1357
+ },
1358
+ onSuccess: () => {
1359
+ setProgress(0);
1360
+ queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta", subId, appTitle], exact: false });
1361
+ onSuccess?.(metadata);
1362
+ }
1363
+ });
1364
+ const previousUploads = await upload.findPreviousUploads();
1365
+ if (previousUploads.length > 0) {
1366
+ upload.resumeFromPreviousUpload(previousUploads[0]);
1367
+ }
1368
+ upload.start();
1369
+ };
1370
+ return { mutate, progress };
1371
+ };
1372
+
1373
+ // src/components/file/fileViewer/FileViewerGrid.tsx
1374
+ import MoreVert from "@mui/icons-material/MoreVert";
1375
+ import { Box as Box2, IconButton, ImageListItem, ImageListItemBar, Stack as Stack3, Tooltip } from "@mui/material";
1376
+ import { grey } from "@mui/material/colors";
1377
+ import { Fragment, useEffect as useEffect3, useState as useState3 } from "react";
1378
+
1379
+ // src/components/file/fileViewer/common/ActionsMenu.tsx
1380
+ import Delete from "@mui/icons-material/Delete";
1381
+ import FileDownload from "@mui/icons-material/FileDownload";
1382
+ import { List, ListItemButton, ListItemIcon, ListItemText, Menu } from "@mui/material";
1383
+ import { useTranslation as useTranslation3 } from "react-i18next";
1384
+
1385
+ // src/hooks/DialogsHooks.tsx
1386
+ import Button from "@mui/material/Button";
1387
+ import Dialog from "@mui/material/Dialog";
1388
+ import DialogActions from "@mui/material/DialogActions";
1389
+ import DialogContent from "@mui/material/DialogContent";
1390
+ import DialogTitle from "@mui/material/DialogTitle";
1391
+
1392
+ // node_modules/@mui/utils/esm/useEventCallback/useEventCallback.js
1393
+ import * as React2 from "react";
1394
+
1395
+ // node_modules/@mui/utils/esm/useEnhancedEffect/useEnhancedEffect.js
1396
+ import * as React from "react";
1397
+ var useEnhancedEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
1398
+ var useEnhancedEffect_default = useEnhancedEffect;
1399
+
1400
+ // node_modules/@mui/utils/esm/useEventCallback/useEventCallback.js
1401
+ function useEventCallback(fn) {
1402
+ const ref = React2.useRef(fn);
1403
+ useEnhancedEffect_default(() => {
1404
+ ref.current = fn;
1405
+ });
1406
+ return React2.useRef((...args) => (
1407
+ // @ts-expect-error hide `this`
1408
+ (0, ref.current)(...args)
1409
+ )).current;
1410
+ }
1411
+ var useEventCallback_default = useEventCallback;
1412
+
1413
+ // src/hooks/DialogsHooks.tsx
1414
+ import { useContext as useContext2, useMemo } from "react";
1415
+ import { useTranslation as useTranslation2 } from "react-i18next";
1416
+
1417
+ // src/contexts/DialogsContext.ts
1418
+ import { createContext as createContext2 } from "react";
1419
+ var DialogsContext = createContext2({});
1420
+
1421
+ // src/hooks/DialogsHooks.tsx
1422
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1423
+ function AlertDialog({ open, payload, onClose }) {
1424
+ const { t: t2 } = useTranslation2();
1425
+ return /* @__PURE__ */ jsxs4(Dialog, { maxWidth: "xs", fullWidth: true, open, onClose: () => onClose(), children: [
1426
+ /* @__PURE__ */ jsx6(DialogTitle, { children: payload.title ?? t2("Layout.Dialog.Alert") }),
1427
+ /* @__PURE__ */ jsx6(DialogContent, { children: payload.message }),
1428
+ /* @__PURE__ */ jsx6(DialogActions, { children: /* @__PURE__ */ jsx6(Button, { disabled: !open, onClick: () => onClose(), children: t2("Layout.Dialog.Confirm") }) })
1429
+ ] });
1430
+ }
1431
+ function ConfirmDialog({ open, payload, onClose }) {
1432
+ const { t: t2 } = useTranslation2();
1433
+ return /* @__PURE__ */ jsxs4(Dialog, { maxWidth: "xs", fullWidth: true, open, onClose: () => onClose(false), children: [
1434
+ /* @__PURE__ */ jsx6(DialogTitle, { children: payload.title ?? t2("Layout.Dialog.Confirm") }),
1435
+ /* @__PURE__ */ jsx6(DialogContent, { children: payload.message }),
1436
+ /* @__PURE__ */ jsxs4(DialogActions, { children: [
1437
+ /* @__PURE__ */ jsx6(Button, { autoFocus: true, disabled: !open, onClick: () => onClose(false), children: payload.cancelText ?? t2("Layout.Dialog.Cancel") }),
1438
+ /* @__PURE__ */ jsx6(Button, { disabled: !open, onClick: () => onClose(true), children: t2("Layout.Dialog.Confirm") })
1439
+ ] })
1440
+ ] });
1441
+ }
1442
+ function useDialogs() {
1443
+ const { open, close } = useContext2(DialogsContext);
1444
+ const alert = useEventCallback_default(
1445
+ (message, { ...options } = {}) => open(AlertDialog, { ...options, message })
1446
+ );
1447
+ const confirm = useEventCallback_default(
1448
+ (message, { ...options } = {}) => open(ConfirmDialog, { ...options, message })
1449
+ );
1450
+ return useMemo(() => ({ alert, confirm, open, close }), [alert, close, confirm, open]);
1451
+ }
1452
+
1453
+ // src/components/file/fileViewer/common/ActionsMenu.tsx
1454
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1455
+ var ActionsMenu = ({ meta, menu, setMenu }) => {
1456
+ const { t: t2 } = useTranslation3();
1457
+ const { fileMetas, onDelete, actions } = useFile();
1458
+ const { confirm } = useDialogs();
1459
+ const handleMenuClose = () => {
1460
+ setMenu(null);
1461
+ };
1462
+ const { mutate: download, isPending: isDownloading } = useDownloadFile();
1463
+ const { mutate: deleteFile, isPending: isDeleting } = useDeleteFile();
1464
+ const handleOnDownload = () => {
1465
+ handleMenuClose();
1466
+ download(meta);
1467
+ };
1468
+ const handleOnDelete = async () => {
1469
+ if (!await confirm(t2("Layout.File.AreYouSureYouWantToDelete", { fileName: meta.fileName })))
1470
+ return;
1471
+ deleteFile(meta);
1472
+ handleMenuClose();
1473
+ if (onDelete) {
1474
+ const remainingFileMetas = fileMetas.filter((m) => m.id !== meta.id);
1475
+ onDelete({ remainingFileMetas, deletedFileMeta: meta });
1476
+ }
1477
+ };
1478
+ return /* @__PURE__ */ jsx7(
1479
+ Menu,
1480
+ {
1481
+ open: menu !== null,
1482
+ onClose: handleMenuClose,
1483
+ anchorReference: "anchorPosition",
1484
+ variant: "menu",
1485
+ anchorPosition: menu === null ? void 0 : { top: menu.mouseY, left: menu.mouseX },
1486
+ children: /* @__PURE__ */ jsxs5(List, { disablePadding: true, children: [
1487
+ actions?.download !== false && /* @__PURE__ */ jsxs5(ListItemButton, { onClick: handleOnDownload, disabled: isDownloading, children: [
1488
+ /* @__PURE__ */ jsx7(ListItemIcon, { children: /* @__PURE__ */ jsx7(FileDownload, {}) }),
1489
+ /* @__PURE__ */ jsx7(ListItemText, { children: t2("Layout.File.Download") })
1490
+ ] }),
1491
+ actions?.delete !== false && /* @__PURE__ */ jsxs5(ListItemButton, { onClick: handleOnDelete, disabled: isDeleting, children: [
1492
+ /* @__PURE__ */ jsx7(ListItemIcon, { children: /* @__PURE__ */ jsx7(Delete, {}) }),
1493
+ /* @__PURE__ */ jsx7(ListItemText, { children: t2("Layout.File.Delete") })
1494
+ ] })
1495
+ ] })
1496
+ }
1497
+ );
1498
+ };
1499
+
1500
+ // src/components/file/fileViewer/FileViewerGrid.tsx
1501
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1502
+ var IMAGE_SIZE = 150;
1503
+ var FileViewerGrid = ({ sx, size, itemBar }) => {
1504
+ const { fileMetas } = useFile();
1505
+ return /* @__PURE__ */ jsx8(Stack3, { direction: "row", spacing: 1, sx: { overflow: "auto", ...sx }, children: fileMetas.map((fileMeta) => /* @__PURE__ */ jsx8(
1506
+ GridFileViewerItem,
1507
+ {
1508
+ meta: fileMeta,
1509
+ size,
1510
+ itemBar
1511
+ },
1512
+ fileMeta.id
1513
+ )) });
1514
+ };
1515
+ var GridFileViewerItem = ({ meta, size, itemBar }) => {
1516
+ const { setImageId, actions } = useFile();
1517
+ const [showItemBar, setShowItemBar] = useState3(itemBar === "always");
1518
+ const [menu, setMenu] = useState3(null);
1519
+ useEffect3(() => {
1520
+ setShowItemBar(itemBar === "always");
1521
+ }, [itemBar]);
1522
+ const { data: source } = useGetFileThumbnail(meta);
1523
+ const handleOnMouseEnter = () => setShowItemBar(true);
1524
+ const handleOnMouseLeave = () => itemBar !== "always" && setShowItemBar(false);
1525
+ const openMenu = (event) => {
1526
+ setMenu(menu === null ? { mouseX: event.clientX, mouseY: event.clientY } : null);
1527
+ setTimeout(() => setShowItemBar(true));
1528
+ };
1529
+ const { mutate: openFile } = useOpenFile();
1530
+ const { mutate: download } = useDownloadFile();
1531
+ const onClick = () => {
1532
+ switch (meta.mediaType) {
1533
+ case "image": {
1534
+ return setImageId(meta.id);
1535
+ }
1536
+ case "application": {
1537
+ return openFile(meta);
1538
+ }
1539
+ case "video": {
1540
+ return openFile(meta);
1541
+ }
1542
+ default: {
1543
+ return download(meta);
1544
+ }
1545
+ }
1546
+ };
1547
+ return /* @__PURE__ */ jsxs6(Fragment, { children: [
1548
+ /* @__PURE__ */ jsxs6(ImageListItem, { sx: { width: size ?? IMAGE_SIZE, height: size ?? IMAGE_SIZE }, onMouseEnter: handleOnMouseEnter, onMouseLeave: handleOnMouseLeave, children: [
1549
+ /* @__PURE__ */ jsx8(
1550
+ Box2,
1551
+ {
1552
+ component: "img",
1553
+ src: source,
1554
+ loading: "lazy",
1555
+ alt: "thumbnail-" + meta.id,
1556
+ onClick,
1557
+ sx: { cursor: "pointer", objectFit: "contain", width: size ?? IMAGE_SIZE, height: size ?? IMAGE_SIZE }
1558
+ }
1559
+ ),
1560
+ itemBar !== "hidden" && showItemBar && /* @__PURE__ */ jsx8(
1561
+ ImageListItemBar,
1562
+ {
1563
+ title: /* @__PURE__ */ jsx8(Tooltip, { title: meta.fileName, children: /* @__PURE__ */ jsx8(Box2, { children: meta.fileName }) }),
1564
+ actionIcon: (actions?.download !== false || actions?.delete !== false) && /* @__PURE__ */ jsx8(IconButton, { sx: { color: grey[100] }, onClick: openMenu, children: /* @__PURE__ */ jsx8(MoreVert, {}) })
1565
+ }
1566
+ )
1567
+ ] }),
1568
+ (actions?.download !== false || actions?.delete !== false) && /* @__PURE__ */ jsx8(ActionsMenu, { meta, menu, setMenu })
1569
+ ] });
1570
+ };
1571
+
1572
+ // src/components/file/fileViewer/FileViewerList.tsx
1573
+ import AttachFile from "@mui/icons-material/AttachFile";
1574
+ import Image from "@mui/icons-material/Image";
1575
+ import MoreVert2 from "@mui/icons-material/MoreVert";
1576
+ import SmartDisplay from "@mui/icons-material/SmartDisplay";
1577
+ import { IconButton as IconButton2, List as List2, ListItemButton as ListItemButton2, ListItemIcon as ListItemIcon2, ListItemText as ListItemText2 } from "@mui/material";
1578
+ import { Fragment as Fragment2, useState as useState4 } from "react";
1579
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1580
+ var FileViewerList = ({ sx }) => {
1581
+ const { fileMetas } = useFile();
1582
+ return /* @__PURE__ */ jsx9(List2, { dense: true, sx, children: fileMetas.map(
1583
+ (fileMeta) => /* @__PURE__ */ jsx9(
1584
+ ListFileViewerItem,
1585
+ {
1586
+ meta: fileMeta
1587
+ },
1588
+ fileMeta.id
1589
+ )
1590
+ ) });
1591
+ };
1592
+ var ListFileViewerItem = ({ meta }) => {
1593
+ const { setImageId, actions } = useFile();
1594
+ const [menu, setMenu] = useState4(null);
1595
+ const openMenu = (event) => {
1596
+ event.stopPropagation();
1597
+ setMenu(menu === null ? { mouseX: event.clientX, mouseY: event.clientY } : null);
1598
+ };
1599
+ const { mutate: openFile } = useOpenFile();
1600
+ const { mutate: download } = useDownloadFile();
1601
+ const onClick = () => {
1602
+ switch (meta.mediaType) {
1603
+ case "image": {
1604
+ return setImageId(meta.id);
1605
+ }
1606
+ case "application": {
1607
+ return openFile(meta);
1608
+ }
1609
+ case "video": {
1610
+ return openFile(meta);
1611
+ }
1612
+ default: {
1613
+ return download(meta);
1614
+ }
1062
1615
  }
1063
- );
1616
+ };
1617
+ const icon = () => {
1618
+ switch (meta.mediaType) {
1619
+ case "image": {
1620
+ return /* @__PURE__ */ jsx9(Image, {});
1621
+ }
1622
+ case "video": {
1623
+ return /* @__PURE__ */ jsx9(SmartDisplay, {});
1624
+ }
1625
+ default: {
1626
+ return /* @__PURE__ */ jsx9(AttachFile, {});
1627
+ }
1628
+ }
1629
+ };
1630
+ return /* @__PURE__ */ jsxs7(Fragment2, { children: [
1631
+ /* @__PURE__ */ jsxs7(ListItemButton2, { onClick, children: [
1632
+ /* @__PURE__ */ jsx9(ListItemIcon2, { children: icon() }),
1633
+ /* @__PURE__ */ jsx9(ListItemText2, { primary: `${meta.fileName}.${meta.fileExtension}` }),
1634
+ (actions?.download !== false || actions?.delete !== false) && /* @__PURE__ */ jsx9(IconButton2, { edge: "end", onClick: openMenu, children: /* @__PURE__ */ jsx9(MoreVert2, {}) })
1635
+ ] }, meta.id),
1636
+ (actions?.download !== false || actions?.delete !== false) && /* @__PURE__ */ jsx9(ActionsMenu, { meta, menu, setMenu })
1637
+ ] });
1064
1638
  };
1065
1639
 
1066
- // src/components/file/Dropzone.tsx
1067
- import CloudUpload from "@mui/icons-material/CloudUpload";
1068
- import { Paper, Typography as Typography2, useTheme } from "@mui/material";
1069
- import { useDropzone } from "react-dropzone";
1070
- import { useTranslation } from "react-i18next";
1071
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1072
- var baseStyle = {
1073
- flex: 1,
1074
- display: "flex",
1075
- flexDirection: "column",
1076
- alignItems: "center",
1077
- padding: "20px",
1078
- borderWidth: 2,
1079
- borderRadius: 2,
1080
- borderStyle: "dashed",
1081
- outline: "none",
1082
- transition: "border .24s ease-in-out",
1083
- cursor: "pointer"
1084
- };
1085
- var Dropzone = ({ sx, ...props }) => {
1086
- const { getRootProps, getInputProps, isFocused, isDragAccept, isDragReject } = useDropzone(props);
1087
- const { t: t2 } = useTranslation();
1088
- const theme = useTheme();
1089
- const style = {
1090
- ...baseStyle,
1091
- ...isFocused ? { borderColor: theme.palette.primary.main } : {},
1092
- ...isDragAccept ? { borderColor: theme.palette.success.main } : {},
1093
- ...isDragReject ? { borderColor: theme.palette.error.main } : {}
1640
+ // src/components/file/fileViewer/ImageViewer.tsx
1641
+ import Close from "@mui/icons-material/Close";
1642
+ import { Box as Box3, Dialog as Dialog2, Fab } from "@mui/material";
1643
+ import { useEffect as useEffect4 } from "react";
1644
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
1645
+ var ImageViewer = ({ metaId }) => {
1646
+ const { fileMetas, setImageId } = useFile();
1647
+ const meta = fileMetas.find((m) => m.id === metaId);
1648
+ const { data: source } = useGetFile(meta);
1649
+ useEffect4(() => {
1650
+ if (globalThis.window !== void 0 && metaId)
1651
+ globalThis.addEventListener("keydown", handleOnKeydown);
1652
+ return () => {
1653
+ globalThis.removeEventListener("keydown", handleOnKeydown);
1654
+ };
1655
+ }, [metaId]);
1656
+ const handleOnKeydown = (event) => {
1657
+ const images = fileMetas.filter((m) => m.mediaType === "image");
1658
+ const imageIndex = images.findIndex((m) => m.id === metaId);
1659
+ switch (event.key) {
1660
+ case "ArrowLeft": {
1661
+ return handleOnArrowLeft(images, imageIndex);
1662
+ }
1663
+ case "ArrowRight": {
1664
+ return handleOnArrowRight(images, imageIndex);
1665
+ }
1666
+ case "Backspace":
1667
+ case "Escape": {
1668
+ event.preventDefault();
1669
+ return onClose();
1670
+ }
1671
+ }
1094
1672
  };
1095
- return /* @__PURE__ */ jsxs2(Paper, { variant: "outlined", ...getRootProps({ style }), sx, children: [
1096
- /* @__PURE__ */ jsx3("input", { ...getInputProps(), style: { display: "none" } }),
1097
- /* @__PURE__ */ jsx3(CloudUpload, {}),
1098
- /* @__PURE__ */ jsx3(Typography2, { children: t2("Layout.File.DragSomeFilesHereOrClickToSelectThem") })
1673
+ const handleOnArrowLeft = (images, index) => {
1674
+ if (index > 0) {
1675
+ const previousFile = images[index - 1];
1676
+ setImageId(previousFile.id);
1677
+ }
1678
+ };
1679
+ const handleOnArrowRight = (images, index) => {
1680
+ if (index < images.length - 1) {
1681
+ const nextFile = images[index + 1];
1682
+ setImageId(nextFile.id);
1683
+ }
1684
+ };
1685
+ const onClose = () => setImageId("");
1686
+ if (!metaId) return null;
1687
+ return /* @__PURE__ */ jsxs8(Dialog2, { open: true, onClose, maxWidth: "xl", children: [
1688
+ /* @__PURE__ */ jsx10(Box3, { component: "img", src: source, alt: metaId, sx: { maxWidth: "100vw", maxHeight: { xs: "calc(100vh - 56px)", sm: "calc(100vh - 64px)" } } }),
1689
+ /* @__PURE__ */ jsx10(Fab, { size: "medium", onClick: onClose, sx: { position: "fixed", top: 8, right: 8 }, children: /* @__PURE__ */ jsx10(Close, {}) })
1690
+ ] });
1691
+ };
1692
+
1693
+ // src/components/file/FileViewer.tsx
1694
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1695
+ var FileViewer = ({ subId, onDelete, actions, children }) => {
1696
+ const { data: fileMetas = [] } = useGetFileMetas(subId, { enabled: !!subId });
1697
+ const [imageId, setImageId] = useState5("");
1698
+ const components = { Grid: FileViewerGrid, List: FileViewerList };
1699
+ if (fileMetas.length === 0) return null;
1700
+ return /* @__PURE__ */ jsxs9(FileContext.Provider, { value: { fileMetas, onDelete, actions, setImageId }, children: [
1701
+ children(components),
1702
+ /* @__PURE__ */ jsx11(ImageViewer, { metaId: imageId })
1099
1703
  ] });
1100
1704
  };
1101
1705
 
1102
1706
  // src/components/data-grid/ChipInputCell.tsx
1103
- import { Chip, Stack as Stack2 } from "@mui/material";
1104
- import { jsx as jsx4 } from "react/jsx-runtime";
1707
+ import { Chip as Chip2, Stack as Stack4 } from "@mui/material";
1708
+ import { jsx as jsx12 } from "react/jsx-runtime";
1105
1709
  var isArray = (value) => Array.isArray(value);
1106
1710
  var ChipInputCell = ({ params, slotProps, getLabel }) => {
1107
1711
  if (!params.value) return null;
@@ -1110,113 +1714,110 @@ var ChipInputCell = ({ params, slotProps, getLabel }) => {
1110
1714
  return value;
1111
1715
  };
1112
1716
  if (isArray(params.value))
1113
- return /* @__PURE__ */ jsx4(Stack2, { direction: "row", alignItems: "center", gap: 1, sx: { overflowX: "auto", height: "100%", width: params.colDef.computedWidth }, children: params.value.map(
1114
- (value, index) => /* @__PURE__ */ jsx4(Chip, { label: getLabelValue(value), ...slotProps }, `${index + 1}-chip-input-cell`)
1717
+ return /* @__PURE__ */ jsx12(Stack4, { direction: "row", alignItems: "center", gap: 1, sx: { overflowX: "auto", height: "100%", width: params.colDef.computedWidth }, children: params.value.map(
1718
+ (value, index) => /* @__PURE__ */ jsx12(Chip2, { label: getLabelValue(value), ...slotProps }, `${index + 1}-chip-input-cell`)
1115
1719
  ) });
1116
- return /* @__PURE__ */ jsx4(Chip, { label: getLabelValue(params.value), ...slotProps });
1720
+ return /* @__PURE__ */ jsx12(Chip2, { label: getLabelValue(params.value), ...slotProps });
1117
1721
  };
1118
1722
 
1119
1723
  // src/components/data-grid/EditableColumnHeader.tsx
1120
1724
  import Edit from "@mui/icons-material/Edit";
1121
- import { jsx as jsx5 } from "react/jsx-runtime";
1725
+ import { jsx as jsx13 } from "react/jsx-runtime";
1122
1726
  var EditableColumnHeader = ({ colDef }) => {
1123
- return /* @__PURE__ */ jsx5(TypographyWithIcon, { endIcon: /* @__PURE__ */ jsx5(Edit, { color: "disabled", fontSize: "small" }), variant: "body2", className: "MuiDataGrid-columnHeaderTitle", children: colDef.headerName });
1727
+ return /* @__PURE__ */ jsx13(TypographyWithIcon, { endIcon: /* @__PURE__ */ jsx13(Edit, { color: "disabled", fontSize: "small" }), variant: "body2", className: "MuiDataGrid-columnHeaderTitle", children: colDef.headerName });
1124
1728
  };
1125
1729
 
1126
1730
  // src/components/router/RouterButton.tsx
1127
- import { Button } from "@mui/material";
1731
+ import { Button as Button2 } from "@mui/material";
1128
1732
  import { createLink } from "@tanstack/react-router";
1129
- import React from "react";
1130
- import { jsx as jsx6 } from "react/jsx-runtime";
1131
- var Component = React.forwardRef(function ButtonComponent(props, reference) {
1132
- return /* @__PURE__ */ jsx6(Button, { ref: reference, component: "a", ...props });
1733
+ import React5 from "react";
1734
+ import { jsx as jsx14 } from "react/jsx-runtime";
1735
+ var Component = React5.forwardRef(function ButtonComponent(props, reference) {
1736
+ return /* @__PURE__ */ jsx14(Button2, { ref: reference, component: "a", ...props });
1133
1737
  });
1134
1738
  var CreatedComponent = createLink(Component);
1135
1739
  var RouterButton = (props) => {
1136
- return /* @__PURE__ */ jsx6(CreatedComponent, { preload: "intent", ...props });
1740
+ return /* @__PURE__ */ jsx14(CreatedComponent, { preload: "intent", ...props });
1137
1741
  };
1138
1742
 
1139
1743
  // src/components/router/RouterGridActionsCellItem.tsx
1140
1744
  import { GridActionsCellItem } from "@mui/x-data-grid-premium";
1141
1745
  import { createLink as createLink2 } from "@tanstack/react-router";
1142
- import React2 from "react";
1143
- import { jsx as jsx7 } from "react/jsx-runtime";
1144
- var Component2 = React2.forwardRef(
1746
+ import React6 from "react";
1747
+ import { jsx as jsx15 } from "react/jsx-runtime";
1748
+ var Component2 = React6.forwardRef(
1145
1749
  function GridActionsCellItemComponent(props, reference) {
1146
- return /* @__PURE__ */ jsx7(GridActionsCellItem, { ref: reference, component: "a", ...props });
1750
+ return /* @__PURE__ */ jsx15(GridActionsCellItem, { ref: reference, component: "a", ...props });
1147
1751
  }
1148
1752
  );
1149
1753
  var CreatedComponent2 = createLink2(Component2);
1150
1754
  var RouterGridActionsCellItem = (props) => {
1151
- return /* @__PURE__ */ jsx7(CreatedComponent2, { preload: "intent", ...props });
1755
+ return /* @__PURE__ */ jsx15(CreatedComponent2, { preload: "intent", ...props });
1152
1756
  };
1153
1757
 
1154
1758
  // src/components/router/RouterIconButton.tsx
1155
- import { IconButton } from "@mui/material";
1759
+ import { IconButton as IconButton3 } from "@mui/material";
1156
1760
  import { createLink as createLink3 } from "@tanstack/react-router";
1157
- import React3 from "react";
1158
- import { jsx as jsx8 } from "react/jsx-runtime";
1159
- var Component3 = React3.forwardRef(function IconButtonComponent(props, reference) {
1160
- return /* @__PURE__ */ jsx8(IconButton, { ref: reference, component: "a", ...props });
1761
+ import React7 from "react";
1762
+ import { jsx as jsx16 } from "react/jsx-runtime";
1763
+ var Component3 = React7.forwardRef(function IconButtonComponent(props, reference) {
1764
+ return /* @__PURE__ */ jsx16(IconButton3, { ref: reference, component: "a", ...props });
1161
1765
  });
1162
1766
  var CreatedComponent3 = createLink3(Component3);
1163
1767
  var RouterIconButton = (props) => {
1164
- return /* @__PURE__ */ jsx8(CreatedComponent3, { preload: "intent", ...props });
1768
+ return /* @__PURE__ */ jsx16(CreatedComponent3, { preload: "intent", ...props });
1165
1769
  };
1166
1770
 
1167
1771
  // src/components/router/RouterLink.tsx
1168
1772
  import { Link } from "@mui/material";
1169
1773
  import { createLink as createLink4 } from "@tanstack/react-router";
1170
- import React4 from "react";
1171
- import { jsx as jsx9 } from "react/jsx-runtime";
1172
- var Component4 = React4.forwardRef(function LinkComponent(props, reference) {
1173
- return /* @__PURE__ */ jsx9(Link, { ref: reference, ...props });
1774
+ import React8 from "react";
1775
+ import { jsx as jsx17 } from "react/jsx-runtime";
1776
+ var Component4 = React8.forwardRef(function LinkComponent(props, reference) {
1777
+ return /* @__PURE__ */ jsx17(Link, { ref: reference, ...props });
1174
1778
  });
1175
1779
  var CreatedComponent4 = createLink4(Component4);
1176
1780
  var RouterLink = (props) => {
1177
- return /* @__PURE__ */ jsx9(CreatedComponent4, { preload: "intent", ...props });
1781
+ return /* @__PURE__ */ jsx17(CreatedComponent4, { preload: "intent", ...props });
1178
1782
  };
1179
1783
 
1180
1784
  // src/components/router/RouterTab.tsx
1181
1785
  import { Tab } from "@mui/material";
1182
1786
  import { createLink as createLink5 } from "@tanstack/react-router";
1183
- import React5 from "react";
1184
- import { jsx as jsx10 } from "react/jsx-runtime";
1185
- var Component5 = React5.forwardRef(function TabComponent(props, reference) {
1186
- return /* @__PURE__ */ jsx10(Tab, { ref: reference, component: "a", ...props });
1787
+ import React9 from "react";
1788
+ import { jsx as jsx18 } from "react/jsx-runtime";
1789
+ var Component5 = React9.forwardRef(function TabComponent(props, reference) {
1790
+ return /* @__PURE__ */ jsx18(Tab, { ref: reference, component: "a", ...props });
1187
1791
  });
1188
1792
  var CreatedComponent5 = createLink5(Component5);
1189
1793
  var RouterTab = (props) => {
1190
- return /* @__PURE__ */ jsx10(CreatedComponent5, { preload: "intent", ...props });
1794
+ return /* @__PURE__ */ jsx18(CreatedComponent5, { preload: "intent", ...props });
1191
1795
  };
1192
1796
 
1193
1797
  // src/components/router/RouterNotFound.tsx
1194
- import { Box, Divider, Typography as Typography3 } from "@mui/material";
1195
- import { useTranslation as useTranslation2 } from "react-i18next";
1196
- import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
1798
+ import { Box as Box4, Divider, Typography as Typography5 } from "@mui/material";
1799
+ import { useTranslation as useTranslation4 } from "react-i18next";
1800
+ import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
1197
1801
  function RouterNotFound() {
1198
- const { t: t2 } = useTranslation2();
1199
- return /* @__PURE__ */ jsx11(Box, { height: "100vh", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", textAlign: "center", px: 2, children: /* @__PURE__ */ jsxs3(Box, { display: "flex", alignItems: "center", mb: 4, children: [
1200
- /* @__PURE__ */ jsx11(Typography3, { variant: "h3", component: "span", fontWeight: 500, sx: { lineHeight: 1 }, children: "404" }),
1201
- /* @__PURE__ */ jsx11(Divider, { orientation: "vertical", flexItem: true, sx: { mx: 3 } }),
1202
- /* @__PURE__ */ jsx11(Typography3, { variant: "h5", component: "span", children: t2("Layout.ThisPageCouldNotBeFound") })
1802
+ const { t: t2 } = useTranslation4();
1803
+ return /* @__PURE__ */ jsx19(Box4, { height: "100vh", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", textAlign: "center", px: 2, children: /* @__PURE__ */ jsxs10(Box4, { display: "flex", alignItems: "center", mb: 4, children: [
1804
+ /* @__PURE__ */ jsx19(Typography5, { variant: "h3", component: "span", fontWeight: 500, sx: { lineHeight: 1 }, children: "404" }),
1805
+ /* @__PURE__ */ jsx19(Divider, { orientation: "vertical", flexItem: true, sx: { mx: 3 } }),
1806
+ /* @__PURE__ */ jsx19(Typography5, { variant: "h5", component: "span", children: t2("Layout.ThisPageCouldNotBeFound") })
1203
1807
  ] }) });
1204
1808
  }
1205
1809
 
1206
1810
  // src/components/router/RouterError.tsx
1207
- import { Box as Box2, Divider as Divider2, Typography as Typography4 } from "@mui/material";
1208
- import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
1811
+ import { Box as Box5, Divider as Divider2, Typography as Typography6 } from "@mui/material";
1812
+ import { jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
1209
1813
  var RouterError = ({ error }) => {
1210
- return /* @__PURE__ */ jsx12(Box2, { height: "100vh", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", textAlign: "center", px: 2, children: /* @__PURE__ */ jsxs4(Box2, { display: "flex", alignItems: "center", mb: 4, children: [
1211
- /* @__PURE__ */ jsx12(Typography4, { variant: "h3", component: "span", fontWeight: 500, sx: { lineHeight: 1 }, children: error.name || "500" }),
1212
- /* @__PURE__ */ jsx12(Divider2, { orientation: "vertical", flexItem: true, sx: { mx: 3 } }),
1213
- /* @__PURE__ */ jsx12(Typography4, { variant: "h5", component: "span", children: error.message })
1814
+ return /* @__PURE__ */ jsx20(Box5, { height: "100vh", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", textAlign: "center", px: 2, children: /* @__PURE__ */ jsxs11(Box5, { display: "flex", alignItems: "center", mb: 4, children: [
1815
+ /* @__PURE__ */ jsx20(Typography6, { variant: "h3", component: "span", fontWeight: 500, sx: { lineHeight: 1 }, children: error.name || "500" }),
1816
+ /* @__PURE__ */ jsx20(Divider2, { orientation: "vertical", flexItem: true, sx: { mx: 3 } }),
1817
+ /* @__PURE__ */ jsx20(Typography6, { variant: "h5", component: "span", children: error.message })
1214
1818
  ] }) });
1215
1819
  };
1216
1820
 
1217
- // src/providers/LayoutProvider.tsx
1218
- import { LinearProgress, useMediaQuery } from "@mui/material";
1219
-
1220
1821
  // node_modules/@babel/runtime/helpers/esm/extends.js
1221
1822
  function _extends() {
1222
1823
  return _extends = Object.assign ? Object.assign.bind() : function(n) {
@@ -1241,11 +1842,11 @@ function _objectWithoutPropertiesLoose(r, e) {
1241
1842
 
1242
1843
  // node_modules/@mui/x-date-pickers/esm/LocalizationProvider/LocalizationProvider.js
1243
1844
  var import_prop_types = __toESM(require_prop_types(), 1);
1244
- import * as React6 from "react";
1845
+ import * as React10 from "react";
1245
1846
  import { useThemeProps } from "@mui/material/styles";
1246
1847
  import { jsx as _jsx } from "react/jsx-runtime";
1247
1848
  var _excluded = ["localeText"];
1248
- var PickerAdapterContext = /* @__PURE__ */ React6.createContext(null);
1849
+ var PickerAdapterContext = /* @__PURE__ */ React10.createContext(null);
1249
1850
  if (process.env.NODE_ENV !== "production") PickerAdapterContext.displayName = "PickerAdapterContext";
1250
1851
  var LocalizationProvider = function LocalizationProvider2(inProps) {
1251
1852
  const {
@@ -1254,7 +1855,7 @@ var LocalizationProvider = function LocalizationProvider2(inProps) {
1254
1855
  const {
1255
1856
  adapter: parentAdapter,
1256
1857
  localeText: parentLocaleText
1257
- } = React6.useContext(PickerAdapterContext) ?? {
1858
+ } = React10.useContext(PickerAdapterContext) ?? {
1258
1859
  utils: void 0,
1259
1860
  adapter: void 0,
1260
1861
  localeText: void 0
@@ -1273,8 +1874,8 @@ var LocalizationProvider = function LocalizationProvider2(inProps) {
1273
1874
  adapterLocale,
1274
1875
  localeText: themeLocaleText
1275
1876
  } = props;
1276
- const localeText = React6.useMemo(() => _extends({}, themeLocaleText, parentLocaleText, inLocaleText), [themeLocaleText, parentLocaleText, inLocaleText]);
1277
- const adapter = React6.useMemo(() => {
1877
+ const localeText = React10.useMemo(() => _extends({}, themeLocaleText, parentLocaleText, inLocaleText), [themeLocaleText, parentLocaleText, inLocaleText]);
1878
+ const adapter = React10.useMemo(() => {
1278
1879
  if (!DateAdapter) {
1279
1880
  if (parentAdapter) {
1280
1881
  return parentAdapter;
@@ -1292,7 +1893,7 @@ var LocalizationProvider = function LocalizationProvider2(inProps) {
1292
1893
  }
1293
1894
  return dateAdapter;
1294
1895
  }, [DateAdapter, adapterLocale, dateFormats, dateLibInstance, parentAdapter]);
1295
- const defaultDates = React6.useMemo(() => {
1896
+ const defaultDates = React10.useMemo(() => {
1296
1897
  if (!adapter) {
1297
1898
  return null;
1298
1899
  }
@@ -1301,7 +1902,7 @@ var LocalizationProvider = function LocalizationProvider2(inProps) {
1301
1902
  maxDate: adapter.date("2099-12-31T00:00:00.000")
1302
1903
  };
1303
1904
  }, [adapter]);
1304
- const contextValue = React6.useMemo(() => {
1905
+ const contextValue = React10.useMemo(() => {
1305
1906
  return {
1306
1907
  utils: adapter,
1307
1908
  adapter,
@@ -1506,396 +2107,759 @@ var defaultFormats = {
1506
2107
  var MISSING_UTC_PLUGIN = ["Missing UTC plugin", "To be able to use UTC or timezones, you have to enable the `utc` plugin", "Find more information on https://mui.com/x/react-date-pickers/timezone/#day-js-and-utc"].join("\n");
1507
2108
  var MISSING_TIMEZONE_PLUGIN = ["Missing timezone plugin", "To be able to use timezones, you have to enable both the `utc` and the `timezone` plugin", "Find more information on https://mui.com/x/react-date-pickers/timezone/#day-js-and-timezone"].join("\n");
1508
2109
  var AdapterDayjs = class {
2110
+ isMUIAdapter = true;
2111
+ isTimezoneCompatible = true;
2112
+ lib = "dayjs";
2113
+ escapedCharacters = {
2114
+ start: "[",
2115
+ end: "]"
2116
+ };
2117
+ formatTokenMap = /* @__PURE__ */ (() => formatTokenMap)();
1509
2118
  constructor({
1510
- locale: _locale,
2119
+ locale,
1511
2120
  formats
1512
2121
  } = {}) {
1513
- this.isMUIAdapter = true;
1514
- this.isTimezoneCompatible = true;
1515
- this.lib = "dayjs";
1516
- this.locale = void 0;
1517
- this.formats = void 0;
1518
- this.escapedCharacters = {
1519
- start: "[",
1520
- end: "]"
1521
- };
1522
- this.formatTokenMap = formatTokenMap;
1523
- this.setLocaleToValue = (value) => {
1524
- const expectedLocale = this.getCurrentLocaleCode();
1525
- if (expectedLocale === value.locale()) {
1526
- return value;
1527
- }
1528
- return value.locale(expectedLocale);
1529
- };
1530
- this.hasUTCPlugin = () => typeof dayjs.utc !== "undefined";
1531
- this.hasTimezonePlugin = () => typeof dayjs.tz !== "undefined";
1532
- this.isSame = (value, comparing, comparisonTemplate) => {
1533
- const comparingInValueTimezone = this.setTimezone(comparing, this.getTimezone(value));
1534
- return value.format(comparisonTemplate) === comparingInValueTimezone.format(comparisonTemplate);
1535
- };
1536
- this.cleanTimezone = (timezone) => {
1537
- switch (timezone) {
1538
- case "default": {
1539
- return void 0;
1540
- }
1541
- case "system": {
1542
- return dayjs.tz.guess();
1543
- }
1544
- default: {
1545
- return timezone;
1546
- }
1547
- }
1548
- };
1549
- this.createSystemDate = (value) => {
1550
- let date;
1551
- if (this.hasUTCPlugin() && this.hasTimezonePlugin()) {
1552
- const timezone = dayjs.tz.guess();
1553
- if (timezone === "UTC") {
1554
- date = dayjs(value);
1555
- } else {
1556
- date = dayjs.tz(value, timezone);
1557
- }
1558
- } else {
1559
- date = dayjs(value);
1560
- }
1561
- return this.setLocaleToValue(date);
1562
- };
1563
- this.createUTCDate = (value) => {
1564
- if (!this.hasUTCPlugin()) {
1565
- throw new Error(MISSING_UTC_PLUGIN);
1566
- }
1567
- return this.setLocaleToValue(dayjs.utc(value));
1568
- };
1569
- this.createTZDate = (value, timezone) => {
1570
- if (!this.hasUTCPlugin()) {
1571
- throw new Error(MISSING_UTC_PLUGIN);
1572
- }
1573
- if (!this.hasTimezonePlugin()) {
1574
- throw new Error(MISSING_TIMEZONE_PLUGIN);
1575
- }
1576
- const keepLocalTime = value !== void 0 && !value.endsWith("Z");
1577
- return this.setLocaleToValue(dayjs(value).tz(this.cleanTimezone(timezone), keepLocalTime));
1578
- };
1579
- this.getLocaleFormats = () => {
1580
- const locales = dayjs.Ls;
1581
- const locale = this.locale || "en";
1582
- let localeObject = locales[locale];
1583
- if (localeObject === void 0) {
1584
- if (process.env.NODE_ENV !== "production") {
1585
- warnOnce(["MUI X: Your locale has not been found.", "Either the locale key is not a supported one. Locales supported by dayjs are available here: https://github.com/iamkun/dayjs/tree/dev/src/locale.", "Or you forget to import the locale from 'dayjs/locale/{localeUsed}'", "fallback on English locale."]);
1586
- }
1587
- localeObject = locales.en;
1588
- }
1589
- return localeObject.formats;
1590
- };
1591
- this.adjustOffset = (value) => {
1592
- if (!this.hasTimezonePlugin()) {
1593
- return value;
1594
- }
1595
- const timezone = this.getTimezone(value);
1596
- if (timezone !== "UTC") {
1597
- const fixedValue = value.tz(this.cleanTimezone(timezone), true);
1598
- if (fixedValue.$offset === (value.$offset ?? 0)) {
1599
- return value;
1600
- }
1601
- value.$offset = fixedValue.$offset;
1602
- }
2122
+ this.locale = locale;
2123
+ this.formats = _extends({}, defaultFormats, formats);
2124
+ dayjs.extend(customParseFormatPlugin);
2125
+ }
2126
+ setLocaleToValue = (value) => {
2127
+ const expectedLocale = this.getCurrentLocaleCode();
2128
+ if (expectedLocale === value.locale()) {
1603
2129
  return value;
1604
- };
1605
- this.date = (value, timezone = "default") => {
1606
- if (value === null) {
1607
- return null;
1608
- }
1609
- if (timezone === "UTC") {
1610
- return this.createUTCDate(value);
1611
- }
1612
- if (timezone === "system" || timezone === "default" && !this.hasTimezonePlugin()) {
1613
- return this.createSystemDate(value);
1614
- }
1615
- return this.createTZDate(value, timezone);
1616
- };
1617
- this.getInvalidDate = () => dayjs(/* @__PURE__ */ new Date("Invalid date"));
1618
- this.getTimezone = (value) => {
1619
- if (this.hasTimezonePlugin()) {
1620
- const zone = value.$x?.$timezone;
1621
- if (zone) {
1622
- return zone;
1623
- }
2130
+ }
2131
+ return value.locale(expectedLocale);
2132
+ };
2133
+ hasUTCPlugin = () => typeof dayjs.utc !== "undefined";
2134
+ hasTimezonePlugin = () => typeof dayjs.tz !== "undefined";
2135
+ isSame = (value, comparing, comparisonTemplate) => {
2136
+ const comparingInValueTimezone = this.setTimezone(comparing, this.getTimezone(value));
2137
+ return value.format(comparisonTemplate) === comparingInValueTimezone.format(comparisonTemplate);
2138
+ };
2139
+ /**
2140
+ * Replaces "default" by undefined and "system" by the system timezone before passing it to `dayjs`.
2141
+ */
2142
+ cleanTimezone = (timezone) => {
2143
+ switch (timezone) {
2144
+ case "default": {
2145
+ return void 0;
1624
2146
  }
1625
- if (this.hasUTCPlugin() && value.isUTC()) {
1626
- return "UTC";
2147
+ case "system": {
2148
+ return dayjs.tz.guess();
1627
2149
  }
1628
- return "system";
1629
- };
1630
- this.setTimezone = (value, timezone) => {
1631
- if (this.getTimezone(value) === timezone) {
1632
- return value;
2150
+ default: {
2151
+ return timezone;
1633
2152
  }
2153
+ }
2154
+ };
2155
+ createSystemDate = (value) => {
2156
+ let date;
2157
+ if (this.hasUTCPlugin() && this.hasTimezonePlugin()) {
2158
+ const timezone = dayjs.tz.guess();
1634
2159
  if (timezone === "UTC") {
1635
- if (!this.hasUTCPlugin()) {
1636
- throw new Error(MISSING_UTC_PLUGIN);
1637
- }
1638
- return value.utc();
1639
- }
1640
- if (timezone === "system") {
1641
- return value.local();
1642
- }
1643
- if (!this.hasTimezonePlugin()) {
1644
- if (timezone === "default") {
1645
- return value;
1646
- }
1647
- throw new Error(MISSING_TIMEZONE_PLUGIN);
1648
- }
1649
- return this.setLocaleToValue(dayjs.tz(value, this.cleanTimezone(timezone)));
1650
- };
1651
- this.toJsDate = (value) => {
1652
- return value.toDate();
1653
- };
1654
- this.parse = (value, format) => {
1655
- if (value === "") {
1656
- return null;
1657
- }
1658
- return dayjs(value, format, this.locale, true);
1659
- };
1660
- this.getCurrentLocaleCode = () => {
1661
- return this.locale || "en";
1662
- };
1663
- this.is12HourCycleInCurrentLocale = () => {
1664
- return /A|a/.test(this.getLocaleFormats().LT || "");
1665
- };
1666
- this.expandFormat = (format) => {
1667
- const localeFormats = this.getLocaleFormats();
1668
- const t2 = (formatBis) => formatBis.replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g, (_, a, b) => a || b.slice(1));
1669
- return format.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g, (_, a, b) => {
1670
- const B = b && b.toUpperCase();
1671
- return a || localeFormats[b] || t2(localeFormats[B]);
1672
- });
1673
- };
1674
- this.isValid = (value) => {
1675
- if (value == null) {
1676
- return false;
1677
- }
1678
- return value.isValid();
1679
- };
1680
- this.format = (value, formatKey) => {
1681
- return this.formatByString(value, this.formats[formatKey]);
1682
- };
1683
- this.formatByString = (value, formatString) => {
1684
- return this.setLocaleToValue(value).format(formatString);
1685
- };
1686
- this.formatNumber = (numberToFormat) => {
1687
- return numberToFormat;
1688
- };
1689
- this.isEqual = (value, comparing) => {
1690
- if (value === null && comparing === null) {
1691
- return true;
2160
+ date = dayjs(value);
2161
+ } else {
2162
+ date = dayjs.tz(value, timezone);
1692
2163
  }
1693
- if (value === null || comparing === null) {
1694
- return false;
2164
+ } else {
2165
+ date = dayjs(value);
2166
+ }
2167
+ return this.setLocaleToValue(date);
2168
+ };
2169
+ createUTCDate = (value) => {
2170
+ if (!this.hasUTCPlugin()) {
2171
+ throw new Error(MISSING_UTC_PLUGIN);
2172
+ }
2173
+ return this.setLocaleToValue(dayjs.utc(value));
2174
+ };
2175
+ createTZDate = (value, timezone) => {
2176
+ if (!this.hasUTCPlugin()) {
2177
+ throw new Error(MISSING_UTC_PLUGIN);
2178
+ }
2179
+ if (!this.hasTimezonePlugin()) {
2180
+ throw new Error(MISSING_TIMEZONE_PLUGIN);
2181
+ }
2182
+ const keepLocalTime = value !== void 0 && !value.endsWith("Z");
2183
+ return this.setLocaleToValue(dayjs(value).tz(this.cleanTimezone(timezone), keepLocalTime));
2184
+ };
2185
+ getLocaleFormats = () => {
2186
+ const locales = dayjs.Ls;
2187
+ const locale = this.locale || "en";
2188
+ let localeObject = locales[locale];
2189
+ if (localeObject === void 0) {
2190
+ if (process.env.NODE_ENV !== "production") {
2191
+ warnOnce(["MUI X: Your locale has not been found.", "Either the locale key is not a supported one. Locales supported by dayjs are available here: https://github.com/iamkun/dayjs/tree/dev/src/locale.", "Or you forget to import the locale from 'dayjs/locale/{localeUsed}'", "fallback on English locale."]);
1695
2192
  }
1696
- return value.toDate().getTime() === comparing.toDate().getTime();
1697
- };
1698
- this.isSameYear = (value, comparing) => {
1699
- return this.isSame(value, comparing, "YYYY");
1700
- };
1701
- this.isSameMonth = (value, comparing) => {
1702
- return this.isSame(value, comparing, "YYYY-MM");
1703
- };
1704
- this.isSameDay = (value, comparing) => {
1705
- return this.isSame(value, comparing, "YYYY-MM-DD");
1706
- };
1707
- this.isSameHour = (value, comparing) => {
1708
- return value.isSame(comparing, "hour");
1709
- };
1710
- this.isAfter = (value, comparing) => {
1711
- return value > comparing;
1712
- };
1713
- this.isAfterYear = (value, comparing) => {
1714
- if (!this.hasUTCPlugin()) {
1715
- return value.isAfter(comparing, "year");
2193
+ localeObject = locales.en;
2194
+ }
2195
+ return localeObject.formats;
2196
+ };
2197
+ /**
2198
+ * If the new day does not have the same offset as the old one (when switching to summer day time for example),
2199
+ * Then dayjs will not automatically adjust the offset (moment does).
2200
+ * We have to parse again the value to make sure the `fixOffset` method is applied.
2201
+ * See https://github.com/iamkun/dayjs/blob/b3624de619d6e734cd0ffdbbd3502185041c1b60/src/plugin/timezone/index.js#L72
2202
+ */
2203
+ adjustOffset = (value) => {
2204
+ if (!this.hasTimezonePlugin()) {
2205
+ return value;
2206
+ }
2207
+ const timezone = this.getTimezone(value);
2208
+ if (timezone !== "UTC") {
2209
+ const fixedValue = value.tz(this.cleanTimezone(timezone), true);
2210
+ if (fixedValue.$offset === (value.$offset ?? 0)) {
2211
+ return value;
1716
2212
  }
1717
- return !this.isSameYear(value, comparing) && value.utc() > comparing.utc();
1718
- };
1719
- this.isAfterDay = (value, comparing) => {
1720
- if (!this.hasUTCPlugin()) {
1721
- return value.isAfter(comparing, "day");
2213
+ value.$offset = fixedValue.$offset;
2214
+ }
2215
+ return value;
2216
+ };
2217
+ date = (value, timezone = "default") => {
2218
+ if (value === null) {
2219
+ return null;
2220
+ }
2221
+ if (timezone === "UTC") {
2222
+ return this.createUTCDate(value);
2223
+ }
2224
+ if (timezone === "system" || timezone === "default" && !this.hasTimezonePlugin()) {
2225
+ return this.createSystemDate(value);
2226
+ }
2227
+ return this.createTZDate(value, timezone);
2228
+ };
2229
+ getInvalidDate = () => dayjs(/* @__PURE__ */ new Date("Invalid date"));
2230
+ getTimezone = (value) => {
2231
+ if (this.hasTimezonePlugin()) {
2232
+ const zone = value.$x?.$timezone;
2233
+ if (zone) {
2234
+ return zone;
1722
2235
  }
1723
- return !this.isSameDay(value, comparing) && value.utc() > comparing.utc();
1724
- };
1725
- this.isBefore = (value, comparing) => {
1726
- return value < comparing;
1727
- };
1728
- this.isBeforeYear = (value, comparing) => {
2236
+ }
2237
+ if (this.hasUTCPlugin() && value.isUTC()) {
2238
+ return "UTC";
2239
+ }
2240
+ return "system";
2241
+ };
2242
+ setTimezone = (value, timezone) => {
2243
+ if (this.getTimezone(value) === timezone) {
2244
+ return value;
2245
+ }
2246
+ if (timezone === "UTC") {
1729
2247
  if (!this.hasUTCPlugin()) {
1730
- return value.isBefore(comparing, "year");
2248
+ throw new Error(MISSING_UTC_PLUGIN);
1731
2249
  }
1732
- return !this.isSameYear(value, comparing) && value.utc() < comparing.utc();
1733
- };
1734
- this.isBeforeDay = (value, comparing) => {
1735
- if (!this.hasUTCPlugin()) {
1736
- return value.isBefore(comparing, "day");
2250
+ return value.utc();
2251
+ }
2252
+ if (timezone === "system") {
2253
+ return value.local();
2254
+ }
2255
+ if (!this.hasTimezonePlugin()) {
2256
+ if (timezone === "default") {
2257
+ return value;
1737
2258
  }
1738
- return !this.isSameDay(value, comparing) && value.utc() < comparing.utc();
1739
- };
1740
- this.isWithinRange = (value, [start, end]) => {
1741
- return value >= start && value <= end;
1742
- };
1743
- this.startOfYear = (value) => {
1744
- return this.adjustOffset(value.startOf("year"));
1745
- };
1746
- this.startOfMonth = (value) => {
1747
- return this.adjustOffset(value.startOf("month"));
1748
- };
1749
- this.startOfWeek = (value) => {
1750
- return this.adjustOffset(this.setLocaleToValue(value).startOf("week"));
1751
- };
1752
- this.startOfDay = (value) => {
1753
- return this.adjustOffset(value.startOf("day"));
1754
- };
1755
- this.endOfYear = (value) => {
1756
- return this.adjustOffset(value.endOf("year"));
1757
- };
1758
- this.endOfMonth = (value) => {
1759
- return this.adjustOffset(value.endOf("month"));
1760
- };
1761
- this.endOfWeek = (value) => {
1762
- return this.adjustOffset(this.setLocaleToValue(value).endOf("week"));
1763
- };
1764
- this.endOfDay = (value) => {
1765
- return this.adjustOffset(value.endOf("day"));
1766
- };
1767
- this.addYears = (value, amount) => {
1768
- return this.adjustOffset(value.add(amount, "year"));
1769
- };
1770
- this.addMonths = (value, amount) => {
1771
- return this.adjustOffset(value.add(amount, "month"));
1772
- };
1773
- this.addWeeks = (value, amount) => {
1774
- return this.adjustOffset(value.add(amount, "week"));
1775
- };
1776
- this.addDays = (value, amount) => {
1777
- return this.adjustOffset(value.add(amount, "day"));
1778
- };
1779
- this.addHours = (value, amount) => {
1780
- return this.adjustOffset(value.add(amount, "hour"));
1781
- };
1782
- this.addMinutes = (value, amount) => {
1783
- return this.adjustOffset(value.add(amount, "minute"));
1784
- };
1785
- this.addSeconds = (value, amount) => {
1786
- return this.adjustOffset(value.add(amount, "second"));
1787
- };
1788
- this.getYear = (value) => {
1789
- return value.year();
1790
- };
1791
- this.getMonth = (value) => {
1792
- return value.month();
1793
- };
1794
- this.getDate = (value) => {
1795
- return value.date();
1796
- };
1797
- this.getHours = (value) => {
1798
- return value.hour();
1799
- };
1800
- this.getMinutes = (value) => {
1801
- return value.minute();
1802
- };
1803
- this.getSeconds = (value) => {
1804
- return value.second();
1805
- };
1806
- this.getMilliseconds = (value) => {
1807
- return value.millisecond();
1808
- };
1809
- this.setYear = (value, year) => {
1810
- return this.adjustOffset(value.set("year", year));
1811
- };
1812
- this.setMonth = (value, month) => {
1813
- return this.adjustOffset(value.set("month", month));
1814
- };
1815
- this.setDate = (value, date) => {
1816
- return this.adjustOffset(value.set("date", date));
1817
- };
1818
- this.setHours = (value, hours) => {
1819
- return this.adjustOffset(value.set("hour", hours));
1820
- };
1821
- this.setMinutes = (value, minutes) => {
1822
- return this.adjustOffset(value.set("minute", minutes));
1823
- };
1824
- this.setSeconds = (value, seconds) => {
1825
- return this.adjustOffset(value.set("second", seconds));
1826
- };
1827
- this.setMilliseconds = (value, milliseconds) => {
1828
- return this.adjustOffset(value.set("millisecond", milliseconds));
1829
- };
1830
- this.getDaysInMonth = (value) => {
1831
- return value.daysInMonth();
1832
- };
1833
- this.getWeekArray = (value) => {
1834
- const start = this.startOfWeek(this.startOfMonth(value));
1835
- const end = this.endOfWeek(this.endOfMonth(value));
1836
- let count = 0;
1837
- let current = start;
1838
- const nestedWeeks = [];
1839
- while (current < end) {
1840
- const weekNumber = Math.floor(count / 7);
1841
- nestedWeeks[weekNumber] = nestedWeeks[weekNumber] || [];
1842
- nestedWeeks[weekNumber].push(current);
1843
- current = this.addDays(current, 1);
1844
- count += 1;
1845
- }
1846
- return nestedWeeks;
1847
- };
1848
- this.getWeekNumber = (value) => {
1849
- return value.week();
1850
- };
1851
- this.getYearRange = ([start, end]) => {
1852
- const startDate = this.startOfYear(start);
1853
- const endDate = this.endOfYear(end);
1854
- const years = [];
1855
- let current = startDate;
1856
- while (this.isBefore(current, endDate)) {
1857
- years.push(current);
1858
- current = this.addYears(current, 1);
1859
- }
1860
- return years;
1861
- };
1862
- this.locale = _locale;
1863
- this.formats = _extends({}, defaultFormats, formats);
1864
- dayjs.extend(customParseFormatPlugin);
1865
- }
2259
+ throw new Error(MISSING_TIMEZONE_PLUGIN);
2260
+ }
2261
+ return this.setLocaleToValue(dayjs.tz(value, this.cleanTimezone(timezone)));
2262
+ };
2263
+ toJsDate = (value) => {
2264
+ return value.toDate();
2265
+ };
2266
+ parse = (value, format) => {
2267
+ if (value === "") {
2268
+ return null;
2269
+ }
2270
+ return dayjs(value, format, this.locale, true);
2271
+ };
2272
+ getCurrentLocaleCode = () => {
2273
+ return this.locale || "en";
2274
+ };
2275
+ is12HourCycleInCurrentLocale = () => {
2276
+ return /A|a/.test(this.getLocaleFormats().LT || "");
2277
+ };
2278
+ expandFormat = (format) => {
2279
+ const localeFormats = this.getLocaleFormats();
2280
+ const t2 = (formatBis) => formatBis.replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g, (_, a, b) => a || b.slice(1));
2281
+ return format.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g, (_, a, b) => {
2282
+ const B = b && b.toUpperCase();
2283
+ return a || localeFormats[b] || t2(localeFormats[B]);
2284
+ });
2285
+ };
2286
+ isValid = (value) => {
2287
+ if (value == null) {
2288
+ return false;
2289
+ }
2290
+ return value.isValid();
2291
+ };
2292
+ format = (value, formatKey) => {
2293
+ return this.formatByString(value, this.formats[formatKey]);
2294
+ };
2295
+ formatByString = (value, formatString) => {
2296
+ return this.setLocaleToValue(value).format(formatString);
2297
+ };
2298
+ formatNumber = (numberToFormat) => {
2299
+ return numberToFormat;
2300
+ };
2301
+ isEqual = (value, comparing) => {
2302
+ if (value === null && comparing === null) {
2303
+ return true;
2304
+ }
2305
+ if (value === null || comparing === null) {
2306
+ return false;
2307
+ }
2308
+ return value.toDate().getTime() === comparing.toDate().getTime();
2309
+ };
2310
+ isSameYear = (value, comparing) => {
2311
+ return this.isSame(value, comparing, "YYYY");
2312
+ };
2313
+ isSameMonth = (value, comparing) => {
2314
+ return this.isSame(value, comparing, "YYYY-MM");
2315
+ };
2316
+ isSameDay = (value, comparing) => {
2317
+ return this.isSame(value, comparing, "YYYY-MM-DD");
2318
+ };
2319
+ isSameHour = (value, comparing) => {
2320
+ return value.isSame(comparing, "hour");
2321
+ };
2322
+ isAfter = (value, comparing) => {
2323
+ return value > comparing;
2324
+ };
2325
+ isAfterYear = (value, comparing) => {
2326
+ if (!this.hasUTCPlugin()) {
2327
+ return value.isAfter(comparing, "year");
2328
+ }
2329
+ return !this.isSameYear(value, comparing) && value.utc() > comparing.utc();
2330
+ };
2331
+ isAfterDay = (value, comparing) => {
2332
+ if (!this.hasUTCPlugin()) {
2333
+ return value.isAfter(comparing, "day");
2334
+ }
2335
+ return !this.isSameDay(value, comparing) && value.utc() > comparing.utc();
2336
+ };
2337
+ isBefore = (value, comparing) => {
2338
+ return value < comparing;
2339
+ };
2340
+ isBeforeYear = (value, comparing) => {
2341
+ if (!this.hasUTCPlugin()) {
2342
+ return value.isBefore(comparing, "year");
2343
+ }
2344
+ return !this.isSameYear(value, comparing) && value.utc() < comparing.utc();
2345
+ };
2346
+ isBeforeDay = (value, comparing) => {
2347
+ if (!this.hasUTCPlugin()) {
2348
+ return value.isBefore(comparing, "day");
2349
+ }
2350
+ return !this.isSameDay(value, comparing) && value.utc() < comparing.utc();
2351
+ };
2352
+ isWithinRange = (value, [start, end]) => {
2353
+ return value >= start && value <= end;
2354
+ };
2355
+ startOfYear = (value) => {
2356
+ return this.adjustOffset(value.startOf("year"));
2357
+ };
2358
+ startOfMonth = (value) => {
2359
+ return this.adjustOffset(value.startOf("month"));
2360
+ };
2361
+ startOfWeek = (value) => {
2362
+ return this.adjustOffset(this.setLocaleToValue(value).startOf("week"));
2363
+ };
2364
+ startOfDay = (value) => {
2365
+ return this.adjustOffset(value.startOf("day"));
2366
+ };
2367
+ endOfYear = (value) => {
2368
+ return this.adjustOffset(value.endOf("year"));
2369
+ };
2370
+ endOfMonth = (value) => {
2371
+ return this.adjustOffset(value.endOf("month"));
2372
+ };
2373
+ endOfWeek = (value) => {
2374
+ return this.adjustOffset(this.setLocaleToValue(value).endOf("week"));
2375
+ };
2376
+ endOfDay = (value) => {
2377
+ return this.adjustOffset(value.endOf("day"));
2378
+ };
2379
+ addYears = (value, amount) => {
2380
+ return this.adjustOffset(value.add(amount, "year"));
2381
+ };
2382
+ addMonths = (value, amount) => {
2383
+ return this.adjustOffset(value.add(amount, "month"));
2384
+ };
2385
+ addWeeks = (value, amount) => {
2386
+ return this.adjustOffset(value.add(amount, "week"));
2387
+ };
2388
+ addDays = (value, amount) => {
2389
+ return this.adjustOffset(value.add(amount, "day"));
2390
+ };
2391
+ addHours = (value, amount) => {
2392
+ return this.adjustOffset(value.add(amount, "hour"));
2393
+ };
2394
+ addMinutes = (value, amount) => {
2395
+ return this.adjustOffset(value.add(amount, "minute"));
2396
+ };
2397
+ addSeconds = (value, amount) => {
2398
+ return this.adjustOffset(value.add(amount, "second"));
2399
+ };
2400
+ getYear = (value) => {
2401
+ return value.year();
2402
+ };
2403
+ getMonth = (value) => {
2404
+ return value.month();
2405
+ };
2406
+ getDate = (value) => {
2407
+ return value.date();
2408
+ };
2409
+ getHours = (value) => {
2410
+ return value.hour();
2411
+ };
2412
+ getMinutes = (value) => {
2413
+ return value.minute();
2414
+ };
2415
+ getSeconds = (value) => {
2416
+ return value.second();
2417
+ };
2418
+ getMilliseconds = (value) => {
2419
+ return value.millisecond();
2420
+ };
2421
+ setYear = (value, year) => {
2422
+ return this.adjustOffset(value.set("year", year));
2423
+ };
2424
+ setMonth = (value, month) => {
2425
+ return this.adjustOffset(value.set("month", month));
2426
+ };
2427
+ setDate = (value, date) => {
2428
+ return this.adjustOffset(value.set("date", date));
2429
+ };
2430
+ setHours = (value, hours) => {
2431
+ return this.adjustOffset(value.set("hour", hours));
2432
+ };
2433
+ setMinutes = (value, minutes) => {
2434
+ return this.adjustOffset(value.set("minute", minutes));
2435
+ };
2436
+ setSeconds = (value, seconds) => {
2437
+ return this.adjustOffset(value.set("second", seconds));
2438
+ };
2439
+ setMilliseconds = (value, milliseconds) => {
2440
+ return this.adjustOffset(value.set("millisecond", milliseconds));
2441
+ };
2442
+ getDaysInMonth = (value) => {
2443
+ return value.daysInMonth();
2444
+ };
2445
+ getWeekArray = (value) => {
2446
+ const start = this.startOfWeek(this.startOfMonth(value));
2447
+ const end = this.endOfWeek(this.endOfMonth(value));
2448
+ let count = 0;
2449
+ let current = start;
2450
+ const nestedWeeks = [];
2451
+ while (current < end) {
2452
+ const weekNumber = Math.floor(count / 7);
2453
+ nestedWeeks[weekNumber] = nestedWeeks[weekNumber] || [];
2454
+ nestedWeeks[weekNumber].push(current);
2455
+ current = this.addDays(current, 1);
2456
+ count += 1;
2457
+ }
2458
+ return nestedWeeks;
2459
+ };
2460
+ getWeekNumber = (value) => {
2461
+ return value.week();
2462
+ };
1866
2463
  getDayOfWeek(value) {
1867
2464
  return value.day() + 1;
1868
2465
  }
2466
+ getYearRange = ([start, end]) => {
2467
+ const startDate = this.startOfYear(start);
2468
+ const endDate = this.endOfYear(end);
2469
+ const years = [];
2470
+ let current = startDate;
2471
+ while (this.isBefore(current, endDate)) {
2472
+ years.push(current);
2473
+ current = this.addYears(current, 1);
2474
+ }
2475
+ return years;
2476
+ };
1869
2477
  };
1870
2478
 
1871
2479
  // src/providers/LayoutProvider.tsx
1872
- import { useIsFetching, useIsMutating } from "@tanstack/react-query";
1873
- import { useRouterState } from "@tanstack/react-router";
1874
- import { DashboardLayout } from "@toolpad/core/DashboardLayout";
1875
- import { TanStackRouterAppProvider } from "@toolpad/core/tanstack-router";
1876
- import { NotificationsProvider } from "@toolpad/core/useNotifications";
1877
- import { useEffect, useState as useState2 } from "react";
1878
- import { I18nextProvider, useTranslation as useTranslation5 } from "react-i18next";
2480
+ import { useEffect as useEffect6, useState as useState10 } from "react";
2481
+ import { I18nextProvider, useTranslation as useTranslation7 } from "react-i18next";
1879
2482
  import * as z from "zod";
1880
2483
  import { cs, en } from "zod/locales";
1881
2484
 
1882
- // src/components/core/AppTitle.tsx
1883
- import { Chip as Chip2, Stack as Stack3, Typography as Typography5 } from "@mui/material";
2485
+ // src/components/core/Layout.tsx
2486
+ import Menu3 from "@mui/icons-material/Menu";
2487
+ import MenuOpen from "@mui/icons-material/MenuOpen";
2488
+ import { AppBar, Box as Box9, CssBaseline, IconButton as IconButton5, InitColorSchemeScript, LinearProgress, Toolbar } from "@mui/material";
2489
+ import { ThemeProvider, styled as styled2 } from "@mui/material/styles";
2490
+ import { useIsFetching, useIsMutating } from "@tanstack/react-query";
2491
+ import useLocalStorageState from "use-local-storage-state";
1884
2492
 
1885
- // src/contexts/LayoutContext.ts
1886
- import { createContext as createContext2, useContext as useContext2 } from "react";
1887
- var LayoutContext = createContext2({});
1888
- var useLayout = () => useContext2(LayoutContext);
2493
+ // src/hooks/ThemeHook.ts
2494
+ import { createTheme, darken, lighten } from "@mui/material";
2495
+ import { grey as grey2 } from "@mui/material/colors";
2496
+ import { csCZ, enUS } from "@mui/material/locale";
2497
+ import { csCZ as dataGridCsCz, enUS as dataGridEnUs } from "@mui/x-data-grid-premium/locales";
2498
+ import { csCZ as datePickersCsCz, enUS as datePickersEnUs } from "@mui/x-date-pickers-pro/locales";
2499
+ import { useTranslation as useTranslation5 } from "react-i18next";
2500
+ var WISTRON_PRIMARY_COLOR = "#00506E";
2501
+ var WISTRON_SECONDARY_COLOR = "#64DC00";
2502
+ var useGetTheme = (theme) => {
2503
+ const { i18n: i18n2 } = useTranslation5();
2504
+ return createTheme(
2505
+ {
2506
+ cssVariables: {
2507
+ colorSchemeSelector: "data-mui-color-scheme"
2508
+ },
2509
+ colorSchemes: {
2510
+ light: {
2511
+ palette: {
2512
+ primary: { main: WISTRON_PRIMARY_COLOR },
2513
+ secondary: { main: WISTRON_SECONDARY_COLOR }
2514
+ }
2515
+ },
2516
+ dark: {
2517
+ palette: {
2518
+ primary: { main: lighten(WISTRON_PRIMARY_COLOR, 0.5) },
2519
+ secondary: { main: darken(WISTRON_SECONDARY_COLOR, 0.5) }
2520
+ }
2521
+ },
2522
+ ...theme?.colorSchemes
2523
+ },
2524
+ components: {
2525
+ MuiCssBaseline: {
2526
+ styleOverrides: (theme2) => {
2527
+ return {
2528
+ body: {
2529
+ "&::-webkit-scrollbar, & *::-webkit-scrollbar": {
2530
+ width: "0.7em",
2531
+ height: "0.7em"
2532
+ },
2533
+ "&::-webkit-scrollbar-track, & *::-webkit-scrollbar-track": {
2534
+ backgroundColor: theme2.palette.mode === "dark" ? grey2[900] : grey2[200],
2535
+ borderRadius: "5px"
2536
+ },
2537
+ "&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
2538
+ backgroundColor: theme2.palette.mode === "dark" ? grey2[800] : grey2[400],
2539
+ borderRadius: "10px"
2540
+ },
2541
+ "&::-webkit-scrollbar-thumb:hover, & *::-webkit-scrollbar-thumb:hover": {
2542
+ backgroundColor: theme2.palette.mode === "dark" ? grey2[700] : grey2[500]
2543
+ },
2544
+ "&::-webkit-scrollbar-corner, & *::-webkit-scrollbar-corner": {
2545
+ backgroundColor: "transparent"
2546
+ }
2547
+ }
2548
+ };
2549
+ }
2550
+ },
2551
+ MuiTableContainer: {
2552
+ styleOverrides: {
2553
+ root: ({ theme: theme2 }) => ({
2554
+ "& .MuiDataGrid-cell--editing": {
2555
+ "& .MuiInputBase-root": {
2556
+ height: "100%"
2557
+ }
2558
+ },
2559
+ "& .MuiDataGrid-columnHeaderTitle": {
2560
+ fontWeight: 600
2561
+ },
2562
+ "& .Mui-error": {
2563
+ backgroundColor: theme2.palette.error.main,
2564
+ color: theme2.palette.error.contrastText
2565
+ },
2566
+ "& .MuiDataGrid-booleanCell[data-value='true']": {
2567
+ color: `${theme2.palette.success.main} !important`
2568
+ },
2569
+ "& .MuiDataGrid-booleanCell[data-value='false']": {
2570
+ color: `${theme2.palette.error.main} !important`
2571
+ }
2572
+ })
2573
+ }
2574
+ },
2575
+ ...theme?.components
2576
+ }
2577
+ },
2578
+ i18n2.resolvedLanguage === "cs" ? datePickersCsCz : datePickersEnUs,
2579
+ i18n2.resolvedLanguage === "cs" ? dataGridCsCz : dataGridEnUs,
2580
+ i18n2.resolvedLanguage === "cs" ? csCZ : enUS
2581
+ );
2582
+ };
1889
2583
 
1890
- // src/components/core/AppTitle.tsx
1891
- import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
1892
- var AppTitle = () => {
1893
- const { appTitle } = useLayout();
1894
- return /* @__PURE__ */ jsxs5(Stack3, { direction: "row", alignItems: "center", spacing: 2, children: [
1895
- /* @__PURE__ */ jsx13("img", { src: "/favicon-32x32.png", alt: "app-logo", loading: "lazy" }),
1896
- /* @__PURE__ */ jsx13(Typography5, { variant: "h6", children: appTitle }),
1897
- import.meta.env.DEV && /* @__PURE__ */ jsx13(Chip2, { size: "small", label: "BETA", color: "info" })
1898
- ] });
2584
+ // src/components/core/navigation/NavigationRail.tsx
2585
+ import { useMediaQuery } from "@mui/material";
2586
+ import Box7 from "@mui/material/Box";
2587
+ import Drawer from "@mui/material/Drawer";
2588
+ import { useTheme as useTheme2 } from "@mui/material/styles";
2589
+ import { useNavigate, useRouterState as useRouterState2 } from "@tanstack/react-router";
2590
+
2591
+ // src/components/core/navigation/NavigationList.tsx
2592
+ import Divider3 from "@mui/material/Divider";
2593
+ import List3 from "@mui/material/List";
2594
+ import ListSubheader from "@mui/material/ListSubheader";
2595
+ import { Fragment as Fragment4, useEffect as useEffect5, useState as useState7 } from "react";
2596
+
2597
+ // src/components/core/navigation/NavigationListItem.tsx
2598
+ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
2599
+ import Avatar from "@mui/material/Avatar";
2600
+ import Box6 from "@mui/material/Box";
2601
+ import Collapse from "@mui/material/Collapse";
2602
+ import Grow from "@mui/material/Grow";
2603
+ import ListItem from "@mui/material/ListItem";
2604
+ import ListItemButton3 from "@mui/material/ListItemButton";
2605
+ import ListItemIcon3 from "@mui/material/ListItemIcon";
2606
+ import ListItemText3 from "@mui/material/ListItemText";
2607
+ import Paper2 from "@mui/material/Paper";
2608
+ import { styled } from "@mui/material/styles";
2609
+ import Typography7 from "@mui/material/Typography";
2610
+ import { Fragment as Fragment3, useMemo as useMemo3, useState as useState6 } from "react";
2611
+ import { jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
2612
+ var ICON_SIZE = 34;
2613
+ var StyledNavButton = styled(ListItemButton3)(({ theme }) => ({
2614
+ borderRadius: 8,
2615
+ "&.Mui-selected": {
2616
+ "& .MuiListItemIcon-root, & .MuiTypography-root, & .MuiSvgIcon-root": {
2617
+ color: (theme.vars ?? theme).palette.primary.dark
2618
+ },
2619
+ "& .MuiAvatar-root": {
2620
+ backgroundColor: (theme.vars ?? theme).palette.primary.dark
2621
+ },
2622
+ "& .MuiTouchRipple-child": {
2623
+ backgroundColor: (theme.vars ?? theme).palette.primary.dark
2624
+ }
2625
+ },
2626
+ "& .MuiSvgIcon-root": {
2627
+ color: (theme.vars ?? theme).palette.action.active
2628
+ },
2629
+ "& .MuiAvatar-root": {
2630
+ backgroundColor: (theme.vars ?? theme).palette.action.active
2631
+ }
2632
+ }));
2633
+ var IconOrAvatar = ({ item, collapsed }) => {
2634
+ if (item.icon || collapsed) {
2635
+ return /* @__PURE__ */ jsxs12(Box6, { sx: collapsed ? { position: "absolute", left: "50%", top: "calc(50% - 6px)", transform: "translate(-50%, -50%)" } : {}, children: [
2636
+ /* @__PURE__ */ jsxs12(ListItemIcon3, { sx: { display: "flex", alignItems: "center", justifyContent: "center", minWidth: ICON_SIZE }, children: [
2637
+ item.icon ?? null,
2638
+ !item.icon && collapsed ? /* @__PURE__ */ jsx21(Avatar, { sx: { width: ICON_SIZE - 7, height: ICON_SIZE - 7, fontSize: 12 }, children: item.title }) : null
2639
+ ] }),
2640
+ collapsed ? /* @__PURE__ */ jsx21(
2641
+ Typography7,
2642
+ {
2643
+ variant: "caption",
2644
+ sx: {
2645
+ position: "absolute",
2646
+ bottom: -18,
2647
+ left: "50%",
2648
+ transform: "translateX(-50%)",
2649
+ fontSize: 10,
2650
+ fontWeight: 500,
2651
+ textAlign: "center",
2652
+ whiteSpace: "nowrap",
2653
+ overflow: "hidden",
2654
+ textOverflow: "ellipsis",
2655
+ maxWidth: MINI_WIDTH - 28
2656
+ },
2657
+ children: item.title
2658
+ }
2659
+ ) : null
2660
+ ] });
2661
+ }
2662
+ return null;
2663
+ };
2664
+ var MiniPopover = ({ open, leftOffset = MINI_WIDTH - 2, children }) => /* @__PURE__ */ jsx21(Grow, { in: open, children: /* @__PURE__ */ jsx21(Box6, { sx: { position: "fixed", left: leftOffset, pl: "6px" }, children: /* @__PURE__ */ jsx21(Paper2, { sx: { pt: 0.5, pb: 0.5, transform: "translateY(calc(50% - 30px))" }, children }) }) });
2665
+ var NavigationListItem = ({ item, isOpen, selected, disabled, collapsed, isSidebarFullyExpanded = true, isSidebarFullyCollapsed, onClick, renderNested }) => {
2666
+ const [hoveredPopoverItem, setHoveredPopoverItem] = useState6(null);
2667
+ const chevronSx = useMemo3(() => {
2668
+ if (collapsed && isSidebarFullyCollapsed && item.children) {
2669
+ return {
2670
+ fontSize: 18,
2671
+ position: "absolute",
2672
+ top: "41.5%",
2673
+ right: "2px",
2674
+ transform: "translateY(-50%) rotate(-90deg)"
2675
+ };
2676
+ }
2677
+ if (!collapsed && isSidebarFullyExpanded && item.children) {
2678
+ return {
2679
+ ml: 0.5,
2680
+ transform: `rotate(${isOpen ? 0 : -90}deg)`,
2681
+ transition: (theme) => theme.transitions.create("transform", {
2682
+ easing: theme.transitions.easing.sharp,
2683
+ duration: 100
2684
+ })
2685
+ };
2686
+ }
2687
+ return { display: "none" };
2688
+ }, [collapsed, isSidebarFullyExpanded, isSidebarFullyCollapsed, isOpen, item.children]);
2689
+ const listItem = /* @__PURE__ */ jsxs12(
2690
+ ListItem,
2691
+ {
2692
+ ...item.children && collapsed ? {
2693
+ onMouseEnter: () => {
2694
+ setHoveredPopoverItem(item.title);
2695
+ },
2696
+ onMouseLeave: () => {
2697
+ setHoveredPopoverItem(null);
2698
+ }
2699
+ } : {},
2700
+ sx: { py: 0, px: 1, overflowX: "hidden" },
2701
+ children: [
2702
+ /* @__PURE__ */ jsxs12(StyledNavButton, { selected, disabled, sx: { px: 1.4, height: collapsed ? 60 : 48 }, onClick: () => onClick(item), children: [
2703
+ /* @__PURE__ */ jsx21(IconOrAvatar, { item, collapsed }),
2704
+ !collapsed && /* @__PURE__ */ jsx21(
2705
+ ListItemText3,
2706
+ {
2707
+ primary: item.title,
2708
+ slotProps: { primary: { noWrap: true, title: item.title } },
2709
+ sx: { ml: 1.2, flex: 1, minWidth: 0, "& .MuiTypography-root": { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" } }
2710
+ }
2711
+ ),
2712
+ item.children ? /* @__PURE__ */ jsx21(ExpandMoreIcon, { sx: chevronSx }) : null
2713
+ ] }),
2714
+ item.children && collapsed ? /* @__PURE__ */ jsx21(MiniPopover, { open: item.title === hoveredPopoverItem, children: renderNested?.(item.children) }) : null
2715
+ ]
2716
+ }
2717
+ );
2718
+ return /* @__PURE__ */ jsxs12(Fragment3, { children: [
2719
+ listItem,
2720
+ item.children && !collapsed ? /* @__PURE__ */ jsx21(Collapse, { in: isOpen, timeout: "auto", unmountOnExit: true, children: renderNested?.(item.children) }) : null
2721
+ ] }, item.to);
2722
+ };
2723
+
2724
+ // src/components/core/navigation/NavigationList.tsx
2725
+ import { jsx as jsx22 } from "react/jsx-runtime";
2726
+ var isPageItem = (item) => !("kind" in item);
2727
+ var isDivider = (item) => "kind" in item && item.kind === "divider";
2728
+ var isHeader = (item) => "kind" in item && item.kind === "header";
2729
+ var NavigationList = ({ subNavigation, depth = 0, collapsed, isPopover, isSidebarFullyExpanded = true, isSidebarFullyCollapsed, expandedWidth, renderItem, activePath, onNavigate }) => {
2730
+ const [openKeys, setOpenKeys] = useState7([]);
2731
+ useEffect5(() => {
2732
+ if (collapsed) setOpenKeys([]);
2733
+ }, [collapsed]);
2734
+ const toggleKey = (key) => setOpenKeys((previous) => previous.includes(key) ? previous.filter((k) => k !== key) : [...previous, key]);
2735
+ const renderNested = (children) => /* @__PURE__ */ jsx22(
2736
+ NavigationList,
2737
+ {
2738
+ subNavigation: children,
2739
+ depth: depth + 1,
2740
+ isPopover: collapsed,
2741
+ expandedWidth,
2742
+ activePath,
2743
+ onNavigate
2744
+ }
2745
+ );
2746
+ return /* @__PURE__ */ jsx22(
2747
+ List3,
2748
+ {
2749
+ sx: {
2750
+ padding: 0,
2751
+ mt: isPopover && depth === 1 ? 0.5 : 0,
2752
+ mb: depth === 0 && !isPopover ? 4 : 0.5,
2753
+ pl: (isPopover ? 1 : 2) * (isPopover ? depth - 1 : depth),
2754
+ minWidth: isPopover && depth === 1 ? EXPANDED_WIDTH : "auto",
2755
+ width: collapsed ? MINI_WIDTH : "auto"
2756
+ },
2757
+ children: subNavigation.map((navItem, index) => {
2758
+ if (isHeader(navItem)) {
2759
+ return /* @__PURE__ */ jsx22(
2760
+ ListSubheader,
2761
+ {
2762
+ sx: {
2763
+ fontSize: 12,
2764
+ fontWeight: "700",
2765
+ height: collapsed ? 0 : 40,
2766
+ px: 2,
2767
+ minWidth: expandedWidth,
2768
+ overflow: "hidden",
2769
+ textOverflow: "ellipsis",
2770
+ whiteSpace: "nowrap",
2771
+ zIndex: 2,
2772
+ bgcolor: "transparent",
2773
+ position: "static"
2774
+ },
2775
+ children: navItem.title
2776
+ },
2777
+ `subheader-${depth}-${index}`
2778
+ );
2779
+ }
2780
+ if (isDivider(navItem)) {
2781
+ const nextItem = subNavigation[index + 1];
2782
+ return /* @__PURE__ */ jsx22("li", { children: /* @__PURE__ */ jsx22(Divider3, { sx: { mx: 1, mt: 1, mb: nextItem && isHeader(nextItem) && !collapsed ? 0 : 1 } }) }, `divider-${depth}-${index}`);
2783
+ }
2784
+ if (!isPageItem(navItem)) return null;
2785
+ const key = `item-${depth}-${index}`;
2786
+ const uniqueItemKey = `${depth}-${index}-${navItem.title}`;
2787
+ if (renderItem) return /* @__PURE__ */ jsx22(Fragment4, { children: renderItem(navItem, { collapsed: !!collapsed }) }, key);
2788
+ return /* @__PURE__ */ jsx22(
2789
+ NavigationListItem,
2790
+ {
2791
+ item: navItem,
2792
+ isOpen: openKeys.includes(uniqueItemKey),
2793
+ selected: activePath === navItem.to,
2794
+ collapsed,
2795
+ isSidebarFullyExpanded,
2796
+ isSidebarFullyCollapsed,
2797
+ onClick: (item) => item.children && !collapsed ? toggleKey(uniqueItemKey) : onNavigate(item),
2798
+ renderNested
2799
+ },
2800
+ key
2801
+ );
2802
+ })
2803
+ }
2804
+ );
2805
+ };
2806
+
2807
+ // src/components/core/navigation/NavigationRail.tsx
2808
+ import { jsx as jsx23 } from "react/jsx-runtime";
2809
+ var MINI_WIDTH = 84;
2810
+ var EXPANDED_WIDTH = 320;
2811
+ var TOOLBAR_HEIGHT = 65;
2812
+ var NavigationRail = ({ navigation, expanded, setExpanded }) => {
2813
+ const navigate = useNavigate();
2814
+ const routerState = useRouterState2();
2815
+ const theme = useTheme2();
2816
+ const showPermanent = useMediaQuery(theme.breakpoints.up("sm"));
2817
+ const drawerContent = (collapsed) => /* @__PURE__ */ jsx23(
2818
+ Box7,
2819
+ {
2820
+ component: "nav",
2821
+ sx: {
2822
+ height: "100%",
2823
+ display: "flex",
2824
+ flexDirection: "column",
2825
+ justifyContent: "space-between",
2826
+ overflow: "auto",
2827
+ scrollbarGutter: collapsed ? "stable" : "auto",
2828
+ overflowX: "hidden",
2829
+ pt: navigation[0] && isHeader(navigation[0]) && !collapsed ? 0 : 2
2830
+ },
2831
+ children: /* @__PURE__ */ jsx23(
2832
+ NavigationList,
2833
+ {
2834
+ subNavigation: navigation,
2835
+ collapsed,
2836
+ isSidebarFullyExpanded: expanded,
2837
+ isSidebarFullyCollapsed: !expanded,
2838
+ expandedWidth: EXPANDED_WIDTH,
2839
+ activePath: routerState.location.pathname,
2840
+ onNavigate: navigate
2841
+ }
2842
+ )
2843
+ }
2844
+ );
2845
+ if (showPermanent)
2846
+ return /* @__PURE__ */ jsx23(
2847
+ Drawer,
2848
+ {
2849
+ variant: "permanent",
2850
+ sx: {
2851
+ width: expanded ? EXPANDED_WIDTH : MINI_WIDTH,
2852
+ ["& .MuiDrawer-paper"]: {
2853
+ position: "absolute",
2854
+ top: `${TOOLBAR_HEIGHT}px`,
2855
+ height: `calc(100% - ${TOOLBAR_HEIGHT}px)`,
2856
+ width: expanded ? EXPANDED_WIDTH : MINI_WIDTH
2857
+ }
2858
+ },
2859
+ children: drawerContent(!expanded)
2860
+ }
2861
+ );
2862
+ return /* @__PURE__ */ jsx23(Drawer, { open: expanded, onClose: () => setExpanded(false), children: drawerContent(!expanded) });
1899
2863
  };
1900
2864
 
1901
2865
  // src/components/core/ToolbarAccount.tsx
@@ -1909,9 +2873,9 @@ import Login from "@mui/icons-material/Login";
1909
2873
  import Logout from "@mui/icons-material/Logout";
1910
2874
  import SettingsBrightness from "@mui/icons-material/SettingsBrightness";
1911
2875
  import Translate from "@mui/icons-material/Translate";
1912
- import { Avatar, Box as Box3, IconButton as IconButton2, List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListSubheader, Menu, Typography as Typography6, useColorScheme } from "@mui/material";
1913
- import { Fragment, useState } from "react";
1914
- import { useTranslation as useTranslation3 } from "react-i18next";
2876
+ import { Avatar as Avatar2, Box as Box8, IconButton as IconButton4, List as List4, ListItem as ListItem2, ListItemButton as ListItemButton4, ListItemIcon as ListItemIcon4, ListItemText as ListItemText4, ListSubheader as ListSubheader2, Menu as Menu2, Typography as Typography8, useColorScheme } from "@mui/material";
2877
+ import { Fragment as Fragment5, useState as useState8 } from "react";
2878
+ import { useTranslation as useTranslation6 } from "react-i18next";
1915
2879
 
1916
2880
  // src/auth-test/keycloak.ts
1917
2881
  import { useRouter } from "@tanstack/react-router";
@@ -1931,12 +2895,12 @@ function useKeycloak() {
1931
2895
  }
1932
2896
 
1933
2897
  // src/components/core/ToolbarAccount.tsx
1934
- import { jsx as jsx14, jsxs as jsxs6 } from "react/jsx-runtime";
2898
+ import { jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
1935
2899
  var ToolbarAccount = () => {
1936
- const [anchorElement, setAnchorElement] = useState();
1937
- const [tab, setTab] = useState("settings");
2900
+ const [anchorElement, setAnchorElement] = useState8();
2901
+ const [tab, setTab] = useState8("settings");
1938
2902
  const open = Boolean(anchorElement);
1939
- const { t: t2, i18n: i18n2 } = useTranslation3();
2903
+ const { t: t2, i18n: i18n2 } = useTranslation6();
1940
2904
  const { mode, setMode } = useColorScheme();
1941
2905
  const changeLanguage = (newLanguage) => () => {
1942
2906
  i18n2.changeLanguage(newLanguage).finally(() => closeMenu());
@@ -1971,160 +2935,124 @@ var ToolbarAccount = () => {
1971
2935
  setTimeout(() => setTab("settings"), 300);
1972
2936
  };
1973
2937
  const changeTab = (newTab) => () => setTab(newTab);
1974
- const settings = /* @__PURE__ */ jsxs6(List, { component: "nav", subheader: /* @__PURE__ */ jsx14(ListSubheader, { sx: { backgroundColor: "transparent" }, children: t2("Layout.Settings") }), children: [
1975
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeTab("theme"), sx: { py: 0.3 }, children: [
1976
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(Brightness4, {}) }),
1977
- /* @__PURE__ */ jsx14(ListItemText, { primary: t2("Layout.Appearance"), secondary: getModeText() }),
1978
- /* @__PURE__ */ jsx14(ChevronRight, {})
2938
+ const settings = /* @__PURE__ */ jsxs13(List4, { component: "nav", subheader: /* @__PURE__ */ jsx24(ListSubheader2, { sx: { backgroundColor: "transparent" }, children: t2("Layout.Settings") }), children: [
2939
+ /* @__PURE__ */ jsxs13(ListItemButton4, { onClick: changeTab("theme"), sx: { py: 0.3 }, children: [
2940
+ /* @__PURE__ */ jsx24(ListItemIcon4, { children: /* @__PURE__ */ jsx24(Brightness4, {}) }),
2941
+ /* @__PURE__ */ jsx24(ListItemText4, { primary: t2("Layout.Appearance"), secondary: getModeText() }),
2942
+ /* @__PURE__ */ jsx24(ChevronRight, {})
1979
2943
  ] }),
1980
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeTab("language"), sx: { py: 0.3 }, children: [
1981
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(Translate, {}) }),
1982
- /* @__PURE__ */ jsx14(ListItemText, { primary: t2("Layout.Language"), secondary: i18n2.resolvedLanguage === "en" ? "English" : "\u010Ce\u0161tina" }),
1983
- /* @__PURE__ */ jsx14(ChevronRight, {})
2944
+ /* @__PURE__ */ jsxs13(ListItemButton4, { onClick: changeTab("language"), sx: { py: 0.3 }, children: [
2945
+ /* @__PURE__ */ jsx24(ListItemIcon4, { children: /* @__PURE__ */ jsx24(Translate, {}) }),
2946
+ /* @__PURE__ */ jsx24(ListItemText4, { primary: t2("Layout.Language"), secondary: i18n2.resolvedLanguage === "en" ? "English" : "\u010Ce\u0161tina" }),
2947
+ /* @__PURE__ */ jsx24(ChevronRight, {})
1984
2948
  ] })
1985
2949
  ] });
1986
- const theme = /* @__PURE__ */ jsxs6(List, { subheader: /* @__PURE__ */ jsxs6(ListSubheader, { onClick: changeTab("settings"), sx: { backgroundColor: "transparent", display: "flex", alignItems: "center", px: 1, cursor: "pointer" }, children: [
1987
- /* @__PURE__ */ jsx14(IconButton2, { size: "small", sx: { mr: 0.5 }, children: /* @__PURE__ */ jsx14(ArrowBack, { fontSize: "small" }) }),
2950
+ const theme = /* @__PURE__ */ jsxs13(List4, { subheader: /* @__PURE__ */ jsxs13(ListSubheader2, { onClick: changeTab("settings"), sx: { backgroundColor: "transparent", display: "flex", alignItems: "center", px: 1, cursor: "pointer" }, children: [
2951
+ /* @__PURE__ */ jsx24(IconButton4, { size: "small", sx: { mr: 0.5 }, children: /* @__PURE__ */ jsx24(ArrowBack, { fontSize: "small" }) }),
1988
2952
  " ",
1989
2953
  t2("Layout.Appearance")
1990
2954
  ] }), children: [
1991
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeMode("light"), disabled: mode === "light", children: [
1992
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(LightMode, {}) }),
1993
- /* @__PURE__ */ jsx14(ListItemText, { primary: t2("Layout.Light") })
2955
+ /* @__PURE__ */ jsxs13(ListItemButton4, { onClick: changeMode("light"), disabled: mode === "light", children: [
2956
+ /* @__PURE__ */ jsx24(ListItemIcon4, { children: /* @__PURE__ */ jsx24(LightMode, {}) }),
2957
+ /* @__PURE__ */ jsx24(ListItemText4, { primary: t2("Layout.Light") })
1994
2958
  ] }),
1995
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeMode("dark"), disabled: mode === "dark", children: [
1996
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(DarkMode, {}) }),
1997
- /* @__PURE__ */ jsx14(ListItemText, { primary: t2("Layout.Dark") })
2959
+ /* @__PURE__ */ jsxs13(ListItemButton4, { onClick: changeMode("dark"), disabled: mode === "dark", children: [
2960
+ /* @__PURE__ */ jsx24(ListItemIcon4, { children: /* @__PURE__ */ jsx24(DarkMode, {}) }),
2961
+ /* @__PURE__ */ jsx24(ListItemText4, { primary: t2("Layout.Dark") })
1998
2962
  ] }),
1999
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeMode("system"), disabled: mode === "system", children: [
2000
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(SettingsBrightness, {}) }),
2001
- /* @__PURE__ */ jsx14(ListItemText, { primary: t2("Layout.System") })
2963
+ /* @__PURE__ */ jsxs13(ListItemButton4, { onClick: changeMode("system"), disabled: mode === "system", children: [
2964
+ /* @__PURE__ */ jsx24(ListItemIcon4, { children: /* @__PURE__ */ jsx24(SettingsBrightness, {}) }),
2965
+ /* @__PURE__ */ jsx24(ListItemText4, { primary: t2("Layout.System") })
2002
2966
  ] })
2003
2967
  ] });
2004
- const language = /* @__PURE__ */ jsxs6(List, { subheader: /* @__PURE__ */ jsxs6(ListSubheader, { onClick: changeTab("settings"), sx: { backgroundColor: "transparent", display: "flex", alignItems: "center", px: 1, cursor: "pointer" }, children: [
2005
- /* @__PURE__ */ jsx14(IconButton2, { size: "small", sx: { mr: 0.5 }, children: /* @__PURE__ */ jsx14(ArrowBack, { fontSize: "small" }) }),
2968
+ const language = /* @__PURE__ */ jsxs13(List4, { subheader: /* @__PURE__ */ jsxs13(ListSubheader2, { onClick: changeTab("settings"), sx: { backgroundColor: "transparent", display: "flex", alignItems: "center", px: 1, cursor: "pointer" }, children: [
2969
+ /* @__PURE__ */ jsx24(IconButton4, { size: "small", sx: { mr: 0.5 }, children: /* @__PURE__ */ jsx24(ArrowBack, { fontSize: "small" }) }),
2006
2970
  " ",
2007
2971
  t2("Layout.Language")
2008
2972
  ] }), children: [
2009
- /* @__PURE__ */ jsx14(ListItemButton, { onClick: changeLanguage("en"), disabled: i18n2.resolvedLanguage === "en", children: /* @__PURE__ */ jsx14(ListItemText, { primary: "English" }) }),
2010
- /* @__PURE__ */ jsx14(ListItemButton, { onClick: changeLanguage("cs"), disabled: i18n2.resolvedLanguage === "cs", children: /* @__PURE__ */ jsx14(ListItemText, { primary: "\u010Ce\u0161tina" }) })
2973
+ /* @__PURE__ */ jsx24(ListItemButton4, { onClick: changeLanguage("en"), disabled: i18n2.resolvedLanguage === "en", children: /* @__PURE__ */ jsx24(ListItemText4, { primary: "English" }) }),
2974
+ /* @__PURE__ */ jsx24(ListItemButton4, { onClick: changeLanguage("cs"), disabled: i18n2.resolvedLanguage === "cs", children: /* @__PURE__ */ jsx24(ListItemText4, { primary: "\u010Ce\u0161tina" }) })
2011
2975
  ] });
2012
- return /* @__PURE__ */ jsxs6(Fragment, { children: [
2013
- /* @__PURE__ */ jsx14(IconButton2, { size: "small", onClick: openMenu, children: user?.name ? /* @__PURE__ */ jsx14(Avatar, { sx: { width: { xs: 32, sm: 40 }, height: { xs: 32, sm: 40 }, bgcolor: "primary.main" }, children: /* @__PURE__ */ jsx14(Typography6, { variant: "subtitle2", sx: { fontWeight: "bold", lineHeight: 0 }, children: usernameInitials() }) }) : /* @__PURE__ */ jsx14(AccountCircle, {}) }),
2014
- /* @__PURE__ */ jsx14(Menu, { anchorEl: anchorElement, open, onClose: closeMenu, children: /* @__PURE__ */ jsxs6(Box3, { sx: { width: 240 }, children: [
2015
- /* @__PURE__ */ jsx14(List, { children: user?.name ? /* @__PURE__ */ jsxs6(Fragment, { children: [
2016
- /* @__PURE__ */ jsx14(ListItem, { children: /* @__PURE__ */ jsx14(ListItemText, { primary: user.name, secondary: /* @__PURE__ */ jsxs6("span", { children: [
2017
- /* @__PURE__ */ jsx14("span", { children: user.employeeId }),
2018
- /* @__PURE__ */ jsx14("br", {}),
2019
- /* @__PURE__ */ jsx14("span", { children: user.department })
2976
+ return /* @__PURE__ */ jsxs13(Fragment5, { children: [
2977
+ /* @__PURE__ */ jsx24(IconButton4, { size: "small", edge: "end", onClick: openMenu, children: user?.name ? /* @__PURE__ */ jsx24(Avatar2, { sx: { width: { xs: 32, sm: 40 }, height: { xs: 32, sm: 40 }, bgcolor: "primary.main" }, children: /* @__PURE__ */ jsx24(Typography8, { variant: "subtitle2", sx: { fontWeight: "bold", lineHeight: 0 }, children: usernameInitials() }) }) : /* @__PURE__ */ jsx24(AccountCircle, { fontSize: "large" }) }),
2978
+ /* @__PURE__ */ jsx24(Menu2, { anchorEl: anchorElement, open, onClose: closeMenu, children: /* @__PURE__ */ jsxs13(Box8, { sx: { width: 240 }, children: [
2979
+ /* @__PURE__ */ jsx24(List4, { children: user?.name ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
2980
+ /* @__PURE__ */ jsx24(ListItem2, { children: /* @__PURE__ */ jsx24(ListItemText4, { primary: user.name, secondary: /* @__PURE__ */ jsxs13("span", { children: [
2981
+ /* @__PURE__ */ jsx24("span", { children: user.employeeId }),
2982
+ /* @__PURE__ */ jsx24("br", {}),
2983
+ /* @__PURE__ */ jsx24("span", { children: user.department })
2020
2984
  ] }) }) }),
2021
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: () => keycloak.logout(), children: [
2022
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(Logout, { color: "error" }) }),
2023
- /* @__PURE__ */ jsx14(ListItemText, { primary: t2("Layout.Logout") })
2985
+ /* @__PURE__ */ jsxs13(ListItemButton4, { onClick: () => keycloak.logout(), children: [
2986
+ /* @__PURE__ */ jsx24(ListItemIcon4, { children: /* @__PURE__ */ jsx24(Logout, { color: "error" }) }),
2987
+ /* @__PURE__ */ jsx24(ListItemText4, { primary: t2("Layout.Logout") })
2024
2988
  ] })
2025
- ] }) : /* @__PURE__ */ jsxs6(ListItemButton, { onClick: () => keycloak.login(), children: [
2026
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(Login, { color: "success" }) }),
2027
- /* @__PURE__ */ jsx14(ListItemText, { primary: t2("Layout.LogIn") })
2989
+ ] }) : /* @__PURE__ */ jsxs13(ListItemButton4, { onClick: () => keycloak.login(), children: [
2990
+ /* @__PURE__ */ jsx24(ListItemIcon4, { children: /* @__PURE__ */ jsx24(Login, { color: "success" }) }),
2991
+ /* @__PURE__ */ jsx24(ListItemText4, { primary: t2("Layout.LogIn") })
2028
2992
  ] }) }),
2029
2993
  tab === "settings" && settings,
2030
2994
  tab === "theme" && theme,
2031
2995
  tab === "language" && language
2032
2996
  ] }) })
2033
- ] });
2034
- };
2035
-
2036
- // src/hooks/ThemeHook.ts
2037
- import { createTheme, darken, lighten } from "@mui/material";
2038
- import { grey } from "@mui/material/colors";
2039
- import { csCZ, enUS } from "@mui/material/locale";
2040
- import { csCZ as dataGridCsCz, enUS as dataGridEnUs } from "@mui/x-data-grid-premium/locales";
2041
- import { csCZ as datePickersCsCz, enUS as datePickersEnUs } from "@mui/x-date-pickers-pro/locales";
2042
- import { useTranslation as useTranslation4 } from "react-i18next";
2043
- var WISTRON_PRIMARY_COLOR = "#00506E";
2044
- var WISTRON_SECONDARY_COLOR = "#64DC00";
2045
- var useGetTheme = (theme) => {
2046
- const { i18n: i18n2 } = useTranslation4();
2047
- return createTheme(
2048
- {
2049
- cssVariables: {
2050
- colorSchemeSelector: "data-toolpad-color-scheme"
2051
- },
2052
- colorSchemes: {
2053
- light: {
2054
- palette: {
2055
- primary: { main: WISTRON_PRIMARY_COLOR },
2056
- secondary: { main: WISTRON_SECONDARY_COLOR }
2057
- }
2058
- },
2059
- dark: {
2060
- palette: {
2061
- primary: { main: lighten(WISTRON_PRIMARY_COLOR, 0.5) },
2062
- secondary: { main: darken(WISTRON_SECONDARY_COLOR, 0.5) }
2063
- }
2064
- },
2065
- ...theme?.colorSchemes
2066
- },
2067
- components: {
2068
- MuiCssBaseline: {
2069
- styleOverrides: (theme2) => {
2070
- return {
2071
- body: {
2072
- "&::-webkit-scrollbar, & *::-webkit-scrollbar": {
2073
- width: "0.7em",
2074
- height: "0.7em"
2075
- },
2076
- "&::-webkit-scrollbar-track, & *::-webkit-scrollbar-track": {
2077
- backgroundColor: theme2.palette.mode === "dark" ? grey[900] : grey[200],
2078
- borderRadius: "5px"
2079
- },
2080
- "&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
2081
- backgroundColor: theme2.palette.mode === "dark" ? grey[800] : grey[400],
2082
- borderRadius: "10px"
2083
- },
2084
- "&::-webkit-scrollbar-thumb:hover, & *::-webkit-scrollbar-thumb:hover": {
2085
- backgroundColor: theme2.palette.mode === "dark" ? grey[700] : grey[500]
2086
- },
2087
- "&::-webkit-scrollbar-corner, & *::-webkit-scrollbar-corner": {
2088
- backgroundColor: "transparent"
2089
- }
2090
- }
2091
- };
2092
- }
2093
- },
2094
- MuiTableContainer: {
2095
- styleOverrides: {
2096
- root: ({ theme: theme2 }) => ({
2097
- flexGrow: 1,
2098
- "& .MuiDataGrid-cell--editing": {
2099
- "& .MuiInputBase-root": {
2100
- height: "100%"
2101
- }
2102
- },
2103
- "& .MuiDataGrid-columnHeaderTitle": {
2104
- fontWeight: 600
2105
- },
2106
- "& .Mui-error": {
2107
- backgroundColor: theme2.palette.error.main,
2108
- color: theme2.palette.error.contrastText
2109
- },
2110
- "& .MuiDataGrid-booleanCell[data-value='true']": {
2111
- color: `${theme2.palette.success.main} !important`
2112
- },
2113
- "& .MuiDataGrid-booleanCell[data-value='false']": {
2114
- color: `${theme2.palette.error.main} !important`
2997
+ ] });
2998
+ };
2999
+
3000
+ // src/components/core/Layout.tsx
3001
+ import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
3002
+ var DrawerHeader = styled2("div")(({ theme }) => ({
3003
+ display: "flex",
3004
+ alignItems: "center",
3005
+ justifyContent: "flex-end",
3006
+ padding: theme.spacing(0, 1),
3007
+ ...theme.mixins.toolbar
3008
+ }));
3009
+ var Layout = (props) => {
3010
+ const theme = useGetTheme(props.theme);
3011
+ const [navigationOpen, setNavigationOpen] = useLocalStorageState("navigationOpen", { defaultServerValue: false });
3012
+ const isFetching = !!useIsFetching();
3013
+ const isMutating = !!useIsMutating();
3014
+ return /* @__PURE__ */ jsxs14(ThemeProvider, { theme, children: [
3015
+ /* @__PURE__ */ jsx25(InitColorSchemeScript, {}),
3016
+ /* @__PURE__ */ jsx25(CssBaseline, {}),
3017
+ /* @__PURE__ */ jsxs14(Box9, { sx: { display: "flex", height: "100dvh", maxHeight: "100dvh", overflow: "hidden", width: "100%" }, children: [
3018
+ /* @__PURE__ */ jsx25(
3019
+ AppBar,
3020
+ {
3021
+ color: "transparent",
3022
+ position: "fixed",
3023
+ sx: {
3024
+ borderBottom: "1px solid",
3025
+ borderColor: theme.vars?.palette.divider,
3026
+ boxShadow: "none"
3027
+ },
3028
+ children: /* @__PURE__ */ jsxs14(Toolbar, { children: [
3029
+ props.navigation && /* @__PURE__ */ jsx25(
3030
+ IconButton5,
3031
+ {
3032
+ onClick: () => setNavigationOpen((previous) => !previous),
3033
+ sx: { marginRight: 2 },
3034
+ children: navigationOpen ? /* @__PURE__ */ jsx25(MenuOpen, {}) : /* @__PURE__ */ jsx25(Menu3, {})
2115
3035
  }
2116
- })
2117
- }
2118
- },
2119
- ...theme?.components
2120
- }
2121
- },
2122
- i18n2.resolvedLanguage === "cs" ? datePickersCsCz : datePickersEnUs,
2123
- i18n2.resolvedLanguage === "cs" ? dataGridCsCz : dataGridEnUs,
2124
- i18n2.resolvedLanguage === "cs" ? csCZ : enUS
2125
- );
3036
+ ),
3037
+ /* @__PURE__ */ jsx25(AppTitle, {}),
3038
+ /* @__PURE__ */ jsx25(ToolbarAccount, {})
3039
+ ] })
3040
+ }
3041
+ ),
3042
+ props.navigation && /* @__PURE__ */ jsx25(NavigationRail, { navigation: props.navigation, expanded: navigationOpen ?? false, setExpanded: setNavigationOpen }),
3043
+ /* @__PURE__ */ jsxs14(Box9, { component: "main", sx: { flexGrow: 1, display: "flex", flexDirection: "column", minWidth: 0, height: "100%", overflow: "hidden" }, children: [
3044
+ /* @__PURE__ */ jsx25(DrawerHeader, {}),
3045
+ /* @__PURE__ */ jsx25(Box9, { sx: { flex: 1, overflow: "auto", position: "relative" }, children: props.children })
3046
+ ] })
3047
+ ] }),
3048
+ (isFetching || isMutating) && /* @__PURE__ */ jsx25(LinearProgress, { sx: { position: "fixed", top: { xs: 56, sm: 64 }, left: 0, right: 0 } })
3049
+ ] });
2126
3050
  };
2127
3051
 
3052
+ // src/contexts/LayoutContext.ts
3053
+ import { createContext as createContext4, useContext as useContext4 } from "react";
3054
+ var LayoutContext = createContext4(null);
3055
+
2128
3056
  // src/utils/i18n.ts
2129
3057
  import i18n from "i18next";
2130
3058
  import LanguageDetector from "i18next-browser-languagedetector";
@@ -2141,88 +3069,91 @@ i18n.use(HttpBackend).use(LanguageDetector).use(initReactI18next).init({
2141
3069
  }
2142
3070
  });
2143
3071
 
3072
+ // src/providers/DialogsProvider.tsx
3073
+ import { useCallback, useId, useMemo as useMemo4, useRef as useRef3, useState as useState9 } from "react";
3074
+ import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
3075
+ function DialogsProvider({ children, unmountAfter = 1e3 }) {
3076
+ const [stack, setStack] = useState9([]);
3077
+ const keyPrefix = useId();
3078
+ const nextId = useRef3(0);
3079
+ const dialogMetadata = useRef3(/* @__PURE__ */ new WeakMap());
3080
+ const requestDialog = useEventCallback_default(function open(Component6, payload, options = {}) {
3081
+ const { onClose = async () => {
3082
+ } } = options;
3083
+ let resolve;
3084
+ const promise = new Promise((resolveImpl) => {
3085
+ resolve = resolveImpl;
3086
+ });
3087
+ const key = `${keyPrefix}-${nextId.current}`;
3088
+ nextId.current += 1;
3089
+ const newEntry = {
3090
+ key,
3091
+ open: true,
3092
+ promise,
3093
+ Component: Component6,
3094
+ payload,
3095
+ onClose,
3096
+ resolve
3097
+ };
3098
+ dialogMetadata.current.set(promise, newEntry);
3099
+ setStack((previousStack) => [...previousStack, newEntry]);
3100
+ return promise;
3101
+ });
3102
+ const removeDialogFromStack = useCallback((dialog) => {
3103
+ setStack((previousStack) => previousStack.filter((entry) => entry.promise !== dialog));
3104
+ dialogMetadata.current.delete(dialog);
3105
+ }, []);
3106
+ const closeDialogUi = useEventCallback_default(function closeDialogUi2(dialog) {
3107
+ setStack(
3108
+ (previousStack) => previousStack.map((entry) => entry.promise === dialog ? { ...entry, open: false } : entry)
3109
+ );
3110
+ setTimeout(() => removeDialogFromStack(dialog), unmountAfter);
3111
+ });
3112
+ const closeDialog = useEventCallback_default(async function closeDialog2(dialog, result) {
3113
+ const entryToClose = dialogMetadata.current.get(dialog);
3114
+ if (!entryToClose) {
3115
+ throw new Error("Dialog not found in stack");
3116
+ }
3117
+ try {
3118
+ await entryToClose.onClose(result);
3119
+ } finally {
3120
+ entryToClose.resolve(result);
3121
+ closeDialogUi(dialog);
3122
+ }
3123
+ return dialog;
3124
+ });
3125
+ const contextValue = useMemo4(() => ({ open: requestDialog, close: closeDialog }), [requestDialog, closeDialog]);
3126
+ return /* @__PURE__ */ jsxs15(DialogsContext.Provider, { value: contextValue, children: [
3127
+ children,
3128
+ stack.map(({ key, open, Component: Component6, payload, promise }) => /* @__PURE__ */ jsx26(
3129
+ Component6,
3130
+ {
3131
+ payload,
3132
+ open,
3133
+ onClose: async (result) => {
3134
+ await closeDialog(promise, result);
3135
+ }
3136
+ },
3137
+ key
3138
+ ))
3139
+ ] });
3140
+ }
3141
+
2144
3142
  // src/providers/LayoutProvider.tsx
2145
- import { jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
3143
+ import { jsx as jsx27 } from "react/jsx-runtime";
2146
3144
  var LayoutProvider = (props) => {
2147
- const rootRouterState = useRouterState({ select: (s) => s.matches[0] });
2148
- const theme = useGetTheme(props.theme);
2149
- const { t: t2 } = useTranslation5();
2150
- const isFetching = !!useIsFetching();
2151
- const isMutating = !!useIsMutating();
2152
- const isLargeScreen = useMediaQuery(theme.breakpoints.up("sm"));
2153
- const [user, setUser] = useState2({ employeeId: "", name: "Unknown", department: "", company: "", category: "" });
3145
+ const [user, setUser] = useState10({ employeeId: "", name: "Unknown", department: "", company: "", category: "" });
3146
+ const { t: t2 } = useTranslation7();
2154
3147
  const navigation = props.getNavigation?.({ user, t: t2 });
2155
- const appTitle = rootRouterState.meta?.find((meta) => meta?.title)?.title;
2156
- useEffect(() => {
3148
+ useEffect6(() => {
2157
3149
  z.config(default2.resolvedLanguage === "cs" ? cs() : en());
2158
3150
  }, []);
2159
- if (!appTitle)
2160
- throw new Error("Title is not defined in the RootRoute head.");
2161
- return /* @__PURE__ */ jsx15(I18nextProvider, { i18n: default2, children: /* @__PURE__ */ jsx15(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: default2.resolvedLanguage, children: /* @__PURE__ */ jsx15(TanStackRouterAppProvider, { navigation, theme, localeText: {
2162
- confirm: t2("Layout.Dialog.Confirm"),
2163
- cancel: t2("Layout.Dialog.Cancel"),
2164
- alert: t2("Layout.Dialog.Alert")
2165
- }, children: /* @__PURE__ */ jsx15(NotificationsProvider, { slotProps: { snackbar: { anchorOrigin: { vertical: isLargeScreen ? "top" : "bottom", horizontal: "center" } } }, children: /* @__PURE__ */ jsx15(LayoutContext.Provider, { value: { appTitle, user: { get: user, set: setUser } }, children: /* @__PURE__ */ jsxs7(
2166
- DashboardLayout,
2167
- {
2168
- defaultSidebarCollapsed: props.defaultSidebarCollapsed ?? true,
2169
- disableCollapsibleSidebar: props.disableCollapsibleSidebar,
2170
- sidebarExpandedWidth: props.sidebarExpandedWidth,
2171
- hideNavigation: navigation?.length === 0,
2172
- slots: {
2173
- toolbarActions: () => null,
2174
- toolbarAccount: ToolbarAccount,
2175
- appTitle: AppTitle
2176
- },
2177
- children: [
2178
- props.children,
2179
- (isFetching || isMutating) && /* @__PURE__ */ jsx15(LinearProgress, { sx: { position: "fixed", top: { xs: 56, sm: 64 }, left: 0, right: 0 } })
2180
- ]
2181
- }
2182
- ) }) }) }) }) });
3151
+ return /* @__PURE__ */ jsx27(I18nextProvider, { i18n: default2, children: /* @__PURE__ */ jsx27(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: default2.resolvedLanguage, children: /* @__PURE__ */ jsx27(DialogsProvider, { children: /* @__PURE__ */ jsx27(LayoutContext.Provider, { value: { user: { get: user, set: setUser } }, children: /* @__PURE__ */ jsx27(Layout, { navigation, theme: props.theme, children: props.children }) }) }) }) });
2183
3152
  };
2184
3153
 
2185
3154
  // src/index.ts
2186
3155
  import { uuidv7 as uuidv72 } from "uuidv7";
2187
3156
 
2188
- // src/utils/ClientUtils.ts
2189
- import axios from "axios";
2190
- var Platform = class {
2191
- static get isAndroid() {
2192
- return /android/i.test(this.userAgent);
2193
- }
2194
- static get isIOS() {
2195
- return /iPad|iPhone|iPod/.test(this.userAgent);
2196
- }
2197
- static get isWindows() {
2198
- return /windows/i.test(this.userAgent);
2199
- }
2200
- static get isMacOS() {
2201
- return /Macintosh|MacIntel|MacPPC|Mac68K/.test(this.userAgent);
2202
- }
2203
- static get userAgent() {
2204
- return typeof navigator === "undefined" ? "" : navigator.userAgent;
2205
- }
2206
- };
2207
- var rootRouteHead = ({ title }) => () => ({
2208
- meta: [
2209
- { charSet: "utf-8" },
2210
- { name: "viewport", content: "width=device-width, initial-scale=1" },
2211
- { title },
2212
- { name: "og:type", content: "website" },
2213
- { name: "og:title", content: title },
2214
- { name: "og:image", content: "/favicon-32x32.png" }
2215
- ],
2216
- links: [
2217
- { rel: "apple-touch-icon", sizes: "180x180", href: "/apple-touch-icon.png" },
2218
- { rel: "icon", type: "image/png", sizes: "32x32", href: "/favicon-32x32.png" },
2219
- { rel: "icon", type: "image/png", sizes: "16x16", href: "/favicon-16x16.png" },
2220
- { rel: "manifest", href: "/site.webmanifest" },
2221
- { rel: "icon", href: "/favicon.ico" }
2222
- ]
2223
- });
2224
- var wczApiClient = axios.create();
2225
-
2226
3157
  // src/hooks/FormHooks.ts
2227
3158
  import { createFormHook, createFormHookContexts } from "@tanstack/react-form";
2228
3159
 
@@ -2239,11 +3170,11 @@ var getFieldStatus = (field) => {
2239
3170
  };
2240
3171
 
2241
3172
  // src/components/form/FormAutocomplete.tsx
2242
- import { jsx as jsx16 } from "react/jsx-runtime";
3173
+ import { jsx as jsx28 } from "react/jsx-runtime";
2243
3174
  var FormAutocomplete = ({ textFieldProps, ...autocompleteProps }) => {
2244
3175
  const field = useFieldContext();
2245
3176
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2246
- return /* @__PURE__ */ jsx16(
3177
+ return /* @__PURE__ */ jsx28(
2247
3178
  Autocomplete,
2248
3179
  {
2249
3180
  value: field.state.value,
@@ -2252,7 +3183,7 @@ var FormAutocomplete = ({ textFieldProps, ...autocompleteProps }) => {
2252
3183
  onBlur: field.handleBlur,
2253
3184
  "aria-label": field.name,
2254
3185
  ...autocompleteProps,
2255
- renderInput: (parameters) => /* @__PURE__ */ jsx16(
3186
+ renderInput: (parameters) => /* @__PURE__ */ jsx28(
2256
3187
  TextField,
2257
3188
  {
2258
3189
  ...parameters,
@@ -2268,15 +3199,15 @@ var FormAutocomplete = ({ textFieldProps, ...autocompleteProps }) => {
2268
3199
 
2269
3200
  // src/components/form/FormCheckbox.tsx
2270
3201
  import { Checkbox, FormControl, FormControlLabel, FormHelperText } from "@mui/material";
2271
- import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
3202
+ import { jsx as jsx29, jsxs as jsxs16 } from "react/jsx-runtime";
2272
3203
  var FormCheckbox = (props) => {
2273
3204
  const field = useFieldContext();
2274
3205
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2275
- return /* @__PURE__ */ jsxs8(FormControl, { component: "fieldset", children: [
2276
- /* @__PURE__ */ jsx17(
3206
+ return /* @__PURE__ */ jsxs16(FormControl, { component: "fieldset", children: [
3207
+ /* @__PURE__ */ jsx29(
2277
3208
  FormControlLabel,
2278
3209
  {
2279
- control: /* @__PURE__ */ jsx17(
3210
+ control: /* @__PURE__ */ jsx29(
2280
3211
  Checkbox,
2281
3212
  {
2282
3213
  name: field.name,
@@ -2290,18 +3221,18 @@ var FormCheckbox = (props) => {
2290
3221
  label: props.label ?? ""
2291
3222
  }
2292
3223
  ),
2293
- isTouched && hasError && /* @__PURE__ */ jsx17(FormHelperText, { error: hasError, children: helperText })
3224
+ isTouched && hasError && /* @__PURE__ */ jsx29(FormHelperText, { error: hasError, children: helperText })
2294
3225
  ] });
2295
3226
  };
2296
3227
 
2297
3228
  // src/components/form/FormDatePicker.tsx
2298
3229
  import { DatePicker } from "@mui/x-date-pickers-pro";
2299
3230
  import dayjs2 from "dayjs";
2300
- import { jsx as jsx18 } from "react/jsx-runtime";
3231
+ import { jsx as jsx30 } from "react/jsx-runtime";
2301
3232
  var FormDatePicker = (props) => {
2302
3233
  const field = useFieldContext();
2303
3234
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2304
- return /* @__PURE__ */ jsx18(
3235
+ return /* @__PURE__ */ jsx30(
2305
3236
  DatePicker,
2306
3237
  {
2307
3238
  name: field.name,
@@ -2325,11 +3256,11 @@ var FormDatePicker = (props) => {
2325
3256
  // src/components/form/FormDateTimePicker.tsx
2326
3257
  import { DateTimePicker } from "@mui/x-date-pickers-pro";
2327
3258
  import dayjs3 from "dayjs";
2328
- import { jsx as jsx19 } from "react/jsx-runtime";
3259
+ import { jsx as jsx31 } from "react/jsx-runtime";
2329
3260
  var FormDateTimePicker = (props) => {
2330
3261
  const field = useFieldContext();
2331
3262
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2332
- return /* @__PURE__ */ jsx19(
3263
+ return /* @__PURE__ */ jsx31(
2333
3264
  DateTimePicker,
2334
3265
  {
2335
3266
  name: field.name,
@@ -2353,11 +3284,11 @@ var FormDateTimePicker = (props) => {
2353
3284
  // src/components/form/FormNumberField.tsx
2354
3285
  import { TextField as TextField2 } from "@mui/material";
2355
3286
  import { NumericFormat } from "react-number-format";
2356
- import { jsx as jsx20 } from "react/jsx-runtime";
3287
+ import { jsx as jsx32 } from "react/jsx-runtime";
2357
3288
  var FormNumberField = ({ options, ...props }) => {
2358
3289
  const field = useFieldContext();
2359
3290
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2360
- return /* @__PURE__ */ jsx20(
3291
+ return /* @__PURE__ */ jsx32(
2361
3292
  NumericFormat,
2362
3293
  {
2363
3294
  customInput: TextField2,
@@ -2376,13 +3307,13 @@ var FormNumberField = ({ options, ...props }) => {
2376
3307
 
2377
3308
  // src/components/form/FormRadioGroup.tsx
2378
3309
  import { FormControl as FormControl2, FormControlLabel as FormControlLabel2, FormHelperText as FormHelperText2, FormLabel, Radio, RadioGroup } from "@mui/material";
2379
- import { jsx as jsx21, jsxs as jsxs9 } from "react/jsx-runtime";
3310
+ import { jsx as jsx33, jsxs as jsxs17 } from "react/jsx-runtime";
2380
3311
  var FormRadioGroup = ({ label, options, ...props }) => {
2381
3312
  const field = useFieldContext();
2382
3313
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2383
- return /* @__PURE__ */ jsxs9(FormControl2, { component: "fieldset", children: [
2384
- label && /* @__PURE__ */ jsx21(FormLabel, { component: "legend", children: label }),
2385
- /* @__PURE__ */ jsx21(
3314
+ return /* @__PURE__ */ jsxs17(FormControl2, { component: "fieldset", children: [
3315
+ label && /* @__PURE__ */ jsx33(FormLabel, { component: "legend", children: label }),
3316
+ /* @__PURE__ */ jsx33(
2386
3317
  RadioGroup,
2387
3318
  {
2388
3319
  name: field.name,
@@ -2391,30 +3322,30 @@ var FormRadioGroup = ({ label, options, ...props }) => {
2391
3322
  onBlur: field.handleBlur,
2392
3323
  "aria-label": field.name,
2393
3324
  ...props,
2394
- children: options.map((option) => /* @__PURE__ */ jsx21(
3325
+ children: options.map((option) => /* @__PURE__ */ jsx33(
2395
3326
  FormControlLabel2,
2396
3327
  {
2397
3328
  value: option.value,
2398
- control: /* @__PURE__ */ jsx21(Radio, {}),
3329
+ control: /* @__PURE__ */ jsx33(Radio, {}),
2399
3330
  label: option.label
2400
3331
  },
2401
3332
  option.value
2402
3333
  ))
2403
3334
  }
2404
3335
  ),
2405
- isTouched && hasError && /* @__PURE__ */ jsx21(FormHelperText2, { error: hasError, children: helperText })
3336
+ isTouched && hasError && /* @__PURE__ */ jsx33(FormHelperText2, { error: hasError, children: helperText })
2406
3337
  ] });
2407
3338
  };
2408
3339
 
2409
3340
  // src/components/form/FormSlider.tsx
2410
3341
  import { FormControl as FormControl3, FormHelperText as FormHelperText3, FormLabel as FormLabel2, Slider } from "@mui/material";
2411
- import { jsx as jsx22, jsxs as jsxs10 } from "react/jsx-runtime";
3342
+ import { jsx as jsx34, jsxs as jsxs18 } from "react/jsx-runtime";
2412
3343
  var FormSlider = ({ label, ...props }) => {
2413
3344
  const field = useFieldContext();
2414
3345
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2415
- return /* @__PURE__ */ jsxs10(FormControl3, { component: "fieldset", children: [
2416
- label && /* @__PURE__ */ jsx22(FormLabel2, { children: label }),
2417
- /* @__PURE__ */ jsx22(
3346
+ return /* @__PURE__ */ jsxs18(FormControl3, { component: "fieldset", children: [
3347
+ label && /* @__PURE__ */ jsx34(FormLabel2, { children: label }),
3348
+ /* @__PURE__ */ jsx34(
2418
3349
  Slider,
2419
3350
  {
2420
3351
  name: field.name,
@@ -2425,13 +3356,13 @@ var FormSlider = ({ label, ...props }) => {
2425
3356
  ...props
2426
3357
  }
2427
3358
  ),
2428
- isTouched && hasError && /* @__PURE__ */ jsx22(FormHelperText3, { error: hasError, children: helperText })
3359
+ isTouched && hasError && /* @__PURE__ */ jsx34(FormHelperText3, { error: hasError, children: helperText })
2429
3360
  ] });
2430
3361
  };
2431
3362
 
2432
3363
  // src/components/form/FormSubmitButton.tsx
2433
- import { Button as Button2 } from "@mui/material";
2434
- import { jsx as jsx23 } from "react/jsx-runtime";
3364
+ import { Button as Button3 } from "@mui/material";
3365
+ import { jsx as jsx35 } from "react/jsx-runtime";
2435
3366
  var FormSubmitButton = (props) => {
2436
3367
  const form = useFormContext();
2437
3368
  const handleClick = (event) => {
@@ -2439,8 +3370,8 @@ var FormSubmitButton = (props) => {
2439
3370
  event.stopPropagation();
2440
3371
  form.handleSubmit();
2441
3372
  };
2442
- return /* @__PURE__ */ jsx23(form.Subscribe, { selector: (state) => [state.canSubmit, state.isSubmitting], children: ([canSubmit, isSubmitting]) => /* @__PURE__ */ jsx23(
2443
- Button2,
3373
+ return /* @__PURE__ */ jsx35(form.Subscribe, { selector: (state) => [state.canSubmit, state.isSubmitting], children: ([canSubmit, isSubmitting]) => /* @__PURE__ */ jsx35(
3374
+ Button3,
2444
3375
  {
2445
3376
  loading: isSubmitting,
2446
3377
  disabled: !canSubmit,
@@ -2454,15 +3385,15 @@ var FormSubmitButton = (props) => {
2454
3385
 
2455
3386
  // src/components/form/FormSwitch.tsx
2456
3387
  import { FormControl as FormControl4, FormControlLabel as FormControlLabel3, FormHelperText as FormHelperText4, Switch } from "@mui/material";
2457
- import { jsx as jsx24, jsxs as jsxs11 } from "react/jsx-runtime";
3388
+ import { jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
2458
3389
  var FormSwitch = (props) => {
2459
3390
  const field = useFieldContext();
2460
3391
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2461
- return /* @__PURE__ */ jsxs11(FormControl4, { component: "fieldset", children: [
2462
- /* @__PURE__ */ jsx24(
3392
+ return /* @__PURE__ */ jsxs19(FormControl4, { component: "fieldset", children: [
3393
+ /* @__PURE__ */ jsx36(
2463
3394
  FormControlLabel3,
2464
3395
  {
2465
- control: /* @__PURE__ */ jsx24(
3396
+ control: /* @__PURE__ */ jsx36(
2466
3397
  Switch,
2467
3398
  {
2468
3399
  name: field.name,
@@ -2476,17 +3407,17 @@ var FormSwitch = (props) => {
2476
3407
  label: props.label ?? ""
2477
3408
  }
2478
3409
  ),
2479
- isTouched && hasError && /* @__PURE__ */ jsx24(FormHelperText4, { error: hasError, children: helperText })
3410
+ isTouched && hasError && /* @__PURE__ */ jsx36(FormHelperText4, { error: hasError, children: helperText })
2480
3411
  ] });
2481
3412
  };
2482
3413
 
2483
3414
  // src/components/form/FormTextField.tsx
2484
3415
  import { TextField as TextField3 } from "@mui/material";
2485
- import { jsx as jsx25 } from "react/jsx-runtime";
3416
+ import { jsx as jsx37 } from "react/jsx-runtime";
2486
3417
  var FormTextField = (props) => {
2487
3418
  const field = useFieldContext();
2488
3419
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2489
- return /* @__PURE__ */ jsx25(
3420
+ return /* @__PURE__ */ jsx37(
2490
3421
  TextField3,
2491
3422
  {
2492
3423
  name: field.name,
@@ -2523,222 +3454,15 @@ var { useAppForm: useLayoutForm, withForm: withLayoutForm } = createFormHook({
2523
3454
  });
2524
3455
 
2525
3456
  // src/index.ts
2526
- import { useDialogs } from "@toolpad/core/useDialogs";
2527
- import { useNotifications } from "@toolpad/core/useNotifications";
2528
- import { useLocalStorageState } from "@toolpad/core/useLocalStorageState";
2529
- import { useTranslation as useTranslation6 } from "react-i18next";
3457
+ import { default as default3 } from "use-local-storage-state";
3458
+ import { useTranslation as useTranslation8 } from "react-i18next";
2530
3459
  import { t } from "i18next";
2531
-
2532
- // src/hooks/FileHooks.ts
2533
- import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
2534
- import saveAs from "file-saver";
2535
- import { useState as useState3 } from "react";
2536
- import { Upload as TusUpload } from "tus-js-client";
2537
- import { uuidv7 } from "uuidv7";
2538
- var BASE_URL = import.meta.env.VITE_FILE_API_BASE_URL;
2539
- var QUERY_KEY = "Files";
2540
- var HOUR = 1e3 * 60 * 60;
2541
- var useGetFileMetas = (subId, options) => {
2542
- const { appTitle } = useLayout();
2543
- return useQuery({
2544
- ...options,
2545
- queryKey: [QUERY_KEY, "meta", subId, appTitle],
2546
- queryFn: ({ signal }) => wczApiClient.request({
2547
- url: `${BASE_URL}/v1/meta?appName=${appTitle}&subId=${subId}`,
2548
- method: "GET",
2549
- signal
2550
- }),
2551
- initialData: [],
2552
- refetchOnWindowFocus: false
2553
- });
2554
- };
2555
- var useGetFileThumbnail = (meta, options) => {
2556
- const { appTitle } = useLayout();
2557
- return useQuery({
2558
- ...options,
2559
- queryKey: [QUERY_KEY, "thumbnail", meta?.id, appTitle],
2560
- queryFn: ({ signal }) => wczApiClient.request({
2561
- url: `${BASE_URL}/v1/thumbnail?appName=${appTitle}&id=${meta?.id}`,
2562
- method: "GET",
2563
- signal,
2564
- responseType: "blob"
2565
- }),
2566
- select: (data) => URL.createObjectURL(data),
2567
- staleTime: HOUR,
2568
- gcTime: HOUR,
2569
- refetchOnWindowFocus: false,
2570
- enabled: !!meta?.id && options?.enabled
2571
- });
2572
- };
2573
- var useGetFile = (meta, options) => {
2574
- const { appTitle } = useLayout();
2575
- return useQuery({
2576
- ...options,
2577
- queryKey: [QUERY_KEY, meta?.id, appTitle],
2578
- queryFn: ({ signal }) => wczApiClient.request({
2579
- url: `${BASE_URL}/v1?appName=${appTitle}&id=${meta?.id}`,
2580
- method: "GET",
2581
- signal,
2582
- responseType: "blob"
2583
- }),
2584
- select: (data) => URL.createObjectURL(data),
2585
- staleTime: HOUR,
2586
- gcTime: HOUR,
2587
- refetchOnWindowFocus: false,
2588
- enabled: !!meta?.id && options?.enabled
2589
- });
2590
- };
2591
- var useDownloadFile = (options) => {
2592
- const { appTitle } = useLayout();
2593
- return useMutation({
2594
- ...options,
2595
- mutationFn: (meta) => wczApiClient.request({
2596
- url: `${BASE_URL}/v1/download?appName=${appTitle}&id=${meta.id}`,
2597
- method: "GET",
2598
- responseType: "blob"
2599
- }),
2600
- onSuccess: (data, variables) => saveAs(data, `${variables.fileName}.${variables.fileExtension}`)
2601
- });
2602
- };
2603
- var useOpenFile = (options) => {
2604
- const { appTitle } = useLayout();
2605
- return useMutation({
2606
- ...options,
2607
- mutationFn: (meta) => wczApiClient.request({
2608
- url: `${BASE_URL}/v1?appName=${appTitle}&id=${meta.id}`,
2609
- method: "GET",
2610
- responseType: "blob"
2611
- }),
2612
- onSuccess: (data) => {
2613
- window.open(URL.createObjectURL(data));
2614
- }
2615
- });
2616
- };
2617
- var useUpdateFileMeta = (options) => {
2618
- const { appTitle } = useLayout();
2619
- const queryClient = useQueryClient();
2620
- return useMutation({
2621
- ...options,
2622
- mutationFn: (meta) => wczApiClient.request({
2623
- url: `${BASE_URL}/v1/meta?appName=${appTitle}&id=${meta.id}`,
2624
- method: "PUT",
2625
- data: meta
2626
- }),
2627
- onSettled: () => queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false })
2628
- });
2629
- };
2630
- var useDeleteFile = (options) => {
2631
- const { appTitle } = useLayout();
2632
- const queryClient = useQueryClient();
2633
- return useMutation({
2634
- ...options,
2635
- mutationFn: (meta) => wczApiClient.request({
2636
- url: `${BASE_URL}/v1?appName=${appTitle}&id=${meta.id}`,
2637
- method: "DELETE"
2638
- }),
2639
- onSettled: () => queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false })
2640
- });
2641
- };
2642
- var useDeleteFiles = (options) => {
2643
- const { appTitle } = useLayout();
2644
- const queryClient = useQueryClient();
2645
- return useMutation({
2646
- ...options,
2647
- mutationFn: (subId) => wczApiClient.request({
2648
- url: `${BASE_URL}/v1?appName=${appTitle}&subId=${subId}`,
2649
- method: "DELETE"
2650
- }),
2651
- onSettled: () => queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false })
2652
- });
2653
- };
2654
- var useUploadFile = ({ subId, onSuccess, onError }) => {
2655
- const { appTitle } = useLayout();
2656
- const [progress, setProgress] = useState3(0);
2657
- const queryClient = useQueryClient();
2658
- const mutate = async (file) => {
2659
- if (!subId) throw new Error("subId is required for file upload");
2660
- const metadata = {
2661
- id: uuidv7(),
2662
- appName: appTitle,
2663
- subId,
2664
- fileName: file.name
2665
- };
2666
- const upload = new TusUpload(file, {
2667
- endpoint: `${BASE_URL}/v1/upload`,
2668
- chunkSize: 1048576,
2669
- // 1 MB
2670
- metadata: {
2671
- id: metadata.id,
2672
- appName: metadata.appName,
2673
- subId: metadata.subId,
2674
- fileName: metadata.fileName,
2675
- fileExtension: file.type
2676
- },
2677
- //headers: { "Authorization": `Bearer ${await getToken()}` }, //TODO: implement token retrieval
2678
- onError: (error) => {
2679
- setProgress(0);
2680
- onError?.(error);
2681
- },
2682
- onProgress: (bytesUploaded, bytesTotal) => {
2683
- setProgress(bytesUploaded / bytesTotal * 100);
2684
- },
2685
- onSuccess: () => {
2686
- setProgress(0);
2687
- queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false });
2688
- onSuccess?.(metadata);
2689
- }
2690
- });
2691
- const previousUploads = await upload.findPreviousUploads();
2692
- if (previousUploads.length > 0) {
2693
- upload.resumeFromPreviousUpload(previousUploads[0]);
2694
- }
2695
- upload.start();
2696
- };
2697
- return { mutate, progress };
2698
- };
2699
- function useOptimisticFileMutation(subId, options) {
2700
- const [uploadedFileIds, setUploadedFileIds] = useState3([]);
2701
- const [deletedFileIds, setDeletedFileIds] = useState3([]);
2702
- const { data } = useGetFileMetas(subId, options);
2703
- const { mutate: deleteAttachment } = useDeleteFile();
2704
- function addFile(meta) {
2705
- setUploadedFileIds((previous) => [...previous, meta.id]);
2706
- }
2707
- function removeFile(meta) {
2708
- const added = uploadedFileIds.includes(meta.id);
2709
- if (added) {
2710
- setUploadedFileIds((previous) => previous.filter((file) => file !== meta.id));
2711
- } else {
2712
- setDeletedFileIds((previous) => [...previous, meta.id]);
2713
- }
2714
- }
2715
- function save() {
2716
- for (const id of deletedFileIds) {
2717
- const meta = data.find((meta2) => meta2.id === id);
2718
- if (!meta) continue;
2719
- deleteAttachment(meta);
2720
- }
2721
- }
2722
- function undo() {
2723
- for (const id of uploadedFileIds) {
2724
- const meta = data.find((meta2) => meta2.id === id);
2725
- if (!meta) continue;
2726
- deleteAttachment(meta);
2727
- }
2728
- }
2729
- return {
2730
- addFile,
2731
- removeFile,
2732
- save,
2733
- undo
2734
- };
2735
- }
2736
3460
  export {
2737
3461
  ChipInputCell,
2738
3462
  Dropzone,
2739
3463
  EditableColumnHeader,
3464
+ FileViewer,
2740
3465
  LayoutProvider,
2741
- PageContainer,
2742
3466
  PageHeader,
2743
3467
  Platform,
2744
3468
  RouterButton,
@@ -2748,6 +3472,7 @@ export {
2748
3472
  RouterLink,
2749
3473
  RouterNotFound,
2750
3474
  RouterTab,
3475
+ TableContainer,
2751
3476
  TypographyWithIcon,
2752
3477
  rootRouteHead,
2753
3478
  t,
@@ -2761,11 +3486,9 @@ export {
2761
3486
  useGetFileMetas,
2762
3487
  useGetFileThumbnail,
2763
3488
  useLayoutForm,
2764
- useLocalStorageState,
2765
- useNotifications,
3489
+ default3 as useLocalStorageState,
2766
3490
  useOpenFile,
2767
- useOptimisticFileMutation,
2768
- useTranslation6 as useTranslation,
3491
+ useTranslation8 as useTranslation,
2769
3492
  useUpdateFileMeta,
2770
3493
  useUploadFile,
2771
3494
  uuidv72 as uuidv7,