ui-soxo-bootstrap-core 2.4.25-dev.9 → 2.4.26

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 (29) hide show
  1. package/.github/workflows/npm-publish.yml +15 -37
  2. package/core/components/extra-info/extra-info-details.js +126 -109
  3. package/core/components/landing-api/landing-api.js +30 -22
  4. package/core/lib/Store.js +18 -20
  5. package/core/lib/components/index.js +1 -4
  6. package/core/lib/components/sidemenu/sidemenu.js +256 -153
  7. package/core/lib/components/sidemenu/sidemenu.scss +26 -39
  8. package/core/lib/elements/basic/rangepicker/rangepicker.js +29 -118
  9. package/core/lib/hooks/use-otp-timer.js +0 -19
  10. package/core/lib/pages/login/login.js +2 -2
  11. package/core/lib/pages/login/login.scss +5 -1
  12. package/core/models/dashboard/dashboard.js +0 -14
  13. package/core/models/menus/components/menu-lists/menu-lists.js +89 -126
  14. package/core/models/menus/components/menu-lists/menu-lists.scss +0 -9
  15. package/core/models/menus/menus.js +267 -247
  16. package/core/models/roles/components/role-add/role-add.js +227 -269
  17. package/core/models/roles/components/role-list/role-list.js +6 -8
  18. package/core/models/roles/roles.js +174 -182
  19. package/core/models/users/components/user-add/user-add.js +1 -69
  20. package/core/models/users/users.js +0 -57
  21. package/core/modules/index.js +13 -23
  22. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +1 -1
  23. package/package.json +2 -2
  24. package/core/models/staff/components/staff-add/staff-add.js +0 -352
  25. package/core/models/staff/components/staff-add/staff-add.scss +0 -0
  26. package/core/modules/steps/action-buttons.js +0 -79
  27. package/core/modules/steps/steps.js +0 -553
  28. package/core/modules/steps/steps.scss +0 -158
  29. package/core/modules/steps/timeline.js +0 -49
@@ -43,8 +43,8 @@
43
43
  width: 17%;
44
44
  background: #fff;
45
45
  // border-bottom: 1.5px solid #24aeb8;
46
- &.close {
47
- width: 6% !important;
46
+ &.close{
47
+ width:6% !important
48
48
  }
49
49
 
50
50
  .logo-wrapper {
@@ -70,7 +70,7 @@
70
70
 
71
71
  @media only screen and (max-width: 500px) {
72
72
  margin-right: 0px;
73
- // margin: 10px;
73
+ // margin: 10px;
74
74
  width: 150px;
75
75
  }
76
76
 
@@ -160,7 +160,7 @@
160
160
 
161
161
  /* Pseudo-element (as before) */
162
162
  .menu-collapsed::after {
163
- content: '';
163
+ content: "";
164
164
  position: absolute;
165
165
  top: -100%;
166
166
  left: 0;
@@ -175,26 +175,26 @@
175
175
  // background-color: #E0EBFF;
176
176
  // transform: scale(0.95); /* Apply scale effect on hover */
177
177
  }
178
- /* Style selected item */
179
- .ant-menu {
180
- background-color: transparent !important;
181
- }
182
- // .ant-menu-inline .ant-menu-item::after{
183
- // border-right: none;
184
- // }
185
- // .ant-menu-item-selected {
186
- // background-color: var(--selected-bg-color) !important;
187
- // color: var(--selected-text-color) !important;
188
- // border-radius: 12px;
189
- // // font-weight: 600;
190
- // // margin: 4px 8px;
191
- // }
192
-
193
- // /* Optional: remove hover effects */
194
- // .ant-menu-item:hover {
195
- // background-color: transparent !important;
196
- // color: transparent !important;
197
- // }
178
+ /* Style selected item */
179
+ .ant-menu{
180
+ background-color: transparent !important;
181
+ }
182
+ // .ant-menu-inline .ant-menu-item::after{
183
+ // border-right: none;
184
+ // }
185
+ // .ant-menu-item-selected {
186
+ // background-color: var(--selected-bg-color) !important;
187
+ // color: var(--selected-text-color) !important;
188
+ // border-radius: 12px;
189
+ // // font-weight: 600;
190
+ // // margin: 4px 8px;
191
+ // }
192
+
193
+ // /* Optional: remove hover effects */
194
+ // .ant-menu-item:hover {
195
+ // background-color: transparent !important;
196
+ // color: transparent !important;
197
+ // }
198
198
 
199
199
  /* River flow effect */
200
200
  .menu-collapsed:hover::after {
@@ -248,7 +248,9 @@
248
248
  padding: 0px;
249
249
  // width: 100% !important;
250
250
  // padding: 10px 16px;
251
+
251
252
  }
253
+
252
254
 
253
255
  .menu-item {
254
256
  width: 100% !important;
@@ -260,18 +262,3 @@
260
262
  }
261
263
  }
262
264
  }
