groovinads-ui 1.2.68 → 1.2.70
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/README.md +134 -66
- package/dist/index.es.js +3 -3
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/src/components/Dropdowns/DropdownMultiSelect.jsx +74 -10
- package/src/components/Inputs/Input.jsx +1 -0
- package/src/components/Inputs/InputEmail.jsx +0 -1
- package/src/components/Navigation/Dropdowns/DeckDropdown.jsx +129 -129
- package/src/components/Navigation/Navbar.jsx +4 -0
- package/src/components/Navigation/Sidebar.jsx +48 -22
- package/src/stories/DropdownMultiSelect.stories.jsx +22 -25
- package/src/stories/Navbar.stories.jsx +12 -9
- package/src/stories/Sidebar.stories.jsx +31 -6
- package/version.js +8 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "groovinads-ui",
|
|
3
3
|
"description": "Groovinads UI is a React component library designed exclusively for Groovinads applications. It provides ready-to-use UI elements styled according to Groovinads design guidelines to facilitate rapid development.",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.70",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
7
7
|
"sass",
|
|
@@ -18,6 +18,7 @@ const DropdownMultiSelect = ({
|
|
|
18
18
|
inputLabel = '',
|
|
19
19
|
object = false,
|
|
20
20
|
nameKey,
|
|
21
|
+
customKey,
|
|
21
22
|
idKey,
|
|
22
23
|
searchLabel = 'Search',
|
|
23
24
|
onToggle,
|
|
@@ -33,14 +34,22 @@ const DropdownMultiSelect = ({
|
|
|
33
34
|
buttonVariant = 'input',
|
|
34
35
|
nowrap = false,
|
|
35
36
|
hasId = true,
|
|
37
|
+
validate = false,
|
|
38
|
+
requiredText = 'required',
|
|
39
|
+
errorRequired = false,
|
|
40
|
+
setErrorRequiered,
|
|
36
41
|
}) => {
|
|
42
|
+
// STATES
|
|
37
43
|
const [query, setQuery] = useState('');
|
|
38
44
|
const [innerShow, setInnerShow] = useState(!!show);
|
|
39
45
|
|
|
40
46
|
const dropdownRef = useRef(null);
|
|
47
|
+
const toggleRef = useRef(null);
|
|
48
|
+
const menuRef = useRef(null);
|
|
41
49
|
|
|
42
50
|
const { highlightText } = useTextFormatter();
|
|
43
51
|
|
|
52
|
+
// FUNCTIONS
|
|
44
53
|
const handleCheckbox = (status, value) => {
|
|
45
54
|
const i = values.findIndex(
|
|
46
55
|
(item) =>
|
|
@@ -68,16 +77,12 @@ const DropdownMultiSelect = ({
|
|
|
68
77
|
const valuesFromSearch = () =>
|
|
69
78
|
values.filter(
|
|
70
79
|
(item) =>
|
|
71
|
-
(object ? `${item[idKey]} ${item[nameKey]}` : item)
|
|
80
|
+
(object ? `${item[idKey]} ${item[nameKey]} ${item[customKey]}` : item)
|
|
72
81
|
.toLowerCase()
|
|
73
82
|
.includes(query.toLowerCase()) &&
|
|
74
83
|
(showStatus ? parseInt(item.status) === parseInt(showStatus) : true),
|
|
75
84
|
);
|
|
76
85
|
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
setInnerShow(show);
|
|
79
|
-
}, [show]);
|
|
80
|
-
|
|
81
86
|
const handleClickOutside = useCallback((event) => {
|
|
82
87
|
if (
|
|
83
88
|
dropdownRef?.current &&
|
|
@@ -89,6 +94,19 @@ const DropdownMultiSelect = ({
|
|
|
89
94
|
}
|
|
90
95
|
}, []);
|
|
91
96
|
|
|
97
|
+
// VALIDATION REQUIRED
|
|
98
|
+
const validateRequired = () => {
|
|
99
|
+
if (!valuesSelected.length) {
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
setErrorRequiered((prev) => !prev);
|
|
102
|
+
}, 2000);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
setInnerShow(show);
|
|
108
|
+
}, [show]);
|
|
109
|
+
|
|
92
110
|
useEffect(() => {
|
|
93
111
|
document.addEventListener('click', handleClickOutside);
|
|
94
112
|
return () => {
|
|
@@ -96,6 +114,36 @@ const DropdownMultiSelect = ({
|
|
|
96
114
|
};
|
|
97
115
|
}, []);
|
|
98
116
|
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
if (validate && errorRequired) validateRequired();
|
|
119
|
+
}, [validate, errorRequired]);
|
|
120
|
+
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (overflow && menuRef.current && toggleRef.current) {
|
|
123
|
+
menuRef.current.style.width = `${toggleRef.current.offsetWidth}px`;
|
|
124
|
+
}
|
|
125
|
+
}, [innerShow, overflow]);
|
|
126
|
+
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
function updateMenuWidth() {
|
|
129
|
+
if (overflow && menuRef.current && toggleRef.current) {
|
|
130
|
+
const width = toggleRef.current.offsetWidth;
|
|
131
|
+
menuRef.current.style.width = `${width}px`;
|
|
132
|
+
menuRef.current.style.minWidth = `${width}px`;
|
|
133
|
+
menuRef.current.style.maxWidth = `${width}px`;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (innerShow) {
|
|
138
|
+
updateMenuWidth();
|
|
139
|
+
window.addEventListener('resize', updateMenuWidth);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return () => {
|
|
143
|
+
window.removeEventListener('resize', updateMenuWidth);
|
|
144
|
+
};
|
|
145
|
+
}, [innerShow, overflow]);
|
|
146
|
+
|
|
99
147
|
return (
|
|
100
148
|
<Dropdown
|
|
101
149
|
className={className}
|
|
@@ -104,14 +152,16 @@ const DropdownMultiSelect = ({
|
|
|
104
152
|
ref={dropdownRef}
|
|
105
153
|
onToggle={onToggle}
|
|
106
154
|
drop={drop}
|
|
155
|
+
data-error={requiredText}
|
|
107
156
|
>
|
|
108
157
|
<Dropdown.Toggle
|
|
109
158
|
as={'div'}
|
|
110
|
-
|
|
159
|
+
ref={toggleRef}
|
|
160
|
+
className={`btn btn-${buttonVariant} ${nowrap ? 'nowrap' : ''}${errorRequired && valuesSelected.length === 0 ? 'not-validated' : ''}`}
|
|
111
161
|
onClick={(e) => {
|
|
112
162
|
e.stopPropagation(); // Detiene la propagación del clic
|
|
113
163
|
setInnerShow((prevShow) => !prevShow); // Alterna el estado interno del dropdown
|
|
114
|
-
setShow((prevShow) => !prevShow); // Alterna el estado del dropdown en el estado externo también
|
|
164
|
+
// setShow((prevShow) => !prevShow); // Alterna el estado del dropdown en el estado externo también
|
|
115
165
|
}}
|
|
116
166
|
>
|
|
117
167
|
{valuesSelected.length > 0 && buttonVariant === 'input' && (
|
|
@@ -127,8 +177,14 @@ const DropdownMultiSelect = ({
|
|
|
127
177
|
}}
|
|
128
178
|
key={'Dropdown.PillComponent' + index}
|
|
129
179
|
>
|
|
130
|
-
{
|
|
131
|
-
|
|
180
|
+
{customKey
|
|
181
|
+
? `${value[nameKey]} - ${value[customKey]}`
|
|
182
|
+
: idInPill
|
|
183
|
+
? `#${value[idKey]}`
|
|
184
|
+
: value[nameKey] || value}
|
|
185
|
+
|
|
186
|
+
{/* {idInPill ? `#${value[idKey]} - ` : ''}
|
|
187
|
+
<span>{object ? value[nameKey] : value}</span> */}
|
|
132
188
|
</PillComponent>
|
|
133
189
|
);
|
|
134
190
|
})}
|
|
@@ -145,6 +201,7 @@ const DropdownMultiSelect = ({
|
|
|
145
201
|
|
|
146
202
|
<Dropdown.Menu
|
|
147
203
|
className='w-100'
|
|
204
|
+
ref={menuRef}
|
|
148
205
|
popperConfig={
|
|
149
206
|
overflow
|
|
150
207
|
? {
|
|
@@ -188,7 +245,9 @@ const DropdownMultiSelect = ({
|
|
|
188
245
|
>
|
|
189
246
|
{highlightText(
|
|
190
247
|
object
|
|
191
|
-
?
|
|
248
|
+
? customKey
|
|
249
|
+
? `${value[nameKey]} - ${value[customKey]}`
|
|
250
|
+
: `${hasId ? `#${value[idKey]} - ` : ''}${value[nameKey]}`
|
|
192
251
|
: value[nameKey] || value,
|
|
193
252
|
query,
|
|
194
253
|
)}
|
|
@@ -222,6 +281,7 @@ DropdownMultiSelect.propTypes = {
|
|
|
222
281
|
setShow: PropTypes.func,
|
|
223
282
|
object: PropTypes.bool,
|
|
224
283
|
nameKey: PropTypes.string,
|
|
284
|
+
customKey: PropTypes.string,
|
|
225
285
|
idKey: PropTypes.string,
|
|
226
286
|
idInPill: PropTypes.bool,
|
|
227
287
|
showStatus: PropTypes.string,
|
|
@@ -235,6 +295,10 @@ DropdownMultiSelect.propTypes = {
|
|
|
235
295
|
]),
|
|
236
296
|
nowrap: PropTypes.bool,
|
|
237
297
|
hasId: PropTypes.bool,
|
|
298
|
+
requiredText: PropTypes.string,
|
|
299
|
+
validate: PropTypes.bool,
|
|
300
|
+
errorRequired: PropTypes.bool,
|
|
301
|
+
setErrorRequiered: PropTypes.func,
|
|
238
302
|
};
|
|
239
303
|
|
|
240
304
|
export default DropdownMultiSelect;
|
|
@@ -149,6 +149,7 @@ Input.propTypes = {
|
|
|
149
149
|
autoFocus: PropTypes.bool,
|
|
150
150
|
min: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
151
151
|
max: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
152
|
+
maxLength: PropTypes.number,
|
|
152
153
|
};
|
|
153
154
|
|
|
154
155
|
export default Input;
|
|
@@ -22,7 +22,6 @@ const DeckDropdown = () => {
|
|
|
22
22
|
element.app_icon_sm = element.application_icon;
|
|
23
23
|
element.app_name = element.application_name;
|
|
24
24
|
});
|
|
25
|
-
|
|
26
25
|
setApplications(resp);
|
|
27
26
|
} catch (error) {
|
|
28
27
|
console.error('fetchData error', error);
|
|
@@ -52,10 +51,8 @@ const DeckDropdown = () => {
|
|
|
52
51
|
|
|
53
52
|
const favApp = async (identification) => {
|
|
54
53
|
try {
|
|
55
|
-
|
|
56
|
-
//console.log('if ---->');
|
|
54
|
+
await ComponentsService.favApplication(identification);
|
|
57
55
|
setApplications((prev) => {
|
|
58
|
-
//console.log('setApplications ---->');
|
|
59
56
|
const index = prev.findIndex(
|
|
60
57
|
(element) => element?.id_application === identification,
|
|
61
58
|
);
|
|
@@ -69,141 +66,144 @@ const DeckDropdown = () => {
|
|
|
69
66
|
|
|
70
67
|
const unfavApp = async (identification) => {
|
|
71
68
|
try {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
});
|
|
82
|
-
}
|
|
69
|
+
await ComponentsService.unfavApplication(identification);
|
|
70
|
+
|
|
71
|
+
setApplications((prev) => {
|
|
72
|
+
const index = prev.findIndex(
|
|
73
|
+
(element) => element?.id_application === identification,
|
|
74
|
+
);
|
|
75
|
+
prev[index].favorite = false;
|
|
76
|
+
return [...prev];
|
|
77
|
+
});
|
|
83
78
|
} catch (error) {
|
|
84
79
|
console.error('unfavApp error', error);
|
|
85
80
|
}
|
|
86
81
|
};
|
|
87
82
|
|
|
88
83
|
useEffect(() => {
|
|
89
|
-
if (applications?.length
|
|
84
|
+
if (!applications?.length) fetchData();
|
|
90
85
|
}, []);
|
|
91
86
|
|
|
92
87
|
return (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
<Dropdown.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
{applications
|
|
123
|
-
.filter((item) => item.favorite)
|
|
124
|
-
.map((element, i) => {
|
|
125
|
-
return (
|
|
126
|
-
<Dropdown.Item key={i} as={'li'}>
|
|
127
|
-
<div
|
|
128
|
-
onClick={() => {
|
|
129
|
-
window.location.replace(
|
|
130
|
-
linkToApp(
|
|
131
|
-
element.application_url,
|
|
132
|
-
element.application_name,
|
|
133
|
-
),
|
|
134
|
-
);
|
|
135
|
-
}}
|
|
136
|
-
className='link-app'
|
|
137
|
-
>
|
|
138
|
-
<span className='icon-app'>
|
|
139
|
-
<Icon
|
|
140
|
-
style={'solid'}
|
|
141
|
-
iconName={element.app_icon_sm}
|
|
142
|
-
scale={1}
|
|
143
|
-
/>
|
|
144
|
-
</span>
|
|
145
|
-
|
|
146
|
-
<span>{element.app_name}</span>
|
|
147
|
-
</div>
|
|
148
|
-
<button
|
|
149
|
-
className='deck-fav'
|
|
150
|
-
onClick={(e) => {
|
|
151
|
-
e.stopPropagation();
|
|
152
|
-
unfavApp(element.id_application);
|
|
153
|
-
}}
|
|
154
|
-
>
|
|
155
|
-
<Icon style={'solid'} iconName={'star'} scale={1} />
|
|
156
|
-
</button>
|
|
88
|
+
<>
|
|
89
|
+
{applications.length ? (
|
|
90
|
+
<Dropdown>
|
|
91
|
+
<Dropdown.Toggle className='btn btn-terciary'>
|
|
92
|
+
<svg
|
|
93
|
+
id='deckApps'
|
|
94
|
+
xmlns='http://www.w3.org/2000/svg'
|
|
95
|
+
className='icon'
|
|
96
|
+
viewBox='0 0 16 16'
|
|
97
|
+
>
|
|
98
|
+
<g>
|
|
99
|
+
<rect x='1' y='1' width='4' height='4' rx='1.25' ry='1.25' />
|
|
100
|
+
<rect x='1' y='6' width='4' height='4' rx='1.25' ry='1.25' />
|
|
101
|
+
<rect x='1' y='11' width='4' height='4' rx='1.25' ry='1.25' />
|
|
102
|
+
<rect x='6' y='1' width='4' height='4' rx='1.25' ry='1.25' />
|
|
103
|
+
<rect x='6' y='6' width='4' height='4' rx='1.25' ry='1.25' />
|
|
104
|
+
<rect x='6' y='11' width='4' height='4' rx='1.25' ry='1.25' />
|
|
105
|
+
<rect x='11' y='1' width='4' height='4' rx='1.25' ry='1.25' />
|
|
106
|
+
<rect x='11' y='6' width='4' height='4' rx='1.25' ry='1.25' />
|
|
107
|
+
<rect x='11' y='11' width='4' height='4' rx='1.25' ry='1.25' />
|
|
108
|
+
</g>
|
|
109
|
+
</svg>
|
|
110
|
+
</Dropdown.Toggle>
|
|
111
|
+
|
|
112
|
+
<Dropdown.Menu as={'ul'}>
|
|
113
|
+
{applications?.filter((item) => item.favorite).length > 0 && (
|
|
114
|
+
<Dropdown.Item as={'li'}>
|
|
115
|
+
<h4 className='dropdown-header'>Favorites</h4>
|
|
157
116
|
</Dropdown.Item>
|
|
158
|
-
)
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
117
|
+
)}
|
|
118
|
+
|
|
119
|
+
{applications
|
|
120
|
+
.filter((item) => item.favorite)
|
|
121
|
+
.map((element, i) => {
|
|
122
|
+
return (
|
|
123
|
+
<Dropdown.Item key={i} as={'li'}>
|
|
124
|
+
<div
|
|
125
|
+
onClick={() => {
|
|
126
|
+
window.location.replace(
|
|
127
|
+
linkToApp(
|
|
128
|
+
element.application_url,
|
|
129
|
+
element.application_name,
|
|
130
|
+
),
|
|
131
|
+
);
|
|
132
|
+
}}
|
|
133
|
+
className='link-app'
|
|
134
|
+
>
|
|
135
|
+
<span className='icon-app'>
|
|
136
|
+
<Icon
|
|
137
|
+
style={'solid'}
|
|
138
|
+
iconName={element.app_icon_sm}
|
|
139
|
+
scale={1}
|
|
140
|
+
/>
|
|
141
|
+
</span>
|
|
142
|
+
|
|
143
|
+
<span>{element.app_name}</span>
|
|
144
|
+
</div>
|
|
145
|
+
<button
|
|
146
|
+
className='deck-fav'
|
|
147
|
+
onClick={(e) => {
|
|
148
|
+
e.stopPropagation();
|
|
149
|
+
unfavApp(element.id_application);
|
|
150
|
+
}}
|
|
151
|
+
>
|
|
152
|
+
<Icon style={'solid'} iconName={'star'} scale={1} />
|
|
153
|
+
</button>
|
|
154
|
+
</Dropdown.Item>
|
|
155
|
+
);
|
|
156
|
+
})}
|
|
157
|
+
|
|
158
|
+
{applications?.filter((item) => item.favorite).length > 0 &&
|
|
159
|
+
applications?.filter((item) => !item.favorite).length > 0 && (
|
|
160
|
+
<Dropdown.Divider as={'li'} />
|
|
161
|
+
)}
|
|
162
|
+
|
|
163
|
+
{applications
|
|
164
|
+
.filter((item) => !item.favorite)
|
|
165
|
+
.map((element, i) => {
|
|
166
|
+
return (
|
|
167
|
+
<Dropdown.Item key={i} as={'li'}>
|
|
168
|
+
<div
|
|
169
|
+
onClick={() => {
|
|
170
|
+
window.location.replace(
|
|
171
|
+
linkToApp(
|
|
172
|
+
element.application_url,
|
|
173
|
+
element.application_name,
|
|
174
|
+
),
|
|
175
|
+
);
|
|
176
|
+
}}
|
|
177
|
+
className='link-app'
|
|
178
|
+
>
|
|
179
|
+
<span className='icon-app'>
|
|
180
|
+
<Icon
|
|
181
|
+
style={'solid'}
|
|
182
|
+
iconName={element.app_icon_sm}
|
|
183
|
+
scale={1}
|
|
184
|
+
/>
|
|
185
|
+
</span>
|
|
186
|
+
|
|
187
|
+
<span>{element.app_name}</span>
|
|
188
|
+
</div>
|
|
189
|
+
<button
|
|
190
|
+
className='deck-fav'
|
|
191
|
+
onClick={(e) => {
|
|
192
|
+
e.stopPropagation();
|
|
193
|
+
favApp(element.id_application);
|
|
194
|
+
}}
|
|
195
|
+
>
|
|
196
|
+
<Icon style={'regular'} iconName={'star'} scale={1} />
|
|
197
|
+
</button>
|
|
198
|
+
</Dropdown.Item>
|
|
199
|
+
);
|
|
200
|
+
})}
|
|
201
|
+
</Dropdown.Menu>
|
|
202
|
+
</Dropdown>
|
|
203
|
+
) : (
|
|
204
|
+
<></>
|
|
205
|
+
)}
|
|
206
|
+
</>
|
|
207
207
|
);
|
|
208
208
|
};
|
|
209
209
|
|
|
@@ -18,7 +18,10 @@ const Navbar = ({
|
|
|
18
18
|
children,
|
|
19
19
|
show,
|
|
20
20
|
setShow,
|
|
21
|
+
applications,
|
|
22
|
+
setApplications,
|
|
21
23
|
}) => {
|
|
24
|
+
|
|
22
25
|
return (
|
|
23
26
|
<div id='ga-header' className='header fixed-top shadow-2'>
|
|
24
27
|
<Container fluid className='navbar'>
|
|
@@ -50,6 +53,7 @@ const Navbar = ({
|
|
|
50
53
|
</svg>
|
|
51
54
|
</Button>
|
|
52
55
|
{/* Dropdown apps */}
|
|
56
|
+
{/* TODO: conditional */}
|
|
53
57
|
{showDeckMenu && <DeckDropdown />}
|
|
54
58
|
|
|
55
59
|
<img
|
|
@@ -25,7 +25,9 @@ const Sidebar = ({
|
|
|
25
25
|
inModal = false,
|
|
26
26
|
customUrl,
|
|
27
27
|
}) => {
|
|
28
|
-
const isMobile = inModal
|
|
28
|
+
const isMobile = inModal
|
|
29
|
+
? true
|
|
30
|
+
: useMediaQuery({ query: '(max-width: 992px)' });
|
|
29
31
|
|
|
30
32
|
const url = customUrl !== undefined ? customUrl : window.location.pathname; // to get current url
|
|
31
33
|
|
|
@@ -55,7 +57,8 @@ const Sidebar = ({
|
|
|
55
57
|
|
|
56
58
|
useEffect(() => {
|
|
57
59
|
if (isMobile && setShow && !inModal) setShow(innerShow);
|
|
58
|
-
if (!inModal)
|
|
60
|
+
if (!inModal)
|
|
61
|
+
setInnerShow(isMobile ? false : firstOpen.current ? defaultOpened : show);
|
|
59
62
|
firstOpen.current = false;
|
|
60
63
|
}, []);
|
|
61
64
|
|
|
@@ -80,13 +83,14 @@ const Sidebar = ({
|
|
|
80
83
|
<div className='scroll'>
|
|
81
84
|
{customLinks.map((section, i) => (
|
|
82
85
|
<div className='sidebar-section' key={`sectionIndex${i}`}>
|
|
83
|
-
{section.title ? <h4>{section.title}</h4> : <></>
|
|
86
|
+
{section.title ? <h4>{section.title}</h4> : <></>}
|
|
84
87
|
|
|
85
88
|
{/* PROPS LINKS */}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
|
|
90
|
+
<ul className='nav'>
|
|
91
|
+
{(section.backData ? sidebarLinks : section.links || []).map(
|
|
92
|
+
(linkSection, y) => (
|
|
93
|
+
<li className='nav-item' key={`linksSections${y}`}>
|
|
90
94
|
{/* CHILDREN - If has children, the collapse is expanded */}
|
|
91
95
|
{linkSection.children && linkSection.children.length ? (
|
|
92
96
|
<>
|
|
@@ -121,20 +125,41 @@ const Sidebar = ({
|
|
|
121
125
|
</Collapse>
|
|
122
126
|
</>
|
|
123
127
|
) : (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
128
|
+
<>
|
|
129
|
+
<button
|
|
130
|
+
className={`nav-link ${
|
|
131
|
+
url === linkSection.url ? 'active' : ''
|
|
132
|
+
}`}
|
|
133
|
+
onClick={() => onNavigate(linkSection.url)}
|
|
134
|
+
>
|
|
135
|
+
<Icon iconName={linkSection.icon} />
|
|
136
|
+
|
|
137
|
+
{linkSection.pendingType ? (
|
|
138
|
+
<div className='link-wrapper'>
|
|
139
|
+
{linkSection.name}
|
|
140
|
+
{linkSection.pendingLength > 0 &&
|
|
141
|
+
(linkSection.pendingType === 'warning' ? (
|
|
142
|
+
<Icon
|
|
143
|
+
iconName='triangle-exclamation'
|
|
144
|
+
className='warning-icon'
|
|
145
|
+
style='duotone'
|
|
146
|
+
/>
|
|
147
|
+
) : linkSection.pendingType === 'badge' ? (
|
|
148
|
+
<span className='badge'>
|
|
149
|
+
{linkSection.pendingLength}
|
|
150
|
+
</span>
|
|
151
|
+
) : null)}
|
|
152
|
+
</div>
|
|
153
|
+
) : (
|
|
154
|
+
linkSection.name
|
|
155
|
+
)}
|
|
156
|
+
</button>
|
|
157
|
+
</>
|
|
133
158
|
)}
|
|
134
159
|
</li>
|
|
135
|
-
|
|
136
|
-
)
|
|
137
|
-
|
|
160
|
+
),
|
|
161
|
+
)}
|
|
162
|
+
</ul>
|
|
138
163
|
</div>
|
|
139
164
|
))}
|
|
140
165
|
</div>
|
|
@@ -160,13 +185,14 @@ Sidebar.propTypes = {
|
|
|
160
185
|
setShow: PropTypes.func, // Add setShow prop for controlling visibility
|
|
161
186
|
onNavigate: PropTypes.func.isRequired, // Nueva prop para manejar la navegación
|
|
162
187
|
selectedClient: PropTypes.object,
|
|
163
|
-
showClients:PropTypes.oneOf([true, false, 'single']),
|
|
188
|
+
showClients: PropTypes.oneOf([true, false, 'single']),
|
|
164
189
|
setGroovinProfile: PropTypes.func,
|
|
165
190
|
inModal: PropTypes.bool,
|
|
166
191
|
customUrl: PropTypes.oneOfType([
|
|
167
192
|
PropTypes.string,
|
|
168
|
-
PropTypes.oneOf([undefined])
|
|
169
|
-
|
|
193
|
+
PropTypes.oneOf([undefined]),
|
|
194
|
+
]),
|
|
195
|
+
pendingType: PropTypes.oneOf(['warning', 'badge']),
|
|
170
196
|
};
|
|
171
197
|
|
|
172
198
|
export default Sidebar;
|