flysoft-react-ui 0.5.3 → 1.0.0
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/components/form-controls/AutocompleteInput.d.ts.map +1 -1
- package/dist/components/form-controls/AutocompleteInput.js +175 -130
- package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -1
- package/dist/components/form-controls/SearchSelectInput-OLD.js +2 -2
- package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -1
- package/dist/components/form-controls/SearchSelectInput.js +1 -1
- package/dist/components/layout/AppLayout.d.ts.map +1 -1
- package/dist/components/layout/AppLayout.js +7 -7
- package/dist/components/layout/Card.d.ts.map +1 -1
- package/dist/components/layout/Card.js +4 -4
- package/dist/components/layout/DataTable.js +1 -1
- package/dist/components/layout/DropdownMenu.d.ts.map +1 -0
- package/dist/components/{utils → layout}/DropdownMenu.js +12 -6
- package/dist/components/layout/DropdownPanel.d.ts +7 -0
- package/dist/components/layout/DropdownPanel.d.ts.map +1 -0
- package/dist/components/layout/DropdownPanel.js +137 -0
- package/dist/components/{utils → layout}/Filter.d.ts +5 -0
- package/dist/components/layout/Filter.d.ts.map +1 -0
- package/dist/components/{utils → layout}/Filter.js +17 -9
- package/dist/components/layout/Menu.d.ts +31 -0
- package/dist/components/layout/Menu.d.ts.map +1 -0
- package/dist/components/layout/Menu.js +21 -0
- package/dist/components/layout/index.d.ts +8 -0
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/components/layout/index.js +4 -0
- package/dist/components/utils/Dialog.d.ts +2 -2
- package/dist/components/utils/Dialog.d.ts.map +1 -1
- package/dist/components/utils/Dialog.js +2 -2
- package/dist/components/utils/FiltersDialog.d.ts +1 -1
- package/dist/components/utils/FiltersDialog.d.ts.map +1 -1
- package/dist/components/utils/FiltersDialog.js +2 -2
- package/dist/components/utils/index.d.ts +0 -2
- package/dist/components/utils/index.d.ts.map +1 -1
- package/dist/components/utils/index.js +0 -1
- package/dist/contexts/{ListCrudContext.d.ts → CrudContext.d.ts} +20 -8
- package/dist/contexts/CrudContext.d.ts.map +1 -0
- package/dist/contexts/{ListCrudContext.js → CrudContext.js} +102 -22
- package/dist/contexts/index.d.ts +2 -2
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/contexts/index.js +2 -2
- package/dist/docs/DialogDocs.d.ts.map +1 -1
- package/dist/docs/DialogDocs.js +1 -1
- package/dist/docs/DocsMenu.d.ts.map +1 -1
- package/dist/docs/DocsMenu.js +1 -1
- package/dist/docs/DocsRouter.d.ts.map +1 -1
- package/dist/docs/DocsRouter.js +3 -1
- package/dist/docs/DropdownPanelDocs.d.ts +4 -0
- package/dist/docs/DropdownPanelDocs.d.ts.map +1 -0
- package/dist/docs/DropdownPanelDocs.js +7 -0
- package/dist/docs/FilterDocs.d.ts.map +1 -1
- package/dist/docs/FilterDocs.js +19 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +26 -14
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.js +34 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.js +66 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +5 -5
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts +10 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.js +39 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +3 -3
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +4 -4
- package/dist/docs/MenuDocs.d.ts +4 -0
- package/dist/docs/MenuDocs.d.ts.map +1 -0
- package/dist/docs/MenuDocs.js +26 -0
- package/dist/docs/docMockServices/empresaService.d.ts +5 -5
- package/dist/docs/docMockServices/empresaService.d.ts.map +1 -1
- package/dist/docs/docMockServices/empresaService.js +18 -10
- package/dist/docs/docMockServices/interfaces.d.ts +12 -0
- package/dist/docs/docMockServices/interfaces.d.ts.map +1 -1
- package/dist/docs/docMockServices/personaEmpresaService.d.ts +6 -6
- package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +1 -1
- package/dist/docs/docMockServices/personaEmpresaService.js +52 -14
- package/dist/docs/docMockServices/personaService.d.ts +1 -1
- package/dist/docs/docMockServices/personaService.d.ts.map +1 -1
- package/dist/docs/docMockServices/personaService.js +14 -5
- package/dist/index.css +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/dist/components/utils/DropdownMenu.d.ts.map +0 -1
- package/dist/components/utils/Filter.d.ts.map +0 -1
- package/dist/contexts/ListCrudContext.d.ts.map +0 -1
- /package/dist/components/{utils → layout}/DropdownMenu.d.ts +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useState, useRef, useEffect, useCallback, useMemo, } from "react";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
3
4
|
import { Button } from "../form-controls/Button";
|
|
4
5
|
export const DropdownMenu = ({ options, onOptionSelected, renderNode, getOptionLabel, renderOption, replaceOnSingleOption = false, }) => {
|
|
5
6
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -136,10 +137,15 @@ export const DropdownMenu = ({ options, onOptionSelected, renderNode, getOptionL
|
|
|
136
137
|
if (shouldReplace && singleOption) {
|
|
137
138
|
return (_jsx("div", { onClick: () => handleOptionClick(singleOption), className: "cursor-pointer", children: renderOption ? renderOption(singleOption) : labelGetter(singleOption) }));
|
|
138
139
|
}
|
|
139
|
-
return (_jsxs("div", { className: "relative inline-block", ref: triggerRef, children: [_jsx("div", { onClick: handleToggle, className: "cursor-pointer", children: renderNode ? (renderNode) : (_jsx(Button, { variant: "ghost", icon: "fa-ellipsis-h" })) }), isOpen &&
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
140
|
+
return (_jsxs("div", { className: "relative inline-block", ref: triggerRef, children: [_jsx("div", { onClick: handleToggle, className: "cursor-pointer", children: renderNode ? (renderNode) : (_jsx(Button, { variant: "ghost", icon: "fa-ellipsis-h" })) }), isOpen &&
|
|
141
|
+
(typeof document !== "undefined" && document.body
|
|
142
|
+
? createPortal(_jsx("div", { ref: menuRef, className: "fixed z-[2000] bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded-md shadow-[var(--shadow-lg)] py-1 min-w-[160px] font-[var(--font-default)]", style: menuStyles, children: options.map((option, index) => {
|
|
143
|
+
const key = String(option?.id ??
|
|
144
|
+
labelGetter(option) ??
|
|
145
|
+
index);
|
|
146
|
+
return (_jsx("div", { onClick: () => handleOptionClick(option), className: "px-4 py-2 text-sm text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)] cursor-pointer transition-colors flex items-center", children: renderOption
|
|
147
|
+
? renderOption(option)
|
|
148
|
+
: labelGetter(option) }, key));
|
|
149
|
+
}) }), document.body)
|
|
150
|
+
: null)] }));
|
|
145
151
|
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface DropdownPanelProps {
|
|
3
|
+
renderNode?: React.ReactNode;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare const DropdownPanel: ({ renderNode, children, }: DropdownPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=DropdownPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DropdownPanel.d.ts","sourceRoot":"","sources":["../../../src/components/layout/DropdownPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAIf,MAAM,WAAW,kBAAkB;IAC/B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED,eAAO,MAAM,aAAa,GAAI,2BAG3B,kBAAkB,4CAmLpB,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState, useRef, useEffect, useCallback, useMemo, } from "react";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
4
|
+
import { Button } from "../form-controls/Button";
|
|
5
|
+
export const DropdownPanel = ({ renderNode, children, }) => {
|
|
6
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
7
|
+
const [menuPosition, setMenuPosition] = useState("bottom");
|
|
8
|
+
const [scrollUpdate, setScrollUpdate] = useState(0);
|
|
9
|
+
const triggerRef = useRef(null);
|
|
10
|
+
const menuRef = useRef(null);
|
|
11
|
+
// Calcular posición del menú
|
|
12
|
+
const calculatePosition = useCallback(() => {
|
|
13
|
+
if (isOpen && triggerRef.current) {
|
|
14
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
15
|
+
const viewportHeight = window.innerHeight;
|
|
16
|
+
// Intentar obtener la altura real del menú, o usar una estimación si no está montado aún
|
|
17
|
+
let menuHeight = 200; // valor por defecto
|
|
18
|
+
if (menuRef.current) {
|
|
19
|
+
menuHeight = menuRef.current.getBoundingClientRect().height;
|
|
20
|
+
}
|
|
21
|
+
const menuMargin = 4;
|
|
22
|
+
// Calcular espacio disponible arriba y abajo
|
|
23
|
+
const spaceBelow = viewportHeight - triggerRect.bottom - menuMargin;
|
|
24
|
+
const spaceAbove = triggerRect.top - menuMargin;
|
|
25
|
+
// Si no hay suficiente espacio abajo pero sí arriba, mostrar arriba
|
|
26
|
+
if (spaceBelow < menuHeight && spaceAbove > spaceBelow) {
|
|
27
|
+
setMenuPosition("top");
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
setMenuPosition("bottom"); // Preferir abajo si cabe o si es el que más espacio tiene, o por defecto
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}, [isOpen]);
|
|
34
|
+
// Recalcular posición cuando cambia isOpen (y cuando el contenido podría haber cambiado el tamaño)
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
calculatePosition();
|
|
37
|
+
// Podríamos necesitar un ResizeObserver para ser más robustos si el contenido cambia
|
|
38
|
+
}, [calculatePosition]);
|
|
39
|
+
// Recalcular posición al hacer scroll o redimensionar
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (isOpen) {
|
|
42
|
+
const handleScroll = () => {
|
|
43
|
+
calculatePosition();
|
|
44
|
+
// Forzar actualización del estilo del menú
|
|
45
|
+
setScrollUpdate((prev) => prev + 1);
|
|
46
|
+
};
|
|
47
|
+
window.addEventListener("scroll", handleScroll, true);
|
|
48
|
+
window.addEventListener("resize", handleScroll);
|
|
49
|
+
return () => {
|
|
50
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
51
|
+
window.removeEventListener("resize", handleScroll);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}, [isOpen, calculatePosition]);
|
|
55
|
+
// Cerrar menú al hacer click fuera
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const handleClickOutside = (event) => {
|
|
58
|
+
if (isOpen &&
|
|
59
|
+
triggerRef.current &&
|
|
60
|
+
menuRef.current &&
|
|
61
|
+
!triggerRef.current.contains(event.target) &&
|
|
62
|
+
!menuRef.current.contains(event.target)) {
|
|
63
|
+
setIsOpen(false);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
if (isOpen) {
|
|
67
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
68
|
+
}
|
|
69
|
+
return () => {
|
|
70
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
71
|
+
};
|
|
72
|
+
}, [isOpen]);
|
|
73
|
+
// Cerrar menú al presionar Escape
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
const handleEscape = (event) => {
|
|
76
|
+
if (event.key === "Escape" && isOpen) {
|
|
77
|
+
setIsOpen(false);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
if (isOpen) {
|
|
81
|
+
document.addEventListener("keydown", handleEscape);
|
|
82
|
+
}
|
|
83
|
+
return () => {
|
|
84
|
+
document.removeEventListener("keydown", handleEscape);
|
|
85
|
+
};
|
|
86
|
+
}, [isOpen]);
|
|
87
|
+
const handleToggle = () => {
|
|
88
|
+
setIsOpen(!isOpen);
|
|
89
|
+
};
|
|
90
|
+
const menuStyles = useMemo(() => {
|
|
91
|
+
if (!isOpen || !triggerRef.current) {
|
|
92
|
+
return {};
|
|
93
|
+
}
|
|
94
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
95
|
+
const menuMargin = 4;
|
|
96
|
+
// Asegurar que el menú no se salga de la pantalla horizontalmente
|
|
97
|
+
let leftPosition = triggerRect.left;
|
|
98
|
+
const menuMinWidth = 160;
|
|
99
|
+
const viewportWidth = window.innerWidth;
|
|
100
|
+
// Si el menú se sale por la derecha, ajustar la posición
|
|
101
|
+
// Nota: Como el ancho es dinámico (basado en children), idealmente deberíamos medirlo.
|
|
102
|
+
// Usaremos menuRef si está disponible o un estimado.
|
|
103
|
+
let currentMenuWidth = menuMinWidth;
|
|
104
|
+
if (menuRef.current) {
|
|
105
|
+
currentMenuWidth = menuRef.current.getBoundingClientRect().width;
|
|
106
|
+
}
|
|
107
|
+
if (leftPosition + currentMenuWidth > viewportWidth) {
|
|
108
|
+
leftPosition = viewportWidth - currentMenuWidth - 8; // 8px de margen
|
|
109
|
+
}
|
|
110
|
+
// Asegurar que no se salga por la izquierda
|
|
111
|
+
if (leftPosition < 8) {
|
|
112
|
+
leftPosition = 8;
|
|
113
|
+
}
|
|
114
|
+
if (menuPosition === "top") {
|
|
115
|
+
return {
|
|
116
|
+
position: "fixed",
|
|
117
|
+
bottom: window.innerHeight - triggerRect.top + menuMargin,
|
|
118
|
+
left: leftPosition,
|
|
119
|
+
minWidth: Math.max(triggerRect.width, menuMinWidth), // Mantener el minWidth del trigger o 160
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
return {
|
|
124
|
+
position: "fixed",
|
|
125
|
+
top: triggerRect.bottom + menuMargin,
|
|
126
|
+
left: leftPosition,
|
|
127
|
+
minWidth: Math.max(triggerRect.width, menuMinWidth),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// scrollUpdate se usa intencionalmente para forzar el recálculo en scroll
|
|
131
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
132
|
+
}, [isOpen, menuPosition, scrollUpdate]);
|
|
133
|
+
return (_jsxs("div", { className: "relative inline-block", ref: triggerRef, children: [_jsx("div", { onClick: handleToggle, className: "cursor-pointer", children: renderNode ? (renderNode) : (_jsx(Button, { variant: "ghost", icon: "fa-ellipsis-h" })) }), isOpen &&
|
|
134
|
+
(typeof document !== "undefined" && document.body
|
|
135
|
+
? createPortal(_jsx("div", { ref: menuRef, className: "fixed z-[2000] bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded-md shadow-[var(--shadow-lg)] py-1 min-w-[160px] font-[var(--font-default)]", style: menuStyles, children: children }), document.body)
|
|
136
|
+
: null)] }));
|
|
137
|
+
};
|
|
@@ -18,6 +18,11 @@ interface BaseFilterProps {
|
|
|
18
18
|
* Por defecto es false.
|
|
19
19
|
*/
|
|
20
20
|
hideEmpty?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Si es true, el componente se muestra con opacidad y no permite interacciones.
|
|
23
|
+
* Si el panel está abierto, se cerrará automáticamente.
|
|
24
|
+
*/
|
|
25
|
+
disabled?: boolean;
|
|
21
26
|
}
|
|
22
27
|
export interface TextFilterProps extends BaseFilterProps {
|
|
23
28
|
filterType?: "text";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Filter.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Filter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAIvE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAGD,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,UAAU,EAAE,QAAQ,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACzE,SAAQ,eAAe;IACvB,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,UAAU,EAAE,QAAQ,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACzE,SAAQ,eAAe;IACvB,UAAU,EAAE,cAAc,CAAC;IAC3B,iBAAiB,EAAE,CACjB,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,uBAAuB,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC9D,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAGD,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,uBAAuB,GACvB,iBAAiB,GACjB,uBAAuB,CAAC;AAE5B,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAy+BxC,CAAC"}
|
|
@@ -8,10 +8,10 @@ import { Input } from "../form-controls/Input";
|
|
|
8
8
|
import { DateInput } from "../form-controls/DateInput";
|
|
9
9
|
import { AutocompleteInput } from "../form-controls/AutocompleteInput";
|
|
10
10
|
import { SearchSelectInput } from "../form-controls/SearchSelectInput";
|
|
11
|
-
import { DataField } from "
|
|
12
|
-
import { normalizeIconClass } from "
|
|
11
|
+
import { DataField } from "./DataField";
|
|
12
|
+
import { normalizeIconClass } from "../utils/iconUtils";
|
|
13
13
|
export const Filter = (props) => {
|
|
14
|
-
const { paramName, label, staticOptions, inputWidth, value: propValue, onChange, hideEmpty = false, } = props;
|
|
14
|
+
const { paramName, label, staticOptions, inputWidth, value: propValue, onChange, hideEmpty = false, disabled = false, } = props;
|
|
15
15
|
const filterType = props.filterType || "text";
|
|
16
16
|
// Calcular el ancho por defecto según el tipo de filtro
|
|
17
17
|
const defaultInputWidth = filterType === "date" || filterType === "autocomplete" ? "160px" : "200px";
|
|
@@ -158,6 +158,12 @@ export const Filter = (props) => {
|
|
|
158
158
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
159
159
|
};
|
|
160
160
|
}, [isOpen]);
|
|
161
|
+
// Cerrar el panel si el componente se deshabilita
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
if (disabled) {
|
|
164
|
+
setIsOpen(false);
|
|
165
|
+
}
|
|
166
|
+
}, [disabled]);
|
|
161
167
|
const handleSetFilter = () => {
|
|
162
168
|
const newValue = inputValue.trim() || undefined;
|
|
163
169
|
// Si hay onChange, llamarlo con el nuevo valor
|
|
@@ -440,6 +446,8 @@ export const Filter = (props) => {
|
|
|
440
446
|
}
|
|
441
447
|
};
|
|
442
448
|
const handleTogglePanel = () => {
|
|
449
|
+
if (disabled)
|
|
450
|
+
return;
|
|
443
451
|
if (!isOpen) {
|
|
444
452
|
// Calcular posición antes de abrir
|
|
445
453
|
if (containerRef.current) {
|
|
@@ -503,7 +511,7 @@ export const Filter = (props) => {
|
|
|
503
511
|
const badgeContainer = (_jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1.5 h-[2.1rem] rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-default)] text-[var(--color-text-primary)] font-[var(--font-default)] cursor-pointer text-sm transition-colors", onClick: handleTogglePanel, children: [_jsx("span", { className: "text-sm min-w-[1rem]", children: getDisplayValue() || "\u00A0" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "p-0.5 hover:bg-[var(--color-bg-secondary)] rounded transition-colors flex items-center justify-center", children: _jsx("i", { className: `${normalizeIconClass("fa-chevron-down")} text-xs text-[var(--color-text-muted)] hover:text-[var(--color-primary)] transition-all ${isOpen ? "rotate-180" : ""}` }) }), currentValue && (_jsx("button", { onClick: handleClearFilter, className: "p-0.5 hover:bg-[var(--color-bg-secondary)] rounded transition-colors flex items-center justify-center", "aria-label": "Borrar filtro", type: "button", children: _jsx("i", { className: `${normalizeIconClass("fa-times")} text-xs text-[var(--color-text-muted)] hover:text-[var(--color-primary)] transition-colors` }) }))] })] }));
|
|
504
512
|
// Renderizar según el tipo de filtro
|
|
505
513
|
if (filterType === "autocomplete") {
|
|
506
|
-
return (_jsxs("div", { ref: containerRef, className:
|
|
514
|
+
return (_jsxs("div", { ref: containerRef, className: `relative inline-block ${disabled ? "opacity-50 pointer-events-none" : ""}`, children: [_jsx(DataField, { label: label, value: badgeContainer, className: "inline-block" }), isOpen &&
|
|
507
515
|
panelPosition &&
|
|
508
516
|
typeof document !== "undefined" &&
|
|
509
517
|
document.body &&
|
|
@@ -515,10 +523,10 @@ export const Filter = (props) => {
|
|
|
515
523
|
: "text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)]"}`, onMouseDown: (e) => {
|
|
516
524
|
e.preventDefault();
|
|
517
525
|
handleStaticOptionSelect(option);
|
|
518
|
-
}, children: _jsx("span", { className: "font-[var(--font-default)]", children: option.text }) }, option.value))) })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { style: { width: finalInputWidth }, children: _jsx(AutocompleteInput, { ref: autocompleteInputRef, options: props.options, value: isUserTyping ? undefined : autocompleteValue, onChange: handleAutocompleteChange, getOptionLabel: props.getOptionLabel, getOptionValue: props.getOptionValue, renderOption: props.renderOption, noResultsText: props.noResultsText, onSelectOption: handleAutocompleteOptionSelect }) }), _jsx(Button, { onClick: handleAutocompleteSelect, icon: "fa-arrow-right", variant: "ghost" })] })] }) }), document.body)] }));
|
|
526
|
+
}, children: _jsx("span", { className: "font-[var(--font-default)]", children: option.text }) }, option.value))) })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { style: { width: finalInputWidth }, children: _jsx(AutocompleteInput, { ref: autocompleteInputRef, options: props.options, value: isUserTyping ? undefined : autocompleteValue, onChange: handleAutocompleteChange, getOptionLabel: props.getOptionLabel, getOptionValue: props.getOptionValue, renderOption: props.renderOption, noResultsText: props.noResultsText, onSelectOption: handleAutocompleteOptionSelect, disabled: disabled }) }), _jsx(Button, { onClick: handleAutocompleteSelect, icon: "fa-arrow-right", variant: "ghost" })] })] }) }), document.body)] }));
|
|
519
527
|
}
|
|
520
528
|
if (filterType === "date") {
|
|
521
|
-
return (_jsxs("div", { ref: containerRef, className:
|
|
529
|
+
return (_jsxs("div", { ref: containerRef, className: `relative inline-block ${disabled ? "opacity-50 pointer-events-none" : ""}`, children: [_jsx(DataField, { label: label, value: badgeContainer, className: "inline-block" }), isOpen &&
|
|
522
530
|
panelPosition &&
|
|
523
531
|
typeof document !== "undefined" &&
|
|
524
532
|
document.body &&
|
|
@@ -535,7 +543,7 @@ export const Filter = (props) => {
|
|
|
535
543
|
// Para searchSelect
|
|
536
544
|
if (filterType === "searchSelect") {
|
|
537
545
|
const searchSelectProps = props;
|
|
538
|
-
return (_jsxs("div", { ref: containerRef, className:
|
|
546
|
+
return (_jsxs("div", { ref: containerRef, className: `relative inline-block ${disabled ? "opacity-50 pointer-events-none" : ""}`, children: [_jsx(DataField, { label: label, value: badgeContainer, className: "inline-block" }), isOpen &&
|
|
539
547
|
panelPosition &&
|
|
540
548
|
typeof document !== "undefined" &&
|
|
541
549
|
document.body &&
|
|
@@ -554,10 +562,10 @@ export const Filter = (props) => {
|
|
|
554
562
|
// Mostrar X solo si hay un valor actual Y el texto del input coincide con ese valor
|
|
555
563
|
const hasValue = !!currentValue;
|
|
556
564
|
const valueMatches = hasValue && searchValue.trim() === currentValue;
|
|
557
|
-
return (_jsx("div", { ref: containerRef, className:
|
|
565
|
+
return (_jsx("div", { ref: containerRef, className: `relative inline-block ${disabled ? "opacity-50 pointer-events-none" : ""}`, children: _jsx(DataField, { label: label, value: _jsx("div", { style: { width: finalInputWidth }, children: _jsx(Input, { ref: searchInputRef, type: "text", value: searchValue, onChange: handleSearchChange, onKeyDown: handleSearchKeyDown, icon: valueMatches ? "fa-times" : "fa-search", iconPosition: "right", onIconClick: handleSearchIconClick, placeholder: "Buscar...", size: "sm", disabled: disabled }) }), className: "inline-block" }) }));
|
|
558
566
|
}
|
|
559
567
|
// Para text y number
|
|
560
|
-
return (_jsxs("div", { ref: containerRef, className:
|
|
568
|
+
return (_jsxs("div", { ref: containerRef, className: `relative inline-block ${disabled ? "opacity-50 pointer-events-none" : ""}`, children: [_jsx(DataField, { label: label, value: badgeContainer, className: "inline-block" }), isOpen &&
|
|
561
569
|
panelPosition &&
|
|
562
570
|
typeof document !== "undefined" &&
|
|
563
571
|
document.body &&
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface MenuProps<T = {
|
|
3
|
+
label: string;
|
|
4
|
+
}> {
|
|
5
|
+
options: T[];
|
|
6
|
+
onOptionSelected: (item: T) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Obtiene el label que se muestra para cada opción. Por defecto usa la propiedad "label".
|
|
9
|
+
*/
|
|
10
|
+
getOptionLabel?: (item: T) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Renderizado personalizado de cada opción. Si se define, se ignora el render por defecto.
|
|
13
|
+
*/
|
|
14
|
+
renderOption?: (item: T) => React.ReactNode;
|
|
15
|
+
/**
|
|
16
|
+
* Clases adicionales para el contenedor del menú. Permite sobreescribir los estilos por defecto.
|
|
17
|
+
*/
|
|
18
|
+
className?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Estilos adicionales para el contenedor del menú.
|
|
21
|
+
*/
|
|
22
|
+
style?: React.CSSProperties;
|
|
23
|
+
/**
|
|
24
|
+
* Clases adicionales para cada opción del menú.
|
|
25
|
+
*/
|
|
26
|
+
itemClassName?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare const Menu: <T = {
|
|
29
|
+
label: string;
|
|
30
|
+
}>({ options, onOptionSelected, getOptionLabel, renderOption, className, style, itemClassName, }: MenuProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
//# sourceMappingURL=Menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Menu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAG3C,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE;IAC5C,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,gBAAgB,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IACpC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,IAAI,GAAI,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAAG,+FAQ1C,SAAS,CAAC,CAAC,CAAC,4CA8Cd,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useCallback } from "react";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
4
|
+
export const Menu = ({ options, onOptionSelected, getOptionLabel, renderOption, className, style, itemClassName, }) => {
|
|
5
|
+
const labelGetter = useCallback((item) => {
|
|
6
|
+
if (getOptionLabel)
|
|
7
|
+
return getOptionLabel(item);
|
|
8
|
+
const anyItem = item;
|
|
9
|
+
return (anyItem.label ?? "").toString();
|
|
10
|
+
}, [getOptionLabel]);
|
|
11
|
+
const handleOptionClick = (item) => {
|
|
12
|
+
onOptionSelected(item);
|
|
13
|
+
};
|
|
14
|
+
const mergedClassName = twMerge("bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded-md shadow-[var(--shadow-sm)] py-1 min-w-[160px] font-[var(--font-default)] inline-block", className);
|
|
15
|
+
return (_jsx("div", { className: mergedClassName, style: style, children: options.map((option, index) => {
|
|
16
|
+
const key = String(option?.id ??
|
|
17
|
+
labelGetter(option) ??
|
|
18
|
+
index);
|
|
19
|
+
return (_jsx("div", { onClick: () => handleOptionClick(option), className: twMerge("px-4 py-2 text-sm text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)] cursor-pointer transition-colors flex items-center", itemClassName), children: renderOption ? renderOption(option) : labelGetter(option) }, key));
|
|
20
|
+
}) }));
|
|
21
|
+
};
|
|
@@ -14,4 +14,12 @@ export { DataTable } from "./DataTable";
|
|
|
14
14
|
export type { DataTableProps, DataTableColumn } from "./DataTable";
|
|
15
15
|
export { Accordion } from "./Accordion";
|
|
16
16
|
export type { AccordionProps } from "./Accordion";
|
|
17
|
+
export { Menu } from "./Menu";
|
|
18
|
+
export type { MenuProps } from "./Menu";
|
|
19
|
+
export { DropdownMenu } from "./DropdownMenu";
|
|
20
|
+
export type { DropdownMenuProps } from "./DropdownMenu";
|
|
21
|
+
export { DropdownPanel } from "./DropdownPanel";
|
|
22
|
+
export type { DropdownPanelProps } from "./DropdownPanel";
|
|
23
|
+
export { Filter } from "./Filter";
|
|
24
|
+
export type { FilterProps } from "./Filter";
|
|
17
25
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -6,3 +6,7 @@ export { TabsGroup } from "./TabsGroup";
|
|
|
6
6
|
export { TabPanel } from "./TabPanel";
|
|
7
7
|
export { DataTable } from "./DataTable";
|
|
8
8
|
export { Accordion } from "./Accordion";
|
|
9
|
+
export { Menu } from "./Menu";
|
|
10
|
+
export { DropdownMenu } from "./DropdownMenu";
|
|
11
|
+
export { DropdownPanel } from "./DropdownPanel";
|
|
12
|
+
export { Filter } from "./Filter";
|
|
@@ -2,8 +2,8 @@ import React from "react";
|
|
|
2
2
|
export interface DialogProps {
|
|
3
3
|
isOpen: boolean;
|
|
4
4
|
title: React.ReactNode;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
footer?: React.ReactNode;
|
|
7
7
|
onClose?: () => void;
|
|
8
8
|
closeOnOverlayClick?: boolean;
|
|
9
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAGzC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAGzC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA2GxC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useEffect } from "react";
|
|
3
3
|
import { normalizeIconClass } from "./iconUtils";
|
|
4
|
-
export const Dialog = ({ isOpen, title,
|
|
4
|
+
export const Dialog = ({ isOpen, title, children, footer, onClose, closeOnOverlayClick = false, }) => {
|
|
5
5
|
// Prevenir scroll del body cuando el dialog está abierto
|
|
6
6
|
useEffect(() => {
|
|
7
7
|
if (isOpen) {
|
|
@@ -40,5 +40,5 @@ export const Dialog = ({ isOpen, title, dialogBody, dialogActions, onClose, clos
|
|
|
40
40
|
overflowY: "auto",
|
|
41
41
|
overflowX: "visible",
|
|
42
42
|
maxHeight: "calc(90vh - 200px)"
|
|
43
|
-
}, children:
|
|
43
|
+
}, children: children }), footer && (_jsx("div", { className: "px-6 py-4 border-t border-[var(--color-border-default)] flex items-center justify-end gap-2 flex-shrink-0 flex-wrap", children: footer }))] })] }));
|
|
44
44
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FiltersDialog.d.ts","sourceRoot":"","sources":["../../../src/components/utils/FiltersDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"FiltersDialog.d.ts","sourceRoot":"","sources":["../../../src/components/utils/FiltersDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG5D,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,MAAM,CAAC;IACvC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,KAAK,CAAC,SAAS,CAAC;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA+ItD,CAAC"}
|
|
@@ -3,7 +3,7 @@ import React, { useState, useEffect } from "react";
|
|
|
3
3
|
import { useSearchParams } from "react-router-dom";
|
|
4
4
|
import { Button } from "../form-controls/Button";
|
|
5
5
|
import { Dialog } from "./Dialog";
|
|
6
|
-
import { Filter } from "
|
|
6
|
+
import { Filter } from "../layout/Filter";
|
|
7
7
|
import { Collection } from "../layout/Collection";
|
|
8
8
|
export const FiltersDialog = ({ filters }) => {
|
|
9
9
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
@@ -100,5 +100,5 @@ export const FiltersDialog = ({ filters }) => {
|
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
-
return (_jsxs(_Fragment, { children: [_jsx(Button, { icon: "fa-filter", variant: "outline", size: "sm", onClick: handleOpen, "aria-label": "Abrir filtros", children: "Filtrar" }), _jsx(Dialog, { isOpen: isOpen, title: "Filtros",
|
|
103
|
+
return (_jsxs(_Fragment, { children: [_jsx(Button, { icon: "fa-filter", variant: "outline", size: "sm", onClick: handleOpen, "aria-label": "Abrir filtros", children: "Filtrar" }), _jsx(Dialog, { isOpen: isOpen, title: "Filtros", footer: _jsxs(_Fragment, { children: [_jsx(Button, { variant: "outline", onClick: handleClose, children: "Cerrar" }), _jsx(Button, { variant: "primary", onClick: handleApplyFilters, children: "Aplicar filtros" })] }), onClose: handleClose, closeOnOverlayClick: false, children: _jsx("div", { className: "space-y-4", children: _jsx(Collection, { direction: "column", gap: "1rem", children: filters.map((filter) => (_jsx(Filter, { ...getFilterProps(filter) }, filter.paramName))) }) }) })] }));
|
|
104
104
|
};
|
|
@@ -8,8 +8,6 @@ export { Dialog } from "./Dialog";
|
|
|
8
8
|
export type { DialogProps } from "./Dialog";
|
|
9
9
|
export { Loader } from "./Loader";
|
|
10
10
|
export type { LoaderProps } from "./Loader";
|
|
11
|
-
export { Filter } from "./Filter";
|
|
12
|
-
export type { FilterProps } from "./Filter";
|
|
13
11
|
export { FiltersDialog } from "./FiltersDialog";
|
|
14
12
|
export type { FiltersDialogProps, FilterConfig } from "./FiltersDialog";
|
|
15
13
|
export { Snackbar } from "./Snackbar";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -3,7 +3,6 @@ export { Avatar } from "./Avatar";
|
|
|
3
3
|
export { RoadMap } from "./RoadMap";
|
|
4
4
|
export { Dialog } from "./Dialog";
|
|
5
5
|
export { Loader } from "./Loader";
|
|
6
|
-
export { Filter } from "./Filter";
|
|
7
6
|
export { FiltersDialog } from "./FiltersDialog";
|
|
8
7
|
export { Snackbar } from "./Snackbar";
|
|
9
8
|
export { SnackbarContainer } from "./SnackbarContainer";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { type ReactNode } from "react";
|
|
1
|
+
import { type ReactNode, type Dispatch, type SetStateAction } from "react";
|
|
2
2
|
import { type PaginationInterface } from "../components/form-controls/Pagination";
|
|
3
|
-
export interface
|
|
3
|
+
export interface CrudContextType<T> {
|
|
4
4
|
list: Array<T> | undefined;
|
|
5
|
+
item: T | undefined;
|
|
5
6
|
page: number;
|
|
6
7
|
pages: number;
|
|
7
8
|
total: number;
|
|
@@ -9,10 +10,16 @@ export interface ListCrudContextType<T> {
|
|
|
9
10
|
isLoading: boolean;
|
|
10
11
|
pagination: ReactNode;
|
|
11
12
|
params: Record<string, any>;
|
|
13
|
+
extraData?: Record<string, any>;
|
|
14
|
+
setExtraData: Dispatch<SetStateAction<Record<string, any> | undefined>>;
|
|
12
15
|
fetchItems: {
|
|
13
16
|
execute: (params?: Record<string, any>) => Promise<void>;
|
|
14
17
|
isLoading: boolean;
|
|
15
18
|
};
|
|
19
|
+
fetchItem: {
|
|
20
|
+
execute: (params?: Record<string, any> | string | number) => Promise<T | undefined>;
|
|
21
|
+
isLoading: boolean;
|
|
22
|
+
};
|
|
16
23
|
createItem: {
|
|
17
24
|
execute: (item: T) => Promise<T | undefined | null>;
|
|
18
25
|
isLoading: boolean;
|
|
@@ -26,25 +33,30 @@ export interface ListCrudContextType<T> {
|
|
|
26
33
|
isLoading: boolean;
|
|
27
34
|
};
|
|
28
35
|
}
|
|
29
|
-
export declare const
|
|
36
|
+
export declare const CrudContext: import("react").Context<CrudContextType<any> | undefined>;
|
|
30
37
|
export interface PromiseWithOptions<TResult, TParams extends any[] = []> {
|
|
31
38
|
execute: (...params: TParams) => Promise<TResult>;
|
|
32
39
|
successMessage?: string;
|
|
33
40
|
errorMessage?: string;
|
|
34
41
|
}
|
|
35
|
-
interface
|
|
42
|
+
interface CrudProviderProps<T> {
|
|
36
43
|
children: ReactNode;
|
|
37
|
-
getPromise
|
|
44
|
+
getPromise?: ((params?: Record<string, any>) => Promise<Array<T> | PaginationInterface<T> | undefined>) | PromiseWithOptions<Array<T> | PaginationInterface<T> | undefined, [
|
|
38
45
|
params?: Record<string, any>
|
|
39
46
|
]>;
|
|
47
|
+
getItemPromise?: ((params?: Record<string, any> | string | number) => Promise<T | undefined>) | PromiseWithOptions<T | undefined, [
|
|
48
|
+
params?: Record<string, any> | string | number
|
|
49
|
+
]>;
|
|
40
50
|
postPromise?: ((item: T) => Promise<T | undefined | null>) | PromiseWithOptions<T | undefined | null, [item: T]>;
|
|
41
51
|
putPromise?: ((item: T) => Promise<T | undefined | null>) | PromiseWithOptions<T | undefined | null, [item: T]>;
|
|
42
52
|
deletePromise?: ((item: T) => Promise<void>) | PromiseWithOptions<void, [item: T]>;
|
|
43
53
|
urlParams?: Array<string>;
|
|
44
54
|
limit?: number;
|
|
45
55
|
pageParam?: string;
|
|
56
|
+
singleItemId?: string | number;
|
|
57
|
+
extraData?: Record<string, any>;
|
|
46
58
|
}
|
|
47
|
-
export declare function
|
|
48
|
-
export declare function
|
|
59
|
+
export declare function CrudProvider<T>({ children, getPromise, getItemPromise, postPromise, putPromise, deletePromise, limit, pageParam, urlParams, singleItemId, extraData: extraDataProp, }: CrudProviderProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
60
|
+
export declare function useCrud<T>(): CrudContextType<T>;
|
|
49
61
|
export {};
|
|
50
|
-
//# sourceMappingURL=
|
|
62
|
+
//# sourceMappingURL=CrudContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CrudContext.d.ts","sourceRoot":"","sources":["../../src/contexts/CrudContext.tsx"],"names":[],"mappings":"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"}
|