ui-soxo-bootstrap-core 2.5.0 → 2.5.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.
- package/core/components/external-window/external-window.js +178 -167
- package/core/components/extra-info/extra-info-details.js +109 -126
- package/core/lib/components/sidemenu/sidemenu.js +193 -238
- package/core/lib/components/sidemenu/sidemenu.scss +39 -26
- package/core/lib/pages/profile/theme-config.js +1 -1
- package/core/modules/index.js +0 -4
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +53 -13
- package/core/modules/steps/action-buttons.js +29 -41
- package/core/modules/steps/action-buttons.scss +16 -0
- package/core/modules/steps/steps.js +71 -57
- package/core/modules/steps/steps.scss +4 -3
- package/package.json +1 -1
|
@@ -1,137 +1,103 @@
|
|
|
1
1
|
/**
|
|
2
2
|
*
|
|
3
3
|
* Sidemenu component
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* @author Ashique Mohammed
|
|
6
|
-
* @co-author Sneha
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* @co-author Sneha
|
|
7
|
+
*
|
|
8
|
+
*
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import React, { useState, useEffect, useContext } from
|
|
11
|
+
import React, { useState, useEffect, useContext } from 'react';
|
|
12
12
|
|
|
13
|
-
import { animationControls, motion, useAnimation } from
|
|
13
|
+
import { animationControls, motion, useAnimation } from 'framer-motion';
|
|
14
14
|
|
|
15
|
-
import { GlobalContext } from
|
|
15
|
+
import { GlobalContext } from './../../Store';
|
|
16
16
|
|
|
17
|
-
import { Menu, message, Skeleton, Space } from
|
|
17
|
+
import { Menu, message, Skeleton, Space, Popover } from 'antd';
|
|
18
18
|
|
|
19
|
-
import FirebaseUtils from
|
|
19
|
+
import FirebaseUtils from './../../utils/firebase.utils';
|
|
20
20
|
|
|
21
|
-
import { useHistory } from
|
|
21
|
+
import { useHistory } from 'react-router-dom';
|
|
22
22
|
|
|
23
23
|
import { useTranslation, Trans } from 'react-i18next';
|
|
24
24
|
|
|
25
|
-
import { Menus } from
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
import { Menus } from '../../models';
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
import "./sidemenu.scss";
|
|
27
|
+
import './sidemenu.scss';
|
|
31
28
|
|
|
32
29
|
const { SubMenu } = Menu;
|
|
33
30
|
|
|
34
|
-
|
|
35
31
|
/**
|
|
36
|
-
*
|
|
37
|
-
* @param {*} collapsed
|
|
38
|
-
* @param {*} icon
|
|
39
|
-
* @param {*} caption
|
|
40
|
-
* @returns
|
|
32
|
+
*
|
|
33
|
+
* @param {*} collapsed
|
|
34
|
+
* @param {*} icon
|
|
35
|
+
* @param {*} caption
|
|
36
|
+
* @returns
|
|
41
37
|
*/
|
|
42
38
|
function CollapsedIconMenu({ menu, collapsed, icon, caption }) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
39
|
// Import t and i18n from useTranslation
|
|
47
40
|
const { t, i18n } = useTranslation();
|
|
48
41
|
const { state } = useContext(GlobalContext);
|
|
49
|
-
|
|
42
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
50
43
|
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const handleResize = () => {
|
|
46
|
+
setIsMobile(window.innerWidth < 768); // Common breakpoint for mobile
|
|
47
|
+
};
|
|
51
48
|
|
|
52
|
-
|
|
49
|
+
handleResize(); // Set initial value
|
|
50
|
+
window.addEventListener('resize', handleResize);
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
53
|
+
}, []);
|
|
55
54
|
|
|
55
|
+
const menuText = t(caption);
|
|
56
|
+
const menuContent = (
|
|
57
|
+
<>
|
|
56
58
|
{/* If value of collapsed is false show caption & icon else hiding caption and showing only icon*/}
|
|
57
59
|
{!collapsed ? (
|
|
58
|
-
|
|
59
|
-
<div
|
|
60
|
-
|
|
61
|
-
className="menu-collapsed" >
|
|
62
|
-
|
|
60
|
+
<div className="menu-collapsed">
|
|
63
61
|
<div>
|
|
64
|
-
|
|
65
|
-
{
|
|
66
|
-
menu && menu.image_path ?
|
|
67
|
-
<img style={{ width: '25px' }} src={menu.image_path}></img>
|
|
68
|
-
:
|
|
69
|
-
<i className={`fa-solid fas ${icon}`} />
|
|
70
|
-
}
|
|
71
|
-
|
|
62
|
+
{menu && menu.image_path ? <img style={{ width: '25px' }} src={menu.image_path}></img> : <i className={`fa-solid fas ${icon}`} />}
|
|
72
63
|
</div>
|
|
73
64
|
|
|
74
65
|
<div style={{ color: state.theme.colors.leftSectionColor }}>
|
|
75
|
-
|
|
76
66
|
<span className="caption">
|
|
77
|
-
|
|
78
67
|
{/* {caption} */}
|
|
79
68
|
{/* <Trans i18nKey="Appointments"></Trans> */}
|
|
80
69
|
{t(`${caption}`)}
|
|
81
|
-
|
|
82
70
|
</span>
|
|
83
|
-
|
|
84
71
|
</div>
|
|
85
|
-
|
|
86
72
|
</div>
|
|
87
|
-
|
|
88
73
|
) : (
|
|
89
|
-
|
|
90
|
-
<div
|
|
91
|
-
|
|
92
|
-
className="menu-collapsed">
|
|
93
|
-
|
|
74
|
+
<div className="menu-collapsed">
|
|
94
75
|
<span className="anticon">
|
|
95
|
-
|
|
96
|
-
{
|
|
97
|
-
menu && menu.image_path ?
|
|
98
|
-
<img style={{ width: '25px' }} src={menu.image_path}></img>
|
|
99
|
-
:
|
|
100
|
-
<i className={`fa-solid fas ${icon}`} />
|
|
101
|
-
}
|
|
102
|
-
|
|
76
|
+
{menu && menu.image_path ? <img style={{ width: '25px' }} src={menu.image_path}></img> : <i className={`fa-solid fas ${icon}`} />}
|
|
103
77
|
</span>
|
|
104
78
|
|
|
105
|
-
<span
|
|
106
|
-
|
|
79
|
+
<span style={{ color: state.theme.colors.colorPrimaryText, paddingLeft: '6px' }}>
|
|
107
80
|
{/* <>{caption}</> */}
|
|
108
81
|
{t(`${caption}`)}
|
|
109
|
-
|
|
110
82
|
</span>
|
|
111
|
-
|
|
112
83
|
</div>
|
|
113
|
-
|
|
114
84
|
)}
|
|
115
|
-
|
|
116
85
|
</>
|
|
86
|
+
);
|
|
117
87
|
|
|
118
|
-
|
|
119
|
-
|
|
88
|
+
// On mobile, or when the menu is collapsed (based on original logic), don't show the popover tooltip.
|
|
89
|
+
return isMobile || collapsed ? menuContent : <Popover content={menuText} placement="right">{menuContent}</Popover>;
|
|
120
90
|
}
|
|
121
91
|
|
|
122
|
-
export default function SideMenu({
|
|
123
|
-
|
|
124
|
-
modules = [],
|
|
125
|
-
callback,
|
|
126
|
-
appSettings,
|
|
127
|
-
collapsed,
|
|
128
|
-
}) {
|
|
129
|
-
const { brandLogo, footerLogo, renderCustomHeader = () => { } } = appSettings;
|
|
92
|
+
export default function SideMenu({ loading, modules = [], callback, appSettings, collapsed }) {
|
|
93
|
+
const { brandLogo, footerLogo, renderCustomHeader = () => {} } = appSettings;
|
|
130
94
|
|
|
131
|
-
|
|
95
|
+
let history = useHistory();
|
|
132
96
|
|
|
133
|
-
const [selected, setSelected] = useState([1]);
|
|
97
|
+
// const [selected, setSelected] = useState([1]);
|
|
134
98
|
|
|
99
|
+
const [selectedKeys, setSelectedKeys] = useState([]);
|
|
100
|
+
const [openKeys, setOpenKeys] = useState([]);
|
|
135
101
|
const [menu, setMenu] = useState({});
|
|
136
102
|
|
|
137
103
|
const { user = { locations: [] }, dispatch, state } = useContext(GlobalContext);
|
|
@@ -147,11 +113,16 @@ export default function SideMenu({
|
|
|
147
113
|
// }
|
|
148
114
|
}, [user]);
|
|
149
115
|
|
|
116
|
+
// Keep current menu item selected after reload or navigation
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
const currentPath = history.location.pathname;
|
|
119
|
+
setSelectedKeys([currentPath]);
|
|
120
|
+
}, [history.location.pathname]);
|
|
121
|
+
|
|
150
122
|
/**
|
|
151
123
|
* Logout Function
|
|
152
124
|
*/
|
|
153
125
|
async function handleLogout() {
|
|
154
|
-
|
|
155
126
|
let dbPtrValue = appSettings.headers.db_ptr;
|
|
156
127
|
const isEnvThemeTrue = process.env.REACT_APP_THEME === 'true';
|
|
157
128
|
|
|
@@ -162,11 +133,9 @@ export default function SideMenu({
|
|
|
162
133
|
|
|
163
134
|
// localStorage.clear();
|
|
164
135
|
|
|
165
|
-
if (process.env.REACT_APP_PRIMARY_BACKEND ===
|
|
166
|
-
|
|
136
|
+
if (process.env.REACT_APP_PRIMARY_BACKEND === 'SQL') {
|
|
167
137
|
// const result = Users.logout()
|
|
168
138
|
localStorage.clear();
|
|
169
|
-
|
|
170
139
|
|
|
171
140
|
localStorage.setItem('db_ptr', dbPtrValue);
|
|
172
141
|
|
|
@@ -176,16 +145,16 @@ export default function SideMenu({
|
|
|
176
145
|
...{ loggedCheckDone: true },
|
|
177
146
|
};
|
|
178
147
|
|
|
179
|
-
dispatch({ type:
|
|
148
|
+
dispatch({ type: 'user', payload: userInfo });
|
|
180
149
|
|
|
181
|
-
history.push(
|
|
150
|
+
history.push('/login');
|
|
182
151
|
|
|
183
|
-
message.success(
|
|
152
|
+
message.success('You have logged out successfully.');
|
|
184
153
|
} else {
|
|
185
154
|
FirebaseUtils.logout().then(() => {
|
|
186
|
-
history.push(
|
|
155
|
+
history.push('/login');
|
|
187
156
|
|
|
188
|
-
message.success(
|
|
157
|
+
message.success('You have logged out successfully.');
|
|
189
158
|
});
|
|
190
159
|
}
|
|
191
160
|
}
|
|
@@ -194,15 +163,80 @@ export default function SideMenu({
|
|
|
194
163
|
* Menu Click Function
|
|
195
164
|
*/
|
|
196
165
|
|
|
166
|
+
// const onMenuClick = (menu, index) => {
|
|
167
|
+
// setSelected([index]);
|
|
168
|
+
|
|
169
|
+
// history.push(menu.path);
|
|
170
|
+
|
|
171
|
+
// setMenu(menu);
|
|
172
|
+
|
|
173
|
+
// callback();
|
|
174
|
+
// };
|
|
175
|
+
|
|
197
176
|
const onMenuClick = (menu, index) => {
|
|
198
|
-
|
|
177
|
+
const key = menu.path || `menu-${menu.id || index}`;
|
|
178
|
+
|
|
179
|
+
if (menu.isRoot) {
|
|
180
|
+
setOpenKeys([]);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
setSelectedKeys([key]);
|
|
199
184
|
|
|
200
|
-
|
|
185
|
+
if (menu.path) {
|
|
186
|
+
history.push(menu.path);
|
|
187
|
+
}
|
|
201
188
|
|
|
202
189
|
setMenu(menu);
|
|
190
|
+
if (callback) callback();
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Controls submenu open/close behavior.
|
|
195
|
+
*
|
|
196
|
+
* - Detects the most recently opened menu key.
|
|
197
|
+
* - When opening a submenu, keeps only its full parent path expanded
|
|
198
|
+
* (accordion behavior).
|
|
199
|
+
* - When closing a submenu, updates state without recalculating paths.
|
|
200
|
+
*
|
|
201
|
+
* @param {string[]} keys - Currently open menu keys from the Menu component.
|
|
202
|
+
*
|
|
203
|
+
* Assumptions:
|
|
204
|
+
* - Menu keys are stable and unique.
|
|
205
|
+
* - Only one menu branch should be open at a time.
|
|
206
|
+
*/
|
|
207
|
+
const onOpenChange = (keys) => {
|
|
208
|
+
const latestOpenKey = keys.find((k) => !openKeys.includes(k));
|
|
209
|
+
|
|
210
|
+
if (!latestOpenKey) {
|
|
211
|
+
setOpenKeys(keys);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
203
214
|
|
|
204
|
-
|
|
215
|
+
const findPath = (items) => {
|
|
216
|
+
const sortedItems = Menus.screenMenus(items, 'order');
|
|
217
|
+
for (const item of sortedItems) {
|
|
218
|
+
const key = String(item.id || item.path || item.caption);
|
|
219
|
+
if (key === latestOpenKey) {
|
|
220
|
+
return [key];
|
|
221
|
+
}
|
|
222
|
+
if (item.sub_menus) {
|
|
223
|
+
const childPath = findPath(item.sub_menus);
|
|
224
|
+
if (childPath) {
|
|
225
|
+
return [key, ...childPath];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const path = findPath(modules);
|
|
233
|
+
if (path) {
|
|
234
|
+
setOpenKeys(path);
|
|
235
|
+
} else {
|
|
236
|
+
setOpenKeys(keys);
|
|
237
|
+
}
|
|
205
238
|
};
|
|
239
|
+
|
|
206
240
|
/**
|
|
207
241
|
* Function renders the footer logo
|
|
208
242
|
*
|
|
@@ -210,15 +244,14 @@ export default function SideMenu({
|
|
|
210
244
|
*/
|
|
211
245
|
function renderFooter(footerLogo) {
|
|
212
246
|
return (
|
|
213
|
-
<div className={`sidebar-footer ${!collapsed ?
|
|
214
|
-
<img className="footer-logo" src={footerLogo} alt={
|
|
247
|
+
<div className={`sidebar-footer ${!collapsed ? 'open' : 'close'}`}>
|
|
248
|
+
<img className="footer-logo" src={footerLogo} alt={'footer-logo'} />
|
|
215
249
|
</div>
|
|
216
250
|
);
|
|
217
251
|
}
|
|
218
252
|
|
|
219
253
|
let icon;
|
|
220
254
|
|
|
221
|
-
|
|
222
255
|
let index = 0;
|
|
223
256
|
|
|
224
257
|
useEffect(() => {
|
|
@@ -227,6 +260,7 @@ export default function SideMenu({
|
|
|
227
260
|
// document.documentElement.style.setProperty('--custom-text-color', state.theme.colors.colorText);
|
|
228
261
|
}, [state.theme]);
|
|
229
262
|
|
|
263
|
+
const rootSubmenuKeys = Menus.screenMenus(modules, 'order').map((m) => m.id || m.path || m.caption);
|
|
230
264
|
|
|
231
265
|
return (
|
|
232
266
|
<div className="sidemenu">
|
|
@@ -235,16 +269,19 @@ export default function SideMenu({
|
|
|
235
269
|
<Skeleton.Avatar />
|
|
236
270
|
<Skeleton.Button />
|
|
237
271
|
{/* <Skeleton.Input /> */}
|
|
238
|
-
</Space>
|
|
239
|
-
|
|
240
|
-
<div
|
|
272
|
+
</Space>
|
|
273
|
+
) : (
|
|
274
|
+
<div
|
|
275
|
+
className="intro"
|
|
276
|
+
style={{ backgroundColor: state.theme.colors.leftSectionBackground, borderBottom: `2px solid ${state.theme.colors.borderColor}` }}
|
|
277
|
+
>
|
|
241
278
|
{/* Logo Bar */}
|
|
242
279
|
<div className="logo-wrapper">
|
|
243
280
|
{/* Changing the size of logo bar according to the value of collapsed */}
|
|
244
281
|
<img
|
|
245
|
-
className={`sidemenu-brand-logo ${!collapsed ?
|
|
282
|
+
className={`sidemenu-brand-logo ${!collapsed ? 'open' : 'close'}`}
|
|
246
283
|
onClick={() => {
|
|
247
|
-
history.push(
|
|
284
|
+
history.push('/');
|
|
248
285
|
}}
|
|
249
286
|
src={brandLogo}
|
|
250
287
|
alt="Logo"
|
|
@@ -255,25 +292,26 @@ export default function SideMenu({
|
|
|
255
292
|
{/* If value of collapsed is true show version else not showing */}
|
|
256
293
|
|
|
257
294
|
{!collapsed && process.env.REACT_APP_package_version && (
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
295
|
+
<small
|
|
296
|
+
style={{
|
|
297
|
+
color: state.theme.colors.leftSectionColor,
|
|
298
|
+
}}
|
|
299
|
+
>
|
|
300
|
+
{process.env.REACT_APP_package_version}
|
|
301
|
+
</small>
|
|
302
|
+
)}
|
|
263
303
|
</div>
|
|
264
304
|
{/* Logo Bar Ends */}
|
|
265
305
|
|
|
266
306
|
{/* If value of collapsed is true render header else not rendering */}
|
|
267
307
|
|
|
268
|
-
{!collapsed ? renderCustomHeader() :
|
|
269
|
-
|
|
308
|
+
{!collapsed ? renderCustomHeader() : ''}
|
|
270
309
|
</div>
|
|
271
|
-
}
|
|
310
|
+
)}
|
|
272
311
|
|
|
273
312
|
{/* Intro Component */}
|
|
274
313
|
{/* Intro Component Ends */}
|
|
275
314
|
|
|
276
|
-
|
|
277
315
|
{/* Search for Queries */}
|
|
278
316
|
|
|
279
317
|
{/* <div className="menu-search">
|
|
@@ -285,15 +323,11 @@ export default function SideMenu({
|
|
|
285
323
|
|
|
286
324
|
{/* Search for Queries Ends */}
|
|
287
325
|
|
|
288
|
-
<div className={`menu-item ${!collapsed ?
|
|
289
|
-
|
|
326
|
+
<div className={`menu-item ${!collapsed ? 'open' : 'close'}`} style={{ backgroundColor: state.theme.colors.leftSectionBackground }}>
|
|
290
327
|
{loading ? (
|
|
291
328
|
<></>
|
|
292
329
|
) : (
|
|
293
|
-
|
|
294
|
-
|
|
295
330
|
<Menu
|
|
296
|
-
|
|
297
331
|
// selectedKeys={[selected]}
|
|
298
332
|
// style={{ width: 256 }}
|
|
299
333
|
// defaultSelectedKeys={selected}
|
|
@@ -301,10 +335,12 @@ export default function SideMenu({
|
|
|
301
335
|
inlineCollapsed={collapsed}
|
|
302
336
|
mode="inline"
|
|
303
337
|
theme={process.env.REACT_APP_THEME}
|
|
304
|
-
|
|
305
|
-
|
|
338
|
+
selectedKeys={selectedKeys}
|
|
339
|
+
openKeys={openKeys}
|
|
340
|
+
onOpenChange={onOpenChange}
|
|
341
|
+
style={{ backgroundColor: state.theme.colors.leftSectionBackground, color: state.theme.colors.leftSectionColor }}
|
|
342
|
+
// theme={''}
|
|
306
343
|
>
|
|
307
|
-
|
|
308
344
|
{/* <Menu.Item
|
|
309
345
|
onClick={() => {
|
|
310
346
|
setSelected([1]);
|
|
@@ -324,7 +360,6 @@ export default function SideMenu({
|
|
|
324
360
|
/>
|
|
325
361
|
</Menu.Item> */}
|
|
326
362
|
|
|
327
|
-
|
|
328
363
|
{/* {
|
|
329
364
|
Menus.screenMenus(modules).map((menu, index) => {
|
|
330
365
|
|
|
@@ -332,7 +367,7 @@ export default function SideMenu({
|
|
|
332
367
|
})
|
|
333
368
|
} */}
|
|
334
369
|
|
|
335
|
-
{Menus.screenMenus(modules,
|
|
370
|
+
{Menus.screenMenus(modules, 'order')
|
|
336
371
|
|
|
337
372
|
.filter((record) => {
|
|
338
373
|
icon = record;
|
|
@@ -354,207 +389,133 @@ export default function SideMenu({
|
|
|
354
389
|
.map((menu, index) => {
|
|
355
390
|
// return <MenuItem menu={menu} index={index} />
|
|
356
391
|
|
|
357
|
-
let sub_menus =
|
|
358
|
-
menu && menu.sub_menus
|
|
359
|
-
? Menus.screenMenus(menu.sub_menus)
|
|
360
|
-
: [];
|
|
392
|
+
let sub_menus = menu && menu.sub_menus ? Menus.screenMenus(menu.sub_menus) : [];
|
|
361
393
|
|
|
362
394
|
if (menu && sub_menus && sub_menus.length) {
|
|
363
|
-
|
|
364
|
-
let randomIndex = parseInt(Math.random() * 10000000000);
|
|
395
|
+
// let randomIndex = parseInt(Math.random() * 10000000000);
|
|
365
396
|
|
|
366
397
|
return (
|
|
367
|
-
|
|
368
398
|
<SubMenu
|
|
369
|
-
|
|
370
399
|
className="popup"
|
|
371
|
-
style={{ color:state.theme.colors.leftSectionColor}}
|
|
372
|
-
|
|
373
|
-
key={`first-level-${randomIndex}-${menu.caption}`}
|
|
400
|
+
style={{ color: state.theme.colors.leftSectionColor }}
|
|
401
|
+
// key={`first-level-${randomIndex}-${menu.caption}`}
|
|
374
402
|
|
|
403
|
+
key={menu.id || menu.path || menu.caption}
|
|
375
404
|
title={
|
|
376
|
-
|
|
377
405
|
<>
|
|
378
|
-
|
|
379
406
|
<CollapsedIconMenu
|
|
380
|
-
|
|
381
407
|
menu={menu}
|
|
382
|
-
|
|
383
408
|
caption={menu.caption}
|
|
384
|
-
|
|
385
409
|
icon={menu.icon_name || 'fa-solid fas fa-user'}
|
|
386
|
-
|
|
387
|
-
|
|
388
410
|
collapsed={collapsed}
|
|
389
|
-
|
|
390
411
|
/>
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
412
|
</>
|
|
395
|
-
|
|
396
413
|
}
|
|
397
|
-
|
|
398
414
|
>
|
|
399
415
|
{sub_menus.map((submenu, innerIndex) => {
|
|
400
|
-
let randomIndex = parseInt(Math.random() * 10000000000);
|
|
416
|
+
// let randomIndex = parseInt(Math.random() * 10000000000);
|
|
401
417
|
|
|
402
|
-
let third_menus =
|
|
403
|
-
submenu && submenu.sub_menus
|
|
404
|
-
? Menus.screenMenus(submenu.sub_menus)
|
|
405
|
-
: [];
|
|
418
|
+
let third_menus = submenu && submenu.sub_menus ? Menus.screenMenus(submenu.sub_menus) : [];
|
|
406
419
|
|
|
407
420
|
if (third_menus && third_menus.length) {
|
|
408
421
|
return (
|
|
409
422
|
<SubMenu
|
|
410
|
-
|
|
411
423
|
className="popup"
|
|
424
|
+
// key={`second-level-${randomIndex}-${submenu.id}`}
|
|
412
425
|
|
|
413
|
-
key={
|
|
414
|
-
|
|
426
|
+
key={submenu.id || submenu.path || submenu.caption}
|
|
415
427
|
title={
|
|
416
|
-
|
|
417
428
|
<span>
|
|
418
|
-
|
|
419
429
|
<CollapsedIconMenu
|
|
420
|
-
|
|
421
430
|
menu={menu}
|
|
422
|
-
|
|
423
431
|
caption={submenu.caption}
|
|
424
|
-
|
|
425
432
|
icon={submenu.icon_name || 'fa-solid fas fa-user'}
|
|
426
|
-
|
|
427
433
|
collapsed={collapsed}
|
|
428
|
-
|
|
429
434
|
/>
|
|
430
|
-
|
|
431
|
-
|
|
432
435
|
</span>
|
|
433
436
|
}
|
|
434
437
|
>
|
|
435
438
|
{third_menus.map((menu) => {
|
|
436
|
-
let randomIndex = parseInt(
|
|
437
|
-
Math.random() * 10000000000
|
|
438
|
-
);
|
|
439
|
+
// let randomIndex = parseInt(Math.random() * 10000000000);
|
|
439
440
|
|
|
440
441
|
return (
|
|
441
442
|
<Menu.Item
|
|
443
|
+
// onClick={() => {
|
|
444
|
+
// onMenuClick(menu, index);
|
|
445
|
+
// }}
|
|
442
446
|
onClick={() => {
|
|
443
|
-
onMenuClick(menu, index);
|
|
447
|
+
onMenuClick({ ...menu, parentKey: submenu.path || submenu.caption }, index);
|
|
444
448
|
}}
|
|
445
|
-
key={`second-level-${randomIndex}-${index}`}
|
|
446
|
-
>
|
|
449
|
+
// key={`second-level-${randomIndex}-${index}`}
|
|
447
450
|
|
|
451
|
+
key={menu.path || menu.caption}
|
|
452
|
+
>
|
|
448
453
|
<CollapsedIconMenu
|
|
449
|
-
|
|
450
454
|
menu={menu}
|
|
451
|
-
|
|
452
455
|
caption={menu.caption}
|
|
453
|
-
|
|
454
456
|
icon={menu.icon_name || 'fa-solid fas fa-user'}
|
|
455
|
-
|
|
456
|
-
|
|
457
457
|
collapsed={collapsed}
|
|
458
|
-
|
|
459
458
|
/>
|
|
460
|
-
|
|
461
459
|
</Menu.Item>
|
|
462
460
|
);
|
|
463
461
|
})}
|
|
464
462
|
</SubMenu>
|
|
465
463
|
);
|
|
466
464
|
} else {
|
|
467
|
-
let randomIndex = parseInt(
|
|
468
|
-
Math.random() * 10000000000
|
|
469
|
-
);
|
|
465
|
+
// let randomIndex = parseInt(Math.random() * 10000000000);
|
|
470
466
|
|
|
471
467
|
return (
|
|
472
468
|
<Menu.Item
|
|
469
|
+
// onClick={() => {
|
|
470
|
+
// onMenuClick(submenu, index);
|
|
471
|
+
// }}
|
|
473
472
|
onClick={() => {
|
|
474
|
-
onMenuClick(submenu, index);
|
|
473
|
+
onMenuClick({ ...submenu, parentKey: menu.path || menu.caption }, index);
|
|
475
474
|
}}
|
|
476
|
-
key={`first-level-${randomIndex}-${innerIndex}`}
|
|
475
|
+
// key={`first-level-${randomIndex}-${innerIndex}`}
|
|
476
|
+
key={submenu.path || submenu.caption}
|
|
477
477
|
>
|
|
478
|
-
|
|
479
478
|
<CollapsedIconMenu
|
|
480
|
-
|
|
481
479
|
menu={menu}
|
|
482
|
-
|
|
483
480
|
caption={submenu.caption}
|
|
484
|
-
|
|
485
481
|
icon={submenu.icon_name || 'fa-solid fas fa-user'}
|
|
486
|
-
|
|
487
|
-
|
|
488
482
|
collapsed={collapsed}
|
|
489
|
-
|
|
490
483
|
/>
|
|
491
|
-
|
|
492
484
|
</Menu.Item>
|
|
493
|
-
|
|
494
485
|
);
|
|
495
|
-
|
|
496
486
|
}
|
|
497
|
-
|
|
498
487
|
})}
|
|
499
|
-
|
|
500
488
|
</SubMenu>
|
|
501
|
-
|
|
502
489
|
);
|
|
503
490
|
} else {
|
|
504
|
-
let randomIndex = parseInt(Math.random() * 10000000000);
|
|
491
|
+
// let randomIndex = parseInt(Math.random() * 10000000000);
|
|
505
492
|
|
|
506
493
|
return (
|
|
507
|
-
|
|
508
494
|
<Menu.Item
|
|
495
|
+
// onClick={() => {
|
|
496
|
+
// onMenuClick(menu, index);
|
|
497
|
+
// }}
|
|
498
|
+
|
|
509
499
|
onClick={() => {
|
|
510
|
-
onMenuClick(menu, index);
|
|
500
|
+
onMenuClick({ ...menu, parentKey: menu.path || menu.caption, isRoot: true }, index);
|
|
511
501
|
}}
|
|
512
|
-
key={`${menu.id}-${randomIndex}`}
|
|
502
|
+
// key={`${menu.id}-${randomIndex}`}
|
|
503
|
+
key={menu.path || menu.caption}
|
|
513
504
|
>
|
|
514
|
-
|
|
515
|
-
<CollapsedIconMenu
|
|
516
|
-
|
|
517
|
-
menu={menu}
|
|
518
|
-
|
|
519
|
-
caption={menu.caption}
|
|
520
|
-
|
|
521
|
-
icon={menu.icon_name || 'fa-solid fas fa-user'}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
collapsed={collapsed}
|
|
525
|
-
|
|
526
|
-
/>
|
|
527
|
-
|
|
528
|
-
|
|
505
|
+
<CollapsedIconMenu menu={menu} caption={menu.caption} icon={menu.icon_name || 'fa-solid fas fa-user'} collapsed={collapsed} />
|
|
529
506
|
</Menu.Item>
|
|
530
|
-
|
|
531
507
|
);
|
|
532
508
|
}
|
|
533
509
|
})}
|
|
534
510
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
<CollapsedIconMenu
|
|
540
|
-
|
|
541
|
-
caption="Logout"
|
|
542
|
-
|
|
543
|
-
icon='fa-solid fas fa-user'
|
|
544
|
-
|
|
545
|
-
collapsed={collapsed}
|
|
546
|
-
|
|
547
|
-
/>
|
|
548
|
-
|
|
549
|
-
|
|
511
|
+
{loading ? (
|
|
512
|
+
<div class="skeleton-wrapper"></div>
|
|
513
|
+
) : (
|
|
514
|
+
<Menu.Item onClick={handleLogout} key="logout-button">
|
|
515
|
+
<CollapsedIconMenu caption="Logout" icon="fa-solid fas fa-user" collapsed={collapsed} />
|
|
550
516
|
</Menu.Item>
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
517
|
+
)}
|
|
556
518
|
</Menu>
|
|
557
|
-
|
|
558
519
|
)}
|
|
559
520
|
|
|
560
521
|
{/* Footer Logo */}
|
|
@@ -570,16 +531,14 @@ export default function SideMenu({
|
|
|
570
531
|
* sub menus
|
|
571
532
|
*/
|
|
572
533
|
function MenuItem({ menu, index, history }) {
|
|
573
|
-
|
|
574
534
|
function renderMenus({ menu, index }) {
|
|
575
535
|
let sub_menus = [];
|
|
576
536
|
|
|
577
537
|
if (menu.sub_menus) {
|
|
578
|
-
sub_menus = Menus.screenMenus(menu.sub_menus)
|
|
538
|
+
sub_menus = Menus.screenMenus(menu.sub_menus);
|
|
579
539
|
}
|
|
580
540
|
|
|
581
541
|
if (menu && sub_menus && sub_menus.length) {
|
|
582
|
-
|
|
583
542
|
// return 'hello';
|
|
584
543
|
return (
|
|
585
544
|
<SubMenu
|
|
@@ -591,9 +550,7 @@ function MenuItem({ menu, index, history }) {
|
|
|
591
550
|
}
|
|
592
551
|
>
|
|
593
552
|
{menu.sub_menus.map((menu, index) => {
|
|
594
|
-
return
|
|
595
|
-
<MenuItem menu={menu} index={menu.id} />
|
|
596
|
-
);
|
|
553
|
+
return <MenuItem menu={menu} index={menu.id} />;
|
|
597
554
|
})}
|
|
598
555
|
</SubMenu>
|
|
599
556
|
);
|
|
@@ -611,7 +568,5 @@ function MenuItem({ menu, index, history }) {
|
|
|
611
568
|
}
|
|
612
569
|
}
|
|
613
570
|
|
|
614
|
-
|
|
615
571
|
return renderMenus({ menu, index });
|
|
616
|
-
|
|
617
|
-
}
|
|
572
|
+
}
|