@argusoft/medplat-app-shell 1.0.6 → 1.0.8

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 (264) hide show
  1. package/package.json +139 -141
  2. package/src/GlobalErrorBoundary.jsx +31 -0
  3. package/src/SilentErrorFallback.jsx +68 -0
  4. package/src/TrackingProviderWrapper.jsx +40 -0
  5. package/src/_tests_/__mocks__/MockTranslationProvider.jsx +21 -0
  6. package/src/_tests_/__mocks__/ckeditor.js +45 -0
  7. package/src/_tests_/__mocks__/fileMock.js +1 -0
  8. package/src/_tests_/__mocks__/useranalytics.js +5 -0
  9. package/src/_tests_/views/components/Dashboard/DashboardUI.test.jsx +137 -0
  10. package/src/_tests_/views/components/Dashboard/DashboardUIMock.js +877 -0
  11. package/src/_tests_/views/components/ForgotPassword/ForgotPassword.test.jsx +314 -0
  12. package/src/_tests_/views/components/LocationDirective/LocationDirective.test.jsx.disable +229 -0
  13. package/src/_tests_/views/components/LocationDirective/mockLocationDirective.js +810 -0
  14. package/src/_tests_/views/components/LocationType/MockLocationType.js +42259 -0
  15. package/src/_tests_/views/components/LocationType/addlocationtype.test.jsx.disable +276 -0
  16. package/src/_tests_/views/components/LocationType/editlocationtype.test.jsx.disable +262 -0
  17. package/src/_tests_/views/components/LocationType/locationtype.test.jsx.disable +148 -0
  18. package/src/_tests_/views/components/Profile/UpdateProfileModalData.js +4396 -0
  19. package/src/_tests_/views/components/Profile/updateprofilemodal.test.jsx +282 -0
  20. package/src/_tests_/views/components/SideBar/MockSideBar.js +1379 -0
  21. package/src/_tests_/views/components/SideBar/SideBar.test.jsx +98 -0
  22. package/src/_tests_/views/components/SystemConfig/ManageSystemConfig/AddManageSystemConfig.test.jsx.disable +164 -0
  23. package/src/_tests_/views/components/SystemConfig/ManageSystemConfig/UpdateManageSystemConfig.test.jsx.disable +157 -0
  24. package/src/_tests_/views/components/SystemConfig/MockSystemConfig.js +1280 -0
  25. package/src/_tests_/views/components/SystemConfig/SystemConfig.test.jsx.disable +165 -0
  26. package/src/_tests_/views/components/login/Login.test.jsx +276 -0
  27. package/src/_tests_/views/components/login/MockAuthorise.js +2414 -0
  28. package/src/_tests_/views/components/login/ServiceResponse.js +595 -0
  29. package/src/_tests_/views/components/user/MockManageUser.js +7965 -0
  30. package/src/_tests_/views/components/user/manageuser.test.jsx.disable +989 -0
  31. package/src/_tests_/views/components/user/mockUsersData.js +582 -0
  32. package/src/assets/img/OASISLogin.png +0 -0
  33. package/src/assets/img/bahaarNew.png +0 -0
  34. package/src/assets/img/dnhdd4K.png +0 -0
  35. package/src/assets/img/govtofup.png +0 -0
  36. package/src/assets/img/sewarural4K.png +0 -0
  37. package/src/assets/img/techo4K.png +0 -0
  38. package/src/assets/img/up4K.png +0 -0
  39. package/src/common/HolidayList.jsx +573 -0
  40. package/src/common/MalaciaousInputUtil.js +23 -0
  41. package/src/common/SafeHtml.jsx +17 -0
  42. package/src/common/VersionManager.jsx +109 -0
  43. package/src/common/constants/PerformanceDashboard.js +514 -0
  44. package/src/common/constants/app.constant.js +781 -0
  45. package/src/common/constants/cccVerificationConstants.js +18 -0
  46. package/src/common/constants/fhsrConstant.js +33 -0
  47. package/src/common/constants/gvk-verification.constant.js +76 -0
  48. package/src/common/constants/search.constant.js +23 -0
  49. package/src/common/constants/teleconsulatationConstant.jsx +1339 -0
  50. package/src/common/directives/SearchTemplate.jsx +784 -0
  51. package/src/common/directives/SearchTemplate.scss +14 -0
  52. package/src/common/dynamicView/DynamicView.jsx +353 -0
  53. package/src/common/dynamicView/InputFieldComponent.jsx +1501 -0
  54. package/src/common/dynamicView/InputViewComponent.jsx +298 -0
  55. package/src/common/dynamicView/InputViewComponent.scss +15 -0
  56. package/src/common/env.js +5 -0
  57. package/src/common/filters/locationNameFilter.js +26 -0
  58. package/src/common/fontAwesomeIcons/FontAwesomeIcons.jsx +27 -0
  59. package/src/common/fontAwesomeIcons/FontAwesomeIconsNames.js +1968 -0
  60. package/src/common/fontPreferences/fontSizeProvider.jsx +34 -0
  61. package/src/common/fontPreferences/fontSizeSelector.jsx +116 -0
  62. package/src/common/getAssignedFeature/getAssignedFeature.js +32 -0
  63. package/src/common/interceptors/AxiosInterceptor.js +216 -0
  64. package/src/common/languageTranslator/TranslationContext.js +5 -0
  65. package/src/common/languageTranslator/TranslationProvider.jsx +24 -0
  66. package/src/common/languageTranslator/i18n.js +49 -0
  67. package/src/common/services/AuthenticateService.js +116 -0
  68. package/src/common/services/DownloadFile.js +35 -0
  69. package/src/common/services/ForgotPassword.js +18 -0
  70. package/src/common/services/FormConfiguratorService.js +195 -0
  71. package/src/common/services/GlobalApis.js +84 -0
  72. package/src/common/services/InterceptorNavigationService.js +17 -0
  73. package/src/common/services/LocationService.js +65 -0
  74. package/src/common/services/LocationType.js +11 -0
  75. package/src/common/services/QueryBuilder.js +36 -0
  76. package/src/common/services/Roles.js +28 -0
  77. package/src/common/services/SyncWithServer.js +15 -0
  78. package/src/common/services/SystemConfig.js +15 -0
  79. package/src/common/services/TranslationService.js +70 -0
  80. package/src/common/services/TwoFactorService.js +7 -0
  81. package/src/common/services/Users.js +91 -0
  82. package/src/common/services/Webtasks.js +27 -0
  83. package/src/common/services/util/Convert-pad-data-to-API-format.jsx +167 -0
  84. package/src/common/services/util/Convert-to-UI-format.jsx +82 -0
  85. package/src/common/services/util/EmptyPrescriptionPadData.jsx +11 -0
  86. package/src/common/services/util/GeneralUtil.js +456 -0
  87. package/src/common/services/util/Prescription-pad-util.js +339 -0
  88. package/src/common/services/util/PrescriptionPadData.js +67 -0
  89. package/src/common/services/util/PrescriptionpadCommonUtil.js +96 -0
  90. package/src/common/services/util/ReportFieldUtil.jsx +398 -0
  91. package/src/common/services/util/WebSocketContext.jsx +261 -0
  92. package/src/common/syncWithServer/SyncWithServerDialog.jsx +170 -0
  93. package/src/common/syncWithServer/SyncWithServerDialogSkeleton.jsx +67 -0
  94. package/src/common/tests/CustomWrapper.jsx +49 -0
  95. package/src/common/tests/TranslationWrapper.jsx +38 -0
  96. package/src/common/themeProvider/ColorInputs.jsx +97 -0
  97. package/src/common/themeProvider/EditableColorInput.jsx +128 -0
  98. package/src/common/themeProvider/ThemeEditor.jsx +319 -0
  99. package/src/common/themeProvider/ThemeProvider.jsx +210 -0
  100. package/src/common/themeProvider/themeConfig.js +558 -0
  101. package/src/common/toaster/toaster.jsx +30 -0
  102. package/src/firebaseConfig.js +24 -0
  103. package/src/global.scss +221 -0
  104. package/src/hooks/.gitkeep +0 -0
  105. package/src/hooks/useAESEncryption.js +56 -0
  106. package/src/hooks/useCaching.js +43 -0
  107. package/src/hooks/useDebounce.js +34 -0
  108. package/src/hooks/useDebounceFn.js +50 -0
  109. package/src/hooks/useDownloadPdf.js +358 -0
  110. package/src/hooks/useDownloadXlsx.js +55 -0
  111. package/src/hooks/useListValueFieldValues.js +30 -0
  112. package/src/hooks/useLocationHierarchies.js +63 -0
  113. package/src/hooks/useLocationHierarchyTranslate.js +16 -0
  114. package/src/hooks/useOnline.js +27 -0
  115. package/src/hooks/usePagination.js +63 -0
  116. package/src/hooks/useRefreshToken.js +87 -0
  117. package/src/hooks/useScript.js +25 -0
  118. package/src/hooks/useStopwatch.js +75 -0
  119. package/src/hooks/useTrackEvent.js +22 -0
  120. package/src/hooks/useWebAudioRecorder.js +115 -0
  121. package/src/layout/LoaderComponet.jsx +22 -0
  122. package/src/layout/LoaderContext.jsx +29 -0
  123. package/src/layout/mainLayout/AdaptiveZoom.jsx +27 -0
  124. package/src/layout/mainLayout/Chatbot.jsx +243 -0
  125. package/src/layout/mainLayout/Layout.jsx +445 -0
  126. package/src/layout/mainLayout/Profile/UpdateProfileModal.jsx +684 -0
  127. package/src/layout/mainLayout/header/LogoutModal.jsx +131 -0
  128. package/src/layout/mainLayout/header/Navbar.jsx +1677 -0
  129. package/src/layout/mainLayout/header/Navbar.scss +4 -0
  130. package/src/layout/mainLayout/header/index.js +0 -0
  131. package/src/layout/mainLayout/sidebar/SideBar.jsx +1402 -0
  132. package/src/layout/mainLayout/sidebar/Sidebar.css +159 -0
  133. package/src/layout/mainLayout/sidebar/index.js +0 -0
  134. package/src/logo.svg +1 -0
  135. package/src/reportWebVitals.js +13 -0
  136. package/src/setupFirebaseMessaging.js +28 -0
  137. package/src/setupTests.js +8 -0
  138. package/src/store/actions/AuthenticationActions.js +0 -0
  139. package/src/store/actions/ReportsActions.js +0 -0
  140. package/src/store/actions/TranslationAction.js +0 -0
  141. package/src/store/index.js +8 -0
  142. package/src/store/reducer.js +46 -0
  143. package/src/store/reducers/AuthenticationReducer.js +50 -0
  144. package/src/store/reducers/CalendarEventReducer.js +41 -0
  145. package/src/store/reducers/ConditionClipboardReducer.js +45 -0
  146. package/src/store/reducers/FeatureReducer.js +27 -0
  147. package/src/store/reducers/FormConfiguratorReducer.js +38 -0
  148. package/src/store/reducers/LoadingReducer.js +20 -0
  149. package/src/store/reducers/MembersAuthenticationReducer.js +28 -0
  150. package/src/store/reducers/PrescriptionPadReducer.js +329 -0
  151. package/src/store/reducers/QuestionaireReducer.js +29 -0
  152. package/src/store/reducers/ReportsReducer.js +24 -0
  153. package/src/store/reducers/SkeletonReducer.js +20 -0
  154. package/src/store/reducers/ThemeReducer.js +106 -0
  155. package/src/store/reducers/TranslationReducer.js +126 -0
  156. package/src/store/reducers/dashboardEditorSlice.js +77 -0
  157. package/src/store/reducers/districtHealthDashboardSlice.js +58 -0
  158. package/src/store/reducers/immunizationSlice.js +234 -0
  159. package/src/store/slices/dashboardPagesSlice.js +51 -0
  160. package/src/store/slices/dashboardSlice.js +14 -0
  161. package/src/utils/.gitkeep +0 -0
  162. package/src/utils/FormConstants.js +2629 -0
  163. package/src/utils/GujaratTopoChart.jsx +483 -0
  164. package/src/utils/UUIDgenerator.js +8 -0
  165. package/src/utils/appointment-utils/appointment-utils.js +123 -0
  166. package/src/utils/feature.js +42 -0
  167. package/src/utils/getThemeColor.js +12 -0
  168. package/src/utils/localStorageHelper.js +11 -0
  169. package/src/utils/notifications/enable-push-notifications.js +27 -0
  170. package/src/utils/resolveAppliedStyle.js +11 -0
  171. package/src/utils/themeConfigs.js +1483 -0
  172. package/src/views/custom-components/.gitkeep +0 -0
  173. package/src/views/custom-components/AgIconButton/RIf.jsx +14 -0
  174. package/src/views/custom-components/AgIconButton/button.jsx +108 -0
  175. package/src/views/custom-components/AgIconButton/waterDrop.jsx +95 -0
  176. package/src/views/custom-components/AgIconButton/waterDrop.scss +37 -0
  177. package/src/views/custom-components/AlertPlaceholder.jsx +32 -0
  178. package/src/views/custom-components/AllFaIconsSelector.jsx +56 -0
  179. package/src/views/custom-components/CkEditor/CkEditor.js +102 -0
  180. package/src/views/custom-components/CustomAccordion.jsx +72 -0
  181. package/src/views/custom-components/CustomActionIcons.jsx +118 -0
  182. package/src/views/custom-components/CustomAutoComplete.jsx +188 -0
  183. package/src/views/custom-components/CustomCheckBox.jsx +60 -0
  184. package/src/views/custom-components/CustomConfirmationModal.jsx +118 -0
  185. package/src/views/custom-components/CustomCountrySelect.jsx +129 -0
  186. package/src/views/custom-components/CustomDatePicker.jsx +122 -0
  187. package/src/views/custom-components/CustomDropdown.jsx +191 -0
  188. package/src/views/custom-components/CustomFileUpload.jsx +387 -0
  189. package/src/views/custom-components/CustomFullCalendar.jsx +514 -0
  190. package/src/views/custom-components/CustomInfiniteScroll.jsx +126 -0
  191. package/src/views/custom-components/CustomRadioComponent.jsx +65 -0
  192. package/src/views/custom-components/CustomStatsComponent.jsx +114 -0
  193. package/src/views/custom-components/CustomSvgUpload.jsx +170 -0
  194. package/src/views/custom-components/CustomSwitch.jsx +37 -0
  195. package/src/views/custom-components/CustomTabPanel.jsx +19 -0
  196. package/src/views/custom-components/CustomTextArea.jsx +62 -0
  197. package/src/views/custom-components/CustomTextArea.scss +27 -0
  198. package/src/views/custom-components/CustomTextField.jsx +116 -0
  199. package/src/views/custom-components/CustomToggleSwitch.jsx +138 -0
  200. package/src/views/custom-components/CustomTooltip.jsx +51 -0
  201. package/src/views/custom-components/CustomZoomImage.jsx +134 -0
  202. package/src/views/custom-components/CustomizedTable/CustomizedTableV2.jsx +1407 -0
  203. package/src/views/custom-components/CustomizedTable/VirtualizeTableBody.jsx +295 -0
  204. package/src/views/custom-components/CustomizedTable/helper.jsx +159 -0
  205. package/src/views/custom-components/CustomizedTable.jsx +532 -0
  206. package/src/views/custom-components/EditInputField.jsx +174 -0
  207. package/src/views/custom-components/FieldDescription.jsx +22 -0
  208. package/src/views/custom-components/FileDisplayComponent.jsx +138 -0
  209. package/src/views/custom-components/FormItem.jsx +53 -0
  210. package/src/views/custom-components/GenericChart.jsx +80 -0
  211. package/src/views/custom-components/InfoBadge.jsx +60 -0
  212. package/src/views/custom-components/PostgresEditor.jsx +801 -0
  213. package/src/views/custom-components/ResizableEditAutocompleteField.jsx +249 -0
  214. package/src/views/custom-components/ResizableEditInputField.jsx +215 -0
  215. package/src/views/custom-components/ResizeableEditSelectField.jsx +197 -0
  216. package/src/views/custom-components/SideOverlay.jsx +113 -0
  217. package/src/views/custom-components/SideOverlay.scss +42 -0
  218. package/src/views/custom-components/calendar.scss +571 -0
  219. package/src/views/feature-components/.gitkeep +0 -0
  220. package/src/views/feature-components/Dashboard/DashboardUI.jsx +1043 -0
  221. package/src/views/feature-components/Dashboard/DhnddModal/AshaDataQualityVerificationModal.jsx +278 -0
  222. package/src/views/feature-components/Dashboard/PinFeatureModal.jsx +143 -0
  223. package/src/views/feature-components/Dashboard/QuickLinks.jsx +163 -0
  224. package/src/views/feature-components/Dashboard/Taskbar.jsx +56 -0
  225. package/src/views/feature-components/Dashboard/WebtasksFilterForm.jsx +109 -0
  226. package/src/views/feature-components/Dashboard/WidgetCard.jsx +161 -0
  227. package/src/views/feature-components/Dashboard/actionModal.jsx +263 -0
  228. package/src/views/feature-components/Dashboard/ekavachModal/HealthWorkerIncorrectDetailsModal.jsx +332 -0
  229. package/src/views/feature-components/Dashboard/ekavachModal/MoMaternalDeathVerifcationModal.jsx +275 -0
  230. package/src/views/feature-components/Dashboard/ekavachModal/MoVerficationForChildScreeningMoadal.jsx +566 -0
  231. package/src/views/feature-components/FeatureUsageAnalytics/FeatureUsageAnalytics.jsx +989 -0
  232. package/src/views/feature-components/Features/NewServerManagement.jsx +217 -0
  233. package/src/views/feature-components/Features/ServerManagement.scss +120 -0
  234. package/src/views/feature-components/ForgotPassword/ForgotPassword.jsx +226 -0
  235. package/src/views/feature-components/LocationDirective/LocationDirective.jsx +992 -0
  236. package/src/views/feature-components/LocationDirective/LocationDirectiveV2.jsx +909 -0
  237. package/src/views/feature-components/NotFound.jsx +66 -0
  238. package/src/views/feature-components/Onboarding/Onboarding.jsx +1400 -0
  239. package/src/views/feature-components/Skeletons.js +115 -0
  240. package/src/views/feature-components/Unauthorized.jsx +48 -0
  241. package/src/views/feature-components/VerifyRoute.jsx +88 -0
  242. package/src/views/feature-components/YearlyRecap/YearlyRecap.jsx +357 -0
  243. package/src/views/feature-components/YearlyRecap/components/RecapSlide.jsx +183 -0
  244. package/src/views/feature-components/YearlyRecap/languageTranslator/TranslationContext.js +5 -0
  245. package/src/views/feature-components/YearlyRecap/languageTranslator/TranslationProvider.jsx +26 -0
  246. package/src/views/feature-components/YearlyRecap/languageTranslator/i18n.js +46 -0
  247. package/src/views/feature-components/YearlyRecap/languageTranslator/translations.json +167 -0
  248. package/src/views/feature-components/YearlyRecap/slides/IntroSlide.jsx +233 -0
  249. package/src/views/feature-components/YearlyRecap/slides/MaternalHealthSlide.jsx +146 -0
  250. package/src/views/feature-components/YearlyRecap/slides/MetricSlide.jsx +227 -0
  251. package/src/views/feature-components/YearlyRecap/slides/OutroSlide.jsx +701 -0
  252. package/src/views/feature-components/YearlyRecap/slides/ReachSlide.jsx +273 -0
  253. package/src/views/feature-components/login/Login.jsx +840 -0
  254. package/src/views/feature-components/login/Login.scss +154 -0
  255. package/src/views/feature-components/login/LoginConfigurator.jsx +1149 -0
  256. package/src/views/feature-components/login/TwoFactorSetupModal.jsx +411 -0
  257. package/src/views/feature-components/login/simplifyMenu.js +45 -0
  258. package/src/views/feature-components/system-config/ManageSystemConfigs.jsx +284 -0
  259. package/src/views/feature-components/system-config/SystemConfig.jsx +299 -0
  260. package/src/views/feature-components/users/ChangePasswordModal.jsx +243 -0
  261. package/src/views/feature-components/users/PasswordField.jsx +56 -0
  262. package/dist/index.css +0 -1
  263. package/dist/index.js +0 -32001
  264. package/dist/index.js.map +0 -1
