groovinads-ui 1.2.68 → 1.2.69
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 +29 -20
- package/dist/index.es.js +2 -2
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/src/components/Dropdowns/DropdownMultiSelect.jsx +37 -13
- 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/stories/DropdownMultiSelect.stories.jsx +7 -0
- package/src/stories/Navbar.stories.jsx +12 -9
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.69",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
7
7
|
"sass",
|
|
@@ -33,7 +33,12 @@ const DropdownMultiSelect = ({
|
|
|
33
33
|
buttonVariant = 'input',
|
|
34
34
|
nowrap = false,
|
|
35
35
|
hasId = true,
|
|
36
|
+
validate = false,
|
|
37
|
+
requiredText = 'required',
|
|
38
|
+
errorRequired = false,
|
|
39
|
+
setErrorRequiered,
|
|
36
40
|
}) => {
|
|
41
|
+
// STATES
|
|
37
42
|
const [query, setQuery] = useState('');
|
|
38
43
|
const [innerShow, setInnerShow] = useState(!!show);
|
|
39
44
|
|
|
@@ -41,6 +46,7 @@ const DropdownMultiSelect = ({
|
|
|
41
46
|
|
|
42
47
|
const { highlightText } = useTextFormatter();
|
|
43
48
|
|
|
49
|
+
// FUNCTIONS
|
|
44
50
|
const handleCheckbox = (status, value) => {
|
|
45
51
|
const i = values.findIndex(
|
|
46
52
|
(item) =>
|
|
@@ -67,17 +73,14 @@ const DropdownMultiSelect = ({
|
|
|
67
73
|
|
|
68
74
|
const valuesFromSearch = () =>
|
|
69
75
|
values.filter(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
setInnerShow(show);
|
|
79
|
-
}, [show]);
|
|
76
|
+
(item) =>
|
|
77
|
+
(object ? `${item[idKey]} ${item[nameKey]}` : item)
|
|
78
|
+
.toLowerCase()
|
|
79
|
+
.includes(query.toLowerCase()) &&
|
|
80
|
+
(showStatus ? parseInt(item.status) === parseInt(showStatus) : true),
|
|
81
|
+
);
|
|
80
82
|
|
|
83
|
+
|
|
81
84
|
const handleClickOutside = useCallback((event) => {
|
|
82
85
|
if (
|
|
83
86
|
dropdownRef?.current &&
|
|
@@ -88,7 +91,20 @@ const DropdownMultiSelect = ({
|
|
|
88
91
|
setShow(false);
|
|
89
92
|
}
|
|
90
93
|
}, []);
|
|
91
|
-
|
|
94
|
+
|
|
95
|
+
// VALIDATION REQUIRED
|
|
96
|
+
const validateRequired = () => {
|
|
97
|
+
if (!valuesSelected.length) {
|
|
98
|
+
setTimeout(() => {
|
|
99
|
+
setErrorRequiered((prev) => !prev);
|
|
100
|
+
}, 2000);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
setInnerShow(show);
|
|
106
|
+
}, [show]);
|
|
107
|
+
|
|
92
108
|
useEffect(() => {
|
|
93
109
|
document.addEventListener('click', handleClickOutside);
|
|
94
110
|
return () => {
|
|
@@ -96,6 +112,9 @@ const DropdownMultiSelect = ({
|
|
|
96
112
|
};
|
|
97
113
|
}, []);
|
|
98
114
|
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
if (validate && errorRequired) validateRequired();
|
|
117
|
+
}, [validate, errorRequired]);
|
|
99
118
|
return (
|
|
100
119
|
<Dropdown
|
|
101
120
|
className={className}
|
|
@@ -104,14 +123,15 @@ const DropdownMultiSelect = ({
|
|
|
104
123
|
ref={dropdownRef}
|
|
105
124
|
onToggle={onToggle}
|
|
106
125
|
drop={drop}
|
|
126
|
+
data-error={requiredText}
|
|
107
127
|
>
|
|
108
128
|
<Dropdown.Toggle
|
|
109
129
|
as={'div'}
|
|
110
|
-
className={`btn btn-${buttonVariant} w-100 ${nowrap ? 'nowrap' : ''}`}
|
|
130
|
+
className={`btn btn-${buttonVariant} w-100 ${nowrap ? 'nowrap' : ''}${errorRequired && valuesSelected.length === 0 ? 'not-validated' : ''}`}
|
|
111
131
|
onClick={(e) => {
|
|
112
132
|
e.stopPropagation(); // Detiene la propagación del clic
|
|
113
133
|
setInnerShow((prevShow) => !prevShow); // Alterna el estado interno del dropdown
|
|
114
|
-
setShow((prevShow) => !prevShow); // Alterna el estado del dropdown en el estado externo también
|
|
134
|
+
// setShow((prevShow) => !prevShow); // Alterna el estado del dropdown en el estado externo también
|
|
115
135
|
}}
|
|
116
136
|
>
|
|
117
137
|
{valuesSelected.length > 0 && buttonVariant === 'input' && (
|
|
@@ -235,6 +255,10 @@ DropdownMultiSelect.propTypes = {
|
|
|
235
255
|
]),
|
|
236
256
|
nowrap: PropTypes.bool,
|
|
237
257
|
hasId: PropTypes.bool,
|
|
258
|
+
requiredText: PropTypes.string,
|
|
259
|
+
validate: PropTypes.bool,
|
|
260
|
+
errorRequired: PropTypes.bool,
|
|
261
|
+
setErrorRequiered: PropTypes.func,
|
|
238
262
|
};
|
|
239
263
|
|
|
240
264
|
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
|
|
@@ -8,6 +8,8 @@ export default {
|
|
|
8
8
|
|
|
9
9
|
const Template = (args) => {
|
|
10
10
|
const [show, setShow] = useState(false);
|
|
11
|
+
const [errorRequired, setErrorRequired] = useState(false);
|
|
12
|
+
|
|
11
13
|
const handleToggle = () => setShow((prevShow) => !prevShow);
|
|
12
14
|
|
|
13
15
|
/* ========== */
|
|
@@ -51,7 +53,12 @@ const Template = (args) => {
|
|
|
51
53
|
inputLabel={'Filters (array de objetos)'}
|
|
52
54
|
focus={show}
|
|
53
55
|
hasId={true}
|
|
56
|
+
errorRequired={errorRequired}
|
|
57
|
+
setErrorRequiered={setErrorRequired}
|
|
58
|
+
validate={true}
|
|
54
59
|
/>
|
|
60
|
+
<button className='my-3' onClick={() => setErrorRequired(true)}>Validate</button>
|
|
61
|
+
|
|
55
62
|
|
|
56
63
|
{/* OPCION 2 */}
|
|
57
64
|
<DropdownMultiSelect
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import Navbar from
|
|
3
|
-
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import Navbar from '../components/Navigation/Navbar';
|
|
4
3
|
|
|
5
4
|
export default {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
title: 'Navigation/Navbar',
|
|
6
|
+
component: Navbar,
|
|
8
7
|
};
|
|
9
8
|
|
|
10
9
|
const Template = (args) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
return (
|
|
11
|
+
<Navbar
|
|
12
|
+
{...args}
|
|
13
|
+
showDeckMenu={true}
|
|
14
|
+
showUserMenu={true}
|
|
15
|
+
></Navbar>
|
|
16
|
+
/* <BrowserRouter>
|
|
14
17
|
<Routes>
|
|
15
18
|
<Route path="*" element={<Navbar {...args}></Navbar>} />
|
|
16
19
|
</Routes>
|
|
17
20
|
</BrowserRouter> */
|
|
18
|
-
|
|
21
|
+
);
|
|
19
22
|
};
|
|
20
23
|
|
|
21
24
|
export const Default = Template.bind({});
|