frontend-plus-react 0.5.0 → 0.7.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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/grid/GenericDataGrid.tsx
2
- import { useState as useState15, useEffect as useEffect6, useCallback as useCallback11, useContext as useContext4, useMemo as useMemo10, useRef as useRef7 } from "react";
2
+ import { useState as useState16, useEffect as useEffect6, useCallback as useCallback12, useContext as useContext4, useMemo as useMemo10, useRef as useRef7 } from "react";
3
3
  import { DataGrid } from "react-data-grid";
4
4
  import "react-data-grid/lib/styles.css";
5
5
 
@@ -317,7 +317,7 @@ var useApiCallWithoutSnackbar = () => {
317
317
  };
318
318
 
319
319
  // src/components/grid/GenericDataGrid.tsx
320
- import { CircularProgress as CircularProgress4, Typography as Typography10, Box as Box12, Alert as Alert2, useTheme as useTheme4, Dialog as Dialog4 } from "@mui/material";
320
+ import { CircularProgress as CircularProgress4, Typography as Typography11, Box as Box13, Alert as Alert2, useTheme as useTheme4, Dialog as Dialog5 } from "@mui/material";
321
321
 
322
322
  // src/store/index.ts
323
323
  import { configureStore, combineReducers } from "@reduxjs/toolkit";
