ui-soxo-bootstrap-core 2.6.1-dev.7 → 2.6.2

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 (26) hide show
  1. package/.github/workflows/npm-publish.yml +19 -49
  2. package/core/components/external-window/DEVELOPER_GUIDE.md +705 -0
  3. package/core/components/menu-template-api/menu-template-api.js +2 -2
  4. package/core/lib/elements/basic/country-phone-input/country-phone-input.js +57 -26
  5. package/core/lib/elements/basic/country-phone-input/phone-input.scss +0 -14
  6. package/core/lib/models/forms/components/form-creator/form-creator.js +502 -468
  7. package/core/lib/pages/change-password/change-password.js +14 -24
  8. package/core/lib/pages/login/login.js +10 -33
  9. package/core/lib/pages/login/reset-password.js +13 -12
  10. package/core/lib/utils/api/api.utils.js +39 -50
  11. package/core/lib/utils/common/common.utils.js +0 -24
  12. package/core/lib/utils/http/http.utils.js +1 -0
  13. package/core/lib/utils/index.js +28 -22
  14. package/core/models/base/base.js +3 -7
  15. package/core/models/menus/components/menu-lists/menu-lists.js +2 -2
  16. package/core/models/menus/menus.js +4 -15
  17. package/core/models/roles/roles.js +0 -9
  18. package/core/models/users/components/assign-role/assign-role.js +50 -138
  19. package/core/models/users/components/assign-role/assign-role.scss +45 -189
  20. package/core/models/users/components/user-add/user-add.js +10 -13
  21. package/core/models/users/components/user-add/user-edit.js +1 -8
  22. package/core/models/users/users.js +8 -24
  23. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +26 -59
  24. package/core/modules/steps/action-buttons.js +1 -5
  25. package/package.json +2 -2
  26. package/core/models/users/components/assign-role/avatar-props.js +0 -45
