@axzydev/axzy_ui_system 1.3.3 → 1.3.4
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.cjs +967 -810
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -8
- package/dist/index.d.ts +49 -8
- package/dist/index.js +899 -742
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/molecules/table/table.doc.mdx +11 -0
- package/src/components/molecules/table/table.props.ts +30 -2
- package/src/components/molecules/table/table.stories.tsx +30 -0
- package/src/components/molecules/table/table.tsx +103 -7
- package/src/components/organisms/data-table/ITDataTable.doc.mdx +11 -2
- package/src/components/organisms/data-table/ITDataTable.stories.tsx +73 -0
- package/src/components/organisms/data-table/dataTable.props.ts +8 -4
- package/src/components/organisms/data-table/dataTable.tsx +72 -0
- package/src/hooks/useTableState.ts +17 -11
- package/src/index.ts +3 -3
- package/src/showcases/DataShowcases.tsx +156 -21
- package/src/types/table.types.ts +17 -0
package/dist/index.js
CHANGED
|
@@ -233,6 +233,11 @@ function useFloatingPanel(anchorRef, isOpen, {
|
|
|
233
233
|
|
|
234
234
|
// src/hooks/useTableState.ts
|
|
235
235
|
import { useCallback as useCallback4, useMemo as useMemo2, useState as useState4 } from "react";
|
|
236
|
+
var isEmptyFilterValue = (value) => {
|
|
237
|
+
if (value === void 0 || value === null || value === "") return true;
|
|
238
|
+
if (Array.isArray(value)) return value[0] == null && value[1] == null;
|
|
239
|
+
return false;
|
|
240
|
+
};
|
|
236
241
|
function useTableState({
|
|
237
242
|
defaultItemsPerPage = 10,
|
|
238
243
|
initialSort = null
|
|
@@ -257,7 +262,7 @@ function useTableState({
|
|
|
257
262
|
const handleFilterChange = useCallback4(
|
|
258
263
|
(key, value) => {
|
|
259
264
|
setFilters((prev) => {
|
|
260
|
-
if (value
|
|
265
|
+
if (isEmptyFilterValue(value)) {
|
|
261
266
|
const next = { ...prev };
|
|
262
267
|
delete next[key];
|
|
263
268
|
return next;
|
|
@@ -3595,9 +3600,9 @@ function useVirtualRows({
|
|
|
3595
3600
|
}
|
|
3596
3601
|
|
|
3597
3602
|
// src/components/organisms/data-table/dataTable.tsx
|
|
3598
|
-
import
|
|
3599
|
-
import { useState as
|
|
3600
|
-
import { FaCheck as FaCheck2, FaSpinner, FaTimes as
|
|
3603
|
+
import clsx23 from "clsx";
|
|
3604
|
+
import { useState as useState19, useEffect as useEffect9, useCallback as useCallback7, useRef as useRef13 } from "react";
|
|
3605
|
+
import { FaCheck as FaCheck2, FaSpinner, FaTimes as FaTimes5, FaTable, FaThLarge } from "react-icons/fa";
|
|
3601
3606
|
import { MdOutlineSwapVert } from "react-icons/md";
|
|
3602
3607
|
|
|
3603
3608
|
// src/components/molecules/pagination/pagination.tsx
|
|
@@ -3890,445 +3895,240 @@ function ITPagination({
|
|
|
3890
3895
|
return /* @__PURE__ */ jsx20("nav", { "aria-label": "Pagination", className: clsx20("inline-flex", className), children: renderPaginationControls() });
|
|
3891
3896
|
}
|
|
3892
3897
|
|
|
3893
|
-
// src/
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
}
|
|
3911
|
-
|
|
3912
|
-
// src/components/organisms/data-table/dataTable.tsx
|
|
3913
|
-
import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3914
|
-
var getNestedValue2 = (obj, path) => {
|
|
3915
|
-
return path.split(".").reduce((acc, part) => acc && acc[part], obj);
|
|
3916
|
-
};
|
|
3917
|
-
var EMPTY_OBJECT = {};
|
|
3918
|
-
function ITDataTable({
|
|
3919
|
-
columns,
|
|
3920
|
-
fetchData,
|
|
3921
|
-
debounceMs = 500,
|
|
3922
|
-
externalFilters = EMPTY_OBJECT,
|
|
3923
|
-
loadingIndicator,
|
|
3924
|
-
fetchOnMount = true,
|
|
3925
|
-
reloadTrigger,
|
|
3926
|
-
containerClassName,
|
|
3898
|
+
// src/components/molecules/search-select/search-select.tsx
|
|
3899
|
+
import { useState as useState17, useEffect as useEffect7, useRef as useRef11, useMemo as useMemo7 } from "react";
|
|
3900
|
+
import { createPortal as createPortal3 } from "react-dom";
|
|
3901
|
+
import clsx21 from "clsx";
|
|
3902
|
+
import { FaSearch as FaSearch2, FaTimes as FaTimes4 } from "react-icons/fa";
|
|
3903
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3904
|
+
function ITSearchSelect({
|
|
3905
|
+
name,
|
|
3906
|
+
options = [],
|
|
3907
|
+
label,
|
|
3908
|
+
placeholder = "Selecciona una opci\xF3n",
|
|
3909
|
+
valueField = "value",
|
|
3910
|
+
labelField = "label",
|
|
3911
|
+
value,
|
|
3912
|
+
onChange,
|
|
3913
|
+
onBlur,
|
|
3914
|
+
disabled = false,
|
|
3927
3915
|
className,
|
|
3928
|
-
|
|
3916
|
+
touched,
|
|
3917
|
+
required,
|
|
3918
|
+
error,
|
|
3919
|
+
readOnly = false,
|
|
3920
|
+
onSearch,
|
|
3921
|
+
isLoading = false,
|
|
3922
|
+
noResultsMessage = "No se encontraron resultados",
|
|
3929
3923
|
size = "md",
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
renderCard,
|
|
3934
|
-
defaultView,
|
|
3935
|
-
showVerticalBorder = true,
|
|
3936
|
-
verticalBorderClassname,
|
|
3937
|
-
onRowClick,
|
|
3938
|
-
layout = "auto",
|
|
3939
|
-
density = "normal",
|
|
3940
|
-
autoCardBreakpoint = 0,
|
|
3941
|
-
virtualized = false,
|
|
3942
|
-
virtualizedMaxHeight = 400,
|
|
3943
|
-
rowHeight,
|
|
3944
|
-
overscan = 5,
|
|
3945
|
-
stickyHeader = false
|
|
3924
|
+
renderOption,
|
|
3925
|
+
clearable = true,
|
|
3926
|
+
onClear
|
|
3946
3927
|
}) {
|
|
3947
|
-
const [
|
|
3948
|
-
const
|
|
3949
|
-
const [
|
|
3950
|
-
const [
|
|
3951
|
-
const
|
|
3952
|
-
const
|
|
3953
|
-
const
|
|
3954
|
-
const
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
const isTableVirtual = virtualized && effectiveView === "table";
|
|
3958
|
-
const isStickyHeader = stickyHeader && isTableVirtual;
|
|
3959
|
-
const resolvedRowHeight = rowHeight ?? getRowHeight(size, density);
|
|
3960
|
-
const columnCount = columns.length;
|
|
3961
|
-
const scrollOuterClass = isTableVirtual ? "relative min-h-[200px]" : "overflow-x-auto relative min-h-[200px]";
|
|
3962
|
-
const {
|
|
3963
|
-
currentPage,
|
|
3964
|
-
itemsPerPage,
|
|
3965
|
-
filters,
|
|
3966
|
-
sortConfig,
|
|
3967
|
-
goToPage,
|
|
3968
|
-
handleFilterChange,
|
|
3969
|
-
handleSort,
|
|
3970
|
-
handleItemsPerPageChange
|
|
3971
|
-
} = useTableState({ defaultItemsPerPage });
|
|
3972
|
-
const {
|
|
3973
|
-
scrollRef,
|
|
3974
|
-
startIndex,
|
|
3975
|
-
endIndex,
|
|
3976
|
-
topSpacerHeight,
|
|
3977
|
-
bottomSpacerHeight
|
|
3978
|
-
} = useVirtualRows({
|
|
3979
|
-
count: data.length,
|
|
3980
|
-
rowHeight: resolvedRowHeight,
|
|
3981
|
-
overscan,
|
|
3982
|
-
enabled: isTableVirtual,
|
|
3983
|
-
resetKey: `${currentPage}-${itemsPerPage}`
|
|
3928
|
+
const [isOpen, setIsOpen] = useState17(false);
|
|
3929
|
+
const [searchTerm, setSearchTerm] = useState17("");
|
|
3930
|
+
const [isFocused, setIsFocused] = useState17(false);
|
|
3931
|
+
const [localTouched, setLocalTouched] = useState17(false);
|
|
3932
|
+
const containerRef = useRef11(null);
|
|
3933
|
+
const inputWrapperRef = useRef11(null);
|
|
3934
|
+
const timeoutRef = useRef11(null);
|
|
3935
|
+
const { panelRef, style: panelStyle } = useFloatingPanel(inputWrapperRef, isOpen, {
|
|
3936
|
+
estimatedHeight: 260,
|
|
3937
|
+
matchWidth: true
|
|
3984
3938
|
});
|
|
3985
|
-
const
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
const fetchDataRef = useRef11(fetchData);
|
|
3989
|
-
fetchDataRef.current = fetchData;
|
|
3990
|
-
const externalFiltersRef = useRef11(externalFilters);
|
|
3991
|
-
externalFiltersRef.current = externalFilters;
|
|
3992
|
-
const externalKey = JSON.stringify(externalFilters);
|
|
3993
|
-
const computedTotalPages = Math.ceil(totalItems / itemsPerPage) || 1;
|
|
3994
|
-
const performFetch = useCallback7(async () => {
|
|
3995
|
-
setIsLoading(true);
|
|
3996
|
-
try {
|
|
3997
|
-
const response = await fetchDataRef.current({
|
|
3998
|
-
page: currentPage,
|
|
3999
|
-
limit: itemsPerPage,
|
|
4000
|
-
filters: { ...filters, ...externalFiltersRef.current },
|
|
4001
|
-
sort: sortConfig || void 0
|
|
4002
|
-
});
|
|
4003
|
-
setData(response.data || []);
|
|
4004
|
-
setTotalItems(response.total || 0);
|
|
4005
|
-
hasFetchedRef.current = true;
|
|
4006
|
-
} catch (error) {
|
|
4007
|
-
console.error("ITDataTable: Error fetching data", error);
|
|
4008
|
-
setData([]);
|
|
4009
|
-
setTotalItems(0);
|
|
4010
|
-
hasFetchedRef.current = true;
|
|
4011
|
-
} finally {
|
|
4012
|
-
setIsLoading(false);
|
|
4013
|
-
}
|
|
4014
|
-
}, [currentPage, itemsPerPage, filters, sortConfig]);
|
|
4015
|
-
const performFetchRef = useRef11(performFetch);
|
|
4016
|
-
performFetchRef.current = performFetch;
|
|
3939
|
+
const selectedOption = useMemo7(() => {
|
|
3940
|
+
return options.find((opt) => opt[valueField] === value);
|
|
3941
|
+
}, [options, value, valueField]);
|
|
4017
3942
|
useEffect7(() => {
|
|
4018
|
-
if (!
|
|
4019
|
-
|
|
4020
|
-
debounceTimerRef.current = setTimeout(() => {
|
|
4021
|
-
performFetchRef.current();
|
|
4022
|
-
}, debounceMs);
|
|
4023
|
-
return () => {
|
|
4024
|
-
if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
|
|
4025
|
-
};
|
|
4026
|
-
}, [currentPage, itemsPerPage, sortConfig, filters, externalKey, reloadTrigger, fetchOnMount, debounceMs]);
|
|
4027
|
-
const renderFilterInput = (col) => {
|
|
4028
|
-
if (!col.filter) return null;
|
|
4029
|
-
if (col.type === "boolean") {
|
|
4030
|
-
const currentValue = filters[col.key];
|
|
4031
|
-
const nextValue = currentValue === void 0 ? true : currentValue === true ? false : void 0;
|
|
4032
|
-
const getToggleLabel = () => {
|
|
4033
|
-
if (currentValue === void 0) return "Mostrar todos";
|
|
4034
|
-
if (currentValue === true) return "Filtrar solo verdaderos";
|
|
4035
|
-
return "Filtrar solo falsos";
|
|
4036
|
-
};
|
|
4037
|
-
return /* @__PURE__ */ jsx21(
|
|
4038
|
-
"button",
|
|
4039
|
-
{
|
|
4040
|
-
className: "flex items-center justify-center cursor-pointer focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 rounded-full p-1 transition-all duration-200",
|
|
4041
|
-
onClick: () => handleFilterChange(col.key, nextValue),
|
|
4042
|
-
"aria-label": `${getToggleLabel()} para ${col.label}`,
|
|
4043
|
-
title: `${getToggleLabel()} para ${col.label}`,
|
|
4044
|
-
disabled: isLoading,
|
|
4045
|
-
children: /* @__PURE__ */ jsx21("div", { className: "relative w-10 h-5 bg-secondary-300 rounded-full", children: /* @__PURE__ */ jsx21(
|
|
4046
|
-
"div",
|
|
4047
|
-
{
|
|
4048
|
-
className: clsx21(
|
|
4049
|
-
"absolute top-0.5 w-4 h-4 rounded-full transition-all duration-300 shadow-sm",
|
|
4050
|
-
{
|
|
4051
|
-
"left-0.5 bg-secondary-400": currentValue === void 0,
|
|
4052
|
-
"left-5 bg-slate-500": currentValue === true,
|
|
4053
|
-
"left-0.5 bg-secondary-500": currentValue === false
|
|
4054
|
-
}
|
|
4055
|
-
)
|
|
4056
|
-
}
|
|
4057
|
-
) })
|
|
4058
|
-
}
|
|
4059
|
-
);
|
|
3943
|
+
if (!isFocused) {
|
|
3944
|
+
setSearchTerm(selectedOption ? String(selectedOption[labelField]) : "");
|
|
4060
3945
|
}
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
3946
|
+
}, [selectedOption, isFocused, labelField]);
|
|
3947
|
+
useEffect7(() => {
|
|
3948
|
+
function handleClickOutside(event) {
|
|
3949
|
+
const target = event.target;
|
|
3950
|
+
const inContainer = containerRef.current?.contains(target);
|
|
3951
|
+
const inPanel = panelRef.current?.contains(target);
|
|
3952
|
+
if (!inContainer && !inPanel) {
|
|
3953
|
+
setIsOpen(false);
|
|
4067
3954
|
}
|
|
4068
|
-
return /* @__PURE__ */ jsx21(
|
|
4069
|
-
ITSelect,
|
|
4070
|
-
{
|
|
4071
|
-
name: `filter-${col.key}`,
|
|
4072
|
-
options: [
|
|
4073
|
-
{ value: "", label: "Todos" },
|
|
4074
|
-
...col.catalogOptions.data.map((item) => ({
|
|
4075
|
-
value: String(item.id),
|
|
4076
|
-
label: item.name
|
|
4077
|
-
}))
|
|
4078
|
-
],
|
|
4079
|
-
value: String(filters[col.key] || ""),
|
|
4080
|
-
onChange: (e) => {
|
|
4081
|
-
const value = e.target.value === "" ? void 0 : e.target.value;
|
|
4082
|
-
handleFilterChange(col.key, value);
|
|
4083
|
-
},
|
|
4084
|
-
onBlur: () => {
|
|
4085
|
-
},
|
|
4086
|
-
className: "w-full text-xs",
|
|
4087
|
-
disabled: isLoading
|
|
4088
|
-
}
|
|
4089
|
-
);
|
|
4090
3955
|
}
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
},
|
|
4101
|
-
disabled: isLoading
|
|
4102
|
-
}
|
|
3956
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
3957
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
3958
|
+
}, []);
|
|
3959
|
+
const selectedLabel = selectedOption ? String(selectedOption[labelField]) : "";
|
|
3960
|
+
const filteredOptions = useMemo7(() => {
|
|
3961
|
+
if (onSearch) return options;
|
|
3962
|
+
if (!searchTerm || !isFocused || searchTerm === selectedLabel) return options;
|
|
3963
|
+
return options.filter(
|
|
3964
|
+
(opt) => String(opt[labelField]).toLowerCase().includes(searchTerm.toLowerCase())
|
|
4103
3965
|
);
|
|
3966
|
+
}, [options, searchTerm, selectedLabel, onSearch, labelField, isFocused]);
|
|
3967
|
+
const handleInputChange = (e) => {
|
|
3968
|
+
const query = e.target.value;
|
|
3969
|
+
setSearchTerm(query);
|
|
3970
|
+
setIsOpen(true);
|
|
3971
|
+
if (onSearch) {
|
|
3972
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
3973
|
+
timeoutRef.current = setTimeout(() => {
|
|
3974
|
+
onSearch(query);
|
|
3975
|
+
}, 500);
|
|
3976
|
+
}
|
|
4104
3977
|
};
|
|
4105
|
-
const
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
switch (col.type) {
|
|
4109
|
-
case "number":
|
|
4110
|
-
return typeof value === "number" && col.currencyMX ? formatCurrencyMX(value) : value;
|
|
4111
|
-
case "boolean":
|
|
4112
|
-
return value ? /* @__PURE__ */ jsx21(FaCheck2, { className: "text-success-500", "aria-label": "Verdadero", title: "Verdadero" }) : /* @__PURE__ */ jsx21(FaTimes4, { className: "text-danger-500", "aria-label": "Falso", title: "Falso" });
|
|
4113
|
-
case "actions":
|
|
4114
|
-
return col.actions ? col.actions(row) : null;
|
|
4115
|
-
case "catalog":
|
|
4116
|
-
if (col.catalogOptions) {
|
|
4117
|
-
const catalogItem = col.catalogOptions.data.find((item) => item.id === value);
|
|
4118
|
-
return catalogItem?.name || value;
|
|
4119
|
-
}
|
|
4120
|
-
return value;
|
|
4121
|
-
default:
|
|
4122
|
-
return value;
|
|
3978
|
+
const handleSelect = (option) => {
|
|
3979
|
+
if (onChange) {
|
|
3980
|
+
onChange(option[valueField], option);
|
|
4123
3981
|
}
|
|
3982
|
+
setSearchTerm(String(option[labelField]));
|
|
3983
|
+
setIsOpen(false);
|
|
4124
3984
|
};
|
|
4125
|
-
const
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
actionCol?.actions && /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-end gap-2 pt-2 border-t border-slate-100 dark:border-slate-700", children: actionCol.actions(row) })
|
|
4134
|
-
] });
|
|
3985
|
+
const handleClear = () => {
|
|
3986
|
+
setSearchTerm("");
|
|
3987
|
+
setIsOpen(true);
|
|
3988
|
+
if (onSearch) onSearch("");
|
|
3989
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
3990
|
+
onChange?.("", void 0);
|
|
3991
|
+
}
|
|
3992
|
+
onClear?.();
|
|
4135
3993
|
};
|
|
4136
|
-
const
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
3994
|
+
const handleFocus = () => {
|
|
3995
|
+
if (disabled || readOnly) return;
|
|
3996
|
+
setIsFocused(true);
|
|
3997
|
+
setIsOpen(true);
|
|
4140
3998
|
};
|
|
4141
|
-
const
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
3999
|
+
const handleInputBlur = (e) => {
|
|
4000
|
+
setTimeout(() => {
|
|
4001
|
+
setIsFocused(false);
|
|
4002
|
+
setLocalTouched(true);
|
|
4003
|
+
onBlur?.(e);
|
|
4004
|
+
}, 200);
|
|
4147
4005
|
};
|
|
4148
|
-
const
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
),
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4006
|
+
const inputTheme = theme.input || {};
|
|
4007
|
+
const isTouched = touched !== void 0 ? touched : localTouched;
|
|
4008
|
+
const isEmpty = value === void 0 || value === null || String(value).trim() === "";
|
|
4009
|
+
const effectiveError = error !== void 0 && error !== false ? error === true ? "Este campo es requerido" : error : required && isEmpty ? "Este campo es requerido" : void 0;
|
|
4010
|
+
const hasError = isTouched && !!effectiveError;
|
|
4011
|
+
const errorMessage = typeof effectiveError === "string" ? effectiveError : "Este campo es requerido";
|
|
4012
|
+
const showClearButton = clearable && !disabled && !readOnly && (searchTerm.length > 0 || !isEmpty);
|
|
4013
|
+
const getInputStyle = () => {
|
|
4014
|
+
const sizeConfig = inputSizeTokens[size] ?? inputSizeTokens.md;
|
|
4015
|
+
const style = {
|
|
4016
|
+
backgroundColor: inputTheme.backgroundColor || "#ffffff",
|
|
4017
|
+
borderColor: inputTheme.borderColor || "var(--color-secondary-300)",
|
|
4018
|
+
borderRadius: inputTheme.borderRadius || "0.5rem",
|
|
4019
|
+
padding: sizeConfig.padding,
|
|
4020
|
+
fontSize: sizeConfig.fontSize,
|
|
4021
|
+
borderWidth: "1px",
|
|
4022
|
+
borderStyle: "solid",
|
|
4023
|
+
transition: "all 0.2s",
|
|
4024
|
+
color: "var(--it-input-text-color, var(--color-secondary-900))",
|
|
4025
|
+
width: "100%"
|
|
4026
|
+
};
|
|
4027
|
+
if (disabled) {
|
|
4028
|
+
style.backgroundColor = inputTheme.disabled?.backgroundColor || "var(--color-secondary-100)";
|
|
4029
|
+
style.borderColor = inputTheme.disabled?.borderColor || "var(--color-secondary-200)";
|
|
4030
|
+
style.opacity = 0.7;
|
|
4031
|
+
style.cursor = "not-allowed";
|
|
4032
|
+
}
|
|
4033
|
+
if (hasError) {
|
|
4034
|
+
style.borderColor = inputTheme.error?.borderColor || "red";
|
|
4035
|
+
if (isFocused) {
|
|
4036
|
+
style.boxShadow = inputTheme.error?.ring;
|
|
4037
|
+
}
|
|
4038
|
+
} else if (isFocused && !readOnly) {
|
|
4039
|
+
style.boxShadow = inputTheme.focus?.ring;
|
|
4040
|
+
style.borderColor = inputTheme.focus?.borderColor;
|
|
4041
|
+
}
|
|
4042
|
+
return style;
|
|
4043
|
+
};
|
|
4044
|
+
return /* @__PURE__ */ jsxs18("div", { className: clsx21("w-full flex flex-col gap-1.5", className, isOpen && "relative z-30"), ref: containerRef, children: [
|
|
4045
|
+
label && /* @__PURE__ */ jsxs18(
|
|
4046
|
+
ITText,
|
|
4047
|
+
{
|
|
4048
|
+
as: "label",
|
|
4049
|
+
className: clsx21("text-sm font-medium text-secondary-700 dark:text-slate-300", {
|
|
4050
|
+
"text-danger-500": hasError
|
|
4051
|
+
}),
|
|
4052
|
+
children: [
|
|
4053
|
+
/* @__PURE__ */ jsx21(ITText, { as: "span", children: label }),
|
|
4054
|
+
required && /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-danger-500 ml-1", children: "*" })
|
|
4055
|
+
]
|
|
4056
|
+
}
|
|
4057
|
+
),
|
|
4058
|
+
/* @__PURE__ */ jsxs18("div", { className: "relative", children: [
|
|
4059
|
+
/* @__PURE__ */ jsxs18("div", { ref: inputWrapperRef, className: "relative flex items-center", children: [
|
|
4060
|
+
/* @__PURE__ */ jsx21(
|
|
4061
|
+
"input",
|
|
4172
4062
|
{
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
|
|
4186
|
-
...isStickyHeader ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {}
|
|
4187
|
-
} : void 0,
|
|
4188
|
-
children: /* @__PURE__ */ jsxs18("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
|
|
4189
|
-
/* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-2", children: [
|
|
4190
|
-
/* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
|
|
4191
|
-
col.sortable && col.type !== "actions" && /* @__PURE__ */ jsx21(
|
|
4192
|
-
"button",
|
|
4193
|
-
{
|
|
4194
|
-
onClick: () => handleSort(col.key),
|
|
4195
|
-
disabled: isLoading,
|
|
4196
|
-
className: `p-1 rounded-md transition-colors ${sortConfig?.key === col.key ? "bg-secondary-200 text-secondary-900" : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"} disabled:opacity-50`,
|
|
4197
|
-
title: `Ordenar por ${col.label}`,
|
|
4198
|
-
children: /* @__PURE__ */ jsx21(MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
|
|
4199
|
-
}
|
|
4200
|
-
)
|
|
4201
|
-
] }),
|
|
4202
|
-
/* @__PURE__ */ jsx21("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
|
|
4203
|
-
] })
|
|
4204
|
-
},
|
|
4205
|
-
col.key
|
|
4206
|
-
))
|
|
4063
|
+
type: "text",
|
|
4064
|
+
name,
|
|
4065
|
+
value: searchTerm,
|
|
4066
|
+
onChange: handleInputChange,
|
|
4067
|
+
onFocus: handleFocus,
|
|
4068
|
+
onBlur: handleInputBlur,
|
|
4069
|
+
disabled,
|
|
4070
|
+
readOnly,
|
|
4071
|
+
placeholder,
|
|
4072
|
+
className: "outline-none pr-10",
|
|
4073
|
+
style: getInputStyle(),
|
|
4074
|
+
autoComplete: "off"
|
|
4207
4075
|
}
|
|
4208
|
-
)
|
|
4209
|
-
/* @__PURE__ */
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
"
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
onRowClick && !isLoading && tableRowClickable
|
|
4221
|
-
),
|
|
4222
|
-
tabIndex: onRowClick && !isLoading ? 0 : void 0,
|
|
4223
|
-
onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
|
|
4224
|
-
onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
|
|
4225
|
-
children: columns.map((col) => {
|
|
4226
|
-
const rawValue = getNestedValue2(row, col.key);
|
|
4227
|
-
const truncateTitle = col.truncate && (typeof rawValue === "string" || typeof rawValue === "number") ? String(rawValue) : void 0;
|
|
4228
|
-
return /* @__PURE__ */ jsx21(
|
|
4229
|
-
"td",
|
|
4230
|
-
{
|
|
4231
|
-
className: clsx21(
|
|
4232
|
-
tableCell(col.className, density),
|
|
4233
|
-
col.align && tableAlignClasses[col.align]
|
|
4234
|
-
),
|
|
4235
|
-
style: col.minWidth != null ? { minWidth: `${col.minWidth}px` } : void 0,
|
|
4236
|
-
title: truncateTitle,
|
|
4237
|
-
children: col.type === "actions" ? /* @__PURE__ */ jsx21("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ jsx21("div", { className: clsx21(tableCellText, col.truncate && "truncate"), children: renderCellContent(col, row) })
|
|
4238
|
-
},
|
|
4239
|
-
`${absoluteIndex}-${col.key}`
|
|
4240
|
-
);
|
|
4241
|
-
})
|
|
4076
|
+
),
|
|
4077
|
+
/* @__PURE__ */ jsxs18("div", { className: "absolute right-3 flex items-center gap-2 text-secondary-400", children: [
|
|
4078
|
+
isLoading && /* @__PURE__ */ jsx21("div", { className: "pointer-events-none animate-spin h-4 w-4 border-2 border-primary-500 border-t-transparent rounded-full" }),
|
|
4079
|
+
!isLoading && showClearButton && /* @__PURE__ */ jsx21(
|
|
4080
|
+
"button",
|
|
4081
|
+
{
|
|
4082
|
+
type: "button",
|
|
4083
|
+
"aria-label": "Limpiar",
|
|
4084
|
+
title: "Limpiar",
|
|
4085
|
+
onMouseDown: (e) => {
|
|
4086
|
+
e.preventDefault();
|
|
4087
|
+
handleClear();
|
|
4242
4088
|
},
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
/* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
|
|
4249
|
-
/* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
|
|
4250
|
-
] }) }) }) })
|
|
4251
|
-
]
|
|
4252
|
-
}
|
|
4253
|
-
);
|
|
4254
|
-
return /* @__PURE__ */ jsxs18("div", { ref: rootRef, className: clsx21("space-y-4 w-full relative", containerClassName), children: [
|
|
4255
|
-
/* @__PURE__ */ jsxs18("div", { className: tableContainer, style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
|
|
4256
|
-
title && /* @__PURE__ */ jsxs18("div", { className: "px-6 py-5 flex items-center justify-between", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
|
|
4257
|
-
/* @__PURE__ */ jsx21(ITText, { as: "h2", className: "text-xl font-bold text-secondary-900 leading-tight", children: title }),
|
|
4258
|
-
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3", children: [
|
|
4259
|
-
isLoading && /* @__PURE__ */ jsx21("div", { className: "text-secondary-400", children: loadingIndicator || /* @__PURE__ */ jsx21(FaSpinner, { className: "animate-spin text-primary-500 text-xl" }) }),
|
|
4260
|
-
/* @__PURE__ */ jsxs18("div", { className: "flex items-center bg-slate-100 dark:bg-slate-800/80 rounded-lg p-0.5 border border-slate-200 dark:border-slate-700/50", children: [
|
|
4261
|
-
/* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("table"), disabled: forcedCards, className: segCtrlClass("table"), children: [
|
|
4262
|
-
/* @__PURE__ */ jsx21(FaTable, { size: 11 }),
|
|
4263
|
-
"Table"
|
|
4264
|
-
] }),
|
|
4265
|
-
/* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("cards"), className: segCtrlClass("cards"), children: [
|
|
4266
|
-
/* @__PURE__ */ jsx21(FaThLarge, { size: 11 }),
|
|
4267
|
-
"Cards"
|
|
4268
|
-
] })
|
|
4269
|
-
] })
|
|
4089
|
+
className: "flex items-center justify-center text-secondary-400 hover:text-secondary-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-400 rounded-full",
|
|
4090
|
+
children: /* @__PURE__ */ jsx21(FaTimes4, { size: 14 })
|
|
4091
|
+
}
|
|
4092
|
+
),
|
|
4093
|
+
!isLoading && !showClearButton && /* @__PURE__ */ jsx21(FaSearch2, { size: 14, className: clsx21("pointer-events-none", { "text-primary-500": isFocused }) })
|
|
4270
4094
|
] })
|
|
4271
4095
|
] }),
|
|
4272
|
-
|
|
4273
|
-
/* @__PURE__ */
|
|
4274
|
-
/* @__PURE__ */ jsx21(FaTable, { size: 11 }),
|
|
4275
|
-
"Table"
|
|
4276
|
-
] }),
|
|
4277
|
-
/* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("cards"), className: segCtrlClass("cards"), children: [
|
|
4278
|
-
/* @__PURE__ */ jsx21(FaThLarge, { size: 11 }),
|
|
4279
|
-
"Cards"
|
|
4280
|
-
] })
|
|
4281
|
-
] }) }),
|
|
4282
|
-
/* @__PURE__ */ jsxs18("div", { className: scrollOuterClass, children: [
|
|
4283
|
-
isLoading && /* @__PURE__ */ jsx21("div", { className: "absolute inset-0 z-20 flex items-center justify-center bg-white/40 backdrop-blur-[2px] transition-all duration-300", children: /* @__PURE__ */ jsx21("div", { className: "flex flex-col items-center gap-3 p-6 rounded-2xl shadow-xl border border-secondary-100 animate-in fade-in zoom-in duration-300", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: loadingIndicator || /* @__PURE__ */ jsxs18(Fragment4, { children: [
|
|
4284
|
-
/* @__PURE__ */ jsx21(FaSpinner, { className: "animate-spin text-primary-500 text-4xl" }),
|
|
4285
|
-
/* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm font-semibold text-secondary-600 animate-pulse", children: "Cargando datos..." })
|
|
4286
|
-
] }) }) }),
|
|
4287
|
-
effectiveView === "cards" ? /* @__PURE__ */ jsx21("div", { className: "p-4 space-y-3 max-h-[400px] overflow-y-auto", children: data.length > 0 ? data.map((row, i) => /* @__PURE__ */ jsx21(
|
|
4288
|
-
"div",
|
|
4289
|
-
{
|
|
4290
|
-
className: clsx21(tableCardHover, onRowClick && !isLoading && tableCardClickable),
|
|
4291
|
-
role: onRowClick && !isLoading ? "button" : void 0,
|
|
4292
|
-
tabIndex: onRowClick && !isLoading ? 0 : void 0,
|
|
4293
|
-
onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
|
|
4294
|
-
onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
|
|
4295
|
-
children: renderCard ? renderCard(row) : renderDefaultCard(row)
|
|
4296
|
-
},
|
|
4297
|
-
i
|
|
4298
|
-
)) : !isLoading && /* @__PURE__ */ jsxs18("div", { className: clsx21(tableEmptyContent, "py-12"), children: [
|
|
4299
|
-
/* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
|
|
4300
|
-
/* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
|
|
4301
|
-
] }) }) : isTableVirtual ? /* @__PURE__ */ jsx21(
|
|
4096
|
+
isOpen && createPortal3(
|
|
4097
|
+
/* @__PURE__ */ jsx21(
|
|
4302
4098
|
"div",
|
|
4303
4099
|
{
|
|
4304
|
-
ref:
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
children:
|
|
4100
|
+
ref: panelRef,
|
|
4101
|
+
style: panelStyle,
|
|
4102
|
+
className: "bg-white dark:bg-slate-900 border border-secondary-200 dark:border-slate-800 rounded-lg shadow-xl overflow-hidden animate-in fade-in zoom-in duration-200 origin-top",
|
|
4103
|
+
children: /* @__PURE__ */ jsx21("div", { className: "max-h-60 overflow-y-auto", children: filteredOptions.length > 0 ? filteredOptions.map((option) => {
|
|
4104
|
+
const isSelected = value === option[valueField];
|
|
4105
|
+
return /* @__PURE__ */ jsx21(
|
|
4106
|
+
ITText,
|
|
4107
|
+
{
|
|
4108
|
+
as: "div",
|
|
4109
|
+
onClick: () => handleSelect(option),
|
|
4110
|
+
className: clsx21(
|
|
4111
|
+
"px-4 py-2 text-sm cursor-pointer transition-colors",
|
|
4112
|
+
isSelected ? "bg-primary-50 dark:bg-primary-950/40 text-primary-700 dark:text-primary-300 font-medium" : "hover:bg-secondary-50 dark:hover:bg-slate-800 text-secondary-700 dark:text-slate-300"
|
|
4113
|
+
),
|
|
4114
|
+
children: renderOption ? renderOption(option, { isSelected, searchTerm }) : /* @__PURE__ */ jsx21(ITText, { as: "span", children: option[labelField] })
|
|
4115
|
+
},
|
|
4116
|
+
option[valueField]
|
|
4117
|
+
);
|
|
4118
|
+
}) : /* @__PURE__ */ jsx21(ITText, { as: "div", className: "px-4 py-6 text-sm text-center text-secondary-500 italic", children: isLoading ? "Cargando..." : noResultsMessage }) })
|
|
4308
4119
|
}
|
|
4309
|
-
)
|
|
4310
|
-
|
|
4120
|
+
),
|
|
4121
|
+
document.body
|
|
4122
|
+
)
|
|
4311
4123
|
] }),
|
|
4312
|
-
/* @__PURE__ */ jsx21(
|
|
4313
|
-
ITPagination,
|
|
4314
|
-
{
|
|
4315
|
-
currentPage,
|
|
4316
|
-
totalPages: computedTotalPages,
|
|
4317
|
-
onPageChange: goToPage,
|
|
4318
|
-
color: "primary",
|
|
4319
|
-
itemsPerPageOptions,
|
|
4320
|
-
itemsPerPage,
|
|
4321
|
-
onItemsPerPageChange: handleItemsPerPageChange,
|
|
4322
|
-
totalItems
|
|
4323
|
-
}
|
|
4324
|
-
) })
|
|
4124
|
+
hasError && /* @__PURE__ */ jsx21(ITText, { as: "p", className: "text-danger-500 text-xs mt-1", children: errorMessage })
|
|
4325
4125
|
] });
|
|
4326
4126
|
}
|
|
4327
4127
|
|
|
4328
4128
|
// src/components/molecules/date-picker/datePicker.tsx
|
|
4329
4129
|
import clsx22 from "clsx";
|
|
4330
4130
|
import React5, { useEffect as useEffect8, useRef as useRef12, useState as useState18 } from "react";
|
|
4331
|
-
import { createPortal as
|
|
4131
|
+
import { createPortal as createPortal4 } from "react-dom";
|
|
4332
4132
|
import { FaCalendarAlt } from "react-icons/fa";
|
|
4333
4133
|
import { isBefore as isBefore2 } from "date-fns";
|
|
4334
4134
|
import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
@@ -4538,7 +4338,7 @@ function ITDatePicker({
|
|
|
4538
4338
|
onClick: handleIconClick
|
|
4539
4339
|
}
|
|
4540
4340
|
),
|
|
4541
|
-
isOpen &&
|
|
4341
|
+
isOpen && createPortal4(
|
|
4542
4342
|
/* @__PURE__ */ jsx22(
|
|
4543
4343
|
"div",
|
|
4544
4344
|
{
|
|
@@ -4578,13 +4378,513 @@ function ITDatePicker({
|
|
|
4578
4378
|
] });
|
|
4579
4379
|
}
|
|
4580
4380
|
|
|
4581
|
-
// src/
|
|
4582
|
-
|
|
4583
|
-
|
|
4381
|
+
// src/utils/table.utils.ts
|
|
4382
|
+
var formatCurrencyMX = (value) => {
|
|
4383
|
+
return value.toLocaleString("es-MX", {
|
|
4384
|
+
style: "currency",
|
|
4385
|
+
currency: "MXN"
|
|
4386
|
+
});
|
|
4387
|
+
};
|
|
4388
|
+
var getNestedValue = (obj, path) => {
|
|
4389
|
+
return path.split(".").reduce((acc, part) => acc && acc[part], obj);
|
|
4390
|
+
};
|
|
4391
|
+
var ROW_CLICK_IGNORE_SELECTOR = 'button, a, input, select, textarea, [role="button"], [role="link"], [data-row-click-ignore]';
|
|
4392
|
+
function isInteractiveTarget(target, boundary = null) {
|
|
4393
|
+
if (!(target instanceof Element)) return false;
|
|
4394
|
+
const interactive = target.closest(ROW_CLICK_IGNORE_SELECTOR);
|
|
4395
|
+
if (!interactive) return false;
|
|
4396
|
+
if (boundary instanceof Node && interactive === boundary) return false;
|
|
4397
|
+
return true;
|
|
4398
|
+
}
|
|
4399
|
+
|
|
4400
|
+
// src/components/organisms/data-table/dataTable.tsx
|
|
4401
|
+
import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4402
|
+
var getNestedValue2 = (obj, path) => {
|
|
4403
|
+
return path.split(".").reduce((acc, part) => acc && acc[part], obj);
|
|
4404
|
+
};
|
|
4405
|
+
var EMPTY_OBJECT = {};
|
|
4406
|
+
function ITDataTable({
|
|
4407
|
+
columns,
|
|
4408
|
+
fetchData,
|
|
4409
|
+
debounceMs = 500,
|
|
4410
|
+
externalFilters = EMPTY_OBJECT,
|
|
4411
|
+
loadingIndicator,
|
|
4412
|
+
fetchOnMount = true,
|
|
4413
|
+
reloadTrigger,
|
|
4414
|
+
containerClassName,
|
|
4415
|
+
className,
|
|
4416
|
+
variant = "default",
|
|
4417
|
+
size = "md",
|
|
4418
|
+
itemsPerPageOptions = [5, 10, 20],
|
|
4419
|
+
defaultItemsPerPage = 10,
|
|
4420
|
+
title,
|
|
4421
|
+
renderCard,
|
|
4422
|
+
defaultView,
|
|
4423
|
+
showVerticalBorder = true,
|
|
4424
|
+
verticalBorderClassname,
|
|
4425
|
+
onRowClick,
|
|
4426
|
+
layout = "auto",
|
|
4427
|
+
density = "normal",
|
|
4428
|
+
autoCardBreakpoint = 0,
|
|
4429
|
+
virtualized = false,
|
|
4430
|
+
virtualizedMaxHeight = 400,
|
|
4431
|
+
rowHeight,
|
|
4432
|
+
overscan = 5,
|
|
4433
|
+
stickyHeader = false
|
|
4434
|
+
}) {
|
|
4435
|
+
const [viewMode, setViewMode] = useState19(defaultView || "table");
|
|
4436
|
+
const { ref: rootRef, width: containerWidth } = useElementSize();
|
|
4437
|
+
const [data, setData] = useState19([]);
|
|
4438
|
+
const [totalItems, setTotalItems] = useState19(0);
|
|
4439
|
+
const [isLoading, setIsLoading] = useState19(fetchOnMount);
|
|
4440
|
+
const isFixed = layout === "fixed";
|
|
4441
|
+
const forcedCards = autoCardBreakpoint > 0 && containerWidth > 0 && containerWidth < autoCardBreakpoint;
|
|
4442
|
+
const effectiveView = forcedCards ? "cards" : viewMode;
|
|
4443
|
+
const hasColumnWidths = columns.some((col) => col.width != null);
|
|
4444
|
+
const tableLayoutClass = isFixed ? "w-full text-sm text-left text-secondary-600 transition-opacity duration-300" : "min-w-max w-full text-sm text-left text-secondary-600 transition-opacity duration-300";
|
|
4445
|
+
const isTableVirtual = virtualized && effectiveView === "table";
|
|
4446
|
+
const isStickyHeader = stickyHeader && isTableVirtual;
|
|
4447
|
+
const resolvedRowHeight = rowHeight ?? getRowHeight(size, density);
|
|
4448
|
+
const columnCount = columns.length;
|
|
4449
|
+
const scrollOuterClass = isTableVirtual ? "relative min-h-[200px]" : "overflow-x-auto relative min-h-[200px]";
|
|
4450
|
+
const {
|
|
4451
|
+
currentPage,
|
|
4452
|
+
itemsPerPage,
|
|
4453
|
+
filters,
|
|
4454
|
+
sortConfig,
|
|
4455
|
+
goToPage,
|
|
4456
|
+
handleFilterChange,
|
|
4457
|
+
handleSort,
|
|
4458
|
+
handleItemsPerPageChange
|
|
4459
|
+
} = useTableState({ defaultItemsPerPage });
|
|
4460
|
+
const {
|
|
4461
|
+
scrollRef,
|
|
4462
|
+
startIndex,
|
|
4463
|
+
endIndex,
|
|
4464
|
+
topSpacerHeight,
|
|
4465
|
+
bottomSpacerHeight
|
|
4466
|
+
} = useVirtualRows({
|
|
4467
|
+
count: data.length,
|
|
4468
|
+
rowHeight: resolvedRowHeight,
|
|
4469
|
+
overscan,
|
|
4470
|
+
enabled: isTableVirtual,
|
|
4471
|
+
resetKey: `${currentPage}-${itemsPerPage}`
|
|
4472
|
+
});
|
|
4473
|
+
const windowData = isTableVirtual ? data.slice(startIndex, endIndex + 1) : data;
|
|
4474
|
+
const debounceTimerRef = useRef13(null);
|
|
4475
|
+
const hasFetchedRef = useRef13(false);
|
|
4476
|
+
const fetchDataRef = useRef13(fetchData);
|
|
4477
|
+
fetchDataRef.current = fetchData;
|
|
4478
|
+
const externalFiltersRef = useRef13(externalFilters);
|
|
4479
|
+
externalFiltersRef.current = externalFilters;
|
|
4480
|
+
const externalKey = JSON.stringify(externalFilters);
|
|
4481
|
+
const computedTotalPages = Math.ceil(totalItems / itemsPerPage) || 1;
|
|
4482
|
+
const performFetch = useCallback7(async () => {
|
|
4483
|
+
setIsLoading(true);
|
|
4484
|
+
try {
|
|
4485
|
+
const response = await fetchDataRef.current({
|
|
4486
|
+
page: currentPage,
|
|
4487
|
+
limit: itemsPerPage,
|
|
4488
|
+
filters: { ...filters, ...externalFiltersRef.current },
|
|
4489
|
+
sort: sortConfig || void 0
|
|
4490
|
+
});
|
|
4491
|
+
setData(response.data || []);
|
|
4492
|
+
setTotalItems(response.total || 0);
|
|
4493
|
+
hasFetchedRef.current = true;
|
|
4494
|
+
} catch (error) {
|
|
4495
|
+
console.error("ITDataTable: Error fetching data", error);
|
|
4496
|
+
setData([]);
|
|
4497
|
+
setTotalItems(0);
|
|
4498
|
+
hasFetchedRef.current = true;
|
|
4499
|
+
} finally {
|
|
4500
|
+
setIsLoading(false);
|
|
4501
|
+
}
|
|
4502
|
+
}, [currentPage, itemsPerPage, filters, sortConfig]);
|
|
4503
|
+
const performFetchRef = useRef13(performFetch);
|
|
4504
|
+
performFetchRef.current = performFetch;
|
|
4505
|
+
useEffect9(() => {
|
|
4506
|
+
if (!fetchOnMount && !hasFetchedRef.current) return;
|
|
4507
|
+
if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
|
|
4508
|
+
debounceTimerRef.current = setTimeout(() => {
|
|
4509
|
+
performFetchRef.current();
|
|
4510
|
+
}, debounceMs);
|
|
4511
|
+
return () => {
|
|
4512
|
+
if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
|
|
4513
|
+
};
|
|
4514
|
+
}, [currentPage, itemsPerPage, sortConfig, filters, externalKey, reloadTrigger, fetchOnMount, debounceMs]);
|
|
4515
|
+
const renderFilterInput = (col) => {
|
|
4516
|
+
if (!col.filter) return null;
|
|
4517
|
+
if (col.type === "boolean") {
|
|
4518
|
+
const currentValue = filters[col.key];
|
|
4519
|
+
const nextValue = currentValue === void 0 ? true : currentValue === true ? false : void 0;
|
|
4520
|
+
const getToggleLabel = () => {
|
|
4521
|
+
if (currentValue === void 0) return "Mostrar todos";
|
|
4522
|
+
if (currentValue === true) return "Filtrar solo verdaderos";
|
|
4523
|
+
return "Filtrar solo falsos";
|
|
4524
|
+
};
|
|
4525
|
+
return /* @__PURE__ */ jsx23(
|
|
4526
|
+
"button",
|
|
4527
|
+
{
|
|
4528
|
+
className: "flex items-center justify-center cursor-pointer focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 rounded-full p-1 transition-all duration-200",
|
|
4529
|
+
onClick: () => handleFilterChange(col.key, nextValue),
|
|
4530
|
+
"aria-label": `${getToggleLabel()} para ${col.label}`,
|
|
4531
|
+
title: `${getToggleLabel()} para ${col.label}`,
|
|
4532
|
+
disabled: isLoading,
|
|
4533
|
+
children: /* @__PURE__ */ jsx23("div", { className: "relative w-10 h-5 bg-secondary-300 rounded-full", children: /* @__PURE__ */ jsx23(
|
|
4534
|
+
"div",
|
|
4535
|
+
{
|
|
4536
|
+
className: clsx23(
|
|
4537
|
+
"absolute top-0.5 w-4 h-4 rounded-full transition-all duration-300 shadow-sm",
|
|
4538
|
+
{
|
|
4539
|
+
"left-0.5 bg-secondary-400": currentValue === void 0,
|
|
4540
|
+
"left-5 bg-slate-500": currentValue === true,
|
|
4541
|
+
"left-0.5 bg-secondary-500": currentValue === false
|
|
4542
|
+
}
|
|
4543
|
+
)
|
|
4544
|
+
}
|
|
4545
|
+
) })
|
|
4546
|
+
}
|
|
4547
|
+
);
|
|
4548
|
+
}
|
|
4549
|
+
if (col.filter === "catalog" && col.catalogOptions) {
|
|
4550
|
+
if (col.catalogOptions.loading) {
|
|
4551
|
+
return /* @__PURE__ */ jsx23(FaSpinner, { className: "animate-spin", "aria-label": "Cargando opciones", title: "Cargando opciones" });
|
|
4552
|
+
}
|
|
4553
|
+
if (col.catalogOptions.error) {
|
|
4554
|
+
return /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-danger-500 text-xs", children: "Error cargando" });
|
|
4555
|
+
}
|
|
4556
|
+
return /* @__PURE__ */ jsx23(
|
|
4557
|
+
ITSelect,
|
|
4558
|
+
{
|
|
4559
|
+
name: `filter-${col.key}`,
|
|
4560
|
+
options: [
|
|
4561
|
+
{ value: "", label: "Todos" },
|
|
4562
|
+
...col.catalogOptions.data.map((item) => ({
|
|
4563
|
+
value: String(item.id),
|
|
4564
|
+
label: item.name
|
|
4565
|
+
}))
|
|
4566
|
+
],
|
|
4567
|
+
value: String(filters[col.key] || ""),
|
|
4568
|
+
onChange: (e) => {
|
|
4569
|
+
const value = e.target.value === "" ? void 0 : e.target.value;
|
|
4570
|
+
handleFilterChange(col.key, value);
|
|
4571
|
+
},
|
|
4572
|
+
onBlur: () => {
|
|
4573
|
+
},
|
|
4574
|
+
className: "w-full text-xs",
|
|
4575
|
+
disabled: isLoading
|
|
4576
|
+
}
|
|
4577
|
+
);
|
|
4578
|
+
}
|
|
4579
|
+
if (col.filter === "search" && col.catalogOptions) {
|
|
4580
|
+
if (col.catalogOptions.loading) {
|
|
4581
|
+
return /* @__PURE__ */ jsx23(FaSpinner, { className: "animate-spin", "aria-label": "Cargando opciones", title: "Cargando opciones" });
|
|
4582
|
+
}
|
|
4583
|
+
if (col.catalogOptions.error) {
|
|
4584
|
+
return /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-danger-500 text-xs", children: "Error cargando" });
|
|
4585
|
+
}
|
|
4586
|
+
const searchValue = filters[col.key];
|
|
4587
|
+
return /* @__PURE__ */ jsx23(
|
|
4588
|
+
ITSearchSelect,
|
|
4589
|
+
{
|
|
4590
|
+
name: `filter-${col.key}`,
|
|
4591
|
+
options: col.catalogOptions.data.map((item) => ({
|
|
4592
|
+
value: item.id,
|
|
4593
|
+
label: item.name
|
|
4594
|
+
})),
|
|
4595
|
+
value: typeof searchValue === "string" || typeof searchValue === "number" ? searchValue : "",
|
|
4596
|
+
onChange: (value) => handleFilterChange(col.key, value === "" ? void 0 : value),
|
|
4597
|
+
onSearch: col.catalogOptions.onSearch,
|
|
4598
|
+
isLoading: col.catalogOptions.loading,
|
|
4599
|
+
size: "sm",
|
|
4600
|
+
placeholder: "Buscar...",
|
|
4601
|
+
clearable: true,
|
|
4602
|
+
className: "w-full",
|
|
4603
|
+
onBlur: () => {
|
|
4604
|
+
},
|
|
4605
|
+
disabled: isLoading
|
|
4606
|
+
}
|
|
4607
|
+
);
|
|
4608
|
+
}
|
|
4609
|
+
if (col.filter === "date") {
|
|
4610
|
+
const dateValue = filters[col.key];
|
|
4611
|
+
return /* @__PURE__ */ jsx23(
|
|
4612
|
+
ITDatePicker,
|
|
4613
|
+
{
|
|
4614
|
+
name: `filter-${col.key}`,
|
|
4615
|
+
value: dateValue instanceof Date ? dateValue : void 0,
|
|
4616
|
+
onChange: (e) => handleFilterChange(col.key, e.target.value),
|
|
4617
|
+
minDate: col.dateFilterOptions?.minDate,
|
|
4618
|
+
maxDate: col.dateFilterOptions?.maxDate,
|
|
4619
|
+
size: "sm",
|
|
4620
|
+
placeholder: "dd/mm/aaaa",
|
|
4621
|
+
className: "w-full",
|
|
4622
|
+
disabled: isLoading
|
|
4623
|
+
}
|
|
4624
|
+
);
|
|
4625
|
+
}
|
|
4626
|
+
if (col.filter === "date-range") {
|
|
4627
|
+
const rangeValue = filters[col.key];
|
|
4628
|
+
return /* @__PURE__ */ jsx23(
|
|
4629
|
+
ITDatePicker,
|
|
4630
|
+
{
|
|
4631
|
+
name: `filter-${col.key}`,
|
|
4632
|
+
range: true,
|
|
4633
|
+
value: Array.isArray(rangeValue) ? rangeValue : void 0,
|
|
4634
|
+
onChange: (e) => handleFilterChange(col.key, e.target.value),
|
|
4635
|
+
minDate: col.dateFilterOptions?.minDate,
|
|
4636
|
+
maxDate: col.dateFilterOptions?.maxDate,
|
|
4637
|
+
size: "sm",
|
|
4638
|
+
placeholder: "dd/mm/aaaa - dd/mm/aaaa",
|
|
4639
|
+
className: "w-full",
|
|
4640
|
+
disabled: isLoading
|
|
4641
|
+
}
|
|
4642
|
+
);
|
|
4643
|
+
}
|
|
4644
|
+
return /* @__PURE__ */ jsx23(
|
|
4645
|
+
ITInput,
|
|
4646
|
+
{
|
|
4647
|
+
name: `filter-${col.key}`,
|
|
4648
|
+
className: "w-full text-xs",
|
|
4649
|
+
placeholder: "Buscar...",
|
|
4650
|
+
value: String(filters[col.key] || ""),
|
|
4651
|
+
onChange: (e) => handleFilterChange(col.key, e.target.value),
|
|
4652
|
+
onBlur: () => {
|
|
4653
|
+
},
|
|
4654
|
+
disabled: isLoading
|
|
4655
|
+
}
|
|
4656
|
+
);
|
|
4657
|
+
};
|
|
4658
|
+
const renderCellContent = (col, row) => {
|
|
4659
|
+
const value = getNestedValue2(row, col.key);
|
|
4660
|
+
if (col.render) return col.render(row);
|
|
4661
|
+
switch (col.type) {
|
|
4662
|
+
case "number":
|
|
4663
|
+
return typeof value === "number" && col.currencyMX ? formatCurrencyMX(value) : value;
|
|
4664
|
+
case "boolean":
|
|
4665
|
+
return value ? /* @__PURE__ */ jsx23(FaCheck2, { className: "text-success-500", "aria-label": "Verdadero", title: "Verdadero" }) : /* @__PURE__ */ jsx23(FaTimes5, { className: "text-danger-500", "aria-label": "Falso", title: "Falso" });
|
|
4666
|
+
case "actions":
|
|
4667
|
+
return col.actions ? col.actions(row) : null;
|
|
4668
|
+
case "catalog":
|
|
4669
|
+
if (col.catalogOptions) {
|
|
4670
|
+
const catalogItem = col.catalogOptions.data.find((item) => item.id === value);
|
|
4671
|
+
return catalogItem?.name || value;
|
|
4672
|
+
}
|
|
4673
|
+
return value;
|
|
4674
|
+
default:
|
|
4675
|
+
return value;
|
|
4676
|
+
}
|
|
4677
|
+
};
|
|
4678
|
+
const renderDefaultCard = (row) => {
|
|
4679
|
+
const dataCols = columns.filter((c) => c.type !== "actions");
|
|
4680
|
+
const actionCol = columns.find((c) => c.type === "actions");
|
|
4681
|
+
return /* @__PURE__ */ jsxs20("div", { className: "bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700 p-3 space-y-2 shadow-sm", children: [
|
|
4682
|
+
dataCols.map((col) => /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between gap-2", children: [
|
|
4683
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] font-bold uppercase tracking-wider text-slate-400 whitespace-nowrap flex-shrink-0 min-w-[70px]", children: col.label }),
|
|
4684
|
+
/* @__PURE__ */ jsx23("span", { className: "text-sm font-medium text-slate-800 dark:text-white text-right truncate", children: renderCellContent(col, row) })
|
|
4685
|
+
] }, col.key)),
|
|
4686
|
+
actionCol?.actions && /* @__PURE__ */ jsx23("div", { className: "flex items-center justify-end gap-2 pt-2 border-t border-slate-100 dark:border-slate-700", children: actionCol.actions(row) })
|
|
4687
|
+
] });
|
|
4688
|
+
};
|
|
4689
|
+
const segCtrlClass = (mode) => `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${effectiveView === mode ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`;
|
|
4690
|
+
const handleRowClick = (row) => (event) => {
|
|
4691
|
+
if (!onRowClick || isLoading || isInteractiveTarget(event.target, event.currentTarget)) return;
|
|
4692
|
+
onRowClick(row, event);
|
|
4693
|
+
};
|
|
4694
|
+
const handleRowKeyDown = (row) => (event) => {
|
|
4695
|
+
if (!onRowClick || isLoading) return;
|
|
4696
|
+
if (event.target !== event.currentTarget) return;
|
|
4697
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
4698
|
+
event.preventDefault();
|
|
4699
|
+
onRowClick(row, event);
|
|
4700
|
+
};
|
|
4701
|
+
const tableEl = /* @__PURE__ */ jsxs20(
|
|
4702
|
+
"table",
|
|
4703
|
+
{
|
|
4704
|
+
className: clsx23(
|
|
4705
|
+
tableLayoutClass,
|
|
4706
|
+
showVerticalBorder && "[&_th]:border-r [&_th:last-child]:border-r-0 [&_td]:border-r [&_td:last-child]:border-r-0",
|
|
4707
|
+
showVerticalBorder && (verticalBorderClassname || "[&_th]:border-slate-100 dark:[&_th]:border-slate-700/30 [&_td]:border-slate-100 dark:[&_td]:border-slate-700/30"),
|
|
4708
|
+
isLoading ? "opacity-50" : "opacity-100",
|
|
4709
|
+
variantStyles[variant],
|
|
4710
|
+
sizeStyles[size],
|
|
4711
|
+
className
|
|
4712
|
+
),
|
|
4713
|
+
style: isFixed ? { tableLayout: "fixed" } : void 0,
|
|
4714
|
+
"aria-rowcount": isTableVirtual ? data.length + 1 : void 0,
|
|
4715
|
+
children: [
|
|
4716
|
+
hasColumnWidths && /* @__PURE__ */ jsx23("colgroup", { children: columns.map((col) => /* @__PURE__ */ jsx23(
|
|
4717
|
+
"col",
|
|
4718
|
+
{
|
|
4719
|
+
style: col.width != null ? { width: typeof col.width === "number" ? `${col.width}px` : col.width } : void 0
|
|
4720
|
+
},
|
|
4721
|
+
col.key
|
|
4722
|
+
)) }),
|
|
4723
|
+
/* @__PURE__ */ jsx23("thead", { children: /* @__PURE__ */ jsx23(
|
|
4724
|
+
"tr",
|
|
4725
|
+
{
|
|
4726
|
+
className: clsx23(tableHeaderRow, "dark:text-slate-200"),
|
|
4727
|
+
"aria-rowindex": isTableVirtual ? 1 : void 0,
|
|
4728
|
+
children: columns.map((col) => /* @__PURE__ */ jsx23(
|
|
4729
|
+
"th",
|
|
4730
|
+
{
|
|
4731
|
+
scope: "col",
|
|
4732
|
+
className: clsx23(
|
|
4733
|
+
tableHeaderCell(col.className, density),
|
|
4734
|
+
col.align && tableAlignClasses[col.align],
|
|
4735
|
+
isStickyHeader && "sticky top-0 z-10 bg-secondary-50"
|
|
4736
|
+
),
|
|
4737
|
+
style: col.minWidth != null || isStickyHeader ? {
|
|
4738
|
+
...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
|
|
4739
|
+
...isStickyHeader ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {}
|
|
4740
|
+
} : void 0,
|
|
4741
|
+
children: /* @__PURE__ */ jsxs20("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
|
|
4742
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between gap-2", children: [
|
|
4743
|
+
/* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
|
|
4744
|
+
col.sortable && col.type !== "actions" && /* @__PURE__ */ jsx23(
|
|
4745
|
+
"button",
|
|
4746
|
+
{
|
|
4747
|
+
onClick: () => handleSort(col.key),
|
|
4748
|
+
disabled: isLoading,
|
|
4749
|
+
className: `p-1 rounded-md transition-colors ${sortConfig?.key === col.key ? "bg-secondary-200 text-secondary-900" : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"} disabled:opacity-50`,
|
|
4750
|
+
title: `Ordenar por ${col.label}`,
|
|
4751
|
+
children: /* @__PURE__ */ jsx23(MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
|
|
4752
|
+
}
|
|
4753
|
+
)
|
|
4754
|
+
] }),
|
|
4755
|
+
/* @__PURE__ */ jsx23("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
|
|
4756
|
+
] })
|
|
4757
|
+
},
|
|
4758
|
+
col.key
|
|
4759
|
+
))
|
|
4760
|
+
}
|
|
4761
|
+
) }),
|
|
4762
|
+
/* @__PURE__ */ jsx23("tbody", { className: clsx23(tableBody, "dark:divide-slate-700/30"), children: data.length > 0 ? /* @__PURE__ */ jsxs20(Fragment4, { children: [
|
|
4763
|
+
isTableVirtual && topSpacerHeight > 0 && /* @__PURE__ */ jsx23("tr", { "aria-hidden": "true", style: { height: topSpacerHeight }, children: /* @__PURE__ */ jsx23("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) }),
|
|
4764
|
+
windowData.map((row, windowIndex) => {
|
|
4765
|
+
const absoluteIndex = isTableVirtual ? startIndex + windowIndex : windowIndex;
|
|
4766
|
+
return /* @__PURE__ */ jsx23(
|
|
4767
|
+
"tr",
|
|
4768
|
+
{
|
|
4769
|
+
"aria-rowindex": isTableVirtual ? absoluteIndex + 2 : void 0,
|
|
4770
|
+
className: clsx23(
|
|
4771
|
+
tableRow,
|
|
4772
|
+
variant === "striped" && absoluteIndex % 2 === 0 && "bg-secondary-50/40 dark:bg-slate-800/20",
|
|
4773
|
+
onRowClick && !isLoading && tableRowClickable
|
|
4774
|
+
),
|
|
4775
|
+
tabIndex: onRowClick && !isLoading ? 0 : void 0,
|
|
4776
|
+
onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
|
|
4777
|
+
onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
|
|
4778
|
+
children: columns.map((col) => {
|
|
4779
|
+
const rawValue = getNestedValue2(row, col.key);
|
|
4780
|
+
const truncateTitle = col.truncate && (typeof rawValue === "string" || typeof rawValue === "number") ? String(rawValue) : void 0;
|
|
4781
|
+
return /* @__PURE__ */ jsx23(
|
|
4782
|
+
"td",
|
|
4783
|
+
{
|
|
4784
|
+
className: clsx23(
|
|
4785
|
+
tableCell(col.className, density),
|
|
4786
|
+
col.align && tableAlignClasses[col.align]
|
|
4787
|
+
),
|
|
4788
|
+
style: col.minWidth != null ? { minWidth: `${col.minWidth}px` } : void 0,
|
|
4789
|
+
title: truncateTitle,
|
|
4790
|
+
children: col.type === "actions" ? /* @__PURE__ */ jsx23("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ jsx23("div", { className: clsx23(tableCellText, col.truncate && "truncate"), children: renderCellContent(col, row) })
|
|
4791
|
+
},
|
|
4792
|
+
`${absoluteIndex}-${col.key}`
|
|
4793
|
+
);
|
|
4794
|
+
})
|
|
4795
|
+
},
|
|
4796
|
+
absoluteIndex
|
|
4797
|
+
);
|
|
4798
|
+
}),
|
|
4799
|
+
isTableVirtual && bottomSpacerHeight > 0 && /* @__PURE__ */ jsx23("tr", { "aria-hidden": "true", style: { height: bottomSpacerHeight }, children: /* @__PURE__ */ jsx23("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) })
|
|
4800
|
+
] }) : /* @__PURE__ */ jsx23("tr", { children: /* @__PURE__ */ jsx23("td", { colSpan: columns.length, className: "px-6 py-12 text-center", children: !isLoading && /* @__PURE__ */ jsxs20("div", { className: tableEmptyContent, children: [
|
|
4801
|
+
/* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
|
|
4802
|
+
/* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
|
|
4803
|
+
] }) }) }) })
|
|
4804
|
+
]
|
|
4805
|
+
}
|
|
4806
|
+
);
|
|
4807
|
+
return /* @__PURE__ */ jsxs20("div", { ref: rootRef, className: clsx23("space-y-4 w-full relative", containerClassName), children: [
|
|
4808
|
+
/* @__PURE__ */ jsxs20("div", { className: tableContainer, style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
|
|
4809
|
+
title && /* @__PURE__ */ jsxs20("div", { className: "px-6 py-5 flex items-center justify-between", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
|
|
4810
|
+
/* @__PURE__ */ jsx23(ITText, { as: "h2", className: "text-xl font-bold text-secondary-900 leading-tight", children: title }),
|
|
4811
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-3", children: [
|
|
4812
|
+
isLoading && /* @__PURE__ */ jsx23("div", { className: "text-secondary-400", children: loadingIndicator || /* @__PURE__ */ jsx23(FaSpinner, { className: "animate-spin text-primary-500 text-xl" }) }),
|
|
4813
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center bg-slate-100 dark:bg-slate-800/80 rounded-lg p-0.5 border border-slate-200 dark:border-slate-700/50", children: [
|
|
4814
|
+
/* @__PURE__ */ jsxs20("button", { onClick: () => setViewMode("table"), disabled: forcedCards, className: segCtrlClass("table"), children: [
|
|
4815
|
+
/* @__PURE__ */ jsx23(FaTable, { size: 11 }),
|
|
4816
|
+
"Table"
|
|
4817
|
+
] }),
|
|
4818
|
+
/* @__PURE__ */ jsxs20("button", { onClick: () => setViewMode("cards"), className: segCtrlClass("cards"), children: [
|
|
4819
|
+
/* @__PURE__ */ jsx23(FaThLarge, { size: 11 }),
|
|
4820
|
+
"Cards"
|
|
4821
|
+
] })
|
|
4822
|
+
] })
|
|
4823
|
+
] })
|
|
4824
|
+
] }),
|
|
4825
|
+
!title && /* @__PURE__ */ jsx23("div", { className: "flex justify-end px-4 pt-3", children: /* @__PURE__ */ jsxs20("div", { className: "flex items-center bg-slate-100 dark:bg-slate-800/80 rounded-lg p-0.5 border border-slate-200 dark:border-slate-700/50", children: [
|
|
4826
|
+
/* @__PURE__ */ jsxs20("button", { onClick: () => setViewMode("table"), disabled: forcedCards, className: segCtrlClass("table"), children: [
|
|
4827
|
+
/* @__PURE__ */ jsx23(FaTable, { size: 11 }),
|
|
4828
|
+
"Table"
|
|
4829
|
+
] }),
|
|
4830
|
+
/* @__PURE__ */ jsxs20("button", { onClick: () => setViewMode("cards"), className: segCtrlClass("cards"), children: [
|
|
4831
|
+
/* @__PURE__ */ jsx23(FaThLarge, { size: 11 }),
|
|
4832
|
+
"Cards"
|
|
4833
|
+
] })
|
|
4834
|
+
] }) }),
|
|
4835
|
+
/* @__PURE__ */ jsxs20("div", { className: scrollOuterClass, children: [
|
|
4836
|
+
isLoading && /* @__PURE__ */ jsx23("div", { className: "absolute inset-0 z-20 flex items-center justify-center bg-white/40 backdrop-blur-[2px] transition-all duration-300", children: /* @__PURE__ */ jsx23("div", { className: "flex flex-col items-center gap-3 p-6 rounded-2xl shadow-xl border border-secondary-100 animate-in fade-in zoom-in duration-300", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: loadingIndicator || /* @__PURE__ */ jsxs20(Fragment4, { children: [
|
|
4837
|
+
/* @__PURE__ */ jsx23(FaSpinner, { className: "animate-spin text-primary-500 text-4xl" }),
|
|
4838
|
+
/* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-sm font-semibold text-secondary-600 animate-pulse", children: "Cargando datos..." })
|
|
4839
|
+
] }) }) }),
|
|
4840
|
+
effectiveView === "cards" ? /* @__PURE__ */ jsx23("div", { className: "p-4 space-y-3 max-h-[400px] overflow-y-auto", children: data.length > 0 ? data.map((row, i) => /* @__PURE__ */ jsx23(
|
|
4841
|
+
"div",
|
|
4842
|
+
{
|
|
4843
|
+
className: clsx23(tableCardHover, onRowClick && !isLoading && tableCardClickable),
|
|
4844
|
+
role: onRowClick && !isLoading ? "button" : void 0,
|
|
4845
|
+
tabIndex: onRowClick && !isLoading ? 0 : void 0,
|
|
4846
|
+
onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
|
|
4847
|
+
onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
|
|
4848
|
+
children: renderCard ? renderCard(row) : renderDefaultCard(row)
|
|
4849
|
+
},
|
|
4850
|
+
i
|
|
4851
|
+
)) : !isLoading && /* @__PURE__ */ jsxs20("div", { className: clsx23(tableEmptyContent, "py-12"), children: [
|
|
4852
|
+
/* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
|
|
4853
|
+
/* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
|
|
4854
|
+
] }) }) : isTableVirtual ? /* @__PURE__ */ jsx23(
|
|
4855
|
+
"div",
|
|
4856
|
+
{
|
|
4857
|
+
ref: scrollRef,
|
|
4858
|
+
className: "overflow-x-auto overflow-y-auto",
|
|
4859
|
+
style: { maxHeight: virtualizedMaxHeight },
|
|
4860
|
+
children: tableEl
|
|
4861
|
+
}
|
|
4862
|
+
) : tableEl
|
|
4863
|
+
] })
|
|
4864
|
+
] }),
|
|
4865
|
+
/* @__PURE__ */ jsx23("div", { className: "rounded-b-xl px-6 py-4", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: /* @__PURE__ */ jsx23(
|
|
4866
|
+
ITPagination,
|
|
4867
|
+
{
|
|
4868
|
+
currentPage,
|
|
4869
|
+
totalPages: computedTotalPages,
|
|
4870
|
+
onPageChange: goToPage,
|
|
4871
|
+
color: "primary",
|
|
4872
|
+
itemsPerPageOptions,
|
|
4873
|
+
itemsPerPage,
|
|
4874
|
+
onItemsPerPageChange: handleItemsPerPageChange,
|
|
4875
|
+
totalItems
|
|
4876
|
+
}
|
|
4877
|
+
) })
|
|
4878
|
+
] });
|
|
4879
|
+
}
|
|
4880
|
+
|
|
4881
|
+
// src/components/organisms/dialog/dialog.tsx
|
|
4882
|
+
import { createPortal as createPortal5 } from "react-dom";
|
|
4883
|
+
import { useEffect as useEffect10, useRef as useRef14 } from "react";
|
|
4584
4884
|
import { FaRegTimesCircle } from "react-icons/fa";
|
|
4585
4885
|
|
|
4586
4886
|
// src/components/molecules/form-header/form-header.tsx
|
|
4587
|
-
import { FaTimes as
|
|
4887
|
+
import { FaTimes as FaTimes6 } from "react-icons/fa";
|
|
4588
4888
|
|
|
4589
4889
|
// src/theme/theme-context.ts
|
|
4590
4890
|
import { createContext, useContext } from "react";
|
|
@@ -4677,7 +4977,7 @@ var getContrastTextColor = (bgColor, palette2, isDarkMode) => {
|
|
|
4677
4977
|
};
|
|
4678
4978
|
|
|
4679
4979
|
// src/components/molecules/form-header/form-header.tsx
|
|
4680
|
-
import { jsx as
|
|
4980
|
+
import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4681
4981
|
function ITFormHeader({
|
|
4682
4982
|
title,
|
|
4683
4983
|
onClose,
|
|
@@ -4691,23 +4991,23 @@ function ITFormHeader({
|
|
|
4691
4991
|
palette2,
|
|
4692
4992
|
isDarkMode
|
|
4693
4993
|
);
|
|
4694
|
-
return /* @__PURE__ */
|
|
4695
|
-
/* @__PURE__ */
|
|
4696
|
-
onClose && /* @__PURE__ */
|
|
4994
|
+
return /* @__PURE__ */ jsxs21("div", { className: `bg-primary-500 ${textColorClass} px-6 py-4 rounded-t-lg flex justify-center items-center relative ${className}`, children: [
|
|
4995
|
+
/* @__PURE__ */ jsx24(ITText, { as: "h2", className: "text-lg font-semibold text-center", style: { color: "inherit" }, children: title }),
|
|
4996
|
+
onClose && /* @__PURE__ */ jsx24(
|
|
4697
4997
|
"button",
|
|
4698
4998
|
{
|
|
4699
4999
|
onClick: onClose,
|
|
4700
5000
|
className: `absolute right-4 ${textColorClass} hover:opacity-80 transition-colors duration-200 p-1 rounded-full`,
|
|
4701
5001
|
style: { color: "inherit" },
|
|
4702
5002
|
"aria-label": "Cerrar",
|
|
4703
|
-
children: /* @__PURE__ */
|
|
5003
|
+
children: /* @__PURE__ */ jsx24(FaTimes6, { className: "w-4 h-4" })
|
|
4704
5004
|
}
|
|
4705
5005
|
)
|
|
4706
5006
|
] });
|
|
4707
5007
|
}
|
|
4708
5008
|
|
|
4709
5009
|
// src/components/organisms/dialog/dialog.tsx
|
|
4710
|
-
import { Fragment as Fragment5, jsx as
|
|
5010
|
+
import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4711
5011
|
function ITDialog({
|
|
4712
5012
|
isOpen,
|
|
4713
5013
|
onClose,
|
|
@@ -4717,9 +5017,9 @@ function ITDialog({
|
|
|
4717
5017
|
useFormHeader = false,
|
|
4718
5018
|
fullScreen = false
|
|
4719
5019
|
}) {
|
|
4720
|
-
const modalRef =
|
|
5020
|
+
const modalRef = useRef14(null);
|
|
4721
5021
|
useClickOutside_default(modalRef, onClose);
|
|
4722
|
-
|
|
5022
|
+
useEffect10(() => {
|
|
4723
5023
|
const handleEscape = (event) => {
|
|
4724
5024
|
if (event.key === "Escape") {
|
|
4725
5025
|
onClose();
|
|
@@ -4734,12 +5034,12 @@ function ITDialog({
|
|
|
4734
5034
|
}, [isOpen, onClose]);
|
|
4735
5035
|
if (!isOpen) return null;
|
|
4736
5036
|
if (typeof document === "undefined") return null;
|
|
4737
|
-
const content = /* @__PURE__ */
|
|
5037
|
+
const content = /* @__PURE__ */ jsx25(
|
|
4738
5038
|
"div",
|
|
4739
5039
|
{
|
|
4740
5040
|
"data-it-dialog": "true",
|
|
4741
5041
|
className: `fixed inset-0 flex ${fullScreen ? "items-stretch" : "items-center justify-center"} bg-slate-900/50 z-[60]`,
|
|
4742
|
-
children: /* @__PURE__ */
|
|
5042
|
+
children: /* @__PURE__ */ jsx25(
|
|
4743
5043
|
"div",
|
|
4744
5044
|
{
|
|
4745
5045
|
ref: modalRef,
|
|
@@ -4752,41 +5052,41 @@ function ITDialog({
|
|
|
4752
5052
|
borderColor: theme.card.borderColor,
|
|
4753
5053
|
borderStyle: "solid"
|
|
4754
5054
|
},
|
|
4755
|
-
children: useFormHeader && title ? /* @__PURE__ */
|
|
4756
|
-
/* @__PURE__ */
|
|
4757
|
-
/* @__PURE__ */
|
|
4758
|
-
] }) : /* @__PURE__ */
|
|
4759
|
-
/* @__PURE__ */
|
|
5055
|
+
children: useFormHeader && title ? /* @__PURE__ */ jsxs22(Fragment5, { children: [
|
|
5056
|
+
/* @__PURE__ */ jsx25(ITFormHeader, { title, onClose }),
|
|
5057
|
+
/* @__PURE__ */ jsx25("div", { className: fullScreen ? "flex-1 overflow-auto p-6" : "p-6", children })
|
|
5058
|
+
] }) : /* @__PURE__ */ jsxs22(Fragment5, { children: [
|
|
5059
|
+
/* @__PURE__ */ jsx25(
|
|
4760
5060
|
"button",
|
|
4761
5061
|
{
|
|
4762
5062
|
className: "absolute top-2 right-2 text-secondary-600 hover:text-secondary-900",
|
|
4763
5063
|
onClick: onClose,
|
|
4764
|
-
children: /* @__PURE__ */
|
|
5064
|
+
children: /* @__PURE__ */ jsx25(FaRegTimesCircle, {})
|
|
4765
5065
|
}
|
|
4766
5066
|
),
|
|
4767
|
-
title && /* @__PURE__ */
|
|
4768
|
-
/* @__PURE__ */
|
|
5067
|
+
title && /* @__PURE__ */ jsx25(ITText, { as: "h2", className: "text-xl font-semibold mb-4", children: title }),
|
|
5068
|
+
/* @__PURE__ */ jsx25("div", { children })
|
|
4769
5069
|
] })
|
|
4770
5070
|
}
|
|
4771
5071
|
)
|
|
4772
5072
|
}
|
|
4773
5073
|
);
|
|
4774
|
-
return
|
|
5074
|
+
return createPortal5(content, document.body);
|
|
4775
5075
|
}
|
|
4776
5076
|
|
|
4777
5077
|
// src/components/atoms/divider/divider.tsx
|
|
4778
|
-
import
|
|
4779
|
-
import { jsx as
|
|
5078
|
+
import clsx24 from "clsx";
|
|
5079
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
4780
5080
|
function ITDivider({
|
|
4781
5081
|
orientation = "horizontal",
|
|
4782
5082
|
className,
|
|
4783
5083
|
color = "bg-slate-200 dark:bg-slate-700",
|
|
4784
5084
|
thickness = orientation === "horizontal" ? "h-px" : "w-px"
|
|
4785
5085
|
}) {
|
|
4786
|
-
return /* @__PURE__ */
|
|
5086
|
+
return /* @__PURE__ */ jsx26(
|
|
4787
5087
|
"div",
|
|
4788
5088
|
{
|
|
4789
|
-
className:
|
|
5089
|
+
className: clsx24(
|
|
4790
5090
|
"flex-shrink-0",
|
|
4791
5091
|
orientation === "horizontal" ? "w-full" : "self-stretch",
|
|
4792
5092
|
thickness,
|
|
@@ -4798,10 +5098,10 @@ function ITDivider({
|
|
|
4798
5098
|
}
|
|
4799
5099
|
|
|
4800
5100
|
// src/components/organisms/drawer/drawer.tsx
|
|
4801
|
-
import
|
|
4802
|
-
import { FaTimes as
|
|
4803
|
-
import { useRef as
|
|
4804
|
-
import { Fragment as Fragment6, jsx as
|
|
5101
|
+
import clsx25 from "clsx";
|
|
5102
|
+
import { FaTimes as FaTimes7 } from "react-icons/fa";
|
|
5103
|
+
import { useRef as useRef15 } from "react";
|
|
5104
|
+
import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4805
5105
|
function ITDrawer({
|
|
4806
5106
|
isOpen,
|
|
4807
5107
|
onClose,
|
|
@@ -4812,15 +5112,15 @@ function ITDrawer({
|
|
|
4812
5112
|
className,
|
|
4813
5113
|
style
|
|
4814
5114
|
}) {
|
|
4815
|
-
const panelRef =
|
|
5115
|
+
const panelRef = useRef15(null);
|
|
4816
5116
|
useClickOutside_default(panelRef, onClose);
|
|
4817
|
-
return /* @__PURE__ */
|
|
4818
|
-
/* @__PURE__ */
|
|
4819
|
-
/* @__PURE__ */
|
|
5117
|
+
return /* @__PURE__ */ jsx27(Fragment6, { children: isOpen && /* @__PURE__ */ jsxs23("div", { className: "fixed inset-0 z-[50] flex", children: [
|
|
5118
|
+
/* @__PURE__ */ jsx27("div", { className: "absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity" }),
|
|
5119
|
+
/* @__PURE__ */ jsxs23(
|
|
4820
5120
|
"div",
|
|
4821
5121
|
{
|
|
4822
5122
|
ref: panelRef,
|
|
4823
|
-
className:
|
|
5123
|
+
className: clsx25(
|
|
4824
5124
|
"relative z-10 h-full bg-white dark:bg-slate-900 shadow-2xl flex flex-col transition-transform duration-300",
|
|
4825
5125
|
position === "right" ? "ml-auto" : "mr-auto",
|
|
4826
5126
|
size,
|
|
@@ -4828,18 +5128,18 @@ function ITDrawer({
|
|
|
4828
5128
|
),
|
|
4829
5129
|
style,
|
|
4830
5130
|
children: [
|
|
4831
|
-
title && /* @__PURE__ */
|
|
4832
|
-
/* @__PURE__ */
|
|
4833
|
-
/* @__PURE__ */
|
|
5131
|
+
title && /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-slate-700", children: [
|
|
5132
|
+
/* @__PURE__ */ jsx27(ITText, { as: "h2", className: "text-lg font-bold text-slate-800 dark:text-white", children: title }),
|
|
5133
|
+
/* @__PURE__ */ jsx27(
|
|
4834
5134
|
"button",
|
|
4835
5135
|
{
|
|
4836
5136
|
onClick: onClose,
|
|
4837
5137
|
className: "w-8 h-8 flex items-center justify-center rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800 text-slate-400 hover:text-slate-600 transition-colors",
|
|
4838
|
-
children: /* @__PURE__ */
|
|
5138
|
+
children: /* @__PURE__ */ jsx27(FaTimes7, { size: 14 })
|
|
4839
5139
|
}
|
|
4840
5140
|
)
|
|
4841
5141
|
] }),
|
|
4842
|
-
/* @__PURE__ */
|
|
5142
|
+
/* @__PURE__ */ jsx27("div", { className: "flex-1 overflow-y-auto p-5", children })
|
|
4843
5143
|
]
|
|
4844
5144
|
}
|
|
4845
5145
|
)
|
|
@@ -4847,27 +5147,27 @@ function ITDrawer({
|
|
|
4847
5147
|
}
|
|
4848
5148
|
|
|
4849
5149
|
// src/components/molecules/empty-state/empty-state.tsx
|
|
4850
|
-
import
|
|
5150
|
+
import clsx26 from "clsx";
|
|
4851
5151
|
import { FaInbox } from "react-icons/fa";
|
|
4852
|
-
import { jsx as
|
|
5152
|
+
import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
4853
5153
|
function ITEmptyState({
|
|
4854
|
-
icon = /* @__PURE__ */
|
|
5154
|
+
icon = /* @__PURE__ */ jsx28(FaInbox, { size: 40 }),
|
|
4855
5155
|
title,
|
|
4856
5156
|
description,
|
|
4857
5157
|
action,
|
|
4858
5158
|
className
|
|
4859
5159
|
}) {
|
|
4860
|
-
return /* @__PURE__ */
|
|
4861
|
-
/* @__PURE__ */
|
|
4862
|
-
/* @__PURE__ */
|
|
4863
|
-
description && /* @__PURE__ */
|
|
4864
|
-
action && /* @__PURE__ */
|
|
5160
|
+
return /* @__PURE__ */ jsxs24("div", { className: clsx26("flex flex-col items-center justify-center py-16 px-6 text-center", className), children: [
|
|
5161
|
+
/* @__PURE__ */ jsx28("div", { className: "text-slate-300 dark:text-slate-600 mb-4", children: icon }),
|
|
5162
|
+
/* @__PURE__ */ jsx28(ITText, { as: "h3", className: "text-lg font-bold text-slate-700 dark:text-slate-200 mb-1", children: title }),
|
|
5163
|
+
description && /* @__PURE__ */ jsx28(ITText, { as: "p", className: "text-sm text-slate-400 dark:text-slate-500 max-w-sm mb-4", children: description }),
|
|
5164
|
+
action && /* @__PURE__ */ jsx28("div", { children: action })
|
|
4865
5165
|
] });
|
|
4866
5166
|
}
|
|
4867
5167
|
|
|
4868
5168
|
// src/components/atoms/flex/flex.tsx
|
|
4869
|
-
import
|
|
4870
|
-
import { jsx as
|
|
5169
|
+
import clsx27 from "clsx";
|
|
5170
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
4871
5171
|
var directionMap = {
|
|
4872
5172
|
row: "flex-row",
|
|
4873
5173
|
column: "flex-col",
|
|
@@ -4916,10 +5216,10 @@ function ITFlex({
|
|
|
4916
5216
|
flexBasis: typeof basis === "number" ? `${basis * 0.25}rem` : basis,
|
|
4917
5217
|
...style
|
|
4918
5218
|
};
|
|
4919
|
-
return /* @__PURE__ */
|
|
5219
|
+
return /* @__PURE__ */ jsx29(
|
|
4920
5220
|
Component,
|
|
4921
5221
|
{
|
|
4922
|
-
className:
|
|
5222
|
+
className: clsx27(
|
|
4923
5223
|
"flex",
|
|
4924
5224
|
directionMap[direction],
|
|
4925
5225
|
align && alignMap[align],
|
|
@@ -4938,33 +5238,33 @@ function ITFlex({
|
|
|
4938
5238
|
import { useMemo as useMemo10 } from "react";
|
|
4939
5239
|
|
|
4940
5240
|
// src/components/organisms/form-builder/formBuilder.context.tsx
|
|
4941
|
-
import
|
|
4942
|
-
import { jsx as
|
|
5241
|
+
import React7, { createContext as createContext2, useContext as useContext2, useState as useState20 } from "react";
|
|
5242
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
4943
5243
|
var ITFormBuilderContext = createContext2(void 0);
|
|
4944
5244
|
var ITFormBuilderProvider = ({
|
|
4945
5245
|
children,
|
|
4946
5246
|
value
|
|
4947
5247
|
}) => {
|
|
4948
|
-
const [fieldRegistry, setFieldRegistry] =
|
|
4949
|
-
const registerField =
|
|
5248
|
+
const [fieldRegistry, setFieldRegistry] = useState20({});
|
|
5249
|
+
const registerField = React7.useCallback((name, config2) => {
|
|
4950
5250
|
setFieldRegistry((prev) => ({ ...prev, [name]: config2 }));
|
|
4951
5251
|
}, []);
|
|
4952
|
-
const unregisterField =
|
|
5252
|
+
const unregisterField = React7.useCallback((name) => {
|
|
4953
5253
|
setFieldRegistry((prev) => {
|
|
4954
5254
|
const next = { ...prev };
|
|
4955
5255
|
delete next[name];
|
|
4956
5256
|
return next;
|
|
4957
5257
|
});
|
|
4958
5258
|
}, []);
|
|
4959
|
-
const getFieldConfig =
|
|
5259
|
+
const getFieldConfig = React7.useCallback(
|
|
4960
5260
|
(name) => fieldRegistry[name],
|
|
4961
5261
|
[fieldRegistry]
|
|
4962
5262
|
);
|
|
4963
|
-
const getAllFieldConfigs =
|
|
5263
|
+
const getAllFieldConfigs = React7.useCallback(
|
|
4964
5264
|
() => Object.values(fieldRegistry),
|
|
4965
5265
|
[fieldRegistry]
|
|
4966
5266
|
);
|
|
4967
|
-
const contextValue =
|
|
5267
|
+
const contextValue = React7.useMemo(
|
|
4968
5268
|
() => ({
|
|
4969
5269
|
...value,
|
|
4970
5270
|
registerField,
|
|
@@ -4974,7 +5274,7 @@ var ITFormBuilderProvider = ({
|
|
|
4974
5274
|
}),
|
|
4975
5275
|
[value, registerField, unregisterField, getFieldConfig, getAllFieldConfigs]
|
|
4976
5276
|
);
|
|
4977
|
-
return /* @__PURE__ */
|
|
5277
|
+
return /* @__PURE__ */ jsx30(ITFormBuilderContext.Provider, { value: contextValue, children });
|
|
4978
5278
|
};
|
|
4979
5279
|
var useITFormBuilderContext = () => {
|
|
4980
5280
|
const context = useContext2(ITFormBuilderContext);
|
|
@@ -4989,11 +5289,11 @@ import { memo, useCallback as useCallback8, useEffect as useEffect12, useMemo as
|
|
|
4989
5289
|
import clsx29 from "clsx";
|
|
4990
5290
|
|
|
4991
5291
|
// src/components/molecules/time-picker/timePicker.tsx
|
|
4992
|
-
import
|
|
4993
|
-
import { useEffect as
|
|
4994
|
-
import { createPortal as
|
|
5292
|
+
import clsx28 from "clsx";
|
|
5293
|
+
import { useEffect as useEffect11, useRef as useRef16, useState as useState21 } from "react";
|
|
5294
|
+
import { createPortal as createPortal6 } from "react-dom";
|
|
4995
5295
|
import { FaClock } from "react-icons/fa";
|
|
4996
|
-
import { jsx as
|
|
5296
|
+
import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
4997
5297
|
function ITTimePicker({
|
|
4998
5298
|
name,
|
|
4999
5299
|
value,
|
|
@@ -5010,12 +5310,12 @@ function ITTimePicker({
|
|
|
5010
5310
|
variant = "primary",
|
|
5011
5311
|
color = "primary"
|
|
5012
5312
|
}) {
|
|
5013
|
-
const [isOpen, setIsOpen] =
|
|
5014
|
-
const [inputValue, setInputValue] =
|
|
5015
|
-
const [isValidTime, setIsValidTime] =
|
|
5016
|
-
const wrapperRef =
|
|
5017
|
-
const hoursRef =
|
|
5018
|
-
const minutesRef =
|
|
5313
|
+
const [isOpen, setIsOpen] = useState21(false);
|
|
5314
|
+
const [inputValue, setInputValue] = useState21(value || "");
|
|
5315
|
+
const [isValidTime, setIsValidTime] = useState21(true);
|
|
5316
|
+
const wrapperRef = useRef16(null);
|
|
5317
|
+
const hoursRef = useRef16(null);
|
|
5318
|
+
const minutesRef = useRef16(null);
|
|
5019
5319
|
const { panelRef: dropdownRef, style: panelStyle } = useFloatingPanel(
|
|
5020
5320
|
wrapperRef,
|
|
5021
5321
|
isOpen && !disabled,
|
|
@@ -5029,7 +5329,7 @@ function ITTimePicker({
|
|
|
5029
5329
|
const isThemeColor = color in theme.colors;
|
|
5030
5330
|
const highlightColor = isThemeColor ? theme.colors[color][50] : "#f3f4f6";
|
|
5031
5331
|
const activeColor = isThemeColor ? theme.colors[color][100] : "#e5e7eb";
|
|
5032
|
-
|
|
5332
|
+
useEffect11(() => {
|
|
5033
5333
|
setInputValue(value || "");
|
|
5034
5334
|
}, [value]);
|
|
5035
5335
|
const validateTime = (timeString) => {
|
|
@@ -5038,7 +5338,7 @@ function ITTimePicker({
|
|
|
5038
5338
|
};
|
|
5039
5339
|
const currentHour = validateTime(inputValue) ? inputValue.split(":")[0] : null;
|
|
5040
5340
|
const currentMinute = validateTime(inputValue) ? inputValue.split(":")[1] : null;
|
|
5041
|
-
|
|
5341
|
+
useEffect11(() => {
|
|
5042
5342
|
if (isOpen) {
|
|
5043
5343
|
setTimeout(() => {
|
|
5044
5344
|
if (hoursRef.current && currentHour) {
|
|
@@ -5108,8 +5408,8 @@ function ITTimePicker({
|
|
|
5108
5408
|
{ length: 60 },
|
|
5109
5409
|
(_, i) => i.toString().padStart(2, "0")
|
|
5110
5410
|
);
|
|
5111
|
-
return /* @__PURE__ */
|
|
5112
|
-
/* @__PURE__ */
|
|
5411
|
+
return /* @__PURE__ */ jsxs25("div", { ref: wrapperRef, className: clsx28("relative w-full", className), children: [
|
|
5412
|
+
/* @__PURE__ */ jsx31(
|
|
5113
5413
|
ITInput,
|
|
5114
5414
|
{
|
|
5115
5415
|
name,
|
|
@@ -5126,7 +5426,7 @@ function ITTimePicker({
|
|
|
5126
5426
|
size,
|
|
5127
5427
|
touched,
|
|
5128
5428
|
error: !isValidTime ? "Hora inv\xE1lida" : typeof error === "string" ? error : void 0,
|
|
5129
|
-
iconRight: /* @__PURE__ */
|
|
5429
|
+
iconRight: /* @__PURE__ */ jsx31(
|
|
5130
5430
|
FaClock,
|
|
5131
5431
|
{
|
|
5132
5432
|
onClick: () => {
|
|
@@ -5134,7 +5434,7 @@ function ITTimePicker({
|
|
|
5134
5434
|
setIsOpen(!isOpen);
|
|
5135
5435
|
}
|
|
5136
5436
|
},
|
|
5137
|
-
className:
|
|
5437
|
+
className: clsx28(
|
|
5138
5438
|
"cursor-pointer transition-colors",
|
|
5139
5439
|
disabled ? "text-slate-400 cursor-not-allowed" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"
|
|
5140
5440
|
)
|
|
@@ -5142,31 +5442,31 @@ function ITTimePicker({
|
|
|
5142
5442
|
)
|
|
5143
5443
|
}
|
|
5144
5444
|
),
|
|
5145
|
-
isOpen && !disabled &&
|
|
5146
|
-
/* @__PURE__ */
|
|
5445
|
+
isOpen && !disabled && createPortal6(
|
|
5446
|
+
/* @__PURE__ */ jsxs25(
|
|
5147
5447
|
"div",
|
|
5148
5448
|
{
|
|
5149
5449
|
ref: dropdownRef,
|
|
5150
5450
|
className: "bg-white border border-secondary-100 shadow-xl rounded-xl w-64 overflow-hidden flex flex-col animate-in fade-in zoom-in-95 duration-200 origin-top it-timepicker-dropdown",
|
|
5151
5451
|
style: panelStyle,
|
|
5152
5452
|
children: [
|
|
5153
|
-
/* @__PURE__ */
|
|
5154
|
-
/* @__PURE__ */
|
|
5155
|
-
/* @__PURE__ */
|
|
5453
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex bg-secondary-50 border-b border-secondary-100 text-xs font-semibold text-secondary-500 uppercase tracking-wider", children: [
|
|
5454
|
+
/* @__PURE__ */ jsx31(ITText, { as: "div", className: "flex-1 text-center py-2 border-r border-secondary-100", children: "Horas" }),
|
|
5455
|
+
/* @__PURE__ */ jsx31(ITText, { as: "div", className: "flex-1 text-center py-2", children: "Minutos" })
|
|
5156
5456
|
] }),
|
|
5157
|
-
/* @__PURE__ */
|
|
5158
|
-
/* @__PURE__ */
|
|
5457
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex h-56 relative bg-white", children: [
|
|
5458
|
+
/* @__PURE__ */ jsx31(
|
|
5159
5459
|
"div",
|
|
5160
5460
|
{
|
|
5161
5461
|
ref: hoursRef,
|
|
5162
5462
|
className: "flex-1 overflow-y-auto no-scrollbar border-r border-secondary-50 scroll-smooth relative",
|
|
5163
|
-
children: /* @__PURE__ */
|
|
5463
|
+
children: /* @__PURE__ */ jsx31("div", { className: "py-2", children: hoursList.map((h) => {
|
|
5164
5464
|
const isSelected = currentHour === h;
|
|
5165
|
-
return /* @__PURE__ */
|
|
5465
|
+
return /* @__PURE__ */ jsx31(
|
|
5166
5466
|
"div",
|
|
5167
5467
|
{
|
|
5168
5468
|
"data-value": h,
|
|
5169
|
-
className:
|
|
5469
|
+
className: clsx28(
|
|
5170
5470
|
"text-center py-2 cursor-pointer transition-all duration-200 text-sm font-medium mx-2 rounded-lg my-1",
|
|
5171
5471
|
isSelected ? "text-slate-900 shadow-sm" : "text-slate-600 hover:text-slate-900"
|
|
5172
5472
|
),
|
|
@@ -5189,18 +5489,18 @@ function ITTimePicker({
|
|
|
5189
5489
|
}) })
|
|
5190
5490
|
}
|
|
5191
5491
|
),
|
|
5192
|
-
/* @__PURE__ */
|
|
5492
|
+
/* @__PURE__ */ jsx31(
|
|
5193
5493
|
"div",
|
|
5194
5494
|
{
|
|
5195
5495
|
ref: minutesRef,
|
|
5196
5496
|
className: "flex-1 overflow-y-auto no-scrollbar scroll-smooth relative",
|
|
5197
|
-
children: /* @__PURE__ */
|
|
5497
|
+
children: /* @__PURE__ */ jsx31("div", { className: "py-2", children: minutesList.map((m) => {
|
|
5198
5498
|
const isSelected = currentMinute === m;
|
|
5199
|
-
return /* @__PURE__ */
|
|
5499
|
+
return /* @__PURE__ */ jsx31(
|
|
5200
5500
|
"div",
|
|
5201
5501
|
{
|
|
5202
5502
|
"data-value": m,
|
|
5203
|
-
className:
|
|
5503
|
+
className: clsx28(
|
|
5204
5504
|
"text-center py-2 cursor-pointer transition-all duration-200 text-sm font-medium mx-2 rounded-lg my-1",
|
|
5205
5505
|
isSelected ? "text-slate-900 shadow-sm" : "text-slate-600 hover:text-slate-900"
|
|
5206
5506
|
),
|
|
@@ -5223,16 +5523,16 @@ function ITTimePicker({
|
|
|
5223
5523
|
}) })
|
|
5224
5524
|
}
|
|
5225
5525
|
),
|
|
5226
|
-
/* @__PURE__ */
|
|
5526
|
+
/* @__PURE__ */ jsx31("div", { className: "absolute top-1/2 left-0 right-0 h-10 -mt-5 bg-black/5 pointer-events-none border-y border-black/10 z-10" })
|
|
5227
5527
|
] }),
|
|
5228
|
-
/* @__PURE__ */
|
|
5528
|
+
/* @__PURE__ */ jsx31("div", { className: "p-3 bg-secondary-50 border-t border-secondary-100 flex justify-end", children: /* @__PURE__ */ jsx31(
|
|
5229
5529
|
ITButton,
|
|
5230
5530
|
{
|
|
5231
5531
|
variant: "solid",
|
|
5232
5532
|
color,
|
|
5233
5533
|
size: "sm",
|
|
5234
5534
|
onClick: handleConfirm,
|
|
5235
|
-
children: /* @__PURE__ */
|
|
5535
|
+
children: /* @__PURE__ */ jsx31(ITText, { as: "span", children: "Aceptar" })
|
|
5236
5536
|
}
|
|
5237
5537
|
) })
|
|
5238
5538
|
]
|
|
@@ -5243,236 +5543,6 @@ function ITTimePicker({
|
|
|
5243
5543
|
] });
|
|
5244
5544
|
}
|
|
5245
5545
|
|
|
5246
|
-
// src/components/molecules/search-select/search-select.tsx
|
|
5247
|
-
import { useState as useState21, useEffect as useEffect11, useRef as useRef16, useMemo as useMemo7 } from "react";
|
|
5248
|
-
import { createPortal as createPortal6 } from "react-dom";
|
|
5249
|
-
import clsx28 from "clsx";
|
|
5250
|
-
import { FaSearch as FaSearch2, FaTimes as FaTimes7 } from "react-icons/fa";
|
|
5251
|
-
import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5252
|
-
function ITSearchSelect({
|
|
5253
|
-
name,
|
|
5254
|
-
options = [],
|
|
5255
|
-
label,
|
|
5256
|
-
placeholder = "Selecciona una opci\xF3n",
|
|
5257
|
-
valueField = "value",
|
|
5258
|
-
labelField = "label",
|
|
5259
|
-
value,
|
|
5260
|
-
onChange,
|
|
5261
|
-
onBlur,
|
|
5262
|
-
disabled = false,
|
|
5263
|
-
className,
|
|
5264
|
-
touched,
|
|
5265
|
-
required,
|
|
5266
|
-
error,
|
|
5267
|
-
readOnly = false,
|
|
5268
|
-
onSearch,
|
|
5269
|
-
isLoading = false,
|
|
5270
|
-
noResultsMessage = "No se encontraron resultados",
|
|
5271
|
-
size = "md",
|
|
5272
|
-
renderOption,
|
|
5273
|
-
clearable = true,
|
|
5274
|
-
onClear
|
|
5275
|
-
}) {
|
|
5276
|
-
const [isOpen, setIsOpen] = useState21(false);
|
|
5277
|
-
const [searchTerm, setSearchTerm] = useState21("");
|
|
5278
|
-
const [isFocused, setIsFocused] = useState21(false);
|
|
5279
|
-
const [localTouched, setLocalTouched] = useState21(false);
|
|
5280
|
-
const containerRef = useRef16(null);
|
|
5281
|
-
const inputWrapperRef = useRef16(null);
|
|
5282
|
-
const timeoutRef = useRef16(null);
|
|
5283
|
-
const { panelRef, style: panelStyle } = useFloatingPanel(inputWrapperRef, isOpen, {
|
|
5284
|
-
estimatedHeight: 260,
|
|
5285
|
-
matchWidth: true
|
|
5286
|
-
});
|
|
5287
|
-
const selectedOption = useMemo7(() => {
|
|
5288
|
-
return options.find((opt) => opt[valueField] === value);
|
|
5289
|
-
}, [options, value, valueField]);
|
|
5290
|
-
useEffect11(() => {
|
|
5291
|
-
if (!isFocused) {
|
|
5292
|
-
setSearchTerm(selectedOption ? String(selectedOption[labelField]) : "");
|
|
5293
|
-
}
|
|
5294
|
-
}, [selectedOption, isFocused, labelField]);
|
|
5295
|
-
useEffect11(() => {
|
|
5296
|
-
function handleClickOutside(event) {
|
|
5297
|
-
const target = event.target;
|
|
5298
|
-
const inContainer = containerRef.current?.contains(target);
|
|
5299
|
-
const inPanel = panelRef.current?.contains(target);
|
|
5300
|
-
if (!inContainer && !inPanel) {
|
|
5301
|
-
setIsOpen(false);
|
|
5302
|
-
}
|
|
5303
|
-
}
|
|
5304
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
5305
|
-
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
5306
|
-
}, []);
|
|
5307
|
-
const selectedLabel = selectedOption ? String(selectedOption[labelField]) : "";
|
|
5308
|
-
const filteredOptions = useMemo7(() => {
|
|
5309
|
-
if (onSearch) return options;
|
|
5310
|
-
if (!searchTerm || !isFocused || searchTerm === selectedLabel) return options;
|
|
5311
|
-
return options.filter(
|
|
5312
|
-
(opt) => String(opt[labelField]).toLowerCase().includes(searchTerm.toLowerCase())
|
|
5313
|
-
);
|
|
5314
|
-
}, [options, searchTerm, selectedLabel, onSearch, labelField, isFocused]);
|
|
5315
|
-
const handleInputChange = (e) => {
|
|
5316
|
-
const query = e.target.value;
|
|
5317
|
-
setSearchTerm(query);
|
|
5318
|
-
setIsOpen(true);
|
|
5319
|
-
if (onSearch) {
|
|
5320
|
-
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5321
|
-
timeoutRef.current = setTimeout(() => {
|
|
5322
|
-
onSearch(query);
|
|
5323
|
-
}, 500);
|
|
5324
|
-
}
|
|
5325
|
-
};
|
|
5326
|
-
const handleSelect = (option) => {
|
|
5327
|
-
if (onChange) {
|
|
5328
|
-
onChange(option[valueField], option);
|
|
5329
|
-
}
|
|
5330
|
-
setSearchTerm(String(option[labelField]));
|
|
5331
|
-
setIsOpen(false);
|
|
5332
|
-
};
|
|
5333
|
-
const handleClear = () => {
|
|
5334
|
-
setSearchTerm("");
|
|
5335
|
-
setIsOpen(true);
|
|
5336
|
-
if (onSearch) onSearch("");
|
|
5337
|
-
if (value !== void 0 && value !== null && value !== "") {
|
|
5338
|
-
onChange?.("", void 0);
|
|
5339
|
-
}
|
|
5340
|
-
onClear?.();
|
|
5341
|
-
};
|
|
5342
|
-
const handleFocus = () => {
|
|
5343
|
-
if (disabled || readOnly) return;
|
|
5344
|
-
setIsFocused(true);
|
|
5345
|
-
setIsOpen(true);
|
|
5346
|
-
};
|
|
5347
|
-
const handleInputBlur = (e) => {
|
|
5348
|
-
setTimeout(() => {
|
|
5349
|
-
setIsFocused(false);
|
|
5350
|
-
setLocalTouched(true);
|
|
5351
|
-
onBlur?.(e);
|
|
5352
|
-
}, 200);
|
|
5353
|
-
};
|
|
5354
|
-
const inputTheme = theme.input || {};
|
|
5355
|
-
const isTouched = touched !== void 0 ? touched : localTouched;
|
|
5356
|
-
const isEmpty = value === void 0 || value === null || String(value).trim() === "";
|
|
5357
|
-
const effectiveError = error !== void 0 && error !== false ? error === true ? "Este campo es requerido" : error : required && isEmpty ? "Este campo es requerido" : void 0;
|
|
5358
|
-
const hasError = isTouched && !!effectiveError;
|
|
5359
|
-
const errorMessage = typeof effectiveError === "string" ? effectiveError : "Este campo es requerido";
|
|
5360
|
-
const showClearButton = clearable && !disabled && !readOnly && (searchTerm.length > 0 || !isEmpty);
|
|
5361
|
-
const getInputStyle = () => {
|
|
5362
|
-
const sizeConfig = inputSizeTokens[size] ?? inputSizeTokens.md;
|
|
5363
|
-
const style = {
|
|
5364
|
-
backgroundColor: inputTheme.backgroundColor || "#ffffff",
|
|
5365
|
-
borderColor: inputTheme.borderColor || "var(--color-secondary-300)",
|
|
5366
|
-
borderRadius: inputTheme.borderRadius || "0.5rem",
|
|
5367
|
-
padding: sizeConfig.padding,
|
|
5368
|
-
fontSize: sizeConfig.fontSize,
|
|
5369
|
-
borderWidth: "1px",
|
|
5370
|
-
borderStyle: "solid",
|
|
5371
|
-
transition: "all 0.2s",
|
|
5372
|
-
color: "var(--it-input-text-color, var(--color-secondary-900))",
|
|
5373
|
-
width: "100%"
|
|
5374
|
-
};
|
|
5375
|
-
if (disabled) {
|
|
5376
|
-
style.backgroundColor = inputTheme.disabled?.backgroundColor || "var(--color-secondary-100)";
|
|
5377
|
-
style.borderColor = inputTheme.disabled?.borderColor || "var(--color-secondary-200)";
|
|
5378
|
-
style.opacity = 0.7;
|
|
5379
|
-
style.cursor = "not-allowed";
|
|
5380
|
-
}
|
|
5381
|
-
if (hasError) {
|
|
5382
|
-
style.borderColor = inputTheme.error?.borderColor || "red";
|
|
5383
|
-
if (isFocused) {
|
|
5384
|
-
style.boxShadow = inputTheme.error?.ring;
|
|
5385
|
-
}
|
|
5386
|
-
} else if (isFocused && !readOnly) {
|
|
5387
|
-
style.boxShadow = inputTheme.focus?.ring;
|
|
5388
|
-
style.borderColor = inputTheme.focus?.borderColor;
|
|
5389
|
-
}
|
|
5390
|
-
return style;
|
|
5391
|
-
};
|
|
5392
|
-
return /* @__PURE__ */ jsxs25("div", { className: clsx28("w-full flex flex-col gap-1.5", className, isOpen && "relative z-30"), ref: containerRef, children: [
|
|
5393
|
-
label && /* @__PURE__ */ jsxs25(
|
|
5394
|
-
ITText,
|
|
5395
|
-
{
|
|
5396
|
-
as: "label",
|
|
5397
|
-
className: clsx28("text-sm font-medium text-secondary-700 dark:text-slate-300", {
|
|
5398
|
-
"text-danger-500": hasError
|
|
5399
|
-
}),
|
|
5400
|
-
children: [
|
|
5401
|
-
/* @__PURE__ */ jsx31(ITText, { as: "span", children: label }),
|
|
5402
|
-
required && /* @__PURE__ */ jsx31(ITText, { as: "span", className: "text-danger-500 ml-1", children: "*" })
|
|
5403
|
-
]
|
|
5404
|
-
}
|
|
5405
|
-
),
|
|
5406
|
-
/* @__PURE__ */ jsxs25("div", { className: "relative", children: [
|
|
5407
|
-
/* @__PURE__ */ jsxs25("div", { ref: inputWrapperRef, className: "relative flex items-center", children: [
|
|
5408
|
-
/* @__PURE__ */ jsx31(
|
|
5409
|
-
"input",
|
|
5410
|
-
{
|
|
5411
|
-
type: "text",
|
|
5412
|
-
name,
|
|
5413
|
-
value: searchTerm,
|
|
5414
|
-
onChange: handleInputChange,
|
|
5415
|
-
onFocus: handleFocus,
|
|
5416
|
-
onBlur: handleInputBlur,
|
|
5417
|
-
disabled,
|
|
5418
|
-
readOnly,
|
|
5419
|
-
placeholder,
|
|
5420
|
-
className: "outline-none pr-10",
|
|
5421
|
-
style: getInputStyle(),
|
|
5422
|
-
autoComplete: "off"
|
|
5423
|
-
}
|
|
5424
|
-
),
|
|
5425
|
-
/* @__PURE__ */ jsxs25("div", { className: "absolute right-3 flex items-center gap-2 text-secondary-400", children: [
|
|
5426
|
-
isLoading && /* @__PURE__ */ jsx31("div", { className: "pointer-events-none animate-spin h-4 w-4 border-2 border-primary-500 border-t-transparent rounded-full" }),
|
|
5427
|
-
!isLoading && showClearButton && /* @__PURE__ */ jsx31(
|
|
5428
|
-
"button",
|
|
5429
|
-
{
|
|
5430
|
-
type: "button",
|
|
5431
|
-
"aria-label": "Limpiar",
|
|
5432
|
-
title: "Limpiar",
|
|
5433
|
-
onMouseDown: (e) => {
|
|
5434
|
-
e.preventDefault();
|
|
5435
|
-
handleClear();
|
|
5436
|
-
},
|
|
5437
|
-
className: "flex items-center justify-center text-secondary-400 hover:text-secondary-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-400 rounded-full",
|
|
5438
|
-
children: /* @__PURE__ */ jsx31(FaTimes7, { size: 14 })
|
|
5439
|
-
}
|
|
5440
|
-
),
|
|
5441
|
-
!isLoading && !showClearButton && /* @__PURE__ */ jsx31(FaSearch2, { size: 14, className: clsx28("pointer-events-none", { "text-primary-500": isFocused }) })
|
|
5442
|
-
] })
|
|
5443
|
-
] }),
|
|
5444
|
-
isOpen && createPortal6(
|
|
5445
|
-
/* @__PURE__ */ jsx31(
|
|
5446
|
-
"div",
|
|
5447
|
-
{
|
|
5448
|
-
ref: panelRef,
|
|
5449
|
-
style: panelStyle,
|
|
5450
|
-
className: "bg-white dark:bg-slate-900 border border-secondary-200 dark:border-slate-800 rounded-lg shadow-xl overflow-hidden animate-in fade-in zoom-in duration-200 origin-top",
|
|
5451
|
-
children: /* @__PURE__ */ jsx31("div", { className: "max-h-60 overflow-y-auto", children: filteredOptions.length > 0 ? filteredOptions.map((option) => {
|
|
5452
|
-
const isSelected = value === option[valueField];
|
|
5453
|
-
return /* @__PURE__ */ jsx31(
|
|
5454
|
-
ITText,
|
|
5455
|
-
{
|
|
5456
|
-
as: "div",
|
|
5457
|
-
onClick: () => handleSelect(option),
|
|
5458
|
-
className: clsx28(
|
|
5459
|
-
"px-4 py-2 text-sm cursor-pointer transition-colors",
|
|
5460
|
-
isSelected ? "bg-primary-50 dark:bg-primary-950/40 text-primary-700 dark:text-primary-300 font-medium" : "hover:bg-secondary-50 dark:hover:bg-slate-800 text-secondary-700 dark:text-slate-300"
|
|
5461
|
-
),
|
|
5462
|
-
children: renderOption ? renderOption(option, { isSelected, searchTerm }) : /* @__PURE__ */ jsx31(ITText, { as: "span", children: option[labelField] })
|
|
5463
|
-
},
|
|
5464
|
-
option[valueField]
|
|
5465
|
-
);
|
|
5466
|
-
}) : /* @__PURE__ */ jsx31(ITText, { as: "div", className: "px-4 py-6 text-sm text-center text-secondary-500 italic", children: isLoading ? "Cargando..." : noResultsMessage }) })
|
|
5467
|
-
}
|
|
5468
|
-
),
|
|
5469
|
-
document.body
|
|
5470
|
-
)
|
|
5471
|
-
] }),
|
|
5472
|
-
hasError && /* @__PURE__ */ jsx31(ITText, { as: "p", className: "text-danger-500 text-xs mt-1", children: errorMessage })
|
|
5473
|
-
] });
|
|
5474
|
-
}
|
|
5475
|
-
|
|
5476
5546
|
// src/components/organisms/form-builder/useFormBuilder.ts
|
|
5477
5547
|
import { useMemo as useMemo8 } from "react";
|
|
5478
5548
|
var useFieldRules = (config2, dependentValues) => {
|
|
@@ -7905,6 +7975,7 @@ import {
|
|
|
7905
7975
|
FaThLarge as FaThLarge2
|
|
7906
7976
|
} from "react-icons/fa";
|
|
7907
7977
|
import { MdOutlineSwapVert as MdOutlineSwapVert2 } from "react-icons/md";
|
|
7978
|
+
import { isSameDay as isSameDay2, startOfDay as startOfDay2, endOfDay } from "date-fns";
|
|
7908
7979
|
import { Fragment as Fragment9, jsx as jsx59, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
7909
7980
|
function ITTable({
|
|
7910
7981
|
columns,
|
|
@@ -7988,15 +8059,32 @@ function ITTable({
|
|
|
7988
8059
|
}, [data, sortConfig, columns]);
|
|
7989
8060
|
const filteredData = sortedData.filter(
|
|
7990
8061
|
(row) => columns.every((col) => {
|
|
7991
|
-
|
|
8062
|
+
const rawFilter = filters[col.key];
|
|
8063
|
+
if (!col.filter || rawFilter === void 0 || rawFilter === "") return true;
|
|
8064
|
+
if (Array.isArray(rawFilter) && rawFilter[0] == null && rawFilter[1] == null) {
|
|
7992
8065
|
return true;
|
|
8066
|
+
}
|
|
7993
8067
|
const value = getNestedValue(row, col.key);
|
|
7994
|
-
|
|
8068
|
+
if (col.filter === "date" || col.filter === "date-range") {
|
|
8069
|
+
const rowDate = value instanceof Date ? value : new Date(String(value));
|
|
8070
|
+
if (isNaN(rowDate.getTime())) return false;
|
|
8071
|
+
if (col.filter === "date") {
|
|
8072
|
+
return isSameDay2(rowDate, rawFilter);
|
|
8073
|
+
}
|
|
8074
|
+
const [start, end] = rawFilter;
|
|
8075
|
+
if (start && rowDate.getTime() < startOfDay2(start).getTime()) return false;
|
|
8076
|
+
if (end && rowDate.getTime() > endOfDay(end).getTime()) return false;
|
|
8077
|
+
return true;
|
|
8078
|
+
}
|
|
8079
|
+
if (col.filter === "search") {
|
|
8080
|
+
return String(value) === String(rawFilter);
|
|
8081
|
+
}
|
|
8082
|
+
const filterValue = String(rawFilter).toLowerCase();
|
|
7995
8083
|
switch (col.type) {
|
|
7996
8084
|
case "number":
|
|
7997
8085
|
return String(value).includes(filterValue);
|
|
7998
8086
|
case "boolean":
|
|
7999
|
-
return value ===
|
|
8087
|
+
return value === rawFilter;
|
|
8000
8088
|
case "catalog": {
|
|
8001
8089
|
if (!col.catalogOptions) return true;
|
|
8002
8090
|
const catalogItem = col.catalogOptions.data.find(
|
|
@@ -8102,6 +8190,75 @@ function ITTable({
|
|
|
8102
8190
|
}
|
|
8103
8191
|
);
|
|
8104
8192
|
}
|
|
8193
|
+
if (col.filter === "search" && col.catalogOptions) {
|
|
8194
|
+
if (col.catalogOptions.loading) {
|
|
8195
|
+
return /* @__PURE__ */ jsx59(
|
|
8196
|
+
FaSpinner3,
|
|
8197
|
+
{
|
|
8198
|
+
className: "animate-spin",
|
|
8199
|
+
"aria-label": "Cargando opciones",
|
|
8200
|
+
title: "Cargando opciones"
|
|
8201
|
+
}
|
|
8202
|
+
);
|
|
8203
|
+
}
|
|
8204
|
+
if (col.catalogOptions.error) {
|
|
8205
|
+
return /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-danger-500 text-xs", children: "Error cargando" });
|
|
8206
|
+
}
|
|
8207
|
+
const searchValue = filters[col.key];
|
|
8208
|
+
return /* @__PURE__ */ jsx59(
|
|
8209
|
+
ITSearchSelect,
|
|
8210
|
+
{
|
|
8211
|
+
name: `filter-${col.key}`,
|
|
8212
|
+
options: col.catalogOptions.data.map((item) => ({
|
|
8213
|
+
value: item.id,
|
|
8214
|
+
label: item.name
|
|
8215
|
+
})),
|
|
8216
|
+
value: typeof searchValue === "string" || typeof searchValue === "number" ? searchValue : "",
|
|
8217
|
+
onChange: (value) => handleFilterChange(col.key, value === "" ? void 0 : value),
|
|
8218
|
+
onSearch: col.catalogOptions.onSearch,
|
|
8219
|
+
isLoading: col.catalogOptions.loading,
|
|
8220
|
+
size: "sm",
|
|
8221
|
+
placeholder: "Buscar...",
|
|
8222
|
+
clearable: true,
|
|
8223
|
+
className: "w-full",
|
|
8224
|
+
onBlur: () => {
|
|
8225
|
+
}
|
|
8226
|
+
}
|
|
8227
|
+
);
|
|
8228
|
+
}
|
|
8229
|
+
if (col.filter === "date") {
|
|
8230
|
+
const dateValue = filters[col.key];
|
|
8231
|
+
return /* @__PURE__ */ jsx59(
|
|
8232
|
+
ITDatePicker,
|
|
8233
|
+
{
|
|
8234
|
+
name: `filter-${col.key}`,
|
|
8235
|
+
value: dateValue instanceof Date ? dateValue : void 0,
|
|
8236
|
+
onChange: (e) => handleFilterChange(col.key, e.target.value),
|
|
8237
|
+
minDate: col.dateFilterOptions?.minDate,
|
|
8238
|
+
maxDate: col.dateFilterOptions?.maxDate,
|
|
8239
|
+
size: "sm",
|
|
8240
|
+
placeholder: "dd/mm/aaaa",
|
|
8241
|
+
className: "w-full"
|
|
8242
|
+
}
|
|
8243
|
+
);
|
|
8244
|
+
}
|
|
8245
|
+
if (col.filter === "date-range") {
|
|
8246
|
+
const rangeValue = filters[col.key];
|
|
8247
|
+
return /* @__PURE__ */ jsx59(
|
|
8248
|
+
ITDatePicker,
|
|
8249
|
+
{
|
|
8250
|
+
name: `filter-${col.key}`,
|
|
8251
|
+
range: true,
|
|
8252
|
+
value: Array.isArray(rangeValue) ? rangeValue : void 0,
|
|
8253
|
+
onChange: (e) => handleFilterChange(col.key, e.target.value),
|
|
8254
|
+
minDate: col.dateFilterOptions?.minDate,
|
|
8255
|
+
maxDate: col.dateFilterOptions?.maxDate,
|
|
8256
|
+
size: "sm",
|
|
8257
|
+
placeholder: "dd/mm/aaaa - dd/mm/aaaa",
|
|
8258
|
+
className: "w-full"
|
|
8259
|
+
}
|
|
8260
|
+
);
|
|
8261
|
+
}
|
|
8105
8262
|
return /* @__PURE__ */ jsx59(
|
|
8106
8263
|
ITInput,
|
|
8107
8264
|
{
|