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.
- package/.github/workflows/npm-publish.yml +15 -37
- package/core/components/extra-info/extra-info-details.js +126 -109
- package/core/components/landing-api/landing-api.js +30 -22
- package/core/lib/Store.js +18 -20
- package/core/lib/components/index.js +1 -4
- package/core/lib/components/sidemenu/sidemenu.js +256 -153
- package/core/lib/components/sidemenu/sidemenu.scss +26 -39
- package/core/lib/elements/basic/rangepicker/rangepicker.js +29 -118
- package/core/lib/hooks/use-otp-timer.js +0 -19
- package/core/lib/pages/login/login.js +2 -2
- package/core/lib/pages/login/login.scss +5 -1
- package/core/models/dashboard/dashboard.js +0 -14
- package/core/models/menus/components/menu-lists/menu-lists.js +89 -126
- package/core/models/menus/components/menu-lists/menu-lists.scss +0 -9
- package/core/models/menus/menus.js +267 -247
- package/core/models/roles/components/role-add/role-add.js +227 -269
- package/core/models/roles/components/role-list/role-list.js +6 -8
- package/core/models/roles/roles.js +174 -182
- package/core/models/users/components/user-add/user-add.js +1 -69
- package/core/models/users/users.js +0 -57
- package/core/modules/index.js +13 -23
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +1 -1
- package/package.json +2 -2
- package/core/models/staff/components/staff-add/staff-add.js +0 -352
- package/core/models/staff/components/staff-add/staff-add.scss +0 -0
- package/core/modules/steps/action-buttons.js +0 -79
- package/core/modules/steps/steps.js +0 -553
- package/core/modules/steps/steps.scss +0 -158
- 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:
|
|
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
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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
|
-
|
|
52
|
-
|
|
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
|
-
//
|
|
72
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|