@@ -1377,7 +1377,7 @@ function BotonDetalle({ row, rowId, detailTable, deshabilitado }) {
1377
1377
  const { abiertos, alternarDetalle } = useDetallesGrilla();
1378
1378
  if (!cumpleCondicion(detailTable.condition, row)) return /* @__PURE__ */ jsx5("div", { className: "fpr-boton-detalle" });
1379
1379
  const abierto = abiertos.has(claveDetalle(rowId, detailTable));
1380
- const titulo = deshabilitado ? "Grab\xE1 la fila para ver sus detalles" : `${detailTable.label || detailTable.abr}${abierto ? " (replegar)" : ""} \u2014 Ctrl+click: en otra pesta\xF1a`;
1380
+ const titulo = deshabilitado ? "Grab\xE1 la fila para ver sus detalles" : "";
1381
1381
  return /* @__PURE__ */ jsx5(Tooltip, { title: titulo, children: /* @__PURE__ */ jsx5("span", { className: "fpr-boton-detalle", children: /* @__PURE__ */ jsx5(
1382
1382
  IconButton,
1383
1383
  {
@@ -1478,7 +1478,7 @@ var opcionesDeReferencia = (campo, definicionReferenciada, filasReferenciadas, f
1478
1478
  const activo = campoDeActivo(definicionReferenciada);
1479
1479
  const nombres = camposDeNombre(definicionReferenciada);
1480
1480
  const columnasDeEtiqueta = nombres.length > 0 ? [...definicionReferenciada.primaryKey, ...nombres] : definicionReferenciada.primaryKey;
1481
- const opciones = filasReferenciadas.filter((fila) => (activo === null || !!fila[activo]) && anteriores.every((par) => comoTexto(fila[par.target]) === comoTexto(filaActual[par.source]))).map((fila) => {
1481
+ const opciones = filasReferenciadas.filter((fila) => (activo === null || !!fila[activo]) && (filaActual === null || anteriores.every((par) => comoTexto(fila[par.target]) === comoTexto(filaActual[par.source])))).map((fila) => {
1482
1482
  const etiquetas = columnasDeEtiqueta.map((columna) => comoTexto(fila[columna]));
1483
1483
  return { valor: fila[columnaDelValor], etiquetas, texto: `${etiquetas.join(", ")}; ${definicionReferenciada.primaryKey.join(", ")}` };
1484
1484
  });
@@ -1813,7 +1813,8 @@ var useGridMenu = ({
1813
1813
  callApi,
1814
1814
  resetSorting,
1815
1815
  triggerImport,
1816
- triggerExport
1816
+ triggerExport,
1817
+ abrirColumnas
1817
1818
  }) => {
1818
1819
  const { showSuccess, showError, showWarning } = useSnackbar();
1819
1820
  const menuOptions = useMemo4(() => {
@@ -1849,7 +1850,7 @@ var useGridMenu = ({
1849
1850
  label: "ocultar o mostrar columnas",
1850
1851
  icon: React4.createElement(VisibilityOffIcon),
1851
1852
  handler: async () => {
1852
- console.log("Ocultar/mostrar columnas");
1853
+ abrirColumnas?.();
1853
1854
  },
1854
1855
  visible: true
1855
1856
  });
@@ -1898,12 +1899,12 @@ var useGridMenu = ({
1898
1899
  visible: true
1899
1900
  });
1900
1901
  return options;
1901
- }, [tableDefinition, tableName, fixedFields, setTableData, callApi, resetSorting, triggerImport, triggerExport, showSuccess, showError, showWarning]);
1902
+ }, [tableDefinition, tableName, fixedFields, setTableData, callApi, resetSorting, triggerImport, triggerExport, abrirColumnas, showSuccess, showError, showWarning]);
1902
1903
  return { menuOptions };
1903
1904
  };
1904
1905
 
1905
1906
  // src/hooks/grid/useGridColumns.ts
1906
- import React12, { useMemo as useMemo8 } from "react";
1907
+ import React13, { useMemo as useMemo8 } from "react";
1907
1908
 
1908
1909
  // src/utils/functions.tsx
1909
1910
  import * as JSON4all2 from "json4all";
@@ -1969,7 +1970,7 @@ var useVistaGrilla = () => useContext3(VistaGrillaContext);
1969
1970
 
1970
1971
  // src/components/grid/renderers/headerCellRenderers.tsx
1971
1972
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1972
- var defaultColumnHeaderCellRenderer = (props, fieldDef) => {
1973
+ var defaultColumnHeaderCellRenderer = (props, fieldDef, ocultarColumna) => {
1973
1974
  const { column, sortDirection, priority } = props;
1974
1975
  const isPrimaryKey = fieldDef.isPk;
1975
1976
  const sorted = sortDirection !== void 0;
@@ -1984,6 +1985,11 @@ var defaultColumnHeaderCellRenderer = (props, fieldDef) => {
1984
1985
  return /* @__PURE__ */ jsxs5(
1985
1986
  Box3,
1986
1987
  {
1988
+ onClickCapture: (e) => {
1989
+ if (!e.altKey || !ocultarColumna) return;
1990
+ e.stopPropagation();
1991
+ ocultarColumna(fieldDef.name);
1992
+ },
1987
1993
  sx: {
1988
1994
  display: "flex",
1989
1995
  alignItems: "center",
@@ -2061,11 +2067,11 @@ var ActionsColumnHeaderCell = ({
2061
2067
  var detailColumnCellHeaderRenderer = (props, detailTable) => /* @__PURE__ */ jsx6(Tooltip2, { title: detailTable.label, children: /* @__PURE__ */ jsx6(Typography2, { variant: "caption", sx: { fontSize: "0.75rem", fontWeight: "bold" }, children: detailTable.abr.toUpperCase() }) });
2062
2068
 
2063
2069
  // src/components/grid/FilterInputRender.tsx
2064
- import { InputBase, Box as Box4 } from "@mui/material";
2065
- import React6 from "react";
2070
+ import { InputBase as InputBase3, Box as Box4 } from "@mui/material";
2071
+ import React10 from "react";
2066
2072
 
2067
2073
  // src/components/forms/TypedField.tsx
2068
- import { useState as useState7, useEffect as useEffect3, useMemo as useMemo5, useCallback as useCallback7 } from "react";
2074
+ import { useState as useState11, useEffect as useEffect4, useMemo as useMemo6, useCallback as useCallback8 } from "react";
2069
2075
  import {
2070
2076
  TextField,
2071
2077
  FormControl,
@@ -2077,13 +2083,282 @@ import {
2077
2083
  useTheme
2078
2084
  } from "@mui/material";
2079
2085
  import typeStore3 from "type-store";
2080
- import { useRef as useRef4 } from "react";
2086
+ import { useRef as useRef5 } from "react";
2087
+
2088
+ // src/hooks/grid/useExpander.tsx
2089
+ import React8, { useCallback as useCallback7, useState as useState10 } from "react";
2090
+ import IconButton4 from "@mui/material/IconButton";
2091
+ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
2092
+ import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
2093
+ import SearchIcon2 from "@mui/icons-material/Search";
2094
+
2095
+ // src/components/grid/MenuDeOpciones.tsx
2096
+ import { useEffect as useEffect3, useMemo as useMemo5, useRef as useRef4, useState as useState7 } from "react";
2097
+ import { InputBase, List as List2, ListItemButton as ListItemButton2, Popover as Popover2, Typography as Typography3 } from "@mui/material";
2081
2098
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2099
+ function MenuDeOpciones({ anclaje, opciones, busquedaInicial, onElegir, onCerrar }) {
2100
+ const [busqueda, setBusqueda] = useState7(busquedaInicial);
2101
+ const [indice, setIndice] = useState7(0);
2102
+ const visibles = useMemo5(() => filtrarOpciones(opciones, busqueda), [opciones, busqueda]);
2103
+ const elegida = useRef4(null);
2104
+ useEffect3(() => {
2105
+ elegida.current?.scrollIntoView({ block: "nearest" });
2106
+ }, [indice, visibles]);
2107
+ const alApretar = (evento) => {
2108
+ if (evento.key === "ArrowDown") {
2109
+ setIndice((i) => Math.min(i + 1, visibles.length - 1));
2110
+ } else if (evento.key === "ArrowUp") {
2111
+ setIndice((i) => Math.max(i - 1, 0));
2112
+ } else if (evento.key === "Enter") {
2113
+ if (visibles[indice]) onElegir(visibles[indice].valor);
2114
+ } else if (evento.key === "F9" || evento.key === "Escape") {
2115
+ onCerrar();
2116
+ } else {
2117
+ return;
2118
+ }
2119
+ evento.preventDefault();
2120
+ evento.stopPropagation();
2121
+ };
2122
+ return /* @__PURE__ */ jsxs6(
2123
+ Popover2,
2124
+ {
2125
+ open: true,
2126
+ anchorEl: anclaje,
2127
+ onClose: onCerrar,
2128
+ disableRestoreFocus: true,
2129
+ anchorOrigin: { vertical: "bottom", horizontal: "left" },
2130
+ slotProps: { paper: { sx: { minWidth: 300, maxWidth: 520 } } },
2131
+ children: [
2132
+ /* @__PURE__ */ jsx7(
2133
+ InputBase,
2134
+ {
2135
+ autoFocus: true,
2136
+ fullWidth: true,
2137
+ value: busqueda,
2138
+ onChange: (e) => {
2139
+ setBusqueda(e.target.value);
2140
+ setIndice(0);
2141
+ },
2142
+ onKeyDown: alApretar,
2143
+ placeholder: "buscar",
2144
+ sx: { px: 1, py: 0.5, fontSize: "0.8rem", borderBottom: "1px solid #ccc" },
2145
+ inputProps: { "aria-label": "buscar" }
2146
+ }
2147
+ ),
2148
+ /* @__PURE__ */ jsxs6(List2, { dense: true, disablePadding: true, sx: { maxHeight: 320, overflowY: "auto" }, role: "listbox", children: [
2149
+ visibles.length === 0 && /* @__PURE__ */ jsx7(Typography3, { variant: "body2", sx: { p: 1, color: "text.secondary" }, children: "sin coincidencias" }),
2150
+ visibles.map((opcion, i) => /* @__PURE__ */ jsx7(
2151
+ ListItemButton2,
2152
+ {
2153
+ ref: i === indice ? elegida : null,
2154
+ selected: i === indice,
2155
+ role: "option",
2156
+ onClick: () => onElegir(opcion.valor),
2157
+ sx: { gap: 2, py: 0.25, fontSize: "0.8rem" },
2158
+ children: opcion.etiquetas.map((etiqueta, j) => /* @__PURE__ */ jsx7("span", { style: { fontWeight: j === 0 ? 600 : 400, minWidth: j === 0 ? 40 : void 0 }, children: etiqueta }, j))
2159
+ },
2160
+ i
2161
+ ))
2162
+ ] })
2163
+ ]
2164
+ }
2165
+ );
2166
+ }
2167
+
2168
+ // src/components/grid/SelectorDeFecha.tsx
2169
+ import { useState as useState8 } from "react";
2170
+ import { Button as Button2, IconButton as IconButton3, Popover as Popover3, Typography as Typography4 } from "@mui/material";
2171
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2172
+ var MESES = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"];
2173
+ var DIAS = ["lu", "ma", "mi", "ju", "vi", "s\xE1", "do"];
2174
+ var mismaFecha = (a, b) => b !== null && a.anio === b.anio && a.mes === b.mes && a.dia === b.dia;
2175
+ var MOVIMIENTOS = {
2176
+ ArrowLeft: [-1, 0],
2177
+ ArrowRight: [1, 0],
2178
+ ArrowUp: [-7, 0],
2179
+ ArrowDown: [7, 0],
2180
+ PageUp: [0, -1],
2181
+ PageDown: [0, 1]
2182
+ };
2183
+ function SelectorDeFecha({ anclaje, fechaActual, admiteNulo, onElegir, onCerrar }) {
2184
+ const hoy = /* @__PURE__ */ new Date();
2185
+ const fechaDeHoy = { anio: hoy.getFullYear(), mes: hoy.getMonth(), dia: hoy.getDate() };
2186
+ const [cursor, setCursor] = useState8(fechaActual ?? fechaDeHoy);
2187
+ const mover = (dias, meses) => {
2188
+ const nueva = new Date(cursor.anio, cursor.mes + meses, cursor.dia + dias);
2189
+ setCursor({ anio: nueva.getFullYear(), mes: nueva.getMonth(), dia: nueva.getDate() });
2190
+ };
2191
+ const alApretar = (evento) => {
2192
+ if (evento.key in MOVIMIENTOS) {
2193
+ mover(...MOVIMIENTOS[evento.key]);
2194
+ } else if (evento.key === "Enter") {
2195
+ onElegir(fechaATexto(cursor));
2196
+ } else if (evento.key === "F9" || evento.key === "Escape") {
2197
+ onCerrar();
2198
+ } else {
2199
+ return;
2200
+ }
2201
+ evento.preventDefault();
2202
+ evento.stopPropagation();
2203
+ };
2204
+ return /* @__PURE__ */ jsx8(Popover3, { open: true, anchorEl: anclaje, onClose: onCerrar, disableRestoreFocus: true, anchorOrigin: { vertical: "bottom", horizontal: "left" }, children: /* @__PURE__ */ jsxs7("div", { tabIndex: 0, ref: (el) => el?.focus(), onKeyDown: alApretar, style: { padding: 8, outline: "none", width: 252 }, "aria-label": "calendario", children: [
2205
+ /* @__PURE__ */ jsxs7("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
2206
+ /* @__PURE__ */ jsx8(IconButton3, { size: "small", "aria-label": "mes anterior", onClick: () => mover(0, -1), children: "\u2039" }),
2207
+ /* @__PURE__ */ jsxs7(Typography4, { variant: "body2", sx: { fontWeight: 600 }, children: [
2208
+ MESES[cursor.mes],
2209
+ " ",
2210
+ cursor.anio
2211
+ ] }),
2212
+ /* @__PURE__ */ jsx8(IconButton3, { size: "small", "aria-label": "mes siguiente", onClick: () => mover(0, 1), children: "\u203A" })
2213
+ ] }),
2214
+ /* @__PURE__ */ jsxs7("table", { style: { borderCollapse: "collapse", width: "100%", textAlign: "center", fontSize: "0.8rem" }, children: [
2215
+ /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsx8("tr", { children: DIAS.map((d) => /* @__PURE__ */ jsx8("th", { style: { fontWeight: 400, color: "#777" }, children: d }, d)) }) }),
2216
+ /* @__PURE__ */ jsx8("tbody", { children: semanasDelMes(cursor.anio, cursor.mes).map((semana, i) => /* @__PURE__ */ jsx8("tr", { children: semana.map((dia) => {
2217
+ const elegido = mismaFecha(dia, fechaActual);
2218
+ const enCursor = mismaFecha(dia, cursor);
2219
+ return /* @__PURE__ */ jsx8("td", { style: { padding: 1 }, children: /* @__PURE__ */ jsx8(
2220
+ "button",
2221
+ {
2222
+ type: "button",
2223
+ tabIndex: -1,
2224
+ onClick: () => onElegir(fechaATexto(dia)),
2225
+ style: {
2226
+ width: 32,
2227
+ height: 26,
2228
+ border: enCursor ? "1px solid #1976d2" : "1px solid transparent",
2229
+ borderRadius: 4,
2230
+ cursor: "pointer",
2231
+ background: elegido ? "#1976d2" : "transparent",
2232
+ color: elegido ? "#fff" : dia.delMesMostrado ? "#000" : "#aaa"
2233
+ },
2234
+ children: dia.dia
2235
+ }
2236
+ ) }, `${dia.mes}-${dia.dia}`);
2237
+ }) }, i)) })
2238
+ ] }),
2239
+ /* @__PURE__ */ jsxs7("div", { style: { display: "flex", justifyContent: "space-between", marginTop: 4 }, children: [
2240
+ /* @__PURE__ */ jsx8(Button2, { size: "small", onClick: () => onElegir(fechaATexto(fechaDeHoy)), children: "hoy" }),
2241
+ admiteNulo && /* @__PURE__ */ jsx8(Button2, { size: "small", onClick: () => onElegir(null), children: "vac\xEDo" })
2242
+ ] })
2243
+ ] }) });
2244
+ }
2245
+
2246
+ // src/components/grid/VentanaDeTexto.tsx
2247
+ import { useState as useState9 } from "react";
2248
+ import { Button as Button3, InputBase as InputBase2, Popover as Popover4 } from "@mui/material";
2249
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2250
+ function VentanaDeTexto({ anclaje, texto, editable, onAceptar, onCerrar }) {
2251
+ const [valor, setValor] = useState9(texto);
2252
+ const alApretar = (evento) => {
2253
+ if (evento.key === "Escape" || evento.key === "F9") {
2254
+ onCerrar();
2255
+ } else if (evento.key === "Enter" && evento.ctrlKey && editable) {
2256
+ onAceptar(valor);
2257
+ } else {
2258
+ return;
2259
+ }
2260
+ evento.preventDefault();
2261
+ evento.stopPropagation();
2262
+ };
2263
+ return /* @__PURE__ */ jsx9(Popover4, { open: true, anchorEl: anclaje, onClose: onCerrar, disableRestoreFocus: true, anchorOrigin: { vertical: "bottom", horizontal: "left" }, children: /* @__PURE__ */ jsxs8("div", { style: { padding: 8, minWidth: 320, maxWidth: 640 }, children: [
2264
+ /* @__PURE__ */ jsx9(
2265
+ InputBase2,
2266
+ {
2267
+ autoFocus: true,
2268
+ multiline: true,
2269
+ fullWidth: true,
2270
+ readOnly: !editable,
2271
+ value: valor,
2272
+ onChange: (e) => setValor(e.target.value),
2273
+ onKeyDown: alApretar,
2274
+ minRows: 2,
2275
+ maxRows: 16,
2276
+ sx: { fontFamily: "monospace", fontSize: "0.8rem", border: "1px solid #ccc", borderRadius: "4px", p: 0.5 },
2277
+ inputProps: { "aria-label": "contenido de la celda" }
2278
+ }
2279
+ ),
2280
+ editable && /* @__PURE__ */ jsxs8("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 4 }, children: [
2281
+ /* @__PURE__ */ jsx9(Button3, { size: "small", onClick: onCerrar, children: "cancelar" }),
2282
+ /* @__PURE__ */ jsx9(Button3, { size: "small", variant: "contained", onClick: () => onAceptar(valor), children: "aceptar" })
2283
+ ] })
2284
+ ] }) });
2285
+ }
2286
+
2287
+ // src/hooks/grid/useExpander.tsx
2288
+ import { jsx as jsx10 } from "react/jsx-runtime";
2289
+ var useExpander = ({ campo, editable, fila, admiteNulo, tipos, anclaje, textoActual, valorActual, alElegirValor, alConfirmarTexto, alFallar }) => {
2290
+ const [expansion, setExpansion] = useState10(null);
2291
+ const abierto = React8.useRef(false);
2292
+ const tipoDelCampo = tipoDeExpander(campo, editable);
2293
+ const tipo = tipoDelCampo === null || tipoDelCampo === "json" || tipos && !tipos.includes(tipoDelCampo) ? null : tipoDelCampo;
2294
+ const abrir = useCallback7(async (busqueda) => {
2295
+ if (tipo === null || abierto.current) return;
2296
+ abierto.current = true;
2297
+ try {
2298
+ if (tipo === "referencia" && esCampoConReferencia(campo)) {
2299
+ const { definicion, filas } = await cargarReferencia(campo.references);
2300
+ setExpansion({ tipo: "opciones", opciones: opcionesDeReferencia(campo, definicion, filas, fila, admiteNulo), busqueda });
2301
+ } else if (tipo === "booleano") {
2302
+ setExpansion({ tipo: "opciones", opciones: opcionesDeBooleano(admiteNulo), busqueda });
2303
+ } else if (tipo === "opciones") {
2304
+ setExpansion({ tipo: "opciones", opciones: opcionesDeEnumerado(campo.options ?? [], admiteNulo), busqueda });
2305
+ } else {
2306
+ setExpansion({ tipo: tipo === "fecha" ? "fecha" : "texto" });
2307
+ }
2308
+ } catch (err) {
2309
+ abierto.current = false;
2310
+ alFallar(mensajeDeError(err));
2311
+ }
2312
+ }, [tipo, campo, fila, admiteNulo, alFallar]);
2313
+ const cerrar = useCallback7(() => {
2314
+ abierto.current = false;
2315
+ setExpansion(null);
2316
+ setTimeout(() => anclaje.current?.focus(), 0);
2317
+ }, [anclaje]);
2318
+ const elegirValor = useCallback7((valor) => {
2319
+ cerrar();
2320
+ alElegirValor(valor);
2321
+ }, [cerrar, alElegirValor]);
2322
+ const confirmarTexto = useCallback7((texto) => {
2323
+ cerrar();
2324
+ alConfirmarTexto(texto);
2325
+ }, [cerrar, alConfirmarTexto]);
2326
+ const manejarTecla = useCallback7((event) => {
2327
+ const esExpander = event.key === "F9" && !event.shiftKey && !event.ctrlKey && !event.altKey || event.key === "ArrowDown" && event.altKey && !event.shiftKey && !event.ctrlKey;
2328
+ if (tipo === null || !esExpander) return false;
2329
+ event.preventDefault();
2330
+ void abrir("");
2331
+ return true;
2332
+ }, [tipo, abrir]);
2333
+ const titulo = tipo === "fecha" ? "elegir fecha (F9)" : tipo === "texto" ? "ver el contenido completo (F9)" : "elegir un valor (F9)";
2334
+ const lupa = tipo === null ? null : /* @__PURE__ */ jsx10(
2335
+ IconButton4,
2336
+ {
2337
+ size: "small",
2338
+ tabIndex: -1,
2339
+ "aria-label": titulo.replace(" (F9)", ""),
2340
+ title: titulo,
2341
+ onMouseDown: (e) => e.preventDefault(),
2342
+ onClick: (e) => {
2343
+ e.stopPropagation();
2344
+ void abrir("");
2345
+ },
2346
+ sx: { p: 0, ml: 0.25, color: "primary.main", "&:hover": { backgroundColor: "action.hover" } },
2347
+ children: tipo === "fecha" ? /* @__PURE__ */ jsx10(CalendarMonthIcon, { sx: { fontSize: 16 } }) : tipo === "texto" ? /* @__PURE__ */ jsx10(SearchIcon2, { sx: { fontSize: 16 } }) : /* @__PURE__ */ jsx10(ArrowDropDownIcon, { sx: { fontSize: 20 } })
2348
+ }
2349
+ );
2350
+ const base = anclaje.current;
2351
+ const ventana = !expansion || !base ? null : expansion.tipo === "opciones" ? /* @__PURE__ */ jsx10(MenuDeOpciones, { anclaje: base, opciones: expansion.opciones, busquedaInicial: expansion.busqueda, onElegir: elegirValor, onCerrar: cerrar }) : expansion.tipo === "fecha" ? /* @__PURE__ */ jsx10(SelectorDeFecha, { anclaje: base, fechaActual: fechaDeValor(valorActual), admiteNulo, onElegir: confirmarTexto, onCerrar: cerrar }) : /* @__PURE__ */ jsx10(VentanaDeTexto, { anclaje: base, texto: textoActual, editable: true, onAceptar: confirmarTexto, onCerrar: cerrar });
2352
+ return { tipo, abierto, abrir, manejarTecla, lupa, ventana };
2353
+ };
2354
+
2355
+ // src/components/forms/TypedField.tsx
2356
+ import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
2082
2357
  var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode = false, feedback, isMandatory = false }) => {
2083
2358
  const theme = useTheme();
2084
- const typer = useMemo5(() => typeStore3.typerFrom(fieldDef), [fieldDef]);
2085
- const isBoolean = fieldDef.typeName === "boolean";
2086
- const [localString, setLocalString] = useState7(() => {
2359
+ const typer = useMemo6(() => typeStore3.typerFrom(fieldDef), [fieldDef]);
2360
+ const isBoolean = fieldDef.typeName === "boolean" && !isFilterMode;
2361
+ const [localString, setLocalString] = useState11(() => {
2087
2362
  if (isBoolean) return "";
2088
2363
  if (isFilterMode) return value !== null && value !== void 0 ? String(value) : "";
2089
2364
  try {
@@ -2092,10 +2367,10 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2092
2367
  return value === null || value === void 0 ? "" : String(value);
2093
2368
  }
2094
2369
  });
2095
- const [errorMsg, setErrorMsg] = useState7(null);
2096
- const lastValueRef = useRef4(value);
2097
- const lastCommittedStringRef = useRef4(localString);
2098
- useEffect3(() => {
2370
+ const [errorMsg, setErrorMsg] = useState11(null);
2371
+ const lastValueRef = useRef5(value);
2372
+ const lastCommittedStringRef = useRef5(localString);
2373
+ useEffect4(() => {
2099
2374
  if (!isBoolean) {
2100
2375
  if (value !== lastValueRef.current) {
2101
2376
  lastValueRef.current = value;
@@ -2112,7 +2387,27 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2112
2387
  }
2113
2388
  }
2114
2389
  }, [value, typer, isBoolean, isFilterMode]);
2115
- const handleTextChange = useCallback7((e) => {
2390
+ const entradaRef = useRef5(null);
2391
+ const [enfocado, setEnfocado] = useState11(false);
2392
+ const escribirEnFiltro = useCallback8((texto) => {
2393
+ setLocalString(texto);
2394
+ lastValueRef.current = texto;
2395
+ onChange(fieldDef.name, texto, true);
2396
+ }, [onChange, fieldDef.name]);
2397
+ const expander = useExpander({
2398
+ campo: fieldDef,
2399
+ editable: true,
2400
+ fila: null,
2401
+ admiteNulo: false,
2402
+ tipos: isFilterMode ? ["referencia", "booleano", "opciones", "fecha"] : [],
2403
+ anclaje: entradaRef,
2404
+ textoActual: localString,
2405
+ valorActual: localString,
2406
+ alElegirValor: (valor) => escribirEnFiltro(valor === null || valor === void 0 ? "" : typeof valor === "boolean" ? typer.toLocalString(valor) : String(valor)),
2407
+ alConfirmarTexto: (texto) => escribirEnFiltro(texto ?? ""),
2408
+ alFallar: (mensaje) => setErrorMsg(mensaje)
2409
+ });
2410
+ const handleTextChange = useCallback8((e) => {
2116
2411
  const newValueString = e.target.value;
2117
2412
  setLocalString(newValueString);
2118
2413
  let parsedValue = null;
@@ -2133,7 +2428,7 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2133
2428
  lastValueRef.current = parsedValue;
2134
2429
  onChange(fieldDef.name, parsedValue, isValid);
2135
2430
  }, [typer, onChange, fieldDef.name, isFilterMode]);
2136
- const handleTextCommit = useCallback7(() => {
2431
+ const handleTextCommit = useCallback8(() => {
2137
2432
  if (!onCommit) return;
2138
2433
  if (localString === lastCommittedStringRef.current) return;
2139
2434
  lastCommittedStringRef.current = localString;
@@ -2151,13 +2446,14 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2151
2446
  }
2152
2447
  onCommit(fieldDef.name, parsedValue, isValid);
2153
2448
  }, [onCommit, fieldDef.name, localString, isFilterMode, typer]);
2154
- const handleTextKeyDown = useCallback7((e) => {
2449
+ const handleTextKeyDown = useCallback8((e) => {
2450
+ if (expander.manejarTecla(e)) return;
2155
2451
  if (e.key === "Enter") {
2156
2452
  e.preventDefault();
2157
2453
  handleTextCommit();
2158
2454
  }
2159
- }, [handleTextCommit]);
2160
- const handleBooleanChange = useCallback7((e) => {
2455
+ }, [handleTextCommit, expander]);
2456
+ const handleBooleanChange = useCallback8((e) => {
2161
2457
  const val = e.target.value;
2162
2458
  let finalValue = null;
2163
2459
  if (val === "true") finalValue = true;
@@ -2185,28 +2481,28 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2185
2481
  }
2186
2482
  const cellBackgroundColor2 = feedback === "error" ? theme.palette.error.light : feedback === "success" ? theme.palette.success.light : defaultBgColor;
2187
2483
  const transitionStyle2 = "background-color 0.3s ease-in-out";
2188
- return /* @__PURE__ */ jsxs6(FormControl, { fullWidth: true, error: !!errorMsg && !isFilterMode, disabled: isDisabled, size: "small", margin: "dense", children: [
2189
- !isFilterMode && /* @__PURE__ */ jsx7(InputLabel, { shrink: true, children: fieldDef.name }),
2190
- /* @__PURE__ */ jsxs6(
2484
+ return /* @__PURE__ */ jsxs9(FormControl, { fullWidth: true, error: !!errorMsg && !isFilterMode, disabled: isDisabled, size: "small", margin: "dense", children: [
2485
+ !isFilterMode && /* @__PURE__ */ jsx11(InputLabel, { shrink: true, children: fieldDef.name }),
2486
+ /* @__PURE__ */ jsxs9(
2191
2487
  Select,
2192
2488
  {
2193
2489
  value: boolVal,
2194
2490
  label: !isFilterMode ? fieldDef.name : void 0,
2195
2491
  onChange: handleBooleanChange,
2196
- startAdornment: isMandatory && isEmpty && !isFilterMode ? /* @__PURE__ */ jsx7(InputAdornment, { position: "start", sx: { color: "text.secondary", ml: 0.5 }, children: "*" }) : void 0,
2492
+ startAdornment: isMandatory && isEmpty && !isFilterMode ? /* @__PURE__ */ jsx11(InputAdornment, { position: "start", sx: { color: "text.secondary", ml: 0.5 }, children: "*" }) : void 0,
2197
2493
  displayEmpty: true,
2198
2494
  sx: isFilterMode ? { height: 25, fontSize: "0.8rem", backgroundColor: "background.paper" } : {
2199
2495
  backgroundColor: cellBackgroundColor2,
2200
2496
  transition: transitionStyle2
2201
2497
  },
2202
2498
  children: [
2203
- fieldDef.nullable !== false && /* @__PURE__ */ jsx7(MenuItem, { value: "", children: /* @__PURE__ */ jsx7("em", { children: "Nulo / Sin Especificar" }) }),
2204
- /* @__PURE__ */ jsx7(MenuItem, { value: "true", children: "S\xED (Verdadero)" }),
2205
- /* @__PURE__ */ jsx7(MenuItem, { value: "false", children: "No (Falso)" })
2499
+ fieldDef.nullable !== false && /* @__PURE__ */ jsx11(MenuItem, { value: "", children: /* @__PURE__ */ jsx11("em", { children: "Nulo / Sin Especificar" }) }),
2500
+ /* @__PURE__ */ jsx11(MenuItem, { value: "true", children: "S\xED (Verdadero)" }),
2501
+ /* @__PURE__ */ jsx11(MenuItem, { value: "false", children: "No (Falso)" })
2206
2502
  ]
2207
2503
  }
2208
2504
  ),
2209
- errorMsg && !isFilterMode && /* @__PURE__ */ jsx7(FormHelperText, { children: errorMsg })
2505
+ errorMsg && !isFilterMode && /* @__PURE__ */ jsx11(FormHelperText, { children: errorMsg })
2210
2506
  ] });
2211
2507
  }
2212
2508
  let inputType = "text";
@@ -2220,54 +2516,65 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2220
2516
  }
2221
2517
  const cellBackgroundColor = feedback === "error" ? theme.palette.error.light : feedback === "success" ? theme.palette.success.light : defaultTextBgColor;
2222
2518
  const transitionStyle = "background-color 0.3s ease-in-out";
2223
- return /* @__PURE__ */ jsx7(
2224
- TextField,
2225
- {
2226
- fullWidth: true,
2227
- type: inputType,
2228
- label: isFilterMode ? void 0 : fieldDef.name,
2229
- variant: "outlined",
2230
- size: "small",
2231
- margin: isFilterMode ? "none" : "dense",
2232
- value: localString,
2233
- onChange: handleTextChange,
2234
- disabled: isDisabled,
2235
- error: !!errorMsg && !isFilterMode,
2236
- helperText: !isFilterMode ? errorMsg || (isMandatory ? "Obligatorio" : "") : void 0,
2237
- InputLabelProps: !isFilterMode ? { shrink: true } : void 0,
2238
- InputProps: !isFilterMode && isMandatory && isEmptyText ? {
2239
- startAdornment: /* @__PURE__ */ jsx7(InputAdornment, { position: "start", sx: { color: "text.secondary", mr: 0.5 }, children: "*" })
2240
- } : {},
2241
- inputProps: {
2242
- style: {
2243
- textAlign: isNumericType(fieldDef.typeName) ? "right" : "left"
2244
- }
2245
- },
2246
- sx: isFilterMode ? {
2247
- "& .MuiOutlinedInput-root": {
2248
- backgroundColor: "background.paper",
2249
- height: FILTER_ROW_HEIGHT - 5,
2250
- minWidth: 50,
2251
- fontSize: "0.8rem",
2252
- padding: "0px"
2253
- }
2254
- } : {
2255
- "& .MuiOutlinedInput-root": {
2256
- backgroundColor: cellBackgroundColor,
2257
- transition: transitionStyle
2519
+ return /* @__PURE__ */ jsxs9(Fragment3, { children: [
2520
+ /* @__PURE__ */ jsx11(
2521
+ TextField,
2522
+ {
2523
+ fullWidth: true,
2524
+ inputRef: entradaRef,
2525
+ type: inputType,
2526
+ label: isFilterMode ? void 0 : fieldDef.name,
2527
+ variant: "outlined",
2528
+ size: "small",
2529
+ margin: isFilterMode ? "none" : "dense",
2530
+ value: localString,
2531
+ onChange: handleTextChange,
2532
+ disabled: isDisabled,
2533
+ error: !!errorMsg && !isFilterMode,
2534
+ helperText: !isFilterMode ? errorMsg || (isMandatory ? "Obligatorio" : "") : void 0,
2535
+ InputLabelProps: !isFilterMode ? { shrink: true } : void 0,
2536
+ InputProps: isFilterMode ? {
2537
+ // la lupa solo al enfocar el filtro, como en backend-plus
2538
+ endAdornment: enfocado || expander.abierto.current ? expander.lupa : void 0
2539
+ } : isMandatory && isEmptyText ? {
2540
+ startAdornment: /* @__PURE__ */ jsx11(InputAdornment, { position: "start", sx: { color: "text.secondary", mr: 0.5 }, children: "*" })
2541
+ } : {},
2542
+ inputProps: {
2543
+ style: {
2544
+ textAlign: isNumericType(fieldDef.typeName) ? "right" : "left"
2545
+ }
2258
2546
  },
2259
- "& .MuiOutlinedInput-input": {
2260
- padding: "6px 12px"
2261
- }
2262
- },
2263
- onBlur: handleTextCommit,
2264
- onKeyDown: handleTextKeyDown
2265
- }
2266
- );
2547
+ sx: isFilterMode ? {
2548
+ "& .MuiOutlinedInput-root": {
2549
+ backgroundColor: "background.paper",
2550
+ height: FILTER_ROW_HEIGHT - 5,
2551
+ minWidth: 50,
2552
+ fontSize: "0.8rem",
2553
+ padding: "0px"
2554
+ }
2555
+ } : {
2556
+ "& .MuiOutlinedInput-root": {
2557
+ backgroundColor: cellBackgroundColor,
2558
+ transition: transitionStyle
2559
+ },
2560
+ "& .MuiOutlinedInput-input": {
2561
+ padding: "6px 12px"
2562
+ }
2563
+ },
2564
+ onFocus: () => setEnfocado(true),
2565
+ onBlur: () => {
2566
+ setEnfocado(false);
2567
+ handleTextCommit();
2568
+ },
2569
+ onKeyDown: handleTextKeyDown
2570
+ }
2571
+ ),
2572
+ expander.ventana
2573
+ ] });
2267
2574
  };
2268
2575
 
2269
2576
  // src/components/grid/FilterInputRender.tsx
2270
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2577
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2271
2578
  function FilterInputRenderer({
2272
2579
  columnKey,
2273
2580
  currentFilter,
@@ -2290,8 +2597,8 @@ function FilterInputRenderer({
2290
2597
  [columnKey]: { operator: newOp, value: formattedVal }
2291
2598
  }));
2292
2599
  };
2293
- return /* @__PURE__ */ jsxs7(Box4, { sx: { mt: 0, display: "flex", alignItems: "center", gap: 0.5, pr: 1 }, children: [
2294
- /* @__PURE__ */ jsx8(
2600
+ return /* @__PURE__ */ jsxs10(Box4, { sx: { mt: 0, display: "flex", alignItems: "center", gap: 0.5, pr: 1 }, children: [
2601
+ /* @__PURE__ */ jsx12(
2295
2602
  "select",
2296
2603
  {
2297
2604
  value: operator,
@@ -2307,10 +2614,10 @@ function FilterInputRenderer({
2307
2614
  textAlign: "center",
2308
2615
  cursor: "pointer"
2309
2616
  },
2310
- children: filterOperators.map((op) => /* @__PURE__ */ jsx8("option", { value: op.value, children: op.label }, op.value))
2617
+ children: filterOperators.map((op) => /* @__PURE__ */ jsx12("option", { value: op.value, children: op.label }, op.value))
2311
2618
  }
2312
2619
  ),
2313
- /* @__PURE__ */ jsx8(
2620
+ /* @__PURE__ */ jsx12(
2314
2621
  TypedField,
2315
2622
  {
2316
2623
  fieldDef,
@@ -2321,8 +2628,8 @@ function FilterInputRenderer({
2321
2628
  )
2322
2629
  ] });
2323
2630
  }
2324
- return /* @__PURE__ */ jsx8(
2325
- InputBase,
2631
+ return /* @__PURE__ */ jsx12(
2632
+ InputBase3,
2326
2633
  {
2327
2634
  value: currentFilter || "",
2328
2635
  onChange: (e) => setFilters((prev) => ({
@@ -2344,18 +2651,18 @@ function FilterInputRenderer({
2344
2651
  }
2345
2652
  );
2346
2653
  }
2347
- var FilterInputRender_default = React6.memo(FilterInputRenderer);
2654
+ var FilterInputRender_default = React10.memo(FilterInputRenderer);
2348
2655
 
2349
2656
  // src/components/grid/renderers/summaryCellRenderers.tsx
2350
2657
  import { Box as Box5 } from "@mui/material";
2351
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2658
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
2352
2659
  var defaultColumnSummaryCellRenderer = (props, fixedFields) => {
2353
2660
  const { column, row } = props;
2354
2661
  if (row.id === "filterRow") {
2355
2662
  const { filters, setFilters } = row;
2356
2663
  if (valorFijoDe(fixedFields, column.key)) return null;
2357
2664
  const fieldDef = esColumnaPropia(column) && column.customType === "default" ? column.fieldDef : void 0;
2358
- return /* @__PURE__ */ jsx9(Box5, { sx: { width: "100%", height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(
2665
+ return /* @__PURE__ */ jsx13(Box5, { sx: { width: "100%", height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx13(
2359
2666
  FilterInputRender_default,
2360
2667
  {
2361
2668
  columnKey: column.key,
@@ -2397,7 +2704,7 @@ var defaultColumnSummaryCellRenderer = (props, fixedFields) => {
2397
2704
  label = "Cant S\xED: ";
2398
2705
  break;
2399
2706
  }
2400
- return /* @__PURE__ */ jsxs8(Box5, { sx: {
2707
+ return /* @__PURE__ */ jsxs11(Box5, { sx: {
2401
2708
  px: 0,
2402
2709
  fontWeight: "bold",
2403
2710
  fontSize: "0.875rem",
@@ -2415,35 +2722,35 @@ var actionsColumnSummaryCellRenderer = (_props) => null;
2415
2722
  var detailColumnCellSummaryRenderer = (_props) => null;
2416
2723
 
2417
2724
  // src/components/grid/renderers/cellRenderers.tsx
2418
- import React7 from "react";
2419
- import { Box as Box8, Button as Button2, Tooltip as Tooltip4, useTheme as useTheme2 } from "@mui/material";
2725
+ import React11 from "react";
2726
+ import { Box as Box8, Button as Button4, Tooltip as Tooltip4, useTheme as useTheme2 } from "@mui/material";
2420
2727
  import ViewHeadlineIcon from "@mui/icons-material/ViewHeadline";
2421
2728
  import DeleteIcon from "@mui/icons-material/Delete";
2422
2729
  import AddIcon2 from "@mui/icons-material/Add";
2423
2730
 
2424
2731
  // src/components/grid/ExampleClientSideComponent.tsx
2425
- import { Box as Box6, Typography as Typography3 } from "@mui/material";
2426
- import { jsx as jsx10 } from "react/jsx-runtime";
2732
+ import { Box as Box6, Typography as Typography5 } from "@mui/material";
2733
+ import { jsx as jsx14 } from "react/jsx-runtime";
2427
2734
  var ExampleClientSideComponent = ({ row, column, fieldDefinition }) => {
2428
2735
  const value = row[column.key];
2429
- return /* @__PURE__ */ jsx10(Box6, { sx: {
2736
+ return /* @__PURE__ */ jsx14(Box6, { sx: {
2430
2737
  padding: 0.5,
2431
2738
  width: "100%",
2432
2739
  height: "100%",
2433
2740
  display: "flex",
2434
2741
  alignItems: "center",
2435
2742
  backgroundColor: value === "Special" ? "lightblue" : "transparent"
2436
- }, children: /* @__PURE__ */ jsx10(Typography3, { variant: "body2", sx: { fontWeight: "bold" }, children: value ? `CS: ${value}` : "N/A" }) });
2743
+ }, children: /* @__PURE__ */ jsx14(Typography5, { variant: "body2", sx: { fontWeight: "bold" }, children: value ? `CS: ${value}` : "N/A" }) });
2437
2744
  };
2438
2745
  var ExampleClientSideComponent_default = ExampleClientSideComponent;
2439
2746
 
2440
2747
  // src/components/grid/FallbackClientSideRenderer.tsx
2441
- import { Box as Box7, Typography as Typography4, Tooltip as Tooltip3 } from "@mui/material";
2748
+ import { Box as Box7, Typography as Typography6, Tooltip as Tooltip3 } from "@mui/material";
2442
2749
  import WarningAmberIcon2 from "@mui/icons-material/WarningAmber";
2443
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
2750
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
2444
2751
  var FallbackClientSideRenderer = ({ column, row, fieldDefinition }) => {
2445
2752
  const clientSideName = fieldDefinition?.clientSide || "Desconocido";
2446
- return /* @__PURE__ */ jsx11(Tooltip3, { title: `Componente clientSide '${clientSideName}' no implementado. Mostrando valor por defecto.`, children: /* @__PURE__ */ jsxs9(
2753
+ return /* @__PURE__ */ jsx15(Tooltip3, { title: `Componente clientSide '${clientSideName}' no implementado. Mostrando valor por defecto.`, children: /* @__PURE__ */ jsxs12(
2447
2754
  Box7,
2448
2755
  {
2449
2756
  sx: {
@@ -2464,8 +2771,8 @@ var FallbackClientSideRenderer = ({ column, row, fieldDefinition }) => {
2464
2771
  // Evita que el contenido se desborde
2465
2772
  },
2466
2773
  children: [
2467
- /* @__PURE__ */ jsx11(Typography4, { variant: "body2", noWrap: true, sx: { flexGrow: 1 }, children: clientSideName + " not found" }),
2468
- /* @__PURE__ */ jsx11(
2774
+ /* @__PURE__ */ jsx15(Typography6, { variant: "body2", noWrap: true, sx: { flexGrow: 1 }, children: clientSideName + " not found" }),
2775
+ /* @__PURE__ */ jsx15(
2469
2776
  WarningAmberIcon2,
2470
2777
  {
2471
2778
  sx: {
@@ -2493,8 +2800,8 @@ var extendClientSides = (newRenderers) => {
2493
2800
  };
2494
2801
 
2495
2802
  // src/components/grid/renderers/cellRenderers.tsx
2496
- import { jsx as jsx12 } from "react/jsx-runtime";
2497
- var CeldaDato = React7.memo(function CeldaDato2({ row, columnKey, defaultColumn }) {
2803
+ import { jsx as jsx16 } from "react/jsx-runtime";
2804
+ var CeldaDato = React11.memo(function CeldaDato2({ row, columnKey, defaultColumn }) {
2498
2805
  const theme = useTheme2();
2499
2806
  const { primaryKey, fixedFields, typer, isMandatory, isNumeric } = defaultColumn;
2500
2807
  const rowId = getPrimaryKeyValues(row, primaryKey);
@@ -2515,7 +2822,7 @@ var CeldaDato = React7.memo(function CeldaDato2({ row, columnKey, defaultColumn
2515
2822
  displayValue = "* " + displayValue;
2516
2823
  }
2517
2824
  const signal = displayValue === "--" ? "typed-controls-signal-no-data" : displayValue === "//" ? "typed-controls-signal-unknown-data" : "";
2518
- const celda = /* @__PURE__ */ jsx12(
2825
+ const celda = /* @__PURE__ */ jsx16(
2519
2826
  "div",
2520
2827
  {
2521
2828
  className: `fpr-celda ${isNumeric ? "fpr-celda-numerica" : ""} ${signal} ${row[NEW_ROW_INDICATOR] ? "new-row-cell-animation" : ""}`,
@@ -2523,13 +2830,13 @@ var CeldaDato = React7.memo(function CeldaDato2({ row, columnKey, defaultColumn
2523
2830
  children: displayValue
2524
2831
  }
2525
2832
  );
2526
- return currentCellFeedback?.message ? /* @__PURE__ */ jsx12(Tooltip4, { title: currentCellFeedback.message, children: celda }) : celda;
2833
+ return currentCellFeedback?.message ? /* @__PURE__ */ jsx16(Tooltip4, { title: currentCellFeedback.message, children: celda }) : celda;
2527
2834
  });
2528
2835
  var allColumnsCellRenderer = (props) => {
2529
2836
  const { row, column } = props;
2530
2837
  if (!esColumnaPropia(column)) return void 0;
2531
2838
  if (esFilaDetalle(row)) {
2532
- return column.customType === "action" ? /* @__PURE__ */ jsx12(CeldaDetalle, { fila: row }) : null;
2839
+ return column.customType === "action" ? /* @__PURE__ */ jsx16(CeldaDetalle, { fila: row }) : null;
2533
2840
  }
2534
2841
  switch (column.customType) {
2535
2842
  case "default": {
@@ -2538,15 +2845,15 @@ var allColumnsCellRenderer = (props) => {
2538
2845
  if (fieldDef?.clientSide) {
2539
2846
  const ClientSideComponent = clientSides[fieldDef.clientSide];
2540
2847
  if (ClientSideComponent) {
2541
- return /* @__PURE__ */ jsx12(ClientSideComponent, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
2848
+ return /* @__PURE__ */ jsx16(ClientSideComponent, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
2542
2849
  }
2543
- return /* @__PURE__ */ jsx12(FallbackClientSideRenderer_default, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
2850
+ return /* @__PURE__ */ jsx16(FallbackClientSideRenderer_default, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
2544
2851
  }
2545
- return /* @__PURE__ */ jsx12(CeldaDato, { row, columnKey: props.column.key, defaultColumn });
2852
+ return /* @__PURE__ */ jsx16(CeldaDato, { row, columnKey: props.column.key, defaultColumn });
2546
2853
  }
2547
2854
  case "detail": {
2548
2855
  const { detailTable, primaryKey } = column;
2549
- return /* @__PURE__ */ jsx12(
2856
+ return /* @__PURE__ */ jsx16(
2550
2857
  BotonDetalle,
2551
2858
  {
2552
2859
  row,
@@ -2581,8 +2888,8 @@ var allColumnsCellRenderer = (props) => {
2581
2888
  color: "primary"
2582
2889
  }
2583
2890
  ];
2584
- return /* @__PURE__ */ jsx12(Box8, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", gap: 0.5 }, children: gridActionButtons.map((actionDef) => tableDefinition.allow[actionDef.action] ? /* @__PURE__ */ jsx12(
2585
- Button2,
2891
+ return /* @__PURE__ */ jsx16(Box8, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", gap: 0.5 }, children: gridActionButtons.map((actionDef) => tableDefinition.allow[actionDef.action] ? /* @__PURE__ */ jsx16(
2892
+ Button4,
2586
2893
  {
2587
2894
  variant: "outlined",
2588
2895
  color: actionDef.color,
@@ -2590,7 +2897,7 @@ var allColumnsCellRenderer = (props) => {
2590
2897
  onClick: () => actionDef.handler(row),
2591
2898
  title: actionDef.title,
2592
2899
  sx: { width: 22, minWidth: 22, height: 22, "& .MuiButton-startIcon": { m: 0 } },
2593
- children: /* @__PURE__ */ jsx12(actionDef.icon, { sx: { fontSize: 18 } })
2900
+ children: /* @__PURE__ */ jsx16(actionDef.icon, { sx: { fontSize: 18 } })
2594
2901
  },
2595
2902
  actionDef.action
2596
2903
  ) : null) });
@@ -2601,13 +2908,13 @@ var allColumnsCellRenderer = (props) => {
2601
2908
  };
2602
2909
 
2603
2910
  // src/components/grid/InputRenderer.tsx
2604
- import React11, { useCallback as useCallback9, useEffect as useEffect5, useMemo as useMemo7, useState as useState11 } from "react";
2911
+ import React12, { useCallback as useCallback10, useEffect as useEffect5, useMemo as useMemo7, useState as useState12 } from "react";
2605
2912
 
2606
2913
  // src/hooks/useTableRecordSave.ts
2607
- import { useCallback as useCallback8 } from "react";
2914
+ import { useCallback as useCallback9 } from "react";
2608
2915
  var useTableRecordSave = () => {
2609
2916
  const { callApi, loading, error } = useApiCall();
2610
- const saveRecord = useCallback8(async ({
2917
+ const saveRecord = useCallback9(async ({
2611
2918
  tableDefinition,
2612
2919
  isNewRow,
2613
2920
  formData,
@@ -2654,207 +2961,9 @@ var useTableRecordSave = () => {
2654
2961
 
2655
2962
  // src/components/grid/InputRenderer.tsx
2656
2963
  import InputBase4 from "@mui/material/InputBase";
2657
- import IconButton4 from "@mui/material/IconButton";
2658
- import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
2659
- import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
2660
- import SearchIcon2 from "@mui/icons-material/Search";
2661
2964
  import { Tooltip as Tooltip5, useTheme as useTheme3 } from "@mui/material";
2662
-
2663
- // src/components/grid/MenuDeOpciones.tsx
2664
- import { useEffect as useEffect4, useMemo as useMemo6, useRef as useRef5, useState as useState8 } from "react";
2665
- import { InputBase as InputBase2, List as List2, ListItemButton as ListItemButton2, Popover as Popover2, Typography as Typography5 } from "@mui/material";
2666
- import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
2667
- function MenuDeOpciones({ anclaje, opciones, busquedaInicial, onElegir, onCerrar }) {
2668
- const [busqueda, setBusqueda] = useState8(busquedaInicial);
2669
- const [indice, setIndice] = useState8(0);
2670
- const visibles = useMemo6(() => filtrarOpciones(opciones, busqueda), [opciones, busqueda]);
2671
- const elegida = useRef5(null);
2672
- useEffect4(() => {
2673
- elegida.current?.scrollIntoView({ block: "nearest" });
2674
- }, [indice, visibles]);
2675
- const alApretar = (evento) => {
2676
- if (evento.key === "ArrowDown") {
2677
- setIndice((i) => Math.min(i + 1, visibles.length - 1));
2678
- } else if (evento.key === "ArrowUp") {
2679
- setIndice((i) => Math.max(i - 1, 0));
2680
- } else if (evento.key === "Enter") {
2681
- if (visibles[indice]) onElegir(visibles[indice].valor);
2682
- } else if (evento.key === "F9" || evento.key === "Escape") {
2683
- onCerrar();
2684
- } else {
2685
- return;
2686
- }
2687
- evento.preventDefault();
2688
- evento.stopPropagation();
2689
- };
2690
- return /* @__PURE__ */ jsxs10(
2691
- Popover2,
2692
- {
2693
- open: true,
2694
- anchorEl: anclaje,
2695
- onClose: onCerrar,
2696
- disableRestoreFocus: true,
2697
- anchorOrigin: { vertical: "bottom", horizontal: "left" },
2698
- slotProps: { paper: { sx: { minWidth: 300, maxWidth: 520 } } },
2699
- children: [
2700
- /* @__PURE__ */ jsx13(
2701
- InputBase2,
2702
- {
2703
- autoFocus: true,
2704
- fullWidth: true,
2705
- value: busqueda,
2706
- onChange: (e) => {
2707
- setBusqueda(e.target.value);
2708
- setIndice(0);
2709
- },
2710
- onKeyDown: alApretar,
2711
- placeholder: "buscar",
2712
- sx: { px: 1, py: 0.5, fontSize: "0.8rem", borderBottom: "1px solid #ccc" },
2713
- inputProps: { "aria-label": "buscar" }
2714
- }
2715
- ),
2716
- /* @__PURE__ */ jsxs10(List2, { dense: true, disablePadding: true, sx: { maxHeight: 320, overflowY: "auto" }, role: "listbox", children: [
2717
- visibles.length === 0 && /* @__PURE__ */ jsx13(Typography5, { variant: "body2", sx: { p: 1, color: "text.secondary" }, children: "sin coincidencias" }),
2718
- visibles.map((opcion, i) => /* @__PURE__ */ jsx13(
2719
- ListItemButton2,
2720
- {
2721
- ref: i === indice ? elegida : null,
2722
- selected: i === indice,
2723
- role: "option",
2724
- onClick: () => onElegir(opcion.valor),
2725
- sx: { gap: 2, py: 0.25, fontSize: "0.8rem" },
2726
- children: opcion.etiquetas.map((etiqueta, j) => /* @__PURE__ */ jsx13("span", { style: { fontWeight: j === 0 ? 600 : 400, minWidth: j === 0 ? 40 : void 0 }, children: etiqueta }, j))
2727
- },
2728
- i
2729
- ))
2730
- ] })
2731
- ]
2732
- }
2733
- );
2734
- }
2735
-
2736
- // src/components/grid/SelectorDeFecha.tsx
2737
- import { useState as useState9 } from "react";
2738
- import { Button as Button3, IconButton as IconButton3, Popover as Popover3, Typography as Typography6 } from "@mui/material";
2739
- import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
2740
- var MESES = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"];
2741
- var DIAS = ["lu", "ma", "mi", "ju", "vi", "s\xE1", "do"];
2742
- var mismaFecha = (a, b) => b !== null && a.anio === b.anio && a.mes === b.mes && a.dia === b.dia;
2743
- var MOVIMIENTOS = {
2744
- ArrowLeft: [-1, 0],
2745
- ArrowRight: [1, 0],
2746
- ArrowUp: [-7, 0],
2747
- ArrowDown: [7, 0],
2748
- PageUp: [0, -1],
2749
- PageDown: [0, 1]
2750
- };
2751
- function SelectorDeFecha({ anclaje, fechaActual, admiteNulo, onElegir, onCerrar }) {
2752
- const hoy = /* @__PURE__ */ new Date();
2753
- const fechaDeHoy = { anio: hoy.getFullYear(), mes: hoy.getMonth(), dia: hoy.getDate() };
2754
- const [cursor, setCursor] = useState9(fechaActual ?? fechaDeHoy);
2755
- const mover = (dias, meses) => {
2756
- const nueva = new Date(cursor.anio, cursor.mes + meses, cursor.dia + dias);
2757
- setCursor({ anio: nueva.getFullYear(), mes: nueva.getMonth(), dia: nueva.getDate() });
2758
- };
2759
- const alApretar = (evento) => {
2760
- if (evento.key in MOVIMIENTOS) {
2761
- mover(...MOVIMIENTOS[evento.key]);
2762
- } else if (evento.key === "Enter") {
2763
- onElegir(fechaATexto(cursor));
2764
- } else if (evento.key === "F9" || evento.key === "Escape") {
2765
- onCerrar();
2766
- } else {
2767
- return;
2768
- }
2769
- evento.preventDefault();
2770
- evento.stopPropagation();
2771
- };
2772
- return /* @__PURE__ */ jsx14(Popover3, { open: true, anchorEl: anclaje, onClose: onCerrar, disableRestoreFocus: true, anchorOrigin: { vertical: "bottom", horizontal: "left" }, children: /* @__PURE__ */ jsxs11("div", { tabIndex: 0, ref: (el) => el?.focus(), onKeyDown: alApretar, style: { padding: 8, outline: "none", width: 252 }, "aria-label": "calendario", children: [
2773
- /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
2774
- /* @__PURE__ */ jsx14(IconButton3, { size: "small", "aria-label": "mes anterior", onClick: () => mover(0, -1), children: "\u2039" }),
2775
- /* @__PURE__ */ jsxs11(Typography6, { variant: "body2", sx: { fontWeight: 600 }, children: [
2776
- MESES[cursor.mes],
2777
- " ",
2778
- cursor.anio
2779
- ] }),
2780
- /* @__PURE__ */ jsx14(IconButton3, { size: "small", "aria-label": "mes siguiente", onClick: () => mover(0, 1), children: "\u203A" })
2781
- ] }),
2782
- /* @__PURE__ */ jsxs11("table", { style: { borderCollapse: "collapse", width: "100%", textAlign: "center", fontSize: "0.8rem" }, children: [
2783
- /* @__PURE__ */ jsx14("thead", { children: /* @__PURE__ */ jsx14("tr", { children: DIAS.map((d) => /* @__PURE__ */ jsx14("th", { style: { fontWeight: 400, color: "#777" }, children: d }, d)) }) }),
2784
- /* @__PURE__ */ jsx14("tbody", { children: semanasDelMes(cursor.anio, cursor.mes).map((semana, i) => /* @__PURE__ */ jsx14("tr", { children: semana.map((dia) => {
2785
- const elegido = mismaFecha(dia, fechaActual);
2786
- const enCursor = mismaFecha(dia, cursor);
2787
- return /* @__PURE__ */ jsx14("td", { style: { padding: 1 }, children: /* @__PURE__ */ jsx14(
2788
- "button",
2789
- {
2790
- type: "button",
2791
- tabIndex: -1,
2792
- onClick: () => onElegir(fechaATexto(dia)),
2793
- style: {
2794
- width: 32,
2795
- height: 26,
2796
- border: enCursor ? "1px solid #1976d2" : "1px solid transparent",
2797
- borderRadius: 4,
2798
- cursor: "pointer",
2799
- background: elegido ? "#1976d2" : "transparent",
2800
- color: elegido ? "#fff" : dia.delMesMostrado ? "#000" : "#aaa"
2801
- },
2802
- children: dia.dia
2803
- }
2804
- ) }, `${dia.mes}-${dia.dia}`);
2805
- }) }, i)) })
2806
- ] }),
2807
- /* @__PURE__ */ jsxs11("div", { style: { display: "flex", justifyContent: "space-between", marginTop: 4 }, children: [
2808
- /* @__PURE__ */ jsx14(Button3, { size: "small", onClick: () => onElegir(fechaATexto(fechaDeHoy)), children: "hoy" }),
2809
- admiteNulo && /* @__PURE__ */ jsx14(Button3, { size: "small", onClick: () => onElegir(null), children: "vac\xEDo" })
2810
- ] })
2811
- ] }) });
2812
- }
2813
-
2814
- // src/components/grid/VentanaDeTexto.tsx
2815
- import { useState as useState10 } from "react";
2816
- import { Button as Button4, InputBase as InputBase3, Popover as Popover4 } from "@mui/material";
2817
- import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
2818
- function VentanaDeTexto({ anclaje, texto, editable, onAceptar, onCerrar }) {
2819
- const [valor, setValor] = useState10(texto);
2820
- const alApretar = (evento) => {
2821
- if (evento.key === "Escape" || evento.key === "F9") {
2822
- onCerrar();
2823
- } else if (evento.key === "Enter" && evento.ctrlKey && editable) {
2824
- onAceptar(valor);
2825
- } else {
2826
- return;
2827
- }
2828
- evento.preventDefault();
2829
- evento.stopPropagation();
2830
- };
2831
- return /* @__PURE__ */ jsx15(Popover4, { open: true, anchorEl: anclaje, onClose: onCerrar, disableRestoreFocus: true, anchorOrigin: { vertical: "bottom", horizontal: "left" }, children: /* @__PURE__ */ jsxs12("div", { style: { padding: 8, minWidth: 320, maxWidth: 640 }, children: [
2832
- /* @__PURE__ */ jsx15(
2833
- InputBase3,
2834
- {
2835
- autoFocus: true,
2836
- multiline: true,
2837
- fullWidth: true,
2838
- readOnly: !editable,
2839
- value: valor,
2840
- onChange: (e) => setValor(e.target.value),
2841
- onKeyDown: alApretar,
2842
- minRows: 2,
2843
- maxRows: 16,
2844
- sx: { fontFamily: "monospace", fontSize: "0.8rem", border: "1px solid #ccc", borderRadius: "4px", p: 0.5 },
2845
- inputProps: { "aria-label": "contenido de la celda" }
2846
- }
2847
- ),
2848
- editable && /* @__PURE__ */ jsxs12("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 4 }, children: [
2849
- /* @__PURE__ */ jsx15(Button4, { size: "small", onClick: onCerrar, children: "cancelar" }),
2850
- /* @__PURE__ */ jsx15(Button4, { size: "small", variant: "contained", onClick: () => onAceptar(valor), children: "aceptar" })
2851
- ] })
2852
- ] }) });
2853
- }
2854
-
2855
- // src/components/grid/InputRenderer.tsx
2856
2965
  import typeStore4 from "type-store";
2857
- import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
2966
+ import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
2858
2967
  function findChangedValues(oldRowData, newRowData, isNewRow) {
2859
2968
  let changes = [];
2860
2969
  for (const key in newRowData) {
@@ -2881,11 +2990,9 @@ function InputRenderer({
2881
2990
  const setLocalCellChanges = estadoGrilla.setCambiosLocales;
2882
2991
  const fieldDefinition = requerido(tableDefinition.fields.find((f) => f.name === column.key), `el campo '${column.key}'`);
2883
2992
  const typer = useMemo7(() => typeStore4.typerFrom(fieldDefinition), [fieldDefinition]);
2884
- const [editingValue, setEditingValue] = useState11(() => row[column.key] !== null ? isNumericType(fieldDefinition?.typeName) ? row[column.key] : typer.toLocalString(row[column.key]) : null);
2885
- const isCommitInProgress = React11.useRef(false);
2886
- const [expansion, setExpansion] = useState11(null);
2887
- const menuAbierto = React11.useRef(false);
2888
- const entradaRef = React11.useRef(null);
2993
+ const [editingValue, setEditingValue] = useState12(() => row[column.key] !== null ? isNumericType(fieldDefinition?.typeName) ? row[column.key] : typer.toLocalString(row[column.key]) : null);
2994
+ const isCommitInProgress = React12.useRef(false);
2995
+ const entradaRef = React12.useRef(null);
2889
2996
  const theme = useTheme3();
2890
2997
  const { showSuccess, showError } = useSnackbar();
2891
2998
  const { saveRecord } = useTableRecordSave();
@@ -2901,7 +3008,7 @@ function InputRenderer({
2901
3008
  cellBorderColor = currentCellFeedback.type === "error" ? theme.palette.error.main : theme.palette.success.main;
2902
3009
  }
2903
3010
  const initialRowId = useMemo7(() => getPrimaryKeyValues(row, primaryKey), [row, primaryKey]);
2904
- const handleCommit = useCallback9(async (currentValue, closeEditor, focusNextCell) => {
3011
+ const handleCommit = useCallback10(async (currentValue, closeEditor, focusNextCell) => {
2905
3012
  if (isCommitInProgress.current) return;
2906
3013
  isCommitInProgress.current = true;
2907
3014
  let processedNewValue;
@@ -3044,49 +3151,30 @@ function InputRenderer({
3044
3151
  initialRowId,
3045
3152
  typer
3046
3153
  ]);
3047
- const tipoExpander = tipoDeExpander(fieldDefinition, fieldDefinition.editable !== false);
3048
- const abrirExpander = useCallback9(async (busqueda) => {
3049
- if (tipoExpander === null || tipoExpander === "json" || menuAbierto.current) return;
3050
- menuAbierto.current = true;
3051
- const admiteNulo = fieldDefinition.nullable !== false;
3052
- try {
3053
- if (tipoExpander === "referencia" && esCampoConReferencia(fieldDefinition)) {
3054
- const { definicion, filas } = await cargarReferencia(fieldDefinition.references);
3055
- setExpansion({ tipo: "opciones", opciones: opcionesDeReferencia(fieldDefinition, definicion, filas, row, admiteNulo), busqueda });
3056
- } else if (tipoExpander === "booleano") {
3057
- setExpansion({ tipo: "opciones", opciones: opcionesDeBooleano(admiteNulo), busqueda });
3058
- } else if (tipoExpander === "opciones") {
3059
- setExpansion({ tipo: "opciones", opciones: opcionesDeEnumerado(fieldDefinition.options ?? [], admiteNulo), busqueda });
3060
- } else {
3061
- setExpansion({ tipo: tipoExpander === "fecha" ? "fecha" : "texto" });
3062
- }
3063
- } catch (err) {
3064
- menuAbierto.current = false;
3065
- showError(mensajeDeError(err));
3066
- }
3067
- }, [tipoExpander, fieldDefinition, row, showError]);
3068
- const cerrarExpansion = useCallback9(() => {
3069
- menuAbierto.current = false;
3070
- setExpansion(null);
3071
- setTimeout(() => entradaRef.current?.focus(), 0);
3072
- }, []);
3073
- const confirmarEnExpansion = useCallback9((nuevo) => {
3154
+ const confirmarEnExpansion = useCallback10((nuevo) => {
3074
3155
  setEditingValue(nuevo);
3075
- cerrarExpansion();
3076
3156
  void handleCommit(nuevo, true, false);
3077
- }, [cerrarExpansion, handleCommit]);
3078
- const elegirOpcion = useCallback9((valor) => {
3157
+ }, [handleCommit]);
3158
+ const elegirOpcion = useCallback10((valor) => {
3079
3159
  confirmarEnExpansion(valor === null || valor === void 0 ? null : typeof valor === "boolean" || isNumericType(fieldDefinition.typeName) ? valor : typer.toLocalString(valor));
3080
3160
  }, [fieldDefinition.typeName, typer, confirmarEnExpansion]);
3081
- const handleKeyDown = useCallback9(async (event) => {
3082
- if (tipoExpander !== null && (event.key === "F9" && !event.shiftKey && !event.ctrlKey && !event.altKey || event.key === "ArrowDown" && event.altKey && !event.shiftKey && !event.ctrlKey)) {
3083
- event.preventDefault();
3084
- void abrirExpander("");
3085
- return;
3086
- }
3161
+ const expander = useExpander({
3162
+ campo: fieldDefinition,
3163
+ editable: fieldDefinition.editable !== false,
3164
+ fila: row,
3165
+ admiteNulo: fieldDefinition.nullable !== false,
3166
+ anclaje: entradaRef,
3167
+ textoActual: editingValue === null || editingValue === void 0 ? "" : String(editingValue),
3168
+ valorActual: row[column.key],
3169
+ alElegirValor: elegirOpcion,
3170
+ alConfirmarTexto: confirmarEnExpansion,
3171
+ alFallar: showError
3172
+ });
3173
+ const handleKeyDown = useCallback10(async (event) => {
3174
+ if (expander.manejarTecla(event)) return;
3087
3175
  if (event.key.length === 1 && !event.ctrlKey && !event.altKey && !event.metaKey && caracterRechazado(event.key, typer)) {
3088
3176
  event.preventDefault();
3089
- if (tipoExpander === "referencia") void abrirExpander(event.key);
3177
+ if (expander.tipo === "referencia") void expander.abrir(event.key);
3090
3178
  return;
3091
3179
  }
3092
3180
  if (event.key === "F4") {
@@ -3099,24 +3187,24 @@ function InputRenderer({
3099
3187
  if (onKeyPress?.(rowIdx, column.key, event, handleCommit, editingValue)) {
3100
3188
  event.preventDefault();
3101
3189
  }
3102
- }, [handleCommit, editingValue, column.key, rowIdx, onKeyPress, tipoExpander, abrirExpander, typer]);
3103
- const procesarTecla = React11.useRef(() => {
3190
+ }, [handleCommit, editingValue, column.key, rowIdx, onKeyPress, expander, typer]);
3191
+ const procesarTecla = React12.useRef(() => {
3104
3192
  });
3105
3193
  procesarTecla.current = (key) => {
3106
3194
  if (key === "F9") {
3107
- void abrirExpander("");
3195
+ void expander.abrir("");
3108
3196
  } else if (key === "F4" && onKeyPress) {
3109
3197
  onKeyPress(rowIdx, column.key, { key, target: document.activeElement ?? document.body }, handleCommit, editingValue);
3110
3198
  }
3111
3199
  };
3112
3200
  useEffect5(() => registrarEditor?.((key) => procesarTecla.current(key)), []);
3113
- const handleBlur = useCallback9(() => {
3114
- if (menuAbierto.current) return;
3201
+ const handleBlur = useCallback10(() => {
3202
+ if (expander.abierto.current) return;
3115
3203
  handleCommit(editingValue, true, false);
3116
3204
  }, [handleCommit, editingValue]);
3117
3205
  const isFieldEditable = fieldDefinition?.editable !== false;
3118
3206
  const isNumeric = isNumericType(fieldDefinition?.typeName);
3119
- const editor = /* @__PURE__ */ jsx16(
3207
+ const editor = /* @__PURE__ */ jsx17(
3120
3208
  InputBase4,
3121
3209
  {
3122
3210
  autoFocus: true,
@@ -3149,61 +3237,19 @@ function InputRenderer({
3149
3237
  },
3150
3238
  onClick: (e) => e.stopPropagation(),
3151
3239
  disabled: !isFieldEditable,
3152
- endAdornment: tipoExpander !== null && tipoExpander !== "json" && /* @__PURE__ */ jsx16(
3153
- IconButton4,
3154
- {
3155
- size: "small",
3156
- tabIndex: -1,
3157
- "aria-label": tipoExpander === "fecha" ? "elegir fecha" : tipoExpander === "texto" ? "ver el contenido completo" : "elegir un valor",
3158
- title: tipoExpander === "fecha" ? "elegir fecha (F9)" : tipoExpander === "texto" ? "ver el contenido completo (F9)" : "elegir un valor (F9)",
3159
- onMouseDown: (e) => e.preventDefault(),
3160
- onClick: (e) => {
3161
- e.stopPropagation();
3162
- void abrirExpander("");
3163
- },
3164
- sx: { p: 0, ml: 0.25, color: "primary.main", "&:hover": { backgroundColor: "action.hover" } },
3165
- children: tipoExpander === "fecha" ? /* @__PURE__ */ jsx16(CalendarMonthIcon, { sx: { fontSize: 16 } }) : tipoExpander === "texto" ? /* @__PURE__ */ jsx16(SearchIcon2, { sx: { fontSize: 16 } }) : /* @__PURE__ */ jsx16(ArrowDropDownIcon, { sx: { fontSize: 20 } })
3166
- }
3167
- )
3240
+ endAdornment: expander.lupa
3168
3241
  }
3169
3242
  );
3170
- const conMenu = /* @__PURE__ */ jsxs13(Fragment3, { children: [
3243
+ const conMenu = /* @__PURE__ */ jsxs13(Fragment4, { children: [
3171
3244
  editor,
3172
- expansion && entradaRef.current && (expansion.tipo === "opciones" ? /* @__PURE__ */ jsx16(
3173
- MenuDeOpciones,
3174
- {
3175
- anclaje: entradaRef.current,
3176
- opciones: expansion.opciones,
3177
- busquedaInicial: expansion.busqueda,
3178
- onElegir: elegirOpcion,
3179
- onCerrar: cerrarExpansion
3180
- }
3181
- ) : expansion.tipo === "fecha" ? /* @__PURE__ */ jsx16(
3182
- SelectorDeFecha,
3183
- {
3184
- anclaje: entradaRef.current,
3185
- fechaActual: fechaDeValor(row[column.key]),
3186
- admiteNulo: fieldDefinition.nullable !== false,
3187
- onElegir: confirmarEnExpansion,
3188
- onCerrar: cerrarExpansion
3189
- }
3190
- ) : /* @__PURE__ */ jsx16(
3191
- VentanaDeTexto,
3192
- {
3193
- anclaje: entradaRef.current,
3194
- texto: editingValue === null || editingValue === void 0 ? "" : String(editingValue),
3195
- editable: true,
3196
- onAceptar: confirmarEnExpansion,
3197
- onCerrar: cerrarExpansion
3198
- }
3199
- ))
3245
+ expander.ventana
3200
3246
  ] });
3201
- return currentCellFeedback?.message ? /* @__PURE__ */ jsx16(Tooltip5, { title: currentCellFeedback.message, children: /* @__PURE__ */ jsx16("div", { style: { width: "100%" }, children: conMenu }) }) : conMenu;
3247
+ return currentCellFeedback?.message ? /* @__PURE__ */ jsx17(Tooltip5, { title: currentCellFeedback.message, children: /* @__PURE__ */ jsx17("div", { style: { width: "100%" }, children: conMenu }) }) : conMenu;
3202
3248
  }
3203
3249
  var InputRenderer_default = InputRenderer;
3204
3250
 
3205
3251
  // src/components/grid/renderers/editCellRenderers.tsx
3206
- import { jsx as jsx17 } from "react/jsx-runtime";
3252
+ import { jsx as jsx18 } from "react/jsx-runtime";
3207
3253
  var allColumnsEditCellRenderer = (props, allColumns) => {
3208
3254
  const column = props.column;
3209
3255
  if (!esColumnaPropia(column)) return void 0;
@@ -3225,7 +3271,7 @@ var allColumnsEditCellRenderer = (props, allColumns) => {
3225
3271
  if (!isFieldEditableByUI) {
3226
3272
  return void 0;
3227
3273
  }
3228
- return /* @__PURE__ */ jsx17(
3274
+ return /* @__PURE__ */ jsx18(
3229
3275
  InputRenderer_default,
3230
3276
  {
3231
3277
  ...props,
@@ -3250,6 +3296,14 @@ var allColumnsEditCellRenderer = (props, allColumns) => {
3250
3296
  }
3251
3297
  };
3252
3298
 
3299
+ // src/utils/columnasOcultas.ts
3300
+ function columnasOcultasIniciales(tableDefinition) {
3301
+ return Array.from(new Set(tableDefinition.hiddenColumns ?? []));
3302
+ }
3303
+ function campoDibujable(field) {
3304
+ return field.visible !== false;
3305
+ }
3306
+
3253
3307
  // src/hooks/grid/useGridColumns.ts
3254
3308
  var estimateTextWidth = (text) => text.length * 8 + 16;
3255
3309
  var calcularAnchosDeColumnas = (tableDefinition, filas) => {
@@ -3287,6 +3341,8 @@ var useGridColumns = ({
3287
3341
  tableDefinition,
3288
3342
  anchosCalculados,
3289
3343
  fixedFields,
3344
+ columnasOcultas,
3345
+ ocultarColumna,
3290
3346
  primaryKey,
3291
3347
  setTableData,
3292
3348
  handleKeyPressInEditor,
@@ -3300,7 +3356,7 @@ var useGridColumns = ({
3300
3356
  const columns = useMemo8(() => {
3301
3357
  if (!tableDefinition) return [];
3302
3358
  const fieldsToShow = tableDefinition.fields.filter((field) => {
3303
- return !columnaOcultaPorFixedField(fixedFields, field.name) && field.visible !== false;
3359
+ return campoDibujable(field) && !columnaOcultaPorFixedField(fixedFields, field.name) && !columnasOcultas.has(field.name);
3304
3360
  });
3305
3361
  const defaultColumns = fieldsToShow.map((fieldDef) => {
3306
3362
  const isFixedField = valorFijoDe(fixedFields, fieldDef.name) !== void 0;
@@ -3325,7 +3381,7 @@ var useGridColumns = ({
3325
3381
  registrarEditor,
3326
3382
  width: colWidth,
3327
3383
  minWidth: 40,
3328
- renderHeaderCell: (props) => defaultColumnHeaderCellRenderer(props, fieldDef),
3384
+ renderHeaderCell: (props) => defaultColumnHeaderCellRenderer(props, fieldDef, ocultarColumna),
3329
3385
  renderSummaryCell: (props) => defaultColumnSummaryCellRenderer(props, fixedFields)
3330
3386
  };
3331
3387
  return column;
@@ -3348,7 +3404,7 @@ var useGridColumns = ({
3348
3404
  editable: false,
3349
3405
  resizable: false,
3350
3406
  sortable: false,
3351
- renderHeaderCell: () => React12.createElement(ActionsColumnHeaderCell, {
3407
+ renderHeaderCell: () => React13.createElement(ActionsColumnHeaderCell, {
3352
3408
  toggleFilterVisibility,
3353
3409
  handleDataGridOptions: (e) => abrirOpcionesDeGrilla(e.currentTarget),
3354
3410
  handleAddRow,
@@ -3388,12 +3444,12 @@ var useGridColumns = ({
3388
3444
  renderEditCell: (props) => allColumnsEditCellRenderer(props, allColumns),
3389
3445
  renderCell: (props) => allColumnsCellRenderer(props)
3390
3446
  }));
3391
- }, [tableDefinition, anchosCalculados, fixedFields, primaryKey, setTableData, handleKeyPressInEditor, registrarEditor, handleDeleteRow, handleAddRow, handleVerticalEditRow, toggleFilterVisibility, abrirOpcionesDeGrilla]);
3447
+ }, [tableDefinition, anchosCalculados, fixedFields, columnasOcultas, ocultarColumna, primaryKey, setTableData, handleKeyPressInEditor, registrarEditor, handleDeleteRow, handleAddRow, handleVerticalEditRow, toggleFilterVisibility, abrirOpcionesDeGrilla]);
3392
3448
  return { columns };
3393
3449
  };
3394
3450
 
3395
3451
  // src/components/grid/ImportDialog.tsx
3396
- import { useState as useState12 } from "react";
3452
+ import { useState as useState13 } from "react";
3397
3453
  import {
3398
3454
  Dialog as Dialog2,
3399
3455
  DialogTitle as DialogTitle2,
@@ -3408,10 +3464,10 @@ import {
3408
3464
  Divider
3409
3465
  } from "@mui/material";
3410
3466
  import FileUploadIcon2 from "@mui/icons-material/FileUpload";
3411
- import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
3467
+ import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
3412
3468
  var ImportDialog = ({ open, onClose, onImport, loading }) => {
3413
- const [file, setFile] = useState12(null);
3414
- const [options, setOptions] = useState12({
3469
+ const [file, setFile] = useState13(null);
3470
+ const [options, setOptions] = useState13({
3415
3471
  skipUnknownFieldsAtImport: false,
3416
3472
  simplificateSpaces: true,
3417
3473
  replaceNewLineWithSpace: true
@@ -3432,12 +3488,12 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3432
3488
  };
3433
3489
  return /* @__PURE__ */ jsxs14(Dialog2, { open, onClose: loading ? void 0 : onClose, maxWidth: "sm", fullWidth: true, children: [
3434
3490
  /* @__PURE__ */ jsxs14(DialogTitle2, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
3435
- /* @__PURE__ */ jsx18(FileUploadIcon2, { color: "primary" }),
3491
+ /* @__PURE__ */ jsx19(FileUploadIcon2, { color: "primary" }),
3436
3492
  "Importar datos desde archivo"
3437
3493
  ] }),
3438
- /* @__PURE__ */ jsx18(DialogContent2, { dividers: true, children: /* @__PURE__ */ jsxs14(Stack, { spacing: 3, sx: { mt: 1 }, children: [
3494
+ /* @__PURE__ */ jsx19(DialogContent2, { dividers: true, children: /* @__PURE__ */ jsxs14(Stack, { spacing: 3, sx: { mt: 1 }, children: [
3439
3495
  /* @__PURE__ */ jsxs14(Box9, { children: [
3440
- /* @__PURE__ */ jsx18(Typography7, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Seleccionar archivo" }),
3496
+ /* @__PURE__ */ jsx19(Typography7, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Seleccionar archivo" }),
3441
3497
  /* @__PURE__ */ jsxs14(
3442
3498
  Box9,
3443
3499
  {
@@ -3451,7 +3507,7 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3451
3507
  position: "relative"
3452
3508
  },
3453
3509
  children: [
3454
- /* @__PURE__ */ jsx18(
3510
+ /* @__PURE__ */ jsx19(
3455
3511
  "input",
3456
3512
  {
3457
3513
  type: "file",
@@ -3468,19 +3524,19 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3468
3524
  }
3469
3525
  }
3470
3526
  ),
3471
- /* @__PURE__ */ jsx18(Typography7, { variant: "body2", color: file ? "textPrimary" : "textSecondary", children: file ? file.name : "Haz clic aqu\xED para seleccionar un archivo" })
3527
+ /* @__PURE__ */ jsx19(Typography7, { variant: "body2", color: file ? "textPrimary" : "textSecondary", children: file ? file.name : "Haz clic aqu\xED para seleccionar un archivo" })
3472
3528
  ]
3473
3529
  }
3474
3530
  )
3475
3531
  ] }),
3476
- /* @__PURE__ */ jsx18(Divider, {}),
3532
+ /* @__PURE__ */ jsx19(Divider, {}),
3477
3533
  /* @__PURE__ */ jsxs14(Box9, { children: [
3478
- /* @__PURE__ */ jsx18(Typography7, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Opciones de importaci\xF3n" }),
3534
+ /* @__PURE__ */ jsx19(Typography7, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Opciones de importaci\xF3n" }),
3479
3535
  /* @__PURE__ */ jsxs14(Stack, { children: [
3480
- /* @__PURE__ */ jsx18(
3536
+ /* @__PURE__ */ jsx19(
3481
3537
  FormControlLabel,
3482
3538
  {
3483
- control: /* @__PURE__ */ jsx18(
3539
+ control: /* @__PURE__ */ jsx19(
3484
3540
  Checkbox,
3485
3541
  {
3486
3542
  checked: options.skipUnknownFieldsAtImport,
@@ -3488,13 +3544,13 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3488
3544
  size: "small"
3489
3545
  }
3490
3546
  ),
3491
- label: /* @__PURE__ */ jsx18(Typography7, { variant: "body2", children: "Omitir campos desconocidos al importar" })
3547
+ label: /* @__PURE__ */ jsx19(Typography7, { variant: "body2", children: "Omitir campos desconocidos al importar" })
3492
3548
  }
3493
3549
  ),
3494
- /* @__PURE__ */ jsx18(
3550
+ /* @__PURE__ */ jsx19(
3495
3551
  FormControlLabel,
3496
3552
  {
3497
- control: /* @__PURE__ */ jsx18(
3553
+ control: /* @__PURE__ */ jsx19(
3498
3554
  Checkbox,
3499
3555
  {
3500
3556
  checked: options.simplificateSpaces,
@@ -3502,13 +3558,13 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3502
3558
  size: "small"
3503
3559
  }
3504
3560
  ),
3505
- label: /* @__PURE__ */ jsx18(Typography7, { variant: "body2", children: "Simplificar espacios" })
3561
+ label: /* @__PURE__ */ jsx19(Typography7, { variant: "body2", children: "Simplificar espacios" })
3506
3562
  }
3507
3563
  ),
3508
- /* @__PURE__ */ jsx18(
3564
+ /* @__PURE__ */ jsx19(
3509
3565
  FormControlLabel,
3510
3566
  {
3511
- control: /* @__PURE__ */ jsx18(
3567
+ control: /* @__PURE__ */ jsx19(
3512
3568
  Checkbox,
3513
3569
  {
3514
3570
  checked: options.replaceNewLineWithSpace,
@@ -3516,21 +3572,21 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3516
3572
  size: "small"
3517
3573
  }
3518
3574
  ),
3519
- label: /* @__PURE__ */ jsx18(Typography7, { variant: "body2", children: "Reemplazar saltos de l\xEDnea con espacios" })
3575
+ label: /* @__PURE__ */ jsx19(Typography7, { variant: "body2", children: "Reemplazar saltos de l\xEDnea con espacios" })
3520
3576
  }
3521
3577
  )
3522
3578
  ] })
3523
3579
  ] })
3524
3580
  ] }) }),
3525
3581
  /* @__PURE__ */ jsxs14(DialogActions2, { sx: { px: 3, py: 2 }, children: [
3526
- /* @__PURE__ */ jsx18(Button5, { onClick: onClose, disabled: loading, children: "Cancelar" }),
3527
- /* @__PURE__ */ jsx18(
3582
+ /* @__PURE__ */ jsx19(Button5, { onClick: onClose, disabled: loading, children: "Cancelar" }),
3583
+ /* @__PURE__ */ jsx19(
3528
3584
  Button5,
3529
3585
  {
3530
3586
  onClick: handleConfirm,
3531
3587
  variant: "contained",
3532
3588
  disabled: !file || loading,
3533
- startIcon: /* @__PURE__ */ jsx18(FileUploadIcon2, {}),
3589
+ startIcon: /* @__PURE__ */ jsx19(FileUploadIcon2, {}),
3534
3590
  children: loading ? "Procesando..." : "Confirmar Importaci\xF3n"
3535
3591
  }
3536
3592
  )
@@ -3539,7 +3595,7 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3539
3595
  };
3540
3596
 
3541
3597
  // src/components/grid/ExportDialog.tsx
3542
- import { useState as useState13 } from "react";
3598
+ import { useState as useState14 } from "react";
3543
3599
  import {
3544
3600
  Dialog as Dialog3,
3545
3601
  DialogTitle as DialogTitle3,
@@ -3559,22 +3615,23 @@ import {
3559
3615
  } from "@mui/material";
3560
3616
  import * as XLSX from "xlsx";
3561
3617
  import typeStore5 from "type-store";
3562
- import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
3618
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
3563
3619
  var ExportDialog = ({
3564
3620
  open,
3565
3621
  onClose,
3566
3622
  tableDefinition,
3623
+ columnasOcultas,
3567
3624
  tableData,
3568
3625
  filteredRows,
3569
3626
  username = "anonymous"
3570
3627
  }) => {
3571
- const [format, setFormat] = useState13("xlsx");
3572
- const [options, setOptions] = useState13({
3628
+ const [format, setFormat] = useState14("xlsx");
3629
+ const [options, setOptions] = useState14({
3573
3630
  fromOtherTables: true,
3574
3631
  readOnly: true,
3575
3632
  hiddens: false
3576
3633
  });
3577
- const [isPreparing, setIsPreparing] = useState13(false);
3634
+ const [isPreparing, setIsPreparing] = useState14(false);
3578
3635
  const handleOptionChange = (event) => {
3579
3636
  setOptions({
3580
3637
  ...options,
@@ -3594,8 +3651,7 @@ var ExportDialog = ({
3594
3651
  };
3595
3652
  const executeExport = async () => {
3596
3653
  const fieldsDef2Export = tableDefinition.fields.filter((fieldDef) => {
3597
- const isVisible = fieldDef.visible !== false;
3598
- return (fieldDef.inTable !== false || options.fromOtherTables) && isVisible && (fieldDef.editable !== false || options.readOnly || tableDefinition.primaryKey?.includes(fieldDef.name)) && (isVisible || options.hiddens);
3654
+ return (fieldDef.inTable !== false || options.fromOtherTables) && campoDibujable(fieldDef) && (fieldDef.editable !== false || options.readOnly || tableDefinition.primaryKey?.includes(fieldDef.name)) && (!columnasOcultas.has(fieldDef.name) || options.hiddens);
3599
3655
  });
3600
3656
  if (format === "xlsx") {
3601
3657
  await excelExport(fieldsDef2Export);
@@ -3705,47 +3761,47 @@ var ExportDialog = ({
3705
3761
  }, 0);
3706
3762
  };
3707
3763
  return /* @__PURE__ */ jsxs15(Dialog3, { open, onClose, maxWidth: "xs", fullWidth: true, children: [
3708
- /* @__PURE__ */ jsx19(DialogTitle3, { children: "Exportar Datos" }),
3709
- /* @__PURE__ */ jsx19(DialogContent3, { children: isPreparing ? /* @__PURE__ */ jsxs15(Box10, { display: "flex", flexDirection: "column", alignItems: "center", py: 4, children: [
3710
- /* @__PURE__ */ jsx19(CircularProgress2, {}),
3711
- /* @__PURE__ */ jsx19(Typography8, { sx: { mt: 2 }, children: "Preparando exportaci\xF3n..." })
3764
+ /* @__PURE__ */ jsx20(DialogTitle3, { children: "Exportar Datos" }),
3765
+ /* @__PURE__ */ jsx20(DialogContent3, { children: isPreparing ? /* @__PURE__ */ jsxs15(Box10, { display: "flex", flexDirection: "column", alignItems: "center", py: 4, children: [
3766
+ /* @__PURE__ */ jsx20(CircularProgress2, {}),
3767
+ /* @__PURE__ */ jsx20(Typography8, { sx: { mt: 2 }, children: "Preparando exportaci\xF3n..." })
3712
3768
  ] }) : /* @__PURE__ */ jsxs15(Box10, { sx: { mt: 1 }, children: [
3713
3769
  /* @__PURE__ */ jsxs15(FormControl2, { component: "fieldset", children: [
3714
- /* @__PURE__ */ jsx19(FormLabel, { component: "legend", children: "Formato" }),
3770
+ /* @__PURE__ */ jsx20(FormLabel, { component: "legend", children: "Formato" }),
3715
3771
  /* @__PURE__ */ jsxs15(
3716
3772
  RadioGroup,
3717
3773
  {
3718
3774
  value: format,
3719
3775
  onChange: (e) => setFormat(e.target.value),
3720
3776
  children: [
3721
- /* @__PURE__ */ jsx19(FormControlLabel2, { value: "xlsx", control: /* @__PURE__ */ jsx19(Radio, {}), label: "Excel (.xlsx)" }),
3722
- /* @__PURE__ */ jsx19(FormControlLabel2, { value: "tab", control: /* @__PURE__ */ jsx19(Radio, {}), label: "Tabulado (.tab | )" }),
3723
- /* @__PURE__ */ jsx19(FormControlLabel2, { value: "csv", control: /* @__PURE__ */ jsx19(Radio, {}), label: "CSV (.csv , )" })
3777
+ /* @__PURE__ */ jsx20(FormControlLabel2, { value: "xlsx", control: /* @__PURE__ */ jsx20(Radio, {}), label: "Excel (.xlsx)" }),
3778
+ /* @__PURE__ */ jsx20(FormControlLabel2, { value: "tab", control: /* @__PURE__ */ jsx20(Radio, {}), label: "Tabulado (.tab | )" }),
3779
+ /* @__PURE__ */ jsx20(FormControlLabel2, { value: "csv", control: /* @__PURE__ */ jsx20(Radio, {}), label: "CSV (.csv , )" })
3724
3780
  ]
3725
3781
  }
3726
3782
  )
3727
3783
  ] }),
3728
3784
  /* @__PURE__ */ jsxs15(Box10, { sx: { mt: 3 }, children: [
3729
- /* @__PURE__ */ jsx19(Typography8, { variant: "subtitle2", gutterBottom: true, children: "Opciones de campos:" }),
3785
+ /* @__PURE__ */ jsx20(Typography8, { variant: "subtitle2", gutterBottom: true, children: "Opciones de campos:" }),
3730
3786
  /* @__PURE__ */ jsxs15(FormGroup, { children: [
3731
- /* @__PURE__ */ jsx19(
3787
+ /* @__PURE__ */ jsx20(
3732
3788
  FormControlLabel2,
3733
3789
  {
3734
- control: /* @__PURE__ */ jsx19(Checkbox2, { checked: options.fromOtherTables, onChange: handleOptionChange, name: "fromOtherTables" }),
3790
+ control: /* @__PURE__ */ jsx20(Checkbox2, { checked: options.fromOtherTables, onChange: handleOptionChange, name: "fromOtherTables" }),
3735
3791
  label: "Desde otras tablas"
3736
3792
  }
3737
3793
  ),
3738
- /* @__PURE__ */ jsx19(
3794
+ /* @__PURE__ */ jsx20(
3739
3795
  FormControlLabel2,
3740
3796
  {
3741
- control: /* @__PURE__ */ jsx19(Checkbox2, { checked: options.readOnly, onChange: handleOptionChange, name: "readOnly" }),
3797
+ control: /* @__PURE__ */ jsx20(Checkbox2, { checked: options.readOnly, onChange: handleOptionChange, name: "readOnly" }),
3742
3798
  label: "Solo lectura"
3743
3799
  }
3744
3800
  ),
3745
- /* @__PURE__ */ jsx19(
3801
+ /* @__PURE__ */ jsx20(
3746
3802
  FormControlLabel2,
3747
3803
  {
3748
- control: /* @__PURE__ */ jsx19(Checkbox2, { checked: options.hiddens, onChange: handleOptionChange, name: "hiddens" }),
3804
+ control: /* @__PURE__ */ jsx20(Checkbox2, { checked: options.hiddens, onChange: handleOptionChange, name: "hiddens" }),
3749
3805
  label: "Ocultos"
3750
3806
  }
3751
3807
  )
@@ -3753,46 +3809,66 @@ var ExportDialog = ({
3753
3809
  ] })
3754
3810
  ] }) }),
3755
3811
  /* @__PURE__ */ jsxs15(DialogActions3, { children: [
3756
- /* @__PURE__ */ jsx19(Button6, { onClick: onClose, disabled: isPreparing, children: "Cancelar" }),
3757
- /* @__PURE__ */ jsx19(Button6, { onClick: handlePrepareExport, variant: "contained", disabled: isPreparing, children: "Descargar" })
3812
+ /* @__PURE__ */ jsx20(Button6, { onClick: onClose, disabled: isPreparing, children: "Cancelar" }),
3813
+ /* @__PURE__ */ jsx20(Button6, { onClick: handlePrepareExport, variant: "contained", disabled: isPreparing, children: "Descargar" })
3758
3814
  ] })
3759
3815
  ] });
3760
3816
  };
3761
3817
 
3818
+ // src/components/grid/DialogoDeColumnas.tsx
3819
+ import { Box as Box11, Button as Button7, Dialog as Dialog4, DialogActions as DialogActions4, DialogContent as DialogContent4, DialogTitle as DialogTitle4, List as List3, ListItemButton as ListItemButton3, ListItemText as ListItemText2, Typography as Typography9 } from "@mui/material";
3820
+ import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
3821
+ var DialogoDeColumnas = ({ open, onClose, columnas, ocultas, alternarColumna }) => {
3822
+ const lista = (titulo, nombres, idDeLista) => /* @__PURE__ */ jsxs16(Box11, { sx: { flex: 1, minWidth: 0 }, children: [
3823
+ /* @__PURE__ */ jsx21(Typography9, { variant: "subtitle2", sx: { mb: 1 }, children: titulo }),
3824
+ /* @__PURE__ */ jsx21(List3, { dense: true, "data-testid": idDeLista, sx: { maxHeight: 360, overflow: "auto", border: 1, borderColor: "divider", borderRadius: 1 }, children: nombres.map((nombre) => /* @__PURE__ */ jsx21(ListItemButton3, { onClick: () => alternarColumna(nombre), children: /* @__PURE__ */ jsx21(ListItemText2, { primary: nombre }) }, nombre)) })
3825
+ ] });
3826
+ return /* @__PURE__ */ jsxs16(Dialog4, { open, onClose, maxWidth: "sm", fullWidth: true, children: [
3827
+ /* @__PURE__ */ jsx21(DialogTitle4, { children: "Ocultar o mostrar columnas" }),
3828
+ /* @__PURE__ */ jsx21(DialogContent4, { children: /* @__PURE__ */ jsxs16(Box11, { sx: { display: "flex", gap: 2, pt: 1 }, children: [
3829
+ lista("Columnas mostradas", columnas.filter((nombre) => !ocultas.has(nombre)), "columnas-mostradas"),
3830
+ lista("Columnas ocultas", columnas.filter((nombre) => ocultas.has(nombre)), "columnas-ocultas")
3831
+ ] }) }),
3832
+ /* @__PURE__ */ jsx21(DialogActions4, { children: /* @__PURE__ */ jsx21(Button7, { onClick: onClose, children: "Cerrar" }) })
3833
+ ] });
3834
+ };
3835
+
3762
3836
  // src/pages/VerticalEditorPage.tsx
3763
- import { useState as useState14, useCallback as useCallback10, useMemo as useMemo9, useRef as useRef6 } from "react";
3837
+ import { useState as useState15, useCallback as useCallback11, useMemo as useMemo9, useRef as useRef6 } from "react";
3764
3838
  import {
3765
- DialogTitle as DialogTitle4,
3766
- DialogContent as DialogContent4,
3767
- DialogActions as DialogActions4,
3768
- Button as Button7,
3839
+ DialogTitle as DialogTitle5,
3840
+ DialogContent as DialogContent5,
3841
+ DialogActions as DialogActions5,
3842
+ Button as Button8,
3769
3843
  Alert,
3770
- Box as Box11,
3844
+ Box as Box12,
3771
3845
  CircularProgress as CircularProgress3,
3772
3846
  IconButton as IconButton5,
3773
- Typography as Typography9
3847
+ Typography as Typography10
3774
3848
  } from "@mui/material";
3775
3849
  import CloseIcon from "@mui/icons-material/Close";
3776
- import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
3850
+ import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
3851
+ var SIN_OCULTAS = /* @__PURE__ */ new Set();
3777
3852
  var VerticalEditorPage = ({
3778
3853
  tableName,
3779
3854
  tableDefinition,
3780
3855
  initialData,
3781
3856
  fixedFields,
3857
+ columnasOcultas = SIN_OCULTAS,
3782
3858
  isNewRow = false,
3783
3859
  onSaveSuccess,
3784
3860
  onClose
3785
3861
  }) => {
3786
3862
  const { saveRecord } = useTableRecordSave();
3787
- const [internalIsNewRow, setInternalIsNewRow] = useState14(isNewRow);
3788
- const [formData, setFormData] = useState14(initialData);
3789
- const [lastSavedData, setLastSavedData] = useState14(initialData);
3790
- const [validityMap, setValidityMap] = useState14({});
3791
- const [globalError, setGlobalError] = useState14(null);
3792
- const [isSaving, setIsSaving] = useState14(false);
3793
- const [fieldFeedback, setFieldFeedback] = useState14({});
3863
+ const [internalIsNewRow, setInternalIsNewRow] = useState15(isNewRow);
3864
+ const [formData, setFormData] = useState15(initialData);
3865
+ const [lastSavedData, setLastSavedData] = useState15(initialData);
3866
+ const [validityMap, setValidityMap] = useState15({});
3867
+ const [globalError, setGlobalError] = useState15(null);
3868
+ const [isSaving, setIsSaving] = useState15(false);
3869
+ const [fieldFeedback, setFieldFeedback] = useState15({});
3794
3870
  const feedbackTimersRef = useRef6({});
3795
- const handleFieldChange = useCallback10((fieldName, newValue, isValid) => {
3871
+ const handleFieldChange = useCallback11((fieldName, newValue, isValid) => {
3796
3872
  setFormData((prev) => ({ ...prev, [fieldName]: newValue }));
3797
3873
  setValidityMap((prev) => ({ ...prev, [fieldName]: isValid }));
3798
3874
  setGlobalError(null);
@@ -3810,7 +3886,7 @@ var VerticalEditorPage = ({
3810
3886
  }
3811
3887
  return true;
3812
3888
  }, [formData, validityMap, tableDefinition.fields]);
3813
- const handleCommit = useCallback10(async (fieldName, newValue, isValid) => {
3889
+ const handleCommit = useCallback11(async (fieldName, newValue, isValid) => {
3814
3890
  if (!isValid) return;
3815
3891
  if (sameValue(newValue, lastSavedData[fieldName])) {
3816
3892
  return;
@@ -3900,21 +3976,21 @@ var VerticalEditorPage = ({
3900
3976
  tableDefinition,
3901
3977
  onSaveSuccess
3902
3978
  ]);
3903
- return /* @__PURE__ */ jsxs16(Box11, { sx: { p: 2, display: "flex", flexDirection: "column", height: "100%" }, children: [
3904
- /* @__PURE__ */ jsxs16(DialogTitle4, { sx: { px: 0, pt: 0, display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
3905
- /* @__PURE__ */ jsxs16(Typography9, { component: "div", variant: "h6", children: [
3979
+ return /* @__PURE__ */ jsxs17(Box12, { sx: { p: 2, display: "flex", flexDirection: "column", height: "100%" }, children: [
3980
+ /* @__PURE__ */ jsxs17(DialogTitle5, { sx: { px: 0, pt: 0, display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
3981
+ /* @__PURE__ */ jsxs17(Typography10, { component: "div", variant: "h6", children: [
3906
3982
  isNewRow ? "Nuevo Registro" : "Editar Registro",
3907
3983
  " - ",
3908
3984
  tableDefinition.title || tableName
3909
3985
  ] }),
3910
- /* @__PURE__ */ jsx20(IconButton5, { onClick: onClose, size: "small", edge: "end", children: /* @__PURE__ */ jsx20(CloseIcon, {}) })
3986
+ /* @__PURE__ */ jsx22(IconButton5, { onClick: onClose, size: "small", edge: "end", children: /* @__PURE__ */ jsx22(CloseIcon, {}) })
3911
3987
  ] }),
3912
- /* @__PURE__ */ jsxs16(DialogContent4, { dividers: true, sx: { px: 2, flexGrow: 1, py: 1 }, children: [
3913
- globalError && /* @__PURE__ */ jsx20(Alert, { severity: "error", sx: { mb: 2 }, children: globalError }),
3914
- /* @__PURE__ */ jsx20(Box11, { sx: { display: "flex", flexDirection: "column", gap: 0.5 }, children: tableDefinition.fields.map((field) => {
3988
+ /* @__PURE__ */ jsxs17(DialogContent5, { dividers: true, sx: { px: 2, flexGrow: 1, py: 1 }, children: [
3989
+ globalError && /* @__PURE__ */ jsx22(Alert, { severity: "error", sx: { mb: 2 }, children: globalError }),
3990
+ /* @__PURE__ */ jsx22(Box12, { sx: { display: "flex", flexDirection: "column", gap: 0.5 }, children: tableDefinition.fields.filter((field) => campoDibujable(field) && !columnasOcultas.has(field.name)).map((field) => {
3915
3991
  const isFixed = fixedFields?.some((ff) => ff.fieldName === field.name);
3916
3992
  const isMandatory = field.nullable === false || tableDefinition.primaryKey.includes(field.name);
3917
- return /* @__PURE__ */ jsx20(Box11, { sx: { width: "100%", maxWidth: "100%" }, children: /* @__PURE__ */ jsx20(
3993
+ return /* @__PURE__ */ jsx22(Box12, { sx: { width: "100%", maxWidth: "100%" }, children: /* @__PURE__ */ jsx22(
3918
3994
  TypedField,
3919
3995
  {
3920
3996
  fieldDef: field,
@@ -3928,12 +4004,12 @@ var VerticalEditorPage = ({
3928
4004
  ) }, field.name);
3929
4005
  }) })
3930
4006
  ] }),
3931
- /* @__PURE__ */ jsxs16(DialogActions4, { sx: { px: 0, pb: 0, pt: 2, justifyContent: "space-between", alignItems: "center" }, children: [
3932
- /* @__PURE__ */ jsxs16(Box11, { children: [
3933
- isSaving && /* @__PURE__ */ jsx20(CircularProgress3, { size: 20, sx: { ml: 2 } }),
3934
- /* @__PURE__ */ jsx20("span", { style: { marginLeft: 10, fontSize: "0.8rem", color: "#666" }, children: isSaving ? "Guardando..." : "Cambios auto-guardados" })
4007
+ /* @__PURE__ */ jsxs17(DialogActions5, { sx: { px: 0, pb: 0, pt: 2, justifyContent: "space-between", alignItems: "center" }, children: [
4008
+ /* @__PURE__ */ jsxs17(Box12, { children: [
4009
+ isSaving && /* @__PURE__ */ jsx22(CircularProgress3, { size: 20, sx: { ml: 2 } }),
4010
+ /* @__PURE__ */ jsx22("span", { style: { marginLeft: 10, fontSize: "0.8rem", color: "#666" }, children: isSaving ? "Guardando..." : "Cambios auto-guardados" })
3935
4011
  ] }),
3936
- /* @__PURE__ */ jsx20(Button7, { variant: "outlined", onClick: onClose, children: "Cerrar" })
4012
+ /* @__PURE__ */ jsx22(Button8, { variant: "outlined", onClick: onClose, children: "Cerrar" })
3937
4013
  ] })
3938
4014
  ] });
3939
4015
  };
@@ -4010,7 +4086,7 @@ var baseDelBundler = import.meta.env?.BASE_URL ?? "/";
4010
4086
  var rutaBase = baseDelBundler.replace(/\/+$/, "");
4011
4087
 
4012
4088
  // src/components/grid/GenericDataGrid.tsx
4013
- import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
4089
+ import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
4014
4090
  var SUMMARY_ROW_HEIGHT = 35;
4015
4091
  var FILTER_ROW_HEIGHT = 35;
4016
4092
  var HEADER_ROW_HEIGHT = 30;
@@ -4042,8 +4118,8 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
4042
4118
  name: field.label || cambiarGuionesBajosPorEspacios(field.name),
4043
4119
  width: 150,
4044
4120
  editable: false,
4045
- renderHeaderCell: () => /* @__PURE__ */ jsx21(Box12, { sx: { p: 0.5, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx21(
4046
- Typography10,
4121
+ renderHeaderCell: () => /* @__PURE__ */ jsx23(Box13, { sx: { p: 0.5, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx23(
4122
+ Typography11,
4047
4123
  {
4048
4124
  variant: "caption",
4049
4125
  sx: {
@@ -4054,11 +4130,11 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
4054
4130
  children: field.label || cambiarGuionesBajosPorEspacios(field.name)
4055
4131
  }
4056
4132
  ) }),
4057
- renderCell: (props) => /* @__PURE__ */ jsx21(Box12, { sx: { px: 1, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx21(Typography10, { variant: "body2", sx: { fontSize: "0.875rem" }, noWrap: true, children: String(props.row[field.name] ?? "") }) })
4133
+ renderCell: (props) => /* @__PURE__ */ jsx23(Box13, { sx: { px: 1, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx23(Typography11, { variant: "body2", sx: { fontSize: "0.875rem" }, noWrap: true, children: String(props.row[field.name] ?? "") }) })
4058
4134
  };
4059
4135
  });
4060
4136
  }, [tableDefinition, fieldsToHide]);
4061
- return /* @__PURE__ */ jsxs17(Box12, { sx: {
4137
+ return /* @__PURE__ */ jsxs18(Box13, { sx: {
4062
4138
  mb: 1.5,
4063
4139
  ml: index * 4,
4064
4140
  // El primer ancestro (index 0) no tiene margen, los siguientes sí
@@ -4069,7 +4145,7 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
4069
4145
  boxShadow: theme.shadows[1],
4070
4146
  bgcolor: "background.paper"
4071
4147
  }, children: [
4072
- /* @__PURE__ */ jsx21(Box12, { sx: {
4148
+ /* @__PURE__ */ jsx23(Box13, { sx: {
4073
4149
  bgcolor: "primary.main",
4074
4150
  color: "primary.contrastText",
4075
4151
  px: 1.5,
@@ -4080,8 +4156,8 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
4080
4156
  alignItems: "center",
4081
4157
  fontWeight: "bold",
4082
4158
  gap: 1
4083
- }, children: /* @__PURE__ */ jsx21(Typography10, { variant: "subtitle2", component: "div", children: cambiarGuionesBajosPorEspacios(ancestor.tableName) }) }),
4084
- /* @__PURE__ */ jsx21(
4159
+ }, children: /* @__PURE__ */ jsx23(Typography11, { variant: "subtitle2", component: "div", children: cambiarGuionesBajosPorEspacios(ancestor.tableName) }) }),
4160
+ /* @__PURE__ */ jsx23(
4085
4161
  DataGrid,
4086
4162
  {
4087
4163
  className: "rdg-light",
@@ -4122,32 +4198,38 @@ var GenericDataGrid = ({
4122
4198
  // eslint-disable-line react-hooks/exhaustive-deps
4123
4199
  );
4124
4200
  const cacheHeredado = useContext4(CacheGrillasContext);
4125
- const [cachePropio] = useState15(() => /* @__PURE__ */ new Map());
4201
+ const [cachePropio] = useState16(() => /* @__PURE__ */ new Map());
4126
4202
  const cache = cacheHeredado ?? cachePropio;
4127
- const [guardada] = useState15(() => claveCache ? cache.get(claveCache) : void 0);
4203
+ const [guardada] = useState16(() => claveCache ? cache.get(claveCache) : void 0);
4128
4204
  const claveCargadaRef = useRef7(guardada ? `${tableName}|${claveFixedFields}|${claveParametros}` : null);
4129
- const [tableDefinition, setTableDefinition] = useState15(guardada?.tableDefinition ?? null);
4130
- const [tableData, setTableData] = useState15(guardada?.tableData ?? []);
4131
- const [cargandoInicial, setCargandoInicial] = useState15(!guardada);
4132
- const [errorDeCarga, setErrorDeCarga] = useState15(null);
4133
- const [anchosCalculados, setAnchosCalculados] = useState15(() => guardada?.anchosCalculados ?? /* @__PURE__ */ new Map());
4134
- const [detallesAbiertos, setDetallesAbiertos] = useState15(guardada?.detallesAbiertos ?? []);
4135
- const [altosDetalle, setAltosDetalle] = useState15(() => guardada?.altosDetalle ?? /* @__PURE__ */ new Map());
4136
- const [anchosDetalle, setAnchosDetalle] = useState15(() => /* @__PURE__ */ new Map());
4137
- const [selectedRows, setSelectedRows] = useState15(() => /* @__PURE__ */ new Set());
4138
- const [, setSelectedCell] = useState15(void 0);
4139
- const [estadoGrilla] = useState15(crearEstadoGrilla);
4205
+ const [tableDefinition, setTableDefinition] = useState16(guardada?.tableDefinition ?? null);
4206
+ const [tableData, setTableData] = useState16(guardada?.tableData ?? []);
4207
+ const [cargandoInicial, setCargandoInicial] = useState16(!guardada);
4208
+ const [errorDeCarga, setErrorDeCarga] = useState16(null);
4209
+ const [anchosCalculados, setAnchosCalculados] = useState16(() => guardada?.anchosCalculados ?? /* @__PURE__ */ new Map());
4210
+ const [columnasOcultas, setColumnasOcultas] = useState16(() => guardada?.columnasOcultas ?? []);
4211
+ const [openDialogoDeColumnas, setOpenDialogoDeColumnas] = useState16(false);
4212
+ const conjuntoDeOcultas = useMemo10(() => new Set(columnasOcultas), [columnasOcultas]);
4213
+ const ocultarColumna = useCallback12((columna) => setColumnasOcultas((anteriores) => anteriores.includes(columna) ? anteriores : [...anteriores, columna]), []);
4214
+ const alternarColumna = useCallback12((columna) => setColumnasOcultas((anteriores) => anteriores.includes(columna) ? anteriores.filter((oculta) => oculta !== columna) : [...anteriores, columna]), []);
4215
+ const abrirDialogoDeColumnas = useCallback12(() => setOpenDialogoDeColumnas(true), []);
4216
+ const [detallesAbiertos, setDetallesAbiertos] = useState16(guardada?.detallesAbiertos ?? []);
4217
+ const [altosDetalle, setAltosDetalle] = useState16(() => guardada?.altosDetalle ?? /* @__PURE__ */ new Map());
4218
+ const [anchosDetalle, setAnchosDetalle] = useState16(() => /* @__PURE__ */ new Map());
4219
+ const [selectedRows, setSelectedRows] = useState16(() => /* @__PURE__ */ new Set());
4220
+ const [, setSelectedCell] = useState16(void 0);
4221
+ const [estadoGrilla] = useState16(crearEstadoGrilla);
4140
4222
  const theme = useTheme4();
4141
- const [openDataGridOptions, setOpenDataGridOptions] = useState15(false);
4142
- const [dataGridOptionsAnchorEl, setDataGridOptionsAnchorEl] = useState15(null);
4143
- const [exitingRowIds, setExitingRowIds] = useState15(/* @__PURE__ */ new Set());
4223
+ const [openDataGridOptions, setOpenDataGridOptions] = useState16(false);
4224
+ const [dataGridOptionsAnchorEl, setDataGridOptionsAnchorEl] = useState16(null);
4225
+ const [exitingRowIds, setExitingRowIds] = useState16(/* @__PURE__ */ new Set());
4144
4226
  const { showError } = useSnackbar();
4145
4227
  const { username: usuario } = useClientContext();
4146
4228
  const dataGridRef = useRef7(null);
4147
4229
  const rowAtEditStartRef = useRef7(null);
4148
- const [openImportDialog, setOpenImportDialog] = useState15(false);
4149
- const [openExportDialog, setOpenExportDialog] = useState15(false);
4150
- const [columnWidths, setColumnWidths] = useState15(() => /* @__PURE__ */ new Map());
4230
+ const [openImportDialog, setOpenImportDialog] = useState16(false);
4231
+ const [openExportDialog, setOpenExportDialog] = useState16(false);
4232
+ const [columnWidths, setColumnWidths] = useState16(() => /* @__PURE__ */ new Map());
4151
4233
  const { callApi, callApiUpload, loading } = useApiCall();
4152
4234
  const primaryKey = useMemo10(() => {
4153
4235
  if (!tableDefinition) return ["id"];
@@ -4197,7 +4279,7 @@ var GenericDataGrid = ({
4197
4279
  filasDetalleRef.current = nuevas;
4198
4280
  return filas;
4199
4281
  }, [filteredRows, abiertos, tableDefinition, primaryKey]);
4200
- const altoDeDetalle = useCallback11((clave) => altosDetalle.get(clave) ?? ALTO_INICIAL_DETALLE, [altosDetalle]);
4282
+ const altoDeDetalle = useCallback12((clave) => altosDetalle.get(clave) ?? ALTO_INICIAL_DETALLE, [altosDetalle]);
4201
4283
  const altoDetalles = useMemo10(
4202
4284
  () => filasMostradas.reduce((total, row) => esFilaDetalle(row) ? total + altoDeDetalle(row.clave) : total, 0),
4203
4285
  [filasMostradas, altoDeDetalle]
@@ -4244,9 +4326,9 @@ var GenericDataGrid = ({
4244
4326
  filasVisiblesMax,
4245
4327
  conPie
4246
4328
  });
4247
- const [contenidoDeCelda, setContenidoDeCelda] = useState15(null);
4248
- const verContenido = useCallback11((anclaje, texto) => setContenidoDeCelda({ anclaje, texto }), []);
4249
- const cerrarContenidoDeCelda = useCallback11(() => {
4329
+ const [contenidoDeCelda, setContenidoDeCelda] = useState16(null);
4330
+ const verContenido = useCallback12((anclaje, texto) => setContenidoDeCelda({ anclaje, texto }), []);
4331
+ const cerrarContenidoDeCelda = useCallback12(() => {
4250
4332
  const anclaje = contenidoDeCelda?.anclaje;
4251
4333
  setContenidoDeCelda(null);
4252
4334
  setTimeout(() => anclaje?.focus(), 0);
@@ -4325,6 +4407,7 @@ var GenericDataGrid = ({
4325
4407
  setTableDefinition(definition);
4326
4408
  setSortColumns(getInitialSortColumns(definition));
4327
4409
  setAnchosCalculados(calcularAnchosDeColumnas(definition, data));
4410
+ setColumnasOcultas(columnasOcultasIniciales(definition));
4328
4411
  setTableData(data);
4329
4412
  const filasDeFiltros = parametros.filterColumns ?? aFiltrosIniciales(definition.filterColumns);
4330
4413
  if (filasDeFiltros.length > 1) console.warn(`'${tableName}': varias filas de filtros (alternativas) todav\xEDa no est\xE1n soportadas; se aplica la primera`);
@@ -4347,8 +4430,8 @@ var GenericDataGrid = ({
4347
4430
  }, [tableName, claveFixedFields, fixedFields, claveParametros, parametros, showError, callApi, getInitialSortColumns, setSortColumns, aplicarFiltrosIniciales, guardada]);
4348
4431
  useEffect6(() => {
4349
4432
  if (!claveCache || !tableDefinition || cargandoInicial) return;
4350
- cache.set(claveCache, { tableDefinition, tableData, anchosCalculados, sortColumns, detallesAbiertos, altosDetalle });
4351
- }, [cache, claveCache, tableDefinition, tableData, anchosCalculados, sortColumns, detallesAbiertos, altosDetalle, cargandoInicial]);
4433
+ cache.set(claveCache, { tableDefinition, tableData, anchosCalculados, columnasOcultas, sortColumns, detallesAbiertos, altosDetalle });
4434
+ }, [cache, claveCache, tableDefinition, tableData, anchosCalculados, columnasOcultas, sortColumns, detallesAbiertos, altosDetalle, cargandoInicial]);
4352
4435
  useEffect6(() => {
4353
4436
  let timer = null;
4354
4437
  const desuscribir = estadoGrilla.suscribir(() => {
@@ -4374,11 +4457,11 @@ var GenericDataGrid = ({
4374
4457
  if (timer) clearTimeout(timer);
4375
4458
  };
4376
4459
  }, [estadoGrilla]);
4377
- const resetSortingDeLaTabla = useCallback11(() => {
4460
+ const resetSortingDeLaTabla = useCallback12(() => {
4378
4461
  if (tableDefinition) resetSorting(tableDefinition);
4379
4462
  }, [tableDefinition, resetSorting]);
4380
- const abrirImportacion = useCallback11(() => setOpenImportDialog(true), []);
4381
- const abrirExportacion = useCallback11(() => setOpenExportDialog(true), []);
4463
+ const abrirImportacion = useCallback12(() => setOpenImportDialog(true), []);
4464
+ const abrirExportacion = useCallback12(() => setOpenExportDialog(true), []);
4382
4465
  const { menuOptions } = useGridMenu({
4383
4466
  tableDefinition,
4384
4467
  tableName,
@@ -4387,13 +4470,14 @@ var GenericDataGrid = ({
4387
4470
  callApi,
4388
4471
  resetSorting: tableDefinition ? resetSortingDeLaTabla : void 0,
4389
4472
  triggerImport: abrirImportacion,
4390
- triggerExport: abrirExportacion
4473
+ triggerExport: abrirExportacion,
4474
+ abrirColumnas: abrirDialogoDeColumnas
4391
4475
  });
4392
- const abrirOpcionesDeGrilla = useCallback11((anchorEl) => {
4476
+ const abrirOpcionesDeGrilla = useCallback12((anchorEl) => {
4393
4477
  setDataGridOptionsAnchorEl(anchorEl);
4394
4478
  setOpenDataGridOptions(true);
4395
4479
  }, []);
4396
- const editarEnFicha = useCallback11((row) => {
4480
+ const editarEnFicha = useCallback12((row) => {
4397
4481
  rowAtEditStartRef.current = { ...row };
4398
4482
  handleVerticalEditRow(row);
4399
4483
  }, [handleVerticalEditRow]);
@@ -4401,6 +4485,8 @@ var GenericDataGrid = ({
4401
4485
  tableDefinition,
4402
4486
  anchosCalculados,
4403
4487
  fixedFields,
4488
+ columnasOcultas: conjuntoDeOcultas,
4489
+ ocultarColumna,
4404
4490
  primaryKey,
4405
4491
  setTableData,
4406
4492
  handleKeyPressInEditor,
@@ -4411,7 +4497,7 @@ var GenericDataGrid = ({
4411
4497
  toggleFilterVisibility,
4412
4498
  abrirOpcionesDeGrilla
4413
4499
  });
4414
- const abrirDetalleEnPestana = useCallback11((row, detailTable) => {
4500
+ const abrirDetalleEnPestana = useCallback12((row, detailTable) => {
4415
4501
  if (!onOpenDetail || !tableDefinition || !detailTable.table) return;
4416
4502
  const porCampo = /* @__PURE__ */ new Map();
4417
4503
  [...fixedFields ?? [], ...calcularFixedFieldsDetalle(detailTable, row)].forEach((ff) => porCampo.set(ff.fieldName, ff));
@@ -4421,12 +4507,12 @@ var GenericDataGrid = ({
4421
4507
  const newAncestors = [...ancestors, { tableName: tableDefinition.name, row, tableDefinition, fixedFields: allFixedFields }];
4422
4508
  onOpenDetail(detailTable.table, allFixedFields, label, newAncestors);
4423
4509
  }, [onOpenDetail, tableDefinition, fixedFields, ancestors]);
4424
- const abrirWScreenEnPestana = useCallback11((row, detailTable) => {
4510
+ const abrirWScreenEnPestana = useCallback12((row, detailTable) => {
4425
4511
  const parametros2 = new URLSearchParams();
4426
4512
  calcularFixedFieldsDetalle(detailTable, row).forEach((ff) => parametros2.set(ff.fieldName, String(ff.value)));
4427
4513
  window.open(`${window.location.origin}${rutaBase}/wScreens/${detailTable.wScreen}?${parametros2}`, "_blank");
4428
4514
  }, []);
4429
- const alternarDetalle = useCallback11((row, rowId, detailTable, enOtraPestana) => {
4515
+ const alternarDetalle = useCallback12((row, rowId, detailTable, enOtraPestana) => {
4430
4516
  if (enOtraPestana && detailTable.wScreen) {
4431
4517
  abrirWScreenEnPestana(row, detailTable);
4432
4518
  return;
@@ -4438,7 +4524,7 @@ var GenericDataGrid = ({
4438
4524
  const clave = claveDetalle(rowId, detailTable);
4439
4525
  setDetallesAbiertos((anteriores) => anteriores.includes(clave) ? anteriores.filter((c) => c !== clave) : [...anteriores, clave]);
4440
4526
  }, [onOpenDetail, abrirDetalleEnPestana, abrirWScreenEnPestana]);
4441
- const [medidas, setMedidas] = useState15(null);
4527
+ const [medidas, setMedidas] = useState16(null);
4442
4528
  useEffect6(() => {
4443
4529
  const elemento = dataGridRef.current?.element;
4444
4530
  if (!elemento) return;
@@ -4452,7 +4538,7 @@ var GenericDataGrid = ({
4452
4538
  return () => observador.disconnect();
4453
4539
  }, [tableDefinition, cargandoInicial]);
4454
4540
  const anchoVisible = medidas?.ancho ?? null;
4455
- const [altoDeVentana, setAltoDeVentana] = useState15(null);
4541
+ const [altoDeVentana, setAltoDeVentana] = useState16(null);
4456
4542
  useEffect6(() => {
4457
4543
  if (anidada) return;
4458
4544
  const elemento = dataGridRef.current?.element;
@@ -4465,22 +4551,22 @@ var GenericDataGrid = ({
4465
4551
  const altoDeContexto = useContext4(AltoDisponibleContext);
4466
4552
  const altoDeEstaGrilla = anidada ? altoDisponible ?? (altoDeContexto === void 0 ? void 0 : altoDeContexto - ALTO_TITULO_ANIDADA) : altoDeVentana ?? void 0;
4467
4553
  const altoMaximoDetalleEfectivo = altoMaximoDetalle ?? (altoDeEstaGrilla !== void 0 ? Math.max(ALTO_MINIMO_DETALLE, altoDeEstaGrilla - HEADER_ROW_HEIGHT - (conPie ? SUMMARY_ROW_HEIGHT : 0) - ROW_HEIGHT - (isFilterRowVisible ? FILTER_ROW_HEIGHT : 0)) : void 0);
4468
- const cambiarAnchoDetalle = useCallback11((clave, ancho) => {
4554
+ const cambiarAnchoDetalle = useCallback12((clave, ancho) => {
4469
4555
  setAnchosDetalle((anteriores) => anteriores.get(clave) === ancho ? anteriores : new Map(anteriores).set(clave, ancho));
4470
4556
  }, []);
4471
- const cambiarAltoDetalle = useCallback11((clave, altoDeseado2) => {
4557
+ const cambiarAltoDetalle = useCallback12((clave, altoDeseado2) => {
4472
4558
  const alto = Math.min(Math.max(Math.round(altoDeseado2), ALTO_MINIMO_DETALLE), altoMaximoDetalleEfectivo ?? Infinity);
4473
4559
  setAltosDetalle((anteriores) => anteriores.get(clave) === alto ? anteriores : new Map(anteriores).set(clave, alto));
4474
4560
  }, [altoMaximoDetalleEfectivo]);
4475
- const renderDetalle = useCallback11((fila) => {
4561
+ const renderDetalle = useCallback12((fila) => {
4476
4562
  const { detailTable } = fila;
4477
- return /* @__PURE__ */ jsx21(
4563
+ return /* @__PURE__ */ jsx23(
4478
4564
  "div",
4479
4565
  {
4480
4566
  className: "fpr-detalle",
4481
4567
  style: { maxWidth: anchoVisible ? anchoVisible - 2 : void 0 },
4482
4568
  onKeyDown: (e) => e.stopPropagation(),
4483
- children: detailTable.table ? /* @__PURE__ */ jsx21(
4569
+ children: detailTable.table ? /* @__PURE__ */ jsx23(
4484
4570
  GenericDataGrid,
4485
4571
  {
4486
4572
  tableName: detailTable.table,
@@ -4493,7 +4579,7 @@ var GenericDataGrid = ({
4493
4579
  onOpenDetail,
4494
4580
  ancestors: tableDefinition ? [...ancestors, { tableName: tableDefinition.name, row: fila.filaPadre, tableDefinition, fixedFields: fila.fixedFields }] : ancestors
4495
4581
  }
4496
- ) : detailTable.wScreen ? /* @__PURE__ */ jsx21(
4582
+ ) : detailTable.wScreen ? /* @__PURE__ */ jsx23(
4497
4583
  DetalleWScreen,
4498
4584
  {
4499
4585
  fila,
@@ -4501,7 +4587,7 @@ var GenericDataGrid = ({
4501
4587
  onAlto: (alto) => cambiarAltoDetalle(fila.clave, alto),
4502
4588
  onAncho: (ancho) => cambiarAnchoDetalle(fila.clave, ancho)
4503
4589
  }
4504
- ) : /* @__PURE__ */ jsxs17(Alert2, { severity: "warning", children: [
4590
+ ) : /* @__PURE__ */ jsxs18(Alert2, { severity: "warning", children: [
4505
4591
  "El detalle '",
4506
4592
  detailTable.abr,
4507
4593
  "' no tiene ni tabla ni wScreen."
@@ -4514,9 +4600,9 @@ var GenericDataGrid = ({
4514
4600
  useEffect6(() => {
4515
4601
  onAltoDeseado?.(altoDeseado);
4516
4602
  }, [onAltoDeseado, altoDeseado]);
4517
- const rowKeyGetter = useCallback11((row) => esFilaDetalle(row) ? `detalle:${row.clave}` : getPrimaryKeyValues(row, primaryKey), [primaryKey]);
4518
- const rowHeight = useCallback11((row) => esFilaDetalle(row) ? altoDeDetalle(row.clave) : ROW_HEIGHT, [altoDeDetalle]);
4519
- const rowClass = useCallback11(
4603
+ const rowKeyGetter = useCallback12((row) => esFilaDetalle(row) ? `detalle:${row.clave}` : getPrimaryKeyValues(row, primaryKey), [primaryKey]);
4604
+ const rowHeight = useCallback12((row) => esFilaDetalle(row) ? altoDeDetalle(row.clave) : ROW_HEIGHT, [altoDeDetalle]);
4605
+ const rowClass = useCallback12(
4520
4606
  (row) => esFilaDetalle(row) ? "fpr-fila-detalle" : exitingRowIds.has(getPrimaryKeyValues(row, primaryKey)) ? "fpr-fila-saliendo" : void 0,
4521
4607
  [exitingRowIds, primaryKey]
4522
4608
  );
@@ -4547,19 +4633,19 @@ var GenericDataGrid = ({
4547
4633
  };
4548
4634
  const fallBackMessage = getFallBackMessage();
4549
4635
  if (cargandoInicial) {
4550
- return /* @__PURE__ */ jsxs17(Box12, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: [
4551
- /* @__PURE__ */ jsx21(CircularProgress4, {}),
4552
- /* @__PURE__ */ jsx21(Typography10, { variant: "h6", sx: { ml: 2 }, children: "Cargando tabla..." })
4636
+ return /* @__PURE__ */ jsxs18(Box13, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: [
4637
+ /* @__PURE__ */ jsx23(CircularProgress4, {}),
4638
+ /* @__PURE__ */ jsx23(Typography11, { variant: "h6", sx: { ml: 2 }, children: "Cargando tabla..." })
4553
4639
  ] });
4554
4640
  }
4555
4641
  if (errorDeCarga) {
4556
- return /* @__PURE__ */ jsx21(Box12, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ jsx21(Alert2, { severity: "error", children: errorDeCarga }) });
4642
+ return /* @__PURE__ */ jsx23(Box13, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ jsx23(Alert2, { severity: "error", children: errorDeCarga }) });
4557
4643
  }
4558
4644
  if (!tableDefinition) {
4559
- return /* @__PURE__ */ jsx21(Box12, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ jsx21(Alert2, { severity: "warning", children: "No se pudo cargar la definici\xF3n de la tabla." }) });
4645
+ return /* @__PURE__ */ jsx23(Box13, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ jsx23(Alert2, { severity: "warning", children: "No se pudo cargar la definici\xF3n de la tabla." }) });
4560
4646
  }
4561
- return /* @__PURE__ */ jsx21(CacheGrillasContext.Provider, { value: cache, children: /* @__PURE__ */ jsxs17(Box12, { sx: { pt: anidada ? 0 : 2, display: "flex", flexDirection: "column", height: "100%", boxSizing: "border-box", width: anchoContenido ?? void 0, maxWidth: "100%" }, children: [
4562
- !anidada && ancestors.length > 0 && /* @__PURE__ */ jsx21(Box12, { sx: { px: 2, pt: 0, pb: 1, display: "flex", flexDirection: "column" }, children: ancestors.map((ancestor, index) => /* @__PURE__ */ jsx21(
4647
+ return /* @__PURE__ */ jsx23(CacheGrillasContext.Provider, { value: cache, children: /* @__PURE__ */ jsxs18(Box13, { sx: { pt: anidada ? 0 : 2, display: "flex", flexDirection: "column", height: "100%", boxSizing: "border-box", width: anchoContenido ?? void 0, maxWidth: "100%" }, children: [
4648
+ !anidada && ancestors.length > 0 && /* @__PURE__ */ jsx23(Box13, { sx: { px: 2, pt: 0, pb: 1, display: "flex", flexDirection: "column" }, children: ancestors.map((ancestor, index) => /* @__PURE__ */ jsx23(
4563
4649
  StaticAncestorGrid,
4564
4650
  {
4565
4651
  ancestor,
@@ -4568,8 +4654,8 @@ var GenericDataGrid = ({
4568
4654
  },
4569
4655
  index
4570
4656
  )) }),
4571
- /* @__PURE__ */ jsxs17(
4572
- Box12,
4657
+ /* @__PURE__ */ jsxs18(
4658
+ Box13,
4573
4659
  {
4574
4660
  sx: {
4575
4661
  backgroundColor: theme.palette.primary.main,
@@ -4591,17 +4677,17 @@ var GenericDataGrid = ({
4591
4677
  gap: 1
4592
4678
  },
4593
4679
  children: [
4594
- /* @__PURE__ */ jsxs17(Typography10, { variant: "subtitle2", component: "div", children: [
4680
+ /* @__PURE__ */ jsxs18(Typography11, { variant: "subtitle2", component: "div", children: [
4595
4681
  titulo ?? cambiarGuionesBajosPorEspacios(tableDefinition.title || tableDefinition.name),
4596
4682
  " - ",
4597
4683
  filteredRows.length === tableData.length ? `${tableData.length} registros` : `${filteredRows.length} (F)`
4598
4684
  ] }),
4599
- loading && /* @__PURE__ */ jsx21(CircularProgress4, { size: 14, color: "inherit" })
4685
+ loading && /* @__PURE__ */ jsx23(CircularProgress4, { size: 14, color: "inherit" })
4600
4686
  ]
4601
4687
  }
4602
4688
  ),
4603
- /* @__PURE__ */ jsxs17(
4604
- Box12,
4689
+ /* @__PURE__ */ jsxs18(
4690
+ Box13,
4605
4691
  {
4606
4692
  sx: {
4607
4693
  // Una grilla anidada se acota con px (el alto que le dio la de arriba, o el de una wScreen): una wScreen
@@ -4619,7 +4705,7 @@ var GenericDataGrid = ({
4619
4705
  pb: anidada ? 0 : 3
4620
4706
  },
4621
4707
  children: [
4622
- /* @__PURE__ */ jsx21(EstadoGrillaContext.Provider, { value: estadoGrilla, children: /* @__PURE__ */ jsx21(VistaGrillaContext.Provider, { value: vistaGrilla, children: /* @__PURE__ */ jsx21(DetallesGrillaContext.Provider, { value: detallesGrilla, children: /* @__PURE__ */ jsx21(
4708
+ /* @__PURE__ */ jsx23(EstadoGrillaContext.Provider, { value: estadoGrilla, children: /* @__PURE__ */ jsx23(VistaGrillaContext.Provider, { value: vistaGrilla, children: /* @__PURE__ */ jsx23(DetallesGrillaContext.Provider, { value: detallesGrilla, children: /* @__PURE__ */ jsx23(
4623
4709
  DataGrid,
4624
4710
  {
4625
4711
  className: "rdg-light",
@@ -4649,8 +4735,8 @@ var GenericDataGrid = ({
4649
4735
  onCellKeyDown: handleCellKeyDown
4650
4736
  }
4651
4737
  ) }) }) }),
4652
- fallBackMessage && /* @__PURE__ */ jsx21(
4653
- Box12,
4738
+ fallBackMessage && /* @__PURE__ */ jsx23(
4739
+ Box13,
4654
4740
  {
4655
4741
  sx: {
4656
4742
  position: "absolute",
@@ -4666,24 +4752,35 @@ var GenericDataGrid = ({
4666
4752
  zIndex: tableData.length === 0 ? 10 : 1
4667
4753
  // Mantenemos el zIndex superior para el estado vacío total
4668
4754
  },
4669
- children: /* @__PURE__ */ jsx21(Typography10, { variant: "body2", color: "textSecondary", children: fallBackMessage })
4755
+ children: /* @__PURE__ */ jsx23(Typography11, { variant: "body2", color: "textSecondary", children: fallBackMessage })
4670
4756
  }
4671
4757
  )
4672
4758
  ]
4673
4759
  }
4674
4760
  ),
4675
- /* @__PURE__ */ jsx21(
4761
+ /* @__PURE__ */ jsx23(
4676
4762
  ExportDialog,
4677
4763
  {
4678
4764
  open: openExportDialog,
4679
4765
  onClose: () => setOpenExportDialog(false),
4680
4766
  tableDefinition,
4767
+ columnasOcultas: conjuntoDeOcultas,
4681
4768
  tableData,
4682
4769
  filteredRows,
4683
4770
  username: usuario || "anonymous"
4684
4771
  }
4685
4772
  ),
4686
- /* @__PURE__ */ jsx21(
4773
+ /* @__PURE__ */ jsx23(
4774
+ DialogoDeColumnas,
4775
+ {
4776
+ open: openDialogoDeColumnas,
4777
+ onClose: () => setOpenDialogoDeColumnas(false),
4778
+ columnas: (tableDefinition?.fields ?? []).filter(campoDibujable).map((field) => field.name).filter((nombre) => !columnaOcultaPorFixedField(fixedFields, nombre)),
4779
+ ocultas: conjuntoDeOcultas,
4780
+ alternarColumna
4781
+ }
4782
+ ),
4783
+ /* @__PURE__ */ jsx23(
4687
4784
  ConfirmDialog,
4688
4785
  {
4689
4786
  open: openConfirmDialog,
@@ -4692,7 +4789,7 @@ var GenericDataGrid = ({
4692
4789
  message: rowToDelete && rowToDelete[NEW_ROW_INDICATOR] ? `\xBFEst\xE1s seguro de que quieres eliminar esta nueva fila (ID: ${getPrimaryKeyValues(rowToDelete, primaryKey)}) localmente?` : rowToDelete ? `\xBFEst\xE1s seguro de que quieres eliminar la fila con ID: ${getPrimaryKeyValues(rowToDelete, primaryKey)} de la base de datos? Esta acci\xF3n es irreversible.` : "\xBFEst\xE1s seguro de que quieres eliminar este registro? Esta acci\xF3n es irreversible."
4693
4790
  }
4694
4791
  ),
4695
- /* @__PURE__ */ jsx21(
4792
+ /* @__PURE__ */ jsx23(
4696
4793
  DataGridOptionsDialog,
4697
4794
  {
4698
4795
  open: openDataGridOptions,
@@ -4701,7 +4798,7 @@ var GenericDataGrid = ({
4701
4798
  anchorEl: dataGridOptionsAnchorEl
4702
4799
  }
4703
4800
  ),
4704
- /* @__PURE__ */ jsx21(
4801
+ /* @__PURE__ */ jsx23(
4705
4802
  ImportDialog,
4706
4803
  {
4707
4804
  open: openImportDialog,
@@ -4710,20 +4807,21 @@ var GenericDataGrid = ({
4710
4807
  loading
4711
4808
  }
4712
4809
  ),
4713
- /* @__PURE__ */ jsx21(
4714
- Dialog4,
4810
+ /* @__PURE__ */ jsx23(
4811
+ Dialog5,
4715
4812
  {
4716
4813
  open: openVerticalEditDialog,
4717
4814
  onClose: () => setOpenVerticalEditDialog(false),
4718
4815
  maxWidth: "sm",
4719
4816
  fullWidth: true,
4720
- children: rowToEditVertical && /* @__PURE__ */ jsx21(
4817
+ children: rowToEditVertical && /* @__PURE__ */ jsx23(
4721
4818
  VerticalEditorPage,
4722
4819
  {
4723
4820
  tableName,
4724
4821
  tableDefinition,
4725
4822
  initialData: rowToEditVertical,
4726
4823
  fixedFields,
4824
+ columnasOcultas: conjuntoDeOcultas,
4727
4825
  isNewRow: !!rowToEditVertical[NEW_ROW_INDICATOR],
4728
4826
  onSaveSuccess: (savedRow, isNewItem) => {
4729
4827
  setRowToEditVertical(savedRow);
@@ -4762,24 +4860,24 @@ var GenericDataGrid = ({
4762
4860
  )
4763
4861
  }
4764
4862
  ),
4765
- contenidoDeCelda && /* @__PURE__ */ jsx21(VentanaDeTexto, { anclaje: contenidoDeCelda.anclaje, texto: contenidoDeCelda.texto, editable: false, onAceptar: cerrarContenidoDeCelda, onCerrar: cerrarContenidoDeCelda })
4863
+ contenidoDeCelda && /* @__PURE__ */ jsx23(VentanaDeTexto, { anclaje: contenidoDeCelda.anclaje, texto: contenidoDeCelda.texto, editable: false, onAceptar: cerrarContenidoDeCelda, onCerrar: cerrarContenidoDeCelda })
4766
4864
  ] }) });
4767
4865
  };
4768
4866
  var GenericDataGrid_default = GenericDataGrid;
4769
4867
 
4770
4868
  // src/App.tsx
4771
- import React32, { useEffect as useEffect18, useMemo as useMemo16 } from "react";
4869
+ import React33, { useEffect as useEffect18, useMemo as useMemo16 } from "react";
4772
4870
  import { BrowserRouter, Routes, Route, useLocation as useLocation8, Navigate as Navigate4, Outlet as Outlet2 } from "react-router-dom";
4773
4871
 
4774
4872
  // src/components/MainLayout.tsx
4775
4873
  import { useEffect as useEffect9 } from "react";
4776
4874
  import { Outlet } from "react-router-dom";
4777
4875
  import {
4778
- Box as Box14,
4876
+ Box as Box15,
4779
4877
  AppBar,
4780
4878
  Toolbar,
4781
- Typography as Typography12,
4782
- Button as Button8,
4879
+ Typography as Typography13,
4880
+ Button as Button9,
4783
4881
  Drawer,
4784
4882
  CssBaseline,
4785
4883
  IconButton as IconButton6,
@@ -4788,10 +4886,10 @@ import {
4788
4886
  } from "@mui/material";
4789
4887
 
4790
4888
  // src/contexts/AppContext.tsx
4791
- import { createContext as createContext4, useContext as useContext5, useState as useState16, useEffect as useEffect7, useCallback as useCallback12, useMemo as useMemo11, useRef as useRef8 } from "react";
4889
+ import { createContext as createContext4, useContext as useContext5, useState as useState17, useEffect as useEffect7, useCallback as useCallback13, useMemo as useMemo11, useRef as useRef8 } from "react";
4792
4890
  import { useLocation, useNavigate } from "react-router-dom";
4793
4891
  import { useSelector as useSelector2, useDispatch as useDispatch2 } from "react-redux";
4794
- import { jsx as jsx22 } from "react/jsx-runtime";
4892
+ import { jsx as jsx24 } from "react/jsx-runtime";
4795
4893
  var AuthContext = createContext4(void 0);
4796
4894
  var useApp = () => {
4797
4895
  const context = useContext5(AuthContext);
@@ -4803,15 +4901,15 @@ var useApp = () => {
4803
4901
  };
4804
4902
  var AppProvider = ({ children, publicPaths = [] }) => {
4805
4903
  console.log("AppProvider rendered/re-rendered");
4806
- const [isLoggedIn, setIsLoggedIn] = useState16(false);
4807
- const [showSessionExpiredMessage, setShowSessionExpiredMessage] = useState16(false);
4904
+ const [isLoggedIn, setIsLoggedIn] = useState17(false);
4905
+ const [showSessionExpiredMessage, setShowSessionExpiredMessage] = useState17(false);
4808
4906
  const isRedirectingRef = useRef8(false);
4809
4907
  const huboSesionRef = useRef8(false);
4810
4908
  const dispatch = useDispatch2();
4811
4909
  const clientContext = useSelector2((state) => state.clientContext);
4812
4910
  if (clientContext.status === "succeeded") huboSesionRef.current = true;
4813
4911
  const navigate = useNavigate();
4814
- const handleExpiredSessionRedirect = useCallback12(() => {
4912
+ const handleExpiredSessionRedirect = useCallback13(() => {
4815
4913
  isRedirectingRef.current = true;
4816
4914
  setShowSessionExpiredMessage(false);
4817
4915
  setIsLoggedIn(false);
@@ -4821,11 +4919,11 @@ var AppProvider = ({ children, publicPaths = [] }) => {
4821
4919
  }, 2e3);
4822
4920
  }, [navigate]);
4823
4921
  const location = useLocation();
4824
- const isCurrentPathPublic = useCallback12(() => {
4922
+ const isCurrentPathPublic = useCallback13(() => {
4825
4923
  const current = location.pathname;
4826
4924
  return publicPaths.some((path) => current === path || current.startsWith(`${path}/`));
4827
4925
  }, [location.pathname, publicPaths]);
4828
- const checkSession = useCallback12(async () => {
4926
+ const checkSession = useCallback13(async () => {
4829
4927
  if (isRedirectingRef.current) return;
4830
4928
  try {
4831
4929
  const response = await fetchApi("/keep-alive.json", { method: "GET" });
@@ -4885,7 +4983,7 @@ var AppProvider = ({ children, publicPaths = [] }) => {
4885
4983
  setShowSessionExpiredMessage,
4886
4984
  handleExpiredSessionRedirect
4887
4985
  ]);
4888
- return /* @__PURE__ */ jsx22(AuthContext.Provider, { value: authContextValue, children });
4986
+ return /* @__PURE__ */ jsx24(AuthContext.Provider, { value: authContextValue, children });
4889
4987
  };
4890
4988
 
4891
4989
  // src/components/MainLayout.tsx
@@ -4894,8 +4992,8 @@ import MenuIcon from "@mui/icons-material/Menu";
4894
4992
  import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
4895
4993
 
4896
4994
  // src/components/SideMenu.tsx
4897
- import React18, { useEffect as useEffect8 } from "react";
4898
- import { List as List3, ListItem, ListItemButton as ListItemButton3, ListItemIcon as ListItemIcon2, ListItemText as ListItemText2, Divider as Divider2, Box as Box13, Typography as Typography11, Collapse } from "@mui/material";
4995
+ import React19, { useEffect as useEffect8 } from "react";
4996
+ import { List as List4, ListItem, ListItemButton as ListItemButton4, ListItemIcon as ListItemIcon2, ListItemText as ListItemText3, Divider as Divider2, Box as Box14, Typography as Typography12, Collapse } from "@mui/material";
4899
4997
  import ExpandLess from "@mui/icons-material/ExpandLess";
4900
4998
  import ExpandMore from "@mui/icons-material/ExpandMore";
4901
4999
  import TableChartIcon from "@mui/icons-material/TableChart";
@@ -4909,12 +5007,43 @@ import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-
4909
5007
  import { blue, orange, teal, red, grey } from "@mui/material/colors";
4910
5008
 
4911
5009
  // src/utils/menuInicial.ts
4912
- function rutaDeItemDeMenu(item) {
5010
+ function rutaDeTablaDeMenu(camino) {
5011
+ return `/menu/${camino.map(encodeURIComponent).join("/")}`;
5012
+ }
5013
+ function gruposDeItem(menu, item) {
5014
+ for (const candidato of menu) {
5015
+ if (candidato === item) return [];
5016
+ if (candidato.menuType === "menu") {
5017
+ const grupos = gruposDeItem(candidato.menuContent, item);
5018
+ if (grupos) return [candidato.name, ...grupos];
5019
+ }
5020
+ }
5021
+ return void 0;
5022
+ }
5023
+ function itemDeCamino(menu, camino) {
5024
+ const [nombre, ...resto] = camino;
5025
+ const item = menu.find((candidato) => candidato.name === nombre && candidato.menuType === (resto.length ? "menu" : "table"));
5026
+ return item && resto.length ? itemDeCamino(item.menuContent, resto) : item;
5027
+ }
5028
+ function primeraTablaConNombre(menu, nombre) {
5029
+ for (const item of menu) {
5030
+ if (item.menuType === "table" && item.name === nombre) return item;
5031
+ const encontrado = item.menuType === "menu" ? primeraTablaConNombre(item.menuContent, nombre) : void 0;
5032
+ if (encontrado) return encontrado;
5033
+ }
5034
+ return void 0;
5035
+ }
5036
+ function itemDeRuta(menu, camino) {
5037
+ if (camino.length === 0) return void 0;
5038
+ const item = itemDeCamino(menu, camino) ?? primeraTablaConNombre(menu, camino[camino.length - 1]);
5039
+ return item;
5040
+ }
5041
+ function rutaDeItemDeMenu(item, grupos = []) {
4913
5042
  if (item.menuType === "table") {
4914
5043
  const consulta = new URLSearchParams();
4915
5044
  if (item.td) consulta.append("td", JSON.stringify(item.td));
4916
5045
  if (item.fc) consulta.append("fc", JSON.stringify(item.fc));
4917
- return `/menu/${item.name}${consulta.size ? `?${consulta.toString()}` : ""}`;
5046
+ return `${rutaDeTablaDeMenu([...grupos, item.name])}${consulta.size ? `?${consulta.toString()}` : ""}`;
4918
5047
  }
4919
5048
  if (item.menuType === "proc") return `/procedures/${item.name}`;
4920
5049
  if (wScreens[item.menuType] !== void 0) return `/wScreens/${item.menuType}`;
@@ -4928,8 +5057,8 @@ function itemInicial(menu) {
4928
5057
  }
4929
5058
 
4930
5059
  // src/components/SideMenu.tsx
4931
- import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
4932
- var MenuListItem = ({ item, level, onMenuItemClick }) => {
5060
+ import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
5061
+ var MenuListItem = ({ item, level, grupos = [], onMenuItemClick }) => {
4933
5062
  const navigate = useNavigate2();
4934
5063
  const location = useLocation2();
4935
5064
  const open = useSubMenuOpenState(item.name);
@@ -4938,7 +5067,7 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
4938
5067
  if (item.menuType === "menu") {
4939
5068
  dispatch(toggleSubMenu(item.name));
4940
5069
  } else {
4941
- navigate(rutaDeItemDeMenu(item));
5070
+ navigate(rutaDeItemDeMenu(item, grupos));
4942
5071
  if (onMenuItemClick) {
4943
5072
  onMenuItemClick();
4944
5073
  }
@@ -4947,17 +5076,17 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
4947
5076
  const getIcon = (item2) => {
4948
5077
  switch (item2.menuType) {
4949
5078
  case "table":
4950
- return /* @__PURE__ */ jsx23(TableChartIcon, { sx: { color: blue[700] } });
5079
+ return /* @__PURE__ */ jsx25(TableChartIcon, { sx: { color: blue[700] } });
4951
5080
  case "proc":
4952
- return /* @__PURE__ */ jsx23(DnsIcon, { sx: { color: teal[700] } });
5081
+ return /* @__PURE__ */ jsx25(DnsIcon, { sx: { color: teal[700] } });
4953
5082
  case "menu":
4954
- return /* @__PURE__ */ jsx23(FolderIcon, { sx: { color: orange[800] } });
5083
+ return /* @__PURE__ */ jsx25(FolderIcon, { sx: { color: orange[800] } });
4955
5084
  default:
4956
5085
  const WScreenComponent = wScreens[item2.menuType];
4957
5086
  if (WScreenComponent !== void 0) {
4958
- return /* @__PURE__ */ jsx23(DesktopWindowsIcon, { sx: { color: grey[700] } });
5087
+ return /* @__PURE__ */ jsx25(DesktopWindowsIcon, { sx: { color: grey[700] } });
4959
5088
  }
4960
- return /* @__PURE__ */ jsx23(WarningAmberIcon3, { sx: { color: red[500] } });
5089
+ return /* @__PURE__ */ jsx25(WarningAmberIcon3, { sx: { color: red[500] } });
4961
5090
  }
4962
5091
  };
4963
5092
  const currentPath = location.pathname;
@@ -4965,37 +5094,38 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
4965
5094
  const pathParts = currentPath.split("/");
4966
5095
  const urlTableName = pathParts[1] === "table" ? pathParts[2] : null;
4967
5096
  if (item.menuType === "table") {
4968
- isSelected = currentPath === `/menu/${item.name}` || urlTableName === (item.table || item.name);
5097
+ isSelected = currentPath === rutaDeTablaDeMenu([...grupos, item.name]) || urlTableName === (item.table || item.name);
4969
5098
  } else if (item.menuType === "proc") {
4970
5099
  isSelected = currentPath === `/procedures/${item.name}`;
4971
5100
  } else if (item.menuType !== "menu") {
4972
5101
  isSelected = currentPath.startsWith(`/wScreens/${item.menuType}`) || currentPath.startsWith(`/wScreens-fallback/${item.menuType}`);
4973
5102
  }
4974
- const itemRef = React18.useRef(null);
5103
+ const itemRef = React19.useRef(null);
4975
5104
  useEffect8(() => {
4976
5105
  if (isSelected && itemRef.current) {
4977
5106
  itemRef.current.scrollIntoView({ behavior: "smooth", block: "nearest" });
4978
5107
  }
4979
5108
  }, [isSelected]);
4980
- return /* @__PURE__ */ jsxs18("div", { ref: itemRef, children: [
4981
- /* @__PURE__ */ jsxs18(
4982
- ListItemButton3,
5109
+ return /* @__PURE__ */ jsxs19("div", { ref: itemRef, children: [
5110
+ /* @__PURE__ */ jsxs19(
5111
+ ListItemButton4,
4983
5112
  {
4984
5113
  onClick: handleClick,
4985
5114
  sx: { pl: level * 2 },
4986
5115
  selected: isSelected,
4987
5116
  children: [
4988
- /* @__PURE__ */ jsx23(ListItemIcon2, { sx: { minWidth: "38px" }, children: getIcon(item) }),
4989
- /* @__PURE__ */ jsx23(ListItemText2, { primary: item.label || item.name }),
4990
- item.menuType === "menu" ? open ? /* @__PURE__ */ jsx23(ExpandLess, {}) : /* @__PURE__ */ jsx23(ExpandMore, {}) : null
5117
+ /* @__PURE__ */ jsx25(ListItemIcon2, { sx: { minWidth: "38px" }, children: getIcon(item) }),
5118
+ /* @__PURE__ */ jsx25(ListItemText3, { primary: item.label || item.name }),
5119
+ item.menuType === "menu" ? open ? /* @__PURE__ */ jsx25(ExpandLess, {}) : /* @__PURE__ */ jsx25(ExpandMore, {}) : null
4991
5120
  ]
4992
5121
  }
4993
5122
  ),
4994
- item.menuType === "menu" && /* @__PURE__ */ jsx23(Collapse, { in: open, timeout: "auto", unmountOnExit: true, children: /* @__PURE__ */ jsx23(List3, { component: "div", disablePadding: true, children: item.menuContent.map((subItem) => /* @__PURE__ */ jsx23(
5123
+ item.menuType === "menu" && /* @__PURE__ */ jsx25(Collapse, { in: open, timeout: "auto", unmountOnExit: true, children: /* @__PURE__ */ jsx25(List4, { component: "div", disablePadding: true, children: item.menuContent.map((subItem) => /* @__PURE__ */ jsx25(
4995
5124
  MenuListItem,
4996
5125
  {
4997
5126
  item: subItem,
4998
5127
  level: level + 1,
5128
+ grupos: [...grupos, item.name],
4999
5129
  onMenuItemClick
5000
5130
  },
5001
5131
  subItem.name
@@ -5015,7 +5145,7 @@ var SideMenu = ({ onMenuItemClick }) => {
5015
5145
  dispatch(setAllSubMenusOpen(!isMostlyOpen));
5016
5146
  };
5017
5147
  if (!clientContext || !clientContext.menu) {
5018
- return /* @__PURE__ */ jsx23(Box13, { sx: { p: 2, textAlign: "center" }, children: /* @__PURE__ */ jsx23(Typography11, { variant: "body2", color: "text.secondary", children: "Cargando men\xFA..." }) });
5148
+ return /* @__PURE__ */ jsx25(Box14, { sx: { p: 2, textAlign: "center" }, children: /* @__PURE__ */ jsx25(Typography12, { variant: "body2", color: "text.secondary", children: "Cargando men\xFA..." }) });
5019
5149
  }
5020
5150
  useEffect8(() => {
5021
5151
  if (!clientContext?.menu) return;
@@ -5025,7 +5155,7 @@ var SideMenu = ({ onMenuItemClick }) => {
5025
5155
  for (const item of items) {
5026
5156
  let matches = false;
5027
5157
  if (item.menuType === "table") {
5028
- matches = targetPath === `/menu/${item.name}` || urlTableName === (item.table || item.name);
5158
+ matches = targetPath === rutaDeTablaDeMenu([...parentNames, item.name]) || urlTableName === (item.table || item.name);
5029
5159
  } else if (item.menuType === "proc") {
5030
5160
  matches = targetPath === `/procedures/${item.name}`;
5031
5161
  } else if (item.menuType !== "menu") {
@@ -5046,13 +5176,13 @@ var SideMenu = ({ onMenuItemClick }) => {
5046
5176
  };
5047
5177
  expandParents(clientContext.menu, location.pathname);
5048
5178
  }, [location.pathname, clientContext, dispatch]);
5049
- return /* @__PURE__ */ jsxs18(Box13, { sx: { width: "100%", flexShrink: 0 }, children: [
5050
- clientContext.menu.some((item) => item.menuType === "menu") && /* @__PURE__ */ jsx23(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsxs18(ListItemButton3, { onClick: handleToggleAllSubMenus, children: [
5051
- /* @__PURE__ */ jsx23(ListItemIcon2, { sx: { minWidth: "38px" }, children: isMostlyOpen ? /* @__PURE__ */ jsx23(UnfoldLessIcon, {}) : /* @__PURE__ */ jsx23(UnfoldMoreIcon, {}) }),
5052
- /* @__PURE__ */ jsx23(ListItemText2, { primary: isMostlyOpen ? "colapsar " : "expandir" })
5179
+ return /* @__PURE__ */ jsxs19(Box14, { sx: { width: "100%", flexShrink: 0 }, children: [
5180
+ clientContext.menu.some((item) => item.menuType === "menu") && /* @__PURE__ */ jsx25(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsxs19(ListItemButton4, { onClick: handleToggleAllSubMenus, children: [
5181
+ /* @__PURE__ */ jsx25(ListItemIcon2, { sx: { minWidth: "38px" }, children: isMostlyOpen ? /* @__PURE__ */ jsx25(UnfoldLessIcon, {}) : /* @__PURE__ */ jsx25(UnfoldMoreIcon, {}) }),
5182
+ /* @__PURE__ */ jsx25(ListItemText3, { primary: isMostlyOpen ? "colapsar " : "expandir" })
5053
5183
  ] }) }),
5054
- /* @__PURE__ */ jsx23(Divider2, {}),
5055
- /* @__PURE__ */ jsx23(List3, { children: clientContext.menu.map((menuItem) => /* @__PURE__ */ jsx23(
5184
+ /* @__PURE__ */ jsx25(Divider2, {}),
5185
+ /* @__PURE__ */ jsx25(List4, { children: clientContext.menu.map((menuItem) => /* @__PURE__ */ jsx25(
5056
5186
  MenuListItem,
5057
5187
  {
5058
5188
  item: menuItem,
@@ -5066,14 +5196,14 @@ var SideMenu = ({ onMenuItemClick }) => {
5066
5196
  var SideMenu_default = SideMenu;
5067
5197
 
5068
5198
  // src/hooks/useLogout.tsx
5069
- import { useCallback as useCallback13 } from "react";
5199
+ import { useCallback as useCallback14 } from "react";
5070
5200
  import { useNavigate as useNavigate3 } from "react-router-dom";
5071
5201
  import { useDispatch as useDispatch3 } from "react-redux";
5072
5202
  var useLogout = () => {
5073
5203
  const { setIsLoggedIn } = useApp();
5074
5204
  const dispatch = useDispatch3();
5075
5205
  const navigate = useNavigate3();
5076
- const logout = useCallback13(async () => {
5206
+ const logout = useCallback14(async () => {
5077
5207
  try {
5078
5208
  const response = await fetchApi("/logout", { method: "GET" });
5079
5209
  if (response.status === 401 || response.ok) {
@@ -5094,7 +5224,7 @@ var useLogout = () => {
5094
5224
  var useLogout_default = useLogout;
5095
5225
 
5096
5226
  // src/components/MainLayout.tsx
5097
- import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
5227
+ import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
5098
5228
  var drawerWidth = 240;
5099
5229
  var MainLayout = () => {
5100
5230
  const { clientContext } = useApp();
@@ -5117,11 +5247,11 @@ var MainLayout = () => {
5117
5247
  }
5118
5248
  };
5119
5249
  if (!clientContext) {
5120
- return /* @__PURE__ */ jsx24(Box14, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx24(Typography12, { children: "Cargando dise\xF1o de la aplicaci\xF3n..." }) });
5250
+ return /* @__PURE__ */ jsx26(Box15, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx26(Typography13, { children: "Cargando dise\xF1o de la aplicaci\xF3n..." }) });
5121
5251
  }
5122
- return /* @__PURE__ */ jsxs19(Box14, { sx: { display: "flex", height: "100vh" }, children: [
5123
- /* @__PURE__ */ jsx24(CssBaseline, {}),
5124
- /* @__PURE__ */ jsx24(
5252
+ return /* @__PURE__ */ jsxs20(Box15, { sx: { display: "flex", height: "100vh" }, children: [
5253
+ /* @__PURE__ */ jsx26(CssBaseline, {}),
5254
+ /* @__PURE__ */ jsx26(
5125
5255
  AppBar,
5126
5256
  {
5127
5257
  position: "fixed",
@@ -5140,8 +5270,8 @@ var MainLayout = () => {
5140
5270
  })
5141
5271
  }
5142
5272
  },
5143
- children: /* @__PURE__ */ jsxs19(Toolbar, { children: [
5144
- /* @__PURE__ */ jsx24(
5273
+ children: /* @__PURE__ */ jsxs20(Toolbar, { children: [
5274
+ /* @__PURE__ */ jsx26(
5145
5275
  IconButton6,
5146
5276
  {
5147
5277
  color: "inherit",
@@ -5151,10 +5281,10 @@ var MainLayout = () => {
5151
5281
  sx: {
5152
5282
  marginRight: 2
5153
5283
  },
5154
- children: isDrawerOpen ? /* @__PURE__ */ jsx24(ChevronLeftIcon, {}) : /* @__PURE__ */ jsx24(MenuIcon, {})
5284
+ children: isDrawerOpen ? /* @__PURE__ */ jsx26(ChevronLeftIcon, {}) : /* @__PURE__ */ jsx26(MenuIcon, {})
5155
5285
  }
5156
5286
  ),
5157
- !isDrawerOpen && /* @__PURE__ */ jsx24(
5287
+ !isDrawerOpen && /* @__PURE__ */ jsx26(
5158
5288
  "img",
5159
5289
  {
5160
5290
  src: `${envConfig.backendUrl}/img/logo-128.png`,
@@ -5162,21 +5292,21 @@ var MainLayout = () => {
5162
5292
  style: { height: "32px", marginRight: "12px", objectFit: "contain" }
5163
5293
  }
5164
5294
  ),
5165
- /* @__PURE__ */ jsx24(Typography12, { variant: "h6", noWrap: true, component: "div", sx: { flexGrow: 1 }, children: isDrawerOpen ? "" : clientContext.config.title }),
5166
- /* @__PURE__ */ jsx24(Typography12, { variant: "subtitle1", component: "div", sx: { mr: 2 }, children: clientContext.username }),
5167
- /* @__PURE__ */ jsx24(
5168
- Button8,
5295
+ /* @__PURE__ */ jsx26(Typography13, { variant: "h6", noWrap: true, component: "div", sx: { flexGrow: 1 }, children: isDrawerOpen ? "" : clientContext.config.title }),
5296
+ /* @__PURE__ */ jsx26(Typography13, { variant: "subtitle1", component: "div", sx: { mr: 2 }, children: clientContext.username }),
5297
+ /* @__PURE__ */ jsx26(
5298
+ Button9,
5169
5299
  {
5170
5300
  color: "inherit",
5171
5301
  onClick: logout,
5172
- startIcon: /* @__PURE__ */ jsx24(LogoutIcon, {}),
5302
+ startIcon: /* @__PURE__ */ jsx26(LogoutIcon, {}),
5173
5303
  children: "Salir"
5174
5304
  }
5175
5305
  )
5176
5306
  ] })
5177
5307
  }
5178
5308
  ),
5179
- /* @__PURE__ */ jsxs19(
5309
+ /* @__PURE__ */ jsxs20(
5180
5310
  Drawer,
5181
5311
  {
5182
5312
  variant: "persistent",
@@ -5193,7 +5323,7 @@ var MainLayout = () => {
5193
5323
  }
5194
5324
  },
5195
5325
  children: [
5196
- /* @__PURE__ */ jsxs19(
5326
+ /* @__PURE__ */ jsxs20(
5197
5327
  Toolbar,
5198
5328
  {
5199
5329
  sx: {
@@ -5206,7 +5336,7 @@ var MainLayout = () => {
5206
5336
  gap: 1.5
5207
5337
  },
5208
5338
  children: [
5209
- /* @__PURE__ */ jsx24(
5339
+ /* @__PURE__ */ jsx26(
5210
5340
  "img",
5211
5341
  {
5212
5342
  src: `${envConfig.backendUrl}/img/logo-128.png`,
@@ -5214,16 +5344,16 @@ var MainLayout = () => {
5214
5344
  style: { height: "32px", objectFit: "contain" }
5215
5345
  }
5216
5346
  ),
5217
- /* @__PURE__ */ jsx24(Typography12, { variant: "h6", sx: { fontWeight: "bold" }, children: clientContext.config.title })
5347
+ /* @__PURE__ */ jsx26(Typography13, { variant: "h6", sx: { fontWeight: "bold" }, children: clientContext.config.title })
5218
5348
  ]
5219
5349
  }
5220
5350
  ),
5221
- /* @__PURE__ */ jsx24(SideMenu_default, { onMenuItemClick: handleDrawerCloseMobile })
5351
+ /* @__PURE__ */ jsx26(SideMenu_default, { onMenuItemClick: handleDrawerCloseMobile })
5222
5352
  ]
5223
5353
  }
5224
5354
  ),
5225
- /* @__PURE__ */ jsxs19(
5226
- Box14,
5355
+ /* @__PURE__ */ jsxs20(
5356
+ Box15,
5227
5357
  {
5228
5358
  component: "main",
5229
5359
  sx: {
@@ -5249,8 +5379,8 @@ var MainLayout = () => {
5249
5379
  width: isDrawerOpen ? `calc(100% - ${drawerWidth}px)` : "100%"
5250
5380
  },
5251
5381
  children: [
5252
- /* @__PURE__ */ jsx24(Toolbar, {}),
5253
- /* @__PURE__ */ jsx24(Box14, { sx: { flex: 1, minHeight: 0, overflowY: "auto", display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsx24(Outlet, {}) })
5382
+ /* @__PURE__ */ jsx26(Toolbar, {}),
5383
+ /* @__PURE__ */ jsx26(Box15, { sx: { flex: 1, minHeight: 0, overflowY: "auto", display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsx26(Outlet, {}) })
5254
5384
  ]
5255
5385
  }
5256
5386
  )
@@ -5259,8 +5389,8 @@ var MainLayout = () => {
5259
5389
  var MainLayout_default = MainLayout;
5260
5390
 
5261
5391
  // src/components/SessionExpiredMessage.tsx
5262
- import { Box as Box15, Typography as Typography13, Button as Button9, Modal } from "@mui/material";
5263
- import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
5392
+ import { Box as Box16, Typography as Typography14, Button as Button10, Modal } from "@mui/material";
5393
+ import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
5264
5394
  var style = {
5265
5395
  position: "absolute",
5266
5396
  top: "50%",
@@ -5279,7 +5409,7 @@ var SessionExpiredMessage = () => {
5279
5409
  const handleClose = () => {
5280
5410
  handleExpiredSessionRedirect();
5281
5411
  };
5282
- return /* @__PURE__ */ jsx25(
5412
+ return /* @__PURE__ */ jsx27(
5283
5413
  Modal,
5284
5414
  {
5285
5415
  open: showSessionExpiredMessage,
@@ -5299,10 +5429,10 @@ var SessionExpiredMessage = () => {
5299
5429
  }
5300
5430
  }
5301
5431
  },
5302
- children: /* @__PURE__ */ jsxs20(Box15, { sx: style, children: [
5303
- /* @__PURE__ */ jsx25(Typography13, { id: "session-expired-modal-title", variant: "h6", component: "h2", gutterBottom: true, children: "\xA1Sesi\xF3n Expirada!" }),
5304
- /* @__PURE__ */ jsx25(Typography13, { id: "session-expired-modal-description", sx: { mt: 2, mb: 3 }, children: "Tu sesi\xF3n ha expirado por inactividad o por seguridad. Por favor, inicia sesi\xF3n de nuevo." }),
5305
- /* @__PURE__ */ jsx25(Button9, { variant: "contained", color: "primary", onClick: handleClose, children: "Ir al Login" })
5432
+ children: /* @__PURE__ */ jsxs21(Box16, { sx: style, children: [
5433
+ /* @__PURE__ */ jsx27(Typography14, { id: "session-expired-modal-title", variant: "h6", component: "h2", gutterBottom: true, children: "\xA1Sesi\xF3n Expirada!" }),
5434
+ /* @__PURE__ */ jsx27(Typography14, { id: "session-expired-modal-description", sx: { mt: 2, mb: 3 }, children: "Tu sesi\xF3n ha expirado por inactividad o por seguridad. Por favor, inicia sesi\xF3n de nuevo." }),
5435
+ /* @__PURE__ */ jsx27(Button10, { variant: "contained", color: "primary", onClick: handleClose, children: "Ir al Login" })
5306
5436
  ] })
5307
5437
  }
5308
5438
  );
@@ -5311,24 +5441,24 @@ var SessionExpiredMessage_default = SessionExpiredMessage;
5311
5441
 
5312
5442
  // src/pages/PantallaInicial.tsx
5313
5443
  import { Navigate } from "react-router-dom";
5314
- import { jsx as jsx26 } from "react/jsx-runtime";
5444
+ import { jsx as jsx28 } from "react/jsx-runtime";
5315
5445
  var PantallaInicial = () => {
5316
5446
  const { clientContext } = useApp();
5317
5447
  const item = clientContext.menu ? itemInicial(clientContext.menu) : void 0;
5318
- return item ? /* @__PURE__ */ jsx26(Navigate, { to: rutaDeItemDeMenu(item), replace: true }) : null;
5448
+ return item && clientContext.menu ? /* @__PURE__ */ jsx28(Navigate, { to: rutaDeItemDeMenu(item, gruposDeItem(clientContext.menu, item)), replace: true }) : null;
5319
5449
  };
5320
5450
  var PantallaInicial_default = PantallaInicial;
5321
5451
 
5322
5452
  // src/pages/LogoutPage.tsx
5323
5453
  import { useEffect as useEffect10 } from "react";
5324
- import { Box as Box16, Typography as Typography14, CircularProgress as CircularProgress5 } from "@mui/material";
5325
- import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
5454
+ import { Box as Box17, Typography as Typography15, CircularProgress as CircularProgress5 } from "@mui/material";
5455
+ import { jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
5326
5456
  var LogoutPage = () => {
5327
5457
  const logout = useLogout_default();
5328
5458
  useEffect10(() => {
5329
5459
  logout();
5330
5460
  }, [logout]);
5331
- return /* @__PURE__ */ jsxs21(Box16, { sx: {
5461
+ return /* @__PURE__ */ jsxs22(Box17, { sx: {
5332
5462
  display: "flex",
5333
5463
  flexDirection: "column",
5334
5464
  justifyContent: "center",
@@ -5336,20 +5466,20 @@ var LogoutPage = () => {
5336
5466
  height: "100vh",
5337
5467
  textAlign: "center"
5338
5468
  }, children: [
5339
- /* @__PURE__ */ jsx27(CircularProgress5, { size: 60 }),
5340
- /* @__PURE__ */ jsx27(Typography14, { variant: "h6", sx: { mt: 2 }, children: "Cerrando sesi\xF3n..." })
5469
+ /* @__PURE__ */ jsx29(CircularProgress5, { size: 60 }),
5470
+ /* @__PURE__ */ jsx29(Typography15, { variant: "h6", sx: { mt: 2 }, children: "Cerrando sesi\xF3n..." })
5341
5471
  ] });
5342
5472
  };
5343
5473
  var LogoutPage_default = LogoutPage;
5344
5474
 
5345
5475
  // src/pages/LoginPage.tsx
5346
- import { useState as useState17 } from "react";
5347
- import { Button as Button10, TextField as TextField2, Typography as Typography15, Alert as Alert3, AlertTitle, Box as Box17, CircularProgress as CircularProgress6 } from "@mui/material";
5476
+ import { useState as useState18 } from "react";
5477
+ import { Button as Button11, TextField as TextField2, Typography as Typography16, Alert as Alert3, AlertTitle, Box as Box18, CircularProgress as CircularProgress6 } from "@mui/material";
5348
5478
  import { useForm, Controller } from "react-hook-form";
5349
5479
  import { zodResolver } from "@hookform/resolvers/zod";
5350
5480
  import * as z from "zod";
5351
5481
  import { useDispatch as useDispatch4 } from "react-redux";
5352
- import { Fragment as Fragment4, jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
5482
+ import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
5353
5483
  var loginSchema = z.object({
5354
5484
  username: z.string().min(1, "El usuario es requerido"),
5355
5485
  // Añadir validación básica
@@ -5357,8 +5487,8 @@ var loginSchema = z.object({
5357
5487
  // Añadir validación básica
5358
5488
  });
5359
5489
  var LoginPage = () => {
5360
- const [loginError, setLoginError] = useState17(null);
5361
- const [isSubmitting, setIsSubmitting] = useState17(false);
5490
+ const [loginError, setLoginError] = useState18(null);
5491
+ const [isSubmitting, setIsSubmitting] = useState18(false);
5362
5492
  const { setIsLoggedIn, checkSession } = useApp();
5363
5493
  const dispatch = useDispatch4();
5364
5494
  const {
@@ -5403,16 +5533,16 @@ var LoginPage = () => {
5403
5533
  setIsSubmitting(false);
5404
5534
  }
5405
5535
  };
5406
- return /* @__PURE__ */ jsx28(
5407
- Box17,
5536
+ return /* @__PURE__ */ jsx30(
5537
+ Box18,
5408
5538
  {
5409
5539
  display: "flex",
5410
5540
  alignItems: "center",
5411
5541
  justifyContent: "center",
5412
5542
  minHeight: "100vh",
5413
5543
  bgcolor: "#f5f5f5",
5414
- children: /* @__PURE__ */ jsxs22(
5415
- Box17,
5544
+ children: /* @__PURE__ */ jsxs23(
5545
+ Box18,
5416
5546
  {
5417
5547
  width: "100%",
5418
5548
  maxWidth: "400px",
@@ -5421,7 +5551,7 @@ var LoginPage = () => {
5421
5551
  borderRadius: 8,
5422
5552
  boxShadow: 3,
5423
5553
  children: [
5424
- /* @__PURE__ */ jsx28(Box17, { sx: { display: "flex", justifyContent: "center", mb: 3 }, children: /* @__PURE__ */ jsx28(
5554
+ /* @__PURE__ */ jsx30(Box18, { sx: { display: "flex", justifyContent: "center", mb: 3 }, children: /* @__PURE__ */ jsx30(
5425
5555
  "img",
5426
5556
  {
5427
5557
  src: `${envConfig.backendUrl}/img/login-logo-icon.png`,
@@ -5429,16 +5559,16 @@ var LoginPage = () => {
5429
5559
  style: { height: "192px", maxWidth: "100%", objectFit: "contain" }
5430
5560
  }
5431
5561
  ) }),
5432
- /* @__PURE__ */ jsx28(Typography15, { variant: "h5", align: "center", gutterBottom: true, sx: { fontWeight: "bold", color: "primary.main" }, children: "Iniciar Sesi\xF3n" }),
5433
- /* @__PURE__ */ jsxs22("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-4", children: [
5434
- /* @__PURE__ */ jsxs22("div", { children: [
5435
- /* @__PURE__ */ jsx28("label", { htmlFor: "username", children: /* @__PURE__ */ jsx28(Typography15, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Usuario" }) }),
5436
- /* @__PURE__ */ jsx28(
5562
+ /* @__PURE__ */ jsx30(Typography16, { variant: "h5", align: "center", gutterBottom: true, sx: { fontWeight: "bold", color: "primary.main" }, children: "Iniciar Sesi\xF3n" }),
5563
+ /* @__PURE__ */ jsxs23("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-4", children: [
5564
+ /* @__PURE__ */ jsxs23("div", { children: [
5565
+ /* @__PURE__ */ jsx30("label", { htmlFor: "username", children: /* @__PURE__ */ jsx30(Typography16, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Usuario" }) }),
5566
+ /* @__PURE__ */ jsx30(
5437
5567
  Controller,
5438
5568
  {
5439
5569
  name: "username",
5440
5570
  control,
5441
- render: ({ field }) => /* @__PURE__ */ jsx28(
5571
+ render: ({ field }) => /* @__PURE__ */ jsx30(
5442
5572
  TextField2,
5443
5573
  {
5444
5574
  ...field,
@@ -5454,14 +5584,14 @@ var LoginPage = () => {
5454
5584
  }
5455
5585
  )
5456
5586
  ] }),
5457
- /* @__PURE__ */ jsxs22("div", { children: [
5458
- /* @__PURE__ */ jsx28("label", { htmlFor: "password", children: /* @__PURE__ */ jsx28(Typography15, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Contrase\xF1a" }) }),
5459
- /* @__PURE__ */ jsx28(
5587
+ /* @__PURE__ */ jsxs23("div", { children: [
5588
+ /* @__PURE__ */ jsx30("label", { htmlFor: "password", children: /* @__PURE__ */ jsx30(Typography16, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Contrase\xF1a" }) }),
5589
+ /* @__PURE__ */ jsx30(
5460
5590
  Controller,
5461
5591
  {
5462
5592
  name: "password",
5463
5593
  control,
5464
- render: ({ field }) => /* @__PURE__ */ jsx28(
5594
+ render: ({ field }) => /* @__PURE__ */ jsx30(
5465
5595
  TextField2,
5466
5596
  {
5467
5597
  ...field,
@@ -5477,14 +5607,14 @@ var LoginPage = () => {
5477
5607
  }
5478
5608
  )
5479
5609
  ] }),
5480
- /* @__PURE__ */ jsx28(Button10, { type: "submit", fullWidth: true, variant: "contained", color: "primary", disabled: isSubmitting, sx: { mt: 2 }, children: isSubmitting ? /* @__PURE__ */ jsxs22(Fragment4, { children: [
5481
- /* @__PURE__ */ jsx28(CircularProgress6, { size: 20, sx: { mr: 1 } }),
5610
+ /* @__PURE__ */ jsx30(Button11, { type: "submit", fullWidth: true, variant: "contained", color: "primary", disabled: isSubmitting, sx: { mt: 2 }, children: isSubmitting ? /* @__PURE__ */ jsxs23(Fragment5, { children: [
5611
+ /* @__PURE__ */ jsx30(CircularProgress6, { size: 20, sx: { mr: 1 } }),
5482
5612
  "Iniciando sesi\xF3n..."
5483
5613
  ] }) : "Iniciar Sesi\xF3n" })
5484
5614
  ] }),
5485
- loginError && /* @__PURE__ */ jsxs22(Alert3, { severity: "error", sx: { mt: 2, maxHeight: "200px" }, children: [
5615
+ loginError && /* @__PURE__ */ jsxs23(Alert3, { severity: "error", sx: { mt: 2, maxHeight: "200px" }, children: [
5486
5616
  " ",
5487
- /* @__PURE__ */ jsx28(AlertTitle, { children: "Error" }),
5617
+ /* @__PURE__ */ jsx30(AlertTitle, { children: "Error" }),
5488
5618
  loginError
5489
5619
  ] })
5490
5620
  ]
@@ -5496,11 +5626,11 @@ var LoginPage = () => {
5496
5626
  var LoginPage_default = LoginPage;
5497
5627
 
5498
5628
  // src/components/ProcedureForm.tsx
5499
- import React22, { useState as useState18, useCallback as useCallback14, useMemo as useMemo12 } from "react";
5629
+ import React23, { useState as useState19, useCallback as useCallback15, useMemo as useMemo12 } from "react";
5500
5630
  import { useParams } from "react-router-dom";
5501
5631
  import {
5502
5632
  TextField as TextField3,
5503
- Button as Button11,
5633
+ Button as Button12,
5504
5634
  FormControl as FormControl3,
5505
5635
  InputLabel as InputLabel2,
5506
5636
  Select as Select2,
@@ -5508,8 +5638,8 @@ import {
5508
5638
  Checkbox as Checkbox3,
5509
5639
  FormControlLabel as FormControlLabel3,
5510
5640
  FormHelperText as FormHelperText2,
5511
- Typography as Typography17,
5512
- Box as Box19,
5641
+ Typography as Typography18,
5642
+ Box as Box20,
5513
5643
  CircularProgress as CircularProgress7,
5514
5644
  Alert as Alert4,
5515
5645
  Divider as Divider3,
@@ -5517,14 +5647,14 @@ import {
5517
5647
  } from "@mui/material";
5518
5648
 
5519
5649
  // src/pages/procedure-results/SuccessDisplay.tsx
5520
- import { Box as Box18, Typography as Typography16, Paper as Paper3 } from "@mui/material";
5521
- import { jsx as jsx29, jsxs as jsxs23 } from "react/jsx-runtime";
5650
+ import { Box as Box19, Typography as Typography17, Paper as Paper3 } from "@mui/material";
5651
+ import { jsx as jsx31, jsxs as jsxs24 } from "react/jsx-runtime";
5522
5652
  var SuccessDisplay = ({ data }) => {
5523
- return /* @__PURE__ */ jsxs23(Paper3, { elevation: 2, sx: { p: 2, mt: 2, bgcolor: "success.light", color: "success.contrastText" }, children: [
5524
- /* @__PURE__ */ jsx29(Typography16, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: "\xA1Operaci\xF3n Exitosa!" }),
5525
- /* @__PURE__ */ jsx29(Typography16, { variant: "body2", sx: { fontSize: "0.85rem" }, children: "Detalles del resultado:" }),
5526
- /* @__PURE__ */ jsx29(Box18, { sx: { bgcolor: "success.dark", p: 1, borderRadius: 1, mt: 1, overflowX: "auto" }, children: /* @__PURE__ */ jsx29("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(data, null, 2) }) }),
5527
- /* @__PURE__ */ jsx29(Typography16, { variant: "body2", sx: { fontSize: "0.8rem", mt: 1 }, children: "Puedes revisar los detalles anteriores o cerrar este mensaje." })
5653
+ return /* @__PURE__ */ jsxs24(Paper3, { elevation: 2, sx: { p: 2, mt: 2, bgcolor: "success.light", color: "success.contrastText" }, children: [
5654
+ /* @__PURE__ */ jsx31(Typography17, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: "\xA1Operaci\xF3n Exitosa!" }),
5655
+ /* @__PURE__ */ jsx31(Typography17, { variant: "body2", sx: { fontSize: "0.85rem" }, children: "Detalles del resultado:" }),
5656
+ /* @__PURE__ */ jsx31(Box19, { sx: { bgcolor: "success.dark", p: 1, borderRadius: 1, mt: 1, overflowX: "auto" }, children: /* @__PURE__ */ jsx31("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(data, null, 2) }) }),
5657
+ /* @__PURE__ */ jsx31(Typography17, { variant: "body2", sx: { fontSize: "0.8rem", mt: 1 }, children: "Puedes revisar los detalles anteriores o cerrar este mensaje." })
5528
5658
  ] });
5529
5659
  };
5530
5660
  var SuccessDisplay_default = SuccessDisplay;
@@ -5538,22 +5668,22 @@ var extendResultsOk = (newComponents) => {
5538
5668
  };
5539
5669
 
5540
5670
  // src/components/ProcedureForm.tsx
5541
- import { jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
5671
+ import { jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
5542
5672
  var ProcedureForm = () => {
5543
5673
  const { procedureName } = useParams();
5544
5674
  const { clientContext } = useApp();
5545
5675
  const { callApi, loading: apiLoading, error: apiError } = useApiCall();
5546
- const [validationErrors, setValidationErrors] = useState18({});
5547
- const [successMessage, setSuccessMessage] = useState18(null);
5548
- const [executionLog, setExecutionLog] = useState18([]);
5549
- const [procedureResultData, setProcedureResultData] = useState18(null);
5676
+ const [validationErrors, setValidationErrors] = useState19({});
5677
+ const [successMessage, setSuccessMessage] = useState19(null);
5678
+ const [executionLog, setExecutionLog] = useState19([]);
5679
+ const [procedureResultData, setProcedureResultData] = useState19(null);
5550
5680
  const procedure = useMemo12(() => {
5551
5681
  if (procedureName && clientContext?.procedure) {
5552
5682
  return clientContext.procedure[procedureName];
5553
5683
  }
5554
5684
  return void 0;
5555
5685
  }, [procedureName, clientContext]);
5556
- const [formValues, setFormValues] = useState18(() => {
5686
+ const [formValues, setFormValues] = useState19(() => {
5557
5687
  if (!procedure) return {};
5558
5688
  const initialValues = {};
5559
5689
  procedure.parameters.forEach((param) => {
@@ -5578,7 +5708,7 @@ var ProcedureForm = () => {
5578
5708
  });
5579
5709
  return initialValues;
5580
5710
  });
5581
- React22.useEffect(() => {
5711
+ React23.useEffect(() => {
5582
5712
  if (procedure) {
5583
5713
  setValidationErrors({});
5584
5714
  setSuccessMessage(null);
@@ -5608,11 +5738,11 @@ var ProcedureForm = () => {
5608
5738
  setExecutionLog([]);
5609
5739
  }
5610
5740
  }, [procedure]);
5611
- const addLogMessage = useCallback14((message, isError = false) => {
5741
+ const addLogMessage = useCallback15((message, isError = false) => {
5612
5742
  const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("es-AR");
5613
5743
  setExecutionLog((prev) => [...prev, `[${timestamp}] ${isError ? "ERROR: " : ""}${message}`]);
5614
5744
  }, []);
5615
- const handleChange = useCallback14((e, child) => {
5745
+ const handleChange = useCallback15((e, child) => {
5616
5746
  const { name, value } = e.target;
5617
5747
  let newValue = value;
5618
5748
  if (e.target.type === "checkbox") {
@@ -5734,7 +5864,7 @@ var ProcedureForm = () => {
5734
5864
  addLogMessage("Ejecuci\xF3n finalizada.");
5735
5865
  }
5736
5866
  };
5737
- const renderInputField = useCallback14((param) => {
5867
+ const renderInputField = useCallback15((param) => {
5738
5868
  const hasError = !!validationErrors[param.name];
5739
5869
  const errorMessage = validationErrors[param.name];
5740
5870
  const commonProps = {
@@ -5753,9 +5883,9 @@ var ProcedureForm = () => {
5753
5883
  sx: { fontSize: "0.8rem" }
5754
5884
  };
5755
5885
  if (param.options && param.options.length > 0) {
5756
- return /* @__PURE__ */ jsxs24(FormControl3, { fullWidth: true, margin: "dense", size: "small", error: hasError, required: commonProps.required, children: [
5757
- /* @__PURE__ */ jsx30(InputLabel2, { id: `${param.name}-label`, sx: { fontSize: "0.8rem" }, children: param.label || param.name }),
5758
- /* @__PURE__ */ jsxs24(
5886
+ return /* @__PURE__ */ jsxs25(FormControl3, { fullWidth: true, margin: "dense", size: "small", error: hasError, required: commonProps.required, children: [
5887
+ /* @__PURE__ */ jsx32(InputLabel2, { id: `${param.name}-label`, sx: { fontSize: "0.8rem" }, children: param.label || param.name }),
5888
+ /* @__PURE__ */ jsxs25(
5759
5889
  Select2,
5760
5890
  {
5761
5891
  labelId: `${param.name}-label`,
@@ -5766,14 +5896,14 @@ var ProcedureForm = () => {
5766
5896
  label: param.label || param.name,
5767
5897
  disabled: apiLoading,
5768
5898
  sx: { fontSize: "0.8rem" },
5769
- renderValue: (selected) => /* @__PURE__ */ jsx30(Typography17, { sx: { fontSize: "0.8rem" }, children: selected }),
5899
+ renderValue: (selected) => /* @__PURE__ */ jsx32(Typography18, { sx: { fontSize: "0.8rem" }, children: selected }),
5770
5900
  children: [
5771
- (!commonProps.required || formValues[param.name] === "") && /* @__PURE__ */ jsx30(MenuItem2, { value: "", sx: { fontSize: "0.8rem" }, children: /* @__PURE__ */ jsx30("em", { children: "Seleccione..." }) }),
5772
- param.options.map((option) => /* @__PURE__ */ jsx30(MenuItem2, { value: option, sx: { fontSize: "0.8rem" }, children: option }, option))
5901
+ (!commonProps.required || formValues[param.name] === "") && /* @__PURE__ */ jsx32(MenuItem2, { value: "", sx: { fontSize: "0.8rem" }, children: /* @__PURE__ */ jsx32("em", { children: "Seleccione..." }) }),
5902
+ param.options.map((option) => /* @__PURE__ */ jsx32(MenuItem2, { value: option, sx: { fontSize: "0.8rem" }, children: option }, option))
5773
5903
  ]
5774
5904
  }
5775
5905
  ),
5776
- (param.description || errorMessage) && /* @__PURE__ */ jsx30(FormHelperText2, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
5906
+ (param.description || errorMessage) && /* @__PURE__ */ jsx32(FormHelperText2, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
5777
5907
  ] });
5778
5908
  }
5779
5909
  switch (param.typeName) {
@@ -5782,18 +5912,18 @@ var ProcedureForm = () => {
5782
5912
  case "tsrange":
5783
5913
  case "time_range":
5784
5914
  case "daterange":
5785
- return /* @__PURE__ */ jsx30(TextField3, { type: "text", value: formValues[param.name] || "", ...commonProps });
5915
+ return /* @__PURE__ */ jsx32(TextField3, { type: "text", value: formValues[param.name] || "", ...commonProps });
5786
5916
  case "decimal":
5787
5917
  case "double":
5788
- return /* @__PURE__ */ jsx30(TextField3, { type: "number", inputProps: { step: "any", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
5918
+ return /* @__PURE__ */ jsx32(TextField3, { type: "number", inputProps: { step: "any", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
5789
5919
  case "integer":
5790
5920
  case "bigint":
5791
- return /* @__PURE__ */ jsx30(TextField3, { type: "number", inputProps: { step: "1", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
5921
+ return /* @__PURE__ */ jsx32(TextField3, { type: "number", inputProps: { step: "1", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
5792
5922
  case "boolean":
5793
- return /* @__PURE__ */ jsx30(
5923
+ return /* @__PURE__ */ jsx32(
5794
5924
  FormControlLabel3,
5795
5925
  {
5796
- control: /* @__PURE__ */ jsx30(
5926
+ control: /* @__PURE__ */ jsx32(
5797
5927
  Checkbox3,
5798
5928
  {
5799
5929
  checked: !!formValues[param.name],
@@ -5804,21 +5934,21 @@ var ProcedureForm = () => {
5804
5934
  size: "small"
5805
5935
  }
5806
5936
  ),
5807
- label: /* @__PURE__ */ jsx30(Typography17, { sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "inherit" }, children: param.label || param.name }),
5937
+ label: /* @__PURE__ */ jsx32(Typography18, { sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "inherit" }, children: param.label || param.name }),
5808
5938
  sx: { mt: 1, mb: 0 }
5809
5939
  }
5810
5940
  );
5811
5941
  case "date":
5812
5942
  case "timestamp":
5813
5943
  case "time":
5814
- return /* @__PURE__ */ jsx30(TextField3, { type: param.typeName === "date" ? "date" : param.typeName === "timestamp" ? "datetime-local" : "time", value: formValues[param.name] || "", ...commonProps, InputLabelProps: { shrink: true, sx: { fontSize: "0.8rem" } } });
5944
+ return /* @__PURE__ */ jsx32(TextField3, { type: param.typeName === "date" ? "date" : param.typeName === "timestamp" ? "datetime-local" : "time", value: formValues[param.name] || "", ...commonProps, InputLabelProps: { shrink: true, sx: { fontSize: "0.8rem" } } });
5815
5945
  case "jsonb":
5816
5946
  case "jsona":
5817
- return /* @__PURE__ */ jsx30(TextField3, { multiline: true, rows: 5, value: formValues[param.name] || "", ...commonProps, InputProps: { sx: { fontSize: "0.8rem" } } });
5947
+ return /* @__PURE__ */ jsx32(TextField3, { multiline: true, rows: 5, value: formValues[param.name] || "", ...commonProps, InputProps: { sx: { fontSize: "0.8rem" } } });
5818
5948
  case "bytea":
5819
- return /* @__PURE__ */ jsxs24(FormControl3, { fullWidth: true, margin: "dense", error: hasError, required: commonProps.required, children: [
5820
- /* @__PURE__ */ jsx30(Typography17, { variant: "body2", color: "textSecondary", component: "label", htmlFor: param.name, sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "text.secondary" }, children: param.label || param.name }),
5821
- /* @__PURE__ */ jsx30(
5949
+ return /* @__PURE__ */ jsxs25(FormControl3, { fullWidth: true, margin: "dense", error: hasError, required: commonProps.required, children: [
5950
+ /* @__PURE__ */ jsx32(Typography18, { variant: "body2", color: "textSecondary", component: "label", htmlFor: param.name, sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "text.secondary" }, children: param.label || param.name }),
5951
+ /* @__PURE__ */ jsx32(
5822
5952
  "input",
5823
5953
  {
5824
5954
  type: "file",
@@ -5832,34 +5962,34 @@ var ProcedureForm = () => {
5832
5962
  style: { padding: "6px 0", fontSize: "0.8rem" }
5833
5963
  }
5834
5964
  ),
5835
- (param.description || errorMessage) && /* @__PURE__ */ jsx30(FormHelperText2, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
5965
+ (param.description || errorMessage) && /* @__PURE__ */ jsx32(FormHelperText2, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
5836
5966
  ] });
5837
5967
  default:
5838
- return /* @__PURE__ */ jsx30(TextField3, { type: "text", value: formValues[param.name] || "", ...commonProps });
5968
+ return /* @__PURE__ */ jsx32(TextField3, { type: "text", value: formValues[param.name] || "", ...commonProps });
5839
5969
  }
5840
5970
  }, [formValues, handleChange, apiLoading, validationErrors]);
5841
5971
  const ResultDisplayContent = useMemo12(() => {
5842
5972
  if (!procedureResultData || !procedure?.resultOk) return null;
5843
5973
  const ComponentToRender = resultsOk[procedure.resultOk];
5844
5974
  if (ComponentToRender) {
5845
- return /* @__PURE__ */ jsx30(ComponentToRender, { data: procedureResultData });
5975
+ return /* @__PURE__ */ jsx32(ComponentToRender, { data: procedureResultData });
5846
5976
  } else {
5847
- return /* @__PURE__ */ jsxs24(Paper4, { elevation: 2, sx: { p: 2, mt: 0, bgcolor: "warning.light" }, children: [
5848
- /* @__PURE__ */ jsxs24(Typography17, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: [
5977
+ return /* @__PURE__ */ jsxs25(Paper4, { elevation: 2, sx: { p: 2, mt: 0, bgcolor: "warning.light" }, children: [
5978
+ /* @__PURE__ */ jsxs25(Typography18, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: [
5849
5979
  "el componente para resolver el resultOk: '",
5850
5980
  procedure.resultOk,
5851
5981
  "' definido en el procedure no existe o no est\xE1 mapeado."
5852
5982
  ] }),
5853
- /* @__PURE__ */ jsx30(Box19, { sx: {
5983
+ /* @__PURE__ */ jsx32(Box20, { sx: {
5854
5984
  bgcolor: "warning.dark",
5855
5985
  p: 1,
5856
5986
  borderRadius: 1
5857
- }, children: /* @__PURE__ */ jsx30("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(procedureResultData, null, 2) }) })
5987
+ }, children: /* @__PURE__ */ jsx32("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(procedureResultData, null, 2) }) })
5858
5988
  ] });
5859
5989
  }
5860
5990
  }, [procedureResultData, procedure]);
5861
5991
  if (!procedure) {
5862
- return /* @__PURE__ */ jsxs24(Box19, { sx: {
5992
+ return /* @__PURE__ */ jsxs25(Box20, { sx: {
5863
5993
  p: 2,
5864
5994
  width: "100%",
5865
5995
  boxSizing: "border-box",
@@ -5869,13 +5999,13 @@ var ProcedureForm = () => {
5869
5999
  boxShadow: 3,
5870
6000
  textAlign: "center"
5871
6001
  }, children: [
5872
- /* @__PURE__ */ jsx30(CircularProgress7, { sx: { mb: 2 } }),
5873
- /* @__PURE__ */ jsx30(Typography17, { variant: "h6", color: "text.secondary", children: "Cargando procedimiento o no encontrado..." })
6002
+ /* @__PURE__ */ jsx32(CircularProgress7, { sx: { mb: 2 } }),
6003
+ /* @__PURE__ */ jsx32(Typography18, { variant: "h6", color: "text.secondary", children: "Cargando procedimiento o no encontrado..." })
5874
6004
  ] });
5875
6005
  }
5876
6006
  return (
5877
6007
  // Esta es la Box más externa que ahora controlará el scroll
5878
- /* @__PURE__ */ jsxs24(Box19, { sx: {
6008
+ /* @__PURE__ */ jsxs25(Box20, { sx: {
5879
6009
  p: 2,
5880
6010
  ml: 1,
5881
6011
  mt: 2,
@@ -5892,17 +6022,17 @@ var ProcedureForm = () => {
5892
6022
  overflowX: "hidden"
5893
6023
  // Oculta el scroll horizontal si no es necesario para el contenedor principal
5894
6024
  }, children: [
5895
- /* @__PURE__ */ jsx30(Typography17, { variant: "h5", component: "h2", gutterBottom: true, align: "left", children: cambiarGuionesBajosPorEspacios(procedure.proceedLabel || procedure.action) }),
5896
- Object.values(validationErrors).some((err) => err !== null) && /* @__PURE__ */ jsxs24(Alert4, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: [
6025
+ /* @__PURE__ */ jsx32(Typography18, { variant: "h5", component: "h2", gutterBottom: true, align: "left", children: cambiarGuionesBajosPorEspacios(procedure.proceedLabel || procedure.action) }),
6026
+ Object.values(validationErrors).some((err) => err !== null) && /* @__PURE__ */ jsxs25(Alert4, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: [
5897
6027
  "Por favor, corrige los errores en el formulario antes de enviar.",
5898
- /* @__PURE__ */ jsx30("ul", { children: Object.values(validationErrors).map((err, idx) => err && /* @__PURE__ */ jsx30("li", { children: err }, idx)) })
6028
+ /* @__PURE__ */ jsx32("ul", { children: Object.values(validationErrors).map((err, idx) => err && /* @__PURE__ */ jsx32("li", { children: err }, idx)) })
5899
6029
  ] }),
5900
- !Object.values(validationErrors).some((err) => err !== null) && apiError && /* @__PURE__ */ jsx30(Alert4, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: apiError.message }),
5901
- !Object.values(validationErrors).some((err) => err !== null) && !apiError && successMessage && /* @__PURE__ */ jsx30(Alert4, { severity: "success", sx: { mb: 2, fontSize: "0.8rem" }, children: successMessage }),
5902
- /* @__PURE__ */ jsxs24("form", { onSubmit: handleSubmit, children: [
5903
- procedure.parameters.map((param) => /* @__PURE__ */ jsx30("div", { children: renderInputField(param) }, param.name)),
5904
- /* @__PURE__ */ jsx30(
5905
- Button11,
6030
+ !Object.values(validationErrors).some((err) => err !== null) && apiError && /* @__PURE__ */ jsx32(Alert4, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: apiError.message }),
6031
+ !Object.values(validationErrors).some((err) => err !== null) && !apiError && successMessage && /* @__PURE__ */ jsx32(Alert4, { severity: "success", sx: { mb: 2, fontSize: "0.8rem" }, children: successMessage }),
6032
+ /* @__PURE__ */ jsxs25("form", { onSubmit: handleSubmit, children: [
6033
+ procedure.parameters.map((param) => /* @__PURE__ */ jsx32("div", { children: renderInputField(param) }, param.name)),
6034
+ /* @__PURE__ */ jsx32(
6035
+ Button12,
5906
6036
  {
5907
6037
  type: "submit",
5908
6038
  variant: "contained",
@@ -5910,20 +6040,20 @@ var ProcedureForm = () => {
5910
6040
  disabled: apiLoading || Object.values(validationErrors).some((err) => err !== null),
5911
6041
  sx: { mt: 2 },
5912
6042
  size: "medium",
5913
- startIcon: apiLoading ? /* @__PURE__ */ jsx30(CircularProgress7, { size: 20, color: "inherit" }) : null,
6043
+ startIcon: apiLoading ? /* @__PURE__ */ jsx32(CircularProgress7, { size: 20, color: "inherit" }) : null,
5914
6044
  children: apiLoading ? "Ejecutando..." : procedure.proceedLabel || "Ejecutar"
5915
6045
  }
5916
6046
  )
5917
6047
  ] }),
5918
- ResultDisplayContent && /* @__PURE__ */ jsxs24(Box19, { sx: { mt: 2 }, children: [
6048
+ ResultDisplayContent && /* @__PURE__ */ jsxs25(Box20, { sx: { mt: 2 }, children: [
5919
6049
  " ",
5920
6050
  ResultDisplayContent
5921
6051
  ] }),
5922
- executionLog.length > 0 && /* @__PURE__ */ jsxs24(Box19, { sx: { mt: 3 }, children: [
5923
- /* @__PURE__ */ jsx30(Divider3, { sx: { mb: 2 } }),
5924
- /* @__PURE__ */ jsx30(Typography17, { variant: "h6", gutterBottom: true, sx: { fontSize: "0.9rem" }, children: "Registro de Ejecuci\xF3n" }),
5925
- /* @__PURE__ */ jsx30(
5926
- Box19,
6052
+ executionLog.length > 0 && /* @__PURE__ */ jsxs25(Box20, { sx: { mt: 3 }, children: [
6053
+ /* @__PURE__ */ jsx32(Divider3, { sx: { mb: 2 } }),
6054
+ /* @__PURE__ */ jsx32(Typography18, { variant: "h6", gutterBottom: true, sx: { fontSize: "0.9rem" }, children: "Registro de Ejecuci\xF3n" }),
6055
+ /* @__PURE__ */ jsx32(
6056
+ Box20,
5927
6057
  {
5928
6058
  sx: {
5929
6059
  bgcolor: "grey.100",
@@ -5936,8 +6066,8 @@ var ProcedureForm = () => {
5936
6066
  fontSize: "0.75rem",
5937
6067
  whiteSpace: "pre-wrap"
5938
6068
  },
5939
- children: executionLog.map((log, index) => /* @__PURE__ */ jsx30(
5940
- Typography17,
6069
+ children: executionLog.map((log, index) => /* @__PURE__ */ jsx32(
6070
+ Typography18,
5941
6071
  {
5942
6072
  component: "pre",
5943
6073
  sx: {
@@ -5964,7 +6094,7 @@ import { PersistGate } from "redux-persist/integration/react";
5964
6094
  // src/components/PrivateRoute.tsx
5965
6095
  import { useEffect as useEffect11 } from "react";
5966
6096
  import { Navigate as Navigate2, useLocation as useLocation3 } from "react-router-dom";
5967
- import { Fragment as Fragment5, jsx as jsx31 } from "react/jsx-runtime";
6097
+ import { Fragment as Fragment6, jsx as jsx33 } from "react/jsx-runtime";
5968
6098
  var PrivateRoute = ({ children }) => {
5969
6099
  const location = useLocation3();
5970
6100
  const dispatch = useAppDispatch();
@@ -5988,14 +6118,14 @@ var PrivateRoute = ({ children }) => {
5988
6118
  }, [isAuthenticated, isLoadingAuth, location, dispatch, clientContextStatus]);
5989
6119
  if (isLoadingAuth) {
5990
6120
  console.log(`[PrivateRoute] Returning loading state...`);
5991
- return /* @__PURE__ */ jsx31("p", { children: "Verificando autenticaci\xF3n..." });
6121
+ return /* @__PURE__ */ jsx33("p", { children: "Verificando autenticaci\xF3n..." });
5992
6122
  }
5993
6123
  if (!isAuthenticated) {
5994
6124
  console.log(`[PrivateRoute] User not authenticated, navigating to /login`);
5995
- return /* @__PURE__ */ jsx31(Navigate2, { to: "/login", replace: true });
6125
+ return /* @__PURE__ */ jsx33(Navigate2, { to: "/login", replace: true });
5996
6126
  }
5997
6127
  console.log(`[PrivateRoute] User authenticated, rendering children.`);
5998
- return /* @__PURE__ */ jsx31(Fragment5, { children });
6128
+ return /* @__PURE__ */ jsx33(Fragment6, { children });
5999
6129
  };
6000
6130
  var PrivateRoute_default = PrivateRoute;
6001
6131
 
@@ -6033,11 +6163,11 @@ var InitialRedirectHandler = () => {
6033
6163
  var InitialRedirectHandler_default = InitialRedirectHandler;
6034
6164
 
6035
6165
  // src/pages/GenericDataGridPage.tsx
6036
- import React25, { useState as useState19, useCallback as useCallback15, useMemo as useMemo13 } from "react";
6166
+ import React26, { useState as useState20, useCallback as useCallback16, useMemo as useMemo13 } from "react";
6037
6167
  import { useParams as useParams2, useLocation as useLocation5 } from "react-router-dom";
6038
- import { Box as Box20, Alert as Alert5, Typography as Typography18, Tabs, Tab, IconButton as IconButton7 } from "@mui/material";
6168
+ import { Box as Box21, Alert as Alert5, Typography as Typography19, Tabs, Tab, IconButton as IconButton7 } from "@mui/material";
6039
6169
  import CloseIcon2 from "@mui/icons-material/Close";
6040
- import { jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
6170
+ import { jsx as jsx34, jsxs as jsxs26 } from "react/jsx-runtime";
6041
6171
  var GenericDataGridPage = ({
6042
6172
  initialTableName,
6043
6173
  initialFixedFields = [],
@@ -6045,14 +6175,14 @@ var GenericDataGridPage = ({
6045
6175
  }) => {
6046
6176
  const { tableName: urlTableName } = useParams2();
6047
6177
  const effectiveTableName = initialTableName || urlTableName;
6048
- const [tabs, setTabs] = useState19([]);
6049
- const [activeTabIdx, setActiveTabIdx] = useState19(0);
6178
+ const [tabs, setTabs] = useState20([]);
6179
+ const [activeTabIdx, setActiveTabIdx] = useState20(0);
6050
6180
  const ffKey = JSON.stringify(initialFixedFields);
6051
6181
  const location = useLocation5();
6052
6182
  const parametros = useMemo13(() => parametrosRecibidos ?? parametrosDeTabla(void 0, location.search), [parametrosRecibidos, location.search]);
6053
6183
  const fixedFieldsIniciales = initialFixedFields.length > 0 ? initialFixedFields : parametros.fixedFields ?? [];
6054
6184
  const parametrosKey = JSON.stringify(parametros);
6055
- React25.useEffect(() => {
6185
+ React26.useEffect(() => {
6056
6186
  if (effectiveTableName) {
6057
6187
  setTabs([{
6058
6188
  id: `main-${effectiveTableName}-${ffKey}-${parametrosKey}`,
@@ -6066,7 +6196,7 @@ var GenericDataGridPage = ({
6066
6196
  setActiveTabIdx(0);
6067
6197
  }
6068
6198
  }, [effectiveTableName, ffKey, parametrosKey, location.key]);
6069
- const handleOpenDetail = useCallback15((tableName, fixedFields, label, ancestors) => {
6199
+ const handleOpenDetail = useCallback16((tableName, fixedFields, label, ancestors) => {
6070
6200
  const tabId = `${tableName}-${JSON.stringify(fixedFields)}`;
6071
6201
  setTabs((prevTabs) => {
6072
6202
  const existingTabIdx = prevTabs.findIndex((t) => t.id === tabId);
@@ -6088,26 +6218,26 @@ var GenericDataGridPage = ({
6088
6218
  else if (activeTabIdx === index) setActiveTabIdx(index - 1);
6089
6219
  };
6090
6220
  if (!effectiveTableName) {
6091
- return /* @__PURE__ */ jsx32(Box20, { p: 3, children: /* @__PURE__ */ jsx32(Alert5, { severity: "error", children: "No se especific\xF3 una tabla." }) });
6221
+ return /* @__PURE__ */ jsx34(Box21, { p: 3, children: /* @__PURE__ */ jsx34(Alert5, { severity: "error", children: "No se especific\xF3 una tabla." }) });
6092
6222
  }
6093
- return /* @__PURE__ */ jsxs25(Box20, { sx: { width: "100%", height: "calc(100vh - 64px)", display: "flex", flexDirection: "column" }, children: [
6094
- /* @__PURE__ */ jsx32(Box20, { sx: { borderBottom: 1, borderColor: "divider", bgcolor: "background.paper" }, children: /* @__PURE__ */ jsx32(Tabs, { value: activeTabIdx, onChange: (_, v) => setActiveTabIdx(v), variant: "scrollable", children: tabs.map((tab, index) => /* @__PURE__ */ jsx32(
6223
+ return /* @__PURE__ */ jsxs26(Box21, { sx: { width: "100%", height: "calc(100vh - 64px)", display: "flex", flexDirection: "column" }, children: [
6224
+ /* @__PURE__ */ jsx34(Box21, { sx: { borderBottom: 1, borderColor: "divider", bgcolor: "background.paper" }, children: /* @__PURE__ */ jsx34(Tabs, { value: activeTabIdx, onChange: (_, v) => setActiveTabIdx(v), variant: "scrollable", children: tabs.map((tab, index) => /* @__PURE__ */ jsx34(
6095
6225
  Tab,
6096
6226
  {
6097
- label: /* @__PURE__ */ jsxs25(Box20, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
6098
- /* @__PURE__ */ jsx32(Typography18, { variant: "caption", sx: { fontWeight: "bold" }, children: tab.label }),
6099
- index !== 0 && /* @__PURE__ */ jsx32(IconButton7, { size: "small", onClick: (e) => handleCloseTab(index, e), children: /* @__PURE__ */ jsx32(CloseIcon2, { fontSize: "inherit" }) })
6227
+ label: /* @__PURE__ */ jsxs26(Box21, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
6228
+ /* @__PURE__ */ jsx34(Typography19, { variant: "caption", sx: { fontWeight: "bold" }, children: tab.label }),
6229
+ index !== 0 && /* @__PURE__ */ jsx34(IconButton7, { size: "small", onClick: (e) => handleCloseTab(index, e), children: /* @__PURE__ */ jsx34(CloseIcon2, { fontSize: "inherit" }) })
6100
6230
  ] })
6101
6231
  },
6102
6232
  tab.id
6103
6233
  )) }) }),
6104
- tabs.map((tab, index) => /* @__PURE__ */ jsx32(
6105
- Box20,
6234
+ tabs.map((tab, index) => /* @__PURE__ */ jsx34(
6235
+ Box21,
6106
6236
  {
6107
6237
  role: "tabpanel",
6108
6238
  hidden: activeTabIdx !== index,
6109
6239
  sx: { flexGrow: 1, display: activeTabIdx === index ? "flex" : "none", flexDirection: "column", overflow: "hidden" },
6110
- children: /* @__PURE__ */ jsx32(
6240
+ children: /* @__PURE__ */ jsx34(
6111
6241
  GenericDataGrid_default,
6112
6242
  {
6113
6243
  tableName: tab.tableName,
@@ -6130,42 +6260,30 @@ var GenericDataGridPage_default = GenericDataGridPage;
6130
6260
  // src/pages/PantallaDeRuta.tsx
6131
6261
  import { useMemo as useMemo14 } from "react";
6132
6262
  import { useSearchParams } from "react-router-dom";
6133
- import { Box as Box21 } from "@mui/material";
6134
- import { jsx as jsx33 } from "react/jsx-runtime";
6263
+ import { Box as Box22 } from "@mui/material";
6264
+ import { jsx as jsx35 } from "react/jsx-runtime";
6135
6265
  var PantallaDeRuta = ({ screenName }) => {
6136
6266
  const [busqueda] = useSearchParams();
6137
6267
  const params = useMemo14(() => Object.fromEntries(busqueda.entries()), [busqueda]);
6138
6268
  const Pantalla = wScreens[screenName];
6139
- return /* @__PURE__ */ jsx33(Box21, { sx: { pt: 3, pl: 4 }, children: Pantalla ? /* @__PURE__ */ jsx33(Pantalla, { screenName, params }) : /* @__PURE__ */ jsx33(FallbackWScreen, { screenName }) });
6269
+ return /* @__PURE__ */ jsx35(Box22, { sx: { pt: 3, pl: 4 }, children: Pantalla ? /* @__PURE__ */ jsx35(Pantalla, { screenName, params }) : /* @__PURE__ */ jsx35(FallbackWScreen, { screenName }) });
6140
6270
  };
6141
6271
 
6142
6272
  // src/pages/MenuTablePage.tsx
6143
6273
  import { useMemo as useMemo15 } from "react";
6144
6274
  import { useLocation as useLocation6, useParams as useParams3 } from "react-router-dom";
6145
- import { Box as Box22, Alert as Alert6, Typography as Typography19 } from "@mui/material";
6146
- import { jsx as jsx34, jsxs as jsxs26 } from "react/jsx-runtime";
6275
+ import { Box as Box23, Alert as Alert6, Typography as Typography20 } from "@mui/material";
6276
+ import { jsx as jsx36, jsxs as jsxs27 } from "react/jsx-runtime";
6147
6277
  var MenuTablePage = () => {
6148
- const { menuName } = useParams3();
6278
+ const { "*": menuName } = useParams3();
6149
6279
  const { clientContext } = useApp();
6150
6280
  const { search } = useLocation6();
6151
- const findMenuItem = (items, nameToFind) => {
6152
- for (const item of items) {
6153
- if (item.name === nameToFind && item.menuType === "table") {
6154
- return item;
6155
- }
6156
- if (item.menuType === "menu" && item.menuContent) {
6157
- const found = findMenuItem(item.menuContent, nameToFind);
6158
- if (found) return found;
6159
- }
6160
- }
6161
- return void 0;
6162
- };
6163
6281
  const { currentTableName, currentFixedFields, parametros } = useMemo15(() => {
6164
6282
  let tableName = void 0;
6165
6283
  let fixedFields = [];
6166
6284
  let parametros2 = {};
6167
6285
  if (menuName && clientContext && clientContext.menu) {
6168
- const menuItem = findMenuItem(clientContext.menu, menuName);
6286
+ const menuItem = itemDeRuta(clientContext.menu, menuName.split("/").filter((tramo) => tramo !== ""));
6169
6287
  if (menuItem) {
6170
6288
  tableName = menuItem.table || menuItem.name;
6171
6289
  parametros2 = parametrosDeTabla(menuItem, search);
@@ -6181,12 +6299,12 @@ var MenuTablePage = () => {
6181
6299
  };
6182
6300
  }, [menuName, clientContext, search]);
6183
6301
  if (!currentTableName) {
6184
- return /* @__PURE__ */ jsx34(Box22, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ jsxs26(Alert6, { severity: "error", children: [
6185
- /* @__PURE__ */ jsx34(Typography19, { variant: "h6", children: "Error: No se pudo cargar la informaci\xF3n de la tabla." }),
6186
- /* @__PURE__ */ jsx34(Typography19, { variant: "body1", children: "Verifique la configuraci\xF3n del men\xFA o el nombre de la tabla en la URL." })
6302
+ return /* @__PURE__ */ jsx36(Box23, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ jsxs27(Alert6, { severity: "error", children: [
6303
+ /* @__PURE__ */ jsx36(Typography20, { variant: "h6", children: "Error: No se pudo cargar la informaci\xF3n de la tabla." }),
6304
+ /* @__PURE__ */ jsx36(Typography20, { variant: "body1", children: "Verifique la configuraci\xF3n del men\xFA o el nombre de la tabla en la URL." })
6187
6305
  ] }) });
6188
6306
  }
6189
- return /* @__PURE__ */ jsx34(
6307
+ return /* @__PURE__ */ jsx36(
6190
6308
  GenericDataGridPage_default,
6191
6309
  {
6192
6310
  initialTableName: currentTableName,
@@ -6198,9 +6316,9 @@ var MenuTablePage = () => {
6198
6316
  var MenuTablePage_default = MenuTablePage;
6199
6317
 
6200
6318
  // src/puente/PantallaBP.tsx
6201
- import { useEffect as useEffect15, useRef as useRef10, useState as useState20 } from "react";
6319
+ import { useEffect as useEffect15, useRef as useRef10, useState as useState21 } from "react";
6202
6320
  import { Navigate as Navigate3, useLocation as useLocation7, useParams as useParams4 } from "react-router-dom";
6203
- import { Alert as Alert7, Box as Box24, CircularProgress as CircularProgress8 } from "@mui/material";
6321
+ import { Alert as Alert7, Box as Box25, CircularProgress as CircularProgress8 } from "@mui/material";
6204
6322
 
6205
6323
  // src/puente/clienteBP.ts
6206
6324
  function extraerRecursos(html) {
@@ -6290,8 +6408,8 @@ async function cargarSinMemoria(urlBackend) {
6290
6408
 
6291
6409
  // src/puente/ConsolaBP.tsx
6292
6410
  import { useEffect as useEffect14 } from "react";
6293
- import { Box as Box23 } from "@mui/material";
6294
- import { jsx as jsx35 } from "react/jsx-runtime";
6411
+ import { Box as Box24 } from "@mui/material";
6412
+ import { jsx as jsx37 } from "react/jsx-runtime";
6295
6413
  var MARGEN_DE_REPETIDO_MS = 1e3;
6296
6414
  function descartarRepetidos(consola, agregados, ahora) {
6297
6415
  for (const nodo of agregados) {
@@ -6313,8 +6431,8 @@ var ConsolaBP = () => {
6313
6431
  observador.observe(consola, { childList: true });
6314
6432
  return () => observador.disconnect();
6315
6433
  }, []);
6316
- return /* @__PURE__ */ jsx35(
6317
- Box23,
6434
+ return /* @__PURE__ */ jsx37(
6435
+ Box24,
6318
6436
  {
6319
6437
  id: "mini-console",
6320
6438
  sx: (tema) => ({
@@ -6410,7 +6528,7 @@ var habilitarPuenteBP = () => {
6410
6528
  var puenteBPHabilitado = () => habilitado;
6411
6529
 
6412
6530
  // src/puente/PantallaBP.tsx
6413
- import { jsx as jsx36, jsxs as jsxs27 } from "react/jsx-runtime";
6531
+ import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
6414
6532
  function buscarItemDeMenu(items, tipo) {
6415
6533
  for (const item of items) {
6416
6534
  if (item.menuType === tipo) return item;
@@ -6423,9 +6541,9 @@ function buscarItemDeMenu(items, tipo) {
6423
6541
  }
6424
6542
  var PantallaBP = ({ nombre, direccion }) => {
6425
6543
  const { clientContext } = useApp();
6426
- const [cargando, setCargando] = useState20(true);
6427
- const [error, setError] = useState20(null);
6428
- const [noExiste, setNoExiste] = useState20(false);
6544
+ const [cargando, setCargando] = useState21(true);
6545
+ const [error, setError] = useState21(null);
6546
+ const [noExiste, setNoExiste] = useState21(false);
6429
6547
  const contenedor = useRef10(null);
6430
6548
  const menu = clientContext.menu;
6431
6549
  useEffect15(() => {
@@ -6459,14 +6577,14 @@ var PantallaBP = ({ nombre, direccion }) => {
6459
6577
  elemento.replaceChildren();
6460
6578
  };
6461
6579
  }, [nombre, direccion, menu]);
6462
- if (noExiste) return /* @__PURE__ */ jsx36(FallbackWScreen, { screenName: nombre });
6580
+ if (noExiste) return /* @__PURE__ */ jsx38(FallbackWScreen, { screenName: nombre });
6463
6581
  return (
6464
6582
  // el indicador de carga flota: si ocupara lugar, el contenido de backend-plus empezaría más abajo mientras carga y subiría al terminar
6465
- /* @__PURE__ */ jsxs27(Box24, { sx: { position: "relative" }, children: [
6466
- cargando && /* @__PURE__ */ jsx36(CircularProgress8, { size: 24, sx: { position: "absolute", top: 16, left: 16 } }),
6467
- error && /* @__PURE__ */ jsx36(Alert7, { severity: "error", sx: { m: 2 }, children: error }),
6468
- /* @__PURE__ */ jsx36("div", { id: "main_layout", ref: contenedor }),
6469
- /* @__PURE__ */ jsx36(ConsolaBP, {})
6583
+ /* @__PURE__ */ jsxs28(Box25, { sx: { position: "relative" }, children: [
6584
+ cargando && /* @__PURE__ */ jsx38(CircularProgress8, { size: 24, sx: { position: "absolute", top: 16, left: 16 } }),
6585
+ error && /* @__PURE__ */ jsx38(Alert7, { severity: "error", sx: { m: 2 }, children: error }),
6586
+ /* @__PURE__ */ jsx38("div", { id: "main_layout", ref: contenedor }),
6587
+ /* @__PURE__ */ jsx38(ConsolaBP, {})
6470
6588
  ] })
6471
6589
  );
6472
6590
  };
@@ -6474,32 +6592,32 @@ var PantallaDeRespaldo = () => {
6474
6592
  const { screenName = "" } = useParams4();
6475
6593
  const { search } = useLocation7();
6476
6594
  if (!puenteBPHabilitado()) {
6477
- return /* @__PURE__ */ jsx36(Box24, { sx: { p: 3 }, children: /* @__PURE__ */ jsx36(FallbackWScreen, { screenName }) });
6595
+ return /* @__PURE__ */ jsx38(Box25, { sx: { p: 3 }, children: /* @__PURE__ */ jsx38(FallbackWScreen, { screenName }) });
6478
6596
  }
6479
- return /* @__PURE__ */ jsx36(Navigate3, { to: rutaDePantallaBP(screenName, search), replace: true });
6597
+ return /* @__PURE__ */ jsx38(Navigate3, { to: rutaDePantallaBP(screenName, search), replace: true });
6480
6598
  };
6481
6599
  var PaginaBP = () => {
6482
6600
  const { hash, search } = useLocation7();
6483
6601
  const direccion = hash || search;
6484
6602
  const nombre = new URLSearchParams(direccion.replace(/^[#?]/, "")).get("w");
6485
- if (!puenteBPHabilitado()) return /* @__PURE__ */ jsx36(Navigate3, { to: "/", replace: true });
6486
- if (!nombre) return /* @__PURE__ */ jsx36(Box24, { sx: { p: 3 }, children: /* @__PURE__ */ jsxs27(Alert7, { severity: "warning", children: [
6603
+ if (!puenteBPHabilitado()) return /* @__PURE__ */ jsx38(Navigate3, { to: "/", replace: true });
6604
+ if (!nombre) return /* @__PURE__ */ jsx38(Box25, { sx: { p: 3 }, children: /* @__PURE__ */ jsxs28(Alert7, { severity: "warning", children: [
6487
6605
  "Falta la pantalla de backend-plus (",
6488
- /* @__PURE__ */ jsx36("code", { children: "#w=..." }),
6606
+ /* @__PURE__ */ jsx38("code", { children: "#w=..." }),
6489
6607
  ")."
6490
6608
  ] }) });
6491
- return /* @__PURE__ */ jsx36(PantallaBP, { nombre, direccion }, nombre);
6609
+ return /* @__PURE__ */ jsx38(PantallaBP, { nombre, direccion }, nombre);
6492
6610
  };
6493
6611
 
6494
6612
  // src/puente/GrillaBP.tsx
6495
- import { useEffect as useEffect16, useRef as useRef11, useState as useState21 } from "react";
6613
+ import { useEffect as useEffect16, useRef as useRef11, useState as useState22 } from "react";
6496
6614
  import { useParams as useParams5 } from "react-router-dom";
6497
- import { Alert as Alert8, Box as Box25, CircularProgress as CircularProgress9 } from "@mui/material";
6498
- import { jsx as jsx37, jsxs as jsxs28 } from "react/jsx-runtime";
6615
+ import { Alert as Alert8, Box as Box26, CircularProgress as CircularProgress9 } from "@mui/material";
6616
+ import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
6499
6617
  var GrillaBP = ({ tabla, fixedFields }) => {
6500
6618
  const contenedor = useRef11(null);
6501
- const [cargando, setCargando] = useState21(true);
6502
- const [error, setError] = useState21(null);
6619
+ const [cargando, setCargando] = useState22(true);
6620
+ const [error, setError] = useState22(null);
6503
6621
  const clave = JSON.stringify(fixedFields ?? []);
6504
6622
  useEffect16(() => {
6505
6623
  const elemento = contenedor.current;
@@ -6524,17 +6642,17 @@ var GrillaBP = ({ tabla, fixedFields }) => {
6524
6642
  }, [tabla, clave]);
6525
6643
  return (
6526
6644
  // el indicador de carga flota: si ocupara lugar, el contenido de backend-plus empezaría más abajo mientras carga y subiría al terminar
6527
- /* @__PURE__ */ jsxs28(Box25, { sx: { position: "relative" }, children: [
6528
- cargando && /* @__PURE__ */ jsx37(CircularProgress9, { size: 24, sx: { position: "absolute", top: 16, left: 16 } }),
6529
- error && /* @__PURE__ */ jsx37(Alert8, { severity: "error", sx: { m: 2 }, children: error }),
6530
- /* @__PURE__ */ jsx37("div", { ref: contenedor }),
6531
- /* @__PURE__ */ jsx37(ConsolaBP, {})
6645
+ /* @__PURE__ */ jsxs29(Box26, { sx: { position: "relative" }, children: [
6646
+ cargando && /* @__PURE__ */ jsx39(CircularProgress9, { size: 24, sx: { position: "absolute", top: 16, left: 16 } }),
6647
+ error && /* @__PURE__ */ jsx39(Alert8, { severity: "error", sx: { m: 2 }, children: error }),
6648
+ /* @__PURE__ */ jsx39("div", { ref: contenedor }),
6649
+ /* @__PURE__ */ jsx39(ConsolaBP, {})
6532
6650
  ] })
6533
6651
  );
6534
6652
  };
6535
6653
  var PaginaGrillaBP = () => {
6536
6654
  const { tableName = "" } = useParams5();
6537
- return /* @__PURE__ */ jsx37(GrillaBP, { tabla: tableName }, tableName);
6655
+ return /* @__PURE__ */ jsx39(GrillaBP, { tabla: tableName }, tableName);
6538
6656
  };
6539
6657
 
6540
6658
  // src/puente/CapturaBP.tsx
@@ -6591,7 +6709,7 @@ var CapturaBP = () => {
6591
6709
 
6592
6710
  // src/App.tsx
6593
6711
  import typeStore6 from "type-store";
6594
- import { Fragment as Fragment6, jsx as jsx38, jsxs as jsxs29 } from "react/jsx-runtime";
6712
+ import { Fragment as Fragment7, jsx as jsx40, jsxs as jsxs30 } from "react/jsx-runtime";
6595
6713
  var LocationTracker = () => {
6596
6714
  const location = useLocation8();
6597
6715
  const dispatch = useAppDispatch();
@@ -6601,45 +6719,45 @@ var LocationTracker = () => {
6601
6719
  return null;
6602
6720
  };
6603
6721
  function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout = MainLayout_default, unloggedLayout: UnloggedLayout }) {
6604
- return /* @__PURE__ */ jsxs29(Fragment6, { children: [
6605
- /* @__PURE__ */ jsx38(InitialRedirectHandler_default, {}),
6606
- puenteBPHabilitado() && /* @__PURE__ */ jsx38(CapturaBP, {}),
6607
- /* @__PURE__ */ jsxs29(Routes, { children: [
6608
- /* @__PURE__ */ jsxs29(Route, { element: UnloggedLayout ? /* @__PURE__ */ jsx38(UnloggedLayout, {}) : /* @__PURE__ */ jsx38(Outlet2, {}), children: [
6609
- /* @__PURE__ */ jsx38(Route, { path: "/login", element: /* @__PURE__ */ jsx38(LoginPage_default, {}) }),
6610
- /* @__PURE__ */ jsx38(Route, { path: "/logout", element: /* @__PURE__ */ jsx38(LogoutPage_default, {}) }),
6722
+ return /* @__PURE__ */ jsxs30(Fragment7, { children: [
6723
+ /* @__PURE__ */ jsx40(InitialRedirectHandler_default, {}),
6724
+ puenteBPHabilitado() && /* @__PURE__ */ jsx40(CapturaBP, {}),
6725
+ /* @__PURE__ */ jsxs30(Routes, { children: [
6726
+ /* @__PURE__ */ jsxs30(Route, { element: UnloggedLayout ? /* @__PURE__ */ jsx40(UnloggedLayout, {}) : /* @__PURE__ */ jsx40(Outlet2, {}), children: [
6727
+ /* @__PURE__ */ jsx40(Route, { path: "/login", element: /* @__PURE__ */ jsx40(LoginPage_default, {}) }),
6728
+ /* @__PURE__ */ jsx40(Route, { path: "/logout", element: /* @__PURE__ */ jsx40(LogoutPage_default, {}) }),
6611
6729
  myUnloggedRoutes
6612
6730
  ] }),
6613
- /* @__PURE__ */ jsxs29(Route, { element: /* @__PURE__ */ jsx38(PrivateRoute_default, { children: /* @__PURE__ */ jsx38(Layout, {}) }), children: [
6614
- /* @__PURE__ */ jsx38(Route, { path: "/", element: /* @__PURE__ */ jsx38(PantallaInicial_default, {}) }),
6615
- /* @__PURE__ */ jsx38(Route, { path: "/table/:tableName", element: /* @__PURE__ */ jsx38(GenericDataGridPage_default, {}) }),
6616
- /* @__PURE__ */ jsx38(Route, { path: "/menu/:menuName", element: /* @__PURE__ */ jsx38(MenuTablePage_default, {}) }),
6617
- /* @__PURE__ */ jsx38(Route, { path: "/procedures/:procedureName", element: /* @__PURE__ */ jsx38(ProcedureForm_default, {}) }),
6618
- Object.keys(wScreens).map((screenName) => /* @__PURE__ */ jsx38(
6731
+ /* @__PURE__ */ jsxs30(Route, { element: /* @__PURE__ */ jsx40(PrivateRoute_default, { children: /* @__PURE__ */ jsx40(Layout, {}) }), children: [
6732
+ /* @__PURE__ */ jsx40(Route, { path: "/", element: /* @__PURE__ */ jsx40(PantallaInicial_default, {}) }),
6733
+ /* @__PURE__ */ jsx40(Route, { path: "/table/:tableName", element: /* @__PURE__ */ jsx40(GenericDataGridPage_default, {}) }),
6734
+ /* @__PURE__ */ jsx40(Route, { path: "/menu/*", element: /* @__PURE__ */ jsx40(MenuTablePage_default, {}) }),
6735
+ /* @__PURE__ */ jsx40(Route, { path: "/procedures/:procedureName", element: /* @__PURE__ */ jsx40(ProcedureForm_default, {}) }),
6736
+ Object.keys(wScreens).map((screenName) => /* @__PURE__ */ jsx40(
6619
6737
  Route,
6620
6738
  {
6621
6739
  path: `/wScreens/${screenName}`,
6622
- element: /* @__PURE__ */ jsx38(PantallaDeRuta, { screenName })
6740
+ element: /* @__PURE__ */ jsx40(PantallaDeRuta, { screenName })
6623
6741
  },
6624
6742
  screenName
6625
6743
  )),
6626
- /* @__PURE__ */ jsx38(Route, { path: "/wScreens-fallback/:screenName", element: /* @__PURE__ */ jsx38(PantallaDeRespaldo, {}) }),
6627
- puenteBPHabilitado() && /* @__PURE__ */ jsx38(Route, { path: "/bp/menu", element: /* @__PURE__ */ jsx38(PaginaBP, {}) }),
6628
- puenteBPHabilitado() && /* @__PURE__ */ jsx38(Route, { path: "/bp/table/:tableName", element: /* @__PURE__ */ jsx38(PaginaGrillaBP, {}) }),
6744
+ /* @__PURE__ */ jsx40(Route, { path: "/wScreens-fallback/:screenName", element: /* @__PURE__ */ jsx40(PantallaDeRespaldo, {}) }),
6745
+ puenteBPHabilitado() && /* @__PURE__ */ jsx40(Route, { path: "/bp/menu", element: /* @__PURE__ */ jsx40(PaginaBP, {}) }),
6746
+ puenteBPHabilitado() && /* @__PURE__ */ jsx40(Route, { path: "/bp/table/:tableName", element: /* @__PURE__ */ jsx40(PaginaGrillaBP, {}) }),
6629
6747
  myRoutes,
6630
- /* @__PURE__ */ jsx38(Route, { path: "*", element: /* @__PURE__ */ jsx38("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
6748
+ /* @__PURE__ */ jsx40(Route, { path: "*", element: /* @__PURE__ */ jsx40("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
6631
6749
  ] }),
6632
- /* @__PURE__ */ jsx38(Route, { path: "*", element: /* @__PURE__ */ jsx38(Navigate4, { to: "/", replace: true }) })
6750
+ /* @__PURE__ */ jsx40(Route, { path: "*", element: /* @__PURE__ */ jsx40(Navigate4, { to: "/", replace: true }) })
6633
6751
  ] })
6634
6752
  ] });
6635
6753
  }
6636
6754
  var FrontendPlusProviders = ({ children, publicPaths }) => {
6637
- return /* @__PURE__ */ jsx38(Provider, { store, children: /* @__PURE__ */ jsx38(PersistGate, { loading: null, persistor, children: /* @__PURE__ */ jsxs29(BrowserRouter, { basename: rutaBase, children: [
6638
- /* @__PURE__ */ jsx38(LocationTracker, {}),
6755
+ return /* @__PURE__ */ jsx40(Provider, { store, children: /* @__PURE__ */ jsx40(PersistGate, { loading: null, persistor, children: /* @__PURE__ */ jsxs30(BrowserRouter, { basename: rutaBase, children: [
6756
+ /* @__PURE__ */ jsx40(LocationTracker, {}),
6639
6757
  " ",
6640
- /* @__PURE__ */ jsx38(AppProvider, { publicPaths, children: /* @__PURE__ */ jsxs29(SnackbarProvider, { children: [
6758
+ /* @__PURE__ */ jsx40(AppProvider, { publicPaths, children: /* @__PURE__ */ jsxs30(SnackbarProvider, { children: [
6641
6759
  children,
6642
- /* @__PURE__ */ jsx38(SessionExpiredMessage_default, {})
6760
+ /* @__PURE__ */ jsx40(SessionExpiredMessage_default, {})
6643
6761
  ] }) })
6644
6762
  ] }) }) });
6645
6763
  };
@@ -6679,11 +6797,11 @@ var App = ({
6679
6797
  link.href = `${envConfig.backendUrl}/img/logo-128.png`;
6680
6798
  document.getElementsByTagName("head")[0].appendChild(link);
6681
6799
  }, []);
6682
- const safePaths = React32.useMemo(() => {
6800
+ const safePaths = React33.useMemo(() => {
6683
6801
  const extracted = extractPathsFromRoutes(myUnloggedRoutes);
6684
6802
  return ["/login", "/logout", ...extracted];
6685
6803
  }, [myUnloggedRoutes]);
6686
- return /* @__PURE__ */ jsx38(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ jsx38(
6804
+ return /* @__PURE__ */ jsx40(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ jsx40(
6687
6805
  FrontendPlusReactRoutes,
6688
6806
  {
6689
6807
  myRoutes,