ui-soxo-bootstrap-core 2.6.1-dev.1 → 2.6.1-dev.11
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/lib/Store.js +3 -3
- package/core/lib/components/global-header/global-header.js +2 -2
- package/core/lib/components/sidemenu/sidemenu.js +19 -13
- 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 +5 -4
- package/core/lib/models/menus/components/menu-list/menu-list.js +424 -467
- 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 +46 -0
- package/core/lib/pages/login/communication-mode-selection.scss +60 -0
- package/core/lib/pages/login/login.js +126 -22
- package/core/lib/pages/login/login.scss +229 -334
- package/core/lib/pages/login/reset-password.js +124 -0
- package/core/lib/pages/login/reset-password.scss +31 -0
- 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 +85 -0
- package/core/lib/utils/http/http.utils.js +1 -0
- package/core/lib/utils/index.js +4 -1
- package/core/models/base/base.js +7 -3
- package/core/models/core-scripts/core-scripts.js +9 -0
- 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 +5 -9
- package/core/models/menus/menus.js +21 -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 +16 -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 +266 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.js +75 -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 +285 -399
- package/core/modules/steps/action-buttons.js +42 -44
- package/core/modules/steps/action-buttons.scss +35 -6
- package/core/modules/steps/steps.js +12 -10
- package/core/modules/steps/steps.scss +229 -31
- package/core/modules/steps/timeline.js +21 -19
- package/package.json +2 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResetPassword Component
|
|
3
|
+
*
|
|
4
|
+
* Handles staff password reset flow:
|
|
5
|
+
* - Accepts username
|
|
6
|
+
* - Selects communication mode (email/SMS)
|
|
7
|
+
* - Calls API to send reset link
|
|
8
|
+
* - Displays success/error messages
|
|
9
|
+
* - Allows navigation back to login
|
|
10
|
+
*
|
|
11
|
+
* Props:
|
|
12
|
+
* @param {Function} onBack - Triggered when "Back to Login" is clicked
|
|
13
|
+
* @param {string} title - Page title
|
|
14
|
+
* @param {string} subtitle - Page subtitle
|
|
15
|
+
* @param {string} buttonText - Submit button text
|
|
16
|
+
* @param {string} defaultUsername - Pre-filled username
|
|
17
|
+
* @param {boolean} disabledUserName - Disable username field
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import React, { useState, useEffect, useRef } from 'react';
|
|
21
|
+
import { Divider, Form, Input, message } from 'antd';
|
|
22
|
+
import { Button } from '../../elements';
|
|
23
|
+
import CommunicationModeSelection from './commnication-mode-selection';
|
|
24
|
+
import { motion } from 'framer-motion';
|
|
25
|
+
import './reset-password.scss';
|
|
26
|
+
import { UsersAPI } from '../../../models';
|
|
27
|
+
|
|
28
|
+
function ResetPassword({ onBack, title, subtitle, buttonText, defaultUsername, disabledUserName }) {
|
|
29
|
+
// Selected communication mode (default: email) */
|
|
30
|
+
const [communicationMode, setCommunicationMode] = useState('email');
|
|
31
|
+
|
|
32
|
+
const [modeError, setModeError] = useState(false);
|
|
33
|
+
|
|
34
|
+
// Loading state for submit button */
|
|
35
|
+
const [loading, setLoading] = useState(false);
|
|
36
|
+
|
|
37
|
+
const [form] = Form.useForm();
|
|
38
|
+
|
|
39
|
+
// Ref to username input auto focus
|
|
40
|
+
const inputRef = useRef(null);
|
|
41
|
+
|
|
42
|
+
// Pre-fills username if provided and disabled.
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (disabledUserName && defaultUsername) {
|
|
45
|
+
form.setFieldsValue({ username: defaultUsername });
|
|
46
|
+
}
|
|
47
|
+
}, [disabledUserName, defaultUsername]);
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
inputRef.current?.focus();
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Sends forgot password request to backend.
|
|
55
|
+
* Payload: { mode, username, user_type: 'staff' }
|
|
56
|
+
*/
|
|
57
|
+
const handleSendForgetPassword = async (values) => {
|
|
58
|
+
const payload = {
|
|
59
|
+
mode: communicationMode,
|
|
60
|
+
username: values.username,
|
|
61
|
+
user_type: 'staff',
|
|
62
|
+
};
|
|
63
|
+
setLoading(true);
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const res = await UsersAPI.createForgotePassword(payload);
|
|
67
|
+
|
|
68
|
+
if (!res?.success) {
|
|
69
|
+
throw new Error(res?.message || 'Reset password failed');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
message.success(res?.message || 'Reset password link sent');
|
|
73
|
+
} catch (err) {
|
|
74
|
+
message.warning(err?.message || 'Reset password failed');
|
|
75
|
+
} finally {
|
|
76
|
+
setLoading(false);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Clears auth storage and navigates back.
|
|
82
|
+
*/
|
|
83
|
+
const handleBackToLogin = () => {
|
|
84
|
+
localStorage.removeItem('access_token');
|
|
85
|
+
localStorage.removeItem('refresh_token');
|
|
86
|
+
sessionStorage.clear();
|
|
87
|
+
onBack();
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<motion.div
|
|
92
|
+
className="forgot-password-container"
|
|
93
|
+
initial={{ opacity: 0, y: 30 }}
|
|
94
|
+
animate={{ opacity: 1, y: 0 }}
|
|
95
|
+
exit={{ opacity: 0, y: -20 }}
|
|
96
|
+
transition={{
|
|
97
|
+
duration: 0.30,
|
|
98
|
+
ease: 'easeOut',
|
|
99
|
+
}}
|
|
100
|
+
>
|
|
101
|
+
<h3 className="password-title">{title}</h3>
|
|
102
|
+
{/* <p className="password-subtitle">{subtitle}</p>
|
|
103
|
+
<Divider /> */}
|
|
104
|
+
<Form layout="vertical" form={form} onFinish={handleSendForgetPassword}>
|
|
105
|
+
<Form.Item label="Username" name="username" rules={[{ required: true, message: 'Please input your username' }]}>
|
|
106
|
+
<Input placeholder="Enter your username" disabled={disabledUserName} ref={inputRef}/>
|
|
107
|
+
</Form.Item>
|
|
108
|
+
|
|
109
|
+
<CommunicationModeSelection communicationMode={communicationMode} setCommunicationMode={setCommunicationMode} modeError={modeError} />
|
|
110
|
+
|
|
111
|
+
<Button type="primary" htmlType="submit" loading={loading}>
|
|
112
|
+
{buttonText}
|
|
113
|
+
</Button>
|
|
114
|
+
<div className="back-to-login">
|
|
115
|
+
<a onClick={handleBackToLogin}>
|
|
116
|
+
Back to Login
|
|
117
|
+
</a>
|
|
118
|
+
</div>
|
|
119
|
+
</Form>
|
|
120
|
+
</motion.div>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export default ResetPassword;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
.forgot-password-container {
|
|
2
|
+
|
|
3
|
+
padding: 4px;
|
|
4
|
+
.password-title{
|
|
5
|
+
color: #1f1f1f;
|
|
6
|
+
margin: 0 0 8px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.password-subtitle {
|
|
10
|
+
font-size: 14px;
|
|
11
|
+
font-weight: 400;
|
|
12
|
+
color: #6b7280;
|
|
13
|
+
line-height: 1.5;
|
|
14
|
+
margin: 0 0 20px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.ant-divider {
|
|
18
|
+
margin: 0;
|
|
19
|
+
border-top: 1px solid #e5e7eb;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.back-to-login {
|
|
23
|
+
margin-top: 10px;
|
|
24
|
+
text-align: center;
|
|
25
|
+
|
|
26
|
+
a {
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
color: #204b7e;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -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,6 +123,42 @@ export const checkLicenseStatus = (expiryDate) => {
|
|
|
122
123
|
return { valid: true, daysLeft, message: null, level: null };
|
|
123
124
|
};
|
|
124
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Checks password expiry status.
|
|
128
|
+
*
|
|
129
|
+
* @param {string|Date} expiryDate
|
|
130
|
+
* @param {number} warningDays
|
|
131
|
+
* @param {string} expiredMessage
|
|
132
|
+
* @param {(daysLeft: number) => string} warningMessage
|
|
133
|
+
*
|
|
134
|
+
* @returns {{ valid: boolean, daysLeft: number, message: string|null, level: "error"|"warning"|null }}
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
export const checkExpiryStatus = ({ expiryDate, warningDays, expiredMessage, warningMessage }) => {
|
|
138
|
+
const expiry = new Date(expiryDate);
|
|
139
|
+
|
|
140
|
+
if (isNaN(expiry)) {
|
|
141
|
+
return { valid: false, daysLeft: 0, message: 'Invalid date', level: 'error' };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
expiry.setHours(0, 0, 0, 0);
|
|
145
|
+
const today = new Date();
|
|
146
|
+
today.setHours(0, 0, 0, 0);
|
|
147
|
+
|
|
148
|
+
const msDiff = expiry.getTime() - today.getTime();
|
|
149
|
+
const daysLeft = Math.ceil(msDiff / (1000 * 60 * 60 * 24));
|
|
150
|
+
|
|
151
|
+
if (daysLeft < 0) {
|
|
152
|
+
return { valid: false, daysLeft, message: expiredMessage, level: 'error' };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (daysLeft <= warningDays) {
|
|
156
|
+
return { valid: true, daysLeft, message: warningMessage(daysLeft), level: 'warning' };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return { valid: true, daysLeft, message: null, level: null };
|
|
160
|
+
};
|
|
161
|
+
|
|
125
162
|
/**
|
|
126
163
|
* Masks a mobile number by hiding all but the last `visibleDigits`.
|
|
127
164
|
* Adds spacing only to the masked portion (groups of 3),
|
|
@@ -185,3 +222,51 @@ export function safeJSON(value) {
|
|
|
185
222
|
return null;
|
|
186
223
|
}
|
|
187
224
|
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Convert +countrycode phone into form compatible structure
|
|
228
|
+
* @param {string} phone
|
|
229
|
+
* @returns {object|null}
|
|
230
|
+
*/
|
|
231
|
+
export const formatPhoneForForm = (phone) => {
|
|
232
|
+
if (!phone) return null;
|
|
233
|
+
|
|
234
|
+
const parsed = parsePhoneNumberFromString(phone);
|
|
235
|
+
|
|
236
|
+
if (!parsed) return null;
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
value: parsed.nationalNumber,
|
|
240
|
+
code: {
|
|
241
|
+
dialCode: parsed.countryCallingCode,
|
|
242
|
+
countryCode: parsed.country?.toLowerCase(),
|
|
243
|
+
},
|
|
244
|
+
valid: true,
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Validates a phone number from CountryPhoneInput.
|
|
250
|
+
* Builds full number using country dial code and checks validity.
|
|
251
|
+
*
|
|
252
|
+
* @param {Object} _ - Ant Design rule parameter (unused)
|
|
253
|
+
* @param {Object} val - Phone value object from form
|
|
254
|
+
* @returns {Promise<void>}
|
|
255
|
+
*/
|
|
256
|
+
export const phoneValidator = (_, val) => {
|
|
257
|
+
if (!val || !val.value || !val?.code?.dialCode) {
|
|
258
|
+
return Promise.resolve();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const fullPhone = `+${val.code.dialCode}${val.value}`;
|
|
262
|
+
|
|
263
|
+
return isValidPhoneNumber(fullPhone) ? Promise.resolve() : Promise.reject('Invalid mobile number');
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// Returns phone number with country code (e.g., +919876543210)
|
|
267
|
+
export const formatPhoneWithCountryCode = (phone) => {
|
|
268
|
+
if (phone && typeof phone === 'object' && phone.code) {
|
|
269
|
+
return `+${phone.code.dialCode}${phone.value}`;
|
|
270
|
+
}
|
|
271
|
+
return phone;
|
|
272
|
+
};
|
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) {
|
|
@@ -6,7 +6,8 @@ import { useTranslation, Button } from './../../../../lib/';
|
|
|
6
6
|
import { UsersAPI } from '../../..';
|
|
7
7
|
import SignatureCanvasComponent from '../../../../lib/components/consent/signature-pad';
|
|
8
8
|
|
|
9
|
-
const DoctorAdd = ({ visible, onCancel,
|
|
9
|
+
const DoctorAdd = ({ visible, onCancel, doctorId, doctorData, onSuccess }) => {
|
|
10
|
+
// console.log('attributes', attributes);
|
|
10
11
|
const [form] = Form.useForm();
|
|
11
12
|
const { t } = useTranslation();
|
|
12
13
|
|
|
@@ -21,8 +22,8 @@ const DoctorAdd = ({ visible, onCancel, attributes, doctorId, doctorData, onSucc
|
|
|
21
22
|
const [doctorID, setDoctorID] = useState(false);
|
|
22
23
|
const [selectedDoctor, setSelectedDoctor] = useState(null);
|
|
23
24
|
|
|
24
|
-
const propValues = attributes || {};
|
|
25
|
-
const doctorType = propValues?.type;
|
|
25
|
+
// const propValues = attributes || {};
|
|
26
|
+
// const doctorType = propValues?.type;
|
|
26
27
|
|
|
27
28
|
const editMode = Boolean(doctorId);
|
|
28
29
|
|
|
@@ -37,6 +38,10 @@ const DoctorAdd = ({ visible, onCancel, attributes, doctorId, doctorData, onSucc
|
|
|
37
38
|
message: '',
|
|
38
39
|
});
|
|
39
40
|
|
|
41
|
+
const getDoctorTypeOptions = () => [
|
|
42
|
+
{ label: 'In House', value: 'DRINH' },
|
|
43
|
+
{ label: 'Out Side', value: 'DROTR' },
|
|
44
|
+
];
|
|
40
45
|
/** Autofocus on modal open */
|
|
41
46
|
useEffect(() => {
|
|
42
47
|
if (visible) {
|
|
@@ -266,7 +271,7 @@ const DoctorAdd = ({ visible, onCancel, attributes, doctorId, doctorData, onSucc
|
|
|
266
271
|
<Row gutter={16}>
|
|
267
272
|
<Col span={8}>
|
|
268
273
|
<Form.Item label="Type" name="type">
|
|
269
|
-
<Select placeholder="Select Type" options={
|
|
274
|
+
<Select placeholder="Select Type" options={getDoctorTypeOptions() || []} showSearch />
|
|
270
275
|
</Form.Item>
|
|
271
276
|
</Col>
|
|
272
277
|
|
|
@@ -164,7 +164,7 @@ const MenuAdd = ({ model, callback, edit, history, formContent, match, additiona
|
|
|
164
164
|
<div className="left-container">
|
|
165
165
|
{/* Caption */}
|
|
166
166
|
<Form.Item name={'caption'} label="Caption" rules={[{ required: true, message: 'Caption is required' }]}>
|
|
167
|
-
<Input placeholder="Enter caption" />
|
|
167
|
+
<Input placeholder="Enter caption" autoFocus />
|
|
168
168
|
</Form.Item>
|
|
169
169
|
{/* Caption Ends */}
|
|
170
170
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useCallback, useEffect } from 'react';
|
|
2
|
-
import { Space, Popconfirm, Input, Drawer, Skeleton, Collapse, message } from 'antd';
|
|
2
|
+
import { Space, Popconfirm, Input, Drawer, Skeleton, Collapse, message, Tag } from 'antd';
|
|
3
3
|
import { ReloadOutlined, DeleteOutlined, EditOutlined, PlusCircleFilled, CopyOutlined } from '@ant-design/icons';
|
|
4
4
|
import { Button, Card, Switch, DraggableWrapper } from '../../../../lib';
|
|
5
5
|
// for draggable menu list import { DndProvider } from "react-dnd";
|
|
@@ -55,7 +55,6 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
|
|
|
55
55
|
.catch(() => setLoading(false));
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
console.log('record', records);
|
|
59
58
|
/**
|
|
60
59
|
*
|
|
61
60
|
*/
|
|
@@ -206,7 +205,7 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
|
|
|
206
205
|
|
|
207
206
|
const filtered = records.filter((r) => r.name?.toUpperCase().includes(query.toUpperCase()));
|
|
208
207
|
|
|
209
|
-
const visibleItems =
|
|
208
|
+
const visibleItems = filtered;
|
|
210
209
|
|
|
211
210
|
const onSearch = (event) => {
|
|
212
211
|
setQuery(event.target.value);
|
|
@@ -440,7 +439,7 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
|
|
|
440
439
|
function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerVisible, deleteRecord) {
|
|
441
440
|
return (
|
|
442
441
|
<Space onClick={(e) => e.stopPropagation()}>
|
|
443
|
-
{
|
|
442
|
+
<Tag color={item.is_visible === true ? 'green' : 'blue'}>{item.is_visible === true ? 'VISIBLE' : 'HIDDEN'}</Tag>{' '}
|
|
444
443
|
<Button
|
|
445
444
|
size="small"
|
|
446
445
|
type="dashed"
|
|
@@ -459,7 +458,6 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
|
|
|
459
458
|
<PlusCircleFilled />
|
|
460
459
|
Add Sub Menu
|
|
461
460
|
</Button>
|
|
462
|
-
|
|
463
461
|
{model.ModalAddComponent && (
|
|
464
462
|
<Button
|
|
465
463
|
size="small"
|
|
@@ -473,8 +471,7 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
|
|
|
473
471
|
<EditOutlined />
|
|
474
472
|
</Button>
|
|
475
473
|
)}
|
|
476
|
-
|
|
477
|
-
{/* <Button
|
|
474
|
+
<Button
|
|
478
475
|
size="small"
|
|
479
476
|
type="default"
|
|
480
477
|
onClick={() => {
|
|
@@ -484,8 +481,7 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
|
|
|
484
481
|
}}
|
|
485
482
|
>
|
|
486
483
|
<CopyOutlined />
|
|
487
|
-
</Button>
|
|
488
|
-
|
|
484
|
+
</Button>
|
|
489
485
|
<Popconfirm title="Are you sure?" onConfirm={() => deleteRecord(item)}>
|
|
490
486
|
<Button danger size="small" type="default">
|
|
491
487
|
<DeleteOutlined />
|
|
@@ -177,28 +177,47 @@ class MenusAPI extends Base {
|
|
|
177
177
|
* @param {*} menu
|
|
178
178
|
* @returns
|
|
179
179
|
*/
|
|
180
|
-
getMenus = (config) => {
|
|
180
|
+
getMenus = (config, dbPtr = null) => {
|
|
181
181
|
// Use 'core-menus' endpoint if REACT_APP_USE_CORE_MENUS is true (used for Matria)
|
|
182
182
|
const url =
|
|
183
183
|
process.env.REACT_APP_USE_CORE_MENUS === 'true'
|
|
184
184
|
? 'core-menus/get-menus' // Matria
|
|
185
185
|
: 'menus/get-menus'; // NURA
|
|
186
186
|
|
|
187
|
+
if (!dbPtr) dbPtr = localStorage.db_ptr;
|
|
188
|
+
|
|
187
189
|
return this.get({
|
|
188
190
|
url,
|
|
189
191
|
config,
|
|
192
|
+
headers: {
|
|
193
|
+
db_ptr: dbPtr,
|
|
194
|
+
},
|
|
195
|
+
}).then((result) => result);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
getMenubyUser = (user_id) => {
|
|
199
|
+
const url = `menus/get-menus?userId=${user_id}`;
|
|
200
|
+
return this.get({
|
|
201
|
+
url,
|
|
190
202
|
}).then((result) => result);
|
|
191
203
|
};
|
|
192
204
|
|
|
193
205
|
// get core-menu list with submenu
|
|
194
206
|
getCoreMenuLists = () => {
|
|
195
207
|
const url = 'core-menus/core-menus?step=1&header_id=null';
|
|
196
|
-
|
|
197
208
|
return this.get({
|
|
198
209
|
url,
|
|
199
210
|
}).then((result) => result);
|
|
200
211
|
};
|
|
201
212
|
|
|
213
|
+
getCoreMenuByRoleId = async (role_id) => {
|
|
214
|
+
const url = `menus/get-menus-by-role/${role_id}`;
|
|
215
|
+
const result = await this.get({
|
|
216
|
+
url,
|
|
217
|
+
});
|
|
218
|
+
return result;
|
|
219
|
+
};
|
|
220
|
+
|
|
202
221
|
getCoreMenus = () => {
|
|
203
222
|
return [
|
|
204
223
|
// {
|