ui-soxo-bootstrap-core 2.6.1-dev.2 → 2.6.1-dev.21

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 (63) hide show
  1. package/core/components/extra-info/extra-info-details.js +2 -2
  2. package/core/components/index.js +2 -11
  3. package/core/components/landing-api/landing-api.js +91 -15
  4. package/core/components/landing-api/landing-api.scss +22 -0
  5. package/core/components/license-management/license-alert.js +97 -0
  6. package/core/lib/Store.js +3 -3
  7. package/core/lib/components/global-header/global-header.js +2 -2
  8. package/core/lib/components/sidemenu/sidemenu.js +19 -13
  9. package/core/lib/components/sidemenu/sidemenu.scss +1 -1
  10. package/core/lib/elements/basic/country-phone-input/country-phone-input.js +14 -9
  11. package/core/lib/elements/basic/dragabble-wrapper/draggable-wrapper.js +1 -1
  12. package/core/lib/elements/basic/menu-tree/menu-tree.js +26 -13
  13. package/core/lib/models/forms/components/form-creator/form-creator.scss +4 -3
  14. package/core/lib/models/menus/components/menu-list/menu-list.js +424 -467
  15. package/core/lib/models/process/components/process-dashboard/process-dashboard.js +469 -3
  16. package/core/lib/models/process/components/process-dashboard/process-dashboard.scss +4 -0
  17. package/core/lib/pages/change-password/change-password.js +17 -24
  18. package/core/lib/pages/change-password/change-password.scss +45 -48
  19. package/core/lib/pages/login/commnication-mode-selection.js +2 -2
  20. package/core/lib/pages/login/login.js +53 -64
  21. package/core/lib/pages/login/login.scss +9 -0
  22. package/core/lib/pages/login/reset-password.js +17 -17
  23. package/core/lib/pages/login/reset-password.scss +10 -1
  24. package/core/lib/pages/profile/themes.json +4 -4
  25. package/core/lib/utils/api/api.utils.js +30 -18
  26. package/core/lib/utils/common/common.utils.js +49 -35
  27. package/core/lib/utils/http/http.utils.js +2 -1
  28. package/core/lib/utils/index.js +4 -1
  29. package/core/models/base/base.js +7 -3
  30. package/core/models/core-scripts/core-scripts.js +134 -126
  31. package/core/models/doctor/components/doctor-add/doctor-add.js +9 -4
  32. package/core/models/menus/components/menu-add/menu-add.js +1 -1
  33. package/core/models/menus/components/menu-lists/menu-lists.js +53 -54
  34. package/core/models/menus/menus.js +27 -2
  35. package/core/models/roles/components/role-add/role-add.js +92 -59
  36. package/core/models/roles/components/role-list/role-list.js +1 -1
  37. package/core/models/staff/components/staff-add/staff-add.js +20 -32
  38. package/core/models/users/components/assign-role/assign-role.js +145 -50
  39. package/core/models/users/components/assign-role/assign-role.scss +209 -45
  40. package/core/models/users/components/assign-role/avatar-props.js +45 -0
  41. package/core/models/users/components/user-add/user-add.js +46 -55
  42. package/core/models/users/components/user-add/user-edit.js +25 -4
  43. package/core/models/users/users.js +9 -1
  44. package/core/modules/dashboard/components/dashboard-card/menu-dashboard-card.js +1 -1
  45. package/core/modules/reporting/components/reporting-dashboard/README.md +316 -0
  46. package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.js +147 -0
  47. package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.scss +76 -0
  48. package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.js +90 -0
  49. package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.test.js +74 -0
  50. package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.js +252 -0
  51. package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.test.js +126 -0
  52. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +326 -436
  53. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.scss +7 -0
  54. package/core/modules/steps/action-buttons.js +30 -16
  55. package/core/modules/steps/action-buttons.scss +55 -9
  56. package/core/modules/steps/chat-assistant.js +141 -0
  57. package/core/modules/steps/openai-realtime.js +275 -0
  58. package/core/modules/steps/readme.md +167 -0
  59. package/core/modules/steps/steps.js +1078 -57
  60. package/core/modules/steps/steps.scss +539 -90
  61. package/core/modules/steps/timeline.js +21 -19
  62. package/core/modules/steps/voice-navigation.js +709 -0
  63. package/package.json +2 -1
