ui-soxo-bootstrap-core 2.6.1-dev.2 → 2.6.1-dev.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/components/extra-info/extra-info-details.js +2 -2
- package/core/components/index.js +2 -11
- package/core/components/landing-api/landing-api.js +91 -15
- package/core/components/landing-api/landing-api.scss +22 -0
- package/core/components/license-management/license-alert.js +97 -0
- package/core/lib/Store.js +3 -3
- package/core/lib/components/global-header/animations.js +78 -4
- package/core/lib/components/global-header/global-header.js +224 -255
- package/core/lib/components/global-header/global-header.scss +162 -24
- package/core/lib/components/sidemenu/animations.js +84 -2
- package/core/lib/components/sidemenu/sidemenu.js +191 -65
- package/core/lib/components/sidemenu/sidemenu.scss +221 -14
- package/core/lib/elements/basic/country-phone-input/country-phone-input.js +14 -8
- package/core/lib/elements/basic/dragabble-wrapper/draggable-wrapper.js +1 -1
- package/core/lib/elements/basic/menu-tree/menu-tree.js +26 -13
- package/core/lib/models/forms/components/form-creator/form-creator.scss +4 -3
- package/core/lib/models/menus/components/menu-list/menu-list.js +424 -467
- package/core/lib/models/process/components/process-dashboard/process-dashboard.js +469 -3
- package/core/lib/models/process/components/process-dashboard/process-dashboard.scss +4 -0
- package/core/lib/pages/change-password/change-password.js +17 -24
- package/core/lib/pages/change-password/change-password.scss +45 -48
- package/core/lib/pages/login/commnication-mode-selection.js +2 -2
- package/core/lib/pages/login/login.js +47 -62
- package/core/lib/pages/login/login.scss +9 -0
- package/core/lib/pages/login/reset-password.js +17 -17
- package/core/lib/pages/login/reset-password.scss +10 -1
- package/core/lib/pages/profile/themes.json +4 -4
- package/core/lib/utils/api/api.utils.js +30 -18
- package/core/lib/utils/common/common.utils.js +49 -35
- package/core/lib/utils/http/http.utils.js +2 -1
- package/core/lib/utils/index.js +4 -1
- package/core/models/base/base.js +7 -3
- package/core/models/core-scripts/core-scripts.js +134 -126
- package/core/models/doctor/components/doctor-add/doctor-add.js +9 -4
- package/core/models/menus/components/menu-add/menu-add.js +1 -1
- package/core/models/menus/components/menu-lists/menu-lists.js +53 -54
- package/core/models/menus/menus.js +27 -2
- package/core/models/roles/components/role-add/role-add.js +92 -59
- package/core/models/roles/components/role-list/role-list.js +1 -1
- package/core/models/staff/components/staff-add/staff-add.js +20 -32
- package/core/models/users/components/assign-role/assign-role.js +145 -50
- package/core/models/users/components/assign-role/assign-role.scss +209 -45
- package/core/models/users/components/assign-role/avatar-props.js +45 -0
- package/core/models/users/components/user-add/user-add.js +46 -55
- package/core/models/users/components/user-add/user-edit.js +25 -4
- package/core/models/users/users.js +9 -1
- package/core/modules/dashboard/components/dashboard-card/menu-dashboard-card.js +1 -1
- package/core/modules/reporting/components/reporting-dashboard/README.md +316 -0
- package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.js +147 -0
- package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.scss +76 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.js +90 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.test.js +74 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.js +252 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.test.js +126 -0
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +326 -436
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.scss +7 -0
- package/core/modules/steps/action-buttons.js +33 -15
- package/core/modules/steps/action-buttons.scss +55 -9
- package/core/modules/steps/chat-assistant.js +141 -0
- package/core/modules/steps/openai-realtime.js +275 -0
- package/core/modules/steps/readme.md +167 -0
- package/core/modules/steps/steps.js +1078 -57
- package/core/modules/steps/steps.scss +539 -90
- package/core/modules/steps/timeline.js +21 -19
- package/core/modules/steps/voice-navigation.js +709 -0
- package/package.json +2 -1
|
@@ -30,7 +30,7 @@ import { getAccessToken, getRefreshToken } from '../../utils/http/auth.helper';
|
|
|
30
30
|
|
|
31
31
|
import { Location } from '../../utils';
|
|
32
32
|
|
|
33
|
-
import { checkLicenseStatus, formatMobile, safeJSON
|
|
33
|
+
import { checkLicenseStatus, formatMobile, safeJSON } from '../../utils/common/common.utils';
|
|
34
34
|
|
|
35
35
|
import { MailOutlined, MessageOutlined, WhatsAppOutlined } from '@ant-design/icons';
|
|
36
36
|
|
|
@@ -50,11 +50,10 @@ const tailLayout = {
|
|
|
50
50
|
|
|
51
51
|
const LICENSE_EXPIRY = '2026-12-12';
|
|
52
52
|
|
|
53
|
+
|
|
53
54
|
const headers = {
|
|
54
55
|
db_ptr: 'nuraho',
|
|
55
56
|
};
|
|
56
|
-
//password valdity expire
|
|
57
|
-
const PASSWORD_VALIDITY_DAYS = 90;
|
|
58
57
|
|
|
59
58
|
/**
|
|
60
59
|
*
|
|
@@ -114,46 +113,32 @@ function LoginPhone({ history, appSettings }) {
|
|
|
114
113
|
*
|
|
115
114
|
* - Parses `last_password_change` from user.other_details.
|
|
116
115
|
* - Calculates expiry using PASSWORD_VALIDITY_DAYS.
|
|
117
|
-
* - Uses `checkExpiryStatus()` to determine status.
|
|
118
116
|
* - Shows Ant Design warning message if expired or within warning period.
|
|
119
117
|
* - Warning message includes navigation to `/change-password`.
|
|
120
118
|
*
|
|
121
119
|
* Requires:
|
|
122
120
|
* - PASSWORD_VALIDITY_DAYS constant
|
|
123
|
-
* - checkExpiryStatus utility
|
|
124
121
|
* - React Router history
|
|
125
122
|
* - antd message component
|
|
126
123
|
*/
|
|
127
|
-
const handlePasswordExpiryCheck = (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const lastPasswordChange = otherDetails?.last_password_change;
|
|
131
|
-
|
|
132
|
-
if (lastPasswordChange) {
|
|
133
|
-
const passwordExpiryDate = new Date(lastPasswordChange);
|
|
134
|
-
passwordExpiryDate.setDate(passwordExpiryDate.getDate() + PASSWORD_VALIDITY_DAYS);
|
|
135
|
-
|
|
136
|
-
const passwordStatus = checkExpiryStatus({
|
|
137
|
-
expiryDate: passwordExpiryDate,
|
|
138
|
-
warningDays: 2,
|
|
139
|
-
expiredMessage: 'Your password has expired. Please reset it.',
|
|
140
|
-
warningMessage: (d) => (
|
|
141
|
-
<span>
|
|
142
|
-
Your password will expire in {d} day(s).{' '}
|
|
143
|
-
<a
|
|
144
|
-
onClick={() => {
|
|
145
|
-
history.push('/change-password');
|
|
146
|
-
}}
|
|
147
|
-
>
|
|
148
|
-
Click here to update.
|
|
149
|
-
</a>
|
|
150
|
-
</span>
|
|
151
|
-
),
|
|
152
|
-
});
|
|
124
|
+
const handlePasswordExpiryCheck = (expiryDays) => {
|
|
125
|
+
if (expiryDays == null) return;
|
|
153
126
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
127
|
+
if (expiryDays <= 0) {
|
|
128
|
+
message.error('Your password has expired. Please reset it.');
|
|
129
|
+
|
|
130
|
+
setExpiredPassword(true);
|
|
131
|
+
setShowResetpassword(true);
|
|
132
|
+
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (expiryDays <= 2) {
|
|
137
|
+
message.warning(
|
|
138
|
+
<span>
|
|
139
|
+
Your password will expire in {expiryDays} day(s). <a onClick={() => history.push('/change-password')}>Click here to update.</a>
|
|
140
|
+
</span>
|
|
141
|
+
);
|
|
157
142
|
}
|
|
158
143
|
};
|
|
159
144
|
|
|
@@ -194,7 +179,7 @@ function LoginPhone({ history, appSettings }) {
|
|
|
194
179
|
if (insider_token) localStorage.insider_token = insider_token;
|
|
195
180
|
|
|
196
181
|
if (result.success) {
|
|
197
|
-
handlePasswordExpiryCheck(
|
|
182
|
+
handlePasswordExpiryCheck(result.expiry_in_days);
|
|
198
183
|
|
|
199
184
|
//two_factor_authentication variable is present then proceed Two factor authentication
|
|
200
185
|
if (result.data && result.data.two_factor_authentication) {
|
|
@@ -349,10 +334,10 @@ function LoginPhone({ history, appSettings }) {
|
|
|
349
334
|
if (result.success) {
|
|
350
335
|
// for expiry_time
|
|
351
336
|
startFromExpiry(result?.expiry_time);
|
|
352
|
-
// if the api is sucess then go for otpverification step
|
|
353
|
-
setotpVerification(true);
|
|
354
337
|
// set button loading false
|
|
355
338
|
setLoading(false);
|
|
339
|
+
// if the api is sucess then go for otpverification step
|
|
340
|
+
setotpVerification(true);
|
|
356
341
|
} else {
|
|
357
342
|
setLoading(false);
|
|
358
343
|
message.error(result.message);
|
|
@@ -409,7 +394,7 @@ function LoginPhone({ history, appSettings }) {
|
|
|
409
394
|
if (result?.user?.organization_details) {
|
|
410
395
|
const data = safeJSON(result?.user?.organization_details);
|
|
411
396
|
|
|
412
|
-
const defaultBranch = data.branch.find((b) => b.defaultBranch ===
|
|
397
|
+
const defaultBranch = data.branch.find((b) => b.defaultBranch === true);
|
|
413
398
|
const defaultDbptr = defaultBranch?.dbPtr;
|
|
414
399
|
|
|
415
400
|
localStorage.setItem('db_ptr', defaultDbptr);
|
|
@@ -419,7 +404,7 @@ function LoginPhone({ history, appSettings }) {
|
|
|
419
404
|
// set user info into local storage
|
|
420
405
|
localStorage.setItem('userInfo', JSON.stringify(userInfo));
|
|
421
406
|
|
|
422
|
-
handlePasswordExpiryCheck(result.
|
|
407
|
+
handlePasswordExpiryCheck(result.expiry_in_days);
|
|
423
408
|
|
|
424
409
|
setTimeout(() => history.push('/'), 500);
|
|
425
410
|
} else {
|
|
@@ -622,28 +607,28 @@ function LoginPhone({ history, appSettings }) {
|
|
|
622
607
|
return user.username;
|
|
623
608
|
};
|
|
624
609
|
|
|
625
|
-
const { globalCustomerHeader = () => {} } = appSettings;
|
|
610
|
+
const { globalCustomerHeader = () => { } } = appSettings;
|
|
626
611
|
|
|
627
612
|
const themeName = process.env.REACT_APP_THEME; // e.g., 'purple'
|
|
628
613
|
const isPurple = themeName === 'purple';
|
|
629
614
|
|
|
630
615
|
const sectionStyle = isPurple
|
|
631
616
|
? {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
617
|
+
width: '100%',
|
|
618
|
+
height: '100vh',
|
|
619
|
+
backgroundImage: `${state.theme.colors.loginPageBackground}`,
|
|
620
|
+
backgroundPosition: 'center bottom, center',
|
|
621
|
+
backgroundRepeat: 'no-repeat, no-repeat',
|
|
622
|
+
backgroundSize: 'cover, cover',
|
|
623
|
+
}
|
|
639
624
|
: {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
625
|
+
width: '100%',
|
|
626
|
+
height: '100vh',
|
|
627
|
+
background: 'linear-gradient(to bottom, #F7F6E3 0%, #EEF1DE 20%, #D5E4DA 45%, #9DBFC8 75%, #4F89A6 100%)',
|
|
628
|
+
backgroundPosition: 'center bottom, center',
|
|
629
|
+
backgroundRepeat: 'no-repeat, no-repeat',
|
|
630
|
+
backgroundSize: 'cover, cover',
|
|
631
|
+
};
|
|
647
632
|
|
|
648
633
|
return (
|
|
649
634
|
<section className="full-page" style={sectionStyle}>
|
|
@@ -811,7 +796,7 @@ function LoginPhone({ history, appSettings }) {
|
|
|
811
796
|
<Button loading={loading} type="primary" htmlType="submit" className="SubmitBtn">
|
|
812
797
|
Submit
|
|
813
798
|
</Button>
|
|
814
|
-
<div className="forgot-password"
|
|
799
|
+
<div className="forgot-password">
|
|
815
800
|
<Link onClick={() => setShowResetpassword(true)}>Forgot Password?</Link>
|
|
816
801
|
</div>
|
|
817
802
|
</Form.Item>
|
|
@@ -827,13 +812,13 @@ function LoginPhone({ history, appSettings }) {
|
|
|
827
812
|
setShowResetpassword(false);
|
|
828
813
|
setExpiredPassword(false);
|
|
829
814
|
}}
|
|
830
|
-
title={expiredPassword ? 'Password Expired' : 'Forgot Password'}
|
|
831
|
-
subtitle={
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
}
|
|
836
|
-
buttonText={expiredPassword ? 'Send Reset Link' : 'Reset
|
|
815
|
+
title={expiredPassword ? 'Password Expired!' : 'Forgot Password?'}
|
|
816
|
+
// subtitle={
|
|
817
|
+
// expiredPassword
|
|
818
|
+
// ? 'Your password has expired. Select a preferred communication method to receive the One-Time Password (OTP) to continue.'
|
|
819
|
+
// : 'Enter your username and Select a preferred communication method to receive the One-Time Password (OTP) to continue..'
|
|
820
|
+
// }
|
|
821
|
+
buttonText={expiredPassword ? 'Send Reset Link' : 'Send Reset Link'}
|
|
837
822
|
/>
|
|
838
823
|
)}
|
|
839
824
|
</div>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* @param {boolean} disabledUserName - Disable username field
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import React, { useState, useEffect } from 'react';
|
|
20
|
+
import React, { useState, useEffect, useRef } from 'react';
|
|
21
21
|
import { Divider, Form, Input, message } from 'antd';
|
|
22
22
|
import { Button } from '../../elements';
|
|
23
23
|
import CommunicationModeSelection from './commnication-mode-selection';
|
|
@@ -36,6 +36,9 @@ function ResetPassword({ onBack, title, subtitle, buttonText, defaultUsername, d
|
|
|
36
36
|
|
|
37
37
|
const [form] = Form.useForm();
|
|
38
38
|
|
|
39
|
+
// Ref to username input auto focus
|
|
40
|
+
const inputRef = useRef(null);
|
|
41
|
+
|
|
39
42
|
// Pre-fills username if provided and disabled.
|
|
40
43
|
useEffect(() => {
|
|
41
44
|
if (disabledUserName && defaultUsername) {
|
|
@@ -43,6 +46,10 @@ function ResetPassword({ onBack, title, subtitle, buttonText, defaultUsername, d
|
|
|
43
46
|
}
|
|
44
47
|
}, [disabledUserName, defaultUsername]);
|
|
45
48
|
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
inputRef.current?.focus();
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
46
53
|
/**
|
|
47
54
|
* Sends forgot password request to backend.
|
|
48
55
|
* Payload: { mode, username, user_type: 'staff' }
|
|
@@ -83,26 +90,20 @@ function ResetPassword({ onBack, title, subtitle, buttonText, defaultUsername, d
|
|
|
83
90
|
return (
|
|
84
91
|
<motion.div
|
|
85
92
|
className="forgot-password-container"
|
|
86
|
-
initial={{ opacity: 0, y:
|
|
93
|
+
initial={{ opacity: 0, y: 30 }}
|
|
87
94
|
animate={{ opacity: 1, y: 0 }}
|
|
88
|
-
exit={{ opacity: 0, y: -
|
|
95
|
+
exit={{ opacity: 0, y: -20 }}
|
|
89
96
|
transition={{
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
ease: [0.22, 0.08, 0.26, 1],
|
|
93
|
-
},
|
|
94
|
-
opacity: {
|
|
95
|
-
duration: 0.45,
|
|
96
|
-
ease: 'easeOut',
|
|
97
|
-
},
|
|
97
|
+
duration: 0.30,
|
|
98
|
+
ease: 'easeOut',
|
|
98
99
|
}}
|
|
99
100
|
>
|
|
100
101
|
<h3 className="password-title">{title}</h3>
|
|
101
|
-
<p className="password-subtitle">{subtitle}</p>
|
|
102
|
-
<Divider />
|
|
102
|
+
{/* <p className="password-subtitle">{subtitle}</p>
|
|
103
|
+
<Divider /> */}
|
|
103
104
|
<Form layout="vertical" form={form} onFinish={handleSendForgetPassword}>
|
|
104
105
|
<Form.Item label="Username" name="username" rules={[{ required: true, message: 'Please input your username' }]}>
|
|
105
|
-
<Input placeholder="Enter your username" disabled={disabledUserName} />
|
|
106
|
+
<Input placeholder="Enter your username" disabled={disabledUserName} ref={inputRef}/>
|
|
106
107
|
</Form.Item>
|
|
107
108
|
|
|
108
109
|
<CommunicationModeSelection communicationMode={communicationMode} setCommunicationMode={setCommunicationMode} modeError={modeError} />
|
|
@@ -110,9 +111,8 @@ function ResetPassword({ onBack, title, subtitle, buttonText, defaultUsername, d
|
|
|
110
111
|
<Button type="primary" htmlType="submit" loading={loading}>
|
|
111
112
|
{buttonText}
|
|
112
113
|
</Button>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<a style={{ cursor: 'pointer' }} onClick={handleBackToLogin}>
|
|
114
|
+
<div className="back-to-login">
|
|
115
|
+
<a onClick={handleBackToLogin}>
|
|
116
116
|
Back to Login
|
|
117
117
|
</a>
|
|
118
118
|
</div>
|
|
@@ -88,10 +88,10 @@
|
|
|
88
88
|
"loginPageBackground": "linear-gradient(#D5F1FB, #24AEB8)",
|
|
89
89
|
"bodyBackground": "#F0F6FF",
|
|
90
90
|
"progressBar": "#24AEB8",
|
|
91
|
-
"primaryButtonBg": "#
|
|
91
|
+
"primaryButtonBg": "#204b7e",
|
|
92
92
|
"primaryButtonHoverBg": "#2E4873",
|
|
93
93
|
"primaryButtonText": "#FFFFFF",
|
|
94
|
-
"primaryButtonActiveBg": "#
|
|
94
|
+
"primaryButtonActiveBg": "#204b7e",
|
|
95
95
|
"primaryButtonDisabledBg": "#C4C6CC",
|
|
96
96
|
"primaryButtonDisabledText": "#6B7280",
|
|
97
97
|
|
|
@@ -104,14 +104,14 @@
|
|
|
104
104
|
|
|
105
105
|
"dashedButtonBg": "#FFFFFF",
|
|
106
106
|
"dashedButtonHoverBg": "#D1E3FF",
|
|
107
|
-
"dashedButtonText": "#
|
|
107
|
+
"dashedButtonText": "#204b7e",
|
|
108
108
|
"dashedButtonActiveBg": "#B8C7FF",
|
|
109
109
|
"dashedButtonDisabledBg": "#F0F6FF",
|
|
110
110
|
"dashedButtonDisabledText": "#A9BCC6",
|
|
111
111
|
|
|
112
112
|
"linkButtonBg": "transparent",
|
|
113
113
|
"linkButtonHoverBg": "#F5F5F5",
|
|
114
|
-
"linkButtonText": "#
|
|
114
|
+
"linkButtonText": "#204b7e",
|
|
115
115
|
"linkButtonActiveBg": "#D1E3FF",
|
|
116
116
|
"linkButtonDisabledText": "#A9BCC6",
|
|
117
117
|
|
|
@@ -24,15 +24,15 @@ export default class ApiUtils {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
static get = async ({ url, config = { queries: [], order: {} }, headers: customHeaders = {}, ...props }) => {
|
|
27
|
-
const
|
|
27
|
+
const dbPtr = localStorage.getItem('db_ptr');
|
|
28
28
|
|
|
29
29
|
try {
|
|
30
30
|
return await GetData({
|
|
31
31
|
url: createUrlParams(url, config),
|
|
32
32
|
settings,
|
|
33
33
|
headers: {
|
|
34
|
-
...
|
|
35
|
-
|
|
34
|
+
...(settings.headers || {}),
|
|
35
|
+
...(dbPtr ? { db_ptr: dbPtr } : {}),
|
|
36
36
|
...customHeaders,
|
|
37
37
|
},
|
|
38
38
|
...props,
|
|
@@ -43,15 +43,15 @@ export default class ApiUtils {
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
static getRecordDetail = async ({ url, config = { queries: [] }, headers: customHeaders = {}, ...props }) => {
|
|
46
|
-
const
|
|
46
|
+
const dbPtr = localStorage.getItem('db_ptr');
|
|
47
47
|
|
|
48
48
|
try {
|
|
49
49
|
return await GetData({
|
|
50
50
|
url: createUrlParams(url, config),
|
|
51
51
|
settings,
|
|
52
52
|
headers: {
|
|
53
|
-
...
|
|
54
|
-
|
|
53
|
+
...(settings.headers || {}),
|
|
54
|
+
...(dbPtr ? { db_ptr: dbPtr } : {}),
|
|
55
55
|
...customHeaders,
|
|
56
56
|
},
|
|
57
57
|
...props,
|
|
@@ -62,52 +62,64 @@ export default class ApiUtils {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
static post = ({ url, formBody, headers: customHeaders = {}, ...props }) => {
|
|
65
|
-
const
|
|
65
|
+
const dbPtr = localStorage.getItem('db_ptr');
|
|
66
66
|
|
|
67
67
|
return PostData({
|
|
68
68
|
url,
|
|
69
69
|
formBody,
|
|
70
70
|
settings,
|
|
71
71
|
headers: {
|
|
72
|
-
...
|
|
73
|
-
|
|
72
|
+
...(settings.headers || {}),
|
|
73
|
+
...(dbPtr ? { db_ptr: dbPtr } : {}),
|
|
74
74
|
...customHeaders,
|
|
75
75
|
},
|
|
76
76
|
...props,
|
|
77
77
|
});
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
-
static put = ({ url, formBody, ...props }) => {
|
|
81
|
-
const
|
|
80
|
+
static put = ({ url, formBody, headers: customHeaders = {}, ...props }) => {
|
|
81
|
+
const dbPtr = localStorage.getItem('db_ptr');
|
|
82
82
|
|
|
83
83
|
return PutData({
|
|
84
84
|
url,
|
|
85
85
|
settings,
|
|
86
86
|
formBody,
|
|
87
|
-
headers
|
|
87
|
+
headers: {
|
|
88
|
+
...(settings.headers || {}),
|
|
89
|
+
...(dbPtr ? { db_ptr: dbPtr } : {}),
|
|
90
|
+
...customHeaders,
|
|
91
|
+
},
|
|
88
92
|
...props,
|
|
89
93
|
});
|
|
90
94
|
};
|
|
91
95
|
|
|
92
|
-
static patch = ({ url, formBody, ...props }) => {
|
|
93
|
-
const
|
|
96
|
+
static patch = ({ url, formBody, headers: customHeaders = {}, ...props }) => {
|
|
97
|
+
const dbPtr = localStorage.getItem('db_ptr');
|
|
94
98
|
|
|
95
99
|
return PatchData({
|
|
96
100
|
url,
|
|
97
101
|
settings,
|
|
98
102
|
formBody,
|
|
99
|
-
headers
|
|
103
|
+
headers: {
|
|
104
|
+
...(settings.headers || {}),
|
|
105
|
+
...(dbPtr ? { db_ptr: dbPtr } : {}),
|
|
106
|
+
...customHeaders,
|
|
107
|
+
},
|
|
100
108
|
...props,
|
|
101
109
|
});
|
|
102
110
|
};
|
|
103
111
|
|
|
104
|
-
static delete = ({ url, formBody, ...props }) => {
|
|
105
|
-
const
|
|
112
|
+
static delete = ({ url, formBody, headers: customHeaders = {}, ...props }) => {
|
|
113
|
+
const dbPtr = localStorage.getItem('db_ptr');
|
|
106
114
|
|
|
107
115
|
return DeleteData({
|
|
108
116
|
url,
|
|
109
117
|
settings,
|
|
110
|
-
headers
|
|
118
|
+
headers: {
|
|
119
|
+
...(settings.headers || {}),
|
|
120
|
+
...(dbPtr ? { db_ptr: dbPtr } : {}),
|
|
121
|
+
...customHeaders,
|
|
122
|
+
},
|
|
111
123
|
...props,
|
|
112
124
|
});
|
|
113
125
|
};
|
|
@@ -4,6 +4,7 @@ Implements utility functions to be used across project
|
|
|
4
4
|
|
|
5
5
|
/*eslint no-useless-escape:"off",eqeqeq: "off"*/
|
|
6
6
|
import moment from 'moment';
|
|
7
|
+
import { parsePhoneNumberFromString, isValidPhoneNumber } from 'libphonenumber-js';
|
|
7
8
|
|
|
8
9
|
export function IsObjectHaveKeys(obj) {
|
|
9
10
|
return obj && typeof obj == 'object' && Object.keys(obj).length;
|
|
@@ -122,41 +123,6 @@ export const checkLicenseStatus = (expiryDate) => {
|
|
|
122
123
|
return { valid: true, daysLeft, message: null, level: null };
|
|
123
124
|
};
|
|
124
125
|
|
|
125
|
-
/**
|
|
126
|
-
* Checks password expiry status.
|
|
127
|
-
*
|
|
128
|
-
* @param {string|Date} expiryDate
|
|
129
|
-
* @param {number} warningDays
|
|
130
|
-
* @param {string} expiredMessage
|
|
131
|
-
* @param {(daysLeft: number) => string} warningMessage
|
|
132
|
-
*
|
|
133
|
-
* @returns {{ valid: boolean, daysLeft: number, message: string|null, level: "error"|"warning"|null }}
|
|
134
|
-
*/
|
|
135
|
-
|
|
136
|
-
export const checkExpiryStatus = ({ expiryDate, warningDays, expiredMessage, warningMessage }) => {
|
|
137
|
-
const expiry = new Date(expiryDate);
|
|
138
|
-
|
|
139
|
-
if (isNaN(expiry)) {
|
|
140
|
-
return { valid: false, daysLeft: 0, message: 'Invalid date', level: 'error' };
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
expiry.setHours(0, 0, 0, 0);
|
|
144
|
-
const today = new Date();
|
|
145
|
-
today.setHours(0, 0, 0, 0);
|
|
146
|
-
|
|
147
|
-
const msDiff = expiry.getTime() - today.getTime();
|
|
148
|
-
const daysLeft = Math.ceil(msDiff / (1000 * 60 * 60 * 24));
|
|
149
|
-
|
|
150
|
-
if (daysLeft < 0) {
|
|
151
|
-
return { valid: false, daysLeft, message: expiredMessage, level: 'error' };
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (daysLeft <= warningDays) {
|
|
155
|
-
return { valid: true, daysLeft, message: warningMessage(daysLeft), level: 'warning' };
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return { valid: true, daysLeft, message: null, level: null };
|
|
159
|
-
};
|
|
160
126
|
|
|
161
127
|
/**
|
|
162
128
|
* Masks a mobile number by hiding all but the last `visibleDigits`.
|
|
@@ -221,3 +187,51 @@ export function safeJSON(value) {
|
|
|
221
187
|
return null;
|
|
222
188
|
}
|
|
223
189
|
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Convert +countrycode phone into form compatible structure
|
|
193
|
+
* @param {string} phone
|
|
194
|
+
* @returns {object|null}
|
|
195
|
+
*/
|
|
196
|
+
export const formatPhoneForForm = (phone) => {
|
|
197
|
+
if (!phone) return null;
|
|
198
|
+
|
|
199
|
+
const parsed = parsePhoneNumberFromString(phone);
|
|
200
|
+
|
|
201
|
+
if (!parsed) return null;
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
value: parsed.nationalNumber,
|
|
205
|
+
code: {
|
|
206
|
+
dialCode: parsed.countryCallingCode,
|
|
207
|
+
countryCode: parsed.country?.toLowerCase(),
|
|
208
|
+
},
|
|
209
|
+
valid: true,
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Validates a phone number from CountryPhoneInput.
|
|
215
|
+
* Builds full number using country dial code and checks validity.
|
|
216
|
+
*
|
|
217
|
+
* @param {Object} _ - Ant Design rule parameter (unused)
|
|
218
|
+
* @param {Object} val - Phone value object from form
|
|
219
|
+
* @returns {Promise<void>}
|
|
220
|
+
*/
|
|
221
|
+
export const phoneValidator = (_, val) => {
|
|
222
|
+
if (!val || !val.value || !val?.code?.dialCode) {
|
|
223
|
+
return Promise.resolve();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const fullPhone = `+${val.code.dialCode}${val.value}`;
|
|
227
|
+
|
|
228
|
+
return isValidPhoneNumber(fullPhone) ? Promise.resolve() : Promise.reject('Invalid mobile number');
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// Returns phone number with country code (e.g., +919876543210)
|
|
232
|
+
export const formatPhoneWithCountryCode = (phone) => {
|
|
233
|
+
if (phone && typeof phone === 'object' && phone.code) {
|
|
234
|
+
return `+${phone.code.dialCode}${phone.value}`;
|
|
235
|
+
}
|
|
236
|
+
return phone;
|
|
237
|
+
};
|
|
@@ -82,7 +82,7 @@ export async function ApiCall({ url, formBody, method, settings, ...props }) {
|
|
|
82
82
|
...settings.headers,
|
|
83
83
|
...headers,
|
|
84
84
|
...(props.headers || {}),
|
|
85
|
-
Authorization: `Bearer ${token}
|
|
85
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
86
86
|
'Content-Type': 'application/json',
|
|
87
87
|
},
|
|
88
88
|
body: formBody ? JSON.stringify(formBody) : null,
|
|
@@ -153,5 +153,6 @@ export async function ApiCall({ url, formBody, method, settings, ...props }) {
|
|
|
153
153
|
return result;
|
|
154
154
|
} catch (err) {
|
|
155
155
|
console.error('Login error -->', err?.message);
|
|
156
|
+
throw err;
|
|
156
157
|
}
|
|
157
158
|
}
|
package/core/lib/utils/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import { GetData, PostData, PutData, DeleteData } from './http/http.utils';
|
|
|
14
14
|
|
|
15
15
|
import { getExportData } from './generic/generic.utils';
|
|
16
16
|
|
|
17
|
-
import { ConvertBytesToArray, safeJSON } from './common/common.utils';
|
|
17
|
+
import { ConvertBytesToArray, safeJSON, formatPhoneForForm, phoneValidator, formatPhoneWithCountryCode } from './common/common.utils';
|
|
18
18
|
|
|
19
19
|
import SettingsUtil from './setting.utils';
|
|
20
20
|
|
|
@@ -37,4 +37,7 @@ export {
|
|
|
37
37
|
SettingsUtil,
|
|
38
38
|
FormUtils,
|
|
39
39
|
safeJSON,
|
|
40
|
+
formatPhoneForForm,
|
|
41
|
+
phoneValidator,
|
|
42
|
+
formatPhoneWithCountryCode,
|
|
40
43
|
};
|
package/core/models/base/base.js
CHANGED
|
@@ -88,9 +88,13 @@ class BaseAPI {
|
|
|
88
88
|
* Get the data from the table
|
|
89
89
|
*/
|
|
90
90
|
get(config = {}) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
const { url, headers, ...rest } = config;
|
|
92
|
+
return ApiUtils.get({
|
|
93
|
+
url: url || this.endpoint,
|
|
94
|
+
headers,
|
|
95
|
+
config: rest,
|
|
96
|
+
...rest,
|
|
97
|
+
});
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
getRelations(id) {
|