@asaleh37/ui-base 1.0.9 → 1.1.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.
Files changed (125) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +1 -1
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/src/components/App.tsx +31 -0
  7. package/src/components/admin/AttachmentGrid.tsx +116 -0
  8. package/src/components/admin/AuthorityGrid.tsx +88 -0
  9. package/src/components/admin/BluePrintGrid.tsx +55 -0
  10. package/src/components/admin/BluePrintPageGrid.tsx +85 -0
  11. package/src/components/admin/BluePrintPointGrid.tsx +85 -0
  12. package/src/components/admin/DashboardGrid.tsx +95 -0
  13. package/src/components/admin/DashboardWidgetGrid.tsx +75 -0
  14. package/src/components/admin/DataQueryGrid.tsx +75 -0
  15. package/src/components/admin/DataQueryParameterGrid.tsx +98 -0
  16. package/src/components/admin/DatasourceConnectionGrid.tsx +98 -0
  17. package/src/components/admin/EmployeeGrid.tsx +105 -0
  18. package/src/components/admin/EntityParameterGrid.tsx +125 -0
  19. package/src/components/admin/ExcelUploaderDetailGrid.tsx +78 -0
  20. package/src/components/admin/ExcelUploaderHeaderGrid.tsx +78 -0
  21. package/src/components/admin/LookupGrid.tsx +95 -0
  22. package/src/components/admin/MailAttachmentGrid.tsx +65 -0
  23. package/src/components/admin/MailBodyGrid.tsx +105 -0
  24. package/src/components/admin/MailNotificationQueueGrid.tsx +131 -0
  25. package/src/components/admin/MailRecipientGrid.tsx +75 -0
  26. package/src/components/admin/MailTemplateGrid.tsx +145 -0
  27. package/src/components/admin/NewTableGrid.tsx +65 -0
  28. package/src/components/admin/NotificationGrid.tsx +115 -0
  29. package/src/components/admin/NotificationQueueGrid.tsx +125 -0
  30. package/src/components/admin/OrganizationApplicationGrid.tsx +81 -0
  31. package/src/components/admin/OrganizationGrid.tsx +65 -0
  32. package/src/components/admin/OrganizationRankGrid.tsx +85 -0
  33. package/src/components/admin/OrganizationUnitGrid.tsx +85 -0
  34. package/src/components/admin/OrganizationUserGrid.tsx +75 -0
  35. package/src/components/admin/OrganizationUserRoleGrid.tsx +98 -0
  36. package/src/components/admin/ReportGrid.tsx +155 -0
  37. package/src/components/admin/ReportParameterGrid.tsx +95 -0
  38. package/src/components/admin/RoleAuthorityGrid.tsx +65 -0
  39. package/src/components/admin/RoleGrid.tsx +78 -0
  40. package/src/components/admin/UserAccountGrid.tsx +65 -0
  41. package/src/components/admin/UserRequestGrid.tsx +145 -0
  42. package/src/components/admin/WidgetGrid.tsx +175 -0
  43. package/src/components/admin/WorkflowDocumentActionGrid.tsx +111 -0
  44. package/src/components/admin/WorkflowDocumentActionHistoryGrid.tsx +111 -0
  45. package/src/components/admin/WorkflowDocumentActionMailGrid.tsx +71 -0
  46. package/src/components/admin/WorkflowDocumentGrid.tsx +185 -0
  47. package/src/components/admin/WorkflowDocumentMailLogGrid.tsx +141 -0
  48. package/src/components/admin/WorkflowDocumentStatusGrid.tsx +121 -0
  49. package/src/components/common/Home.tsx +31 -0
  50. package/src/components/common/LanguageSwitcher.tsx +25 -0
  51. package/src/components/common/LayoutHandlers.tsx +12 -0
  52. package/src/components/common/LoadingMask.tsx +19 -0
  53. package/src/components/common/Login.tsx +183 -0
  54. package/src/components/templates/DataEntryTemplates/DataEntryTypes.ts +288 -0
  55. package/src/components/templates/DataEntryTemplates/DataEntryUtil.ts +201 -0
  56. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormAction.tsx +60 -0
  57. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormElementField.tsx +194 -0
  58. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormElementGroup.tsx +98 -0
  59. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/CheckBox.tsx +64 -0
  60. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/ComboBox.tsx +94 -0
  61. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/Datefield.tsx +65 -0
  62. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/DatetimeField.tsx +64 -0
  63. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/FiltersPanel.tsx +237 -0
  64. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormFields/TemplateTextField.tsx +9 -0
  65. package/src/components/templates/DataEntryTemplates/TemplateDataForm/TemplateForm.tsx +256 -0
  66. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/DataGridColumnsUtil.tsx +188 -0
  67. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGrid.tsx +844 -0
  68. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGridMultiRecordAction.tsx +89 -0
  69. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGridRecordAction.tsx +92 -0
  70. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGridTopBar.tsx +228 -0
  71. package/src/components/templates/DataEntryTemplates/useApiActions.ts +125 -0
  72. package/src/components/templates/TransferList.tsx +250 -0
  73. package/src/components/templates/Window/ConfirmationWindow.tsx +55 -0
  74. package/src/components/templates/visuals/TemplateDashboard.tsx +126 -0
  75. package/src/components/templates/visuals/charts/TemplateBarChart.tsx +16 -0
  76. package/src/components/templates/visuals/charts/TemplateDataCard.tsx +60 -0
  77. package/src/components/templates/visuals/charts/TemplateGauge.tsx +16 -0
  78. package/src/components/templates/visuals/charts/TemplateLineChart.tsx +16 -0
  79. package/src/components/templates/visuals/charts/TemplateLineProgress.tsx +40 -0
  80. package/src/components/templates/visuals/charts/TemplatePieChart.tsx +25 -0
  81. package/src/hooks/UseConfirmationWindow.tsx +54 -0
  82. package/src/hooks/UseMobile.tsx +13 -0
  83. package/src/hooks/UseSession.tsx +26 -0
  84. package/src/hooks/UseWindow.tsx +106 -0
  85. package/src/hooks/useAxios.tsx +271 -0
  86. package/src/hooks/useLoadingMask.tsx +16 -0
  87. package/src/layout/DrawerHeader.tsx +10 -0
  88. package/src/layout/Layout.tsx +122 -0
  89. package/src/layout/MainContent.tsx +43 -0
  90. package/src/layout/MobileDrawer.tsx +103 -0
  91. package/src/layout/NavigationTree.tsx +284 -0
  92. package/src/layout/SideBar.tsx +80 -0
  93. package/src/layout/TopBar.tsx +142 -0
  94. package/src/locales/arabic/adminLocalsAr.json +356 -0
  95. package/src/locales/arabic/common.json +34 -0
  96. package/src/locales/arabic/index.ts +7 -0
  97. package/src/locales/english/adminLocalsEn.json +356 -0
  98. package/src/locales/english/common.json +33 -0
  99. package/src/locales/english/index.ts +6 -0
  100. package/src/locales/english/index.tsx +0 -0
  101. package/src/locales/i18n.ts +15 -0
  102. package/src/locales/index.ts +9 -0
  103. package/src/navigationItems/Administration/adminNavigationItems.tsx +182 -0
  104. package/src/navigationItems/Administration/index.tsx +71 -0
  105. package/src/navigationItems/common/CommonNavigationItems.tsx +12 -0
  106. package/src/navigationItems/common/index.tsx +7 -0
  107. package/src/navigationItems/index.tsx +34 -0
  108. package/src/redux/features/administration/AdministrationStoresMetaData.ts +72 -0
  109. package/src/redux/features/business/BusinessStoresMetaData.ts +3 -0
  110. package/src/redux/features/business/CommonStoreSlice.ts +37 -0
  111. package/src/redux/features/common/AppInfoSlice.ts +30 -0
  112. package/src/redux/features/common/AppLayoutSlice.ts +37 -0
  113. package/src/redux/features/common/LoadingMaskSlice.ts +30 -0
  114. package/src/redux/features/common/UserSessionSlice.ts +62 -0
  115. package/src/redux/store.ts +10 -10
  116. package/src/routes/administration/adminRoutes.tsx +259 -0
  117. package/src/routes/administration/index.ts +4 -0
  118. package/src/routes/index.ts +11 -0
  119. package/src/routes/types/index.ts +5 -0
  120. package/src/theme/DarkThemeOptions.ts +30 -0
  121. package/src/theme/LightThemeOptions.ts +34 -0
  122. package/src/util/AppUtils.ts +18 -0
  123. package/src/util/constants.ts +2 -0
  124. package/tsconfig.json +2 -2
  125. package/src/redux/CounterSlice.ts +0 -17
