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/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.68",
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
- (item) =>
71
- (object ? `${item[idKey]} ${item[nameKey]}` : item)
72
- .toLowerCase()
73
- .includes(query.toLowerCase()) &&
74
- (showStatus ? parseInt(item.status) === parseInt(showStatus) : true),
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;
@@ -31,7 +31,6 @@ const InputEmail = ({
31
31
  // GET, Returns a list of emails
32
32
  const fetchNotifications = async () => {
33
33
  const resp = await ComponentsService.getInfo(apiGetEmail);
34
- console.log('resp', resp);
35
34
  setNotifications(resp || []);
36
35
 
37
36
  };
@@ -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
- const resp = await ComponentsService.favApplication(identification);
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
- const resp = await ComponentsService.unfavApplication(identification);
73
-
74
- if (resp.status === 204) {
75
- setApplications((prev) => {
76
- const index = prev.findIndex(
77
- (element) => element?.id_application === identification,
78
- );
79
- prev[index].favorite = false;
80
- return [...prev];
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 === 0) fetchData();
84
+ if (!applications?.length) fetchData();
90
85
  }, []);
91
86
 
92
87
  return (
93
- <Dropdown>
94
- <Dropdown.Toggle className='btn btn-terciary'>
95
- <svg
96
- id='deckApps'
97
- xmlns='http://www.w3.org/2000/svg'
98
- className='icon'
99
- viewBox='0 0 16 16'
100
- >
101
- <g>
102
- <rect x='1' y='1' width='4' height='4' rx='1.25' ry='1.25' />
103
- <rect x='1' y='6' width='4' height='4' rx='1.25' ry='1.25' />
104
- <rect x='1' y='11' width='4' height='4' rx='1.25' ry='1.25' />
105
- <rect x='6' y='1' width='4' height='4' rx='1.25' ry='1.25' />
106
- <rect x='6' y='6' width='4' height='4' rx='1.25' ry='1.25' />
107
- <rect x='6' y='11' width='4' height='4' rx='1.25' ry='1.25' />
108
- <rect x='11' y='1' width='4' height='4' rx='1.25' ry='1.25' />
109
- <rect x='11' y='6' width='4' height='4' rx='1.25' ry='1.25' />
110
- <rect x='11' y='11' width='4' height='4' rx='1.25' ry='1.25' />
111
- </g>
112
- </svg>
113
- </Dropdown.Toggle>
114
-
115
- <Dropdown.Menu as={'ul'}>
116
- {applications?.filter((item) => item.favorite).length > 0 && (
117
- <Dropdown.Item as={'li'}>
118
- <h4 className='dropdown-header'>Favorites</h4>
119
- </Dropdown.Item>
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
- {applications?.filter((item) => item.favorite).length > 0 &&
162
- applications?.filter((item) => !item.favorite).length > 0 && (
163
- <Dropdown.Divider as={'li'} />
164
- )}
165
-
166
- {applications
167
- .filter((item) => !item.favorite)
168
- .map((element, i) => {
169
- return (
170
- <Dropdown.Item key={i} as={'li'}>
171
- <div
172
- onClick={() => {
173
- window.location.replace(
174
- linkToApp(
175
- element.application_url,
176
- element.application_name,
177
- ),
178
- );
179
- }}
180
- className='link-app'
181
- >
182
- <span className='icon-app'>
183
- <Icon
184
- style={'solid'}
185
- iconName={element.app_icon_sm}
186
- scale={1}
187
- />
188
- </span>
189
-
190
- <span>{element.app_name}</span>
191
- </div>
192
- <button
193
- className='deck-fav'
194
- onClick={(e) => {
195
- e.stopPropagation();
196
- favApp(element.id_application);
197
- }}
198
- >
199
- <Icon style={'regular'} iconName={'star'} scale={1} />
200
- </button>
201
- </Dropdown.Item>
202
- );
203
- })}
204
- </Dropdown.Menu>
205
-
206
- </Dropdown>
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 "react";
2
- import Navbar from "../components/Navigation/Navbar";
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
- title: "Navigation/Navbar",
7
- component: Navbar,
5
+ title: 'Navigation/Navbar',
6
+ component: Navbar,
8
7
  };
9
8
 
10
9
  const Template = (args) => {
11
- return (
12
- <Navbar {...args}></Navbar>
13
- /* <BrowserRouter>
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({});