@@ -0,0 +1,1402 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import './Sidebar.css';
3
+ import PropTypes from 'prop-types';
4
+ import Box from '@mui/material/Box';
5
+ import Drawer from '@mui/material/Drawer';
6
+ import List from '@mui/material/List';
7
+ import ListItem from '@mui/material/ListItem';
8
+ import ListItemButton from '@mui/material/ListItemButton';
9
+ import Collapse from '@mui/material/Collapse';
10
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
11
+ import { Typography, Portal, ButtonBase } from '@mui/material';
12
+ import { Grid } from '@mui/system';
13
+ import { useLocation, useNavigate } from 'react-router';
14
+ import { alpha, useTheme } from '@mui/material/styles';
15
+ import medplatFavIcon from '@/assets/img/medplat-loader.gif';
16
+ import medplatLogo from '@/assets/img/medplat-highres.png';
17
+
18
+ import {
19
+ faAward,
20
+ faBookOpen,
21
+ faBoxOpen,
22
+ faFileLines,
23
+ faGear,
24
+ faHeartPulse,
25
+ faMinus,
26
+ faPersonBreastfeeding,
27
+ faPlus,
28
+ faUserGear,
29
+ faUserGroup,
30
+ faXmark,
31
+ } from '@fortawesome/free-solid-svg-icons';
32
+ import GeneralUtil from '@/common/services/util/GeneralUtil';
33
+ import { faMosquito } from '@fortawesome/free-solid-svg-icons';
34
+ import useScript from '@/hooks/useScript';
35
+
36
+ const bhashiniLanguageMap = {
37
+ as: 'Assamese',
38
+ bn: 'Bengali',
39
+ brx: 'Bodo',
40
+ doi: 'Dogri',
41
+ gu: 'Gujarati',
42
+ hi: 'Hindi',
43
+ kn: 'Kannada',
44
+ mai: 'Maithili',
45
+ ml: 'Malayalam',
46
+ mr: 'Marathi',
47
+ ne: 'Nepali',
48
+ or: 'Odia',
49
+ pa: 'Punjabi',
50
+ sa: 'Sanskrit',
51
+ sat: 'Santali',
52
+ ta: 'Tamil',
53
+ te: 'Telugu',
54
+ ur: 'Urdu',
55
+ mni: 'Manipuri',
56
+ sd: 'Sindhi',
57
+ gom: 'Konkani',
58
+ ks: 'Kashmiri',
59
+ en: 'English',
60
+ };
61
+
62
+ const formatSidebarLabel = (value = '') =>
63
+ value
64
+ .split(' ')
65
+ .filter(Boolean)
66
+ .map((word) => {
67
+ if (word === word.toLowerCase() && word.length <= 4) {
68
+ return word.toUpperCase();
69
+ }
70
+
71
+ return word.charAt(0).toUpperCase() + word.slice(1);
72
+ })
73
+ .join(' ');
74
+
75
+ const menuItemShape = PropTypes.shape({
76
+ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
77
+ name: PropTypes.string,
78
+ displayName: PropTypes.string,
79
+ navigationState: PropTypes.string,
80
+ isGroup: PropTypes.bool,
81
+ isSubGroup: PropTypes.bool,
82
+ subGroups: PropTypes.arrayOf(PropTypes.object),
83
+ });
84
+
85
+ const normalizeNavPath = (item) => {
86
+ if (!item?.navigationState) return '';
87
+ const rawPath = GeneralUtil.naviagationFunc(item);
88
+ if (!rawPath) return '';
89
+ return rawPath.startsWith('/ui/') ? rawPath.split('?')[0] : `/ui/${rawPath}`.split('?')[0];
90
+ };
91
+
92
+ const isItemActive = (item, pathname) => {
93
+ if (!item) return false;
94
+ const normalizedPath = normalizeNavPath(item);
95
+ const currentPath = (pathname || '').split('?')[0];
96
+
97
+ if (normalizedPath && (currentPath === normalizedPath || currentPath.startsWith(`${normalizedPath}/`))) {
98
+ return true;
99
+ }
100
+
101
+ return item.subGroups?.some((subItem) => isItemActive(subItem, pathname)) || false;
102
+ };
103
+
104
+ const navigateToItem = (item, navigate) => {
105
+ if (!item?.navigationState) return;
106
+
107
+ const path = GeneralUtil.naviagationFunc(item);
108
+ if (!path) return;
109
+
110
+ if (path.includes('report/view/')) {
111
+ if (GeneralUtil.isEkavach) {
112
+ window.open(`/ui/${path}`, '_blank');
113
+ } else {
114
+ navigate(path);
115
+ }
116
+ } else {
117
+ navigate(path);
118
+ }
119
+ };
120
+
121
+ const RecursiveNavItem = ({ item, navigate, pathname, depth = 1 }) => {
122
+ const theme = useTheme();
123
+ const [isOpen, setIsOpen] = React.useState(false);
124
+ const hasSubGroups = item.subGroups && item.subGroups.length > 0;
125
+ const activeItem = isItemActive(item, pathname);
126
+
127
+ useEffect(() => {
128
+ if (hasSubGroups && activeItem) {
129
+ setIsOpen(true);
130
+ }
131
+ }, [activeItem, hasSubGroups]);
132
+
133
+ const handleClick = (e) => {
134
+ e.stopPropagation();
135
+ if (hasSubGroups) {
136
+ setIsOpen(!isOpen);
137
+ } else {
138
+ navigateToItem(item, navigate);
139
+ }
140
+ };
141
+
142
+ return (
143
+ <Box sx={{ mb: isOpen ? 1 : 0, transition: 'margin 0.2s ease' }}>
144
+ <ListItem
145
+ disablePadding
146
+ sx={{
147
+ position: 'relative',
148
+ borderLeft: `1px solid ${alpha(theme.palette.common.white, theme.palette.mode === 'dark' ? 0.08 : 0.18)}`,
149
+ ml: depth > 1 ? depth : 0,
150
+ '&::before':
151
+ depth > 1
152
+ ? {
153
+ content: '""',
154
+ position: 'absolute',
155
+ top: '50%',
156
+ left: 0,
157
+ width: '12px',
158
+ height: '1px',
159
+ backgroundColor: alpha(theme.palette.common.white, theme.palette.mode === 'dark' ? 0.12 : 0.22),
160
+ }
161
+ : {},
162
+ }}
163
+ >
164
+ <ListItemButton
165
+ onClick={handleClick}
166
+ sx={{
167
+ pl: depth > 1 ? depth * 0.75 : 0.75, // Room for the dash
168
+ pr: 0.75,
169
+ py: 0.35,
170
+ minHeight: 30,
171
+ display: 'flex',
172
+ justifyContent: 'space-between',
173
+ borderRadius: '12px',
174
+ backgroundColor:
175
+ activeItem || isOpen ? alpha('#596C83', theme.palette.mode === 'dark' ? 0.1 : 0.74) : 'transparent',
176
+ border: `1px solid ${activeItem ? alpha(theme.palette.common.white, theme.palette.mode === 'dark' ? 0.12 : 0.8) : 'transparent'
177
+ }`,
178
+ '&:hover': {
179
+ backgroundColor: alpha('#596C83', theme.palette.mode === 'dark' ? 0.08 : 0.58),
180
+ '& .MuiTypography-root': {
181
+ color: theme.palette.custom?.sidebarTextHover || '#ffffff',
182
+ },
183
+ },
184
+ }}
185
+ >
186
+ <Typography
187
+ variant="body2"
188
+ sx={{
189
+ margin: '5px 0px',
190
+ fontSize: '13px',
191
+ fontWeight: activeItem ? 700 : 500,
192
+ color: activeItem ? '#ffffff' : theme.palette.custom?.sidebarText || '#ffffff',
193
+ }}
194
+ >
195
+ {formatSidebarLabel(item.name)}
196
+ </Typography>
197
+
198
+ {hasSubGroups && (
199
+ <FontAwesomeIcon
200
+ icon={isOpen ? faMinus : faPlus}
201
+ size="xs"
202
+ style={{
203
+ fontSize: '10px',
204
+ color:
205
+ activeItem || isOpen
206
+ ? theme.palette.custom?.sidebarIconHover || '#ffffff'
207
+ : theme.palette.custom?.sidebarIcon || '#9ca3af',
208
+ }}
209
+ />
210
+ )}
211
+ </ListItemButton>
212
+ </ListItem>
213
+
214
+ {hasSubGroups && (
215
+ <Collapse in={isOpen} timeout="auto" unmountOnExit>
216
+ <List component="div" disablePadding>
217
+ {item.subGroups.map((subItem) => (
218
+ <RecursiveNavItem
219
+ key={subItem.name}
220
+ item={subItem}
221
+ navigate={navigate}
222
+ pathname={pathname}
223
+ depth={depth + 1}
224
+ />
225
+ ))}
226
+ </List>
227
+ </Collapse>
228
+ )}
229
+ </Box>
230
+ );
231
+ };
232
+
233
+ RecursiveNavItem.propTypes = {
234
+ item: menuItemShape.isRequired,
235
+ navigate: PropTypes.func.isRequired,
236
+ pathname: PropTypes.string,
237
+ depth: PropTypes.number,
238
+ };
239
+ const SideBar = ({
240
+ orientation,
241
+ subGroups,
242
+ sideBarOrientation,
243
+ isVisible,
244
+ onToggle,
245
+ datatestid,
246
+ parentPosition = {
247
+ position: 'fixed',
248
+ left: 0,
249
+ top: 0,
250
+ height: '100%',
251
+ maxHeight: null,
252
+ drawerWidth: 80,
253
+ },
254
+ depth = 0,
255
+ bhashiniEnabled: bhashiniEnabledProp = false,
256
+ }) => {
257
+ const theme = useTheme();
258
+ const [hoveredItem, setHoveredItem] = useState(null);
259
+ const [hoveredSubgroup, setHoveredSubgroup] = useState(null);
260
+ const [expandedItem, setExpandedItem] = useState(null);
261
+ const navigate = useNavigate();
262
+ const location = useLocation();
263
+
264
+ const [bhashiniEnabled, setBhashiniEnabled] = useState(bhashiniEnabledProp);
265
+ const [currentLanguageName, setCurrentLanguageName] = useState('English');
266
+
267
+ useEffect(() => {
268
+ setBhashiniEnabled(bhashiniEnabledProp);
269
+ }, [bhashiniEnabledProp]);
270
+
271
+ useEffect(() => {
272
+ if (depth !== 0) return;
273
+ const prefLang = localStorage.getItem('preferredLanguage') || 'en';
274
+ localStorage.setItem('selectedLang', prefLang);
275
+ setCurrentLanguageName(bhashiniLanguageMap[prefLang] || 'English');
276
+ }, [depth]);
277
+
278
+ useEffect(() => {
279
+ if (!bhashiniEnabled) return;
280
+ const handleBhashiniAction = (e) => {
281
+ const languageOption = e.target.closest ? e.target.closest('.language-option') : null;
282
+ if (languageOption) {
283
+ const selectedLanguage = languageOption.textContent?.trim();
284
+ if (selectedLanguage) {
285
+ setCurrentLanguageName(selectedLanguage);
286
+ }
287
+ localStorage.setItem('showCustomBhashiniToast', 'true');
288
+ }
289
+ };
290
+
291
+ const handleBhashiniKeyAction = (e) => {
292
+ if (e.key === 'Enter') handleBhashiniAction(e);
293
+ };
294
+
295
+ document.addEventListener('click', handleBhashiniAction, true);
296
+ document.addEventListener('keydown', handleBhashiniKeyAction, true);
297
+
298
+ let dropDownPolling = setInterval(() => {
299
+ const dropdown = document.getElementById('bhashiniLanguageDropdown');
300
+ if (dropdown) {
301
+ dropdown.querySelectorAll('.language-option').forEach((option) => {
302
+ const isSelected = option.textContent?.trim() === currentLanguageName;
303
+ option.setAttribute('aria-selected', isSelected ? 'true' : 'false');
304
+ });
305
+ }
306
+
307
+ if (dropdown && !document.getElementById('custom-bhashini-clear-btn')) {
308
+ const clearBtn = document.createElement('li');
309
+ clearBtn.id = 'custom-bhashini-clear-btn';
310
+ clearBtn.style.cssText =
311
+ 'position: sticky; bottom: 0; left: 0; z-index: 10; background: white; padding: 4px; border-top: 1px solid #e5e7eb; width: 100%; display: flex; justify-content: flex-start; list-style: none;';
312
+
313
+ dropdown.appendChild(clearBtn);
314
+
315
+ const btn = document.createElement('button');
316
+ btn.style.cssText =
317
+ 'display: flex; align-items: center; gap: 4px; color: #ef4444; font-size: 11px; font-weight: 600; padding: 4px 8px; border-radius: 4px; cursor: pointer; background: transparent; border: none; width: 100%; text-align: left;';
318
+
319
+ btn.innerHTML = '<span style="font-size: 12px; min-width: 12px; text-align: center;">✕</span> Clear / English';
320
+
321
+ btn.addEventListener('click', (e) => {
322
+ e.stopPropagation();
323
+ const currentLang = localStorage.getItem('preferredLanguage');
324
+ if (currentLang === 'en') return;
325
+ localStorage.setItem('preferredLanguage', 'en');
326
+ localStorage.setItem('selectedLang', 'en');
327
+ window.location.reload();
328
+ });
329
+
330
+ clearBtn.appendChild(btn);
331
+ }
332
+ }, 500);
333
+
334
+ const toastObserver = new MutationObserver((mutations) => {
335
+ mutations.forEach((mutation) => {
336
+ mutation.addedNodes.forEach((node) => {
337
+ if (
338
+ node.nodeType === Node.ELEMENT_NODE &&
339
+ node.classList &&
340
+ node.classList.contains('bhashini-toast') &&
341
+ !node.classList.contains('custom-bhashini-toast')
342
+ ) {
343
+ node.style.display = 'none';
344
+
345
+ if (localStorage.getItem('showCustomBhashiniToast') === 'true') {
346
+ localStorage.removeItem('showCustomBhashiniToast');
347
+
348
+ const customToast = document.createElement('div');
349
+ customToast.className = 'custom-bhashini-toast';
350
+ customToast.textContent = node.textContent;
351
+ document.body.appendChild(customToast);
352
+
353
+ setTimeout(() => {
354
+ if (document.body.contains(customToast)) {
355
+ customToast.style.opacity = '0';
356
+ setTimeout(() => {
357
+ if (document.body.contains(customToast)) {
358
+ document.body.removeChild(customToast);
359
+ }
360
+ }, 300);
361
+ }
362
+ }, 10000);
363
+ }
364
+ }
365
+ });
366
+ });
367
+ });
368
+
369
+ toastObserver.observe(document.body, { childList: true, subtree: false });
370
+
371
+ return () => {
372
+ clearInterval(dropDownPolling);
373
+ toastObserver.disconnect();
374
+ document.removeEventListener('click', handleBhashiniAction, true);
375
+ document.removeEventListener('keydown', handleBhashiniKeyAction, true);
376
+ };
377
+ }, [bhashiniEnabled, currentLanguageName]);
378
+
379
+ useEffect(() => {
380
+ const activeGroup = subGroups?.find((item) => item.subGroups?.length && isItemActive(item, location.pathname));
381
+ if (activeGroup) {
382
+ setExpandedItem(activeGroup.name);
383
+ }
384
+ }, [location.pathname, subGroups]);
385
+
386
+ useScript(
387
+ 'https://translation-plugin.bhashini.co.in/v3/website_translation_utility.js',
388
+ 'bhashini-translation-script',
389
+ !bhashiniEnabled,
390
+ true
391
+ );
392
+
393
+ const iconComponents = {
394
+ fhs: faUserGroup,
395
+ admin: faUserGear,
396
+ training: faBookOpen,
397
+ ncd: faHeartPulse,
398
+ mch: faBoxOpen,
399
+ manage: faGear,
400
+ reports: faFileLines,
401
+ vbd: faMosquito,
402
+ rch: faPersonBreastfeeding,
403
+ tbi: faAward,
404
+ };
405
+
406
+ const getIcon = (name) => {
407
+ const Icon = iconComponents[name];
408
+ if (!Icon) return null;
409
+ return (
410
+ <Grid
411
+ className="flex items-center justify-center"
412
+ sx={{
413
+ width: orientation === 'horizontal' ? 30 : 40,
414
+ height: orientation === 'horizontal' ? 30 : 40,
415
+ borderRadius: orientation === 'horizontal' ? '10px' : '14px',
416
+ background: hoveredItem === name ? alpha('#ffffff', 0.16) : alpha('#ffffff', 0.08),
417
+ border: `1px solid ${alpha('#ffffff', hoveredItem === name ? 0.16 : 0.08)}`,
418
+ }}
419
+ >
420
+ <FontAwesomeIcon
421
+ icon={Icon}
422
+ className={`${orientation !== 'horizontal' ? 'text-lg' : 'text-sm'} transition-colors duration-200`}
423
+ style={{
424
+ color:
425
+ hoveredItem === name
426
+ ? theme.palette.custom?.sidebarIconHover || '#ffffff'
427
+ : theme.palette.custom?.sidebarIcon || '#9ca3af', // theme fallback
428
+ }}
429
+ />
430
+ </Grid>
431
+ );
432
+ };
433
+
434
+ const handleMouseEnter = (subgroup, event) => {
435
+ const rect = event.currentTarget.getBoundingClientRect();
436
+ let position;
437
+
438
+ if (orientation === 'horizontal') {
439
+ position = {
440
+ left: rect.left,
441
+ top: rect.bottom,
442
+ drawerWidth: rect.right - rect.left,
443
+ position: 'fixed',
444
+ };
445
+ } else {
446
+ const subgroupWidth = 260; // Adjust width based on depth
447
+ const windowWidth = window.innerWidth;
448
+ const potentialRight = rect.right + subgroupWidth;
449
+ const adjustLeft = potentialRight > windowWidth;
450
+
451
+ position = {
452
+ left: adjustLeft ? rect.left - subgroupWidth : rect.right + rect.left,
453
+ top: rect.top,
454
+ drawerWidth: subgroupWidth,
455
+ position: 'fixed',
456
+ };
457
+ }
458
+
459
+ if (subgroup?.subGroups?.length > 10) {
460
+ setHoveredSubgroup({
461
+ subgroup,
462
+ position: {
463
+ ...position,
464
+ //here this subGroup id is written to differentiate between parent group and its subGroup
465
+ top:
466
+ orientation === 'vertical' && sideBarOrientation === 'vertical'
467
+ ? 0
468
+ : (() => (subgroup.id ? rect.top : rect.bottom))(),
469
+ height: '100%',
470
+ },
471
+ });
472
+ } else {
473
+ setHoveredSubgroup({
474
+ subgroup,
475
+ position: {
476
+ ...position,
477
+ top: orientation === 'vertical' ? rect.top : rect.bottom,
478
+ },
479
+ });
480
+ }
481
+
482
+ setHoveredItem(subgroup.name);
483
+ };
484
+
485
+ const handleMouseLeave = () => {
486
+ setHoveredItem(null);
487
+ setHoveredSubgroup(null);
488
+ };
489
+
490
+ const rootVerticalSidebar = depth === 0 && orientation === 'vertical' && sideBarOrientation === 'vertical';
491
+ const hoveredPrimaryItem = subGroups?.find((item) => item.name === hoveredItem && item.subGroups?.length);
492
+ const hoveredPrimaryLabel = formatSidebarLabel(hoveredPrimaryItem?.name || 'Navigation');
493
+ const hoveredPrimaryTitle = formatSidebarLabel(
494
+ hoveredPrimaryItem?.displayName || hoveredPrimaryItem?.name || 'Select a menu'
495
+ );
496
+
497
+ return (
498
+ <Box className="flex" onMouseLeave={handleMouseLeave} data-testid={datatestid}>
499
+ <Drawer
500
+ variant="permanent"
501
+ sx={{
502
+ '& .MuiDrawer-paper': {
503
+ width: rootVerticalSidebar
504
+ ? '96px'
505
+ : orientation === 'horizontal'
506
+ ? '100%'
507
+ : sideBarOrientation === 'horizontal'
508
+ ? '100%'
509
+ : parentPosition.drawerWidth,
510
+ height: rootVerticalSidebar
511
+ ? 'calc(100vh - 72px)'
512
+ : orientation === 'horizontal'
513
+ ? 'fit-content'
514
+ : sideBarOrientation === 'horizontal'
515
+ ? 'fit-content'
516
+ : parentPosition.height,
517
+ boxSizing: 'border-box',
518
+ position: parentPosition.position,
519
+ left:
520
+ typeof parentPosition.left === 'number'
521
+ ? sideBarOrientation === 'horizontal'
522
+ ? '0'
523
+ : `${parentPosition.left}px`
524
+ : 'unset',
525
+ top:
526
+ typeof parentPosition.top === 'number'
527
+ ? sideBarOrientation === 'horizontal' && depth === 0
528
+ ? '80px'
529
+ : rootVerticalSidebar
530
+ ? '72px'
531
+ : depth === 0
532
+ ? '84px'
533
+ : `${parentPosition.top}px`
534
+ : 'unset',
535
+ maxHeight:
536
+ sideBarOrientation === 'horizontal'
537
+ ? `calc(${parentPosition.height} - 92px)`
538
+ : rootVerticalSidebar
539
+ ? 'calc(100vh - 72px)'
540
+ : depth === 0
541
+ ? `calc(${parentPosition.height} - 104px)`
542
+ : `calc(${parentPosition.height})`,
543
+ background:
544
+ theme.palette.mode === 'dark'
545
+ ? theme.palette.custom.sidebarBg
546
+ : 'linear-gradient(180deg, rgba(28, 52, 85, 0.96) 0%, rgba(17, 39, 68, 0.98) 100%)',
547
+ border: `1px solid ${depth === 0 ? alpha(theme.palette.common.white, 0.08) : alpha(theme.palette.common.white, 0.12)
548
+ }`,
549
+ borderRight: rootVerticalSidebar ? 'none' : undefined,
550
+ borderRadius: rootVerticalSidebar ? 0 : orientation === 'horizontal' ? '5px' : depth === 0 ? '28px' : '0',
551
+ marginLeft: rootVerticalSidebar ? 0 : orientation === 'horizontal' ? '0px' : depth === 0 ? '12px' : 0,
552
+ marginRight: orientation === 'horizontal' ? '0px' : 0,
553
+ boxShadow: rootVerticalSidebar
554
+ ? '12px 0 30px rgba(2, 8, 23, 0.18)'
555
+ : depth === 0
556
+ ? '0 26px 60px rgba(2, 8, 23, 0.34)'
557
+ : '0 18px 38px rgba(2, 8, 23, 0.28)',
558
+ backdropFilter: 'blur(20px)',
559
+ overflow: rootVerticalSidebar ? 'visible' : 'hidden',
560
+ transition: 'transform 0.3s ease-in-out, opacity 0.3s ease-in-out',
561
+ transform: (() => {
562
+ if (parentPosition.left === 0 && typeof isVisible !== 'undefined' && orientation !== 'horizontal') {
563
+ return isVisible ? 'translateX(0)' : 'translateX(-100%)';
564
+ }
565
+ return 'translateX(0)';
566
+ })(),
567
+ opacity: orientation === 'horizontal' ? (() => (isVisible ? 1 : 0))() : 1,
568
+ pointerEvents: (() => {
569
+ if (orientation === 'horizontal') {
570
+ return isVisible ? 'auto' : 'none';
571
+ }
572
+
573
+ if (parentPosition.left === 0 && typeof isVisible !== 'undefined') {
574
+ return isVisible ? 'auto' : 'none';
575
+ }
576
+
577
+ return 'auto';
578
+ })(),
579
+ },
580
+ }}
581
+ >
582
+ {rootVerticalSidebar ? (
583
+ <Box sx={{ position: 'relative', height: '100%' }}>
584
+ <List
585
+ className="sidebar-scroll"
586
+ sx={{
587
+ width: 96,
588
+ height: '100%',
589
+ display: 'flex',
590
+ flexDirection: 'column',
591
+ gap: 0.75,
592
+ padding: '12px 8px',
593
+ borderRight: 'none',
594
+ overflowY: 'scroll',
595
+ flexShrink: 0,
596
+ }}
597
+ >
598
+ {subGroups?.map((item) => {
599
+ const activeItem = isItemActive(item, location.pathname);
600
+ const hasIcon = Boolean(iconComponents[item.name]);
601
+
602
+ return (
603
+ <ListItem key={item.name} disablePadding sx={{ display: 'block' }}>
604
+ <ListItemButton
605
+ data-testid={`sidebar-listitembutton-${item.name}`}
606
+ onMouseEnter={() => {
607
+ setHoveredItem(item.subGroups?.length ? item.name : null);
608
+ }}
609
+ onClick={() => {
610
+ if (!item.subGroups?.length) {
611
+ navigateToItem(item, navigate);
612
+ }
613
+ }}
614
+ sx={{
615
+ minHeight: 76,
616
+ borderRadius: '22px',
617
+ px: 1,
618
+ py: 1.1,
619
+ display: 'flex',
620
+ flexDirection: 'column',
621
+ justifyContent: 'center',
622
+ gap: 0.75,
623
+ background: hoveredItem === item.name ? alpha('#ffffff', 0.1) : 'transparent',
624
+ border: `1px solid ${activeItem ? alpha('#ffffff', 0.08) : alpha('#ffffff', 0.06)}`,
625
+ '&:hover': {
626
+ background: alpha('#ffffff', 0.1),
627
+ },
628
+ }}
629
+ >
630
+ {hasIcon ? (
631
+ getIcon(item.name)
632
+ ) : (
633
+ <Box
634
+ sx={{
635
+ width: 36,
636
+ height: 36,
637
+ display: 'grid',
638
+ placeItems: 'center',
639
+ borderRadius: '12px',
640
+ background: alpha('#ffffff', 0.08),
641
+ color: '#ffffff',
642
+ fontWeight: 800,
643
+ }}
644
+ >
645
+ {item.name?.charAt(0)?.toUpperCase()}
646
+ </Box>
647
+ )}
648
+ <Typography
649
+ sx={{
650
+ width: '100%',
651
+ textAlign: 'center',
652
+ fontSize: '0.7rem',
653
+ lineHeight: 1.15,
654
+ color: '#ffffff',
655
+ fontWeight: activeItem ? 700 : 500,
656
+ }}
657
+ >
658
+ {formatSidebarLabel(item.name)}
659
+ </Typography>
660
+ </ListItemButton>
661
+ </ListItem>
662
+ );
663
+ })}
664
+
665
+ {bhashiniEnabled && (
666
+ <ListItem disablePadding sx={{ display: 'block', mt: 'auto' }}>
667
+ <ListItemButton
668
+ sx={{
669
+ minHeight: 76,
670
+ borderRadius: '22px',
671
+ mx: 1,
672
+ mb: 0.75,
673
+ display: 'flex',
674
+ flexDirection: 'column',
675
+ justifyContent: 'center',
676
+ gap: 0.75,
677
+ background: 'transparent',
678
+ border: `1px solid ${alpha('#ffffff', 0.06)}`,
679
+ '&:hover': {
680
+ background: alpha('#ffffff', 0.1),
681
+ },
682
+ }}
683
+ >
684
+ <div className="bhashini-plugin-container flex justify-center items-center w-full relative min-h-[40px]"></div>
685
+ </ListItemButton>
686
+ </ListItem>
687
+ )}
688
+
689
+ {!GeneralUtil.isTecho && !GeneralUtil.isEkavach && !GeneralUtil.isSewaRural && (
690
+ <Box sx={{ mt: bhashiniEnabled ? 0 : 'auto', px: 1, pb: 0.5 }}>
691
+ <Box
692
+ sx={{
693
+ display: 'grid',
694
+ placeItems: 'center',
695
+ borderRadius: '18px',
696
+ minHeight: 56,
697
+ marginTop: 0.75,
698
+ background: alpha('#ffffff', 0.06),
699
+ border: `1px solid ${alpha('#ffffff', 0.08)}`,
700
+ }}
701
+ >
702
+ <img src={medplatFavIcon} className="h-[30px] w-[30px]" alt="medplat-logo" />
703
+ </Box>
704
+ </Box>
705
+ )}
706
+ </List>
707
+
708
+ {hoveredPrimaryItem && (
709
+ <Box
710
+ sx={{
711
+ position: 'absolute',
712
+ top: 0,
713
+ left: 95,
714
+ width: 260,
715
+ height: '100%',
716
+ display: 'flex',
717
+ flexDirection: 'column',
718
+ minWidth: 0,
719
+ background:
720
+ theme.palette.mode === 'dark'
721
+ ? theme.palette.custom.sidebarBg
722
+ : 'linear-gradient(180deg, rgba(28, 52, 85, 0.98) 0%, rgba(17, 39, 68, 0.98) 100%)',
723
+ border: `1px solid ${alpha('#ffffff', 0.08)}`,
724
+ borderLeft: 'none',
725
+ boxShadow: '16px 0 36px rgba(2, 8, 23, 0.22)',
726
+ // borderRadius: '0 24px 24px 0',
727
+ overflow: 'hidden',
728
+ }}
729
+ >
730
+ <Box
731
+ sx={{
732
+ px: 2.5,
733
+ py: 2.25,
734
+ borderBottom: `1px solid ${alpha('#ffffff', 0.08)}`,
735
+ background: alpha('#ffffff', 0.03),
736
+ display: 'flex',
737
+ alignItems: 'flex-start',
738
+ justifyContent: 'space-between',
739
+ gap: 1.5,
740
+ }}
741
+ >
742
+ <Box sx={{ minWidth: 0 }}>
743
+ <Typography
744
+ sx={{
745
+ fontSize: '0.78rem',
746
+ letterSpacing: '0.14em',
747
+ textTransform: 'uppercase',
748
+ color: alpha('#ffffff', 0.75),
749
+ }}
750
+ >
751
+ {hoveredPrimaryLabel}
752
+ </Typography>
753
+ {hoveredPrimaryTitle.toLowerCase() !== hoveredPrimaryLabel.toLowerCase() && (
754
+ <Typography sx={{ mt: 0.8, fontSize: '1.15rem', fontWeight: 700, color: '#ffffff' }}>
755
+ {hoveredPrimaryTitle}
756
+ </Typography>
757
+ )}
758
+ </Box>
759
+ {onToggle && (
760
+ <ButtonBase
761
+ onClick={onToggle}
762
+ sx={{
763
+ width: 32,
764
+ height: 32,
765
+ borderRadius: '14px',
766
+ background: alpha('#ffffff', 0.07),
767
+ border: `1px solid ${alpha('#ffffff', 0.12)}`,
768
+ color: '#ffffff',
769
+ '&:hover': {
770
+ background: alpha('#ffffff', 0.12),
771
+ },
772
+ }}
773
+ data-testid="sidebar-close-menu"
774
+ >
775
+ <FontAwesomeIcon icon={faXmark} size="xs" />
776
+ </ButtonBase>
777
+ )}
778
+ </Box>
779
+
780
+ <List
781
+ className="sidebar-scroll"
782
+ sx={{
783
+ px: 1.5,
784
+ py: 1.5,
785
+ overflowY: 'auto',
786
+ flex: 1,
787
+ }}
788
+ >
789
+ {hoveredPrimaryItem.subGroups.map((subItem) => (
790
+ <RecursiveNavItem
791
+ key={subItem.name}
792
+ item={subItem}
793
+ navigate={navigate}
794
+ pathname={location.pathname}
795
+ />
796
+ ))}
797
+ </List>
798
+ </Box>
799
+ )}
800
+ </Box>
801
+ ) : (
802
+ <List
803
+ className="sidebar-scroll"
804
+ sx={{
805
+ display: 'flex',
806
+ flexDirection: orientation === 'horizontal' ? 'row' : 'column',
807
+ gap: orientation === 'horizontal' ? 0.25 : 0.5,
808
+ padding: depth === 0 ? (orientation === 'horizontal' ? '8px' : '14px 10px') : '10px',
809
+ overflowY: orientation === 'vertical' ? 'scroll' : 'auto',
810
+ height: '100%',
811
+ }}
812
+ >
813
+ {sideBarOrientation === 'horizontal' && depth > 0 ? (
814
+ <Grid className="flex overflow-x-auto h-full">
815
+ {(() => {
816
+ const containerWidth = window.innerWidth;
817
+ const columnWidth = 250;
818
+ const maxColumns = Math.floor(containerWidth / columnWidth);
819
+
820
+ let flattenedItems = [];
821
+
822
+ subGroups.forEach((item) => {
823
+ flattenedItems.push(item);
824
+
825
+ if (expandedItem === item.name && item.subGroups?.length > 0) {
826
+ item.subGroups.forEach((subItem) => {
827
+ flattenedItems.push({
828
+ ...subItem,
829
+ _isSubItem: true,
830
+ _parentName: item.name,
831
+ });
832
+ });
833
+ }
834
+ });
835
+
836
+ const totalItems = flattenedItems.length;
837
+ const baseItemsPerColumn = Math.floor(totalItems / maxColumns);
838
+ const extraItems = totalItems % maxColumns;
839
+
840
+ const columns = [];
841
+ let currentIndex = 0;
842
+
843
+ for (let col = 0; col < maxColumns && currentIndex < totalItems; col++) {
844
+ const itemsInThisColumn = col < extraItems ? baseItemsPerColumn + 1 : baseItemsPerColumn;
845
+
846
+ if (itemsInThisColumn === 0) continue;
847
+
848
+ const columnItems = [];
849
+ for (let i = 0; i < itemsInThisColumn && currentIndex < totalItems; i++) {
850
+ columnItems.push(flattenedItems[currentIndex]);
851
+ currentIndex++;
852
+ }
853
+
854
+ columns.push(columnItems);
855
+ }
856
+
857
+ return columns.map((columnItems, colIndex) => (
858
+ <Grid
859
+ key={colIndex}
860
+ sx={{
861
+ width: `${columnWidth}px`,
862
+ padding: '6px',
863
+ borderRadius: '16px',
864
+ background: alpha('#ffffff', 0.08),
865
+ border: `1px solid ${alpha('#ffffff', 0.08)}`,
866
+ }}
867
+ className="inline-flex flex-col mr-2 max-h-full"
868
+ >
869
+ {columnItems.map((item) =>
870
+ item._isSubItem ? (
871
+ <ListItem key={`${item._parentName}-sub-${item.name}`} disablePadding>
872
+ <List component="div" disablePadding sx={{ pl: 1, width: '100%' }}>
873
+ <RecursiveNavItem
874
+ key={item.name}
875
+ item={item}
876
+ navigate={navigate}
877
+ pathname={location.pathname}
878
+ />
879
+ </List>
880
+ {/* <ListItemButton
881
+ onClick={() => {
882
+ const path = GeneralUtil.naviagationFunc(item);
883
+ navigate(path);
884
+ }}
885
+ sx={{
886
+ py: 0.5,
887
+ minHeight: 32,
888
+ }}
889
+ >
890
+ <Typography
891
+ variant="body2"
892
+ sx={{
893
+ fontSize: '0.85rem',
894
+ fontWeight: 400,
895
+ }}
896
+ >
897
+ {item.name}
898
+ </Typography>
899
+ </ListItemButton> */}
900
+ </ListItem>
901
+ ) : (
902
+ <ListItem
903
+ key={item.name}
904
+ disablePadding
905
+ onMouseEnter={(event) => handleMouseEnter(item, event)}
906
+ data-testid={`sidebar-listitem-${item.name}`}
907
+ sx={{
908
+ width: orientation === 'horizontal' ? 'fit-content' : '100%',
909
+ borderTop: 'none',
910
+ borderLeft: 'none',
911
+ my: 0.25,
912
+ }}
913
+ className="flex flex-col"
914
+ onClick={() => {
915
+ setExpandedItem(expandedItem === item.name ? null : item.name);
916
+ }}
917
+ >
918
+ <ListItemButton
919
+ sx={{
920
+ padding: '5px 6px',
921
+ display: 'flex',
922
+ alignItems: 'center',
923
+ width: '100%',
924
+ justifyContent: 'space-between',
925
+ borderRadius: '14px',
926
+ border: `1px solid ${isItemActive(item, location.pathname)
927
+ ? alpha('#ffffff', 0.18)
928
+ : alpha('#ffffff', 0.05)
929
+ }`,
930
+ '&:hover': {
931
+ backgroundColor: alpha('#ffffff', 0.1),
932
+ },
933
+ background: isItemActive(item, location.pathname)
934
+ ? 'linear-gradient(180deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0.06) 100%)'
935
+ : hoveredItem === item.name
936
+ ? alpha('#ffffff', 0.08)
937
+ : 'transparent',
938
+ }}
939
+ data-testid={`sidebar-listitembutton-${item.name}`}
940
+ >
941
+ <Grid
942
+ container
943
+ className={`flex items-center flex-1 ${orientation === 'horizontal'
944
+ ? 'justify-center'
945
+ : (() => {
946
+ return parentPosition.left === 0 ? 'justify-center' : 'justify-start';
947
+ })()
948
+ }`}
949
+ data-testid={`sidebar-listitemdiv-${item.name}`}
950
+ >
951
+ <Grid item="true" className="flex flex-col items-center">
952
+ {getIcon(item.name) && (
953
+ <Grid
954
+ sx={{
955
+ padding: 0,
956
+ borderRadius: '99px',
957
+ display: 'flex',
958
+ width: '100%',
959
+ }}
960
+ >
961
+ <Grid>{getIcon(item.name)}</Grid>
962
+ {orientation === 'horizontal' && (
963
+ <Grid
964
+ className="px-1"
965
+ sx={{
966
+ color: isItemActive(item, location.pathname)
967
+ ? '#ffffff'
968
+ : theme.palette.custom?.sidebarText || '#ffffff',
969
+ fontSize: '13px',
970
+ fontWeight: isItemActive(item, location.pathname) ? 700 : 600,
971
+ lineHeight: 1.05,
972
+ }}
973
+ >
974
+ {formatSidebarLabel(item.name)}
975
+ </Grid>
976
+ )}
977
+ </Grid>
978
+ )}
979
+ <Grid
980
+ onClick={(e) => {
981
+ if (!item.subGroups?.length) {
982
+ e.stopPropagation();
983
+ navigateToItem(item, navigate);
984
+ }
985
+ }}
986
+ >
987
+ {!getIcon(item.name) && (
988
+ <Typography
989
+ variant="body2"
990
+ data-testid={`sidebar-listitemtext-${item.name}`}
991
+ className="pl-3"
992
+ sx={{
993
+ color: isItemActive(item, location.pathname)
994
+ ? '#ffffff'
995
+ : hoveredItem === item.name
996
+ ? theme.palette.custom?.sidebarTextHover || '#ffffff'
997
+ : theme.palette.custom?.sidebarText || '#9ca3af',
998
+ maxWidth: '180px',
999
+ overflow: 'hidden',
1000
+ textOverflow: 'ellipsis',
1001
+ whiteSpace: 'nowrap',
1002
+ display: 'block',
1003
+ }}
1004
+ >
1005
+ {item.name}
1006
+ </Typography>
1007
+ )}
1008
+ </Grid>
1009
+ </Grid>
1010
+ </Grid>
1011
+
1012
+ {!getIcon(item.name) && (
1013
+ <Grid
1014
+ className="pl-3 flex flex-row items-center justify-end w-5 mr-[4px]"
1015
+ sx={{
1016
+ color: isItemActive(item, location.pathname)
1017
+ ? '#ffffff'
1018
+ : hoveredItem === item.name
1019
+ ? theme.palette.custom?.sidebarTextHover || '#ffffff'
1020
+ : theme.palette.custom?.sidebarText || '#9ca3af',
1021
+ }}
1022
+ onClick={() => {
1023
+ setExpandedItem(expandedItem === item.name ? null : item.name);
1024
+ }}
1025
+ >
1026
+ {item.subGroups?.length > 0 &&
1027
+ (() => {
1028
+ if (!item.subGroups?.length) return null;
1029
+
1030
+ const isHovered = expandedItem === item.name;
1031
+
1032
+ // if (orientation === 'horizontal') {
1033
+ // return isHovered ? <ExpandMore /> : <ExpandLess />;
1034
+ // }
1035
+
1036
+ return isHovered ? (
1037
+ <FontAwesomeIcon icon={faMinus} />
1038
+ ) : (
1039
+ <FontAwesomeIcon icon={faPlus} />
1040
+ );
1041
+ })()}
1042
+ </Grid>
1043
+ )}
1044
+ </ListItemButton>
1045
+ </ListItem>
1046
+ )
1047
+ )}
1048
+ </Grid>
1049
+ ));
1050
+ })()}
1051
+ </Grid>
1052
+ ) : (
1053
+ <>
1054
+ {/* {depth === 0 && (
1055
+ <ListItem
1056
+ disablePadding
1057
+ sx={{
1058
+ width: orientation === 'horizontal' ? 'fit-content' : '100%',
1059
+ borderTop: orientation === 'vertical' ? '1px solid rgba(255, 255, 255, 0.09)' : 'none',
1060
+ borderLeft: orientation === 'horizontal' ? '1px solid rgba(255, 255, 255, 0.09)' : 'none',
1061
+ aspectRatio: depth === 0 && orientation === 'vertical' ? '1' : 'auto',
1062
+ backgroundColor: 'var(--color-primary)',
1063
+ borderRadius: '999px',
1064
+ }}
1065
+ className={`flex flex-col ${orientation === 'vertical' ? 'mb-1' : 'mr-1'}`}
1066
+ >
1067
+ <ListItemButton
1068
+ sx={{
1069
+ padding: '8px 5px',
1070
+ display: 'flex',
1071
+ alignItems: 'center',
1072
+ width: '100%',
1073
+ justifyContent: 'space-between',
1074
+ borderRadius: '999px',
1075
+ color: 'white',
1076
+ }}
1077
+ >
1078
+ <Grid container className="flex items-center flex-1 justify-center">
1079
+ <Grid item className="flex flex-col w-full">
1080
+ <Grid
1081
+ sx={{
1082
+ display: 'flex',
1083
+ width: '100%',
1084
+ }}
1085
+ onClick={(e) => {
1086
+ e.preventDefault();
1087
+ navigate('/ui/medplat/dashboard/webtasks');
1088
+ }}
1089
+ >
1090
+ <Grid
1091
+ className={`mx-auto ${orientation === 'horizontal' ? 'pl-2' : ''} flex items-center justify-center`}
1092
+ >
1093
+ <FontAwesomeIcon icon={faBorderAll} className="text-2xl" />
1094
+ </Grid>
1095
+ {orientation === 'horizontal' && <Grid className="px-2">Dashboard</Grid>}
1096
+ </Grid>
1097
+ </Grid>
1098
+ </Grid>
1099
+ </ListItemButton>
1100
+ </ListItem>
1101
+ )} */}
1102
+
1103
+ {subGroups?.map((item) => {
1104
+ const activeItem = isItemActive(item, location.pathname);
1105
+ const hasIcon = Boolean(iconComponents[item.name]);
1106
+
1107
+ return (
1108
+ <ListItem
1109
+ key={item.name}
1110
+ disablePadding
1111
+ onMouseEnter={(event) => handleMouseEnter(item, event)}
1112
+ data-testid={`sidebar-listitem-${item.name}`}
1113
+ sx={{
1114
+ width: orientation === 'horizontal' ? 'fit-content' : '100%',
1115
+ borderTop: 'none',
1116
+ borderLeft: 'none',
1117
+ aspectRatio: depth === 0 && orientation === 'vertical' ? '1' : 'auto',
1118
+ mb: orientation === 'horizontal' ? 0 : 0.5,
1119
+ }}
1120
+ className="flex flex-col"
1121
+ onClick={() => {
1122
+ setExpandedItem(expandedItem === item.name ? null : item.name);
1123
+ }}
1124
+ >
1125
+ <ListItemButton
1126
+ sx={{
1127
+ padding:
1128
+ depth === 0 && orientation !== 'horizontal'
1129
+ ? '12px 6px'
1130
+ : orientation === 'horizontal'
1131
+ ? '6px 8px'
1132
+ : '10px 8px',
1133
+ display: 'flex',
1134
+ alignItems: 'center',
1135
+ width: '100%',
1136
+ justifyContent: 'space-between',
1137
+ borderRadius:
1138
+ depth === 0 && orientation !== 'horizontal'
1139
+ ? '22px'
1140
+ : orientation === 'horizontal'
1141
+ ? '16px'
1142
+ : '18px',
1143
+ border: `1px solid ${activeItem ? alpha('#ffffff', 0.08) : alpha('#ffffff', 0.05)}`,
1144
+ boxShadow:
1145
+ activeItem && orientation !== 'horizontal'
1146
+ ? 'inset 0 1px 0 rgba(255,255,255,0.06)'
1147
+ : 'none',
1148
+ '&:hover': {
1149
+ backgroundColor: alpha('#ffffff', 0.12),
1150
+ '& .MuiTypography-root': {
1151
+ color: theme.palette.custom?.sidebarTextHover || '#ffffff',
1152
+ },
1153
+ },
1154
+ background:
1155
+ activeItem && orientation !== 'horizontal'
1156
+ ? 'linear-gradient(180deg, rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.08) 100%)'
1157
+ : hoveredItem === item.name
1158
+ ? alpha('#ffffff', 0.08)
1159
+ : 'transparent',
1160
+ }}
1161
+ data-testid={`sidebar-listitembutton-${item.name}`}
1162
+ >
1163
+ <Grid
1164
+ container
1165
+ className={`flex items-center flex-1 ${orientation === 'horizontal'
1166
+ ? 'justify-center'
1167
+ : (() => {
1168
+ return parentPosition.left === 0 ? 'justify-center' : 'justify-start';
1169
+ })()
1170
+ }`}
1171
+ data-testid={`sidebar-listitemdiv-${item.name}`}
1172
+ >
1173
+ <Grid item="true" className="w-full">
1174
+ {hasIcon && (
1175
+ <Grid
1176
+ className="flex items-center justify-between"
1177
+ sx={{
1178
+ padding: orientation === 'horizontal' ? '0px 1px' : 0,
1179
+ borderRadius: '99px',
1180
+ display: 'flex',
1181
+ width: '100%',
1182
+ }}
1183
+ >
1184
+ {orientation === 'horizontal' && (
1185
+ <>
1186
+ <Grid className="mx-auto">{getIcon(item.name)}</Grid>
1187
+ <Grid
1188
+ className="px-1.5"
1189
+ sx={{
1190
+ color: activeItem ? '#ffffff' : theme.palette.custom?.sidebarText || '#ffffff',
1191
+ fontSize: '13px',
1192
+ fontWeight: activeItem ? 700 : 600,
1193
+ lineHeight: 1.1,
1194
+ }}
1195
+ >
1196
+ {formatSidebarLabel(item.name)}
1197
+ </Grid>
1198
+ </>
1199
+ )}
1200
+ {orientation !== 'horizontal' && (
1201
+ <Grid className="flex flex-col items-center justify-center w-full">
1202
+ <Grid className="mx-auto">{getIcon(item.name)}</Grid>
1203
+ <Typography
1204
+ variant="caption"
1205
+ sx={{
1206
+ color: activeItem ? '#ffffff' : theme.palette.custom?.sidebarText || '#ffffff',
1207
+ fontSize: '11px',
1208
+ fontWeight: activeItem ? 700 : 600,
1209
+ lineHeight: 1.3,
1210
+ textAlign: 'center',
1211
+ mt: 1,
1212
+ padding: '0px 2px',
1213
+ width: '100%',
1214
+ overflow: 'hidden',
1215
+ letterSpacing: '0.01em',
1216
+ }}
1217
+ >
1218
+ {formatSidebarLabel(item.name)}
1219
+ </Typography>
1220
+ </Grid>
1221
+ )}
1222
+ </Grid>
1223
+ )}
1224
+ <Grid
1225
+ onClick={() => {
1226
+ if (!item.subGroups?.length) {
1227
+ navigateToItem(item, navigate);
1228
+ }
1229
+ }}
1230
+ >
1231
+ {!hasIcon && (
1232
+ <Typography
1233
+ variant="body2"
1234
+ data-testid={`sidebar-listitemtext-${item.name}`}
1235
+ className="pl-3"
1236
+ sx={{
1237
+ color: activeItem
1238
+ ? '#ffffff'
1239
+ : hoveredItem === item.name
1240
+ ? theme.palette.custom?.sidebarTextHover || '#ffffff'
1241
+ : theme.palette.custom?.sidebarText || '#ffffff',
1242
+ maxWidth: '180px',
1243
+ overflow: 'hidden',
1244
+ textOverflow: 'ellipsis',
1245
+ whiteSpace: 'nowrap',
1246
+ display: 'block',
1247
+ fontWeight: activeItem || hoveredItem === item.name ? 700 : 500,
1248
+ }}
1249
+ >
1250
+ {formatSidebarLabel(item.name)}
1251
+ </Typography>
1252
+ )}
1253
+ </Grid>
1254
+ </Grid>
1255
+ </Grid>
1256
+
1257
+ {!hasIcon && (
1258
+ <Grid
1259
+ className="pl-3 flex flex-row items-center justify-end w-5 mr-[4px]"
1260
+ sx={{
1261
+ color: activeItem
1262
+ ? '#ffffff'
1263
+ : hoveredItem === item.name
1264
+ ? theme.palette.custom?.sidebarTextHover || '#ffffff'
1265
+ : theme.palette.custom?.sidebarText || '#ffffff',
1266
+ }}
1267
+ onClick={(e) => {
1268
+ e.stopPropagation();
1269
+ setExpandedItem(expandedItem === item.name ? null : item.name);
1270
+ }}
1271
+ >
1272
+ {item.subGroups?.length > 0 &&
1273
+ (() => {
1274
+ if (!item.subGroups?.length) return null;
1275
+ const isHovered = expandedItem === item.name;
1276
+ return isHovered ? (
1277
+ <FontAwesomeIcon icon={faMinus} />
1278
+ ) : (
1279
+ <FontAwesomeIcon icon={faPlus} />
1280
+ );
1281
+ })()}
1282
+ </Grid>
1283
+ )}
1284
+ </ListItemButton>
1285
+
1286
+ {depth >= 1 && item.subGroups?.length > 0 && (
1287
+ <Collapse
1288
+ in={expandedItem === item.name}
1289
+ timeout="auto"
1290
+ unmountOnExit
1291
+ sx={{ marginRight: 'auto', width: '100%' }}
1292
+ className="w-full"
1293
+ >
1294
+ <List component="div" disablePadding sx={{ pl: 2 }}>
1295
+ {item.subGroups.map((subItem) => (
1296
+ <RecursiveNavItem
1297
+ key={subItem.name}
1298
+ item={subItem}
1299
+ navigate={navigate}
1300
+ pathname={location.pathname}
1301
+ />
1302
+ ))}
1303
+ </List>
1304
+ </Collapse>
1305
+ )}
1306
+ </ListItem>
1307
+ );
1308
+ })}
1309
+ </>
1310
+ )}
1311
+ {bhashiniEnabled && (
1312
+ <Box sx={{ mt: 'auto', px: 1, pb: 1, display: 'flex', justifyContent: 'center' }}>
1313
+ <ListItemButton
1314
+ sx={{
1315
+ minHeight: orientation === 'horizontal' ? 40 : 48,
1316
+ borderRadius: orientation === 'horizontal' ? '12px' : '22px',
1317
+ display: 'flex',
1318
+ flexDirection: orientation === 'horizontal' ? 'row' : 'column',
1319
+ justifyContent: 'center',
1320
+ background: 'transparent',
1321
+ border: `1px solid ${alpha('#ffffff', 0.06)}`,
1322
+ '&:hover': {
1323
+ background: alpha('#ffffff', 0.1),
1324
+ },
1325
+ width: '100%'
1326
+ }}
1327
+ >
1328
+ <div className="bhashini-plugin-container flex justify-center items-center w-full relative min-h-[40px]"></div>
1329
+ </ListItemButton>
1330
+ </Box>
1331
+ )}
1332
+ </List>
1333
+ )}
1334
+ {isVisible &&
1335
+ !rootVerticalSidebar &&
1336
+ !GeneralUtil.isTecho &&
1337
+ !GeneralUtil.isEkavach &&
1338
+ !GeneralUtil.isSewaRural && (
1339
+ <Portal>
1340
+ <div
1341
+ className={`fixed group z-[1200] ${orientation === 'vertical' ? 'bottom-4 left-6' : 'top-22 right-3'}`}
1342
+ >
1343
+ {/* Small Icon */}
1344
+ <img
1345
+ src={medplatFavIcon}
1346
+ className="h-[40px] mb-2 cursor-pointer rounded-[14px] hidden lg:block"
1347
+ style={{
1348
+ border: `1px solid ${alpha('#ffffff', 0.12)}`,
1349
+ boxShadow: '0 14px 26px rgba(2, 8, 23, 0.3)',
1350
+ }}
1351
+ alt="medplat-logo"
1352
+ />
1353
+
1354
+ {/* Big Floating Icon */}
1355
+ <img
1356
+ src={medplatLogo}
1357
+ className={`absolute object-contain
1358
+ opacity-0 scale-90
1359
+ group-hover:opacity-100 group-hover:scale-400
1360
+ transition-all duration-300
1361
+ ${orientation === 'vertical' ? 'bottom-6.5 left-30' : 'top-4 right-30'}`}
1362
+ alt="medplat-floating-logo"
1363
+ />
1364
+ </div>
1365
+ </Portal>
1366
+ )}
1367
+ </Drawer>
1368
+ {depth === 0 && hoveredSubgroup?.subgroup?.subGroups && (
1369
+ <SideBar
1370
+ subGroups={hoveredSubgroup.subgroup.subGroups}
1371
+ parentPosition={hoveredSubgroup.position}
1372
+ datatestid={`sidebar-subgroup-sidebar-${hoveredSubgroup.subgroup.name}`}
1373
+ orientation="vertical"
1374
+ sideBarOrientation={orientation}
1375
+ depth={depth + 1}
1376
+ bhashiniEnabled={bhashiniEnabled}
1377
+ />
1378
+ )}
1379
+ </Box>
1380
+ );
1381
+ };
1382
+
1383
+ SideBar.propTypes = {
1384
+ orientation: PropTypes.oneOf(['vertical', 'horizontal']).isRequired,
1385
+ sideBarOrientation: PropTypes.oneOf(['vertical', 'horizontal']).isRequired,
1386
+ subGroups: PropTypes.arrayOf(menuItemShape),
1387
+ isVisible: PropTypes.bool,
1388
+ onToggle: PropTypes.func,
1389
+ parentPosition: PropTypes.shape({
1390
+ position: PropTypes.string,
1391
+ left: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
1392
+ top: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
1393
+ height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
1394
+ maxHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.oneOf([null])]),
1395
+ drawerWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
1396
+ }),
1397
+ datatestid: PropTypes.string,
1398
+ depth: PropTypes.number,
1399
+ bhashiniEnabled: PropTypes.bool,
1400
+ };
1401
+
1402
+ export default SideBar;