@@ -39,7 +39,7 @@ function ChangePassword({ history }) {
39
39
 
40
40
  const [loading, setLoading] = useState(false);
41
41
 
42
- console.log(user);
42
+
43
43
 
44
44
  const onFinish = (values) => {
45
45
 
@@ -55,34 +55,24 @@ function ChangePassword({ history }) {
55
55
  confirm_password: values.conpassword
56
56
  }
57
57
 
58
- ApiUtils.post({
59
- url: `users/change-password`,
60
- formBody,
61
- hideError: true
62
- }).then((result) => {
63
-
64
- var msg = Object.values(result)
65
-
66
- if (msg[0] === 'INCORRECT PASSWORD') {
67
- //If current Password is entered wrong
68
- message.error('Incorrect Password')
69
- setLoading(false);
70
- return false
71
- }
72
- else {
58
+ ApiUtils.post({
59
+ url: `users/change-password`,
60
+ formBody,
61
+ hideError: true
62
+ })
63
+ .then((result) => {
73
64
 
74
65
  setLoading(false);
75
66
 
76
67
  history.goBack();
77
68
 
78
- // Update successful.
79
- message.success('Your password has been updated!')
80
- }
81
-
82
- }).catch(function (error) {
83
-
84
- // An error happened.
85
- message.error(error.result || error.message)
69
+ // Update successful.
70
+ message.success(result.result || 'Your password has been updated!');
71
+
72
+ }).catch(function (error) {
73
+
74
+ // An error happened.
75
+ message.warning(error.result || error.message);
86
76
 
87
77
  setLoading(false);
88
78
 
@@ -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 ,checkExpiryStatus} from '../../utils/common/common.utils';
33
+ import { checkLicenseStatus, formatMobile, checkExpiryStatus } from '../../utils/common/common.utils';
34
34
 
35
35
  import { MailOutlined, MessageOutlined, WhatsAppOutlined } from '@ant-design/icons';
36
36
 
@@ -50,9 +50,6 @@ const tailLayout = {
50
50
 
51
51
  const LICENSE_EXPIRY = '2026-12-12';
52
52
 
53
- const headers = {
54
- db_ptr: 'nuraho',
55
- };
56
53
  //password valdity expire
57
54
  const PASSWORD_VALIDITY_DAYS = 90;
58
55
 
@@ -62,7 +59,7 @@ const PASSWORD_VALIDITY_DAYS = 90;
62
59
  * @returns
63
60
  */
64
61
  function LoginPhone({ history, appSettings }) {
65
- const { brandLogo, heroImage, footerLogo } = appSettings;
62
+ const { brandLogo, heroImage, footerLogo, headers } = appSettings;
66
63
 
67
64
  // Hook for OTP Timer
68
65
  const { expired: otpExpired, formatted, startFromExpiry } = useOtpTimer();
@@ -130,7 +127,8 @@ function LoginPhone({ history, appSettings }) {
130
127
  const lastPasswordChange = otherDetails?.last_password_change;
131
128
 
132
129
  if (lastPasswordChange) {
133
- const passwordExpiryDate = new Date(lastPasswordChange);
130
+ const onlyDate = new Date(lastPasswordChange).toISOString().split('T')[0];
131
+ const passwordExpiryDate = new Date(onlyDate);
134
132
  passwordExpiryDate.setDate(passwordExpiryDate.getDate() + PASSWORD_VALIDITY_DAYS);
135
133
 
136
134
  const passwordStatus = checkExpiryStatus({
@@ -215,7 +213,7 @@ function LoginPhone({ history, appSettings }) {
215
213
  setUser(data);
216
214
  // Set default communication mode automatically
217
215
  if (result.data.mode) {
218
- setCommunicationMode(result.data.mode);
216
+ setCommunicationMode(result.data.mode); // <--- fix
219
217
  }
220
218
  } else {
221
219
  let d = user;
@@ -234,17 +232,6 @@ function LoginPhone({ history, appSettings }) {
234
232
  localStorage.setItem('userInfo', JSON.stringify(userInfo));
235
233
  if (refresh_token) localStorage.setItem('refresh_token', refresh_token);
236
234
 
237
- // Setting DBPTR
238
- if (user?.organization_details) {
239
- const data = safeJSON(user?.organization_details);
240
-
241
- const defaultBranch = data.branch.find((b) => b.defaultBranch === true);
242
-
243
- const defaultDbptr = defaultBranch?.dbPtr;
244
-
245
- localStorage.setItem('db_ptr', defaultDbptr);
246
- }
247
-
248
235
  history.push('/');
249
236
  }
250
237
  } else {
@@ -349,10 +336,10 @@ function LoginPhone({ history, appSettings }) {
349
336
  if (result.success) {
350
337
  // for expiry_time
351
338
  startFromExpiry(result?.expiry_time);
352
- // if the api is sucess then go for otpverification step
353
- setotpVerification(true);
354
339
  // set button loading false
355
340
  setLoading(false);
341
+ // if the api is sucess then go for otpverification step
342
+ setotpVerification(true);
356
343
  } else {
357
344
  setLoading(false);
358
345
  message.error(result.message);
@@ -405,16 +392,6 @@ function LoginPhone({ history, appSettings }) {
405
392
  // Setting refresh_token
406
393
  if (result.refresh_token) localStorage.setItem('refresh_token', result.refresh_token);
407
394
 
408
- // Setting DBPTR
409
- if (result?.user?.organization_details) {
410
- const data = safeJSON(result?.user?.organization_details);
411
-
412
- const defaultBranch = data.branch.find((b) => b.defaultBranch === 'true');
413
- const defaultDbptr = defaultBranch?.dbPtr;
414
-
415
- localStorage.setItem('db_ptr', defaultDbptr);
416
- }
417
-
418
395
  dispatch({ type: 'user', payload: userInfo });
419
396
  // set user info into local storage
420
397
  localStorage.setItem('userInfo', JSON.stringify(userInfo));
@@ -791,7 +768,7 @@ function LoginPhone({ history, appSettings }) {
791
768
  <h4></h4>
792
769
  </div>
793
770
 
794
- {/* {!process.env.REACT_APP_SHOW_BRANCH_SWITCHER && <div className="branch-switcher">{globalCustomerHeader()}</div>} */}
771
+ {!process.env.REACT_APP_SHOW_BRANCH_SWITCHER && <div className="branch-switcher">{globalCustomerHeader()}</div>}
795
772
 
796
773
  {process.env.REACT_APP_ENABLE_LDAP === 'true' && (
797
774
  <Button loading={ldaploading} type="secondary" className="SubmitBtn" onClick={loginWithLdap}>
@@ -830,8 +807,8 @@ function LoginPhone({ history, appSettings }) {
830
807
  title={expiredPassword ? 'Password Expired' : 'Forgot Password'}
831
808
  subtitle={
832
809
  expiredPassword
833
- ? 'Enter your username and choose your preferred OTP method to receive a reset link.'
834
- : 'Enter your username to reset your password and select your preferred OTP method.'
810
+ ? 'Your password has expired. Select a preferred communication method to receive the One-Time Password (OTP) to continue.'
811
+ : 'Enter your username and Select a preferred communication method to receive the One-Time Password (OTP) to continue..'
835
812
  }
836
813
  buttonText={expiredPassword ? 'Send Reset Link' : 'Reset Password'}
837
814
  />
@@ -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,18 +90,12 @@ 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: 70 }}
93
+ initial={{ opacity: 0, y: 30 }}
87
94
  animate={{ opacity: 1, y: 0 }}
88
- exit={{ opacity: 0, y: -50 }}
95
+ exit={{ opacity: 0, y: -20 }}
89
96
  transition={{
90
- y: {
91
- duration: 1,
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>
@@ -102,7 +103,7 @@ function ResetPassword({ onBack, title, subtitle, buttonText, defaultUsername, d
102
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} />
@@ -1,4 +1,10 @@
1
- import { PostData, GetData, PutData, PatchData, DeleteData } from './../http/http.utils';
1
+ import {
2
+ PostData,
3
+ GetData,
4
+ PutData,
5
+ PatchData,
6
+ DeleteData,
7
+ } from "./../http/http.utils";
2
8
 
3
9
  let headers = {};
4
10
 
@@ -23,56 +29,40 @@ export default class ApiUtils {
23
29
  return this.user;
24
30
  };
25
31
 
26
- static get = async ({ url, config = { queries: [], order: {} }, headers: customHeaders = {}, ...props }) => {
27
- const { headers: defaultHeaders } = settings;
28
-
29
- try {
30
- return await GetData({
31
- url: createUrlParams(url, config),
32
- settings,
33
- headers: {
34
- ...defaultHeaders,
35
- // override here
36
- ...customHeaders,
37
- },
38
- ...props,
39
- });
40
- } catch (result_1) {
41
- console.log(result_1);
42
- }
32
+ static get = ({ url, config = { queries: [], order: {} }, ...props }) => {
33
+ const { headers } = settings;
34
+
35
+ return GetData({
36
+ url: createUrlParams(url, config),
37
+ settings,
38
+ headers,
39
+ ...props,
40
+ }).catch((result) => {
41
+ console.log(result);
42
+ });
43
43
  };
44
44
 
45
- static getRecordDetail = async ({ url, config = { queries: [] }, headers: customHeaders = {}, ...props }) => {
46
- const { headers: defaultHeaders } = settings;
47
-
48
- try {
49
- return await GetData({
50
- url: createUrlParams(url, config),
51
- settings,
52
- headers: {
53
- ...defaultHeaders,
54
- // override here
55
- ...customHeaders,
56
- },
57
- ...props,
58
- });
59
- } catch (result_1) {
60
- console.log(result_1);
61
- }
45
+ static getRecordDetail = ({ url, config = { queries: [] }, ...props }) => {
46
+ const { headers } = settings;
47
+
48
+ return GetData({
49
+ url: createUrlParams(url, config),
50
+ settings,
51
+ headers,
52
+ ...props,
53
+ }).catch((result) => {
54
+ console.log(result);
55
+ });
62
56
  };
63
57
 
64
- static post = ({ url, formBody, headers: customHeaders = {}, ...props }) => {
65
- const { headers: defaultHeaders } = settings;
58
+ static post = ({ url, formBody, ...props }) => {
59
+ const { headers } = settings;
66
60
 
67
61
  return PostData({
68
62
  url,
69
63
  formBody,
70
64
  settings,
71
- headers: {
72
- ...defaultHeaders,
73
- // override here
74
- ...customHeaders,
75
- },
65
+ headers,
76
66
  ...props,
77
67
  });
78
68
  };
@@ -115,11 +105,11 @@ export default class ApiUtils {
115
105
  static upload = ({ url, data }) => {
116
106
  return fetch(process.env.REACT_APP_endpoint + url, {
117
107
  // Your POST endpoint
118
- method: 'POST',
108
+ method: "POST",
119
109
  headers: {
120
110
  // 'App-Type': 313,
121
111
  // 'App-Version': '1.0.1',
122
- Authorization: 'Bearer ' + localStorage.access_token,
112
+ Authorization: "Bearer " + localStorage.access_token,
123
113
  // type:'multipart/formData'
124
114
  },
125
115
  // credentials: 'include',
@@ -146,17 +136,16 @@ export default class ApiUtils {
146
136
  * @returns
147
137
  */
148
138
  static getAuthStatus = ({ settings: config, token }) => {
149
- // headers = headers;
139
+ headers = headers;
150
140
 
151
141
  settings = config;
152
142
 
153
143
  return GetData({
154
144
  url: `auth/profile`,
155
145
  settings,
156
- headers: {
157
- db_ptr: 'nuraho',
158
- },
159
- token,
146
+
147
+ headers,
148
+ token
160
149
  });
161
150
  };
162
151
  }
@@ -170,7 +159,7 @@ function createUrlParams(url, config) {
170
159
  let { queries = [], limit, order } = config;
171
160
 
172
161
  if (queries.length > 0 || limit > 0) {
173
- base_url += '?';
162
+ base_url += "?";
174
163
  }
175
164
 
176
165
  queries.forEach((ele) => {
@@ -197,27 +197,3 @@ export const formatMobile = (mobile, visibleDigits = 4) => {
197
197
  // Combine masked and visible parts without spacing the visible digits
198
198
  return `${maskedWithSpaces} ${visible}`;
199
199
  };
200
-
201
- /**
202
- * Safely parse a JSON value.
203
- *
204
- * - Accepts JSON strings or plain objects
205
- * - Returns null on any invalid or missing data
206
- */
207
- export function safeJSON(value) {
208
- if (value == null) return null;
209
-
210
- if (typeof value === 'object' && !Array.isArray(value)) {
211
- return value;
212
- }
213
-
214
- if (typeof value !== 'string' || value.trim() === '') {
215
- return null;
216
- }
217
-
218
- try {
219
- return JSON.parse(value);
220
- } catch {
221
- return null;
222
- }
223
- }
@@ -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
  }
@@ -1,8 +1,10 @@
1
- import { Location } from './location/location.utils';
1
+
2
+
3
+ import { Location } from './location/location.utils'
2
4
 
3
5
  import Notification from './notification.utils';
4
6
 
5
- import DateUtils from './date/date.utils';
7
+ import DateUtils from './date/date.utils'
6
8
 
7
9
  import ApiUtils from './api/api.utils';
8
10
 
@@ -14,27 +16,31 @@ import { GetData, PostData, PutData, DeleteData } from './http/http.utils';
14
16
 
15
17
  import { getExportData } from './generic/generic.utils';
16
18
 
17
- import { ConvertBytesToArray, safeJSON } from './common/common.utils';
19
+ import { ConvertBytesToArray } from './common/common.utils';
18
20
 
19
21
  import SettingsUtil from './setting.utils';
20
22
 
23
+
21
24
  export {
22
- // FirebaseUtils,
23
-
24
- Notification,
25
- Location,
26
- DateUtils,
27
- ApiUtils,
28
- UploadUtils,
29
- GetData,
30
- PostData,
31
- PutData,
32
- DeleteData,
33
- getExportData,
34
-
35
- // Common Functions
36
- ConvertBytesToArray,
37
- SettingsUtil,
38
- FormUtils,
39
- safeJSON,
40
- };
25
+ // FirebaseUtils,
26
+
27
+ Notification,
28
+
29
+ Location,
30
+ DateUtils,
31
+ ApiUtils,
32
+ UploadUtils,
33
+ GetData,
34
+ PostData,
35
+ PutData,
36
+ DeleteData,
37
+
38
+ getExportData,
39
+
40
+
41
+ // Common Functions
42
+ ConvertBytesToArray,
43
+
44
+ SettingsUtil,
45
+ FormUtils
46
+ }
@@ -88,13 +88,9 @@ class BaseAPI {
88
88
  * Get the data from the table
89
89
  */
90
90
  get(config = {}) {
91
- const { url, headers, ...rest } = config;
92
- return ApiUtils.get({
93
- url: url || this.endpoint,
94
- headers,
95
- config: rest,
96
- ...rest,
97
- });
91
+ // Get the records from firebase
92
+
93
+ return ApiUtils.get({ url: config.url || this.endpoint, config });
98
94
  }
99
95
 
100
96
  getRelations(id) {
@@ -474,7 +474,7 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
474
474
  </Button>
475
475
  )}
476
476
 
477
- <Button
477
+ {/* <Button
478
478
  size="small"
479
479
  type="default"
480
480
  onClick={() => {
@@ -484,7 +484,7 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
484
484
  }}
485
485
  >
486
486
  <CopyOutlined />
487
- </Button>
487
+ </Button> */}
488
488
 
489
489
  <Popconfirm title="Are you sure?" onConfirm={() => deleteRecord(item)}>
490
490
  <Button danger size="small" type="default">
@@ -177,34 +177,23 @@ class MenusAPI extends Base {
177
177
  * @param {*} menu
178
178
  * @returns
179
179
  */
180
- getMenus = (config, dbPtr = null) => {
180
+ getMenus = (config) => {
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
-
189
187
  return this.get({
190
188
  url,
191
189
  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,
202
190
  }).then((result) => result);
203
191
  };
204
192
 
205
193
  // get core-menu list with submenu
206
- getCoreMenuLists = (role_id) => {
207
- const url = `menus/get-menus-by-role/${role_id}`;
194
+ getCoreMenuLists = () => {
195
+ const url = 'core-menus/core-menus?step=1&header_id=null';
196
+
208
197
  return this.get({
209
198
  url,
210
199
  }).then((result) => result);
@@ -155,15 +155,6 @@ class RolesAPI extends BaseAPI {
155
155
 
156
156
  /**
157
157
  * Cutsom Api for creating user
158
- getRole = () => {
159
- return ApiUtils.get({
160
- url: `core-roles/get-core-roles?active=Y`,
161
- });
162
- };
163
-
164
-
165
- /**
166
- * Cutsom Api for updating user
167
158
  *
168
159
  * @param {*} values
169
160
  * @returns