263
-
264
- .ant-menu-item:hover {
265
- background-color: #e6f7ff !important;
266
- color: #1677ff !important;
267
- }
268
-
269
- /* Tooltip styling if needed */
270
- .ant-tooltip-inner {
271
- max-width: 200px;
272
- white-space: nowrap;
273
- overflow: hidden;
274
- text-overflow: ellipsis;
275
- background-color: #ffffff !important;
276
- color: #000000 !important;
277
- }
@@ -1,135 +1,46 @@
1
- /**
2
- * @file rangepicker.js
3
- * @description A reusable, enhanced Ant Design RangePicker component.
4
- *
5
- * Features:
6
- * - Manual selections require "Apply" button confirmation
7
- * - Preset ranges apply immediately without confirmation
8
- * - Optimized state management and event handling
9
- */
10
-
11
- import { useCallback, useRef, useState } from 'react';
12
- import { DatePicker, Space } from 'antd';
1
+ import { DatePicker } from 'antd';
13
2
  import moment from 'moment-timezone';
14
3
  import PropTypes from 'prop-types';
15
- import { useTranslation } from 'react-i18next';
16
- import Button from '../button/button';
17
4
  import './rangepicker.scss';
18
5
 
19
- /**
20
- * Enhanced RangePicker with Apply/Cancel controls for manual selections.
21
- * @param {object} props
22
- * @param {moment.Moment[]} props.value - Current applied date range
23
- * @param {function(moment.Moment[]): void} props.onChange - Callback when range is applied
24
- * @param {string} [props.format='DD/MM/YYYY'] - Date display format
25
- * @param {object} [props.ranges] - Preset date ranges
26
- * @param {boolean} [props.allowClear=false] - Whether to show clear button
27
- * @param {boolean} [props.inputReadOnly=true] - Whether input is read-only
28
- */
29
-
30
6
  const { RangePicker } = DatePicker;
31
7
 
