wcz-test 3.1.1 → 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
@@ -47,7 +47,7 @@ var require_react_is_production_min = __commonJS({
47
47
  var w = b ? Symbol.for("react.fundamental") : 60117;
48
48
  var x = b ? Symbol.for("react.responder") : 60118;
49
49
  var y = b ? Symbol.for("react.scope") : 60119;
50
- function z(a) {
50
+ function z2(a) {
51
51
  if ("object" === typeof a && null !== a) {
52
52
  var u = a.$$typeof;
53
53
  switch (u) {
@@ -78,7 +78,7 @@ var require_react_is_production_min = __commonJS({
78
78
  }
79
79
  }
80
80
  function A(a) {
81
- return z(a) === m;
81
+ return z2(a) === m;
82
82
  }
83
83
  exports.AsyncMode = l;
84
84
  exports.ConcurrentMode = m;
@@ -94,46 +94,46 @@ var require_react_is_production_min = __commonJS({
94
94
  exports.StrictMode = f;
95
95
  exports.Suspense = p;
96
96
  exports.isAsyncMode = function(a) {
97
- return A(a) || z(a) === l;
97
+ return A(a) || z2(a) === l;
98
98
  };
99
99
  exports.isConcurrentMode = A;
100
100
  exports.isContextConsumer = function(a) {
101
- return z(a) === k;
101
+ return z2(a) === k;
102
102
  };
103
103
  exports.isContextProvider = function(a) {
104
- return z(a) === h;
104
+ return z2(a) === h;
105
105
  };
106
106
  exports.isElement = function(a) {
107
107
  return "object" === typeof a && null !== a && a.$$typeof === c;
108
108
  };
109
109
  exports.isForwardRef = function(a) {
110
- return z(a) === n;
110
+ return z2(a) === n;
111
111
  };
112
112
  exports.isFragment = function(a) {
113
- return z(a) === e;
113
+ return z2(a) === e;
114
114
  };
115
115
  exports.isLazy = function(a) {
116
- return z(a) === t2;
116
+ return z2(a) === t2;
117
117
  };
118
118
  exports.isMemo = function(a) {
119
- return z(a) === r;
119
+ return z2(a) === r;
120
120
  };
121
121
  exports.isPortal = function(a) {
122
- return z(a) === d;
122
+ return z2(a) === d;
123
123
  };
124
124
  exports.isProfiler = function(a) {
125
- return z(a) === g;
125
+ return z2(a) === g;
126
126
  };
127
127
  exports.isStrictMode = function(a) {
128
- return z(a) === f;
128
+ return z2(a) === f;
129
129
  };
130
130
  exports.isSuspense = function(a) {
131
- return z(a) === p;
131
+ return z2(a) === p;
132
132
  };
133
133
  exports.isValidElementType = function(a) {
134
134
  return "string" === typeof a || "function" === typeof a || a === e || a === m || a === g || a === f || a === p || a === q || "object" === typeof a && null !== a && (a.$$typeof === t2 || a.$$typeof === r || a.$$typeof === h || a.$$typeof === k || a.$$typeof === n || a.$$typeof === w || a.$$typeof === x || a.$$typeof === y || a.$$typeof === v);
135
135
  };
136
- exports.typeOf = z;
136
+ exports.typeOf = z2;
137
137
  }
138
138
  });
139
139
 
@@ -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,394 +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
2480
+ import { useEffect as useEffect6, useState as useState10 } from "react";
2481
+ import { I18nextProvider, useTranslation as useTranslation7 } from "react-i18next";
2482
+ import * as z from "zod";
2483
+ import { cs, en } from "zod/locales";
2484
+
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";
1872
2490
  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 { useState as useState2 } from "react";
1878
- import { I18nextProvider, useTranslation as useTranslation5 } from "react-i18next";
2491
+ import useLocalStorageState from "use-local-storage-state";
1879
2492
 
1880
- // src/components/core/AppTitle.tsx
1881
- import { Chip as Chip2, Stack as Stack3, Typography as Typography5 } from "@mui/material";
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
+ };
1882
2583
 
1883
- // src/contexts/LayoutContext.ts
1884
- import { createContext as createContext2, useContext as useContext2 } from "react";
1885
- var LayoutContext = createContext2({});
1886
- var useLayout = () => useContext2(LayoutContext);
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";
1887
2590
 
1888
- // src/components/core/AppTitle.tsx
1889
- import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
1890
- var AppTitle = () => {
1891
- const { appTitle } = useLayout();
1892
- return /* @__PURE__ */ jsxs5(Stack3, { direction: "row", alignItems: "center", spacing: 2, children: [
1893
- /* @__PURE__ */ jsx13("img", { src: "/favicon-32x32.png", alt: "app-logo", loading: "lazy" }),
1894
- /* @__PURE__ */ jsx13(Typography5, { variant: "h6", children: appTitle }),
1895
- import.meta.env.DEV && /* @__PURE__ */ jsx13(Chip2, { size: "small", label: "BETA", color: "info" })
1896
- ] });
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) });
1897
2863
  };
1898
2864
 
1899
2865
  // src/components/core/ToolbarAccount.tsx
@@ -1907,9 +2873,9 @@ import Login from "@mui/icons-material/Login";
1907
2873
  import Logout from "@mui/icons-material/Logout";
1908
2874
  import SettingsBrightness from "@mui/icons-material/SettingsBrightness";
1909
2875
  import Translate from "@mui/icons-material/Translate";
1910
- import { Avatar, Box as Box3, IconButton as IconButton2, List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListSubheader, Menu, Typography as Typography6, useColorScheme } from "@mui/material";
1911
- import { Fragment, useState } from "react";
1912
- 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";
1913
2879
 
1914
2880
  // src/auth-test/keycloak.ts
1915
2881
  import { useRouter } from "@tanstack/react-router";
@@ -1929,12 +2895,12 @@ function useKeycloak() {
1929
2895
  }
1930
2896
 
1931
2897
  // src/components/core/ToolbarAccount.tsx
1932
- import { jsx as jsx14, jsxs as jsxs6 } from "react/jsx-runtime";
2898
+ import { jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
1933
2899
  var ToolbarAccount = () => {
1934
- const [anchorElement, setAnchorElement] = useState();
1935
- const [tab, setTab] = useState("settings");
2900
+ const [anchorElement, setAnchorElement] = useState8();
2901
+ const [tab, setTab] = useState8("settings");
1936
2902
  const open = Boolean(anchorElement);
1937
- const { t: t2, i18n: i18n2 } = useTranslation3();
2903
+ const { t: t2, i18n: i18n2 } = useTranslation6();
1938
2904
  const { mode, setMode } = useColorScheme();
1939
2905
  const changeLanguage = (newLanguage) => () => {
1940
2906
  i18n2.changeLanguage(newLanguage).finally(() => closeMenu());
@@ -1969,160 +2935,124 @@ var ToolbarAccount = () => {
1969
2935
  setTimeout(() => setTab("settings"), 300);
1970
2936
  };
1971
2937
  const changeTab = (newTab) => () => setTab(newTab);
1972
- const settings = /* @__PURE__ */ jsxs6(List, { component: "nav", subheader: /* @__PURE__ */ jsx14(ListSubheader, { sx: { backgroundColor: "transparent" }, children: t2("Layout.Settings") }), children: [
1973
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeTab("theme"), sx: { py: 0.3 }, children: [
1974
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(Brightness4, {}) }),
1975
- /* @__PURE__ */ jsx14(ListItemText, { primary: t2("Layout.Appearance"), secondary: getModeText() }),
1976
- /* @__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, {})
1977
2943
  ] }),
1978
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeTab("language"), sx: { py: 0.3 }, children: [
1979
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(Translate, {}) }),
1980
- /* @__PURE__ */ jsx14(ListItemText, { primary: t2("Layout.Language"), secondary: i18n2.resolvedLanguage === "en" ? "English" : "\u010Ce\u0161tina" }),
1981
- /* @__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, {})
1982
2948
  ] })
1983
2949
  ] });
1984
- const theme = /* @__PURE__ */ jsxs6(List, { subheader: /* @__PURE__ */ jsxs6(ListSubheader, { onClick: changeTab("settings"), sx: { backgroundColor: "transparent", display: "flex", alignItems: "center", px: 1, cursor: "pointer" }, children: [
1985
- /* @__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" }) }),
1986
2952
  " ",
1987
2953
  t2("Layout.Appearance")
1988
2954
  ] }), children: [
1989
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeMode("light"), disabled: mode === "light", children: [
1990
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(LightMode, {}) }),
1991
- /* @__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") })
1992
2958
  ] }),
1993
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeMode("dark"), disabled: mode === "dark", children: [
1994
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(DarkMode, {}) }),
1995
- /* @__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") })
1996
2962
  ] }),
1997
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: changeMode("system"), disabled: mode === "system", children: [
1998
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(SettingsBrightness, {}) }),
1999
- /* @__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") })
2000
2966
  ] })
2001
2967
  ] });
2002
- const language = /* @__PURE__ */ jsxs6(List, { subheader: /* @__PURE__ */ jsxs6(ListSubheader, { onClick: changeTab("settings"), sx: { backgroundColor: "transparent", display: "flex", alignItems: "center", px: 1, cursor: "pointer" }, children: [
2003
- /* @__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" }) }),
2004
2970
  " ",
2005
2971
  t2("Layout.Language")
2006
2972
  ] }), children: [
2007
- /* @__PURE__ */ jsx14(ListItemButton, { onClick: changeLanguage("en"), disabled: i18n2.resolvedLanguage === "en", children: /* @__PURE__ */ jsx14(ListItemText, { primary: "English" }) }),
2008
- /* @__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" }) })
2009
2975
  ] });
2010
- return /* @__PURE__ */ jsxs6(Fragment, { children: [
2011
- /* @__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, {}) }),
2012
- /* @__PURE__ */ jsx14(Menu, { anchorEl: anchorElement, open, onClose: closeMenu, children: /* @__PURE__ */ jsxs6(Box3, { sx: { width: 240 }, children: [
2013
- /* @__PURE__ */ jsx14(List, { children: user?.name ? /* @__PURE__ */ jsxs6(Fragment, { children: [
2014
- /* @__PURE__ */ jsx14(ListItem, { children: /* @__PURE__ */ jsx14(ListItemText, { primary: user.name, secondary: /* @__PURE__ */ jsxs6("span", { children: [
2015
- /* @__PURE__ */ jsx14("span", { children: user.employeeId }),
2016
- /* @__PURE__ */ jsx14("br", {}),
2017
- /* @__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 })
2018
2984
  ] }) }) }),
2019
- /* @__PURE__ */ jsxs6(ListItemButton, { onClick: () => keycloak.logout(), children: [
2020
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(Logout, { color: "error" }) }),
2021
- /* @__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") })
2022
2988
  ] })
2023
- ] }) : /* @__PURE__ */ jsxs6(ListItemButton, { onClick: () => keycloak.login(), children: [
2024
- /* @__PURE__ */ jsx14(ListItemIcon, { children: /* @__PURE__ */ jsx14(Login, { color: "success" }) }),
2025
- /* @__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") })
2026
2992
  ] }) }),
2027
2993
  tab === "settings" && settings,
2028
2994
  tab === "theme" && theme,
2029
- tab === "language" && language
2030
- ] }) })
2031
- ] });
2032
- };
2033
-
2034
- // src/hooks/ThemeHook.ts
2035
- import { createTheme, darken, lighten } from "@mui/material";
2036
- import { grey } from "@mui/material/colors";
2037
- import { csCZ, enUS } from "@mui/material/locale";
2038
- import { csCZ as dataGridCsCz, enUS as dataGridEnUs } from "@mui/x-data-grid-premium/locales";
2039
- import { csCZ as datePickersCsCz, enUS as datePickersEnUs } from "@mui/x-date-pickers-pro/locales";
2040
- import { useTranslation as useTranslation4 } from "react-i18next";
2041
- var WISTRON_PRIMARY_COLOR = "#00506E";
2042
- var WISTRON_SECONDARY_COLOR = "#64DC00";
2043
- var useGetTheme = (theme) => {
2044
- const { i18n: i18n2 } = useTranslation4();
2045
- return createTheme(
2046
- {
2047
- cssVariables: {
2048
- colorSchemeSelector: "data-toolpad-color-scheme"
2049
- },
2050
- colorSchemes: {
2051
- light: {
2052
- palette: {
2053
- primary: { main: WISTRON_PRIMARY_COLOR },
2054
- secondary: { main: WISTRON_SECONDARY_COLOR }
2055
- }
2056
- },
2057
- dark: {
2058
- palette: {
2059
- primary: { main: lighten(WISTRON_PRIMARY_COLOR, 0.5) },
2060
- secondary: { main: darken(WISTRON_SECONDARY_COLOR, 0.5) }
2061
- }
2062
- },
2063
- ...theme?.colorSchemes
2064
- },
2065
- components: {
2066
- MuiCssBaseline: {
2067
- styleOverrides: (theme2) => {
2068
- return {
2069
- body: {
2070
- "&::-webkit-scrollbar, & *::-webkit-scrollbar": {
2071
- width: "0.7em",
2072
- height: "0.7em"
2073
- },
2074
- "&::-webkit-scrollbar-track, & *::-webkit-scrollbar-track": {
2075
- backgroundColor: theme2.palette.mode === "dark" ? grey[900] : grey[200],
2076
- borderRadius: "5px"
2077
- },
2078
- "&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
2079
- backgroundColor: theme2.palette.mode === "dark" ? grey[800] : grey[400],
2080
- borderRadius: "10px"
2081
- },
2082
- "&::-webkit-scrollbar-thumb:hover, & *::-webkit-scrollbar-thumb:hover": {
2083
- backgroundColor: theme2.palette.mode === "dark" ? grey[700] : grey[500]
2084
- },
2085
- "&::-webkit-scrollbar-corner, & *::-webkit-scrollbar-corner": {
2086
- backgroundColor: "transparent"
2087
- }
2088
- }
2089
- };
2090
- }
2091
- },
2092
- MuiTableContainer: {
2093
- styleOverrides: {
2094
- root: ({ theme: theme2 }) => ({
2095
- flexGrow: 1,
2096
- "& .MuiDataGrid-cell--editing": {
2097
- "& .MuiInputBase-root": {
2098
- height: "100%"
2099
- }
2100
- },
2101
- "& .MuiDataGrid-columnHeaderTitle": {
2102
- fontWeight: 600
2103
- },
2104
- "& .Mui-error": {
2105
- backgroundColor: theme2.palette.error.main,
2106
- color: theme2.palette.error.contrastText
2107
- },
2108
- "& .MuiDataGrid-booleanCell[data-value='true']": {
2109
- color: `${theme2.palette.success.main} !important`
2110
- },
2111
- "& .MuiDataGrid-booleanCell[data-value='false']": {
2112
- color: `${theme2.palette.error.main} !important`
2995
+ tab === "language" && language
2996
+ ] }) })
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, {})
2113
3035
  }
2114
- })
2115
- }
2116
- },
2117
- ...theme?.components
2118
- }
2119
- },
2120
- i18n2.resolvedLanguage === "cs" ? datePickersCsCz : datePickersEnUs,
2121
- i18n2.resolvedLanguage === "cs" ? dataGridCsCz : dataGridEnUs,
2122
- i18n2.resolvedLanguage === "cs" ? csCZ : enUS
2123
- );
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
+ ] });
2124
3050
  };
2125
3051
 
3052
+ // src/contexts/LayoutContext.ts
3053
+ import { createContext as createContext4, useContext as useContext4 } from "react";
3054
+ var LayoutContext = createContext4(null);
3055
+
2126
3056
  // src/utils/i18n.ts
2127
3057
  import i18n from "i18next";
2128
3058
  import LanguageDetector from "i18next-browser-languagedetector";
@@ -2139,85 +3069,91 @@ i18n.use(HttpBackend).use(LanguageDetector).use(initReactI18next).init({
2139
3069
  }
2140
3070
  });
2141
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
+
2142
3142
  // src/providers/LayoutProvider.tsx
2143
- import { jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
3143
+ import { jsx as jsx27 } from "react/jsx-runtime";
2144
3144
  var LayoutProvider = (props) => {
2145
- const rootRouterState = useRouterState({ select: (s) => s.matches[0] });
2146
- const theme = useGetTheme(props.theme);
2147
- const { t: t2 } = useTranslation5();
2148
- const isFetching = !!useIsFetching();
2149
- const isMutating = !!useIsMutating();
2150
- const isLargeScreen = useMediaQuery(theme.breakpoints.up("sm"));
2151
- 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();
2152
3147
  const navigation = props.getNavigation?.({ user, t: t2 });
2153
- const appTitle = rootRouterState.meta?.find((meta) => meta?.title)?.title;
2154
- if (!appTitle)
2155
- throw new Error("Title is not defined in the RootRoute head.");
2156
- return /* @__PURE__ */ jsx15(I18nextProvider, { i18n: default2, children: /* @__PURE__ */ jsx15(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: default2.resolvedLanguage, children: /* @__PURE__ */ jsx15(TanStackRouterAppProvider, { navigation, theme, localeText: {
2157
- confirm: t2("Layout.Dialog.Confirm"),
2158
- cancel: t2("Layout.Dialog.Cancel"),
2159
- alert: t2("Layout.Dialog.Alert")
2160
- }, 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(
2161
- DashboardLayout,
2162
- {
2163
- defaultSidebarCollapsed: props.defaultSidebarCollapsed ?? true,
2164
- disableCollapsibleSidebar: props.disableCollapsibleSidebar,
2165
- sidebarExpandedWidth: props.sidebarExpandedWidth,
2166
- hideNavigation: navigation?.length === 0,
2167
- slots: {
2168
- toolbarActions: () => null,
2169
- toolbarAccount: ToolbarAccount,
2170
- appTitle: AppTitle
2171
- },
2172
- children: [
2173
- props.children,
2174
- (isFetching || isMutating) && /* @__PURE__ */ jsx15(LinearProgress, { sx: { position: "fixed", top: { xs: 56, sm: 64 }, left: 0, right: 0 } })
2175
- ]
2176
- }
2177
- ) }) }) }) }) });
3148
+ useEffect6(() => {
3149
+ z.config(default2.resolvedLanguage === "cs" ? cs() : en());
3150
+ }, []);
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 }) }) }) }) });
2178
3152
  };
2179
3153
 
2180
3154
  // src/index.ts
2181
3155
  import { uuidv7 as uuidv72 } from "uuidv7";
2182
3156
 
2183
- // src/utils/ClientUtils.ts
2184
- import axios from "axios";
2185
- var Platform = class {
2186
- static get isAndroid() {
2187
- return /android/i.test(this.userAgent);
2188
- }
2189
- static get isIOS() {
2190
- return /iPad|iPhone|iPod/.test(this.userAgent);
2191
- }
2192
- static get isWindows() {
2193
- return /windows/i.test(this.userAgent);
2194
- }
2195
- static get isMacOS() {
2196
- return /Macintosh|MacIntel|MacPPC|Mac68K/.test(this.userAgent);
2197
- }
2198
- static get userAgent() {
2199
- return typeof navigator === "undefined" ? "" : navigator.userAgent;
2200
- }
2201
- };
2202
- var rootRouteHead = ({ title }) => () => ({
2203
- meta: [
2204
- { charSet: "utf-8" },
2205
- { name: "viewport", content: "width=device-width, initial-scale=1" },
2206
- { title },
2207
- { name: "og:type", content: "website" },
2208
- { name: "og:title", content: title },
2209
- { name: "og:image", content: "/favicon-32x32.png" }
2210
- ],
2211
- links: [
2212
- { rel: "apple-touch-icon", sizes: "180x180", href: "/apple-touch-icon.png" },
2213
- { rel: "icon", type: "image/png", sizes: "32x32", href: "/favicon-32x32.png" },
2214
- { rel: "icon", type: "image/png", sizes: "16x16", href: "/favicon-16x16.png" },
2215
- { rel: "manifest", href: "/site.webmanifest" },
2216
- { rel: "icon", href: "/favicon.ico" }
2217
- ]
2218
- });
2219
- var wczApiClient = axios.create();
2220
-
2221
3157
  // src/hooks/FormHooks.ts
2222
3158
  import { createFormHook, createFormHookContexts } from "@tanstack/react-form";
2223
3159
 
@@ -2234,11 +3170,11 @@ var getFieldStatus = (field) => {
2234
3170
  };
2235
3171
 
2236
3172
  // src/components/form/FormAutocomplete.tsx
2237
- import { jsx as jsx16 } from "react/jsx-runtime";
3173
+ import { jsx as jsx28 } from "react/jsx-runtime";
2238
3174
  var FormAutocomplete = ({ textFieldProps, ...autocompleteProps }) => {
2239
3175
  const field = useFieldContext();
2240
3176
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2241
- return /* @__PURE__ */ jsx16(
3177
+ return /* @__PURE__ */ jsx28(
2242
3178
  Autocomplete,
2243
3179
  {
2244
3180
  value: field.state.value,
@@ -2247,7 +3183,7 @@ var FormAutocomplete = ({ textFieldProps, ...autocompleteProps }) => {
2247
3183
  onBlur: field.handleBlur,
2248
3184
  "aria-label": field.name,
2249
3185
  ...autocompleteProps,
2250
- renderInput: (parameters) => /* @__PURE__ */ jsx16(
3186
+ renderInput: (parameters) => /* @__PURE__ */ jsx28(
2251
3187
  TextField,
2252
3188
  {
2253
3189
  ...parameters,
@@ -2263,15 +3199,15 @@ var FormAutocomplete = ({ textFieldProps, ...autocompleteProps }) => {
2263
3199
 
2264
3200
  // src/components/form/FormCheckbox.tsx
2265
3201
  import { Checkbox, FormControl, FormControlLabel, FormHelperText } from "@mui/material";
2266
- import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
3202
+ import { jsx as jsx29, jsxs as jsxs16 } from "react/jsx-runtime";
2267
3203
  var FormCheckbox = (props) => {
2268
3204
  const field = useFieldContext();
2269
3205
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2270
- return /* @__PURE__ */ jsxs8(FormControl, { component: "fieldset", children: [
2271
- /* @__PURE__ */ jsx17(
3206
+ return /* @__PURE__ */ jsxs16(FormControl, { component: "fieldset", children: [
3207
+ /* @__PURE__ */ jsx29(
2272
3208
  FormControlLabel,
2273
3209
  {
2274
- control: /* @__PURE__ */ jsx17(
3210
+ control: /* @__PURE__ */ jsx29(
2275
3211
  Checkbox,
2276
3212
  {
2277
3213
  name: field.name,
@@ -2285,18 +3221,18 @@ var FormCheckbox = (props) => {
2285
3221
  label: props.label ?? ""
2286
3222
  }
2287
3223
  ),
2288
- isTouched && hasError && /* @__PURE__ */ jsx17(FormHelperText, { error: hasError, children: helperText })
3224
+ isTouched && hasError && /* @__PURE__ */ jsx29(FormHelperText, { error: hasError, children: helperText })
2289
3225
  ] });
2290
3226
  };
2291
3227
 
2292
3228
  // src/components/form/FormDatePicker.tsx
2293
3229
  import { DatePicker } from "@mui/x-date-pickers-pro";
2294
3230
  import dayjs2 from "dayjs";
2295
- import { jsx as jsx18 } from "react/jsx-runtime";
3231
+ import { jsx as jsx30 } from "react/jsx-runtime";
2296
3232
  var FormDatePicker = (props) => {
2297
3233
  const field = useFieldContext();
2298
3234
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2299
- return /* @__PURE__ */ jsx18(
3235
+ return /* @__PURE__ */ jsx30(
2300
3236
  DatePicker,
2301
3237
  {
2302
3238
  name: field.name,
@@ -2320,11 +3256,11 @@ var FormDatePicker = (props) => {
2320
3256
  // src/components/form/FormDateTimePicker.tsx
2321
3257
  import { DateTimePicker } from "@mui/x-date-pickers-pro";
2322
3258
  import dayjs3 from "dayjs";
2323
- import { jsx as jsx19 } from "react/jsx-runtime";
3259
+ import { jsx as jsx31 } from "react/jsx-runtime";
2324
3260
  var FormDateTimePicker = (props) => {
2325
3261
  const field = useFieldContext();
2326
3262
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2327
- return /* @__PURE__ */ jsx19(
3263
+ return /* @__PURE__ */ jsx31(
2328
3264
  DateTimePicker,
2329
3265
  {
2330
3266
  name: field.name,
@@ -2348,11 +3284,11 @@ var FormDateTimePicker = (props) => {
2348
3284
  // src/components/form/FormNumberField.tsx
2349
3285
  import { TextField as TextField2 } from "@mui/material";
2350
3286
  import { NumericFormat } from "react-number-format";
2351
- import { jsx as jsx20 } from "react/jsx-runtime";
3287
+ import { jsx as jsx32 } from "react/jsx-runtime";
2352
3288
  var FormNumberField = ({ options, ...props }) => {
2353
3289
  const field = useFieldContext();
2354
3290
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2355
- return /* @__PURE__ */ jsx20(
3291
+ return /* @__PURE__ */ jsx32(
2356
3292
  NumericFormat,
2357
3293
  {
2358
3294
  customInput: TextField2,
@@ -2371,13 +3307,13 @@ var FormNumberField = ({ options, ...props }) => {
2371
3307
 
2372
3308
  // src/components/form/FormRadioGroup.tsx
2373
3309
  import { FormControl as FormControl2, FormControlLabel as FormControlLabel2, FormHelperText as FormHelperText2, FormLabel, Radio, RadioGroup } from "@mui/material";
2374
- import { jsx as jsx21, jsxs as jsxs9 } from "react/jsx-runtime";
3310
+ import { jsx as jsx33, jsxs as jsxs17 } from "react/jsx-runtime";
2375
3311
  var FormRadioGroup = ({ label, options, ...props }) => {
2376
3312
  const field = useFieldContext();
2377
3313
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2378
- return /* @__PURE__ */ jsxs9(FormControl2, { component: "fieldset", children: [
2379
- label && /* @__PURE__ */ jsx21(FormLabel, { component: "legend", children: label }),
2380
- /* @__PURE__ */ jsx21(
3314
+ return /* @__PURE__ */ jsxs17(FormControl2, { component: "fieldset", children: [
3315
+ label && /* @__PURE__ */ jsx33(FormLabel, { component: "legend", children: label }),
3316
+ /* @__PURE__ */ jsx33(
2381
3317
  RadioGroup,
2382
3318
  {
2383
3319
  name: field.name,
@@ -2386,30 +3322,30 @@ var FormRadioGroup = ({ label, options, ...props }) => {
2386
3322
  onBlur: field.handleBlur,
2387
3323
  "aria-label": field.name,
2388
3324
  ...props,
2389
- children: options.map((option) => /* @__PURE__ */ jsx21(
3325
+ children: options.map((option) => /* @__PURE__ */ jsx33(
2390
3326
  FormControlLabel2,
2391
3327
  {
2392
3328
  value: option.value,
2393
- control: /* @__PURE__ */ jsx21(Radio, {}),
3329
+ control: /* @__PURE__ */ jsx33(Radio, {}),
2394
3330
  label: option.label
2395
3331
  },
2396
3332
  option.value
2397
3333
  ))
2398
3334
  }
2399
3335
  ),
2400
- isTouched && hasError && /* @__PURE__ */ jsx21(FormHelperText2, { error: hasError, children: helperText })
3336
+ isTouched && hasError && /* @__PURE__ */ jsx33(FormHelperText2, { error: hasError, children: helperText })
2401
3337
  ] });
2402
3338
  };
2403
3339
 
2404
3340
  // src/components/form/FormSlider.tsx
2405
3341
  import { FormControl as FormControl3, FormHelperText as FormHelperText3, FormLabel as FormLabel2, Slider } from "@mui/material";
2406
- import { jsx as jsx22, jsxs as jsxs10 } from "react/jsx-runtime";
3342
+ import { jsx as jsx34, jsxs as jsxs18 } from "react/jsx-runtime";
2407
3343
  var FormSlider = ({ label, ...props }) => {
2408
3344
  const field = useFieldContext();
2409
3345
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2410
- return /* @__PURE__ */ jsxs10(FormControl3, { component: "fieldset", children: [
2411
- label && /* @__PURE__ */ jsx22(FormLabel2, { children: label }),
2412
- /* @__PURE__ */ jsx22(
3346
+ return /* @__PURE__ */ jsxs18(FormControl3, { component: "fieldset", children: [
3347
+ label && /* @__PURE__ */ jsx34(FormLabel2, { children: label }),
3348
+ /* @__PURE__ */ jsx34(
2413
3349
  Slider,
2414
3350
  {
2415
3351
  name: field.name,
@@ -2420,13 +3356,13 @@ var FormSlider = ({ label, ...props }) => {
2420
3356
  ...props
2421
3357
  }
2422
3358
  ),
2423
- isTouched && hasError && /* @__PURE__ */ jsx22(FormHelperText3, { error: hasError, children: helperText })
3359
+ isTouched && hasError && /* @__PURE__ */ jsx34(FormHelperText3, { error: hasError, children: helperText })
2424
3360
  ] });
2425
3361
  };
2426
3362
 
2427
3363
  // src/components/form/FormSubmitButton.tsx
2428
- import { Button as Button2 } from "@mui/material";
2429
- 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";
2430
3366
  var FormSubmitButton = (props) => {
2431
3367
  const form = useFormContext();
2432
3368
  const handleClick = (event) => {
@@ -2434,8 +3370,8 @@ var FormSubmitButton = (props) => {
2434
3370
  event.stopPropagation();
2435
3371
  form.handleSubmit();
2436
3372
  };
2437
- return /* @__PURE__ */ jsx23(form.Subscribe, { selector: (state) => [state.canSubmit, state.isSubmitting], children: ([canSubmit, isSubmitting]) => /* @__PURE__ */ jsx23(
2438
- Button2,
3373
+ return /* @__PURE__ */ jsx35(form.Subscribe, { selector: (state) => [state.canSubmit, state.isSubmitting], children: ([canSubmit, isSubmitting]) => /* @__PURE__ */ jsx35(
3374
+ Button3,
2439
3375
  {
2440
3376
  loading: isSubmitting,
2441
3377
  disabled: !canSubmit,
@@ -2449,15 +3385,15 @@ var FormSubmitButton = (props) => {
2449
3385
 
2450
3386
  // src/components/form/FormSwitch.tsx
2451
3387
  import { FormControl as FormControl4, FormControlLabel as FormControlLabel3, FormHelperText as FormHelperText4, Switch } from "@mui/material";
2452
- import { jsx as jsx24, jsxs as jsxs11 } from "react/jsx-runtime";
3388
+ import { jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
2453
3389
  var FormSwitch = (props) => {
2454
3390
  const field = useFieldContext();
2455
3391
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2456
- return /* @__PURE__ */ jsxs11(FormControl4, { component: "fieldset", children: [
2457
- /* @__PURE__ */ jsx24(
3392
+ return /* @__PURE__ */ jsxs19(FormControl4, { component: "fieldset", children: [
3393
+ /* @__PURE__ */ jsx36(
2458
3394
  FormControlLabel3,
2459
3395
  {
2460
- control: /* @__PURE__ */ jsx24(
3396
+ control: /* @__PURE__ */ jsx36(
2461
3397
  Switch,
2462
3398
  {
2463
3399
  name: field.name,
@@ -2471,17 +3407,17 @@ var FormSwitch = (props) => {
2471
3407
  label: props.label ?? ""
2472
3408
  }
2473
3409
  ),
2474
- isTouched && hasError && /* @__PURE__ */ jsx24(FormHelperText4, { error: hasError, children: helperText })
3410
+ isTouched && hasError && /* @__PURE__ */ jsx36(FormHelperText4, { error: hasError, children: helperText })
2475
3411
  ] });
2476
3412
  };
2477
3413
 
2478
3414
  // src/components/form/FormTextField.tsx
2479
3415
  import { TextField as TextField3 } from "@mui/material";
2480
- import { jsx as jsx25 } from "react/jsx-runtime";
3416
+ import { jsx as jsx37 } from "react/jsx-runtime";
2481
3417
  var FormTextField = (props) => {
2482
3418
  const field = useFieldContext();
2483
3419
  const { isTouched, hasError, helperText } = getFieldStatus(field);
2484
- return /* @__PURE__ */ jsx25(
3420
+ return /* @__PURE__ */ jsx37(
2485
3421
  TextField3,
2486
3422
  {
2487
3423
  name: field.name,
@@ -2518,222 +3454,15 @@ var { useAppForm: useLayoutForm, withForm: withLayoutForm } = createFormHook({
2518
3454
  });
2519
3455
 
2520
3456
  // src/index.ts
2521
- import { useDialogs } from "@toolpad/core/useDialogs";
2522
- import { useNotifications } from "@toolpad/core/useNotifications";
2523
- import { useLocalStorageState } from "@toolpad/core/useLocalStorageState";
2524
- 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";
2525
3459
  import { t } from "i18next";
2526
-
2527
- // src/hooks/FileHooks.ts
2528
- import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
2529
- import saveAs from "file-saver";
2530
- import { useState as useState3 } from "react";
2531
- import { Upload as TusUpload } from "tus-js-client";
2532
- import { uuidv7 } from "uuidv7";
2533
- var BASE_URL = import.meta.env.VITE_FILE_API_BASE_URL;
2534
- var QUERY_KEY = "Files";
2535
- var HOUR = 1e3 * 60 * 60;
2536
- var useGetFileMetas = (subId, options) => {
2537
- const { appTitle } = useLayout();
2538
- return useQuery({
2539
- ...options,
2540
- queryKey: [QUERY_KEY, "meta", subId, appTitle],
2541
- queryFn: ({ signal }) => wczApiClient.request({
2542
- url: `${BASE_URL}/v1/meta?appName=${appTitle}&subId=${subId}`,
2543
- method: "GET",
2544
- signal
2545
- }),
2546
- initialData: [],
2547
- refetchOnWindowFocus: false
2548
- });
2549
- };
2550
- var useGetFileThumbnail = (meta, options) => {
2551
- const { appTitle } = useLayout();
2552
- return useQuery({
2553
- ...options,
2554
- queryKey: [QUERY_KEY, "thumbnail", meta?.id, appTitle],
2555
- queryFn: ({ signal }) => wczApiClient.request({
2556
- url: `${BASE_URL}/v1/thumbnail?appName=${appTitle}&id=${meta?.id}`,
2557
- method: "GET",
2558
- signal,
2559
- responseType: "blob"
2560
- }),
2561
- select: (data) => URL.createObjectURL(data),
2562
- staleTime: HOUR,
2563
- gcTime: HOUR,
2564
- refetchOnWindowFocus: false,
2565
- enabled: !!meta?.id && options?.enabled
2566
- });
2567
- };
2568
- var useGetFile = (meta, options) => {
2569
- const { appTitle } = useLayout();
2570
- return useQuery({
2571
- ...options,
2572
- queryKey: [QUERY_KEY, meta?.id, appTitle],
2573
- queryFn: ({ signal }) => wczApiClient.request({
2574
- url: `${BASE_URL}/v1?appName=${appTitle}&id=${meta?.id}`,
2575
- method: "GET",
2576
- signal,
2577
- responseType: "blob"
2578
- }),
2579
- select: (data) => URL.createObjectURL(data),
2580
- staleTime: HOUR,
2581
- gcTime: HOUR,
2582
- refetchOnWindowFocus: false,
2583
- enabled: !!meta?.id && options?.enabled
2584
- });
2585
- };
2586
- var useDownloadFile = (options) => {
2587
- const { appTitle } = useLayout();
2588
- return useMutation({
2589
- ...options,
2590
- mutationFn: (meta) => wczApiClient.request({
2591
- url: `${BASE_URL}/v1/download?appName=${appTitle}&id=${meta.id}`,
2592
- method: "GET",
2593
- responseType: "blob"
2594
- }),
2595
- onSuccess: (data, variables) => saveAs(data, `${variables.fileName}.${variables.fileExtension}`)
2596
- });
2597
- };
2598
- var useOpenFile = (options) => {
2599
- const { appTitle } = useLayout();
2600
- return useMutation({
2601
- ...options,
2602
- mutationFn: (meta) => wczApiClient.request({
2603
- url: `${BASE_URL}/v1?appName=${appTitle}&id=${meta.id}`,
2604
- method: "GET",
2605
- responseType: "blob"
2606
- }),
2607
- onSuccess: (data) => {
2608
- window.open(URL.createObjectURL(data));
2609
- }
2610
- });
2611
- };
2612
- var useUpdateFileMeta = (options) => {
2613
- const { appTitle } = useLayout();
2614
- const queryClient = useQueryClient();
2615
- return useMutation({
2616
- ...options,
2617
- mutationFn: (meta) => wczApiClient.request({
2618
- url: `${BASE_URL}/v1/meta?appName=${appTitle}&id=${meta.id}`,
2619
- method: "PUT",
2620
- data: meta
2621
- }),
2622
- onSettled: () => queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false })
2623
- });
2624
- };
2625
- var useDeleteFile = (options) => {
2626
- const { appTitle } = useLayout();
2627
- const queryClient = useQueryClient();
2628
- return useMutation({
2629
- ...options,
2630
- mutationFn: (meta) => wczApiClient.request({
2631
- url: `${BASE_URL}/v1?appName=${appTitle}&id=${meta.id}`,
2632
- method: "DELETE"
2633
- }),
2634
- onSettled: () => queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false })
2635
- });
2636
- };
2637
- var useDeleteFiles = (options) => {
2638
- const { appTitle } = useLayout();
2639
- const queryClient = useQueryClient();
2640
- return useMutation({
2641
- ...options,
2642
- mutationFn: (subId) => wczApiClient.request({
2643
- url: `${BASE_URL}/v1?appName=${appTitle}&subId=${subId}`,
2644
- method: "DELETE"
2645
- }),
2646
- onSettled: () => queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false })
2647
- });
2648
- };
2649
- var useUploadFile = ({ subId, onSuccess, onError }) => {
2650
- const { appTitle } = useLayout();
2651
- const [progress, setProgress] = useState3(0);
2652
- const queryClient = useQueryClient();
2653
- const mutate = async (file) => {
2654
- if (!subId) throw new Error("subId is required for file upload");
2655
- const metadata = {
2656
- id: uuidv7(),
2657
- appName: appTitle,
2658
- subId,
2659
- fileName: file.name
2660
- };
2661
- const upload = new TusUpload(file, {
2662
- endpoint: `${BASE_URL}/v1/upload`,
2663
- chunkSize: 1048576,
2664
- // 1 MB
2665
- metadata: {
2666
- id: metadata.id,
2667
- appName: metadata.appName,
2668
- subId: metadata.subId,
2669
- fileName: metadata.fileName,
2670
- fileExtension: file.type
2671
- },
2672
- //headers: { "Authorization": `Bearer ${await getToken()}` }, //TODO: implement token retrieval
2673
- onError: (error) => {
2674
- setProgress(0);
2675
- onError?.(error);
2676
- },
2677
- onProgress: (bytesUploaded, bytesTotal) => {
2678
- setProgress(bytesUploaded / bytesTotal * 100);
2679
- },
2680
- onSuccess: () => {
2681
- setProgress(0);
2682
- queryClient.invalidateQueries({ queryKey: [QUERY_KEY, "meta"], exact: false });
2683
- onSuccess?.(metadata);
2684
- }
2685
- });
2686
- const previousUploads = await upload.findPreviousUploads();
2687
- if (previousUploads.length > 0) {
2688
- upload.resumeFromPreviousUpload(previousUploads[0]);
2689
- }
2690
- upload.start();
2691
- };
2692
- return { mutate, progress };
2693
- };
2694
- function useOptimisticFileMutation(subId, options) {
2695
- const [uploadedFileIds, setUploadedFileIds] = useState3([]);
2696
- const [deletedFileIds, setDeletedFileIds] = useState3([]);
2697
- const { data } = useGetFileMetas(subId, options);
2698
- const { mutate: deleteAttachment } = useDeleteFile();
2699
- function addFile(meta) {
2700
- setUploadedFileIds((previous) => [...previous, meta.id]);
2701
- }
2702
- function removeFile(meta) {
2703
- const added = uploadedFileIds.includes(meta.id);
2704
- if (added) {
2705
- setUploadedFileIds((previous) => previous.filter((file) => file !== meta.id));
2706
- } else {
2707
- setDeletedFileIds((previous) => [...previous, meta.id]);
2708
- }
2709
- }
2710
- function save() {
2711
- for (const id of deletedFileIds) {
2712
- const meta = data.find((meta2) => meta2.id === id);
2713
- if (!meta) continue;
2714
- deleteAttachment(meta);
2715
- }
2716
- }
2717
- function undo() {
2718
- for (const id of uploadedFileIds) {
2719
- const meta = data.find((meta2) => meta2.id === id);
2720
- if (!meta) continue;
2721
- deleteAttachment(meta);
2722
- }
2723
- }
2724
- return {
2725
- addFile,
2726
- removeFile,
2727
- save,
2728
- undo
2729
- };
2730
- }
2731
3460
  export {
2732
3461
  ChipInputCell,
2733
3462
  Dropzone,
2734
3463
  EditableColumnHeader,
3464
+ FileViewer,
2735
3465
  LayoutProvider,
2736
- PageContainer,
2737
3466
  PageHeader,
2738
3467
  Platform,
2739
3468
  RouterButton,
@@ -2743,6 +3472,7 @@ export {
2743
3472
  RouterLink,
2744
3473
  RouterNotFound,
2745
3474
  RouterTab,
3475
+ TableContainer,
2746
3476
  TypographyWithIcon,
2747
3477
  rootRouteHead,
2748
3478
  t,
@@ -2756,11 +3486,9 @@ export {
2756
3486
  useGetFileMetas,
2757
3487
  useGetFileThumbnail,
2758
3488
  useLayoutForm,
2759
- useLocalStorageState,
2760
- useNotifications,
3489
+ default3 as useLocalStorageState,
2761
3490
  useOpenFile,
2762
- useOptimisticFileMutation,
2763
- useTranslation6 as useTranslation,
3491
+ useTranslation8 as useTranslation,
2764
3492
  useUpdateFileMeta,
2765
3493
  useUploadFile,
2766
3494
  uuidv72 as uuidv7,