wcz-layout 6.7.2 → 8.3.2

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.
Files changed (269) hide show
  1. package/dist/Approval-BTJTexDo.js +143 -0
  2. package/dist/Approval-BTJTexDo.js.map +1 -0
  3. package/dist/DialogsContext-DLqA8RJ_.js +7 -0
  4. package/dist/DialogsContext-DLqA8RJ_.js.map +1 -0
  5. package/dist/Email-C9qwj7GD.js +20 -0
  6. package/dist/Email-C9qwj7GD.js.map +1 -0
  7. package/dist/FileMeta-DDqUju1Y.js +19 -0
  8. package/dist/FileMeta-DDqUju1Y.js.map +1 -0
  9. package/dist/FileMeta-ILLTOjaM.d.ts +20 -0
  10. package/dist/NotificationContext-CgwUOeW0.js +7 -0
  11. package/dist/NotificationContext-CgwUOeW0.js.map +1 -0
  12. package/dist/RouterListItemButton-owZVvuC_.js +78 -0
  13. package/dist/RouterListItemButton-owZVvuC_.js.map +1 -0
  14. package/dist/User-CT_IDGuG.d.ts +15 -0
  15. package/dist/apiMiddleware-CtY4rOFU.js +23 -0
  16. package/dist/apiMiddleware-CtY4rOFU.js.map +1 -0
  17. package/dist/components.d.ts +118 -0
  18. package/dist/components.js +1554 -0
  19. package/dist/components.js.map +1 -0
  20. package/dist/data/client.d.ts +3111 -0
  21. package/dist/data/client.js +188 -0
  22. package/dist/data/client.js.map +1 -0
  23. package/dist/data/server.d.ts +19 -0
  24. package/dist/data/server.js +16 -0
  25. package/dist/data/server.js.map +1 -0
  26. package/dist/data.d.ts +7 -0
  27. package/dist/data.js +2 -0
  28. package/dist/env-ON-cyE3N.js +31 -0
  29. package/dist/env-ON-cyE3N.js.map +1 -0
  30. package/dist/file-BUdLb7H1.js +148 -0
  31. package/dist/file-BUdLb7H1.js.map +1 -0
  32. package/dist/file-Dsht7yOP.js +100 -0
  33. package/dist/file-Dsht7yOP.js.map +1 -0
  34. package/dist/hooks.d.ts +226 -0
  35. package/dist/hooks.js +1180 -0
  36. package/dist/hooks.js.map +1 -0
  37. package/dist/index.d.ts +50 -0
  38. package/dist/index.js +2106 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/middleware.d.ts +47 -0
  41. package/dist/middleware.js +80 -0
  42. package/dist/middleware.js.map +1 -0
  43. package/dist/models.d.ts +474 -0
  44. package/dist/models.js +74 -0
  45. package/dist/models.js.map +1 -0
  46. package/dist/msalClient-CYiQAFnY.d.ts +15 -0
  47. package/dist/msalServer-B9sVqpQ2.js +47 -0
  48. package/dist/msalServer-B9sVqpQ2.js.map +1 -0
  49. package/dist/peoplesoft-BCjRje6b.js +240 -0
  50. package/dist/peoplesoft-BCjRje6b.js.map +1 -0
  51. package/dist/peoplesoft-Cze2ngGd.d.ts +1150 -0
  52. package/dist/queryClient-D64McLhZ.js +7 -0
  53. package/dist/queryClient-D64McLhZ.js.map +1 -0
  54. package/dist/useDialogs-BJVhBr8S.js +248 -0
  55. package/dist/useDialogs-BJVhBr8S.js.map +1 -0
  56. package/dist/utils-BMUmv2ws.js +191 -0
  57. package/dist/utils-BMUmv2ws.js.map +1 -0
  58. package/dist/utils-CvvyM8Xw.d.ts +56 -0
  59. package/dist/utils.d.ts +21 -0
  60. package/dist/utils.js +6 -0
  61. package/dist/vite.d.ts +7 -0
  62. package/dist/vite.js +147 -0
  63. package/dist/vite.js.map +1 -0
  64. package/package.json +158 -62
  65. package/skills/client-db/SKILL.md +107 -0
  66. package/skills/data-grid/SKILL.md +147 -0
  67. package/skills/db-schema/SKILL.md +68 -0
  68. package/skills/dialogs/SKILL.md +79 -0
  69. package/skills/forms/SKILL.md +82 -0
  70. package/skills/general/SKILL.md +17 -0
  71. package/skills/notifications/SKILL.md +43 -0
  72. package/skills/routing/SKILL.md +123 -0
  73. package/skills/server-functions/SKILL.md +109 -0
  74. package/skills/services/SKILL.md +28 -0
  75. package/skills/services/docs/approval.md +204 -0
  76. package/skills/services/docs/email.md +32 -0
  77. package/skills/services/docs/file.md +85 -0
  78. package/skills/services/docs/peoplesoft.md +110 -0
  79. package/skills/start/SKILL.md +46 -0
  80. package/skills/start/steps/01-git-setup.md +10 -0
  81. package/skills/start/steps/02-project-name-setup.md +14 -0
  82. package/skills/start/steps/03-apm-setup.md +208 -0
  83. package/skills/start/steps/04-database-setup.md +37 -0
  84. package/skills/start/steps/05-entra-setup.md +59 -0
  85. package/skills/start/steps/06-vault-setup.md +53 -0
  86. package/skills/start/steps/07-generate-favicon.md +10 -0
  87. package/skills/start/steps/08-commit.md +15 -0
  88. package/dist/src/components/Layout.d.ts +0 -16
  89. package/dist/src/components/Layout.js +0 -122
  90. package/dist/src/components/Layout.js.map +0 -1
  91. package/dist/src/components/dataGrid/ChipInputCell.d.ts +0 -9
  92. package/dist/src/components/dataGrid/ChipInputCell.js +0 -17
  93. package/dist/src/components/dataGrid/ChipInputCell.js.map +0 -1
  94. package/dist/src/components/dataGrid/EditableColumnHeader.d.ts +0 -2
  95. package/dist/src/components/dataGrid/EditableColumnHeader.js +0 -7
  96. package/dist/src/components/dataGrid/EditableColumnHeader.js.map +0 -1
  97. package/dist/src/components/dataGrid/GridToolbar.d.ts +0 -8
  98. package/dist/src/components/dataGrid/GridToolbar.js +0 -40
  99. package/dist/src/components/dataGrid/GridToolbar.js.map +0 -1
  100. package/dist/src/components/dataGrid/TableContainer.d.ts +0 -3
  101. package/dist/src/components/dataGrid/TableContainer.js +0 -32
  102. package/dist/src/components/dataGrid/TableContainer.js.map +0 -1
  103. package/dist/src/components/form/FormAutocomplete.d.ts +0 -7
  104. package/dist/src/components/form/FormAutocomplete.js +0 -10
  105. package/dist/src/components/form/FormAutocomplete.js.map +0 -1
  106. package/dist/src/components/form/FormCheckbox.d.ts +0 -7
  107. package/dist/src/components/form/FormCheckbox.js +0 -11
  108. package/dist/src/components/form/FormCheckbox.js.map +0 -1
  109. package/dist/src/components/form/FormDatePicker.d.ts +0 -9
  110. package/dist/src/components/form/FormDatePicker.js +0 -19
  111. package/dist/src/components/form/FormDatePicker.js.map +0 -1
  112. package/dist/src/components/form/FormDateTimePicker.d.ts +0 -9
  113. package/dist/src/components/form/FormDateTimePicker.js +0 -19
  114. package/dist/src/components/form/FormDateTimePicker.js.map +0 -1
  115. package/dist/src/components/form/FormNumberField.d.ts +0 -12
  116. package/dist/src/components/form/FormNumberField.js +0 -12
  117. package/dist/src/components/form/FormNumberField.js.map +0 -1
  118. package/dist/src/components/form/FormRadioGroup.d.ts +0 -13
  119. package/dist/src/components/form/FormRadioGroup.js +0 -11
  120. package/dist/src/components/form/FormRadioGroup.js.map +0 -1
  121. package/dist/src/components/form/FormSlider.d.ts +0 -7
  122. package/dist/src/components/form/FormSlider.js +0 -11
  123. package/dist/src/components/form/FormSlider.js.map +0 -1
  124. package/dist/src/components/form/FormSubmitButton.d.ts +0 -5
  125. package/dist/src/components/form/FormSubmitButton.js +0 -13
  126. package/dist/src/components/form/FormSubmitButton.js.map +0 -1
  127. package/dist/src/components/form/FormSwitch.d.ts +0 -7
  128. package/dist/src/components/form/FormSwitch.js +0 -11
  129. package/dist/src/components/form/FormSwitch.js.map +0 -1
  130. package/dist/src/components/form/FormTextField.d.ts +0 -7
  131. package/dist/src/components/form/FormTextField.js +0 -11
  132. package/dist/src/components/form/FormTextField.js.map +0 -1
  133. package/dist/src/components/layout/AccountMenu.d.ts +0 -9
  134. package/dist/src/components/layout/AccountMenu.js +0 -44
  135. package/dist/src/components/layout/AccountMenu.js.map +0 -1
  136. package/dist/src/components/layout/DevelopmentBanner.d.ts +0 -7
  137. package/dist/src/components/layout/DevelopmentBanner.js +0 -29
  138. package/dist/src/components/layout/DevelopmentBanner.js.map +0 -1
  139. package/dist/src/components/layout/ErrorPage.d.ts +0 -2
  140. package/dist/src/components/layout/ErrorPage.js +0 -25
  141. package/dist/src/components/layout/ErrorPage.js.map +0 -1
  142. package/dist/src/components/layout/LayoutDialog.d.ts +0 -12
  143. package/dist/src/components/layout/LayoutDialog.js +0 -12
  144. package/dist/src/components/layout/LayoutDialog.js.map +0 -1
  145. package/dist/src/components/layout/LayoutSnackbar.d.ts +0 -8
  146. package/dist/src/components/layout/LayoutSnackbar.js +0 -25
  147. package/dist/src/components/layout/LayoutSnackbar.js.map +0 -1
  148. package/dist/src/components/layout/NavigationDrawer.d.ts +0 -11
  149. package/dist/src/components/layout/NavigationDrawer.js +0 -70
  150. package/dist/src/components/layout/NavigationDrawer.js.map +0 -1
  151. package/dist/src/components/layout/NotificationMenu.d.ts +0 -8
  152. package/dist/src/components/layout/NotificationMenu.js +0 -26
  153. package/dist/src/components/layout/NotificationMenu.js.map +0 -1
  154. package/dist/src/components/layout/TypographyWithIcon.d.ts +0 -7
  155. package/dist/src/components/layout/TypographyWithIcon.js +0 -22
  156. package/dist/src/components/layout/TypographyWithIcon.js.map +0 -1
  157. package/dist/src/components/layout/Unauthorized.d.ts +0 -2
  158. package/dist/src/components/layout/Unauthorized.js +0 -26
  159. package/dist/src/components/layout/Unauthorized.js.map +0 -1
  160. package/dist/src/contexts/LayoutContext.d.ts +0 -40
  161. package/dist/src/contexts/LayoutContext.js +0 -60
  162. package/dist/src/contexts/LayoutContext.js.map +0 -1
  163. package/dist/src/contexts/UserContext.d.ts +0 -24
  164. package/dist/src/contexts/UserContext.js +0 -55
  165. package/dist/src/contexts/UserContext.js.map +0 -1
  166. package/dist/src/hooks/FormHooks.d.ts +0 -46
  167. package/dist/src/hooks/FormHooks.js +0 -31
  168. package/dist/src/hooks/FormHooks.js.map +0 -1
  169. package/dist/src/hooks/UseSnackbar.d.ts +0 -10
  170. package/dist/src/hooks/UseSnackbar.js +0 -23
  171. package/dist/src/hooks/UseSnackbar.js.map +0 -1
  172. package/dist/src/hooks/UseUser.d.ts +0 -10
  173. package/dist/src/hooks/UseUser.js +0 -25
  174. package/dist/src/hooks/UseUser.js.map +0 -1
  175. package/dist/src/index.d.ts +0 -20
  176. package/dist/src/index.js +0 -15
  177. package/dist/src/index.js.map +0 -1
  178. package/dist/src/models/Error.d.ts +0 -6
  179. package/dist/src/models/Error.js +0 -2
  180. package/dist/src/models/Error.js.map +0 -1
  181. package/dist/src/models/KeycloakSettings.d.ts +0 -8
  182. package/dist/src/models/KeycloakSettings.js +0 -2
  183. package/dist/src/models/KeycloakSettings.js.map +0 -1
  184. package/dist/src/models/LayoutPaletteColorOptions.d.ts +0 -6
  185. package/dist/src/models/LayoutPaletteColorOptions.js +0 -2
  186. package/dist/src/models/LayoutPaletteColorOptions.js.map +0 -1
  187. package/dist/src/models/LayoutRoute.d.ts +0 -14
  188. package/dist/src/models/LayoutRoute.js +0 -2
  189. package/dist/src/models/LayoutRoute.js.map +0 -1
  190. package/dist/src/models/Notification.d.ts +0 -9
  191. package/dist/src/models/Notification.js +0 -2
  192. package/dist/src/models/Notification.js.map +0 -1
  193. package/dist/src/models/PeoplesoftDepartment.d.ts +0 -14
  194. package/dist/src/models/PeoplesoftDepartment.js +0 -2
  195. package/dist/src/models/PeoplesoftDepartment.js.map +0 -1
  196. package/dist/src/models/PeoplesoftEmployee.d.ts +0 -34
  197. package/dist/src/models/PeoplesoftEmployee.js +0 -2
  198. package/dist/src/models/PeoplesoftEmployee.js.map +0 -1
  199. package/dist/src/models/Snackbar.d.ts +0 -15
  200. package/dist/src/models/Snackbar.js +0 -2
  201. package/dist/src/models/Snackbar.js.map +0 -1
  202. package/dist/src/models/User.d.ts +0 -27
  203. package/dist/src/models/User.js +0 -11
  204. package/dist/src/models/User.js.map +0 -1
  205. package/dist/src/models/types/EmployeeCategoryGroup.d.ts +0 -1
  206. package/dist/src/models/types/EmployeeCategoryGroup.js +0 -2
  207. package/dist/src/models/types/EmployeeCategoryGroup.js.map +0 -1
  208. package/dist/src/models/types/EmployeeStatus.d.ts +0 -1
  209. package/dist/src/models/types/EmployeeStatus.js +0 -2
  210. package/dist/src/models/types/EmployeeStatus.js.map +0 -1
  211. package/dist/src/utils/Auth.d.ts +0 -12
  212. package/dist/src/utils/Auth.js +0 -49
  213. package/dist/src/utils/Auth.js.map +0 -1
  214. package/dist/src/utils/Fetches.d.ts +0 -5
  215. package/dist/src/utils/Fetches.js +0 -66
  216. package/dist/src/utils/Fetches.js.map +0 -1
  217. package/dist/src/utils/FormUtils.d.ts +0 -7
  218. package/dist/src/utils/FormUtils.js +0 -9
  219. package/dist/src/utils/FormUtils.js.map +0 -1
  220. package/dist/src/utils/Helpers.d.ts +0 -11
  221. package/dist/src/utils/Helpers.js +0 -26
  222. package/dist/src/utils/Helpers.js.map +0 -1
  223. package/dist/tsconfig.tsbuildinfo +0 -1
  224. package/src/components/Layout.tsx +0 -183
  225. package/src/components/dataGrid/ChipInputCell.tsx +0 -31
  226. package/src/components/dataGrid/EditableColumnHeader.tsx +0 -7
  227. package/src/components/dataGrid/GridToolbar.tsx +0 -63
  228. package/src/components/dataGrid/TableContainer.tsx +0 -39
  229. package/src/components/form/FormAutocomplete.tsx +0 -34
  230. package/src/components/form/FormCheckbox.tsx +0 -32
  231. package/src/components/form/FormDatePicker.tsx +0 -34
  232. package/src/components/form/FormDateTimePicker.tsx +0 -34
  233. package/src/components/form/FormNumberField.tsx +0 -33
  234. package/src/components/form/FormRadioGroup.tsx +0 -43
  235. package/src/components/form/FormSlider.tsx +0 -28
  236. package/src/components/form/FormSubmitButton.tsx +0 -29
  237. package/src/components/form/FormSwitch.tsx +0 -32
  238. package/src/components/form/FormTextField.tsx +0 -26
  239. package/src/components/layout/AccountMenu.tsx +0 -160
  240. package/src/components/layout/DevelopmentBanner.tsx +0 -54
  241. package/src/components/layout/ErrorPage.tsx +0 -34
  242. package/src/components/layout/LayoutDialog.tsx +0 -50
  243. package/src/components/layout/LayoutSnackbar.tsx +0 -44
  244. package/src/components/layout/NavigationDrawer.tsx +0 -131
  245. package/src/components/layout/NotificationMenu.tsx +0 -76
  246. package/src/components/layout/TypographyWithIcon.tsx +0 -35
  247. package/src/components/layout/Unauthorized.tsx +0 -37
  248. package/src/contexts/LayoutContext.tsx +0 -127
  249. package/src/contexts/UserContext.tsx +0 -88
  250. package/src/hooks/FormHooks.ts +0 -33
  251. package/src/hooks/UseSnackbar.tsx +0 -28
  252. package/src/hooks/UseUser.tsx +0 -29
  253. package/src/index.ts +0 -27
  254. package/src/models/Error.tsx +0 -6
  255. package/src/models/KeycloakSettings.ts +0 -8
  256. package/src/models/LayoutPaletteColorOptions.tsx +0 -7
  257. package/src/models/LayoutRoute.ts +0 -15
  258. package/src/models/Notification.ts +0 -10
  259. package/src/models/PeoplesoftDepartment.ts +0 -15
  260. package/src/models/PeoplesoftEmployee.ts +0 -35
  261. package/src/models/Snackbar.ts +0 -16
  262. package/src/models/User.ts +0 -13
  263. package/src/models/types/EmployeeCategoryGroup.ts +0 -1
  264. package/src/models/types/EmployeeStatus.ts +0 -1
  265. package/src/utils/Auth.ts +0 -58
  266. package/src/utils/Fetches.ts +0 -83
  267. package/src/utils/FormUtils.ts +0 -22
  268. package/src/utils/Helpers.ts +0 -27
  269. package/tsconfig.json +0 -29
