next-recomponents 1.7.63 → 1.8.2
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/dist/index.d.mts +30 -37
- package/dist/index.d.ts +30 -37
- package/dist/index.js +671 -742
- package/dist/index.mjs +677 -748
- package/package.json +1 -1
- package/src/container/index.tsx +3 -6
- package/src/index.tsx +1 -2
- package/src/table/filters.tsx +16 -15
- package/src/table/h.tsx +49 -63
- package/src/table/td.tsx +5 -24
- package/src/table/vtd.tsx +1 -0
- package/src/table3/body.tsx +75 -0
- package/src/table3/dialog.tsx +49 -0
- package/src/table3/filter.tsx +213 -0
- package/src/table3/footer.tsx +56 -0
- package/src/table3/head.tsx +72 -0
- package/src/table3/index.tsx +190 -0
- package/src/table3/panel.tsx +85 -0
- package/src/table3/tr.tsx +148 -0
- package/tsconfig.json +2 -2
- package/src/table2/context.tsx +0 -141
- package/src/table2/h.table.tsx +0 -5
- package/src/table2/icons.tsx +0 -116
- package/src/table2/index.tsx +0 -70
- package/src/table2/v.table.body.tsx +0 -155
- package/src/table2/v.table.head.filter.tsx +0 -196
- package/src/table2/v.table.head.tsx +0 -43
- package/src/table2/v.table.pagination.tsx +0 -73
- package/src/table2/v.table.tsx +0 -58
- package/src/use-modal/index.tsx +0 -79
package/package.json
CHANGED
package/src/container/index.tsx
CHANGED
|
@@ -44,7 +44,7 @@ export default function Container({
|
|
|
44
44
|
<h1 className="text-xl font-bold">{appName}</h1>
|
|
45
45
|
</div>
|
|
46
46
|
<div
|
|
47
|
-
className={` gap-2 bg-
|
|
47
|
+
className={` gap-2 bg-gray-800 text-white ${
|
|
48
48
|
isSidebarOpen ? "px-[270px]" : "px-[60px]"
|
|
49
49
|
} hidden sm:flex`}
|
|
50
50
|
>
|
|
@@ -84,7 +84,7 @@ export default function Container({
|
|
|
84
84
|
? 250
|
|
85
85
|
: 60,
|
|
86
86
|
}}
|
|
87
|
-
className="bg-
|
|
87
|
+
className="bg-gray-800 text-white overflow-y-auto fixed md:static top-0 left-0 h-full z-50 md:z-auto transition-all duration-300 ease-in-out"
|
|
88
88
|
>
|
|
89
89
|
<div className="p-4 ">
|
|
90
90
|
{menuList && (
|
|
@@ -123,10 +123,7 @@ export default function Container({
|
|
|
123
123
|
</div>
|
|
124
124
|
)}
|
|
125
125
|
{!isSidebarOpen && (
|
|
126
|
-
<div
|
|
127
|
-
title={`${itemMenu.name}`}
|
|
128
|
-
className="text-sm hover:bg-gray-200 hover:text-black rounded p-1"
|
|
129
|
-
>
|
|
126
|
+
<div className="text-sm hover:bg-gray-200 hover:text-black rounded p-1">
|
|
130
127
|
{icon}
|
|
131
128
|
</div>
|
|
132
129
|
)}
|
package/src/index.tsx
CHANGED
|
@@ -16,5 +16,4 @@ export { default as MyCalendar } from "./calendar";
|
|
|
16
16
|
export type { TableEventProps } from "./table";
|
|
17
17
|
export { useFormValues } from "./form";
|
|
18
18
|
export { default as DocumentViewer } from "./doc-viewer";
|
|
19
|
-
export { default as
|
|
20
|
-
export { default as useModal } from "./use-modal";
|
|
19
|
+
export { default as Table3 } from "./table3";
|
package/src/table/filters.tsx
CHANGED
|
@@ -13,6 +13,21 @@ export function FilterOffIcon() {
|
|
|
13
13
|
</svg>
|
|
14
14
|
);
|
|
15
15
|
}
|
|
16
|
+
export function EditIcon() {
|
|
17
|
+
return (
|
|
18
|
+
<svg
|
|
19
|
+
stroke="currentColor"
|
|
20
|
+
fill="currentColor"
|
|
21
|
+
strokeWidth="0"
|
|
22
|
+
viewBox="0 0 576 512"
|
|
23
|
+
height="20px"
|
|
24
|
+
width="20px"
|
|
25
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
26
|
+
>
|
|
27
|
+
<path d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"></path>
|
|
28
|
+
</svg>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
16
31
|
|
|
17
32
|
export function MdLastPage() {
|
|
18
33
|
return (
|
|
@@ -110,21 +125,7 @@ export function ExcelIcon() {
|
|
|
110
125
|
</svg>
|
|
111
126
|
);
|
|
112
127
|
}
|
|
113
|
-
|
|
114
|
-
return (
|
|
115
|
-
<svg
|
|
116
|
-
stroke="currentColor"
|
|
117
|
-
fill="currentColor"
|
|
118
|
-
strokeWidth="0"
|
|
119
|
-
viewBox="0 0 576 512"
|
|
120
|
-
height="20px"
|
|
121
|
-
width="20px"
|
|
122
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
123
|
-
>
|
|
124
|
-
<path d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"></path>
|
|
125
|
-
</svg>
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
+
|
|
128
129
|
export function ArrowIcon() {
|
|
129
130
|
return (
|
|
130
131
|
<svg
|
package/src/table/h.tsx
CHANGED
|
@@ -67,14 +67,7 @@ export default function HTable({
|
|
|
67
67
|
|
|
68
68
|
const isDate = !isObject && regex.test(`${d[key]}`);
|
|
69
69
|
const cellTypeOf = isDate ? "date" : isObject ? "object" : typeOf;
|
|
70
|
-
const
|
|
71
|
-
`${d.id}`.includes(
|
|
72
|
-
(mpd?.id as any)?.content,
|
|
73
|
-
(mpd?._id as any)?.content
|
|
74
|
-
)
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
const mapedContent = (mapedIndex?.[key] as any)?.content;
|
|
70
|
+
const mapedContent = (mapedData[trkey][key] as any)?.content;
|
|
78
71
|
|
|
79
72
|
const content =
|
|
80
73
|
mapedContent ||
|
|
@@ -145,43 +138,41 @@ export default function HTable({
|
|
|
145
138
|
)}
|
|
146
139
|
</div>
|
|
147
140
|
<table {...props} className="w-full border-collapse table-auto">
|
|
148
|
-
<thead className="bg-
|
|
141
|
+
<thead className="bg-gray-800 text-white">
|
|
149
142
|
<tr>
|
|
150
143
|
{head.map((h, key) => {
|
|
151
144
|
return (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
145
|
+
<th
|
|
146
|
+
key={h}
|
|
147
|
+
className="whitespace-nowrap overflow-hidden text-ellipsis max-w-[200px] border-b p-2"
|
|
148
|
+
>
|
|
149
|
+
<div
|
|
150
|
+
className="cursor-pointer flex "
|
|
151
|
+
onClick={(e) => {
|
|
152
|
+
setSelectedFilter(key == selectedFilter ? null : key);
|
|
153
|
+
}}
|
|
156
154
|
>
|
|
157
|
-
<div
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
?.map((d: any) => d[h]?.exclude)
|
|
167
|
-
?.every((d: any) => d === false) && (
|
|
168
|
-
<div className="text-red-300">
|
|
169
|
-
<FilterOffIcon />
|
|
170
|
-
</div>
|
|
171
|
-
)}
|
|
172
|
-
</div>
|
|
155
|
+
<div className="text-white w-full bg-black rounded flex justify-center">
|
|
156
|
+
{h}{" "}
|
|
157
|
+
{!mapedData
|
|
158
|
+
?.map((d: any) => d[h]?.exclude)
|
|
159
|
+
?.every((d: any) => d === false) && (
|
|
160
|
+
<div className="text-red-300">
|
|
161
|
+
<FilterOffIcon />
|
|
162
|
+
</div>
|
|
163
|
+
)}
|
|
173
164
|
</div>
|
|
165
|
+
</div>
|
|
174
166
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
)
|
|
167
|
+
<FilterMenu
|
|
168
|
+
h={h}
|
|
169
|
+
mapedData={mapedData}
|
|
170
|
+
setMapedData={setMapedData}
|
|
171
|
+
index={key}
|
|
172
|
+
selectedFilter={selectedFilter}
|
|
173
|
+
setSelectedFilter={setSelectedFilter}
|
|
174
|
+
/>
|
|
175
|
+
</th>
|
|
185
176
|
);
|
|
186
177
|
})}
|
|
187
178
|
</tr>
|
|
@@ -201,7 +192,7 @@ export default function HTable({
|
|
|
201
192
|
return null;
|
|
202
193
|
}
|
|
203
194
|
}
|
|
204
|
-
const dataKey = md?.
|
|
195
|
+
const dataKey = md?.id?.content || trKey;
|
|
205
196
|
|
|
206
197
|
return (
|
|
207
198
|
<tr
|
|
@@ -212,32 +203,24 @@ export default function HTable({
|
|
|
212
203
|
key={dataKey}
|
|
213
204
|
onClick={(e) => setSelected(trKey)}
|
|
214
205
|
className={[
|
|
215
|
-
"hover:bg-
|
|
206
|
+
"hover:bg-green-100 ",
|
|
216
207
|
color,
|
|
217
|
-
selected == trKey && "
|
|
208
|
+
selected == trKey && "bg-green-200 hover:bg-green-300",
|
|
218
209
|
].join(" ")}
|
|
219
210
|
>
|
|
220
211
|
{head.map((h, tdKey: number) => {
|
|
221
212
|
const item = md[h];
|
|
222
|
-
const id =
|
|
223
|
-
trKey +
|
|
224
|
-
"-" +
|
|
225
|
-
(md?.["_id"]?.content || md?.id?.content || tdKey) +
|
|
226
|
-
"-" +
|
|
227
|
-
h;
|
|
213
|
+
const id = trKey + "-" + (md?.id?.content || tdKey) + "-" + h;
|
|
228
214
|
return (
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
setMapedData={setMapedData}
|
|
239
|
-
/>
|
|
240
|
-
)
|
|
215
|
+
<TD
|
|
216
|
+
key={id}
|
|
217
|
+
index={trKey}
|
|
218
|
+
symbols={symbols}
|
|
219
|
+
item={item}
|
|
220
|
+
color={color}
|
|
221
|
+
mapedData={mapedData}
|
|
222
|
+
setMapedData={setMapedData}
|
|
223
|
+
/>
|
|
241
224
|
);
|
|
242
225
|
})}
|
|
243
226
|
</tr>
|
|
@@ -245,13 +228,16 @@ export default function HTable({
|
|
|
245
228
|
})}
|
|
246
229
|
</tbody>
|
|
247
230
|
{totals && (
|
|
248
|
-
<tfoot className="bg-
|
|
231
|
+
<tfoot className="bg-gray-800 text-white">
|
|
249
232
|
<tr>
|
|
250
233
|
{head.map((h, fkey) => {
|
|
251
234
|
return (
|
|
252
|
-
<th
|
|
235
|
+
<th
|
|
236
|
+
key={fkey}
|
|
237
|
+
className="text-right border-b max-w-[200px] p-2 "
|
|
238
|
+
>
|
|
253
239
|
{totals.includes(h) && (
|
|
254
|
-
<div className="flex justify-between text-white w-full rounded ">
|
|
240
|
+
<div className="flex justify-between text-white w-full bg-black rounded ">
|
|
255
241
|
<div className="p-1">
|
|
256
242
|
{symbols && symbols[h] && symbols[h]}
|
|
257
243
|
</div>
|
package/src/table/td.tsx
CHANGED
|
@@ -84,38 +84,19 @@ export default function TD({
|
|
|
84
84
|
{ ...symbols[item?.name]?.props }
|
|
85
85
|
);
|
|
86
86
|
|
|
87
|
-
const typeOf = (value: any): string => {
|
|
88
|
-
if (value instanceof Date) return "date";
|
|
89
|
-
if (typeof value === "number") return "number";
|
|
90
|
-
if (typeof value === "string") {
|
|
91
|
-
// validar si es fecha en string
|
|
92
|
-
const d = new Date(value);
|
|
93
|
-
if (!isNaN(d.getTime())) return "date-string";
|
|
94
|
-
return "string";
|
|
95
|
-
}
|
|
96
|
-
return typeof value;
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const result = typeOf(item?.content);
|
|
100
|
-
|
|
101
87
|
return (
|
|
102
88
|
<td
|
|
103
|
-
{...props}
|
|
104
89
|
onDoubleClick={(e) => setIsHidded(!isHidded)}
|
|
105
90
|
// title={item?.title}
|
|
106
91
|
className={[
|
|
107
92
|
isHidded && color,
|
|
108
|
-
!isHidded && "whitespace-nowrap overflow-hidden text-ellipsis
|
|
109
|
-
"
|
|
93
|
+
!isHidded && "whitespace-nowrap overflow-hidden text-ellipsis ",
|
|
94
|
+
"border-b max-w-[200px] p-2 ",
|
|
95
|
+
// ["number", "money"].includes(item?.cellTypeOf) && "text-right",
|
|
110
96
|
].join(" ")}
|
|
111
97
|
>
|
|
112
98
|
<div
|
|
113
|
-
className={
|
|
114
|
-
symbols && symbols?.[item?.name]
|
|
115
|
-
? symbols[item?.name]
|
|
116
|
-
: " flex " +
|
|
117
|
-
(result == "number" ? "justify-end" : "justify-start")
|
|
118
|
-
}
|
|
99
|
+
className={symbols && symbols[item?.name] && "flex justify-between "}
|
|
119
100
|
>
|
|
120
101
|
{symbols ? (
|
|
121
102
|
<div className="flex items-center justify-between gap-1">
|
|
@@ -133,7 +114,7 @@ export default function TD({
|
|
|
133
114
|
<div>{!newProps?.["row"] && item?.content}</div>
|
|
134
115
|
</div>
|
|
135
116
|
) : (
|
|
136
|
-
<div
|
|
117
|
+
<div>{item?.content}</div>
|
|
137
118
|
)}
|
|
138
119
|
</div>
|
|
139
120
|
</td>
|
package/src/table/vtd.tsx
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import TR from "./tr";
|
|
3
|
+
|
|
4
|
+
export default function TableBody({
|
|
5
|
+
objectData,
|
|
6
|
+
setObjectData,
|
|
7
|
+
headers,
|
|
8
|
+
handlers,
|
|
9
|
+
selectItems,
|
|
10
|
+
page,
|
|
11
|
+
maxItems,
|
|
12
|
+
colSizes,
|
|
13
|
+
modal,
|
|
14
|
+
modalRef,
|
|
15
|
+
dialogRow,
|
|
16
|
+
setDialogRow,
|
|
17
|
+
onChange,
|
|
18
|
+
}: {
|
|
19
|
+
objectData: any;
|
|
20
|
+
setObjectData: any;
|
|
21
|
+
headers: string[];
|
|
22
|
+
handlers: Record<string, any>;
|
|
23
|
+
selectItems?: boolean;
|
|
24
|
+
page: number;
|
|
25
|
+
maxItems?: number;
|
|
26
|
+
colSizes?: Record<string, number>;
|
|
27
|
+
modal?: React.ReactNode;
|
|
28
|
+
modalRef: React.RefObject<HTMLDialogElement>;
|
|
29
|
+
dialogRow: any;
|
|
30
|
+
setDialogRow: any;
|
|
31
|
+
onChange?: any;
|
|
32
|
+
}) {
|
|
33
|
+
const [selected, setSelected] = useState(-1);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<tbody>
|
|
37
|
+
{Object.keys(objectData)
|
|
38
|
+
.reverse()
|
|
39
|
+
.filter((id) => {
|
|
40
|
+
return objectData[id]?._visible === true;
|
|
41
|
+
})
|
|
42
|
+
.filter((_id, key) => {
|
|
43
|
+
if (!maxItems) return true;
|
|
44
|
+
const start = (page - 1) * maxItems; // ej: 0 en la página 1
|
|
45
|
+
const end = page * maxItems; // ej: 10 en la página 1
|
|
46
|
+
return key >= start && key < end; // 👈 usamos < en vez de <=
|
|
47
|
+
})
|
|
48
|
+
.map((id, index) => {
|
|
49
|
+
const row = objectData[id];
|
|
50
|
+
return (
|
|
51
|
+
<TR
|
|
52
|
+
key={id}
|
|
53
|
+
{...{
|
|
54
|
+
headers,
|
|
55
|
+
index,
|
|
56
|
+
setObjectData,
|
|
57
|
+
id,
|
|
58
|
+
row,
|
|
59
|
+
handlers,
|
|
60
|
+
selectItems,
|
|
61
|
+
colSizes,
|
|
62
|
+
modal,
|
|
63
|
+
modalRef,
|
|
64
|
+
dialogRow,
|
|
65
|
+
setDialogRow,
|
|
66
|
+
setSelected,
|
|
67
|
+
selected,
|
|
68
|
+
onChange,
|
|
69
|
+
}}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
})}
|
|
73
|
+
</tbody>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
function Dialog({
|
|
4
|
+
modalRef,
|
|
5
|
+
children,
|
|
6
|
+
dialogRow,
|
|
7
|
+
setDialogRow,
|
|
8
|
+
setObjectData,
|
|
9
|
+
}: {
|
|
10
|
+
modalRef: React.RefObject<HTMLDialogElement>;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
dialogRow: any;
|
|
13
|
+
setDialogRow: any;
|
|
14
|
+
setObjectData: any;
|
|
15
|
+
}) {
|
|
16
|
+
const show = () => modalRef.current?.showModal();
|
|
17
|
+
const hide = () => modalRef.current?.close();
|
|
18
|
+
const clonedModal = useMemo(() => {
|
|
19
|
+
if (dialogRow && React.isValidElement(children)) {
|
|
20
|
+
return React.cloneElement(children, {
|
|
21
|
+
key: JSON.stringify(dialogRow),
|
|
22
|
+
row: dialogRow,
|
|
23
|
+
show,
|
|
24
|
+
hide,
|
|
25
|
+
update: setObjectData,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}, [dialogRow, children]);
|
|
30
|
+
return (
|
|
31
|
+
<dialog
|
|
32
|
+
ref={modalRef}
|
|
33
|
+
className="p-6 rounded-xl shadow-2xl backdrop:bg-black/50 w-[100%] h-screen"
|
|
34
|
+
>
|
|
35
|
+
<div className="flex justify-between items-center mb-4">
|
|
36
|
+
<div></div>
|
|
37
|
+
<button
|
|
38
|
+
onClick={() => modalRef.current?.close()}
|
|
39
|
+
className="text-white hover:text-gray-100 text-xl border shadow rounded p-1 bg-red-500"
|
|
40
|
+
>
|
|
41
|
+
✕
|
|
42
|
+
</button>
|
|
43
|
+
</div>
|
|
44
|
+
<div className="text-gray-700">{clonedModal}</div>
|
|
45
|
+
</dialog>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default Dialog;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { FilterOffIcon } from "../../src/table/filters";
|
|
4
|
+
|
|
5
|
+
export default function Filter({
|
|
6
|
+
h,
|
|
7
|
+
objectData,
|
|
8
|
+
setObjectData,
|
|
9
|
+
setPage,
|
|
10
|
+
colSizes,
|
|
11
|
+
}: {
|
|
12
|
+
h: any;
|
|
13
|
+
objectData: any;
|
|
14
|
+
setObjectData: any;
|
|
15
|
+
setPage: any;
|
|
16
|
+
colSizes?: Record<string, number>;
|
|
17
|
+
}) {
|
|
18
|
+
const [visible, setVisible] = useState(false);
|
|
19
|
+
const [text, setText] = useState("");
|
|
20
|
+
const items = useMemo(
|
|
21
|
+
() => [...new Set(Object.values(objectData).map((o: any) => o[h]))],
|
|
22
|
+
[objectData]
|
|
23
|
+
);
|
|
24
|
+
const [selected, setSelected] = useState<string[]>(items);
|
|
25
|
+
|
|
26
|
+
const itemsFiltered = useMemo(
|
|
27
|
+
() =>
|
|
28
|
+
items
|
|
29
|
+
.sort((a, b) => `${a}`.localeCompare(b))
|
|
30
|
+
.filter((item: string) => {
|
|
31
|
+
if (!text) return true;
|
|
32
|
+
|
|
33
|
+
return `${item}`.toLowerCase().includes(text.toLowerCase());
|
|
34
|
+
}),
|
|
35
|
+
[items, text]
|
|
36
|
+
);
|
|
37
|
+
function filtrar(itemsInterno: any[] = []) {
|
|
38
|
+
const array = Object.values(objectData);
|
|
39
|
+
let obj;
|
|
40
|
+
if (itemsInterno.length > 0) {
|
|
41
|
+
setSelected(items);
|
|
42
|
+
obj = array.map((row: any) => {
|
|
43
|
+
return row?._id
|
|
44
|
+
? {
|
|
45
|
+
_id: row._id,
|
|
46
|
+
_visible: itemsInterno.includes(row[h]),
|
|
47
|
+
}
|
|
48
|
+
: { id: row.id, _visible: itemsInterno.includes(row[h]) };
|
|
49
|
+
});
|
|
50
|
+
} else {
|
|
51
|
+
obj = array.map((row: any) => {
|
|
52
|
+
return row?._id
|
|
53
|
+
? {
|
|
54
|
+
_id: row._id,
|
|
55
|
+
_visible:
|
|
56
|
+
itemsFiltered.length < items.length
|
|
57
|
+
? itemsFiltered.includes(row[h])
|
|
58
|
+
: selected.includes(row[h]),
|
|
59
|
+
}
|
|
60
|
+
: {
|
|
61
|
+
id: row.id,
|
|
62
|
+
_visible:
|
|
63
|
+
itemsFiltered.length < items.length
|
|
64
|
+
? itemsFiltered.includes(row[h])
|
|
65
|
+
: selected.includes(row[h]),
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setObjectData(obj);
|
|
71
|
+
setPage(1);
|
|
72
|
+
setVisible(false);
|
|
73
|
+
setText("");
|
|
74
|
+
}
|
|
75
|
+
const hidden = Object.values(objectData)
|
|
76
|
+
.filter((d: any) => d._visible === false)
|
|
77
|
+
.map((d: any) => d[h]);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<th className="cursor-pointer">
|
|
81
|
+
<div className="relative">
|
|
82
|
+
{visible && (
|
|
83
|
+
<div
|
|
84
|
+
className=" w-full h-screen top-0 left-0 fixed"
|
|
85
|
+
style={{ zIndex: 9998 }}
|
|
86
|
+
onClick={(e) => setVisible(!visible)}
|
|
87
|
+
></div>
|
|
88
|
+
)}
|
|
89
|
+
</div>
|
|
90
|
+
<div className="relative w-full justify-center flex">
|
|
91
|
+
<div
|
|
92
|
+
style={{
|
|
93
|
+
minWidth: "100px",
|
|
94
|
+
maxWidth: `${(colSizes?.[h] || 0) + 100}px`,
|
|
95
|
+
width: `${colSizes?.[h]}px`,
|
|
96
|
+
}}
|
|
97
|
+
className={`resize-x overflow-auto text-center flex justify-evenly p-1 items-center`}
|
|
98
|
+
onClick={(e) => setVisible(!visible)}
|
|
99
|
+
>
|
|
100
|
+
<div>{h}</div>
|
|
101
|
+
{selected.length < items.length && (
|
|
102
|
+
<div className="text-red-500 ">
|
|
103
|
+
<FilterOffIcon />
|
|
104
|
+
</div>
|
|
105
|
+
)}
|
|
106
|
+
</div>
|
|
107
|
+
{visible && (
|
|
108
|
+
<div
|
|
109
|
+
className="border shadow rounded bg-white p-1 absolute fixed text-black"
|
|
110
|
+
style={{ zIndex: 9999 }}
|
|
111
|
+
>
|
|
112
|
+
<div className="flex flex-col gap-1 w-[300px] min-w-[300px] resize-x overflow-auto">
|
|
113
|
+
{selected.length < items.length && (
|
|
114
|
+
<div
|
|
115
|
+
className="p-1 flex items-center justify-between px-2 bg-red-200 border shadow rounded"
|
|
116
|
+
onClick={(e) => {
|
|
117
|
+
filtrar(items);
|
|
118
|
+
}}
|
|
119
|
+
>
|
|
120
|
+
Borrar Filtro{" "}
|
|
121
|
+
<div className="text-white ">
|
|
122
|
+
<FilterOffIcon />
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
)}
|
|
126
|
+
<div className="">
|
|
127
|
+
<input
|
|
128
|
+
className="border shadow rounded p-2 w-full"
|
|
129
|
+
type="search"
|
|
130
|
+
onChange={(e) => setText(`${e.target.value}`)}
|
|
131
|
+
value={text}
|
|
132
|
+
onKeyDown={(e) => {
|
|
133
|
+
if (e.key === "Enter") {
|
|
134
|
+
setSelected(
|
|
135
|
+
items.filter((i) =>
|
|
136
|
+
`${i}`.toLowerCase().includes(`${text}`.toLowerCase())
|
|
137
|
+
)
|
|
138
|
+
);
|
|
139
|
+
filtrar();
|
|
140
|
+
}
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
<div>
|
|
145
|
+
<label className="flex gap-1 cursor-pointer px-1">
|
|
146
|
+
<input
|
|
147
|
+
type="checkbox"
|
|
148
|
+
checked={!Boolean(selected.length < items.length)}
|
|
149
|
+
onChange={(e) => {
|
|
150
|
+
if (selected.length < items.length) {
|
|
151
|
+
setSelected(items);
|
|
152
|
+
} else {
|
|
153
|
+
setSelected([]);
|
|
154
|
+
}
|
|
155
|
+
}}
|
|
156
|
+
/>
|
|
157
|
+
(Seleccionar Todo)
|
|
158
|
+
</label>
|
|
159
|
+
</div>
|
|
160
|
+
<div className="overflow-auto flex gap-1 flex-col p-1 border shadow rounded h-[300px]">
|
|
161
|
+
{itemsFiltered.map((item) => {
|
|
162
|
+
return (
|
|
163
|
+
<div key={item} className="hover:bg-gray-100 ">
|
|
164
|
+
<label className="flex gap-1 cursor-pointer truncate">
|
|
165
|
+
<input
|
|
166
|
+
type="checkbox"
|
|
167
|
+
disabled={
|
|
168
|
+
hidden.includes(item) && items.includes(item)
|
|
169
|
+
}
|
|
170
|
+
checked={selected.includes(item)}
|
|
171
|
+
onChange={(e) => {
|
|
172
|
+
const newSelected = [...selected];
|
|
173
|
+
const index = newSelected.indexOf(item);
|
|
174
|
+
if (index >= 0) {
|
|
175
|
+
newSelected.splice(index, 1);
|
|
176
|
+
} else {
|
|
177
|
+
newSelected.push(item);
|
|
178
|
+
}
|
|
179
|
+
setSelected(newSelected);
|
|
180
|
+
}}
|
|
181
|
+
/>
|
|
182
|
+
{item || "(Vacias)"}
|
|
183
|
+
</label>
|
|
184
|
+
</div>
|
|
185
|
+
);
|
|
186
|
+
})}
|
|
187
|
+
</div>
|
|
188
|
+
<div className="flex justify-between px-1">
|
|
189
|
+
<button
|
|
190
|
+
className="p-1 shadow rounded border bg-red-500 text-white"
|
|
191
|
+
onClick={(e) => {
|
|
192
|
+
setText("");
|
|
193
|
+
setVisible(false);
|
|
194
|
+
}}
|
|
195
|
+
>
|
|
196
|
+
Cancelar
|
|
197
|
+
</button>
|
|
198
|
+
<button
|
|
199
|
+
className="p-1 shadow rounded border bg-blue-500 text-white"
|
|
200
|
+
onClick={(e) => {
|
|
201
|
+
filtrar();
|
|
202
|
+
}}
|
|
203
|
+
>
|
|
204
|
+
Aceptar
|
|
205
|
+
</button>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
)}
|
|
210
|
+
</div>
|
|
211
|
+
</th>
|
|
212
|
+
);
|
|
213
|
+
}
|