@@ -21,7 +21,7 @@ import ExtraInfo from './extra-info';
21
21
 
22
22
  const { TabPane } = Tabs;
23
23
 
24
- export default function ExtraInfoDetail({ modeValue, icon, title, tabPosition = 'left', showDrawerData, dbPtr, callback, ...record }) {
24
+ export default function ExtraInfoDetail({ modeValue, icon, title, tabPosition = 'left', showDrawerData, dbPtr, callback, drawerWidth = '35%', ...record }) {
25
25
  // State to control drawer
26
26
  const [open, setOpen] = useState(false);
27
27
 
@@ -121,7 +121,7 @@ export default function ExtraInfoDetail({ modeValue, icon, title, tabPosition =
121
121
  {/* */}
122
122
 
123
123
  {/* */}
124
- <Drawer width={'35%'} title={title} onClose={onClose} open={open}>
124
+ <Drawer width={drawerWidth} title={title} onClose={onClose} open={open}>
125
125
  <div className="main-drawer-content">
126
126
  <div className="drawer-container">
127
127
  <div className="drawer-click">
@@ -1,7 +1,3 @@
1
-
2
-
3
-
4
-
5
1
  import LandingAPI from './landing-api/landing-api';
6
2
 
7
3
  import ExtraInfoDetail from './extra-info/extra-info-details';
@@ -11,11 +7,6 @@ import RootApplicationAPI from './root-application-api/root-application-api';
11
7
  import { HomePageAPI } from '../modules';
12
8
 
13
9
  import { ExternalWindow } from './external-window/external-window';
10
+ import LicenseAlert from './license-management/license-alert';
14
11
 
15
- export {
16
- LandingAPI,
17
- RootApplicationAPI,
18
- ExtraInfoDetail,
19
- HomePageAPI,
20
- ExternalWindow
21
- }
12
+ export { LandingAPI, RootApplicationAPI, ExtraInfoDetail, HomePageAPI, ExternalWindow, LicenseAlert };
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useContext } from 'react';
1
+ import React, { useState, useEffect, useContext, useRef } from 'react';
2
2
 
3
3
  import { Route, Switch } from 'react-router-dom';
4
4
 
@@ -17,6 +17,27 @@ import ReportingDashboard from '../../modules/reporting/components/reporting-das
17
17
  import PropTypes from 'prop-types';
18
18
 
19
19
  import { MenusAPI, CoreScripts } from '../../models';
20
+ import LicenseAlert from '../license-management/license-alert';
21
+
22
+ const motivatingMessages = [
23
+ 'Setting things up for a great start...',
24
+ 'Good things are loading. Stay with us.',
25
+ 'Almost there. Preparing your workspace.',
26
+ 'You are one moment away from your dashboard.',
27
+ 'Getting everything ready for you.',
28
+ 'Great care takes a second. Loading now.',
29
+ ];
30
+
31
+ function getRandomMessage(previousMessage = '') {
32
+ const options = motivatingMessages.filter((message) => message !== previousMessage);
33
+
34
+ if (!options.length) {
35
+ return motivatingMessages[0];
36
+ }
37
+
38
+ const randomIndex = Math.floor(Math.random() * options.length);
39
+ return options[randomIndex];
40
+ }
20
41
 
21
42
  /**
22
43
  * Landing API
@@ -24,7 +45,7 @@ import { MenusAPI, CoreScripts } from '../../models';
24
45
  * @param {*} param0
25
46
  * @returns
26
47
  */
27
- export default function LandingApi({ history, CustomComponents, CustomModels, appSettings, ...props }) {
48
+ export default function LandingApi({ history, CustomComponents, CustomModels, appSettings, transitionPending = false, onHomeReady, ...props }) {
28
49
  const [loader, setLoader] = useState(false);
29
50
 
30
51
  // const [modules, setModules] = useState([]);
@@ -34,12 +55,20 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
34
55
  const { dispatch, user = {} } = useContext(GlobalContext);
35
56
 
36
57
  const [allModules, setAllModules] = useState();
58
+ const homeReadyNotifiedRef = useRef(false);
59
+ const messageIntervalRef = useRef(null);
37
60
 
38
61
  const [meta, setMeta] = useState({});
62
+ const [loadingMessage, setLoadingMessage] = useState('');
63
+ const [licenseData, setLicenseData] = useState(null);
64
+
65
+ const [licAlert, setLicAlert] = useState(false);
66
+ // License data state
39
67
 
40
68
  // const [reports, setReports] = useState([]);
41
69
 
42
70
  var config = {};
71
+ //fetch license summary
43
72
 
44
73
  // Variable decides the control of homepage
45
74
  // #TODO This is a temporary fix - Homemage
@@ -49,7 +78,20 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
49
78
  if (process.env.REACT_APP_DISABLEHOMEPAGE) {
50
79
  disableHomepage = JSON.parse(process.env.REACT_APP_DISABLEHOMEPAGE);
51
80
  }
52
-
81
+ const fetchSummary = async () => {
82
+ try {
83
+ const res = await MenusAPI.getSummary();
84
+ if (res?.data) {
85
+ setLicenseData(res?.data);
86
+ setLicAlert(true);
87
+ } else {
88
+ setLicenseData(null);
89
+ setLicAlert(false);
90
+ }
91
+ } catch (err) {
92
+ console.error(err);
93
+ }
94
+ };
53
95
  // useEffect(() => {
54
96
 
55
97
  // // Initialize the menus for the logged in user
@@ -70,14 +112,56 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
70
112
  initializeUserMenus();
71
113
  }, []);
72
114
 
115
+ useEffect(() => {
116
+ if (!transitionPending) {
117
+ homeReadyNotifiedRef.current = false;
118
+ return;
119
+ }
120
+
121
+ if (!loader && allModules && !homeReadyNotifiedRef.current) {
122
+ homeReadyNotifiedRef.current = true;
123
+ if (typeof onHomeReady === 'function') {
124
+ onHomeReady();
125
+ }
126
+ }
127
+ }, [transitionPending, loader, allModules, onHomeReady]);
128
+
129
+ useEffect(() => {
130
+ if (!loader) {
131
+ setLoadingMessage('');
132
+
133
+ if (messageIntervalRef.current) {
134
+ clearInterval(messageIntervalRef.current);
135
+ messageIntervalRef.current = null;
136
+ }
137
+
138
+ return;
139
+ }
140
+
141
+ setLoadingMessage((previousMessage) => getRandomMessage(previousMessage));
142
+
143
+ messageIntervalRef.current = setInterval(() => {
144
+ setLoadingMessage((previousMessage) => getRandomMessage(previousMessage));
145
+ }, 2200);
146
+
147
+ return () => {
148
+ if (messageIntervalRef.current) {
149
+ clearInterval(messageIntervalRef.current);
150
+ messageIntervalRef.current = null;
151
+ }
152
+ };
153
+ }, [loader]);
154
+
73
155
  /**
74
156
  * Initialize the user menus
75
157
  */
76
158
  async function initializeUserMenus() {
77
159
  // need to find what implement, with a login who has the respective value ("wug_custreportids")
160
+
78
161
  const report = await loadScripts(user);
79
162
 
80
163
  await loadMenus(report);
164
+ // fetch license summary
81
165
  }
82
166
 
83
167
  // const keyMap = {
@@ -96,26 +180,21 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
96
180
  * @param reports
97
181
  */
98
182
  async function loadMenus(reports) {
99
-
100
183
  setLoader(true);
101
184
 
102
185
  // setReports(report)
103
-
186
+ fetchSummary();
104
187
  const result = await MenusAPI.getMenus(user);
105
188
 
106
189
  // console.log(result);
107
190
 
108
191
  if (result && Array.isArray(result.result) && result.result.length) {
109
-
110
192
  // setModules(result.result);
111
-
112
193
  // result.result.map((ele) => {
113
194
  // let languageString = JSON.parse(ele.attributes)
114
195
  // console.log('language_string', languageString);
115
196
  // if (languageString && languageString.languages) {
116
-
117
197
  // const language = i18n.language;
118
-
119
198
  // i18n.addResourceBundle(language, 'translation', languageString.languages[i18n.language]);
120
199
  // }
121
200
  // })
@@ -126,7 +205,6 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
126
205
  dispatch({ type: 'settings', payload: result.result.settings });
127
206
  }
128
207
 
129
-
130
208
  // Reports length
131
209
  if (reports.length) {
132
210
  reportMenus = [
@@ -161,7 +239,6 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
161
239
  //If there is no roles assigned to the user
162
240
  setAllModules([...coreModules]);
163
241
  }
164
-
165
242
  } else {
166
243
  // for nura
167
244
  if (result && result.result.menus && reportMenus) {
@@ -170,14 +247,10 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
170
247
  //If there is no roles assigned to the user
171
248
  setAllModules([...coreModules]);
172
249
  }
173
-
174
-
175
250
  }
176
251
  setLoader(false);
177
-
178
252
  }
179
253
 
180
-
181
254
  /**
182
255
  * Load the scripts
183
256
  *
@@ -240,11 +313,14 @@ export default function LandingApi({ history, CustomComponents, CustomModels, ap
240
313
  modules={allModules}
241
314
  user={user}
242
315
  history={history}
316
+ licenseData={licenseData}
317
+ licAlert={licAlert}
243
318
  >
244
319
  {loader ? (
245
320
  <Card className="skeleton-card">
246
321
  <div className="skeleton-wrapper">
247
322
  <Skeleton paragraph={{ rows: 4 }} />
323
+ <p className="motivating-text">{loadingMessage}</p>
248
324
  </div>
249
325
  </Card>
250
326
  ) : (
@@ -11,9 +11,31 @@
11
11
  }
12
12
 
13
13
  .skeleton-wrapper {
14
+ .motivating-text {
15
+ margin-top: 14px;
16
+ margin-bottom: 4px;
17
+ font-size: 14px;
18
+ line-height: 20px;
19
+ text-align: center;
20
+ color: #5e6d86;
21
+ font-weight: 500;
22
+ animation: skeletonTextFade 0.4s ease-in-out;
23
+ }
14
24
  }
15
25
 
16
26
  .wrapper-loader {
17
27
  margin: 20px;
18
28
  }
19
29
  }
30
+
31
+ @keyframes skeletonTextFade {
32
+ from {
33
+ opacity: 0;
34
+ transform: translateY(2px);
35
+ }
36
+
37
+ to {
38
+ opacity: 1;
39
+ transform: translateY(0);
40
+ }
41
+ }
@@ -0,0 +1,97 @@
1
+ import { Alert } from 'antd';
2
+ import React, { useState, useEffect } from 'react';
3
+
4
+ export default function LicenseAlert({ data }) {
5
+ // setting visibility of alert based on license status
6
+ const [visible, setVisible] = useState(true);
7
+ // resolve alert configuration based on license data
8
+ const alertConfig = resolveLicenseAlert(data);
9
+ // auto-hide alert after 10 seconds or when data changes
10
+ useEffect(() => {
11
+ if (alertConfig) {
12
+ setVisible(true);
13
+
14
+ const timer = setTimeout(() => {
15
+ setVisible(false);
16
+ }, 10000); // 10 seconds
17
+
18
+ return () => {
19
+ clearTimeout(timer);
20
+ };
21
+ }
22
+ }, [data]);
23
+ // if no alert configuration or not visible, render nothing
24
+ if (!alertConfig || !visible) return null;
25
+
26
+ return (
27
+ // render the alert with appropriate type, message, and description
28
+ <Alert
29
+ type={alertConfig.type}
30
+ message={alertConfig.message}
31
+ description={alertConfig.description}
32
+ showIcon
33
+ closable
34
+ onClose={() => setVisible(false)}
35
+ />
36
+ );
37
+ }
38
+ // function to determine alert configuration based on license data
39
+ function resolveLicenseAlert(data) {
40
+ if (!data) return null;
41
+ // destructure relevant fields from license data
42
+ const { status, expiresInDays, isExpiringSoon, gracePeriod } = data;
43
+
44
+ // ===== NOT INSTALLED =====
45
+ if (status === 'NOT_INSTALLED') {
46
+ return {
47
+ type: 'error',
48
+ message: 'License not found',
49
+ description: 'Please install a valid license to continue.',
50
+ };
51
+ }
52
+
53
+ // ===== GRACE PERIOD =====
54
+ if (gracePeriod) {
55
+ return {
56
+ type: 'warning',
57
+ message: 'Grace period mode',
58
+ description: 'License expired. Running in read-only mode.',
59
+ };
60
+ }
61
+
62
+ // ===== EXPIRING SOON =====
63
+ if (status === 'ACTIVE' && isExpiringSoon) {
64
+ let descriptionText = '';
65
+ // customize message based on how soon the license is expiring
66
+ if (expiresInDays === 1) {
67
+ descriptionText = 'Your license will expire today. Please renew immediately.';
68
+ } else {
69
+ descriptionText = `Your license will expire in ${expiresInDays} days. Please plan for renewal.`;
70
+ }
71
+
72
+ return {
73
+ type: 'warning',
74
+ message: 'License expiring soon',
75
+ description: descriptionText,
76
+ };
77
+ }
78
+
79
+ // ===== NOT INSTALLED =====
80
+ if (status === 'NOT_INSTALLED') {
81
+ return {
82
+ type: 'error',
83
+ message: 'License not found',
84
+ description: 'Please install a valid license to continue.',
85
+ };
86
+ }
87
+ // =====EXPIRED=====
88
+ if (status === 'EXPIRED') {
89
+ return {
90
+ type: 'error',
91
+ message: 'License expired',
92
+ description: 'Your license has expired. Please renew or install a new license.',
93
+ };
94
+ }
95
+
96
+ return null;
97
+ }
package/core/lib/Store.js CHANGED
@@ -50,7 +50,7 @@ const initialTheme = () => {
50
50
  // manage theme with env
51
51
  const isEnvThemeTrue = process.env.REACT_APP_THEME;
52
52
 
53
- console.log('REACT_APP_THEME:', isEnvThemeTrue);
53
+ // console.log('REACT_APP_THEME:', isEnvThemeTrue);
54
54
  const matchedTheme = themes.find((t) => t.name === isEnvThemeTrue);
55
55
 
56
56
  if (matchedTheme) return matchedTheme;
@@ -64,7 +64,7 @@ const initialTheme = () => {
64
64
  // Fallback to default
65
65
  return themes[0];
66
66
  } catch (e) {
67
- console.error('Error loading theme:', e);
67
+ // console.error('Error loading theme:', e);
68
68
  return themes[0];
69
69
  }
70
70
  };
@@ -94,7 +94,7 @@ export const GlobalProvider = ({ children, CustomModels,CustomComponents, appSet
94
94
 
95
95
  const [state, dispatch] = useReducer(AppReducer, initialState);
96
96
 
97
- console.log(state);
97
+ // console.log(state);
98
98
 
99
99
  const { isMobile } = useDeviceDetect();
100
100
 
@@ -49,7 +49,7 @@ import { useTranslation } from "react-i18next";
49
49
  import BorderStyle from "pdf-lib/cjs/core/annotation/BorderStyle";
50
50
 
51
51
  import SettingsUtil from "../../../utils/settings.utils";
52
- import { SpotlightSearch } from "..";
52
+ import SpotlightSearch from "../spotlight-search/spotlight-search.component";
53
53
 
54
54
 
55
55
 
@@ -410,4 +410,4 @@ function ProfileAvatar() {
410
410
  {/* {user.name} */}
411
411
  </Link>
412
412
  );
413
- }
413
+ }
@@ -39,18 +39,18 @@ function CollapsedIconMenu({ menu, collapsed, icon, caption }) {
39
39
  // Import t and i18n from useTranslation
40
40
  const { t, i18n } = useTranslation();
41
41
  const { state } = useContext(GlobalContext);
42
- const [isMobile, setIsMobile] = useState(false);
42
+ const [isMobile, setIsMobile] = useState(false);
43
43
 
44
- useEffect(() => {
45
- const handleResize = () => {
46
- setIsMobile(window.innerWidth < 768); // Common breakpoint for mobile
47
- };
44
+ useEffect(() => {
45
+ const handleResize = () => {
46
+ setIsMobile(window.innerWidth < 768); // Common breakpoint for mobile
47
+ };
48
48
 
49
- handleResize(); // Set initial value
50
- window.addEventListener('resize', handleResize);
49
+ handleResize(); // Set initial value
50
+ window.addEventListener('resize', handleResize);
51
51
 
52
- return () => window.removeEventListener('resize', handleResize);
53
- }, []);
52
+ return () => window.removeEventListener('resize', handleResize);
53
+ }, []);
54
54
 
55
55
  const menuText = t(caption);
56
56
  const menuContent = (
@@ -85,8 +85,14 @@ function CollapsedIconMenu({ menu, collapsed, icon, caption }) {
85
85
  </>
86
86
  );
87
87
 
88
- // On mobile, or when the menu is collapsed (based on original logic), don't show the popover tooltip.
89
- return isMobile || collapsed ? menuContent : <Popover content={menuText} placement="right">{menuContent}</Popover>;
88
+ // On mobile, or when the menu is collapsed (based on original logic), don't show the popover tooltip.
89
+ return isMobile || collapsed ? (
90
+ menuContent
91
+ ) : (
92
+ <Popover content={menuText} placement="right">
93
+ {menuContent}
94
+ </Popover>
95
+ );
90
96
  }
91
97
 
92
98
  export default function SideMenu({ loading, modules = [], callback, appSettings, collapsed }) {
@@ -123,7 +129,7 @@ export default function SideMenu({ loading, modules = [], callback, appSettings,
123
129
  * Logout Function
124
130
  */
125
131
  async function handleLogout() {
126
- let dbPtrValue = appSettings.headers.db_ptr;
132
+ // let dbPtrValue = appSettings.headers.db_ptr;
127
133
  const isEnvThemeTrue = process.env.REACT_APP_THEME === 'true';
128
134
 
129
135
  // Only clear localStorage if theme is not 'true'
@@ -137,7 +143,7 @@ export default function SideMenu({ loading, modules = [], callback, appSettings,
137
143
  // const result = Users.logout()
138
144
  localStorage.clear();
139
145
 
140
- localStorage.setItem('db_ptr', dbPtrValue);
146
+ // localStorage.setItem('db_ptr', dbPtrValue);
141
147
 
142
148
  let userInfo = {
143
149
  dms: {},
@@ -263,7 +263,7 @@
263
263
 
264
264
  .ant-menu-item:hover {
265
265
  background-color: #e6f7ff !important;
266
- color: #1677ff !important;
266
+ color: #1a90ff9e !important;
267
267
  }
268
268
 
269
269
  /* Tooltip styling if needed */
@@ -11,21 +11,26 @@ import 'react-phone-input-2/lib/style.css';
11
11
  import PropTypes from 'prop-types';
12
12
  import './phone-input.scss';
13
13
 
14
- export default function CountryPhoneInput({ value, onChange, disabled, disableCountryCode, required, defaultCountryCode, onBlur,className }) {
14
+ export default function CountryPhoneInput({
15
+ value,
16
+ onChange,
17
+ disabled,
18
+ disableCountryCode,
19
+ required,
20
+ defaultCountryCode,
21
+ onBlur,
22
+ className,
23
+ onKeyDown,
24
+ }) {
15
25
  const inputRef = useRef();
16
26
  const hasInitializedRef = useRef(false); // IMPORTANT
17
27
 
18
28
  const [phone, setPhone] = useState('');
19
-
20
29
  /**
21
30
  * run ONLY ONCE when initial value has dial code
22
31
  */
23
32
  useEffect(() => {
24
- if (
25
- !hasInitializedRef.current &&
26
- value?.code?.dialCode &&
27
- value?.value
28
- ) {
33
+ if (!hasInitializedRef.current && value?.code?.dialCode && value?.value) {
29
34
  setPhone(value.code.dialCode + value.value);
30
35
  hasInitializedRef.current = true; // 👈 mark as done
31
36
  }
@@ -54,7 +59,7 @@ export default function CountryPhoneInput({ value, onChange, disabled, disableCo
54
59
  // country={disableCountryCode ? false : 'in'}
55
60
  value={phone}
56
61
  onChange={handleInput}
57
- inputProps={{ required: required }}
62
+ inputProps={{ required: required, onKeyDown: onKeyDown }}
58
63
  disabled={disabled}
59
64
  onBlur={onBlur}
60
65
  />
@@ -73,4 +78,4 @@ CountryPhoneInput.propTypes = {
73
78
  disableCountryCode: PropTypes.bool,
74
79
  /** A boolean indicating whether the input is required or not. This prop is optional. */
75
80
  required: PropTypes.bool,
76
- };
81
+ };
@@ -102,7 +102,7 @@ export default function DraggableWrapper({ id, index, movePanel, item, dragEnabl
102
102
  >
103
103
  <div style={{ flex: 1 }}>
104
104
  {dragEnabled && <span style={{ marginRight: 8 }}>⋮⋮</span>}
105
- <span>{item.name}</span>
105
+ <span>{item.caption}</span>
106
106
  {dragEnabled ? (
107
107
  <span style={{ marginLeft: 8, fontSize: 11, color: '#999' }}>(Level {level})</span>
108
108
  ) : (
@@ -23,7 +23,7 @@
23
23
  */
24
24
 
25
25
  import React from 'react';
26
- import { Checkbox, Collapse } from 'antd';
26
+ import { Checkbox, Collapse, Tag } from 'antd';
27
27
 
28
28
  const { Panel } = Collapse;
29
29
 
@@ -73,11 +73,15 @@ export const MenuTree = ({ menus, selectedMenus = [], toggleMenu, parentId = nul
73
73
  background: '#fff',
74
74
  display: 'flex',
75
75
  alignItems: 'center',
76
- gap: 8,
76
+ justifyContent: 'space-between',
77
77
  }}
78
78
  >
79
- {showCheckbox && <Checkbox checked={selectedMenus.includes(menu.id)} onChange={(e) => onParentChange(e.target.checked)} />}
80
- <span>{menu.title || menu.caption}</span>
79
+ {/* Left Side */}
80
+ <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
81
+ {showCheckbox && <Checkbox checked={selectedMenus.includes(menu.id)} onChange={(e) => onParentChange(e.target.checked)} />}
82
+ <span>{menu.caption}</span>
83
+ </div>
84
+ <Tag color={menu.is_visible === true ? 'green' : 'blue'}>{menu.is_visible === true ? 'VISIBLE' : 'HIDDEN'}</Tag>{' '}
81
85
  </div>
82
86
  );
83
87
  }
@@ -91,15 +95,24 @@ export const MenuTree = ({ menus, selectedMenus = [], toggleMenu, parentId = nul
91
95
  <Panel
92
96
  key={menu.id}
93
97
  header={
94
- <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
95
- {showCheckbox && (
96
- <Checkbox
97
- checked={children.every((c) => selectedMenus.includes(c.id))}
98
- indeterminate={children.some((c) => selectedMenus.includes(c.id)) && !children.every((c) => selectedMenus.includes(c.id))}
99
- onChange={(e) => onParentChange(e.target.checked)}
100
- />
101
- )}
102
- <span>{menu.title || menu.caption}</span>
98
+ <div
99
+ style={{
100
+ display: 'flex',
101
+ alignItems: 'center',
102
+ justifyContent: 'space-between',
103
+ }}
104
+ >
105
+ <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
106
+ {showCheckbox && (
107
+ <Checkbox
108
+ checked={children.every((c) => selectedMenus.includes(c.id))}
109
+ indeterminate={children.some((c) => selectedMenus.includes(c.id)) && !children.every((c) => selectedMenus.includes(c.id))}
110
+ onChange={(e) => onParentChange(e.target.checked)}
111
+ />
112
+ )}
113
+ <span>{menu.caption}</span>
114
+ </div>
115
+ <Tag color={menu.is_visible === true ? 'green' : 'blue'}>{menu.is_visible === true ? 'VISIBLE' : 'HIDDEN'}</Tag>{' '}
103
116
  </div>
104
117
  }
105
118
  >
@@ -4,7 +4,7 @@
4
4
  }
5
5
 
6
6
  .new-record {
7
- gap: 10px !important;
7
+ gap: 10px !important;
8
8
  }
9
9
 
10
10
  .form-item-element {
@@ -22,9 +22,10 @@
22
22
  // right: 0px;
23
23
  }
24
24
  }
25
-
25
+
26
26
  }
27
- .submit-button{
27
+
28
+ .submit-button {
28
29
  margin-top: 10px;
29
30
  }
30
31
  }