@zauru-sdk/components 2.0.46 → 2.0.48
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/CHANGELOG.md +16 -0
- package/dist/Alerts/ComponentError/index.d.ts +4 -0
- package/dist/Alerts/index.d.ts +1 -0
- package/dist/DynamicTable/GenericDynamicTable.d.ts +2 -0
- package/dist/Layouts/errorLayout/index.d.ts +2 -1
- package/dist/SidePanel/index.d.ts +2 -2
- package/dist/esm/Alerts/ComponentError/index.js +6 -0
- package/dist/esm/Alerts/index.js +1 -0
- package/dist/esm/DynamicTable/GenericDynamicTable.js +183 -173
- package/dist/esm/Form/SelectField/index.js +7 -17
- package/dist/esm/Layouts/errorLayout/index.js +7 -3
- package/dist/esm/SidePanel/index.js +1 -2
- package/package.json +3 -3
- package/src/Alerts/ComponentError/index.tsx +48 -0
- package/src/Alerts/index.ts +1 -0
- package/src/DynamicTable/GenericDynamicTable.tsx +388 -368
- package/src/Form/SelectField/index.tsx +7 -18
- package/src/Layouts/errorLayout/index.tsx +28 -3
- package/src/SidePanel/index.tsx +1 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.48](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.47...v2.0.48) (2024-10-23)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @zauru-sdk/components
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [2.0.47](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.46...v2.0.47) (2024-10-17)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @zauru-sdk/components
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [2.0.46](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.45...v2.0.46) (2024-10-17)
|
|
7
23
|
|
|
8
24
|
**Note:** Version bump only for package @zauru-sdk/components
|
package/dist/Alerts/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { GenericDynamicTableColumn, RowDataType, SelectFieldOption } from "@zaur
|
|
|
3
3
|
export type FooterColumnConfig = {
|
|
4
4
|
content: React.ReactNode;
|
|
5
5
|
className?: string;
|
|
6
|
+
name?: string;
|
|
6
7
|
};
|
|
7
8
|
type Props = {
|
|
8
9
|
name?: string;
|
|
@@ -33,6 +34,7 @@ type Props = {
|
|
|
33
34
|
name="invoice_details"
|
|
34
35
|
withoutBg
|
|
35
36
|
editable={!show}
|
|
37
|
+
searcheables={[{ value: "id_number", label: "No. Contraseña" }]}
|
|
36
38
|
defaultValue={
|
|
37
39
|
invoiceDetailsDefaultValue ?? [{ id: crypto.randomUUID() }]
|
|
38
40
|
}
|
|
@@ -17,5 +17,5 @@ interface SidePanelProps {
|
|
|
17
17
|
widthPercentage?: number;
|
|
18
18
|
buttonIcon?: "chevron" | "filter" | ReactNode;
|
|
19
19
|
}
|
|
20
|
-
declare const SidePanel: React.FC<SidePanelProps>;
|
|
21
|
-
export
|
|
20
|
+
export declare const SidePanel: React.FC<SidePanelProps>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
export const ComponentError = ({ error, componentName = "", }) => {
|
|
4
|
+
const [isDetailsOpen, setIsDetailsOpen] = useState(true);
|
|
5
|
+
return (_jsxs("div", { className: "bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative", role: "alert", children: [_jsx("strong", { className: "font-bold", children: "\u00A1Error!" }), _jsxs("span", { className: "block sm:inline", children: ["Ocurri\u00F3 un problema al cargar el componente", componentName ? `: "${componentName}"` : "", "."] }), _jsx("button", { onClick: () => setIsDetailsOpen(!isDetailsOpen), className: "mt-2 text-sm underline cursor-pointer", children: isDetailsOpen ? "Ocultar detalles" : "Ver detalles del error" }), isDetailsOpen && (_jsxs("div", { className: "mt-2 text-sm", children: [_jsx("strong", { children: "Detalles del error:" }), _jsx("pre", { className: "mt-1 whitespace-pre-wrap", children: error instanceof Error ? error.message : String(error) })] })), _jsx("span", { className: "absolute top-0 bottom-0 right-0 px-4 py-3", children: _jsxs("svg", { className: "fill-current h-6 w-6 text-red-500", role: "button", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", children: [_jsx("title", { children: "Cerrar" }), _jsx("path", { d: "M14.348 14.849a1.2 1.2 0 0 1-1.697 0L10 11.819l-2.651 3.029a1.2 1.2 0 1 1-1.697-1.697l2.758-3.15-2.759-3.152a1.2 1.2 0 1 1 1.697-1.697L10 8.183l2.651-3.031a1.2 1.2 0 1 1 1.697 1.697l-2.758 3.152 2.758 3.15a1.2 1.2 0 0 1 0 1.698z" })] }) })] }));
|
|
6
|
+
};
|
package/dist/esm/Alerts/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { LoadingInputSkeleton } from "../Skeletons/index.js";
|
|
|
10
10
|
import { WithTooltip } from "../WithTooltip/index.js";
|
|
11
11
|
import { TrashSvg } from "@zauru-sdk/icons";
|
|
12
12
|
import { useFormContext } from "react-hook-form";
|
|
13
|
+
import { ComponentError } from "../Alerts/index.js";
|
|
13
14
|
const GenericDynamicTableErrorComponent = ({ name }) => {
|
|
14
15
|
const { formState: { errors }, } = useFormContext() || { formState: {} }; // Obtener el contexto solo si existe
|
|
15
16
|
const error = errors ? errors[name ?? "-1"] : undefined;
|
|
@@ -25,6 +26,7 @@ const GenericDynamicTableErrorComponent = ({ name }) => {
|
|
|
25
26
|
name="invoice_details"
|
|
26
27
|
withoutBg
|
|
27
28
|
editable={!show}
|
|
29
|
+
searcheables={[{ value: "id_number", label: "No. Contraseña" }]}
|
|
28
30
|
defaultValue={
|
|
29
31
|
invoiceDetailsDefaultValue ?? [{ id: crypto.randomUUID() }]
|
|
30
32
|
}
|
|
@@ -67,181 +69,189 @@ const GenericDynamicTableErrorComponent = ({ name }) => {
|
|
|
67
69
|
*/
|
|
68
70
|
export const GenericDynamicTable = (props) => {
|
|
69
71
|
const { columns, onChange, className, footerRow, defaultValue = [], thCSSProperties, thElementsClassName = "", editable = true, searcheables = [], loading = false, paginated = true, defaultItemsPerPage = 10, itemsPerPageOptions = [10, 50, 100], name, withoutBg = false, orientation = "horizontal", maxRows, } = props;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
x.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
setTableData((prevData) => [
|
|
106
|
-
...prevData,
|
|
107
|
-
{ id: generateClientUUID(), ...defs },
|
|
108
|
-
]);
|
|
109
|
-
};
|
|
110
|
-
const removeRow = (rowId) => {
|
|
111
|
-
const newDeletedData = [...deletedData];
|
|
112
|
-
const deletedItem = tableData?.find((x) => x.id === rowId);
|
|
113
|
-
if (deletedItem && !isNaN(deletedItem.id)) {
|
|
114
|
-
newDeletedData.push(deletedItem);
|
|
115
|
-
}
|
|
116
|
-
setDeletedData(newDeletedData);
|
|
117
|
-
setTableData((prevData) => prevData?.filter((x) => x.id !== rowId));
|
|
118
|
-
};
|
|
119
|
-
const handleChange = (name, value, rowId) => {
|
|
120
|
-
setTableData((prevData) => {
|
|
121
|
-
const updatedData = prevData.map((row) => {
|
|
122
|
-
if (row.id === rowId) {
|
|
123
|
-
return { ...row, [name]: value };
|
|
124
|
-
}
|
|
125
|
-
return row;
|
|
72
|
+
try {
|
|
73
|
+
const [tableData, setTableData] = useState(defaultValue);
|
|
74
|
+
const [deletedData, setDeletedData] = useState([]);
|
|
75
|
+
const [search, setSearch] = useState("");
|
|
76
|
+
const [filteredTableData, setFilteredTableData] = useState(tableData);
|
|
77
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
78
|
+
const [itemsPerPage, setItemsPerPage] = useState(defaultItemsPerPage);
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (defaultValue.length) {
|
|
81
|
+
setTableData(defaultValue);
|
|
82
|
+
}
|
|
83
|
+
}, []);
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
setFilteredTableData(tableData);
|
|
86
|
+
}, [tableData]);
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
changeFilteredData();
|
|
89
|
+
}, [tableData, search]);
|
|
90
|
+
const totalPages = () => {
|
|
91
|
+
return Math.ceil(filteredTableData.length / itemsPerPage);
|
|
92
|
+
};
|
|
93
|
+
const addRow = () => {
|
|
94
|
+
if (maxRows && tableData.length >= maxRows) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const defs = {};
|
|
98
|
+
columns.forEach((x) => {
|
|
99
|
+
defs[`${x.name}`] =
|
|
100
|
+
x.type == "label" || x.type == "textField"
|
|
101
|
+
? ""
|
|
102
|
+
: x.type == "selectField"
|
|
103
|
+
? 0
|
|
104
|
+
: x.type == "checkbox"
|
|
105
|
+
? false
|
|
106
|
+
: 0;
|
|
126
107
|
});
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const renderHeader = () => {
|
|
132
|
-
if (orientation === "horizontal") {
|
|
133
|
-
return (_jsxs("tr", { style: { ...thCSSProperties }, children: [columns.map((column, index) => {
|
|
134
|
-
const ancho = column.width ?? (editable ? 94 : 100) / (columns.length ?? 1);
|
|
135
|
-
return (_jsx("th", { className: `text-left align-middle p-2 ${thElementsClassName} ${column.headerClassName || ""}`, style: { width: `${ancho}%` }, children: column.label }, index));
|
|
136
|
-
}), editable && _jsx("th", { style: { width: "4%" } })] }));
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
const renderRow = (rowData, index) => {
|
|
143
|
-
if (orientation === "horizontal") {
|
|
144
|
-
return (_jsxs("tr", { className: index % 2 === 0 ? `${withoutBg ? "" : "bg-gray-200"}` : "", children: [columns.map((column) => renderCell(rowData, column)), editable && renderDeleteButton(rowData)] }, rowData.id));
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
return columns.map((column) => (_jsxs("tr", { className: index % 2 === 0 ? `${withoutBg ? "" : "bg-gray-200"}` : "", children: [_jsx("th", { className: `text-left align-middle p-2 ${thElementsClassName} ${column.headerClassName || ""}`, children: column.label }), renderCell(rowData, column), editable &&
|
|
148
|
-
column === columns[columns.length - 1] &&
|
|
149
|
-
renderDeleteButton(rowData)] }, `${rowData.id}-${column.name}`)));
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
const renderCell = (rowData, column) => {
|
|
153
|
-
if (loading) {
|
|
154
|
-
return (_jsx("td", { className: `align-middle p-1 ${column.cellClassName || ""}`, children: _jsx(LoadingInputSkeleton, {}) }, `${rowData.id}-${column.name}`));
|
|
155
|
-
}
|
|
156
|
-
const tempVal = rowData[column.name];
|
|
157
|
-
const defaultVal = column.type === "selectField"
|
|
158
|
-
? column.options?.find((x) => x.value === tempVal)
|
|
159
|
-
: tempVal;
|
|
160
|
-
if (column.type === "label") {
|
|
161
|
-
return (_jsx("td", { className: `align-middle p-1 ${column.cellClassName || ""}`, children: _jsx("div", { children: defaultVal }) }, `${rowData.id}-${column.name}`));
|
|
162
|
-
}
|
|
163
|
-
const FieldComponent = column.type === "textField"
|
|
164
|
-
? TextField
|
|
165
|
-
: column.type === "checkbox"
|
|
166
|
-
? CheckBox
|
|
167
|
-
: SelectField;
|
|
168
|
-
const setTableValue = (columnName, newValue) => {
|
|
169
|
-
handleChange(columnName, newValue, rowData.id);
|
|
108
|
+
setTableData((prevData) => [
|
|
109
|
+
...prevData,
|
|
110
|
+
{ id: generateClientUUID(), ...defs },
|
|
111
|
+
]);
|
|
170
112
|
};
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (response === "OK") {
|
|
186
|
-
removeRow(rowData.id);
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
}, type: "button", children: _jsx(TrashSvg, {}) }) }) }));
|
|
190
|
-
const renderRows = () => {
|
|
191
|
-
let mapeable = filteredTableData.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);
|
|
192
|
-
if (loading) {
|
|
193
|
-
mapeable = [
|
|
194
|
-
{ id: 1 },
|
|
195
|
-
{ id: 2 },
|
|
196
|
-
{ id: 3 },
|
|
197
|
-
{ id: 4 },
|
|
198
|
-
{ id: 5 },
|
|
199
|
-
{ id: 6 },
|
|
200
|
-
{ id: 7 },
|
|
201
|
-
{ id: 8 },
|
|
202
|
-
{ id: 9 },
|
|
203
|
-
{ id: 10 },
|
|
204
|
-
];
|
|
205
|
-
}
|
|
206
|
-
return mapeable.map((rowData, index) => renderRow(rowData, index));
|
|
207
|
-
};
|
|
208
|
-
const handleChangeSearch = (newSearch) => {
|
|
209
|
-
setSearch(newSearch);
|
|
210
|
-
};
|
|
211
|
-
const changeFilteredData = () => {
|
|
212
|
-
if (search) {
|
|
213
|
-
const filteredData = tableData.filter((rowData) => {
|
|
214
|
-
for (const searchable of searcheables) {
|
|
215
|
-
const column = columns.find((col) => col.name === searchable.value);
|
|
216
|
-
if (column) {
|
|
217
|
-
const tempVal = rowData[column.name];
|
|
218
|
-
const defaultVal = column.type === "selectField"
|
|
219
|
-
? column.options?.find((x) => x.value === tempVal)?.label
|
|
220
|
-
: tempVal;
|
|
221
|
-
if (defaultVal
|
|
222
|
-
?.toString()
|
|
223
|
-
.toLowerCase()
|
|
224
|
-
.includes(search.toLowerCase())) {
|
|
225
|
-
return true;
|
|
226
|
-
}
|
|
113
|
+
const removeRow = (rowId) => {
|
|
114
|
+
const newDeletedData = [...deletedData];
|
|
115
|
+
const deletedItem = tableData?.find((x) => x.id === rowId);
|
|
116
|
+
if (deletedItem && !isNaN(deletedItem.id)) {
|
|
117
|
+
newDeletedData.push(deletedItem);
|
|
118
|
+
}
|
|
119
|
+
setDeletedData(newDeletedData);
|
|
120
|
+
setTableData((prevData) => prevData?.filter((x) => x.id !== rowId));
|
|
121
|
+
};
|
|
122
|
+
const handleChange = (name, value, rowId) => {
|
|
123
|
+
setTableData((prevData) => {
|
|
124
|
+
const updatedData = prevData.map((row) => {
|
|
125
|
+
if (row.id === rowId) {
|
|
126
|
+
return { ...row, [name]: value };
|
|
227
127
|
}
|
|
228
|
-
|
|
229
|
-
|
|
128
|
+
return row;
|
|
129
|
+
});
|
|
130
|
+
onChange && onChange(updatedData);
|
|
131
|
+
return updatedData;
|
|
230
132
|
});
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
133
|
+
};
|
|
134
|
+
const renderHeader = () => {
|
|
135
|
+
if (orientation === "horizontal") {
|
|
136
|
+
return (_jsxs("tr", { style: { ...thCSSProperties }, children: [columns.map((column, index) => {
|
|
137
|
+
const ancho = column.width ?? (editable ? 94 : 100) / (columns.length ?? 1);
|
|
138
|
+
return (_jsx("th", { className: `text-left align-middle p-2 ${thElementsClassName} ${column.headerClassName || ""}`, style: { width: `${ancho}%` }, children: column.label }, index));
|
|
139
|
+
}), editable && _jsx("th", { style: { width: "4%" } })] }));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
const renderRow = (rowData, index) => {
|
|
146
|
+
if (orientation === "horizontal") {
|
|
147
|
+
return (_jsxs("tr", { className: index % 2 === 0 ? `${withoutBg ? "" : "bg-gray-200"}` : "", children: [columns.map((column) => renderCell(rowData, column)), editable && renderDeleteButton(rowData)] }, rowData.id));
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
return columns.map((column) => (_jsxs("tr", { className: index % 2 === 0 ? `${withoutBg ? "" : "bg-gray-200"}` : "", children: [_jsx("th", { className: `text-left align-middle p-2 ${thElementsClassName} ${column.headerClassName || ""}`, children: column.label }), renderCell(rowData, column), editable &&
|
|
151
|
+
column === columns[columns.length - 1] &&
|
|
152
|
+
renderDeleteButton(rowData)] }, `${rowData.id}-${column.name}`)));
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const renderCell = (rowData, column) => {
|
|
156
|
+
if (loading) {
|
|
157
|
+
return (_jsx("td", { className: `align-middle p-1 ${column.cellClassName || ""}`, children: _jsx(LoadingInputSkeleton, {}) }, `${rowData.id}-${column.name}`));
|
|
158
|
+
}
|
|
159
|
+
const tempVal = rowData[column.name];
|
|
160
|
+
const defaultVal = column.type === "selectField"
|
|
161
|
+
? column.options?.find((x) => x.value === tempVal)
|
|
162
|
+
: tempVal;
|
|
163
|
+
if (column.type === "label") {
|
|
164
|
+
return (_jsx("td", { className: `align-middle p-1 ${column.cellClassName || ""}`, children: _jsx("div", { children: defaultVal }) }, `${rowData.id}-${column.name}`));
|
|
165
|
+
}
|
|
166
|
+
const FieldComponent = column.type === "textField"
|
|
167
|
+
? TextField
|
|
168
|
+
: column.type === "checkbox"
|
|
169
|
+
? CheckBox
|
|
170
|
+
: SelectField;
|
|
171
|
+
const setTableValue = (columnName, newValue) => {
|
|
172
|
+
handleChange(columnName, newValue, rowData.id);
|
|
173
|
+
};
|
|
174
|
+
return (_jsx("td", { className: `align-middle p-1 ${column.cellClassName || ""}`, children: column.loadingOptions ? (_jsx(LoadingInputSkeleton, {})) : (_jsx(FieldComponent, { name: `${rowData.id}-${column.name}`, type: column.textFieldType, integer: !!column.integer, disabled: column.disabled, isClearable: true, onChange: (value) => {
|
|
175
|
+
const sendValue = value?.value ?? value;
|
|
176
|
+
handleChange(column.name, sendValue, rowData.id);
|
|
177
|
+
column.onChange &&
|
|
178
|
+
column.onChange(rowData, sendValue, setTableValue);
|
|
179
|
+
}, defaultValue: defaultVal, options: column.options ?? [] }, `${rowData.id}-${column.name}`)) }, `${rowData.id}-${column.name}`));
|
|
180
|
+
};
|
|
181
|
+
const renderDeleteButton = (rowData) => (_jsx("td", { className: "align-middle w-16", children: _jsx(WithTooltip, { text: "Eliminar", children: _jsx("button", { className: "bg-red-500 hover:bg-red-600 font-bold py-1 px-2 rounded ml-2", onClick: (event) => {
|
|
182
|
+
event.preventDefault();
|
|
183
|
+
event.stopPropagation();
|
|
184
|
+
createModal({
|
|
185
|
+
title: "¿Está seguro que quiere eliminar este registro?",
|
|
186
|
+
description: "Una vez eliminada la información no podrá ser recuperada.",
|
|
187
|
+
}).then((response) => {
|
|
188
|
+
if (response === "OK") {
|
|
189
|
+
removeRow(rowData.id);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}, type: "button", children: _jsx(TrashSvg, {}) }) }) }));
|
|
193
|
+
const renderRows = () => {
|
|
194
|
+
let mapeable = filteredTableData.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);
|
|
195
|
+
if (loading) {
|
|
196
|
+
mapeable = [
|
|
197
|
+
{ id: 1 },
|
|
198
|
+
{ id: 2 },
|
|
199
|
+
{ id: 3 },
|
|
200
|
+
{ id: 4 },
|
|
201
|
+
{ id: 5 },
|
|
202
|
+
{ id: 6 },
|
|
203
|
+
{ id: 7 },
|
|
204
|
+
{ id: 8 },
|
|
205
|
+
{ id: 9 },
|
|
206
|
+
{ id: 10 },
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
return mapeable.map((rowData, index) => renderRow(rowData, index));
|
|
210
|
+
};
|
|
211
|
+
const handleChangeSearch = (newSearch) => {
|
|
212
|
+
setSearch(newSearch);
|
|
213
|
+
};
|
|
214
|
+
const changeFilteredData = () => {
|
|
215
|
+
if (search) {
|
|
216
|
+
const filteredData = tableData.filter((rowData) => {
|
|
217
|
+
for (const searchable of searcheables) {
|
|
218
|
+
const column = columns.find((col) => col.name === searchable.value);
|
|
219
|
+
if (column) {
|
|
220
|
+
const tempVal = rowData[column.name];
|
|
221
|
+
const defaultVal = column.type === "selectField"
|
|
222
|
+
? column.options?.find((x) => x.value === tempVal)?.label
|
|
223
|
+
: tempVal;
|
|
224
|
+
if (defaultVal
|
|
225
|
+
?.toString()
|
|
226
|
+
.toLowerCase()
|
|
227
|
+
.includes(search.toLowerCase())) {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return false;
|
|
233
|
+
});
|
|
234
|
+
setFilteredTableData(filteredData);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
setFilteredTableData(tableData);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
return (_jsxs(_Fragment, { children: [name && (_jsxs(_Fragment, { children: [_jsx(GenericDynamicTableErrorComponent, { name: name }), _jsx("input", { name: name, type: "hidden", value: JSON.stringify(tableData), hidden: true }), _jsx("input", { name: `deleted_${name}`, type: "hidden", value: JSON.stringify(deletedData), hidden: true })] })), _jsxs("div", { className: `${className}`, children: [searcheables.length > 0 && (_jsx("div", { children: _jsx(TextField, { className: "mb-2", name: "search", title: `Buscar por: ${searcheables
|
|
241
|
+
.map((x) => x.label)
|
|
242
|
+
.join(", ")}`, onChange: handleChangeSearch, disabled: loading }) })), _jsxs("table", { className: "w-full", children: [orientation === "horizontal" && _jsx("thead", { children: renderHeader() }), _jsx("tbody", { children: renderRows() }), editable && (_jsx("tfoot", { children: _jsx("tr", { children: _jsx("td", { colSpan: orientation === "horizontal" ? columns.length + 1 : 2, className: "align-middle", children: (!maxRows || tableData.length < maxRows) && (_jsx("button", { className: "bg-blue-500 hover:bg-blue-600 font-bold py-2 px-4 rounded", onClick: (event) => {
|
|
243
|
+
event.preventDefault();
|
|
244
|
+
event.stopPropagation();
|
|
245
|
+
addRow();
|
|
246
|
+
}, type: "button", children: "+" })) }) }) })), footerRow && (_jsx("tfoot", { className: "border-t-2 border-black", children: _jsxs("tr", { children: [columns.map((column, index) => {
|
|
247
|
+
const footerCell = footerRow.find((fc) => fc.name === column.name);
|
|
248
|
+
return (_jsx("td", { colSpan: orientation === "vertical" ? 2 : 1, className: `align-middle ${footerCell?.className || ""}`, children: footerCell ? footerCell.content : _jsx(_Fragment, {}) }, index));
|
|
249
|
+
}), editable && _jsx("td", {})] }) }))] }), paginated && totalPages() > 1 && (_jsxs("div", { className: "flex justify-between items-center mt-4", children: [_jsxs("div", { className: "flex items-center", children: [_jsx(Button, { type: "button", disabled: currentPage === 1, onClickSave: () => setCurrentPage((old) => Math.max(old - 1, 1)), children: "Anterior" }), _jsx("span", { className: "mx-2", children: `Página ${currentPage} de ${totalPages()}` }), _jsx(Button, { type: "button", disabled: currentPage === totalPages(), onClickSave: () => setCurrentPage((old) => Math.min(old + 1, totalPages())), children: "Siguiente" })] }), _jsx("div", { children: _jsx("select", { value: itemsPerPage, onChange: (e) => {
|
|
250
|
+
setItemsPerPage(Number(e.target.value));
|
|
251
|
+
setCurrentPage(1); // resetear la página al cambiar los elementos por página
|
|
252
|
+
}, children: itemsPerPageOptions.map((option) => (_jsxs("option", { value: option, children: [option, " elementos por p\u00E1gina"] }, option))) }) })] }))] })] }));
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
return _jsx(ComponentError, { error: error, componentName: "GenericDynamicTable" });
|
|
256
|
+
}
|
|
247
257
|
};
|
|
@@ -15,7 +15,6 @@ export const SelectField = (props) => {
|
|
|
15
15
|
const selectRef = useRef(null);
|
|
16
16
|
const optionsRef = useRef(null);
|
|
17
17
|
const [isTabPressed, setIsTabPressed] = useState(false);
|
|
18
|
-
const [isEnterPressed, setIsEnterPressed] = useState(false);
|
|
19
18
|
const [isSearching, setIsSearching] = useState(false);
|
|
20
19
|
const { register: tempRegister, formState: { errors }, setValue: setFormValue, } = useFormContext() || { formState: {} };
|
|
21
20
|
const error = errors ? errors[props.name ?? "-1"] : undefined;
|
|
@@ -80,6 +79,9 @@ export const SelectField = (props) => {
|
|
|
80
79
|
setFormValue(name || "", option.value);
|
|
81
80
|
}
|
|
82
81
|
}
|
|
82
|
+
setHighlightedIndex(-1);
|
|
83
|
+
setIsSearching(false);
|
|
84
|
+
setFilteredOptions([]);
|
|
83
85
|
setIsOpen(false);
|
|
84
86
|
};
|
|
85
87
|
const handleClear = () => {
|
|
@@ -101,24 +103,13 @@ export const SelectField = (props) => {
|
|
|
101
103
|
};
|
|
102
104
|
const handleBlur = () => {
|
|
103
105
|
setTimeout(() => {
|
|
104
|
-
if (isTabPressed &&
|
|
105
|
-
filteredOptions
|
|
106
|
-
!isEnterPressed &&
|
|
107
|
-
isSearching) {
|
|
108
|
-
if (highlightedIndex >= 0) {
|
|
109
|
-
handleOptionClick(filteredOptions[highlightedIndex]);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
handleOptionClick(filteredOptions[0]);
|
|
113
|
-
}
|
|
106
|
+
if (isTabPressed && highlightedIndex >= 0) {
|
|
107
|
+
handleOptionClick(filteredOptions[highlightedIndex]);
|
|
114
108
|
}
|
|
115
|
-
else if (isTabPressed) {
|
|
116
|
-
|
|
117
|
-
handleOptionClick(filteredOptions[highlightedIndex]);
|
|
118
|
-
}
|
|
109
|
+
else if (isTabPressed && filteredOptions.length > 0 && isSearching) {
|
|
110
|
+
handleOptionClick(filteredOptions[0]);
|
|
119
111
|
}
|
|
120
112
|
setIsTabPressed(false);
|
|
121
|
-
setIsEnterPressed(false);
|
|
122
113
|
setIsSearching(false);
|
|
123
114
|
setIsOpen(false);
|
|
124
115
|
}, 200);
|
|
@@ -139,7 +130,6 @@ export const SelectField = (props) => {
|
|
|
139
130
|
}
|
|
140
131
|
else if (e.key === "Enter" && highlightedIndex !== -1) {
|
|
141
132
|
e.preventDefault();
|
|
142
|
-
setIsEnterPressed(true);
|
|
143
133
|
handleOptionClick(filteredOptions[highlightedIndex]);
|
|
144
134
|
}
|
|
145
135
|
else if (e.key === "Backspace" && (value || valueMulti.length > 0)) {
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { isRouteErrorResponse, Links, Meta, Scripts, useRouteError, Link, } from "@remix-run/react";
|
|
3
|
-
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
export const ErrorLayout = ({ from, error: parentError, }) => {
|
|
4
5
|
const error = useRouteError();
|
|
5
|
-
|
|
6
|
+
const [showDetails, setShowDetails] = useState(!!parentError);
|
|
7
|
+
return (_jsxs("html", { lang: "es", className: "bg-gray-900 text-white", children: [_jsxs("head", { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: "\u00A1Ups! Algo sali\u00F3 mal" }), _jsx(Meta, {}), _jsx(Links, {})] }), _jsxs("body", { className: "min-h-screen flex flex-col items-center justify-center p-4", children: [_jsx("img", { src: "/logo.png", alt: "Zauru Logo", className: "mb-8 h-20" }), _jsx("h1", { className: "text-5xl font-extrabold text-red-500 mb-6", children: "\u00A1Ups!" }), _jsxs("div", { className: "w-full max-w-2xl flex flex-col items-center", children: [_jsx("p", { className: "text-2xl text-gray-300 mb-8 text-center", children: isRouteErrorResponse(error)
|
|
6
8
|
? `Error ${error.status}: ${error.statusText}`
|
|
7
9
|
: error instanceof Error
|
|
8
10
|
? error.message
|
|
9
|
-
: "Ha ocurrido un error inesperado" }), from && (_jsxs("p", { className: "text-lg text-gray-400 mb-4 text-center", children: ["Error lanzado desde: ", from] }))
|
|
11
|
+
: "Ha ocurrido un error inesperado" }), from && (_jsxs("p", { className: "text-lg text-gray-400 mb-4 text-center", children: ["Error lanzado desde: ", from] })), parentError && (_jsxs("div", { className: "mb-4 text-center", children: [_jsx("button", { onClick: () => setShowDetails(!showDetails), className: "text-blue-400 hover:text-blue-300 transition duration-300", children: showDetails ? "Ocultar detalles" : "Ver más detalles" }), showDetails && (_jsx("p", { className: "mt-2 text-gray-400 text-sm", children: parentError instanceof Error
|
|
12
|
+
? parentError.message
|
|
13
|
+
: String(parentError) }))] }))] }), _jsx(Link, { to: "/", className: "bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105", children: "Regresar al inicio" }), _jsx("div", { className: "mt-12 text-gray-500 text-center", children: _jsx("p", { children: "Si el problema persiste, por favor contacta a soporte." }) }), _jsx(Scripts, {})] })] }));
|
|
10
14
|
};
|
|
@@ -7,7 +7,7 @@ const ChevronLeftIcon = () => (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg"
|
|
|
7
7
|
const ChevronRightIcon = () => (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "h-6 w-6", children: _jsx("path", { fillRule: "evenodd", d: "M16.28 11.47a.75.75 0 010 1.06l-7.5 7.5a.75.75 0 01-1.06-1.06L14.69 12 7.72 5.03a.75.75 0 011.06-1.06l7.5 7.5z", clipRule: "evenodd" }) }));
|
|
8
8
|
// SVG icon for the filter (bars filter icon)
|
|
9
9
|
const FilterIcon = () => (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "h-6 w-6", children: _jsx("path", { fillRule: "evenodd", d: "M3 6a1 1 0 011-1h16a1 1 0 110 2H4a1 1 0 01-1-1zm0 6a1 1 0 011-1h10a1 1 0 110 2H4a1 1 0 01-1-1zm0 6a1 1 0 011-1h4a1 1 0 110 2H4a1 1 0 01-1-1z", clipRule: "evenodd" }) }));
|
|
10
|
-
const SidePanel = ({ children, closeOnClickOutside = true, widthPercentage = 25, buttonIcon = "chevron", }) => {
|
|
10
|
+
export const SidePanel = ({ children, closeOnClickOutside = true, widthPercentage = 25, buttonIcon = "chevron", }) => {
|
|
11
11
|
const [isOpen, setIsOpen] = useState(false);
|
|
12
12
|
const panelRef = useRef(null);
|
|
13
13
|
const togglePanel = () => {
|
|
@@ -43,4 +43,3 @@ const SidePanel = ({ children, closeOnClickOutside = true, widthPercentage = 25,
|
|
|
43
43
|
};
|
|
44
44
|
return (_jsxs(_Fragment, { children: [_jsxs(motion.div, { ref: panelRef, initial: { x: "100%" }, animate: { x: isOpen ? 0 : "100%" }, transition: { type: "spring", stiffness: 300, damping: 30 }, className: `fixed top-0 right-0 h-full bg-white shadow-lg z-[9999] overflow-y-auto`, style: { width: `${widthPercentage}%` }, children: [_jsx("button", { onClick: togglePanel, className: "absolute top-4 left-4 p-2 rounded-full bg-gray-200 hover:bg-gray-300 transition-colors", children: _jsx(ChevronRightIcon, {}) }), _jsx("div", { className: "p-6 mt-16", children: children })] }), _jsx(AnimatePresence, { children: !isOpen && (_jsx(motion.button, { initial: { opacity: 0, x: 20 }, animate: { opacity: 1, x: 0 }, exit: { opacity: 0, x: 20 }, transition: { duration: 0.2 }, onClick: togglePanel, className: `fixed top-1/2 right-0 transform -translate-y-1/2 bg-indigo-600 text-white p-3 rounded-l-lg shadow-md hover:bg-indigo-700 transition-colors z-[10000]`, children: renderIcon() })) })] }));
|
|
45
45
|
};
|
|
46
|
-
export default SidePanel;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zauru-sdk/components",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.48",
|
|
4
4
|
"description": "Componentes reutilizables en las WebApps de Zauru.",
|
|
5
5
|
"main": "./dist/esm/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@zauru-sdk/hooks": "^2.0.44",
|
|
38
38
|
"@zauru-sdk/icons": "^2.0.0",
|
|
39
39
|
"@zauru-sdk/types": "^2.0.44",
|
|
40
|
-
"@zauru-sdk/utils": "^2.0.
|
|
40
|
+
"@zauru-sdk/utils": "^2.0.48",
|
|
41
41
|
"framer-motion": "^11.7.0",
|
|
42
42
|
"jsonwebtoken": "^9.0.2",
|
|
43
43
|
"react": "^18.2.0",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"styled-components": "^5.3.5",
|
|
50
50
|
"zod": "^3.23.8"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "23cf4319aea8a8e017a453c31a4aa327898bf3a1"
|
|
53
53
|
}
|