@@ -1,160 +0,0 @@
1
- import { useIsAuthenticated, useMsal } from "@azure/msal-react";
2
- import { AccountCircle, ArrowBack, Brightness4, ChevronRight, DarkMode, LightMode, Login, Logout, SettingsBrightness, Translate } from "@mui/icons-material";
3
- import { Avatar, Box, IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListSubheader, Menu } from "@mui/material";
4
- import { useQuery } from "@tanstack/react-query";
5
- import React, { Fragment, useState } from "react";
6
- import { useTranslation } from "react-i18next";
7
- import { graphQueries } from "../../hooks/UseUser";
8
- import { User } from "../../models/User";
9
-
10
- const drawerWidth = 240;
11
- type TabType = "settings" | "theme" | "language";
12
-
13
- interface AccountMenuProps {
14
- mode: "light" | "dark" | "system";
15
- setMode: (mode: "light" | "dark" | "system") => void;
16
- user: User;
17
- }
18
-
19
- export const AccountMenu: React.FC<AccountMenuProps> = ({ mode, setMode, user }) => {
20
- const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
21
- const [tab, setTab] = useState<TabType>("settings");
22
- const open = Boolean(anchorEl);
23
- const { t, i18n } = useTranslation();
24
- const { instance } = useMsal();
25
- const isAuthenticated = useIsAuthenticated();
26
-
27
- const { data: userPhoto } = useQuery({ ...graphQueries.sessionUserPhoto(), enabled: isAuthenticated });
28
-
29
- const changeLanguage = (newLanguage: "en" | "cs") => () => {
30
- i18n.changeLanguage(newLanguage)
31
- .finally(() => closeMenu());
32
- };
33
-
34
- const changeMode = (newMode: "light" | "dark" | "system") => () => {
35
- setMode(newMode);
36
- closeMenu();
37
- };
38
-
39
- const openMenu = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => setAnchorEl(e.currentTarget);
40
- const closeMenu = () => { setAnchorEl(null); setTimeout(() => setTab("settings"), 300); };
41
-
42
- const login = () => instance.loginRedirect();
43
- const logout = () => instance.logoutRedirect({
44
- postLogoutRedirectUri: "/",
45
- });
46
-
47
- const changeTab = (newTab: TabType) => () => setTab(newTab);
48
-
49
- const settings = (
50
- <List component="nav" subheader={<ListSubheader sx={{ backgroundColor: "transparent" }}>{t("Layout.Settings")}</ListSubheader>}>
51
- <ListItemButton onClick={changeTab("theme")} sx={{ py: 0.3 }}>
52
- <ListItemIcon>
53
- <Brightness4 />
54
- </ListItemIcon>
55
- <ListItemText primary={t("Layout.Appearance")} secondary={t(`Layout.${mode.charAt(0).toUpperCase() + mode.slice(1)}`)} />
56
- <ChevronRight />
57
- </ListItemButton>
58
-
59
- <ListItemButton onClick={changeTab("language")} sx={{ py: 0.3 }}>
60
- <ListItemIcon>
61
- <Translate />
62
- </ListItemIcon>
63
- <ListItemText primary={t("Layout.Language")} secondary={i18n.resolvedLanguage === "en" ? "English" : "Čeština"} />
64
- <ChevronRight />
65
- </ListItemButton>
66
- </List>
67
- );
68
-
69
- const theme = (
70
- <List subheader={
71
- <ListSubheader onClick={changeTab("settings")} sx={{ backgroundColor: "transparent", display: "flex", alignItems: "center", px: 1, cursor: "pointer" }}>
72
- <IconButton size="small" sx={{ mr: 0.5 }}>
73
- <ArrowBack fontSize="small" />
74
- </IconButton> {t("Layout.Appearance")}
75
- </ListSubheader>
76
- }>
77
- <ListItemButton onClick={changeMode("light")} disabled={mode === "light"}>
78
- <ListItemIcon>
79
- <LightMode />
80
- </ListItemIcon>
81
- <ListItemText primary={t("Layout.Light")} />
82
- </ListItemButton>
83
- <ListItemButton onClick={changeMode("dark")} disabled={mode === "dark"}>
84
- <ListItemIcon>
85
- <DarkMode />
86
- </ListItemIcon>
87
- <ListItemText primary={t("Layout.Dark")} />
88
- </ListItemButton>
89
- <ListItemButton onClick={changeMode("system")} disabled={mode === "system"}>
90
- <ListItemIcon>
91
- <SettingsBrightness />
92
- </ListItemIcon>
93
- <ListItemText primary={t("Layout.System")} />
94
- </ListItemButton>
95
- </List>
96
- );
97
-
98
- const language = (
99
- <List subheader={
100
- <ListSubheader onClick={changeTab("settings")} sx={{ backgroundColor: "transparent", display: "flex", alignItems: "center", px: 1, cursor: "pointer" }}>
101
- <IconButton size="small" sx={{ mr: 0.5 }}>
102
- <ArrowBack fontSize="small" />
103
- </IconButton> {t("Layout.Language")}
104
- </ListSubheader>
105
- }>
106
- <ListItemButton onClick={changeLanguage("en")} disabled={i18n.resolvedLanguage === "en"}>
107
- <ListItemText primary="English" />
108
- </ListItemButton>
109
- <ListItemButton onClick={changeLanguage("cs")} disabled={i18n.resolvedLanguage === "cs"}>
110
- <ListItemText primary="Čeština" />
111
- </ListItemButton>
112
- </List>
113
- );
114
-
115
- return (
116
- <Fragment>
117
- <IconButton size="small" edge="end" onClick={openMenu}>
118
- {userPhoto ?
119
- <Avatar src={userPhoto} sx={{ width: { xs: 32, sm: 40 }, height: { xs: 32, sm: 40 } }} />
120
- :
121
- <AccountCircle sx={{ width: { xs: 32, sm: 40 }, height: { xs: 32, sm: 40 } }} />
122
- }
123
- </IconButton>
124
-
125
- <Menu anchorEl={anchorEl} open={open} onClose={closeMenu}>
126
- <Box sx={{ width: drawerWidth }}>
127
- <List disablePadding>
128
- {isAuthenticated ?
129
- <Fragment>
130
- <ListItem>
131
- <ListItemText primary={user.name} secondary={
132
- <span>
133
- {user.employeeId && <span>{user.employeeId}</span>}
134
- {user.employeeId && <br />}
135
- {user.department && <span>{user.department}</span>}
136
- </span>
137
- } />
138
- </ListItem>
139
-
140
- <ListItemButton onClick={logout}>
141
- <ListItemIcon><Logout color="error" /></ListItemIcon>
142
- <ListItemText primary={t("Layout.Logout")} />
143
- </ListItemButton>
144
- </Fragment>
145
- :
146
- <ListItemButton onClick={login}>
147
- <ListItemIcon><Login color="success" /></ListItemIcon>
148
- <ListItemText primary={t("Layout.LogIn")} />
149
- </ListItemButton>
150
- }
151
- </List>
152
-
153
- {tab === "settings" && settings}
154
- {tab === "theme" && theme}
155
- {tab === "language" && language}
156
- </Box>
157
- </Menu>
158
- </Fragment>
159
- );
160
- };
@@ -1,54 +0,0 @@
1
- import { Close } from "@mui/icons-material";
2
- import { Fade, Grid2, IconButton, Paper, Typography } from "@mui/material";
3
- import { grey } from "@mui/material/colors";
4
- import { useEffect, useState } from "react";
5
- import { useTranslation } from "react-i18next";
6
- import { User } from "../../models/User";
7
- import { environment } from "../../utils/Helpers";
8
- import { hasRole } from "../../utils/Auth";
9
-
10
- interface DevelopmentBannerProps {
11
- user: User;
12
- hasNavigationRoutes: boolean;
13
- }
14
-
15
- export const DevelopmentBanner: React.FC<DevelopmentBannerProps> = ({ user, hasNavigationRoutes }) => {
16
- const { t } = useTranslation();
17
- const [bannerOpen, setBannerOpen] = useState<boolean>(false);
18
-
19
- useEffect(() => {
20
- if (!hasRole(user, ["wcz-developers"]) && (environment === "dev" || environment === "qas"))
21
- setBannerOpen(true);
22
- }, [user]);
23
-
24
- const closeBanner = () => setBannerOpen(false);
25
-
26
- return (
27
- <Fade appear={false} in={bannerOpen}>
28
- <Paper square variant="outlined" tabIndex={-1} sx={theme => ({
29
- position: "fixed",
30
- bottom: 0,
31
- left: { xs: 0, sm: hasNavigationRoutes ? 68.7 : 0 },
32
- right: 0,
33
- m: 0,
34
- p: 2,
35
- borderWidth: 0,
36
- borderTopWidth: 1,
37
- bgcolor: theme.palette.mode === "dark" ? grey[900] : grey[100]
38
- })}>
39
- <Grid2 container justifyContent="space-between" alignItems="center">
40
- <Grid2 size={10}>
41
- <Typography fontWeight="bold">{t("Layout.DevelopmentDialogTitle")}</Typography>
42
- <Typography variant="body2">{t("Layout.DevelopmentDialogContent")}</Typography>
43
- </Grid2>
44
-
45
- <Grid2 size={2} sx={{ p: 1, textAlign: "right" }}>
46
- <IconButton size="small" onClick={closeBanner}>
47
- <Close />
48
- </IconButton>
49
- </Grid2>
50
- </Grid2>
51
- </Paper>
52
- </Fade>
53
- );
54
- };
@@ -1,34 +0,0 @@
1
- import { Box, Container, Typography } from "@mui/material";
2
- import { FC } from "react";
3
- import { useRouteError } from "react-router-dom";
4
-
5
- export const ErrorPage: FC = () => {
6
- const error = useRouteError();
7
-
8
- const formatErrorMessage = (error: unknown): string => {
9
- if (typeof error === "string") {
10
- return error;
11
- } else if (error instanceof Error) {
12
- return error.message;
13
- } else if (typeof error === "object" && error !== null) {
14
- return JSON.stringify(error, null, 2);
15
- } else if (typeof error === "number" || typeof error === "boolean") {
16
- return error.toString();
17
- } else {
18
- return "An unknown error occurred.";
19
- }
20
- };
21
-
22
- return (
23
- <Container maxWidth="sm">
24
- <Box display="flex" flexDirection="column" alignItems="center" justifyContent="center" minHeight="100vh" textAlign="center" padding={3} >
25
- <Typography variant="h2" gutterBottom>
26
- Oops!
27
- </Typography>
28
- <Typography variant="h6" color="textSecondary" gutterBottom>
29
- {formatErrorMessage(error)}
30
- </Typography>
31
- </Box>
32
- </Container>
33
- );
34
- };
@@ -1,50 +0,0 @@
1
- import { Close } from "@mui/icons-material";
2
- import { AppBar, Breakpoint, Dialog, DialogTitle, Grid2, IconButton, Toolbar, Typography, useMediaQuery, useTheme } from "@mui/material";
3
- import { ReactNode } from "react";
4
-
5
- interface DialogProps {
6
- open: boolean;
7
- onClose: (_event?: {}, reason?: "backdropClick" | "escapeKeyDown") => void;
8
- title: string | ReactNode;
9
- color?: "success" | "info" | "warning" | "error" | "primary" | "secondary" | "inherit" | "default";
10
- maxWidth?: Breakpoint;
11
- children?: ReactNode;
12
- }
13
-
14
- export const LayoutDialog: React.FC<DialogProps> = ({ open, onClose, title, color, maxWidth, children }) => {
15
- const theme = useTheme();
16
- const fullscreen = useMediaQuery(theme.breakpoints.down("sm"));
17
-
18
- return (
19
- <Dialog open={open} onClose={onClose} fullScreen={fullscreen} fullWidth maxWidth={maxWidth}>
20
- {fullscreen ?
21
- <AppBar sx={{ position: "relative", bgcolor: `${color}.main` }}>
22
- <Toolbar>
23
- <Typography sx={{ flex: 1 }} variant="h6">
24
- {title}
25
- </Typography>
26
- <IconButton onClick={onClose}>
27
- <Close sx={{ color: `${color}.contrastText` }} />
28
- </IconButton>
29
- </Toolbar>
30
- </AppBar>
31
- :
32
- <Grid2 container justifyContent="space-between" sx={{ bgcolor: `${color}.main`, color: `${color}.contrastText` }}>
33
- <Grid2>
34
- <DialogTitle>
35
- {title}
36
- </DialogTitle>
37
- </Grid2>
38
-
39
- <Grid2 size={2} sx={{ p: 1, textAlign: "right" }}>
40
- <IconButton onClick={onClose}>
41
- <Close fontSize="small" sx={{ color: `${color}.contrastText` }} />
42
- </IconButton>
43
- </Grid2>
44
- </Grid2>
45
- }
46
-
47
- {open ? children : null}
48
- </Dialog >
49
- );
50
- };
@@ -1,44 +0,0 @@
1
- import { Alert, AlertTitle, Portal, Snackbar } from "@mui/material";
2
- import { Dispatch, Fragment, SetStateAction, SyntheticEvent, useMemo } from "react";
3
- import { Snackbar as SnackbarModel } from "../../models/Snackbar";
4
-
5
- interface SnackbarProps {
6
- snackbar: SnackbarModel;
7
- setSnackbar: Dispatch<SetStateAction<SnackbarModel>>;
8
- }
9
-
10
- export const LayoutSnackbar: React.FC<SnackbarProps> = ({ snackbar, setSnackbar }) => {
11
-
12
- const handleOnSnackbarClose = (_event?: SyntheticEvent | Event, reason?: string) => {
13
- if (reason === "clickaway") return;
14
- setSnackbar(prevSnackbar => ({ ...prevSnackbar, title: "" }));
15
- };
16
-
17
- const autoHideDuration = useMemo(() => {
18
- if (snackbar?.duration === undefined) {
19
- if (snackbar?.severity === "error")
20
- return 15000;
21
- if (snackbar?.severity === "warning")
22
- return 10000;
23
- return 5000;
24
- }
25
- return snackbar.duration;
26
- }, [snackbar]);
27
-
28
- return (
29
- <Portal>
30
- <Snackbar open={!!snackbar?.title} autoHideDuration={autoHideDuration} onClose={handleOnSnackbarClose}>
31
- <Alert onClose={handleOnSnackbarClose} severity={snackbar?.severity} sx={{ width: "100%" }} variant="filled">
32
- {snackbar?.description ?
33
- <Fragment>
34
- <AlertTitle>{snackbar?.title}</AlertTitle>
35
- {snackbar.description}
36
- </Fragment>
37
- :
38
- snackbar?.title
39
- }
40
- </Alert>
41
- </Snackbar>
42
- </Portal>
43
- );
44
- };
@@ -1,131 +0,0 @@
1
- import { ChevronLeft, ChevronRight } from "@mui/icons-material";
2
- import { Box, Divider, IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Drawer as MuiDrawer, Tooltip, Typography } from "@mui/material";
3
- import { CSSObject, Theme, styled, useTheme } from "@mui/material/styles";
4
- import React, { Fragment } from "react";
5
- import { useTranslation } from "react-i18next";
6
- import { useLocation, useNavigate } from "react-router-dom";
7
- import { LayoutRoute } from "../../models/LayoutRoute";
8
-
9
- const drawerWidth = 240;
10
-
11
- const openedMixin = (theme: Theme): CSSObject => ({
12
- width: drawerWidth,
13
- transition: theme.transitions.create("width", {
14
- easing: theme.transitions.easing.sharp,
15
- duration: theme.transitions.duration.enteringScreen,
16
- }),
17
- overflowX: "hidden",
18
- });
19
-
20
- const closedMixin = (theme: Theme): CSSObject => ({
21
- transition: theme.transitions.create("width", {
22
- easing: theme.transitions.easing.sharp,
23
- duration: theme.transitions.duration.leavingScreen,
24
- }),
25
- overflowX: "hidden",
26
- width: `calc(${theme.spacing(7)} + 1px)`,
27
- [theme.breakpoints.up("sm")]: {
28
- width: `calc(${theme.spacing(8.4)} + 1px)`,
29
- },
30
- });
31
-
32
- const DrawerHeader = styled("div")(({ theme }) => ({
33
- display: "flex",
34
- alignItems: "center",
35
- justifyContent: "flex-end",
36
- padding: theme.spacing(0, 1),
37
- // necessary for content to be below app bar
38
- ...theme.mixins.toolbar,
39
- }));
40
-
41
- const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== "open" })(
42
- ({ theme, open }) => ({
43
- width: drawerWidth,
44
- flexShrink: 0,
45
- whiteSpace: "nowrap",
46
- boxSizing: "border-box",
47
- ...(open && {
48
- ...openedMixin(theme),
49
- "& .MuiDrawer-paper": openedMixin(theme),
50
- }),
51
- ...(!open && {
52
- ...closedMixin(theme),
53
- "& .MuiDrawer-paper": closedMixin(theme),
54
- }),
55
- }),
56
- );
57
-
58
- const isExternalUrl = (url: string) => url.startsWith("http://") || url.startsWith("https://");
59
-
60
- interface NavigationDrawerProps {
61
- routes: LayoutRoute[];
62
- appVersion: string;
63
- open: boolean;
64
- setOpen: (open: boolean) => void;
65
- hasRoutes: boolean;
66
- }
67
-
68
- export const NavigationDrawer: React.FC<NavigationDrawerProps> = ({ routes, appVersion, open, setOpen, hasRoutes }) => {
69
- const theme = useTheme();
70
- const { t } = useTranslation();
71
- const navigate = useNavigate();
72
- const location = useLocation();
73
-
74
- const closeDrawer = () => setOpen(false);
75
-
76
- const handleMenuItemClick = (item: LayoutRoute) => () => {
77
- if (!item.path) return console.error("Path is not defined for menu item", item);
78
- setOpen(false);
79
-
80
- if (location.pathname === item.path)
81
- return window.location.reload();
82
-
83
- if (isExternalUrl(item.path))
84
- return window.open(item.path, "_blank");
85
-
86
- navigate(item.path);
87
- };
88
-
89
- const menuItems = (
90
- <List>
91
- {routes.filter(route => route.showInMenu && !route.disabled).map(item =>
92
- <Fragment key={item.path}>
93
- <Tooltip title={item.title} placement="right" disableInteractive disableHoverListener={open} disableTouchListener={open}>
94
- <ListItem disablePadding sx={{ display: "block" }} onClick={handleMenuItemClick(item)}>
95
- <ListItemButton selected={location.pathname === item.path}>
96
- <ListItemIcon>
97
- {item.icon}
98
- </ListItemIcon>
99
- <ListItemText primary={item.title} />
100
- </ListItemButton>
101
- </ListItem>
102
- </Tooltip>
103
-
104
- {item.divider && <Divider sx={{ my: 1 }} />}
105
- </Fragment>
106
- )}
107
- </List>
108
- );
109
-
110
- return (
111
- <Fragment>
112
- <Drawer variant="permanent" open={open} sx={{ display: { xs: "none", sm: hasRoutes ? "inherit" : "none" } }}>
113
- <DrawerHeader>
114
- <Typography sx={{ flexGrow: 1, textAlign: "center", marginLeft: 3 }}>{t("Layout.Version")}: {appVersion}</Typography>
115
- <IconButton onClick={closeDrawer}>
116
- {theme.direction === "rtl" ? <ChevronRight /> : <ChevronLeft />}
117
- </IconButton>
118
- </DrawerHeader>
119
- <Divider />
120
- {menuItems}
121
- </Drawer>
122
-
123
- <MuiDrawer anchor="left" open={open} onClose={closeDrawer} sx={{ display: { xs: "inherit", sm: hasRoutes ? "none" : "inherit" } }}>
124
- <Box sx={{ width: drawerWidth }}>
125
- <Typography sx={{ textAlign: "center", my: 1.5 }}>{t("Layout.Version")}: {appVersion}</Typography>
126
- {menuItems}
127
- </Box>
128
- </MuiDrawer>
129
- </Fragment>
130
- );
131
- };
@@ -1,76 +0,0 @@
1
- import { Done, Error, Info, Notifications, NotificationsOff, Warning } from "@mui/icons-material";
2
- import { Badge, Grid, IconButton, List, ListItem, ListItemIcon, ListItemText, Menu, Typography } from "@mui/material";
3
- import { grey } from "@mui/material/colors";
4
- import moment from "moment";
5
- import React, { Dispatch, Fragment, SetStateAction, useEffect, useState } from "react";
6
- import { useTranslation } from "react-i18next";
7
- import Notification from "../../models/Notification";
8
- import { TypographyWithIcon } from "./TypographyWithIcon";
9
-
10
- interface NotificationMenuProps {
11
- notifications: Notification[] | undefined;
12
- setNotifications: Dispatch<SetStateAction<Notification[] | undefined>>;
13
- }
14
-
15
- export const NotificationMenu: React.FC<NotificationMenuProps> = ({ notifications, setNotifications }) => {
16
- const { t } = useTranslation();
17
- const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
18
- const open = Boolean(anchorEl);
19
-
20
- const openMenu = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => setAnchorEl(e.currentTarget);
21
- const closeMenu = () => setAnchorEl(null);
22
-
23
- useEffect(() => {
24
- if (open)
25
- setAllNotificationsAsRead();
26
- }, [open]);
27
-
28
- const setAllNotificationsAsRead = () => {
29
- const updatedNotifications = [...notifications || []].map(notification => ({ ...notification, isRead: true }));
30
- setNotifications(updatedNotifications);
31
- };
32
-
33
- return (
34
- <Fragment>
35
- <IconButton color="inherit" onClick={openMenu} sx={{ mr: 1 }}>
36
- <Badge badgeContent={notifications?.filter(notification => !notification.isRead).length} color="error">
37
- <Notifications />
38
- </Badge>
39
- </IconButton>
40
-
41
- <Menu anchorEl={anchorEl} open={open} onClose={closeMenu} sx={{ height: 700, maxHeight: "calc(100vh - 50px)" }}>
42
- <List dense sx={{ width: 400, maxWidth: "calc(100vw - 50px)" }}>
43
- <ListItem>
44
- <Typography variant="h6">{t("Layout.Notifications")}</Typography>
45
- </ListItem>
46
-
47
- {notifications?.map(notification =>
48
- <ListItem key={notification.dateTime} sx={theme => ({ transition: "background-color 0.2s ease", cursor: "default", "&:hover": { bgcolor: theme.palette.mode === "dark" ? grey[800] : grey[200] } })}>
49
- <ListItemIcon>
50
- {notification.severity === "error" && <Error color="error" fontSize="large" />}
51
- {notification.severity === "warning" && <Warning color="warning" fontSize="large" />}
52
- {notification.severity === "info" && <Info color="info" fontSize="large" />}
53
- {(notification.severity === "success" || !notification.severity) && <Done color="success" fontSize="large" />}
54
- </ListItemIcon>
55
-
56
- <ListItemText primary={<Typography variant="body1">{notification.title}</Typography>} secondary={
57
- <Fragment>
58
- <Typography variant="body2">{notification.description}</Typography>
59
- <Typography variant="caption">{moment(notification.dateTime).fromNow()}</Typography>
60
- </Fragment>
61
- } />
62
- </ListItem>
63
- )}
64
-
65
- {!notifications?.length &&
66
- <Grid container justifyContent="center" alignItems="center" sx={{ width: "100%", height: 200, maxHeight: "calc(100vh - 150px)" }}>
67
- <Grid item>
68
- <TypographyWithIcon startIcon={<NotificationsOff color="disabled" />} color="text.secondary">{t("Layout.NoNotificationsAtTheMoment")}</TypographyWithIcon>
69
- </Grid>
70
- </Grid>
71
- }
72
- </List>
73
- </Menu>
74
- </Fragment>
75
- );
76
- };
@@ -1,35 +0,0 @@
1
- import { Stack, SxProps, Theme, Typography, TypographyProps } from "@mui/material";
2
-
3
- const stackSxProps = [
4
- "margin", "marginTop", "marginRight", "marginBottom", "marginLeft", "m", "mt", "mr", "mb", "ml", "mx", "my",
5
- "padding", "paddingTop", "paddingRight", "paddingBottom", "paddingLeft", "p", "pt", "pr", "pb", "pl", "px", "py",
6
- "flexGrow", "flexShrink", "flexBasis", "flexDirection", "alignItems", "justifyContent",
7
- "position", "zIndex", "top", "right", "bottom", "left",
8
- "gridGap", "gridColumnGap", "gridRowGap", "gridColumn", "gridRow", "gridAutoFlow",
9
- "gap", "columnGap", "rowGap"
10
- ];
11
-
12
- interface TypographyWithIconProps extends TypographyProps {
13
- startIcon?: React.ReactNode;
14
- endIcon?: React.ReactNode;
15
- }
16
-
17
- export const TypographyWithIcon: React.FC<TypographyWithIconProps> = ({ startIcon, endIcon, children, sx, gutterBottom, ...props }) => {
18
- const sxCopy = { ...sx };
19
-
20
- const stackStyles = stackSxProps.reduce((acc, curr) => {
21
- if (sxCopy && (sxCopy as any)[curr]) {
22
- (acc as any)[curr] = (sxCopy as any)[curr];
23
- delete (sxCopy as any)[curr];
24
- }
25
- return acc;
26
- }, {} as SxProps<Theme>);
27
-
28
- return (
29
- <Stack direction="row" alignItems="center" gap={1} sx={stackStyles} mb={gutterBottom ? 0.7 : undefined}>
30
- {startIcon && startIcon}
31
- <Typography {...props} sx={sxCopy}>{children}</Typography>
32
- {endIcon && endIcon}
33
- </Stack>
34
- );
35
- };
@@ -1,37 +0,0 @@
1
- import { Box, CircularProgress, Typography } from "@mui/material";
2
- import React, { useEffect, useState } from "react";
3
- import { useTranslation } from "react-i18next";
4
-
5
- export const Unauthorized: React.FC = () => {
6
- const { t } = useTranslation();
7
- const [isInitializingKeycloak, setIsInitializingKeycloak] = useState(false);
8
- const [showComponent, setShowComponent] = useState(false);
9
-
10
- useEffect(() => {
11
- const timer = setTimeout(() => {
12
- setShowComponent(true);
13
- }, 1000);
14
-
15
- window.addEventListener("keycloakInitialization", handleInitialization as EventListener);
16
-
17
- return () => {
18
- clearTimeout(timer);
19
- window.removeEventListener("keycloakInitialization", handleInitialization as EventListener);
20
- };
21
- }, []);
22
-
23
- const handleInitialization = (event: CustomEvent) => {
24
- setIsInitializingKeycloak(event.detail.initializing);
25
- };
26
-
27
- if (!showComponent)
28
- return null;
29
-
30
- return (
31
- <Box sx={{ position: "relative", height: { xs: "calc(100vh - 56px)", sm: "calc(100vh - 64px)" } }}>
32
- <Box sx={{ position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%)" }}>
33
- {isInitializingKeycloak ? <CircularProgress /> : <Typography variant="h6">{t("Layout.Unauthorized")}</Typography>}
34
- </Box>
35
- </Box>
36
- );
37
- };