@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,319 @@
1
+ import { updateThemeConfig, updateCanSetPersonalizedTheme } from '@/store/reducers/ThemeReducer';
2
+ import CustomDropdown from '@/views/custom-components/CustomDropdown';
3
+ import { Box, Button, Switch, Typography } from '@mui/material';
4
+ import { useState, useEffect } from 'react';
5
+ import { useForm } from 'react-hook-form';
6
+ import { useDispatch, useSelector } from 'react-redux';
7
+ import ColorInputs from './ColorInputs';
8
+ import { execute } from '@/common/services/QueryBuilder';
9
+ import GeneralUtil from '@/common/services/util/GeneralUtil';
10
+ import { lightThemeConfig, darkThemeConfig } from '@/common/themeProvider/themeConfig';
11
+ import { showToast } from '../toaster/toaster';
12
+ import { setHeaderTitle } from '@/store/reducers/AuthenticationReducer';
13
+
14
+ const THEME_SOURCE_KEYS = {
15
+ personalized: 'userTheme',
16
+ implementation: 'implementationTheme',
17
+ };
18
+
19
+ const syncThemeConfigCache = (implementationWise, themeObject) => {
20
+ try {
21
+ const currentCache = JSON.parse(localStorage.getItem('theme_config') || '{}');
22
+ const cacheWithoutLegacyTheme = { ...currentCache };
23
+ delete cacheWithoutLegacyTheme.theme;
24
+
25
+ const cacheKey = implementationWise ? THEME_SOURCE_KEYS.implementation : THEME_SOURCE_KEYS.personalized;
26
+ localStorage.setItem(
27
+ 'theme_config',
28
+ JSON.stringify({
29
+ ...cacheWithoutLegacyTheme,
30
+ [cacheKey]: JSON.stringify(themeObject),
31
+ })
32
+ );
33
+ } catch (error) {
34
+ console.error('Error syncing theme config cache:', error);
35
+ }
36
+ };
37
+
38
+ const ThemeEditor = () => {
39
+ const dispatch = useDispatch();
40
+ const env = GeneralUtil.getEnv();
41
+ const personilizedThemes = useSelector((state) => state.theme.personilizedThemes);
42
+ const [implementationWise, setImplementationWise] = useState(false);
43
+ const [themeConfigs, setThemeConfigs] = useState({
44
+ light: lightThemeConfig,
45
+ dark: darkThemeConfig,
46
+ });
47
+
48
+ const { user } = useSelector((state) => state.Authenticate);
49
+ const [selectedThemeType, setSelectedThemeType] = useState('light');
50
+ const [updatedConfig, setUpdatedConfig] = useState(themeConfigs[selectedThemeType]);
51
+ const [themeStyle] = useState('palette');
52
+
53
+ const { control } = useForm({
54
+ mode: 'onChange',
55
+ });
56
+
57
+ useEffect(() => {
58
+ dispatch(setHeaderTitle("Theme Configuration"));
59
+ setUpdatedConfig(() => themeConfigs[selectedThemeType]);
60
+ }, [selectedThemeType, themeConfigs]);
61
+
62
+ const getThemeConfig = async (personalized) => {
63
+ try {
64
+ let data;
65
+ if (personalized) {
66
+ const response = await execute({
67
+ code: 'get_user_theme_config',
68
+ parameters: {
69
+ user_id: user?.id,
70
+ },
71
+ });
72
+ data = response.data;
73
+ } else {
74
+ const response = await execute({
75
+ code: 'GET_IMPLEMENTATION_THEME_CONFIG',
76
+ parameters: {
77
+ implementation: env,
78
+ },
79
+ });
80
+ data = response.data;
81
+ }
82
+ if (data && data.result && data.result[0]?.theme) {
83
+ const fetchedTheme = JSON.parse(data.result[0].theme);
84
+ setThemeConfigs(fetchedTheme);
85
+ } else {
86
+ setThemeConfigs({
87
+ light: lightThemeConfig,
88
+ dark: darkThemeConfig,
89
+ });
90
+ }
91
+ } catch (error) {
92
+ console.error('Error fetching theme config:', error);
93
+ }
94
+ };
95
+ useEffect(() => {
96
+ if (implementationWise) {
97
+ getThemeConfig(false);
98
+ } else {
99
+ getThemeConfig(true);
100
+ }
101
+ }, [implementationWise]);
102
+
103
+ const handleColorChange = (colorGroup, colorKey, value) => {
104
+ setUpdatedConfig((prev) => ({
105
+ ...prev,
106
+ palette: {
107
+ ...prev.palette,
108
+ [colorGroup]: {
109
+ ...prev.palette[colorGroup],
110
+ [colorKey]: value,
111
+ },
112
+ },
113
+ }));
114
+ };
115
+
116
+ const handleSave = async () => {
117
+ try {
118
+ const themeObject = { ...themeConfigs, [selectedThemeType]: updatedConfig };
119
+ if (implementationWise) {
120
+ await execute({
121
+ code: 'UPDATE_IMPLEMANTATIONWISE_THEME_CONFIG',
122
+ parameters: {
123
+ implementation: env,
124
+ theme_config: JSON.stringify(themeObject),
125
+ },
126
+ }).catch((err) => {
127
+ showToast({ message: 'Error in saving config', type: 'error' });
128
+ console.error(err);
129
+ });
130
+ showToast({ message: 'Config Saved Successfully', type: 'success' });
131
+ } else {
132
+ await execute({
133
+ code: 'update_theme_config',
134
+ parameters: {
135
+ user_id: user?.id,
136
+ theme_config: JSON.stringify(themeObject),
137
+ },
138
+ }).catch((err) => {
139
+ showToast({ message: 'Error in saving config', type: 'error' });
140
+ console.error(err);
141
+ });
142
+ showToast({ message: 'Config Saved Successfully', type: 'success' });
143
+ dispatch(updateCanSetPersonalizedTheme(true));
144
+ }
145
+
146
+ syncThemeConfigCache(implementationWise, themeObject);
147
+ setThemeConfigs(themeObject);
148
+
149
+ if ((personilizedThemes && !implementationWise) || (!personilizedThemes && implementationWise)) {
150
+ dispatch(
151
+ updateThemeConfig({
152
+ themeType: selectedThemeType,
153
+ config: updatedConfig,
154
+ })
155
+ );
156
+ }
157
+ } catch (error) {
158
+ console.error(error);
159
+ }
160
+ };
161
+
162
+ const resetThemeConfig = async () => {
163
+ try {
164
+ const themeObject = { light: lightThemeConfig, dark: darkThemeConfig };
165
+ if (implementationWise) {
166
+ await execute({
167
+ code: 'UPDATE_IMPLEMANTATIONWISE_THEME_CONFIG',
168
+ parameters: {
169
+ implementation: env,
170
+ theme_config: JSON.stringify(themeObject),
171
+ },
172
+ }).catch((err) => {
173
+ console.error(err);
174
+ showToast({ message: 'Error in resetting config', type: 'error' });
175
+ });
176
+ showToast({ message: 'Config Reset Successfully', type: 'success' });
177
+ } else {
178
+ await execute({
179
+ code: 'update_theme_config',
180
+ parameters: {
181
+ user_id: user?.id,
182
+ theme_config: JSON.stringify(themeObject),
183
+ },
184
+ }).catch((err) => {
185
+ showToast({ message: 'Error in resetting config', type: 'error' });
186
+ console.error(err);
187
+ });
188
+ showToast({ message: 'Config Reset Successfully', type: 'success' });
189
+ dispatch(updateCanSetPersonalizedTheme(true));
190
+ }
191
+
192
+ syncThemeConfigCache(implementationWise, themeObject);
193
+
194
+ if ((personilizedThemes && !implementationWise) || (!personilizedThemes && implementationWise)) {
195
+ dispatch(
196
+ updateThemeConfig({
197
+ themeType: 'light',
198
+ config: lightThemeConfig,
199
+ })
200
+ );
201
+ dispatch(
202
+ updateThemeConfig({
203
+ themeType: 'dark',
204
+ config: darkThemeConfig,
205
+ })
206
+ );
207
+ }
208
+
209
+ setThemeConfigs({
210
+ light: lightThemeConfig,
211
+ dark: darkThemeConfig,
212
+ });
213
+ } catch (error) {
214
+ console.error(error);
215
+ }
216
+ };
217
+
218
+ return (
219
+ <Box sx={{ padding: '20px 0px', maxWidth: 1600, margin: '0 auto' }}>
220
+ <Box
221
+ sx={{
222
+ display: 'flex',
223
+ gap: 3,
224
+ mb: 4,
225
+ flexWrap: 'wrap',
226
+ '& > *': { flex: '1 1 300px' },
227
+ }}
228
+ >
229
+ <Box
230
+ sx={{
231
+ display: 'flex',
232
+ alignItems: 'center', // ✅ vertical centering
233
+ // justifyContent: 'space-between', // optional: space between label & switch
234
+ minWidth: 300,
235
+ }}
236
+ >
237
+ <Typography variant="subtitle2" sx={{ color: 'text.secondary' }}>
238
+ Implentation Wise Theme
239
+ </Typography>
240
+ <Switch
241
+ checked={implementationWise}
242
+ onChange={(e) => {
243
+ if (user?.roleName === 'Argus Admin') {
244
+ setImplementationWise(e.target.checked)
245
+ } else {
246
+ showToast({ message: 'You are not authorized to change implementation wise theme!', type: 'info' })
247
+ }
248
+ }}
249
+ color="primary"
250
+ />
251
+ </Box>
252
+ <Box sx={{ minWidth: 300 }}>
253
+ <Typography variant="subtitle2" sx={{ mb: 1, color: 'text.secondary' }}>
254
+ Select Theme
255
+ </Typography>
256
+ <CustomDropdown
257
+ control={control}
258
+ size="small"
259
+ defaultValue={selectedThemeType}
260
+ name="themeType"
261
+ options={Object.keys(themeConfigs)}
262
+ onChange={(e) => setSelectedThemeType(e.target.value.toLowerCase())}
263
+ />
264
+ </Box>
265
+ {/* <Box sx={{ minWidth: 300 }}>
266
+ <Typography variant="subtitle2" sx={{ mb: 1, color: 'text.secondary' }}>
267
+ Select Theme Styles :
268
+ </Typography>
269
+ <CustomDropdown
270
+ control={control}
271
+ name="themeStyles"
272
+ defaultValue={themeStyle.charAt(0).toUpperCase() + themeStyle.slice(1)}
273
+ options={Object.keys(themeConfigs[selectedThemeType]).map(
274
+ (key) => key.charAt(0).toUpperCase() + key.slice(1)
275
+ )}
276
+ onChange={(e) => setThemeStyle(e.target.value.toLowerCase())}
277
+ />
278
+ </Box> */}
279
+ </Box>
280
+
281
+ <ColorInputs updatedConfig={updatedConfig} handleColorChange={handleColorChange} themeStyle={themeStyle} />
282
+
283
+ <Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 4, gap: 1 }}>
284
+ <Button
285
+ variant="contained"
286
+ color="secondary"
287
+ onClick={resetThemeConfig}
288
+ sx={{
289
+ px: 4,
290
+ py: 1.5,
291
+ fontWeight: 600,
292
+ textTransform: 'none',
293
+ boxShadow: 1,
294
+ '&:hover': { boxShadow: 2 },
295
+ }}
296
+ >
297
+ Reset to Default
298
+ </Button>
299
+ <Button
300
+ variant="contained"
301
+ color="primary"
302
+ onClick={handleSave}
303
+ sx={{
304
+ px: 4,
305
+ py: 1.5,
306
+ fontWeight: 600,
307
+ textTransform: 'none',
308
+ boxShadow: 1,
309
+ '&:hover': { boxShadow: 2 },
310
+ }}
311
+ >
312
+ Save Changes
313
+ </Button>
314
+ </Box>
315
+ </Box>
316
+ );
317
+ };
318
+
319
+ export default ThemeEditor;
@@ -0,0 +1,210 @@
1
+ import { useDispatch, useSelector } from 'react-redux';
2
+ import React, { useEffect, useMemo, useState } from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import { createTheme, ThemeProvider as MUIThemeProvider } from '@mui/material/styles';
5
+ import CssBaseline from '@mui/material/CssBaseline';
6
+ import { execute } from '@/common/services/QueryBuilder';
7
+ import { updateThemeConfig, setIsLoadingTheme } from '@/store/reducers/ThemeReducer';
8
+
9
+ import { lightThemeConfig, darkThemeConfig } from '@/common/themeProvider/themeConfig';
10
+
11
+ import GeneralUtil from '@/common/services/util/GeneralUtil';
12
+
13
+ const THEME_SOURCE_KEYS = {
14
+ personalized: 'userTheme',
15
+ implementation: 'implementationTheme',
16
+ };
17
+
18
+ const getStoredThemeCache = () => {
19
+ try {
20
+ const cache = JSON.parse(localStorage.getItem('theme_config') || '{}');
21
+ if (cache.theme && !cache.userTheme && !cache.implementationTheme) {
22
+ const migratedKey = cache.personalized ? THEME_SOURCE_KEYS.personalized : THEME_SOURCE_KEYS.implementation;
23
+ return {
24
+ ...cache,
25
+ [migratedKey]: cache.theme,
26
+ };
27
+ }
28
+ return cache;
29
+ } catch {
30
+ return {};
31
+ }
32
+ };
33
+
34
+ const setStoredThemeCache = (cache) => {
35
+ const cacheWithoutLegacyTheme = { ...cache };
36
+ delete cacheWithoutLegacyTheme.theme;
37
+ localStorage.setItem('theme_config', JSON.stringify(cacheWithoutLegacyTheme));
38
+ };
39
+
40
+ const mergeWithBaseTheme = (mode, config) => {
41
+ const baseConfig = mode === 'dark' ? darkThemeConfig : lightThemeConfig;
42
+ return {
43
+ ...baseConfig,
44
+ ...config,
45
+ palette: {
46
+ ...baseConfig.palette,
47
+ ...config?.palette,
48
+ },
49
+ };
50
+ };
51
+
52
+ const ThemeProvider = ({ children }) => {
53
+ const env = GeneralUtil.getEnv();
54
+ const isLoading = useSelector((state) => state.loading.isLoading);
55
+ const personilizedThemes = useSelector((state) => state.theme.personilizedThemes);
56
+ const isThemeLoading = useSelector((state) => state.theme.isThemeLoading);
57
+ const { user, isLoggedIn } = useSelector((state) => state.Authenticate);
58
+ const { mode, configs } = useSelector((state) => state.theme);
59
+ const [cachedCustomPalette, setCachedCustomPalette] = useState(null);
60
+ const dispatch = useDispatch();
61
+
62
+ const applyThemeConfig = (theme) => {
63
+ const fetchedTheme = typeof theme === 'string' ? JSON.parse(theme) : theme;
64
+ Object.entries(fetchedTheme || {}).forEach(([mode, config]) => {
65
+ dispatch(
66
+ updateThemeConfig({
67
+ themeType: mode,
68
+ config: mergeWithBaseTheme(mode, config),
69
+ })
70
+ );
71
+ });
72
+ };
73
+
74
+ const fetchThemeBySource = async (usePersonalizedTheme) => {
75
+ const response = await execute(
76
+ usePersonalizedTheme
77
+ ? {
78
+ code: 'get_user_theme_config',
79
+ parameters: {
80
+ user_id: user?.id,
81
+ },
82
+ }
83
+ : {
84
+ code: 'GET_IMPLEMENTATION_THEME_CONFIG',
85
+ parameters: {
86
+ implementation: env,
87
+ },
88
+ }
89
+ );
90
+
91
+ return response?.data?.result?.[0]?.theme || null;
92
+ };
93
+
94
+ const fetchUserThemeConfigDetails = async () => {
95
+ try {
96
+ if (isThemeLoading) return;
97
+
98
+ const usePersonalizedTheme = Boolean(personilizedThemes);
99
+ const cacheKey = usePersonalizedTheme ? THEME_SOURCE_KEYS.personalized : THEME_SOURCE_KEYS.implementation;
100
+ const themeCache = getStoredThemeCache();
101
+
102
+ if (themeCache[cacheKey]) {
103
+ applyThemeConfig(themeCache[cacheKey]);
104
+ return;
105
+ }
106
+
107
+ const fetchedTheme = await (async () => {
108
+ dispatch(setIsLoadingTheme(true));
109
+ try {
110
+ return await fetchThemeBySource(usePersonalizedTheme);
111
+ } finally {
112
+ dispatch(setIsLoadingTheme(false));
113
+ }
114
+ })();
115
+
116
+ if (fetchedTheme) {
117
+ setStoredThemeCache({
118
+ ...themeCache,
119
+ personalized: usePersonalizedTheme,
120
+ [cacheKey]: fetchedTheme,
121
+ });
122
+ applyThemeConfig(fetchedTheme);
123
+ } else {
124
+ setStoredThemeCache({
125
+ ...themeCache,
126
+ personalized: usePersonalizedTheme,
127
+ [cacheKey]: null,
128
+ });
129
+
130
+ dispatch(
131
+ updateThemeConfig({
132
+ themeType: 'light',
133
+ config: lightThemeConfig,
134
+ })
135
+ );
136
+ dispatch(
137
+ updateThemeConfig({
138
+ themeType: 'dark',
139
+ config: darkThemeConfig,
140
+ })
141
+ );
142
+ }
143
+ } catch (error) {
144
+ console.error('Error fetching user theme:', error);
145
+ }
146
+ };
147
+
148
+ useEffect(() => {
149
+ if (user?.id && isLoggedIn) {
150
+ fetchUserThemeConfigDetails();
151
+ }
152
+ }, [user?.id, isLoggedIn, personilizedThemes]);
153
+
154
+ useEffect(() => {
155
+ const custom = configs[mode]?.palette?.custom;
156
+ if (custom) {
157
+ setCachedCustomPalette(custom);
158
+ }
159
+ }, [mode, configs]);
160
+
161
+ const theme = useMemo(() => {
162
+ const baseTheme = createTheme(configs[mode]);
163
+ if (cachedCustomPalette) {
164
+ baseTheme.palette.custom = cachedCustomPalette;
165
+ }
166
+ return baseTheme;
167
+ }, [mode, configs, cachedCustomPalette]);
168
+
169
+ useEffect(() => {
170
+ const root = document.documentElement;
171
+ const palette = theme.palette;
172
+
173
+ root.style.setProperty('--color-primary', palette.primary.main);
174
+ root.style.setProperty('--color-secondary', palette.secondary.main);
175
+ root.style.setProperty('--color-error', palette.error.main);
176
+ root.style.setProperty('--color-success', palette.success.main);
177
+ root.style.setProperty('--color-warning', palette.warning.main);
178
+ root.style.setProperty('--color-info', palette.info.main);
179
+ root.style.setProperty('--color-background', palette.background.default);
180
+ root.style.setProperty('--color-background2', palette.background.paper);
181
+ root.style.setProperty('--color-text', palette.text.primary);
182
+ // custom colors
183
+ root.style.setProperty('--color-tableHeader', palette.custom.tableHeader);
184
+ root.style.setProperty('--color-black1', palette.custom.black1);
185
+ root.style.setProperty('--color-black2', palette.custom.black2);
186
+ root.style.setProperty('--color-gray1', palette.custom.gray1);
187
+ root.style.setProperty('--color-gray2', palette.custom.gray2);
188
+ root.style.setProperty('--color-gray3', palette.custom.gray3);
189
+ root.style.setProperty('--color-gray4', palette.custom.gray4);
190
+ root.style.setProperty('--color-customBlue', palette.custom.customBlue);
191
+ }, [theme]);
192
+
193
+ return (
194
+ <MUIThemeProvider theme={theme}>
195
+ <CssBaseline />
196
+ {isLoading && (
197
+ <div className="loader-overlay">
198
+ <div className="loader-spinner"></div>
199
+ </div>
200
+ )}
201
+ {children}
202
+ </MUIThemeProvider>
203
+ );
204
+ };
205
+
206
+ ThemeProvider.propTypes = {
207
+ children: PropTypes.any,
208
+ };
209
+
210
+ export default ThemeProvider;