@@ -0,0 +1,26 @@
1
+ import { useSelector } from "react-redux";
2
+ import { RootState } from "../redux/store";
3
+
4
+
5
+ const useSession = () => {
6
+ const UserSession = useSelector((state: RootState) => state.UserSession);
7
+ const isUserAuthorized = (authorityCode: string): boolean => {
8
+ if (UserSession?.value?.authorities) {
9
+ // if (UserSession.value.authorities.includes("DEVELOPMENT_ADMIN")) {
10
+ // return true;
11
+ // }
12
+ for (let grantedAuthority of UserSession.value.authorities) {
13
+ if (
14
+ grantedAuthority?.authority === "DEVELOPMENT_ADMIN" ||
15
+ grantedAuthority?.authority === authorityCode
16
+ ) {
17
+ return true;
18
+ }
19
+ }
20
+ }
21
+ return false;
22
+ };
23
+ return { UserSession, isUserAuthorized };
24
+ };
25
+
26
+ export default useSession;
@@ -0,0 +1,106 @@
1
+ import { useEffect, useState } from "react";
2
+ import {
3
+ AppBar,
4
+ Box,
5
+ IconButton,
6
+ Modal,
7
+ Paper,
8
+ Toolbar,
9
+ Typography,
10
+ } from "@mui/material";
11
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
12
+
13
+ export interface TemplateWindowProp {
14
+ height?: any;
15
+ width?: any;
16
+ minWidth?: any;
17
+ minHeight?: any;
18
+ windowIcon?: any;
19
+ windowTitle?: string;
20
+ onCloseCallBack?: any;
21
+ }
22
+
23
+ interface WindowProps {
24
+ children?: React.ReactNode;
25
+ }
26
+
27
+ export const useWindow = (props: TemplateWindowProp) => {
28
+ const [windowState, setWindowState] = useState(false);
29
+
30
+ const Window: React.FC<WindowProps> = (windowProps: WindowProps) => {
31
+ return (
32
+ <Modal
33
+ open={windowState}
34
+ sx={{ zIndex: (theme) => theme.zIndex.drawer }}
35
+ onClose={() => {
36
+ if (!windowState && props?.onCloseCallBack) {
37
+ props.onCloseCallBack();
38
+ }
39
+ }}
40
+ >
41
+ <Box
42
+ sx={{
43
+ position: "absolute",
44
+ top: "50%",
45
+ left: "50%",
46
+ maxHeight: "90%",
47
+ transform: "translate(-50%, -50%)",
48
+ height: props?.height || "80%",
49
+ width: props?.width || "90%",
50
+ minWidth: props.minWidth || 400,
51
+ minHeight: props.minHeight || 200,
52
+ overflow: "hidden",
53
+ bgcolor: "modalBackground.main",
54
+ display: "flex",
55
+ flexDirection: "column",
56
+ alignItems: "center",
57
+ justifyContent: "flex-start",
58
+ }}
59
+ >
60
+ <AppBar position="static">
61
+ <Toolbar variant="dense">
62
+ <FontAwesomeIcon
63
+ icon={props?.windowIcon || "window-maximize"}
64
+ style={{ marginRight: 5 }}
65
+ />
66
+ <Typography variant="h6" color="inherit" component="div">
67
+ {props?.windowTitle || "window"}
68
+ </Typography>
69
+ <div style={{ flexGrow: 1 }}></div>
70
+ <IconButton
71
+ onClick={() => {
72
+ setWindowState(false);
73
+ if (
74
+ props.onCloseCallBack != undefined &&
75
+ props.onCloseCallBack != null
76
+ ) {
77
+ props.onCloseCallBack();
78
+ }
79
+ }}
80
+ color="secondary"
81
+ >
82
+ <FontAwesomeIcon icon="xmark-square" />
83
+ </IconButton>
84
+ </Toolbar>
85
+ </AppBar>
86
+ <Paper
87
+ sx={{
88
+ // flexGrow: 1,
89
+ display: "flex",
90
+ flexDirection: "column",
91
+ alignItems: "center",
92
+ width: "100%",
93
+ height: "100%",
94
+ padding: 1,
95
+ // justifyContent: "center",
96
+ overflow: "hidden",
97
+ }}
98
+ >
99
+ {windowProps?.children}
100
+ </Paper>
101
+ </Box>
102
+ </Modal>
103
+ );
104
+ };
105
+ return { windowState, setWindowState, Window };
106
+ };
@@ -0,0 +1,271 @@
1
+ import { toast } from "react-toastify";
2
+ import axios from "axios";
3
+ import { useSelector } from "react-redux";
4
+ import { RootState } from "../redux/store";
5
+ import useLoadingMask from "./useLoadingMask";
6
+
7
+ export interface APIRequest {
8
+ endPointURI: string;
9
+ parameters?: any;
10
+ data?: any;
11
+ showMask?: Boolean;
12
+ loadingMessage?: string;
13
+ successCallBkFn?: Function;
14
+ failureCallBkFn?: Function;
15
+ }
16
+
17
+ const useAxios = () => {
18
+ const mask = useLoadingMask();
19
+ const apiBaseUrl = useSelector(
20
+ (state: RootState) => state.AppInfo.apiBaseUrl
21
+ );
22
+ const axiosInstance = axios.create({
23
+ baseURL: apiBaseUrl,
24
+ timeout: 600000,
25
+ withCredentials: true,
26
+ });
27
+
28
+ axiosInstance.defaults.withCredentials = true;
29
+ axiosInstance.interceptors.response.use(
30
+ (response: any) => {
31
+ return response;
32
+ },
33
+ (error: any) => {
34
+ if (
35
+ error
36
+ ? error.response
37
+ ? error.response.status
38
+ ? error.response.status === 401
39
+ : false
40
+ : false
41
+ : false
42
+ ) {
43
+ toast.error("your session is now expired, you need to login again", {
44
+ autoClose: false,
45
+ });
46
+ } else if (
47
+ error
48
+ ? error.response
49
+ ? error.response.status
50
+ ? error.response.status === 403
51
+ : false
52
+ : false
53
+ : false
54
+ ) {
55
+ toast.error("you aren't authorized to process this request");
56
+ } else if (
57
+ error
58
+ ? error.response
59
+ ? error.response.status
60
+ ? error.response.status === 500
61
+ : false
62
+ : false
63
+ : false
64
+ ) {
65
+ toast.error(error.response.data);
66
+ } else {
67
+ toast.error(
68
+ "failed to communicate with the server ... try again later"
69
+ );
70
+ }
71
+ return "ERROR";
72
+ }
73
+ );
74
+ const handleGetRequest = async (
75
+ props: APIRequest = { endPointURI: "", parameters: {} }
76
+ ) => {
77
+ if (
78
+ props.showMask !== undefined &&
79
+ props.showMask != null &&
80
+ props.showMask === true
81
+ ) {
82
+ mask.show(props.loadingMessage);
83
+ }
84
+ const response: any = await axiosInstance.get(props.endPointURI, {
85
+ params: { ...props.parameters },
86
+ withCredentials: true,
87
+ // withCredentials: true,
88
+ });
89
+ if (
90
+ props.showMask !== undefined &&
91
+ props.showMask != null &&
92
+ props.showMask === true
93
+ ) {
94
+ mask.hide();
95
+ }
96
+ if (response !== "ERROR") {
97
+ if (
98
+ props.successCallBkFn !== undefined &&
99
+ props.successCallBkFn != null
100
+ ) {
101
+ props.successCallBkFn(response);
102
+ }
103
+ return response;
104
+ } else {
105
+ if (
106
+ props.failureCallBkFn !== undefined &&
107
+ props.failureCallBkFn != null
108
+ ) {
109
+ props.failureCallBkFn(response);
110
+ }
111
+ return "ERROR";
112
+ }
113
+ };
114
+
115
+ const HandleDownloadHTTPPostPDF = async (
116
+ props: APIRequest = { endPointURI: "", parameters: {}, data: {} }
117
+ ) => {
118
+ if (
119
+ props.showMask !== undefined &&
120
+ props.showMask != null &&
121
+ props.showMask === true
122
+ ) {
123
+ mask.show(props.loadingMessage);
124
+ }
125
+ const response: any = await axiosInstance.post(
126
+ props.endPointURI,
127
+ props.data,
128
+ {
129
+ responseType: "blob",
130
+ }
131
+ );
132
+ if (
133
+ props.showMask !== undefined &&
134
+ props.showMask != null &&
135
+ props.showMask === true
136
+ ) {
137
+ mask.hide();
138
+ }
139
+ if (response !== "ERROR") {
140
+ if (
141
+ props.successCallBkFn !== undefined &&
142
+ props.successCallBkFn != null
143
+ ) {
144
+ props.successCallBkFn(response);
145
+ }
146
+ return response;
147
+ } else {
148
+ if (
149
+ props.failureCallBkFn !== undefined &&
150
+ props.failureCallBkFn != null
151
+ ) {
152
+ props.failureCallBkFn(response);
153
+ }
154
+ return "ERROR";
155
+ }
156
+ // axiosInstance
157
+ // .request({
158
+ // url: props.endPointURI,
159
+ // method: "POST",
160
+ // data: props.data,
161
+ // responseType: "blob",
162
+ // })
163
+ // .then((response) => {
164
+ // const url = window.URL.createObjectURL(
165
+ // new Blob([response.data], { type: "application/pdf" })
166
+ // );
167
+ // const link = document.createElement("a");
168
+ // link.href = url;
169
+ // link.setAttribute("download", "example.pdf"); // specify download filename
170
+ // document.body.appendChild(link);
171
+ // link.click();
172
+ // link.remove();
173
+ // })
174
+ // .catch((error) => {
175
+ // console.error("Download error:", error);
176
+ // })
177
+ // .finally(() => {
178
+
179
+ // });
180
+ };
181
+ const handlePostRequest = async (
182
+ props: APIRequest = { endPointURI: "", parameters: {}, data: {} }
183
+ ) => {
184
+ if (
185
+ props.showMask !== undefined &&
186
+ props.showMask != null &&
187
+ props.showMask === true
188
+ ) {
189
+ mask.show(props.loadingMessage);
190
+ }
191
+ let response: any = await axiosInstance.post(
192
+ props.endPointURI,
193
+ props.data,
194
+ {
195
+ params: props.parameters,
196
+ }
197
+ );
198
+ if (
199
+ props.showMask !== undefined &&
200
+ props.showMask != null &&
201
+ props.showMask === true
202
+ ) {
203
+ mask.hide();
204
+ }
205
+ if (response !== "ERROR") {
206
+ if (
207
+ props.successCallBkFn !== undefined &&
208
+ props.successCallBkFn != null
209
+ ) {
210
+ props.successCallBkFn(response);
211
+ }
212
+ return response;
213
+ } else {
214
+ if (
215
+ props.failureCallBkFn !== undefined &&
216
+ props.failureCallBkFn != null
217
+ ) {
218
+ props.failureCallBkFn(response);
219
+ }
220
+ return "ERROR";
221
+ }
222
+ };
223
+ const handleDeleteRequest = async (
224
+ props: APIRequest = { endPointURI: "", parameters: {} }
225
+ ) => {
226
+ if (
227
+ props.showMask !== undefined &&
228
+ props.showMask != null &&
229
+ props.showMask === true
230
+ ) {
231
+ mask.show(props.loadingMessage);
232
+ }
233
+ let response: any = await axiosInstance.delete(props.endPointURI, {
234
+ params: {
235
+ ...props.parameters,
236
+ },
237
+ });
238
+ if (
239
+ props.showMask !== undefined &&
240
+ props.showMask != null &&
241
+ props.showMask === true
242
+ ) {
243
+ mask.hide();
244
+ }
245
+ if (response !== "ERROR") {
246
+ if (
247
+ props.successCallBkFn !== undefined &&
248
+ props.successCallBkFn != null
249
+ ) {
250
+ props.successCallBkFn(response);
251
+ }
252
+ return response;
253
+ } else {
254
+ if (
255
+ props.failureCallBkFn !== undefined &&
256
+ props.failureCallBkFn != null
257
+ ) {
258
+ props.failureCallBkFn(response);
259
+ }
260
+ return "ERROR";
261
+ }
262
+ };
263
+ return {
264
+ handleGetRequest,
265
+ handlePostRequest,
266
+ handleDeleteRequest,
267
+ HandleDownloadHTTPPostPDF,
268
+ };
269
+ };
270
+
271
+ export default useAxios;
@@ -0,0 +1,16 @@
1
+ import { useDispatch } from "react-redux";
2
+ import { hideLoadingMask, showLoadingMask } from "../redux/features/common/LoadingMaskSlice";
3
+
4
+
5
+ const useLoadingMask = () => {
6
+ const dispatch = useDispatch();
7
+ const show = (message?: string) => {
8
+ dispatch(showLoadingMask(message));
9
+ };
10
+ const hide = () => {
11
+ dispatch(hideLoadingMask());
12
+ };
13
+ return { show, hide };
14
+ };
15
+
16
+ export default useLoadingMask;
@@ -0,0 +1,10 @@
1
+ import { styled } from "@mui/material";
2
+
3
+ export const DrawerHeader = styled("div")(({ theme }) => ({
4
+ display: "flex",
5
+ alignItems: "center",
6
+ // padding: theme.spacing(0, 1),
7
+ // necessary for content to be below app bar
8
+ ...theme.mixins.toolbar,
9
+ justifyContent: "flex-end",
10
+ }));
@@ -0,0 +1,122 @@
1
+ import { styled, useTheme } from "@mui/material/styles";
2
+ import CssBaseline from "@mui/material/CssBaseline";
3
+ import { useDispatch, useSelector } from "react-redux";
4
+ import TopBar from "./TopBar";
5
+ import { DrawerHeader } from "./DrawerHeader";
6
+ import SideBar from "./SideBar";
7
+ import MainContent from "./MainContent";
8
+ import { BrowserRouter } from "react-router-dom";
9
+ import MobileDrawer from "./MobileDrawer";
10
+ import { ToastContainer } from "react-toastify";
11
+ import { useEffect } from "react";
12
+ import { RootState } from "../redux/store";
13
+ import useLoadingMask from "../hooks/useLoadingMask";
14
+ import { useIsMobile } from "../hooks/UseMobile";
15
+ import useSession from "../hooks/UseSession";
16
+ import useAxios from "../hooks/useAxios";
17
+ import { setStoreData } from "../redux/features/business/CommonStoreSlice";
18
+ import { DRAWER_WIDTH } from "../redux/features/common/AppLayoutSlice";
19
+ import { UserSessionProps } from "../redux/features/common/UserSessionSlice";
20
+ import LoadingMask from "../components/common/LoadingMask";
21
+ import Login from "../components/common/Login";
22
+
23
+
24
+ const Main = styled("main", {
25
+ shouldForwardProp: (prop) => prop !== "open",
26
+ })<{
27
+ open?: boolean;
28
+ }>(({ theme: any, open }) => {
29
+ const AppLayout = useSelector((state: RootState) => state.AppLayout);
30
+ const dispatch = useDispatch();
31
+ const { show, hide } = useLoadingMask();
32
+ const CommonStores = useSelector((state: RootState) => state.commonStores);
33
+ const theme = useTheme();
34
+ const isMobile = useIsMobile();
35
+ const { isUserAuthorized } = useSession();
36
+
37
+ // loadCommonStores
38
+ const { handleGetRequest } = useAxios();
39
+ const loadCommonStores = async () => {
40
+ show("Loading ... please wait");
41
+ let storeKeys = Object.keys(CommonStores);
42
+ for (let storeKey of storeKeys) {
43
+ if (
44
+ (CommonStores[storeKey]?.authority === undefined ||
45
+ CommonStores[storeKey]?.authority === null ||
46
+ isUserAuthorized(CommonStores[storeKey]?.authority)) &&
47
+ CommonStores[storeKey]?.url != "" &&
48
+ CommonStores[storeKey].autoLoad === true
49
+ ) {
50
+ await handleGetRequest({
51
+ endPointURI: CommonStores[storeKey].url,
52
+ showMask: false,
53
+ successCallBkFn: (response) => {
54
+ dispatch(setStoreData({ storeKey, data: response.data }));
55
+ },
56
+ failureCallBkFn: () => {
57
+ dispatch(setStoreData({ storeKey, data: [] }));
58
+ },
59
+ });
60
+ }
61
+ }
62
+ hide();
63
+ };
64
+
65
+ useEffect(() => {
66
+ loadCommonStores();
67
+ }, []);
68
+
69
+ return {
70
+ display: "flex",
71
+ flexDirection: "column",
72
+ overflow: "hidden",
73
+ flexGrow: 1,
74
+ width: !isMobile && open ? `calc(100% - ${DRAWER_WIDTH}px)` : "100%",
75
+ direction: AppLayout.appDirection,
76
+ justifyContent: "flex-start",
77
+ transition:
78
+ open === true
79
+ ? theme.transitions.create(["margin", "width"], {
80
+ easing: theme.transitions.easing.easeOut,
81
+ duration: theme.transitions.duration.enteringScreen,
82
+ })
83
+ : theme.transitions.create(["margin", "width"], {
84
+ easing: theme.transitions.easing.sharp,
85
+ duration: theme.transitions.duration.leavingScreen,
86
+ }),
87
+ marginLeft:
88
+ !isMobile && AppLayout.appDirection === "ltr" && open === true
89
+ ? DRAWER_WIDTH + "px"
90
+ : 0,
91
+ marginRight:
92
+ !isMobile && AppLayout.appDirection === "rtl" && open === true
93
+ ? DRAWER_WIDTH + "px"
94
+ : 0,
95
+ };
96
+ });
97
+
98
+ export default function Layout() {
99
+ const AppLayoutState = useSelector((state: RootState) => state.AppLayout);
100
+ const isMobile = useIsMobile();
101
+ const UserSession: UserSessionProps = useSelector(
102
+ (state: RootState) => state.UserSession
103
+ );
104
+ return (
105
+ <BrowserRouter>
106
+ <ToastContainer draggable={true} position="bottom-center" />
107
+ <LoadingMask />
108
+ {UserSession.value.isAuthenticated === true ? (
109
+ <Main open={AppLayoutState.sideBarOpened}>
110
+ <CssBaseline />
111
+ <TopBar />
112
+ {!isMobile ? <SideBar /> : null}
113
+ {isMobile ? <MobileDrawer /> : null}
114
+ <DrawerHeader />
115
+ <MainContent />
116
+ </Main>
117
+ ) : (
118
+ <Login />
119
+ )}
120
+ </BrowserRouter>
121
+ );
122
+ }
@@ -0,0 +1,43 @@
1
+ import { Box } from "@mui/material";
2
+ import { useSelector } from "react-redux";
3
+ import { CacheProvider } from "@emotion/react";
4
+ import { Route, Routes } from "react-router-dom";
5
+ import { RootState } from "../redux/store";
6
+ import { cacheLtr, cacheRtl } from "../components/common/LayoutHandlers";
7
+ import { SYSTEM_ROUTES } from "../routes";
8
+ import { SystemRoute } from "../routes/types";
9
+
10
+ const MainContent: React.FC = () => {
11
+ const AppLayoutState = useSelector((state: RootState) => state.AppLayout);
12
+ return (
13
+ <CacheProvider
14
+ value={AppLayoutState.appDirection === "ltr" ? cacheLtr : cacheRtl}
15
+ >
16
+ <Box
17
+ sx={{
18
+ display: "flex",
19
+ flexDirection: "column",
20
+ // alignItems: "center",
21
+ justifyContent: "flex-start",
22
+ flex: 1,
23
+ overflow: "hidden",
24
+ padding: 3,
25
+ }}
26
+ >
27
+ <Routes>
28
+ {SYSTEM_ROUTES.map((route: SystemRoute, index) => {
29
+ return (
30
+ <Route
31
+ key={index}
32
+ path={route.path}
33
+ Component={route.component}
34
+ />
35
+ );
36
+ })}
37
+ </Routes>
38
+ </Box>
39
+ </CacheProvider>
40
+ );
41
+ };
42
+
43
+ export default MainContent;
@@ -0,0 +1,103 @@
1
+ import { styled } from "@mui/material/styles";
2
+ import { grey } from "@mui/material/colors";
3
+ import SwipeableDrawer from "@mui/material/SwipeableDrawer";
4
+ import { useDispatch, useSelector } from "react-redux";
5
+ import { Box, Typography } from "@mui/material";
6
+ import { RootState } from "../redux/store";
7
+ import { AppLayoutActions } from "../redux/features/common/AppLayoutSlice";
8
+ import NavigationTree from "./NavigationTree";
9
+
10
+ const drawerBleeding = 56;
11
+
12
+ interface Props {
13
+ /**
14
+ * Injected by the documentation to work in an iframe.
15
+ * You won't need it on your project.
16
+ */
17
+ window?: () => Window;
18
+ }
19
+
20
+ const Puller = styled("div")(({ theme }) => ({
21
+ width: 30,
22
+ height: 6,
23
+ margin: 10,
24
+ backgroundColor: grey[300],
25
+ borderRadius: 3,
26
+ // position: "absolute",
27
+ top: 8,
28
+ // left: "calc(50% - 15px)",
29
+ ...theme.applyStyles("dark", {
30
+ backgroundColor: grey[900],
31
+ }),
32
+ }));
33
+
34
+ export default function MobileDrawer(props: Props) {
35
+ const { window } = props;
36
+ const AppLayout = useSelector((state: RootState) => state.AppLayout);
37
+ const AppInfo = useSelector((state: RootState) => state.AppInfo);
38
+ const dispatch = useDispatch();
39
+ const toggleDrawer = (newState: boolean) => {
40
+ dispatch(AppLayoutActions.setSideBarState(newState));
41
+ };
42
+ // This is used only for the example
43
+ const container =
44
+ window !== undefined ? () => window().document.body : undefined;
45
+
46
+ return (
47
+ <SwipeableDrawer
48
+ container={container}
49
+ anchor="bottom"
50
+ open={AppLayout.sideBarOpened}
51
+ onClose={() => {
52
+ toggleDrawer(false);
53
+ }}
54
+ onOpen={() => {
55
+ toggleDrawer(true);
56
+ }}
57
+ swipeAreaWidth={drawerBleeding}
58
+ disableSwipeToOpen={false}
59
+ ModalProps={{
60
+ keepMounted: true,
61
+ }}
62
+ >
63
+ <Box
64
+ sx={{
65
+ display: "flex",
66
+ flexDirection: "column",
67
+ alignItems: "center",
68
+ height: "100%",
69
+ overflow: "hidden",
70
+ }}
71
+ >
72
+ <Puller />
73
+ <Box
74
+ sx={{
75
+ flexGrow: 1,
76
+ display: "flex",
77
+ justifyContent: "center",
78
+ width: "99%",
79
+ overflowY: "auto",
80
+ }}
81
+ >
82
+ <NavigationTree />
83
+ </Box>
84
+ <Box
85
+ sx={{
86
+ display: "flex",
87
+ alignItems: "center",
88
+ justifyContent: "space-around",
89
+ marginTop: 1,
90
+ width: "100%",
91
+ }}
92
+ >
93
+ <Typography sx={{ fontSize: 12 }} color="textDisabled">
94
+ {AppInfo.appName}
95
+ </Typography>
96
+ <Typography sx={{ fontSize: 12 }} color="textDisabled">
97
+ V.{AppInfo.appVersion}
98
+ </Typography>
99
+ </Box>
100
+ </Box>
101
+ </SwipeableDrawer>
102
+ );
103
+ }