32
- export default function RangePickerComponent({
33
- value,
34
- onChange,
35
- format = 'DD/MM/YYYY',
36
- ranges,
37
- allowClear = false,
38
- inputReadOnly = true,
39
- ...restProps
40
- }) {
41
- const { t } = useTranslation();
42
-
43
- // Temporary range during selection (before Apply is clicked)
44
- const [tempRange, setTempRange] = useState(null);
45
- const [isOpen, setIsOpen] = useState(false);
46
-
47
- // Ref to track if a selection just happened, to prevent the picker from closing.
48
- const selectionJustHappened = useRef(false);
8
+ export default function RangePickerComponent({ onChange, value, ranges }) {
9
+ // value is still: [moment, moment]
10
+ const startDate = value[0];
11
+ const endDate = value[1];
49
12
 
50
- /**
51
- * Handles any completed date selection (both manual and preset).
52
- * It updates the temporary range and sets a flag to keep the picker open.
53
- */
54
- const handleChange = useCallback((dates) => {
55
- setTempRange(dates || []);
56
- selectionJustHappened.current = true;
57
- }, []);
58
-
59
- /**
60
- * Handles picker open/close events.
61
- * Prevents closing after a selection, requiring user to click Apply/Cancel.
62
- */
63
- const handleOpenChange = useCallback((open) => {
64
- // If the picker is trying to close, check if it was due to a selection.
65
- if (!open && selectionJustHappened.current) {
66
- // It was a selection, so ignore the close request and reset the flag.
67
- selectionJustHappened.current = false;
13
+ function handleChange(dates) {
14
+ if (!dates) {
15
+ onChange(null);
68
16
  return;
69
17
  }
70
18
 
71
- // For all other cases (opening, or closing by clicking outside), proceed as normal.
72
- if (open) {
73
- // Reset temp range when opening for a fresh selection.
74
- setTempRange(null);
75
- }
76
- setIsOpen(open);
77
- }, []);
78
-
79
- /**
80
- * Applies the temporary range and closes picker
81
- */
82
- const handleApply = useCallback(() => {
83
- if (tempRange?.length === 2 && onChange) {
84
- onChange(tempRange);
85
- }
86
- selectionJustHappened.current = false; // Clear the flag
87
- setIsOpen(false);
88
- }, [tempRange, onChange]);
19
+ // Convert dayjs moment so your external code does NOT break
20
+ const converted = [moment(dates[0].toDate()), moment(dates[1].toDate())];
89
21
 
90
- /**
91
- * Cancels selection and closes picker
92
- */
93
- const handleCancel = useCallback(() => {
94
- selectionJustHappened.current = false; // Clear the flag
95
- setTempRange(null);
96
- setIsOpen(false);
97
- }, []);
22
+ onChange(converted);
23
+ }
98
24
 
99
- // Memoized preset ranges - use provided ranges or default set
100
- const defaultRanges = useRef({
101
- Today: [moment(), moment()],
102
- Yesterday: [moment().subtract(1, 'days').startOf('day'), moment().subtract(1, 'days').endOf('day')],
103
- 'This Week': [moment().startOf('week'), moment().endOf('week')],
104
- 'Last Week': [moment().subtract(1, 'week').startOf('week'), moment().subtract(1, 'week').endOf('week')],
105
- 'This Month': [moment().startOf('month'), moment().endOf('month')],
106
- 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
107
- }).current;
25
+ // Convert your old "ranges" object into AntD presets array
26
+ const presets = Object.entries(ranges).map(([label, range]) => ({
27
+ label,
28
+ value: range,
29
+ }));
108
30
 
109
31
  return (
110
- <RangePicker
111
- allowClear={allowClear}
112
- inputReadOnly={inputReadOnly}
113
- format={format}
114
- value={tempRange || value}
115
- open={isOpen}
116
- onOpenChange={handleOpenChange}
117
- onChange={handleChange}
118
- ranges={ranges !== undefined ? ranges : defaultRanges}
119
- {...restProps}
120
- renderExtraFooter={() => (
121
- <div style={{ width: '100%', display: 'flex', justifyContent: 'flex-end', order: 1 }}>
122
- <Space>
123
- <Button size="small" onClick={handleCancel}>
124
- {t('Cancel')}
125
- </Button>
126
- <Button type="primary" size="small" onClick={handleApply}>
127
- {t('Apply')}
128
- </Button>
129
- </Space>
130
- </div>
131
- )}
132
- />
32
+ <div className="rangepicker">
33
+ <RangePicker
34
+ allowClear={false}
35
+ inputReadOnly
36
+ format="DD/MM/YYYY"
37
+ // moment → allowed
38
+ value={[startDate, endDate]}
39
+ onChange={handleChange}
40
+ presets={presets}
41
+ ranges={ranges}
42
+ />
43
+ </div>
133
44
  );
134
45
  }
135
46
 
@@ -16,25 +16,6 @@ import { useState, useEffect, useRef } from 'react';
16
16
  * @returns {(seconds: number) => void} API.start - Start timer with seconds.
17
17
  * @returns {(expirytime: string) => void} API.startFromExpiry - Start timer using expiry string (e.g. "2025-09-04T12:13:09.000Z").
18
18
  *
19
- * @example
20
- * const { remaining, expired, formatted, start, startFromExpiry } = useOtpTimer();
21
- *
22
- * // Start with 30 seconds
23
- * useEffect(() => {
24
- * start(30);
25
- * }, []);
26
- *
27
- * // OR start from backend expiry timestamp
28
- * useEffect(() => {
29
- * startFromExpiry("2025-09-04T12:13:09.000Z");
30
- * }, []);
31
- *
32
- * return (
33
- * <div>
34
- * <p>Time left: {formatted}</p>
35
- * {expired && <p>OTP expired!</p>}
36
- * </div>
37
- * );
38
19
  */
39
20
 
40
21
  // helper to format time
@@ -610,10 +610,10 @@ function LoginPhone({ history, appSettings }) {
610
610
  <Text type="primary">Select Preferred OTP Verification Method</Text>
611
611
  <div className="otp-method-group">
612
612
  <Radio checked={communicationMode === 'email'} onChange={() => setCommunicationMode('email')}>
613
- Email <MailOutlined style={{ marginLeft: 6 }} />
613
+ Email <MailOutlined className="otp-icon" style={{ marginLeft: 6 }} />
614
614
  </Radio>
615
615
  <Radio checked={communicationMode === 'mobile'} onChange={() => setCommunicationMode('mobile')}>
616
- SMS <MessageOutlined style={{ marginLeft: 6 }} />
616
+ SMS <MessageOutlined className="otp-icon" style={{ marginLeft: 6 }} />
617
617
  </Radio>
618
618
  </div>
619
619
  {modeError && <p className="otp-mode-error">Please select a communication mode.</p>}
@@ -352,10 +352,14 @@ body {
352
352
  gap: 30px;
353
353
  font-size: 12px;
354
354
  }
355
+ .otp-icon {
356
+ position: relative;
357
+ top: 2px;
358
+ }
355
359
 
356
360
  .ant-radio-wrapper {
357
361
  display: flex;
358
- align-items: center;
362
+ // align-items: center;
359
363
  gap: 6px;
360
364
 
361
365
  svg {
@@ -81,20 +81,6 @@ class Dashboard extends Base {
81
81
  ];
82
82
  }
83
83
 
84
- loadProcess(id) {
85
- return ApiUtils.get({
86
- url: `process/${id}`,
87
- });
88
- }
89
-
90
- processLog(formBody) {
91
- return ApiUtils.post({
92
- url: `process/process-log`,
93
- formBody,
94
- });
95
- }
96
-
97
-
98
84
  /**
99
85
  * Function to load dashboards based on user information
100
86
  * @param {*} user