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.cjs CHANGED
@@ -59,7 +59,7 @@ __export(src_exports, {
59
59
  module.exports = __toCommonJS(src_exports);
60
60
 
61
61
  // src/components/grid/GenericDataGrid.tsx
62
- var import_react25 = require("react");
62
+ var import_react26 = require("react");
63
63
  var import_react_data_grid = require("react-data-grid");
64
64
  var import_styles = require("react-data-grid/lib/styles.css");
65
65
 
@@ -378,7 +378,7 @@ var useApiCallWithoutSnackbar = () => {
378
378
  };
379
379
 
380
380
  // src/components/grid/GenericDataGrid.tsx
381
- var import_material18 = require("@mui/material");
381
+ var import_material19 = require("@mui/material");
382
382
 
383
383
  // src/store/index.ts
384
384
  var import_toolkit4 = require("@reduxjs/toolkit");
@@ -1420,7 +1420,7 @@ function BotonDetalle({ row, rowId, detailTable, deshabilitado }) {
1420
1420
  const { abiertos, alternarDetalle } = useDetallesGrilla();
1421
1421
  if (!cumpleCondicion(detailTable.condition, row)) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "fpr-boton-detalle" });
1422
1422
  const abierto = abiertos.has(claveDetalle(rowId, detailTable));
1423
- const titulo = deshabilitado ? "Grab\xE1 la fila para ver sus detalles" : `${detailTable.label || detailTable.abr}${abierto ? " (replegar)" : ""} \u2014 Ctrl+click: en otra pesta\xF1a`;
1423
+ const titulo = deshabilitado ? "Grab\xE1 la fila para ver sus detalles" : "";
1424
1424
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material3.Tooltip, { title: titulo, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "fpr-boton-detalle", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1425
1425
  import_material3.IconButton,
1426
1426
  {
@@ -1521,7 +1521,7 @@ var opcionesDeReferencia = (campo, definicionReferenciada, filasReferenciadas, f
1521
1521
  const activo = campoDeActivo(definicionReferenciada);
1522
1522
  const nombres = camposDeNombre(definicionReferenciada);
1523
1523
  const columnasDeEtiqueta = nombres.length > 0 ? [...definicionReferenciada.primaryKey, ...nombres] : definicionReferenciada.primaryKey;
1524
- const opciones = filasReferenciadas.filter((fila) => (activo === null || !!fila[activo]) && anteriores.every((par) => comoTexto(fila[par.target]) === comoTexto(filaActual[par.source]))).map((fila) => {
1524
+ const opciones = filasReferenciadas.filter((fila) => (activo === null || !!fila[activo]) && (filaActual === null || anteriores.every((par) => comoTexto(fila[par.target]) === comoTexto(filaActual[par.source])))).map((fila) => {
1525
1525
  const etiquetas = columnasDeEtiqueta.map((columna) => comoTexto(fila[columna]));
1526
1526
  return { valor: fila[columnaDelValor], etiquetas, texto: `${etiquetas.join(", ")}; ${definicionReferenciada.primaryKey.join(", ")}` };
1527
1527
  });
@@ -1856,7 +1856,8 @@ var useGridMenu = ({
1856
1856
  callApi,
1857
1857
  resetSorting,
1858
1858
  triggerImport,
1859
- triggerExport
1859
+ triggerExport,
1860
+ abrirColumnas
1860
1861
  }) => {
1861
1862
  const { showSuccess, showError, showWarning } = useSnackbar();
1862
1863
  const menuOptions = (0, import_react10.useMemo)(() => {
@@ -1892,7 +1893,7 @@ var useGridMenu = ({
1892
1893
  label: "ocultar o mostrar columnas",
1893
1894
  icon: import_react10.default.createElement(import_VisibilityOff.default),
1894
1895
  handler: async () => {
1895
- console.log("Ocultar/mostrar columnas");
1896
+ abrirColumnas?.();
1896
1897
  },
1897
1898
  visible: true
1898
1899
  });
@@ -1941,12 +1942,12 @@ var useGridMenu = ({
1941
1942
  visible: true
1942
1943
  });
1943
1944
  return options;
1944
- }, [tableDefinition, tableName, fixedFields, setTableData, callApi, resetSorting, triggerImport, triggerExport, showSuccess, showError, showWarning]);
1945
+ }, [tableDefinition, tableName, fixedFields, setTableData, callApi, resetSorting, triggerImport, triggerExport, abrirColumnas, showSuccess, showError, showWarning]);
1945
1946
  return { menuOptions };
1946
1947
  };
1947
1948
 
1948
1949
  // src/hooks/grid/useGridColumns.ts
1949
- var import_react21 = __toESM(require("react"), 1);
1950
+ var import_react22 = __toESM(require("react"), 1);
1950
1951
 
1951
1952
  // src/utils/functions.tsx
1952
1953
  var JSON4all2 = __toESM(require("json4all"), 1);
@@ -2012,7 +2013,7 @@ var useVistaGrilla = () => (0, import_react11.useContext)(VistaGrillaContext);
2012
2013
 
2013
2014
  // src/components/grid/renderers/headerCellRenderers.tsx
2014
2015
  var import_jsx_runtime6 = require("react/jsx-runtime");
2015
- var defaultColumnHeaderCellRenderer = (props, fieldDef) => {
2016
+ var defaultColumnHeaderCellRenderer = (props, fieldDef, ocultarColumna) => {
2016
2017
  const { column, sortDirection, priority } = props;
2017
2018
  const isPrimaryKey = fieldDef.isPk;
2018
2019
  const sorted = sortDirection !== void 0;
@@ -2027,6 +2028,11 @@ var defaultColumnHeaderCellRenderer = (props, fieldDef) => {
2027
2028
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2028
2029
  import_material4.Box,
2029
2030
  {
2031
+ onClickCapture: (e) => {
2032
+ if (!e.altKey || !ocultarColumna) return;
2033
+ e.stopPropagation();
2034
+ ocultarColumna(fieldDef.name);
2035
+ },
2030
2036
  sx: {
2031
2037
  display: "flex",
2032
2038
  alignItems: "center",
@@ -2104,20 +2110,289 @@ var ActionsColumnHeaderCell = ({
2104
2110
  var detailColumnCellHeaderRenderer = (props, detailTable) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.Tooltip, { title: detailTable.label, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.Typography, { variant: "caption", sx: { fontSize: "0.75rem", fontWeight: "bold" }, children: detailTable.abr.toUpperCase() }) });
2105
2111
 
2106
2112
  // src/components/grid/FilterInputRender.tsx
2107
- var import_material6 = require("@mui/material");
2108
- var import_react14 = __toESM(require("react"), 1);
2113
+ var import_material9 = require("@mui/material");
2114
+ var import_react18 = __toESM(require("react"), 1);
2109
2115
 
2110
2116
  // src/components/forms/TypedField.tsx
2117
+ var import_react16 = require("react");
2118
+ var import_material8 = require("@mui/material");
2119
+ var import_type_store3 = __toESM(require("type-store"), 1);
2120
+ var import_react17 = require("react");
2121
+
2122
+ // src/hooks/grid/useExpander.tsx
2123
+ var import_react15 = __toESM(require("react"), 1);
2124
+ var import_IconButton = __toESM(require("@mui/material/IconButton"), 1);
2125
+ var import_ArrowDropDown = __toESM(require("@mui/icons-material/ArrowDropDown"), 1);
2126
+ var import_CalendarMonth = __toESM(require("@mui/icons-material/CalendarMonth"), 1);
2127
+ var import_Search2 = __toESM(require("@mui/icons-material/Search"), 1);
2128
+
2129
+ // src/components/grid/MenuDeOpciones.tsx
2111
2130
  var import_react12 = require("react");
2112
2131
  var import_material5 = require("@mui/material");
2113
- var import_type_store3 = __toESM(require("type-store"), 1);
2114
- var import_react13 = require("react");
2115
2132
  var import_jsx_runtime7 = require("react/jsx-runtime");
2133
+ function MenuDeOpciones({ anclaje, opciones, busquedaInicial, onElegir, onCerrar }) {
2134
+ const [busqueda, setBusqueda] = (0, import_react12.useState)(busquedaInicial);
2135
+ const [indice, setIndice] = (0, import_react12.useState)(0);
2136
+ const visibles = (0, import_react12.useMemo)(() => filtrarOpciones(opciones, busqueda), [opciones, busqueda]);
2137
+ const elegida = (0, import_react12.useRef)(null);
2138
+ (0, import_react12.useEffect)(() => {
2139
+ elegida.current?.scrollIntoView({ block: "nearest" });
2140
+ }, [indice, visibles]);
2141
+ const alApretar = (evento) => {
2142
+ if (evento.key === "ArrowDown") {
2143
+ setIndice((i) => Math.min(i + 1, visibles.length - 1));
2144
+ } else if (evento.key === "ArrowUp") {
2145
+ setIndice((i) => Math.max(i - 1, 0));
2146
+ } else if (evento.key === "Enter") {
2147
+ if (visibles[indice]) onElegir(visibles[indice].valor);
2148
+ } else if (evento.key === "F9" || evento.key === "Escape") {
2149
+ onCerrar();
2150
+ } else {
2151
+ return;
2152
+ }
2153
+ evento.preventDefault();
2154
+ evento.stopPropagation();
2155
+ };
2156
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2157
+ import_material5.Popover,
2158
+ {
2159
+ open: true,
2160
+ anchorEl: anclaje,
2161
+ onClose: onCerrar,
2162
+ disableRestoreFocus: true,
2163
+ anchorOrigin: { vertical: "bottom", horizontal: "left" },
2164
+ slotProps: { paper: { sx: { minWidth: 300, maxWidth: 520 } } },
2165
+ children: [
2166
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2167
+ import_material5.InputBase,
2168
+ {
2169
+ autoFocus: true,
2170
+ fullWidth: true,
2171
+ value: busqueda,
2172
+ onChange: (e) => {
2173
+ setBusqueda(e.target.value);
2174
+ setIndice(0);
2175
+ },
2176
+ onKeyDown: alApretar,
2177
+ placeholder: "buscar",
2178
+ sx: { px: 1, py: 0.5, fontSize: "0.8rem", borderBottom: "1px solid #ccc" },
2179
+ inputProps: { "aria-label": "buscar" }
2180
+ }
2181
+ ),
2182
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_material5.List, { dense: true, disablePadding: true, sx: { maxHeight: 320, overflowY: "auto" }, role: "listbox", children: [
2183
+ visibles.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material5.Typography, { variant: "body2", sx: { p: 1, color: "text.secondary" }, children: "sin coincidencias" }),
2184
+ visibles.map((opcion, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2185
+ import_material5.ListItemButton,
2186
+ {
2187
+ ref: i === indice ? elegida : null,
2188
+ selected: i === indice,
2189
+ role: "option",
2190
+ onClick: () => onElegir(opcion.valor),
2191
+ sx: { gap: 2, py: 0.25, fontSize: "0.8rem" },
2192
+ children: opcion.etiquetas.map((etiqueta, j) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontWeight: j === 0 ? 600 : 400, minWidth: j === 0 ? 40 : void 0 }, children: etiqueta }, j))
2193
+ },
2194
+ i
2195
+ ))
2196
+ ] })
2197
+ ]
2198
+ }
2199
+ );
2200
+ }
2201
+
2202
+ // src/components/grid/SelectorDeFecha.tsx
2203
+ var import_react13 = require("react");
2204
+ var import_material6 = require("@mui/material");
2205
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2206
+ var MESES = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"];
2207
+ var DIAS = ["lu", "ma", "mi", "ju", "vi", "s\xE1", "do"];
2208
+ var mismaFecha = (a, b) => b !== null && a.anio === b.anio && a.mes === b.mes && a.dia === b.dia;
2209
+ var MOVIMIENTOS = {
2210
+ ArrowLeft: [-1, 0],
2211
+ ArrowRight: [1, 0],
2212
+ ArrowUp: [-7, 0],
2213
+ ArrowDown: [7, 0],
2214
+ PageUp: [0, -1],
2215
+ PageDown: [0, 1]
2216
+ };
2217
+ function SelectorDeFecha({ anclaje, fechaActual, admiteNulo, onElegir, onCerrar }) {
2218
+ const hoy = /* @__PURE__ */ new Date();
2219
+ const fechaDeHoy = { anio: hoy.getFullYear(), mes: hoy.getMonth(), dia: hoy.getDate() };
2220
+ const [cursor, setCursor] = (0, import_react13.useState)(fechaActual ?? fechaDeHoy);
2221
+ const mover = (dias, meses) => {
2222
+ const nueva = new Date(cursor.anio, cursor.mes + meses, cursor.dia + dias);
2223
+ setCursor({ anio: nueva.getFullYear(), mes: nueva.getMonth(), dia: nueva.getDate() });
2224
+ };
2225
+ const alApretar = (evento) => {
2226
+ if (evento.key in MOVIMIENTOS) {
2227
+ mover(...MOVIMIENTOS[evento.key]);
2228
+ } else if (evento.key === "Enter") {
2229
+ onElegir(fechaATexto(cursor));
2230
+ } else if (evento.key === "F9" || evento.key === "Escape") {
2231
+ onCerrar();
2232
+ } else {
2233
+ return;
2234
+ }
2235
+ evento.preventDefault();
2236
+ evento.stopPropagation();
2237
+ };
2238
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_material6.Popover, { open: true, anchorEl: anclaje, onClose: onCerrar, disableRestoreFocus: true, anchorOrigin: { vertical: "bottom", horizontal: "left" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { tabIndex: 0, ref: (el) => el?.focus(), onKeyDown: alApretar, style: { padding: 8, outline: "none", width: 252 }, "aria-label": "calendario", children: [
2239
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
2240
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_material6.IconButton, { size: "small", "aria-label": "mes anterior", onClick: () => mover(0, -1), children: "\u2039" }),
2241
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_material6.Typography, { variant: "body2", sx: { fontWeight: 600 }, children: [
2242
+ MESES[cursor.mes],
2243
+ " ",
2244
+ cursor.anio
2245
+ ] }),
2246
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_material6.IconButton, { size: "small", "aria-label": "mes siguiente", onClick: () => mover(0, 1), children: "\u203A" })
2247
+ ] }),
2248
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("table", { style: { borderCollapse: "collapse", width: "100%", textAlign: "center", fontSize: "0.8rem" }, children: [
2249
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tr", { children: DIAS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("th", { style: { fontWeight: 400, color: "#777" }, children: d }, d)) }) }),
2250
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tbody", { children: semanasDelMes(cursor.anio, cursor.mes).map((semana, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tr", { children: semana.map((dia) => {
2251
+ const elegido = mismaFecha(dia, fechaActual);
2252
+ const enCursor = mismaFecha(dia, cursor);
2253
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("td", { style: { padding: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2254
+ "button",
2255
+ {
2256
+ type: "button",
2257
+ tabIndex: -1,
2258
+ onClick: () => onElegir(fechaATexto(dia)),
2259
+ style: {
2260
+ width: 32,
2261
+ height: 26,
2262
+ border: enCursor ? "1px solid #1976d2" : "1px solid transparent",
2263
+ borderRadius: 4,
2264
+ cursor: "pointer",
2265
+ background: elegido ? "#1976d2" : "transparent",
2266
+ color: elegido ? "#fff" : dia.delMesMostrado ? "#000" : "#aaa"
2267
+ },
2268
+ children: dia.dia
2269
+ }
2270
+ ) }, `${dia.mes}-${dia.dia}`);
2271
+ }) }, i)) })
2272
+ ] }),
2273
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", marginTop: 4 }, children: [
2274
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_material6.Button, { size: "small", onClick: () => onElegir(fechaATexto(fechaDeHoy)), children: "hoy" }),
2275
+ admiteNulo && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_material6.Button, { size: "small", onClick: () => onElegir(null), children: "vac\xEDo" })
2276
+ ] })
2277
+ ] }) });
2278
+ }
2279
+
2280
+ // src/components/grid/VentanaDeTexto.tsx
2281
+ var import_react14 = require("react");
2282
+ var import_material7 = require("@mui/material");
2283
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2284
+ function VentanaDeTexto({ anclaje, texto, editable, onAceptar, onCerrar }) {
2285
+ const [valor, setValor] = (0, import_react14.useState)(texto);
2286
+ const alApretar = (evento) => {
2287
+ if (evento.key === "Escape" || evento.key === "F9") {
2288
+ onCerrar();
2289
+ } else if (evento.key === "Enter" && evento.ctrlKey && editable) {
2290
+ onAceptar(valor);
2291
+ } else {
2292
+ return;
2293
+ }
2294
+ evento.preventDefault();
2295
+ evento.stopPropagation();
2296
+ };
2297
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Popover, { open: true, anchorEl: anclaje, onClose: onCerrar, disableRestoreFocus: true, anchorOrigin: { vertical: "bottom", horizontal: "left" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { padding: 8, minWidth: 320, maxWidth: 640 }, children: [
2298
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2299
+ import_material7.InputBase,
2300
+ {
2301
+ autoFocus: true,
2302
+ multiline: true,
2303
+ fullWidth: true,
2304
+ readOnly: !editable,
2305
+ value: valor,
2306
+ onChange: (e) => setValor(e.target.value),
2307
+ onKeyDown: alApretar,
2308
+ minRows: 2,
2309
+ maxRows: 16,
2310
+ sx: { fontFamily: "monospace", fontSize: "0.8rem", border: "1px solid #ccc", borderRadius: "4px", p: 0.5 },
2311
+ inputProps: { "aria-label": "contenido de la celda" }
2312
+ }
2313
+ ),
2314
+ editable && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 4 }, children: [
2315
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Button, { size: "small", onClick: onCerrar, children: "cancelar" }),
2316
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Button, { size: "small", variant: "contained", onClick: () => onAceptar(valor), children: "aceptar" })
2317
+ ] })
2318
+ ] }) });
2319
+ }
2320
+
2321
+ // src/hooks/grid/useExpander.tsx
2322
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2323
+ var useExpander = ({ campo, editable, fila, admiteNulo, tipos, anclaje, textoActual, valorActual, alElegirValor, alConfirmarTexto, alFallar }) => {
2324
+ const [expansion, setExpansion] = (0, import_react15.useState)(null);
2325
+ const abierto = import_react15.default.useRef(false);
2326
+ const tipoDelCampo = tipoDeExpander(campo, editable);
2327
+ const tipo = tipoDelCampo === null || tipoDelCampo === "json" || tipos && !tipos.includes(tipoDelCampo) ? null : tipoDelCampo;
2328
+ const abrir = (0, import_react15.useCallback)(async (busqueda) => {
2329
+ if (tipo === null || abierto.current) return;
2330
+ abierto.current = true;
2331
+ try {
2332
+ if (tipo === "referencia" && esCampoConReferencia(campo)) {
2333
+ const { definicion, filas } = await cargarReferencia(campo.references);
2334
+ setExpansion({ tipo: "opciones", opciones: opcionesDeReferencia(campo, definicion, filas, fila, admiteNulo), busqueda });
2335
+ } else if (tipo === "booleano") {
2336
+ setExpansion({ tipo: "opciones", opciones: opcionesDeBooleano(admiteNulo), busqueda });
2337
+ } else if (tipo === "opciones") {
2338
+ setExpansion({ tipo: "opciones", opciones: opcionesDeEnumerado(campo.options ?? [], admiteNulo), busqueda });
2339
+ } else {
2340
+ setExpansion({ tipo: tipo === "fecha" ? "fecha" : "texto" });
2341
+ }
2342
+ } catch (err) {
2343
+ abierto.current = false;
2344
+ alFallar(mensajeDeError(err));
2345
+ }
2346
+ }, [tipo, campo, fila, admiteNulo, alFallar]);
2347
+ const cerrar = (0, import_react15.useCallback)(() => {
2348
+ abierto.current = false;
2349
+ setExpansion(null);
2350
+ setTimeout(() => anclaje.current?.focus(), 0);
2351
+ }, [anclaje]);
2352
+ const elegirValor = (0, import_react15.useCallback)((valor) => {
2353
+ cerrar();
2354
+ alElegirValor(valor);
2355
+ }, [cerrar, alElegirValor]);
2356
+ const confirmarTexto = (0, import_react15.useCallback)((texto) => {
2357
+ cerrar();
2358
+ alConfirmarTexto(texto);
2359
+ }, [cerrar, alConfirmarTexto]);
2360
+ const manejarTecla = (0, import_react15.useCallback)((event) => {
2361
+ const esExpander = event.key === "F9" && !event.shiftKey && !event.ctrlKey && !event.altKey || event.key === "ArrowDown" && event.altKey && !event.shiftKey && !event.ctrlKey;
2362
+ if (tipo === null || !esExpander) return false;
2363
+ event.preventDefault();
2364
+ void abrir("");
2365
+ return true;
2366
+ }, [tipo, abrir]);
2367
+ const titulo = tipo === "fecha" ? "elegir fecha (F9)" : tipo === "texto" ? "ver el contenido completo (F9)" : "elegir un valor (F9)";
2368
+ const lupa = tipo === null ? null : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2369
+ import_IconButton.default,
2370
+ {
2371
+ size: "small",
2372
+ tabIndex: -1,
2373
+ "aria-label": titulo.replace(" (F9)", ""),
2374
+ title: titulo,
2375
+ onMouseDown: (e) => e.preventDefault(),
2376
+ onClick: (e) => {
2377
+ e.stopPropagation();
2378
+ void abrir("");
2379
+ },
2380
+ sx: { p: 0, ml: 0.25, color: "primary.main", "&:hover": { backgroundColor: "action.hover" } },
2381
+ children: tipo === "fecha" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_CalendarMonth.default, { sx: { fontSize: 16 } }) : tipo === "texto" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_Search2.default, { sx: { fontSize: 16 } }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ArrowDropDown.default, { sx: { fontSize: 20 } })
2382
+ }
2383
+ );
2384
+ const base = anclaje.current;
2385
+ const ventana = !expansion || !base ? null : expansion.tipo === "opciones" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuDeOpciones, { anclaje: base, opciones: expansion.opciones, busquedaInicial: expansion.busqueda, onElegir: elegirValor, onCerrar: cerrar }) : expansion.tipo === "fecha" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectorDeFecha, { anclaje: base, fechaActual: fechaDeValor(valorActual), admiteNulo, onElegir: confirmarTexto, onCerrar: cerrar }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(VentanaDeTexto, { anclaje: base, texto: textoActual, editable: true, onAceptar: confirmarTexto, onCerrar: cerrar });
2386
+ return { tipo, abierto, abrir, manejarTecla, lupa, ventana };
2387
+ };
2388
+
2389
+ // src/components/forms/TypedField.tsx
2390
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2116
2391
  var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode = false, feedback, isMandatory = false }) => {
2117
- const theme = (0, import_material5.useTheme)();
2118
- const typer = (0, import_react12.useMemo)(() => import_type_store3.default.typerFrom(fieldDef), [fieldDef]);
2119
- const isBoolean = fieldDef.typeName === "boolean";
2120
- const [localString, setLocalString] = (0, import_react12.useState)(() => {
2392
+ const theme = (0, import_material8.useTheme)();
2393
+ const typer = (0, import_react16.useMemo)(() => import_type_store3.default.typerFrom(fieldDef), [fieldDef]);
2394
+ const isBoolean = fieldDef.typeName === "boolean" && !isFilterMode;
2395
+ const [localString, setLocalString] = (0, import_react16.useState)(() => {
2121
2396
  if (isBoolean) return "";
2122
2397
  if (isFilterMode) return value !== null && value !== void 0 ? String(value) : "";
2123
2398
  try {
@@ -2126,10 +2401,10 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2126
2401
  return value === null || value === void 0 ? "" : String(value);
2127
2402
  }
2128
2403
  });
2129
- const [errorMsg, setErrorMsg] = (0, import_react12.useState)(null);
2130
- const lastValueRef = (0, import_react13.useRef)(value);
2131
- const lastCommittedStringRef = (0, import_react13.useRef)(localString);
2132
- (0, import_react12.useEffect)(() => {
2404
+ const [errorMsg, setErrorMsg] = (0, import_react16.useState)(null);
2405
+ const lastValueRef = (0, import_react17.useRef)(value);
2406
+ const lastCommittedStringRef = (0, import_react17.useRef)(localString);
2407
+ (0, import_react16.useEffect)(() => {
2133
2408
  if (!isBoolean) {
2134
2409
  if (value !== lastValueRef.current) {
2135
2410
  lastValueRef.current = value;
@@ -2146,7 +2421,27 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2146
2421
  }
2147
2422
  }
2148
2423
  }, [value, typer, isBoolean, isFilterMode]);
2149
- const handleTextChange = (0, import_react12.useCallback)((e) => {
2424
+ const entradaRef = (0, import_react17.useRef)(null);
2425
+ const [enfocado, setEnfocado] = (0, import_react16.useState)(false);
2426
+ const escribirEnFiltro = (0, import_react16.useCallback)((texto) => {
2427
+ setLocalString(texto);
2428
+ lastValueRef.current = texto;
2429
+ onChange(fieldDef.name, texto, true);
2430
+ }, [onChange, fieldDef.name]);
2431
+ const expander = useExpander({
2432
+ campo: fieldDef,
2433
+ editable: true,
2434
+ fila: null,
2435
+ admiteNulo: false,
2436
+ tipos: isFilterMode ? ["referencia", "booleano", "opciones", "fecha"] : [],
2437
+ anclaje: entradaRef,
2438
+ textoActual: localString,
2439
+ valorActual: localString,
2440
+ alElegirValor: (valor) => escribirEnFiltro(valor === null || valor === void 0 ? "" : typeof valor === "boolean" ? typer.toLocalString(valor) : String(valor)),
2441
+ alConfirmarTexto: (texto) => escribirEnFiltro(texto ?? ""),
2442
+ alFallar: (mensaje) => setErrorMsg(mensaje)
2443
+ });
2444
+ const handleTextChange = (0, import_react16.useCallback)((e) => {
2150
2445
  const newValueString = e.target.value;
2151
2446
  setLocalString(newValueString);
2152
2447
  let parsedValue = null;
@@ -2167,7 +2462,7 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2167
2462
  lastValueRef.current = parsedValue;
2168
2463
  onChange(fieldDef.name, parsedValue, isValid);
2169
2464
  }, [typer, onChange, fieldDef.name, isFilterMode]);
2170
- const handleTextCommit = (0, import_react12.useCallback)(() => {
2465
+ const handleTextCommit = (0, import_react16.useCallback)(() => {
2171
2466
  if (!onCommit) return;
2172
2467
  if (localString === lastCommittedStringRef.current) return;
2173
2468
  lastCommittedStringRef.current = localString;
@@ -2185,13 +2480,14 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2185
2480
  }
2186
2481
  onCommit(fieldDef.name, parsedValue, isValid);
2187
2482
  }, [onCommit, fieldDef.name, localString, isFilterMode, typer]);
2188
- const handleTextKeyDown = (0, import_react12.useCallback)((e) => {
2483
+ const handleTextKeyDown = (0, import_react16.useCallback)((e) => {
2484
+ if (expander.manejarTecla(e)) return;
2189
2485
  if (e.key === "Enter") {
2190
2486
  e.preventDefault();
2191
2487
  handleTextCommit();
2192
2488
  }
2193
- }, [handleTextCommit]);
2194
- const handleBooleanChange = (0, import_react12.useCallback)((e) => {
2489
+ }, [handleTextCommit, expander]);
2490
+ const handleBooleanChange = (0, import_react16.useCallback)((e) => {
2195
2491
  const val = e.target.value;
2196
2492
  let finalValue = null;
2197
2493
  if (val === "true") finalValue = true;
@@ -2219,28 +2515,28 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2219
2515
  }
2220
2516
  const cellBackgroundColor2 = feedback === "error" ? theme.palette.error.light : feedback === "success" ? theme.palette.success.light : defaultBgColor;
2221
2517
  const transitionStyle2 = "background-color 0.3s ease-in-out";
2222
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_material5.FormControl, { fullWidth: true, error: !!errorMsg && !isFilterMode, disabled: isDisabled, size: "small", margin: "dense", children: [
2223
- !isFilterMode && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material5.InputLabel, { shrink: true, children: fieldDef.name }),
2224
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2225
- import_material5.Select,
2518
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material8.FormControl, { fullWidth: true, error: !!errorMsg && !isFilterMode, disabled: isDisabled, size: "small", margin: "dense", children: [
2519
+ !isFilterMode && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.InputLabel, { shrink: true, children: fieldDef.name }),
2520
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2521
+ import_material8.Select,
2226
2522
  {
2227
2523
  value: boolVal,
2228
2524
  label: !isFilterMode ? fieldDef.name : void 0,
2229
2525
  onChange: handleBooleanChange,
2230
- startAdornment: isMandatory && isEmpty && !isFilterMode ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material5.InputAdornment, { position: "start", sx: { color: "text.secondary", ml: 0.5 }, children: "*" }) : void 0,
2526
+ startAdornment: isMandatory && isEmpty && !isFilterMode ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.InputAdornment, { position: "start", sx: { color: "text.secondary", ml: 0.5 }, children: "*" }) : void 0,
2231
2527
  displayEmpty: true,
2232
2528
  sx: isFilterMode ? { height: 25, fontSize: "0.8rem", backgroundColor: "background.paper" } : {
2233
2529
  backgroundColor: cellBackgroundColor2,
2234
2530
  transition: transitionStyle2
2235
2531
  },
2236
2532
  children: [
2237
- fieldDef.nullable !== false && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material5.MenuItem, { value: "", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("em", { children: "Nulo / Sin Especificar" }) }),
2238
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material5.MenuItem, { value: "true", children: "S\xED (Verdadero)" }),
2239
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material5.MenuItem, { value: "false", children: "No (Falso)" })
2533
+ fieldDef.nullable !== false && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.MenuItem, { value: "", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("em", { children: "Nulo / Sin Especificar" }) }),
2534
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.MenuItem, { value: "true", children: "S\xED (Verdadero)" }),
2535
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.MenuItem, { value: "false", children: "No (Falso)" })
2240
2536
  ]
2241
2537
  }
2242
2538
  ),
2243
- errorMsg && !isFilterMode && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material5.FormHelperText, { children: errorMsg })
2539
+ errorMsg && !isFilterMode && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.FormHelperText, { children: errorMsg })
2244
2540
  ] });
2245
2541
  }
2246
2542
  let inputType = "text";
@@ -2254,54 +2550,65 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
2254
2550
  }
2255
2551
  const cellBackgroundColor = feedback === "error" ? theme.palette.error.light : feedback === "success" ? theme.palette.success.light : defaultTextBgColor;
2256
2552
  const transitionStyle = "background-color 0.3s ease-in-out";
2257
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2258
- import_material5.TextField,
2259
- {
2260
- fullWidth: true,
2261
- type: inputType,
2262
- label: isFilterMode ? void 0 : fieldDef.name,
2263
- variant: "outlined",
2264
- size: "small",
2265
- margin: isFilterMode ? "none" : "dense",
2266
- value: localString,
2267
- onChange: handleTextChange,
2268
- disabled: isDisabled,
2269
- error: !!errorMsg && !isFilterMode,
2270
- helperText: !isFilterMode ? errorMsg || (isMandatory ? "Obligatorio" : "") : void 0,
2271
- InputLabelProps: !isFilterMode ? { shrink: true } : void 0,
2272
- InputProps: !isFilterMode && isMandatory && isEmptyText ? {
2273
- startAdornment: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material5.InputAdornment, { position: "start", sx: { color: "text.secondary", mr: 0.5 }, children: "*" })
2274
- } : {},
2275
- inputProps: {
2276
- style: {
2277
- textAlign: isNumericType(fieldDef.typeName) ? "right" : "left"
2278
- }
2279
- },
2280
- sx: isFilterMode ? {
2281
- "& .MuiOutlinedInput-root": {
2282
- backgroundColor: "background.paper",
2283
- height: FILTER_ROW_HEIGHT - 5,
2284
- minWidth: 50,
2285
- fontSize: "0.8rem",
2286
- padding: "0px"
2287
- }
2288
- } : {
2289
- "& .MuiOutlinedInput-root": {
2290
- backgroundColor: cellBackgroundColor,
2291
- transition: transitionStyle
2553
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2554
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2555
+ import_material8.TextField,
2556
+ {
2557
+ fullWidth: true,
2558
+ inputRef: entradaRef,
2559
+ type: inputType,
2560
+ label: isFilterMode ? void 0 : fieldDef.name,
2561
+ variant: "outlined",
2562
+ size: "small",
2563
+ margin: isFilterMode ? "none" : "dense",
2564
+ value: localString,
2565
+ onChange: handleTextChange,
2566
+ disabled: isDisabled,
2567
+ error: !!errorMsg && !isFilterMode,
2568
+ helperText: !isFilterMode ? errorMsg || (isMandatory ? "Obligatorio" : "") : void 0,
2569
+ InputLabelProps: !isFilterMode ? { shrink: true } : void 0,
2570
+ InputProps: isFilterMode ? {
2571
+ // la lupa solo al enfocar el filtro, como en backend-plus
2572
+ endAdornment: enfocado || expander.abierto.current ? expander.lupa : void 0
2573
+ } : isMandatory && isEmptyText ? {
2574
+ startAdornment: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.InputAdornment, { position: "start", sx: { color: "text.secondary", mr: 0.5 }, children: "*" })
2575
+ } : {},
2576
+ inputProps: {
2577
+ style: {
2578
+ textAlign: isNumericType(fieldDef.typeName) ? "right" : "left"
2579
+ }
2292
2580
  },
2293
- "& .MuiOutlinedInput-input": {
2294
- padding: "6px 12px"
2295
- }
2296
- },
2297
- onBlur: handleTextCommit,
2298
- onKeyDown: handleTextKeyDown
2299
- }
2300
- );
2581
+ sx: isFilterMode ? {
2582
+ "& .MuiOutlinedInput-root": {
2583
+ backgroundColor: "background.paper",
2584
+ height: FILTER_ROW_HEIGHT - 5,
2585
+ minWidth: 50,
2586
+ fontSize: "0.8rem",
2587
+ padding: "0px"
2588
+ }
2589
+ } : {
2590
+ "& .MuiOutlinedInput-root": {
2591
+ backgroundColor: cellBackgroundColor,
2592
+ transition: transitionStyle
2593
+ },
2594
+ "& .MuiOutlinedInput-input": {
2595
+ padding: "6px 12px"
2596
+ }
2597
+ },
2598
+ onFocus: () => setEnfocado(true),
2599
+ onBlur: () => {
2600
+ setEnfocado(false);
2601
+ handleTextCommit();
2602
+ },
2603
+ onKeyDown: handleTextKeyDown
2604
+ }
2605
+ ),
2606
+ expander.ventana
2607
+ ] });
2301
2608
  };
2302
2609
 
2303
2610
  // src/components/grid/FilterInputRender.tsx
2304
- var import_jsx_runtime8 = require("react/jsx-runtime");
2611
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2305
2612
  function FilterInputRenderer({
2306
2613
  columnKey,
2307
2614
  currentFilter,
@@ -2324,8 +2631,8 @@ function FilterInputRenderer({
2324
2631
  [columnKey]: { operator: newOp, value: formattedVal }
2325
2632
  }));
2326
2633
  };
2327
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_material6.Box, { sx: { mt: 0, display: "flex", alignItems: "center", gap: 0.5, pr: 1 }, children: [
2328
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2634
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material9.Box, { sx: { mt: 0, display: "flex", alignItems: "center", gap: 0.5, pr: 1 }, children: [
2635
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2329
2636
  "select",
2330
2637
  {
2331
2638
  value: operator,
@@ -2341,10 +2648,10 @@ function FilterInputRenderer({
2341
2648
  textAlign: "center",
2342
2649
  cursor: "pointer"
2343
2650
  },
2344
- children: filterOperators.map((op) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: op.value, children: op.label }, op.value))
2651
+ children: filterOperators.map((op) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: op.value, children: op.label }, op.value))
2345
2652
  }
2346
2653
  ),
2347
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2654
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2348
2655
  TypedField,
2349
2656
  {
2350
2657
  fieldDef,
@@ -2355,8 +2662,8 @@ function FilterInputRenderer({
2355
2662
  )
2356
2663
  ] });
2357
2664
  }
2358
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2359
- import_material6.InputBase,
2665
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2666
+ import_material9.InputBase,
2360
2667
  {
2361
2668
  value: currentFilter || "",
2362
2669
  onChange: (e) => setFilters((prev) => ({
@@ -2378,18 +2685,18 @@ function FilterInputRenderer({
2378
2685
  }
2379
2686
  );
2380
2687
  }
2381
- var FilterInputRender_default = import_react14.default.memo(FilterInputRenderer);
2688
+ var FilterInputRender_default = import_react18.default.memo(FilterInputRenderer);
2382
2689
 
2383
2690
  // src/components/grid/renderers/summaryCellRenderers.tsx
2384
- var import_material7 = require("@mui/material");
2385
- var import_jsx_runtime9 = require("react/jsx-runtime");
2691
+ var import_material10 = require("@mui/material");
2692
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2386
2693
  var defaultColumnSummaryCellRenderer = (props, fixedFields) => {
2387
2694
  const { column, row } = props;
2388
2695
  if (row.id === "filterRow") {
2389
2696
  const { filters, setFilters } = row;
2390
2697
  if (valorFijoDe(fixedFields, column.key)) return null;
2391
2698
  const fieldDef = esColumnaPropia(column) && column.customType === "default" ? column.fieldDef : void 0;
2392
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Box, { sx: { width: "100%", height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2699
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Box, { sx: { width: "100%", height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2393
2700
  FilterInputRender_default,
2394
2701
  {
2395
2702
  columnKey: column.key,
@@ -2431,7 +2738,7 @@ var defaultColumnSummaryCellRenderer = (props, fixedFields) => {
2431
2738
  label = "Cant S\xED: ";
2432
2739
  break;
2433
2740
  }
2434
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material7.Box, { sx: {
2741
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material10.Box, { sx: {
2435
2742
  px: 0,
2436
2743
  fontWeight: "bold",
2437
2744
  fontSize: "0.875rem",
@@ -2449,36 +2756,36 @@ var actionsColumnSummaryCellRenderer = (_props) => null;
2449
2756
  var detailColumnCellSummaryRenderer = (_props) => null;
2450
2757
 
2451
2758
  // src/components/grid/renderers/cellRenderers.tsx
2452
- var import_react15 = __toESM(require("react"), 1);
2453
- var import_material10 = require("@mui/material");
2759
+ var import_react19 = __toESM(require("react"), 1);
2760
+ var import_material13 = require("@mui/material");
2454
2761
  var import_ViewHeadline = __toESM(require("@mui/icons-material/ViewHeadline"), 1);
2455
2762
  var import_Delete = __toESM(require("@mui/icons-material/Delete"), 1);
2456
2763
  var import_Add2 = __toESM(require("@mui/icons-material/Add"), 1);
2457
2764
 
2458
2765
  // src/components/grid/ExampleClientSideComponent.tsx
2459
- var import_material8 = require("@mui/material");
2460
- var import_jsx_runtime10 = require("react/jsx-runtime");
2766
+ var import_material11 = require("@mui/material");
2767
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2461
2768
  var ExampleClientSideComponent = ({ row, column, fieldDefinition }) => {
2462
2769
  const value = row[column.key];
2463
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_material8.Box, { sx: {
2770
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material11.Box, { sx: {
2464
2771
  padding: 0.5,
2465
2772
  width: "100%",
2466
2773
  height: "100%",
2467
2774
  display: "flex",
2468
2775
  alignItems: "center",
2469
2776
  backgroundColor: value === "Special" ? "lightblue" : "transparent"
2470
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_material8.Typography, { variant: "body2", sx: { fontWeight: "bold" }, children: value ? `CS: ${value}` : "N/A" }) });
2777
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material11.Typography, { variant: "body2", sx: { fontWeight: "bold" }, children: value ? `CS: ${value}` : "N/A" }) });
2471
2778
  };
2472
2779
  var ExampleClientSideComponent_default = ExampleClientSideComponent;
2473
2780
 
2474
2781
  // src/components/grid/FallbackClientSideRenderer.tsx
2475
- var import_material9 = require("@mui/material");
2782
+ var import_material12 = require("@mui/material");
2476
2783
  var import_WarningAmber2 = __toESM(require("@mui/icons-material/WarningAmber"), 1);
2477
- var import_jsx_runtime11 = require("react/jsx-runtime");
2784
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2478
2785
  var FallbackClientSideRenderer = ({ column, row, fieldDefinition }) => {
2479
2786
  const clientSideName = fieldDefinition?.clientSide || "Desconocido";
2480
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material9.Tooltip, { title: `Componente clientSide '${clientSideName}' no implementado. Mostrando valor por defecto.`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2481
- import_material9.Box,
2787
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material12.Tooltip, { title: `Componente clientSide '${clientSideName}' no implementado. Mostrando valor por defecto.`, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2788
+ import_material12.Box,
2482
2789
  {
2483
2790
  sx: {
2484
2791
  display: "flex",
@@ -2498,8 +2805,8 @@ var FallbackClientSideRenderer = ({ column, row, fieldDefinition }) => {
2498
2805
  // Evita que el contenido se desborde
2499
2806
  },
2500
2807
  children: [
2501
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material9.Typography, { variant: "body2", noWrap: true, sx: { flexGrow: 1 }, children: clientSideName + " not found" }),
2502
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2808
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material12.Typography, { variant: "body2", noWrap: true, sx: { flexGrow: 1 }, children: clientSideName + " not found" }),
2809
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2503
2810
  import_WarningAmber2.default,
2504
2811
  {
2505
2812
  sx: {
@@ -2527,9 +2834,9 @@ var extendClientSides = (newRenderers) => {
2527
2834
  };
2528
2835
 
2529
2836
  // src/components/grid/renderers/cellRenderers.tsx
2530
- var import_jsx_runtime12 = require("react/jsx-runtime");
2531
- var CeldaDato = import_react15.default.memo(function CeldaDato2({ row, columnKey, defaultColumn }) {
2532
- const theme = (0, import_material10.useTheme)();
2837
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2838
+ var CeldaDato = import_react19.default.memo(function CeldaDato2({ row, columnKey, defaultColumn }) {
2839
+ const theme = (0, import_material13.useTheme)();
2533
2840
  const { primaryKey, fixedFields, typer, isMandatory, isNumeric } = defaultColumn;
2534
2841
  const rowId = getPrimaryKeyValues(row, primaryKey);
2535
2842
  const currentCellFeedback = useFeedbackCelda(`${rowId}-${columnKey}`);
@@ -2549,7 +2856,7 @@ var CeldaDato = import_react15.default.memo(function CeldaDato2({ row, columnKey
2549
2856
  displayValue = "* " + displayValue;
2550
2857
  }
2551
2858
  const signal = displayValue === "--" ? "typed-controls-signal-no-data" : displayValue === "//" ? "typed-controls-signal-unknown-data" : "";
2552
- const celda = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2859
+ const celda = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2553
2860
  "div",
2554
2861
  {
2555
2862
  className: `fpr-celda ${isNumeric ? "fpr-celda-numerica" : ""} ${signal} ${row[NEW_ROW_INDICATOR] ? "new-row-cell-animation" : ""}`,
@@ -2557,13 +2864,13 @@ var CeldaDato = import_react15.default.memo(function CeldaDato2({ row, columnKey
2557
2864
  children: displayValue
2558
2865
  }
2559
2866
  );
2560
- return currentCellFeedback?.message ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_material10.Tooltip, { title: currentCellFeedback.message, children: celda }) : celda;
2867
+ return currentCellFeedback?.message ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_material13.Tooltip, { title: currentCellFeedback.message, children: celda }) : celda;
2561
2868
  });
2562
2869
  var allColumnsCellRenderer = (props) => {
2563
2870
  const { row, column } = props;
2564
2871
  if (!esColumnaPropia(column)) return void 0;
2565
2872
  if (esFilaDetalle(row)) {
2566
- return column.customType === "action" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CeldaDetalle, { fila: row }) : null;
2873
+ return column.customType === "action" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CeldaDetalle, { fila: row }) : null;
2567
2874
  }
2568
2875
  switch (column.customType) {
2569
2876
  case "default": {
@@ -2572,15 +2879,15 @@ var allColumnsCellRenderer = (props) => {
2572
2879
  if (fieldDef?.clientSide) {
2573
2880
  const ClientSideComponent = clientSides[fieldDef.clientSide];
2574
2881
  if (ClientSideComponent) {
2575
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ClientSideComponent, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
2882
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ClientSideComponent, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
2576
2883
  }
2577
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FallbackClientSideRenderer_default, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
2884
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FallbackClientSideRenderer_default, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
2578
2885
  }
2579
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CeldaDato, { row, columnKey: props.column.key, defaultColumn });
2886
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CeldaDato, { row, columnKey: props.column.key, defaultColumn });
2580
2887
  }
2581
2888
  case "detail": {
2582
2889
  const { detailTable, primaryKey } = column;
2583
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2890
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2584
2891
  BotonDetalle,
2585
2892
  {
2586
2893
  row,
@@ -2615,8 +2922,8 @@ var allColumnsCellRenderer = (props) => {
2615
2922
  color: "primary"
2616
2923
  }
2617
2924
  ];
2618
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_material10.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", gap: 0.5 }, children: gridActionButtons.map((actionDef) => tableDefinition.allow[actionDef.action] ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2619
- import_material10.Button,
2925
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_material13.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", gap: 0.5 }, children: gridActionButtons.map((actionDef) => tableDefinition.allow[actionDef.action] ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2926
+ import_material13.Button,
2620
2927
  {
2621
2928
  variant: "outlined",
2622
2929
  color: actionDef.color,
@@ -2624,7 +2931,7 @@ var allColumnsCellRenderer = (props) => {
2624
2931
  onClick: () => actionDef.handler(row),
2625
2932
  title: actionDef.title,
2626
2933
  sx: { width: 22, minWidth: 22, height: 22, "& .MuiButton-startIcon": { m: 0 } },
2627
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(actionDef.icon, { sx: { fontSize: 18 } })
2934
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(actionDef.icon, { sx: { fontSize: 18 } })
2628
2935
  },
2629
2936
  actionDef.action
2630
2937
  ) : null) });
@@ -2635,260 +2942,62 @@ var allColumnsCellRenderer = (props) => {
2635
2942
  };
2636
2943
 
2637
2944
  // src/components/grid/InputRenderer.tsx
2638
- var import_react20 = __toESM(require("react"), 1);
2639
-
2640
- // src/hooks/useTableRecordSave.ts
2641
- var import_react16 = require("react");
2642
- var useTableRecordSave = () => {
2643
- const { callApi, loading, error } = useApiCall();
2644
- const saveRecord = (0, import_react16.useCallback)(async ({
2645
- tableDefinition,
2646
- isNewRow,
2647
- formData,
2648
- initialData,
2649
- targetFieldName
2650
- }) => {
2651
- const status = isNewRow ? "new" : "update";
2652
- let rowToSend = {};
2653
- if (isNewRow) {
2654
- tableDefinition.fields.forEach((fieldDef) => {
2655
- const fieldValue = formData[fieldDef.name];
2656
- if (fieldValue !== void 0 && fieldValue !== null && String(fieldValue).trim() !== "") {
2657
- rowToSend[fieldDef.name] = fieldValue;
2658
- } else if (tableDefinition.primaryKey.includes(fieldDef.name) && (fieldValue === null || fieldValue === void 0 || String(fieldValue).trim() === "")) {
2659
- rowToSend[fieldDef.name] = fieldValue;
2660
- }
2661
- });
2662
- delete rowToSend["$new"];
2663
- } else {
2664
- if (targetFieldName) {
2665
- rowToSend[targetFieldName] = formData[targetFieldName];
2666
- } else {
2667
- Object.keys(formData).forEach((key) => {
2668
- if (formData[key] !== initialData[key]) {
2669
- rowToSend[key] = formData[key];
2670
- }
2671
- });
2672
- }
2673
- }
2674
- const primaryKeyValuesForBackend = isNewRow ? [] : tableDefinition.primaryKey.map((key) => initialData[key]);
2675
- const response = await callApi("table_record_save", {
2676
- // como backend-plus (`depot.def.name`): el servidor busca la definición por este nombre. Una definición que guarda en
2677
- // otra tabla (`tableName`, con campos de `table`) no existe con el nombre de la física: ahí faltarían sus campos
2678
- table: tableDefinition.name,
2679
- primaryKeyValues: primaryKeyValuesForBackend,
2680
- newRow: rowToSend,
2681
- oldRow: isNewRow ? {} : initialData,
2682
- status
2683
- });
2684
- return requerido(response, "la respuesta del guardado");
2685
- }, [callApi]);
2686
- return { saveRecord, loading, error };
2687
- };
2688
-
2689
- // src/components/grid/InputRenderer.tsx
2690
- var import_InputBase = __toESM(require("@mui/material/InputBase"), 1);
2691
- var import_IconButton = __toESM(require("@mui/material/IconButton"), 1);
2692
- var import_ArrowDropDown = __toESM(require("@mui/icons-material/ArrowDropDown"), 1);
2693
- var import_CalendarMonth = __toESM(require("@mui/icons-material/CalendarMonth"), 1);
2694
- var import_Search2 = __toESM(require("@mui/icons-material/Search"), 1);
2695
- var import_material14 = require("@mui/material");
2696
-
2697
- // src/components/grid/MenuDeOpciones.tsx
2698
- var import_react17 = require("react");
2699
- var import_material11 = require("@mui/material");
2700
- var import_jsx_runtime13 = require("react/jsx-runtime");
2701
- function MenuDeOpciones({ anclaje, opciones, busquedaInicial, onElegir, onCerrar }) {
2702
- const [busqueda, setBusqueda] = (0, import_react17.useState)(busquedaInicial);
2703
- const [indice, setIndice] = (0, import_react17.useState)(0);
2704
- const visibles = (0, import_react17.useMemo)(() => filtrarOpciones(opciones, busqueda), [opciones, busqueda]);
2705
- const elegida = (0, import_react17.useRef)(null);
2706
- (0, import_react17.useEffect)(() => {
2707
- elegida.current?.scrollIntoView({ block: "nearest" });
2708
- }, [indice, visibles]);
2709
- const alApretar = (evento) => {
2710
- if (evento.key === "ArrowDown") {
2711
- setIndice((i) => Math.min(i + 1, visibles.length - 1));
2712
- } else if (evento.key === "ArrowUp") {
2713
- setIndice((i) => Math.max(i - 1, 0));
2714
- } else if (evento.key === "Enter") {
2715
- if (visibles[indice]) onElegir(visibles[indice].valor);
2716
- } else if (evento.key === "F9" || evento.key === "Escape") {
2717
- onCerrar();
2718
- } else {
2719
- return;
2720
- }
2721
- evento.preventDefault();
2722
- evento.stopPropagation();
2723
- };
2724
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2725
- import_material11.Popover,
2726
- {
2727
- open: true,
2728
- anchorEl: anclaje,
2729
- onClose: onCerrar,
2730
- disableRestoreFocus: true,
2731
- anchorOrigin: { vertical: "bottom", horizontal: "left" },
2732
- slotProps: { paper: { sx: { minWidth: 300, maxWidth: 520 } } },
2733
- children: [
2734
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2735
- import_material11.InputBase,
2736
- {
2737
- autoFocus: true,
2738
- fullWidth: true,
2739
- value: busqueda,
2740
- onChange: (e) => {
2741
- setBusqueda(e.target.value);
2742
- setIndice(0);
2743
- },
2744
- onKeyDown: alApretar,
2745
- placeholder: "buscar",
2746
- sx: { px: 1, py: 0.5, fontSize: "0.8rem", borderBottom: "1px solid #ccc" },
2747
- inputProps: { "aria-label": "buscar" }
2748
- }
2749
- ),
2750
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material11.List, { dense: true, disablePadding: true, sx: { maxHeight: 320, overflowY: "auto" }, role: "listbox", children: [
2751
- visibles.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material11.Typography, { variant: "body2", sx: { p: 1, color: "text.secondary" }, children: "sin coincidencias" }),
2752
- visibles.map((opcion, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2753
- import_material11.ListItemButton,
2754
- {
2755
- ref: i === indice ? elegida : null,
2756
- selected: i === indice,
2757
- role: "option",
2758
- onClick: () => onElegir(opcion.valor),
2759
- sx: { gap: 2, py: 0.25, fontSize: "0.8rem" },
2760
- children: opcion.etiquetas.map((etiqueta, j) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontWeight: j === 0 ? 600 : 400, minWidth: j === 0 ? 40 : void 0 }, children: etiqueta }, j))
2761
- },
2762
- i
2763
- ))
2764
- ] })
2765
- ]
2766
- }
2767
- );
2768
- }
2769
-
2770
- // src/components/grid/SelectorDeFecha.tsx
2771
- var import_react18 = require("react");
2772
- var import_material12 = require("@mui/material");
2773
- var import_jsx_runtime14 = require("react/jsx-runtime");
2774
- var MESES = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"];
2775
- var DIAS = ["lu", "ma", "mi", "ju", "vi", "s\xE1", "do"];
2776
- var mismaFecha = (a, b) => b !== null && a.anio === b.anio && a.mes === b.mes && a.dia === b.dia;
2777
- var MOVIMIENTOS = {
2778
- ArrowLeft: [-1, 0],
2779
- ArrowRight: [1, 0],
2780
- ArrowUp: [-7, 0],
2781
- ArrowDown: [7, 0],
2782
- PageUp: [0, -1],
2783
- PageDown: [0, 1]
2784
- };
2785
- function SelectorDeFecha({ anclaje, fechaActual, admiteNulo, onElegir, onCerrar }) {
2786
- const hoy = /* @__PURE__ */ new Date();
2787
- const fechaDeHoy = { anio: hoy.getFullYear(), mes: hoy.getMonth(), dia: hoy.getDate() };
2788
- const [cursor, setCursor] = (0, import_react18.useState)(fechaActual ?? fechaDeHoy);
2789
- const mover = (dias, meses) => {
2790
- const nueva = new Date(cursor.anio, cursor.mes + meses, cursor.dia + dias);
2791
- setCursor({ anio: nueva.getFullYear(), mes: nueva.getMonth(), dia: nueva.getDate() });
2792
- };
2793
- const alApretar = (evento) => {
2794
- if (evento.key in MOVIMIENTOS) {
2795
- mover(...MOVIMIENTOS[evento.key]);
2796
- } else if (evento.key === "Enter") {
2797
- onElegir(fechaATexto(cursor));
2798
- } else if (evento.key === "F9" || evento.key === "Escape") {
2799
- onCerrar();
2800
- } else {
2801
- return;
2802
- }
2803
- evento.preventDefault();
2804
- evento.stopPropagation();
2805
- };
2806
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Popover, { open: true, anchorEl: anclaje, onClose: onCerrar, disableRestoreFocus: true, anchorOrigin: { vertical: "bottom", horizontal: "left" }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { tabIndex: 0, ref: (el) => el?.focus(), onKeyDown: alApretar, style: { padding: 8, outline: "none", width: 252 }, "aria-label": "calendario", children: [
2807
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
2808
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.IconButton, { size: "small", "aria-label": "mes anterior", onClick: () => mover(0, -1), children: "\u2039" }),
2809
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Typography, { variant: "body2", sx: { fontWeight: 600 }, children: [
2810
- MESES[cursor.mes],
2811
- " ",
2812
- cursor.anio
2813
- ] }),
2814
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.IconButton, { size: "small", "aria-label": "mes siguiente", onClick: () => mover(0, 1), children: "\u203A" })
2815
- ] }),
2816
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("table", { style: { borderCollapse: "collapse", width: "100%", textAlign: "center", fontSize: "0.8rem" }, children: [
2817
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tr", { children: DIAS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("th", { style: { fontWeight: 400, color: "#777" }, children: d }, d)) }) }),
2818
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tbody", { children: semanasDelMes(cursor.anio, cursor.mes).map((semana, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tr", { children: semana.map((dia) => {
2819
- const elegido = mismaFecha(dia, fechaActual);
2820
- const enCursor = mismaFecha(dia, cursor);
2821
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("td", { style: { padding: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2822
- "button",
2823
- {
2824
- type: "button",
2825
- tabIndex: -1,
2826
- onClick: () => onElegir(fechaATexto(dia)),
2827
- style: {
2828
- width: 32,
2829
- height: 26,
2830
- border: enCursor ? "1px solid #1976d2" : "1px solid transparent",
2831
- borderRadius: 4,
2832
- cursor: "pointer",
2833
- background: elegido ? "#1976d2" : "transparent",
2834
- color: elegido ? "#fff" : dia.delMesMostrado ? "#000" : "#aaa"
2835
- },
2836
- children: dia.dia
2837
- }
2838
- ) }, `${dia.mes}-${dia.dia}`);
2839
- }) }, i)) })
2840
- ] }),
2841
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", marginTop: 4 }, children: [
2842
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Button, { size: "small", onClick: () => onElegir(fechaATexto(fechaDeHoy)), children: "hoy" }),
2843
- admiteNulo && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Button, { size: "small", onClick: () => onElegir(null), children: "vac\xEDo" })
2844
- ] })
2845
- ] }) });
2846
- }
2847
-
2848
- // src/components/grid/VentanaDeTexto.tsx
2849
- var import_react19 = require("react");
2850
- var import_material13 = require("@mui/material");
2851
- var import_jsx_runtime15 = require("react/jsx-runtime");
2852
- function VentanaDeTexto({ anclaje, texto, editable, onAceptar, onCerrar }) {
2853
- const [valor, setValor] = (0, import_react19.useState)(texto);
2854
- const alApretar = (evento) => {
2855
- if (evento.key === "Escape" || evento.key === "F9") {
2856
- onCerrar();
2857
- } else if (evento.key === "Enter" && evento.ctrlKey && editable) {
2858
- onAceptar(valor);
2945
+ var import_react21 = __toESM(require("react"), 1);
2946
+
2947
+ // src/hooks/useTableRecordSave.ts
2948
+ var import_react20 = require("react");
2949
+ var useTableRecordSave = () => {
2950
+ const { callApi, loading, error } = useApiCall();
2951
+ const saveRecord = (0, import_react20.useCallback)(async ({
2952
+ tableDefinition,
2953
+ isNewRow,
2954
+ formData,
2955
+ initialData,
2956
+ targetFieldName
2957
+ }) => {
2958
+ const status = isNewRow ? "new" : "update";
2959
+ let rowToSend = {};
2960
+ if (isNewRow) {
2961
+ tableDefinition.fields.forEach((fieldDef) => {
2962
+ const fieldValue = formData[fieldDef.name];
2963
+ if (fieldValue !== void 0 && fieldValue !== null && String(fieldValue).trim() !== "") {
2964
+ rowToSend[fieldDef.name] = fieldValue;
2965
+ } else if (tableDefinition.primaryKey.includes(fieldDef.name) && (fieldValue === null || fieldValue === void 0 || String(fieldValue).trim() === "")) {
2966
+ rowToSend[fieldDef.name] = fieldValue;
2967
+ }
2968
+ });
2969
+ delete rowToSend["$new"];
2859
2970
  } else {
2860
- return;
2861
- }
2862
- evento.preventDefault();
2863
- evento.stopPropagation();
2864
- };
2865
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material13.Popover, { open: true, anchorEl: anclaje, onClose: onCerrar, disableRestoreFocus: true, anchorOrigin: { vertical: "bottom", horizontal: "left" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { padding: 8, minWidth: 320, maxWidth: 640 }, children: [
2866
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2867
- import_material13.InputBase,
2868
- {
2869
- autoFocus: true,
2870
- multiline: true,
2871
- fullWidth: true,
2872
- readOnly: !editable,
2873
- value: valor,
2874
- onChange: (e) => setValor(e.target.value),
2875
- onKeyDown: alApretar,
2876
- minRows: 2,
2877
- maxRows: 16,
2878
- sx: { fontFamily: "monospace", fontSize: "0.8rem", border: "1px solid #ccc", borderRadius: "4px", p: 0.5 },
2879
- inputProps: { "aria-label": "contenido de la celda" }
2971
+ if (targetFieldName) {
2972
+ rowToSend[targetFieldName] = formData[targetFieldName];
2973
+ } else {
2974
+ Object.keys(formData).forEach((key) => {
2975
+ if (formData[key] !== initialData[key]) {
2976
+ rowToSend[key] = formData[key];
2977
+ }
2978
+ });
2880
2979
  }
2881
- ),
2882
- editable && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 4 }, children: [
2883
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material13.Button, { size: "small", onClick: onCerrar, children: "cancelar" }),
2884
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material13.Button, { size: "small", variant: "contained", onClick: () => onAceptar(valor), children: "aceptar" })
2885
- ] })
2886
- ] }) });
2887
- }
2980
+ }
2981
+ const primaryKeyValuesForBackend = isNewRow ? [] : tableDefinition.primaryKey.map((key) => initialData[key]);
2982
+ const response = await callApi("table_record_save", {
2983
+ // como backend-plus (`depot.def.name`): el servidor busca la definición por este nombre. Una definición que guarda en
2984
+ // otra tabla (`tableName`, con campos de `table`) no existe con el nombre de la física: ahí faltarían sus campos
2985
+ table: tableDefinition.name,
2986
+ primaryKeyValues: primaryKeyValuesForBackend,
2987
+ newRow: rowToSend,
2988
+ oldRow: isNewRow ? {} : initialData,
2989
+ status
2990
+ });
2991
+ return requerido(response, "la respuesta del guardado");
2992
+ }, [callApi]);
2993
+ return { saveRecord, loading, error };
2994
+ };
2888
2995
 
2889
2996
  // src/components/grid/InputRenderer.tsx
2997
+ var import_InputBase = __toESM(require("@mui/material/InputBase"), 1);
2998
+ var import_material14 = require("@mui/material");
2890
2999
  var import_type_store4 = __toESM(require("type-store"), 1);
2891
- var import_jsx_runtime16 = require("react/jsx-runtime");
3000
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2892
3001
  function findChangedValues(oldRowData, newRowData, isNewRow) {
2893
3002
  let changes = [];
2894
3003
  for (const key in newRowData) {
@@ -2914,12 +3023,10 @@ function InputRenderer({
2914
3023
  const setCellFeedbackMap = estadoGrilla.setFeedback;
2915
3024
  const setLocalCellChanges = estadoGrilla.setCambiosLocales;
2916
3025
  const fieldDefinition = requerido(tableDefinition.fields.find((f) => f.name === column.key), `el campo '${column.key}'`);
2917
- const typer = (0, import_react20.useMemo)(() => import_type_store4.default.typerFrom(fieldDefinition), [fieldDefinition]);
2918
- const [editingValue, setEditingValue] = (0, import_react20.useState)(() => row[column.key] !== null ? isNumericType(fieldDefinition?.typeName) ? row[column.key] : typer.toLocalString(row[column.key]) : null);
2919
- const isCommitInProgress = import_react20.default.useRef(false);
2920
- const [expansion, setExpansion] = (0, import_react20.useState)(null);
2921
- const menuAbierto = import_react20.default.useRef(false);
2922
- const entradaRef = import_react20.default.useRef(null);
3026
+ const typer = (0, import_react21.useMemo)(() => import_type_store4.default.typerFrom(fieldDefinition), [fieldDefinition]);
3027
+ const [editingValue, setEditingValue] = (0, import_react21.useState)(() => row[column.key] !== null ? isNumericType(fieldDefinition?.typeName) ? row[column.key] : typer.toLocalString(row[column.key]) : null);
3028
+ const isCommitInProgress = import_react21.default.useRef(false);
3029
+ const entradaRef = import_react21.default.useRef(null);
2923
3030
  const theme = (0, import_material14.useTheme)();
2924
3031
  const { showSuccess, showError } = useSnackbar();
2925
3032
  const { saveRecord } = useTableRecordSave();
@@ -2934,8 +3041,8 @@ function InputRenderer({
2934
3041
  cellBackgroundColor = currentCellFeedback.type === "error" ? theme.palette.error.light : theme.palette.success.light;
2935
3042
  cellBorderColor = currentCellFeedback.type === "error" ? theme.palette.error.main : theme.palette.success.main;
2936
3043
  }
2937
- const initialRowId = (0, import_react20.useMemo)(() => getPrimaryKeyValues(row, primaryKey), [row, primaryKey]);
2938
- const handleCommit = (0, import_react20.useCallback)(async (currentValue, closeEditor, focusNextCell) => {
3044
+ const initialRowId = (0, import_react21.useMemo)(() => getPrimaryKeyValues(row, primaryKey), [row, primaryKey]);
3045
+ const handleCommit = (0, import_react21.useCallback)(async (currentValue, closeEditor, focusNextCell) => {
2939
3046
  if (isCommitInProgress.current) return;
2940
3047
  isCommitInProgress.current = true;
2941
3048
  let processedNewValue;
@@ -3078,49 +3185,30 @@ function InputRenderer({
3078
3185
  initialRowId,
3079
3186
  typer
3080
3187
  ]);
3081
- const tipoExpander = tipoDeExpander(fieldDefinition, fieldDefinition.editable !== false);
3082
- const abrirExpander = (0, import_react20.useCallback)(async (busqueda) => {
3083
- if (tipoExpander === null || tipoExpander === "json" || menuAbierto.current) return;
3084
- menuAbierto.current = true;
3085
- const admiteNulo = fieldDefinition.nullable !== false;
3086
- try {
3087
- if (tipoExpander === "referencia" && esCampoConReferencia(fieldDefinition)) {
3088
- const { definicion, filas } = await cargarReferencia(fieldDefinition.references);
3089
- setExpansion({ tipo: "opciones", opciones: opcionesDeReferencia(fieldDefinition, definicion, filas, row, admiteNulo), busqueda });
3090
- } else if (tipoExpander === "booleano") {
3091
- setExpansion({ tipo: "opciones", opciones: opcionesDeBooleano(admiteNulo), busqueda });
3092
- } else if (tipoExpander === "opciones") {
3093
- setExpansion({ tipo: "opciones", opciones: opcionesDeEnumerado(fieldDefinition.options ?? [], admiteNulo), busqueda });
3094
- } else {
3095
- setExpansion({ tipo: tipoExpander === "fecha" ? "fecha" : "texto" });
3096
- }
3097
- } catch (err) {
3098
- menuAbierto.current = false;
3099
- showError(mensajeDeError(err));
3100
- }
3101
- }, [tipoExpander, fieldDefinition, row, showError]);
3102
- const cerrarExpansion = (0, import_react20.useCallback)(() => {
3103
- menuAbierto.current = false;
3104
- setExpansion(null);
3105
- setTimeout(() => entradaRef.current?.focus(), 0);
3106
- }, []);
3107
- const confirmarEnExpansion = (0, import_react20.useCallback)((nuevo) => {
3188
+ const confirmarEnExpansion = (0, import_react21.useCallback)((nuevo) => {
3108
3189
  setEditingValue(nuevo);
3109
- cerrarExpansion();
3110
3190
  void handleCommit(nuevo, true, false);
3111
- }, [cerrarExpansion, handleCommit]);
3112
- const elegirOpcion = (0, import_react20.useCallback)((valor) => {
3191
+ }, [handleCommit]);
3192
+ const elegirOpcion = (0, import_react21.useCallback)((valor) => {
3113
3193
  confirmarEnExpansion(valor === null || valor === void 0 ? null : typeof valor === "boolean" || isNumericType(fieldDefinition.typeName) ? valor : typer.toLocalString(valor));
3114
3194
  }, [fieldDefinition.typeName, typer, confirmarEnExpansion]);
3115
- const handleKeyDown = (0, import_react20.useCallback)(async (event) => {
3116
- if (tipoExpander !== null && (event.key === "F9" && !event.shiftKey && !event.ctrlKey && !event.altKey || event.key === "ArrowDown" && event.altKey && !event.shiftKey && !event.ctrlKey)) {
3117
- event.preventDefault();
3118
- void abrirExpander("");
3119
- return;
3120
- }
3195
+ const expander = useExpander({
3196
+ campo: fieldDefinition,
3197
+ editable: fieldDefinition.editable !== false,
3198
+ fila: row,
3199
+ admiteNulo: fieldDefinition.nullable !== false,
3200
+ anclaje: entradaRef,
3201
+ textoActual: editingValue === null || editingValue === void 0 ? "" : String(editingValue),
3202
+ valorActual: row[column.key],
3203
+ alElegirValor: elegirOpcion,
3204
+ alConfirmarTexto: confirmarEnExpansion,
3205
+ alFallar: showError
3206
+ });
3207
+ const handleKeyDown = (0, import_react21.useCallback)(async (event) => {
3208
+ if (expander.manejarTecla(event)) return;
3121
3209
  if (event.key.length === 1 && !event.ctrlKey && !event.altKey && !event.metaKey && caracterRechazado(event.key, typer)) {
3122
3210
  event.preventDefault();
3123
- if (tipoExpander === "referencia") void abrirExpander(event.key);
3211
+ if (expander.tipo === "referencia") void expander.abrir(event.key);
3124
3212
  return;
3125
3213
  }
3126
3214
  if (event.key === "F4") {
@@ -3133,24 +3221,24 @@ function InputRenderer({
3133
3221
  if (onKeyPress?.(rowIdx, column.key, event, handleCommit, editingValue)) {
3134
3222
  event.preventDefault();
3135
3223
  }
3136
- }, [handleCommit, editingValue, column.key, rowIdx, onKeyPress, tipoExpander, abrirExpander, typer]);
3137
- const procesarTecla = import_react20.default.useRef(() => {
3224
+ }, [handleCommit, editingValue, column.key, rowIdx, onKeyPress, expander, typer]);
3225
+ const procesarTecla = import_react21.default.useRef(() => {
3138
3226
  });
3139
3227
  procesarTecla.current = (key) => {
3140
3228
  if (key === "F9") {
3141
- void abrirExpander("");
3229
+ void expander.abrir("");
3142
3230
  } else if (key === "F4" && onKeyPress) {
3143
3231
  onKeyPress(rowIdx, column.key, { key, target: document.activeElement ?? document.body }, handleCommit, editingValue);
3144
3232
  }
3145
3233
  };
3146
- (0, import_react20.useEffect)(() => registrarEditor?.((key) => procesarTecla.current(key)), []);
3147
- const handleBlur = (0, import_react20.useCallback)(() => {
3148
- if (menuAbierto.current) return;
3234
+ (0, import_react21.useEffect)(() => registrarEditor?.((key) => procesarTecla.current(key)), []);
3235
+ const handleBlur = (0, import_react21.useCallback)(() => {
3236
+ if (expander.abierto.current) return;
3149
3237
  handleCommit(editingValue, true, false);
3150
3238
  }, [handleCommit, editingValue]);
3151
3239
  const isFieldEditable = fieldDefinition?.editable !== false;
3152
3240
  const isNumeric = isNumericType(fieldDefinition?.typeName);
3153
- const editor = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3241
+ const editor = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3154
3242
  import_InputBase.default,
3155
3243
  {
3156
3244
  autoFocus: true,
@@ -3183,61 +3271,19 @@ function InputRenderer({
3183
3271
  },
3184
3272
  onClick: (e) => e.stopPropagation(),
3185
3273
  disabled: !isFieldEditable,
3186
- endAdornment: tipoExpander !== null && tipoExpander !== "json" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3187
- import_IconButton.default,
3188
- {
3189
- size: "small",
3190
- tabIndex: -1,
3191
- "aria-label": tipoExpander === "fecha" ? "elegir fecha" : tipoExpander === "texto" ? "ver el contenido completo" : "elegir un valor",
3192
- title: tipoExpander === "fecha" ? "elegir fecha (F9)" : tipoExpander === "texto" ? "ver el contenido completo (F9)" : "elegir un valor (F9)",
3193
- onMouseDown: (e) => e.preventDefault(),
3194
- onClick: (e) => {
3195
- e.stopPropagation();
3196
- void abrirExpander("");
3197
- },
3198
- sx: { p: 0, ml: 0.25, color: "primary.main", "&:hover": { backgroundColor: "action.hover" } },
3199
- children: tipoExpander === "fecha" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_CalendarMonth.default, { sx: { fontSize: 16 } }) : tipoExpander === "texto" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_Search2.default, { sx: { fontSize: 16 } }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_ArrowDropDown.default, { sx: { fontSize: 20 } })
3200
- }
3201
- )
3274
+ endAdornment: expander.lupa
3202
3275
  }
3203
3276
  );
3204
- const conMenu = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3277
+ const conMenu = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3205
3278
  editor,
3206
- expansion && entradaRef.current && (expansion.tipo === "opciones" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3207
- MenuDeOpciones,
3208
- {
3209
- anclaje: entradaRef.current,
3210
- opciones: expansion.opciones,
3211
- busquedaInicial: expansion.busqueda,
3212
- onElegir: elegirOpcion,
3213
- onCerrar: cerrarExpansion
3214
- }
3215
- ) : expansion.tipo === "fecha" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3216
- SelectorDeFecha,
3217
- {
3218
- anclaje: entradaRef.current,
3219
- fechaActual: fechaDeValor(row[column.key]),
3220
- admiteNulo: fieldDefinition.nullable !== false,
3221
- onElegir: confirmarEnExpansion,
3222
- onCerrar: cerrarExpansion
3223
- }
3224
- ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3225
- VentanaDeTexto,
3226
- {
3227
- anclaje: entradaRef.current,
3228
- texto: editingValue === null || editingValue === void 0 ? "" : String(editingValue),
3229
- editable: true,
3230
- onAceptar: confirmarEnExpansion,
3231
- onCerrar: cerrarExpansion
3232
- }
3233
- ))
3279
+ expander.ventana
3234
3280
  ] });
3235
- return currentCellFeedback?.message ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_material14.Tooltip, { title: currentCellFeedback.message, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { width: "100%" }, children: conMenu }) }) : conMenu;
3281
+ return currentCellFeedback?.message ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_material14.Tooltip, { title: currentCellFeedback.message, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { width: "100%" }, children: conMenu }) }) : conMenu;
3236
3282
  }
3237
3283
  var InputRenderer_default = InputRenderer;
3238
3284
 
3239
3285
  // src/components/grid/renderers/editCellRenderers.tsx
3240
- var import_jsx_runtime17 = require("react/jsx-runtime");
3286
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3241
3287
  var allColumnsEditCellRenderer = (props, allColumns) => {
3242
3288
  const column = props.column;
3243
3289
  if (!esColumnaPropia(column)) return void 0;
@@ -3259,7 +3305,7 @@ var allColumnsEditCellRenderer = (props, allColumns) => {
3259
3305
  if (!isFieldEditableByUI) {
3260
3306
  return void 0;
3261
3307
  }
3262
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3308
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3263
3309
  InputRenderer_default,
3264
3310
  {
3265
3311
  ...props,
@@ -3284,6 +3330,14 @@ var allColumnsEditCellRenderer = (props, allColumns) => {
3284
3330
  }
3285
3331
  };
3286
3332
 
3333
+ // src/utils/columnasOcultas.ts
3334
+ function columnasOcultasIniciales(tableDefinition) {
3335
+ return Array.from(new Set(tableDefinition.hiddenColumns ?? []));
3336
+ }
3337
+ function campoDibujable(field) {
3338
+ return field.visible !== false;
3339
+ }
3340
+
3287
3341
  // src/hooks/grid/useGridColumns.ts
3288
3342
  var estimateTextWidth = (text) => text.length * 8 + 16;
3289
3343
  var calcularAnchosDeColumnas = (tableDefinition, filas) => {
@@ -3321,6 +3375,8 @@ var useGridColumns = ({
3321
3375
  tableDefinition,
3322
3376
  anchosCalculados,
3323
3377
  fixedFields,
3378
+ columnasOcultas,
3379
+ ocultarColumna,
3324
3380
  primaryKey,
3325
3381
  setTableData,
3326
3382
  handleKeyPressInEditor,
@@ -3331,10 +3387,10 @@ var useGridColumns = ({
3331
3387
  toggleFilterVisibility,
3332
3388
  abrirOpcionesDeGrilla
3333
3389
  }) => {
3334
- const columns = (0, import_react21.useMemo)(() => {
3390
+ const columns = (0, import_react22.useMemo)(() => {
3335
3391
  if (!tableDefinition) return [];
3336
3392
  const fieldsToShow = tableDefinition.fields.filter((field) => {
3337
- return !columnaOcultaPorFixedField(fixedFields, field.name) && field.visible !== false;
3393
+ return campoDibujable(field) && !columnaOcultaPorFixedField(fixedFields, field.name) && !columnasOcultas.has(field.name);
3338
3394
  });
3339
3395
  const defaultColumns = fieldsToShow.map((fieldDef) => {
3340
3396
  const isFixedField = valorFijoDe(fixedFields, fieldDef.name) !== void 0;
@@ -3359,7 +3415,7 @@ var useGridColumns = ({
3359
3415
  registrarEditor,
3360
3416
  width: colWidth,
3361
3417
  minWidth: 40,
3362
- renderHeaderCell: (props) => defaultColumnHeaderCellRenderer(props, fieldDef),
3418
+ renderHeaderCell: (props) => defaultColumnHeaderCellRenderer(props, fieldDef, ocultarColumna),
3363
3419
  renderSummaryCell: (props) => defaultColumnSummaryCellRenderer(props, fixedFields)
3364
3420
  };
3365
3421
  return column;
@@ -3382,7 +3438,7 @@ var useGridColumns = ({
3382
3438
  editable: false,
3383
3439
  resizable: false,
3384
3440
  sortable: false,
3385
- renderHeaderCell: () => import_react21.default.createElement(ActionsColumnHeaderCell, {
3441
+ renderHeaderCell: () => import_react22.default.createElement(ActionsColumnHeaderCell, {
3386
3442
  toggleFilterVisibility,
3387
3443
  handleDataGridOptions: (e) => abrirOpcionesDeGrilla(e.currentTarget),
3388
3444
  handleAddRow,
@@ -3422,18 +3478,18 @@ var useGridColumns = ({
3422
3478
  renderEditCell: (props) => allColumnsEditCellRenderer(props, allColumns),
3423
3479
  renderCell: (props) => allColumnsCellRenderer(props)
3424
3480
  }));
3425
- }, [tableDefinition, anchosCalculados, fixedFields, primaryKey, setTableData, handleKeyPressInEditor, registrarEditor, handleDeleteRow, handleAddRow, handleVerticalEditRow, toggleFilterVisibility, abrirOpcionesDeGrilla]);
3481
+ }, [tableDefinition, anchosCalculados, fixedFields, columnasOcultas, ocultarColumna, primaryKey, setTableData, handleKeyPressInEditor, registrarEditor, handleDeleteRow, handleAddRow, handleVerticalEditRow, toggleFilterVisibility, abrirOpcionesDeGrilla]);
3426
3482
  return { columns };
3427
3483
  };
3428
3484
 
3429
3485
  // src/components/grid/ImportDialog.tsx
3430
- var import_react22 = require("react");
3486
+ var import_react23 = require("react");
3431
3487
  var import_material15 = require("@mui/material");
3432
3488
  var import_FileUpload2 = __toESM(require("@mui/icons-material/FileUpload"), 1);
3433
- var import_jsx_runtime18 = require("react/jsx-runtime");
3489
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3434
3490
  var ImportDialog = ({ open, onClose, onImport, loading }) => {
3435
- const [file, setFile] = (0, import_react22.useState)(null);
3436
- const [options, setOptions] = (0, import_react22.useState)({
3491
+ const [file, setFile] = (0, import_react23.useState)(null);
3492
+ const [options, setOptions] = (0, import_react23.useState)({
3437
3493
  skipUnknownFieldsAtImport: false,
3438
3494
  simplificateSpaces: true,
3439
3495
  replaceNewLineWithSpace: true
@@ -3452,15 +3508,15 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3452
3508
  onClose();
3453
3509
  }
3454
3510
  };
3455
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material15.Dialog, { open, onClose: loading ? void 0 : onClose, maxWidth: "sm", fullWidth: true, children: [
3456
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material15.DialogTitle, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
3457
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_FileUpload2.default, { color: "primary" }),
3511
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material15.Dialog, { open, onClose: loading ? void 0 : onClose, maxWidth: "sm", fullWidth: true, children: [
3512
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material15.DialogTitle, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
3513
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_FileUpload2.default, { color: "primary" }),
3458
3514
  "Importar datos desde archivo"
3459
3515
  ] }),
3460
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material15.DialogContent, { dividers: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material15.Stack, { spacing: 3, sx: { mt: 1 }, children: [
3461
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material15.Box, { children: [
3462
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material15.Typography, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Seleccionar archivo" }),
3463
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3516
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material15.DialogContent, { dividers: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material15.Stack, { spacing: 3, sx: { mt: 1 }, children: [
3517
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material15.Box, { children: [
3518
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material15.Typography, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Seleccionar archivo" }),
3519
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3464
3520
  import_material15.Box,
3465
3521
  {
3466
3522
  sx: {
@@ -3473,7 +3529,7 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3473
3529
  position: "relative"
3474
3530
  },
3475
3531
  children: [
3476
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3532
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3477
3533
  "input",
3478
3534
  {
3479
3535
  type: "file",
@@ -3490,19 +3546,19 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3490
3546
  }
3491
3547
  }
3492
3548
  ),
3493
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material15.Typography, { variant: "body2", color: file ? "textPrimary" : "textSecondary", children: file ? file.name : "Haz clic aqu\xED para seleccionar un archivo" })
3549
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material15.Typography, { variant: "body2", color: file ? "textPrimary" : "textSecondary", children: file ? file.name : "Haz clic aqu\xED para seleccionar un archivo" })
3494
3550
  ]
3495
3551
  }
3496
3552
  )
3497
3553
  ] }),
3498
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material15.Divider, {}),
3499
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material15.Box, { children: [
3500
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material15.Typography, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Opciones de importaci\xF3n" }),
3501
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material15.Stack, { children: [
3502
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3554
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material15.Divider, {}),
3555
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material15.Box, { children: [
3556
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material15.Typography, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Opciones de importaci\xF3n" }),
3557
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material15.Stack, { children: [
3558
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3503
3559
  import_material15.FormControlLabel,
3504
3560
  {
3505
- control: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3561
+ control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3506
3562
  import_material15.Checkbox,
3507
3563
  {
3508
3564
  checked: options.skipUnknownFieldsAtImport,
@@ -3510,13 +3566,13 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3510
3566
  size: "small"
3511
3567
  }
3512
3568
  ),
3513
- label: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material15.Typography, { variant: "body2", children: "Omitir campos desconocidos al importar" })
3569
+ label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material15.Typography, { variant: "body2", children: "Omitir campos desconocidos al importar" })
3514
3570
  }
3515
3571
  ),
3516
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3572
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3517
3573
  import_material15.FormControlLabel,
3518
3574
  {
3519
- control: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3575
+ control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3520
3576
  import_material15.Checkbox,
3521
3577
  {
3522
3578
  checked: options.simplificateSpaces,
@@ -3524,13 +3580,13 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3524
3580
  size: "small"
3525
3581
  }
3526
3582
  ),
3527
- label: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material15.Typography, { variant: "body2", children: "Simplificar espacios" })
3583
+ label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material15.Typography, { variant: "body2", children: "Simplificar espacios" })
3528
3584
  }
3529
3585
  ),
3530
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3586
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3531
3587
  import_material15.FormControlLabel,
3532
3588
  {
3533
- control: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3589
+ control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3534
3590
  import_material15.Checkbox,
3535
3591
  {
3536
3592
  checked: options.replaceNewLineWithSpace,
@@ -3538,21 +3594,21 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3538
3594
  size: "small"
3539
3595
  }
3540
3596
  ),
3541
- label: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material15.Typography, { variant: "body2", children: "Reemplazar saltos de l\xEDnea con espacios" })
3597
+ label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material15.Typography, { variant: "body2", children: "Reemplazar saltos de l\xEDnea con espacios" })
3542
3598
  }
3543
3599
  )
3544
3600
  ] })
3545
3601
  ] })
3546
3602
  ] }) }),
3547
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material15.DialogActions, { sx: { px: 3, py: 2 }, children: [
3548
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material15.Button, { onClick: onClose, disabled: loading, children: "Cancelar" }),
3549
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3603
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material15.DialogActions, { sx: { px: 3, py: 2 }, children: [
3604
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material15.Button, { onClick: onClose, disabled: loading, children: "Cancelar" }),
3605
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3550
3606
  import_material15.Button,
3551
3607
  {
3552
3608
  onClick: handleConfirm,
3553
3609
  variant: "contained",
3554
3610
  disabled: !file || loading,
3555
- startIcon: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_FileUpload2.default, {}),
3611
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_FileUpload2.default, {}),
3556
3612
  children: loading ? "Procesando..." : "Confirmar Importaci\xF3n"
3557
3613
  }
3558
3614
  )
@@ -3561,26 +3617,27 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
3561
3617
  };
3562
3618
 
3563
3619
  // src/components/grid/ExportDialog.tsx
3564
- var import_react23 = require("react");
3620
+ var import_react24 = require("react");
3565
3621
  var import_material16 = require("@mui/material");
3566
3622
  var XLSX = __toESM(require("xlsx"), 1);
3567
3623
  var import_type_store5 = __toESM(require("type-store"), 1);
3568
- var import_jsx_runtime19 = require("react/jsx-runtime");
3624
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3569
3625
  var ExportDialog = ({
3570
3626
  open,
3571
3627
  onClose,
3572
3628
  tableDefinition,
3629
+ columnasOcultas,
3573
3630
  tableData,
3574
3631
  filteredRows,
3575
3632
  username = "anonymous"
3576
3633
  }) => {
3577
- const [format, setFormat] = (0, import_react23.useState)("xlsx");
3578
- const [options, setOptions] = (0, import_react23.useState)({
3634
+ const [format, setFormat] = (0, import_react24.useState)("xlsx");
3635
+ const [options, setOptions] = (0, import_react24.useState)({
3579
3636
  fromOtherTables: true,
3580
3637
  readOnly: true,
3581
3638
  hiddens: false
3582
3639
  });
3583
- const [isPreparing, setIsPreparing] = (0, import_react23.useState)(false);
3640
+ const [isPreparing, setIsPreparing] = (0, import_react24.useState)(false);
3584
3641
  const handleOptionChange = (event) => {
3585
3642
  setOptions({
3586
3643
  ...options,
@@ -3600,8 +3657,7 @@ var ExportDialog = ({
3600
3657
  };
3601
3658
  const executeExport = async () => {
3602
3659
  const fieldsDef2Export = tableDefinition.fields.filter((fieldDef) => {
3603
- const isVisible = fieldDef.visible !== false;
3604
- return (fieldDef.inTable !== false || options.fromOtherTables) && isVisible && (fieldDef.editable !== false || options.readOnly || tableDefinition.primaryKey?.includes(fieldDef.name)) && (isVisible || options.hiddens);
3660
+ return (fieldDef.inTable !== false || options.fromOtherTables) && campoDibujable(fieldDef) && (fieldDef.editable !== false || options.readOnly || tableDefinition.primaryKey?.includes(fieldDef.name)) && (!columnasOcultas.has(fieldDef.name) || options.hiddens);
3605
3661
  });
3606
3662
  if (format === "xlsx") {
3607
3663
  await excelExport(fieldsDef2Export);
@@ -3710,90 +3766,110 @@ var ExportDialog = ({
3710
3766
  URL.revokeObjectURL(url);
3711
3767
  }, 0);
3712
3768
  };
3713
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material16.Dialog, { open, onClose, maxWidth: "xs", fullWidth: true, children: [
3714
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.DialogTitle, { children: "Exportar Datos" }),
3715
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.DialogContent, { children: isPreparing ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material16.Box, { display: "flex", flexDirection: "column", alignItems: "center", py: 4, children: [
3716
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.CircularProgress, {}),
3717
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Typography, { sx: { mt: 2 }, children: "Preparando exportaci\xF3n..." })
3718
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material16.Box, { sx: { mt: 1 }, children: [
3719
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material16.FormControl, { component: "fieldset", children: [
3720
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.FormLabel, { component: "legend", children: "Formato" }),
3721
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3769
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material16.Dialog, { open, onClose, maxWidth: "xs", fullWidth: true, children: [
3770
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.DialogTitle, { children: "Exportar Datos" }),
3771
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.DialogContent, { children: isPreparing ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material16.Box, { display: "flex", flexDirection: "column", alignItems: "center", py: 4, children: [
3772
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.CircularProgress, {}),
3773
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Typography, { sx: { mt: 2 }, children: "Preparando exportaci\xF3n..." })
3774
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material16.Box, { sx: { mt: 1 }, children: [
3775
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material16.FormControl, { component: "fieldset", children: [
3776
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.FormLabel, { component: "legend", children: "Formato" }),
3777
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3722
3778
  import_material16.RadioGroup,
3723
3779
  {
3724
3780
  value: format,
3725
3781
  onChange: (e) => setFormat(e.target.value),
3726
3782
  children: [
3727
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.FormControlLabel, { value: "xlsx", control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Radio, {}), label: "Excel (.xlsx)" }),
3728
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.FormControlLabel, { value: "tab", control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Radio, {}), label: "Tabulado (.tab | )" }),
3729
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.FormControlLabel, { value: "csv", control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Radio, {}), label: "CSV (.csv , )" })
3783
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.FormControlLabel, { value: "xlsx", control: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Radio, {}), label: "Excel (.xlsx)" }),
3784
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.FormControlLabel, { value: "tab", control: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Radio, {}), label: "Tabulado (.tab | )" }),
3785
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.FormControlLabel, { value: "csv", control: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Radio, {}), label: "CSV (.csv , )" })
3730
3786
  ]
3731
3787
  }
3732
3788
  )
3733
3789
  ] }),
3734
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material16.Box, { sx: { mt: 3 }, children: [
3735
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Typography, { variant: "subtitle2", gutterBottom: true, children: "Opciones de campos:" }),
3736
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material16.FormGroup, { children: [
3737
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3790
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material16.Box, { sx: { mt: 3 }, children: [
3791
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Typography, { variant: "subtitle2", gutterBottom: true, children: "Opciones de campos:" }),
3792
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material16.FormGroup, { children: [
3793
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3738
3794
  import_material16.FormControlLabel,
3739
3795
  {
3740
- control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Checkbox, { checked: options.fromOtherTables, onChange: handleOptionChange, name: "fromOtherTables" }),
3796
+ control: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Checkbox, { checked: options.fromOtherTables, onChange: handleOptionChange, name: "fromOtherTables" }),
3741
3797
  label: "Desde otras tablas"
3742
3798
  }
3743
3799
  ),
3744
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3800
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3745
3801
  import_material16.FormControlLabel,
3746
3802
  {
3747
- control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Checkbox, { checked: options.readOnly, onChange: handleOptionChange, name: "readOnly" }),
3803
+ control: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Checkbox, { checked: options.readOnly, onChange: handleOptionChange, name: "readOnly" }),
3748
3804
  label: "Solo lectura"
3749
3805
  }
3750
3806
  ),
3751
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3807
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3752
3808
  import_material16.FormControlLabel,
3753
3809
  {
3754
- control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Checkbox, { checked: options.hiddens, onChange: handleOptionChange, name: "hiddens" }),
3810
+ control: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Checkbox, { checked: options.hiddens, onChange: handleOptionChange, name: "hiddens" }),
3755
3811
  label: "Ocultos"
3756
3812
  }
3757
3813
  )
3758
3814
  ] })
3759
3815
  ] })
3760
3816
  ] }) }),
3761
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material16.DialogActions, { children: [
3762
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Button, { onClick: onClose, disabled: isPreparing, children: "Cancelar" }),
3763
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Button, { onClick: handlePrepareExport, variant: "contained", disabled: isPreparing, children: "Descargar" })
3817
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material16.DialogActions, { children: [
3818
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Button, { onClick: onClose, disabled: isPreparing, children: "Cancelar" }),
3819
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Button, { onClick: handlePrepareExport, variant: "contained", disabled: isPreparing, children: "Descargar" })
3764
3820
  ] })
3765
3821
  ] });
3766
3822
  };
3767
3823
 
3768
- // src/pages/VerticalEditorPage.tsx
3769
- var import_react24 = require("react");
3824
+ // src/components/grid/DialogoDeColumnas.tsx
3770
3825
  var import_material17 = require("@mui/material");
3826
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3827
+ var DialogoDeColumnas = ({ open, onClose, columnas, ocultas, alternarColumna }) => {
3828
+ const lista = (titulo, nombres, idDeLista) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_material17.Box, { sx: { flex: 1, minWidth: 0 }, children: [
3829
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material17.Typography, { variant: "subtitle2", sx: { mb: 1 }, children: titulo }),
3830
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material17.List, { dense: true, "data-testid": idDeLista, sx: { maxHeight: 360, overflow: "auto", border: 1, borderColor: "divider", borderRadius: 1 }, children: nombres.map((nombre) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material17.ListItemButton, { onClick: () => alternarColumna(nombre), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material17.ListItemText, { primary: nombre }) }, nombre)) })
3831
+ ] });
3832
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_material17.Dialog, { open, onClose, maxWidth: "sm", fullWidth: true, children: [
3833
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material17.DialogTitle, { children: "Ocultar o mostrar columnas" }),
3834
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material17.DialogContent, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_material17.Box, { sx: { display: "flex", gap: 2, pt: 1 }, children: [
3835
+ lista("Columnas mostradas", columnas.filter((nombre) => !ocultas.has(nombre)), "columnas-mostradas"),
3836
+ lista("Columnas ocultas", columnas.filter((nombre) => ocultas.has(nombre)), "columnas-ocultas")
3837
+ ] }) }),
3838
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material17.DialogActions, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material17.Button, { onClick: onClose, children: "Cerrar" }) })
3839
+ ] });
3840
+ };
3841
+
3842
+ // src/pages/VerticalEditorPage.tsx
3843
+ var import_react25 = require("react");
3844
+ var import_material18 = require("@mui/material");
3771
3845
  var import_Close = __toESM(require("@mui/icons-material/Close"), 1);
3772
- var import_jsx_runtime20 = require("react/jsx-runtime");
3846
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3847
+ var SIN_OCULTAS = /* @__PURE__ */ new Set();
3773
3848
  var VerticalEditorPage = ({
3774
3849
  tableName,
3775
3850
  tableDefinition,
3776
3851
  initialData,
3777
3852
  fixedFields,
3853
+ columnasOcultas = SIN_OCULTAS,
3778
3854
  isNewRow = false,
3779
3855
  onSaveSuccess,
3780
3856
  onClose
3781
3857
  }) => {
3782
3858
  const { saveRecord } = useTableRecordSave();
3783
- const [internalIsNewRow, setInternalIsNewRow] = (0, import_react24.useState)(isNewRow);
3784
- const [formData, setFormData] = (0, import_react24.useState)(initialData);
3785
- const [lastSavedData, setLastSavedData] = (0, import_react24.useState)(initialData);
3786
- const [validityMap, setValidityMap] = (0, import_react24.useState)({});
3787
- const [globalError, setGlobalError] = (0, import_react24.useState)(null);
3788
- const [isSaving, setIsSaving] = (0, import_react24.useState)(false);
3789
- const [fieldFeedback, setFieldFeedback] = (0, import_react24.useState)({});
3790
- const feedbackTimersRef = (0, import_react24.useRef)({});
3791
- const handleFieldChange = (0, import_react24.useCallback)((fieldName, newValue, isValid) => {
3859
+ const [internalIsNewRow, setInternalIsNewRow] = (0, import_react25.useState)(isNewRow);
3860
+ const [formData, setFormData] = (0, import_react25.useState)(initialData);
3861
+ const [lastSavedData, setLastSavedData] = (0, import_react25.useState)(initialData);
3862
+ const [validityMap, setValidityMap] = (0, import_react25.useState)({});
3863
+ const [globalError, setGlobalError] = (0, import_react25.useState)(null);
3864
+ const [isSaving, setIsSaving] = (0, import_react25.useState)(false);
3865
+ const [fieldFeedback, setFieldFeedback] = (0, import_react25.useState)({});
3866
+ const feedbackTimersRef = (0, import_react25.useRef)({});
3867
+ const handleFieldChange = (0, import_react25.useCallback)((fieldName, newValue, isValid) => {
3792
3868
  setFormData((prev) => ({ ...prev, [fieldName]: newValue }));
3793
3869
  setValidityMap((prev) => ({ ...prev, [fieldName]: isValid }));
3794
3870
  setGlobalError(null);
3795
3871
  }, []);
3796
- const isFormValid = (0, import_react24.useMemo)(() => {
3872
+ const isFormValid = (0, import_react25.useMemo)(() => {
3797
3873
  for (const key in validityMap) {
3798
3874
  if (validityMap[key] === false) return false;
3799
3875
  }
@@ -3806,7 +3882,7 @@ var VerticalEditorPage = ({
3806
3882
  }
3807
3883
  return true;
3808
3884
  }, [formData, validityMap, tableDefinition.fields]);
3809
- const handleCommit = (0, import_react24.useCallback)(async (fieldName, newValue, isValid) => {
3885
+ const handleCommit = (0, import_react25.useCallback)(async (fieldName, newValue, isValid) => {
3810
3886
  if (!isValid) return;
3811
3887
  if (sameValue(newValue, lastSavedData[fieldName])) {
3812
3888
  return;
@@ -3896,21 +3972,21 @@ var VerticalEditorPage = ({
3896
3972
  tableDefinition,
3897
3973
  onSaveSuccess
3898
3974
  ]);
3899
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material17.Box, { sx: { p: 2, display: "flex", flexDirection: "column", height: "100%" }, children: [
3900
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material17.DialogTitle, { sx: { px: 0, pt: 0, display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
3901
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material17.Typography, { component: "div", variant: "h6", children: [
3975
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.Box, { sx: { p: 2, display: "flex", flexDirection: "column", height: "100%" }, children: [
3976
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.DialogTitle, { sx: { px: 0, pt: 0, display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
3977
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.Typography, { component: "div", variant: "h6", children: [
3902
3978
  isNewRow ? "Nuevo Registro" : "Editar Registro",
3903
3979
  " - ",
3904
3980
  tableDefinition.title || tableName
3905
3981
  ] }),
3906
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material17.IconButton, { onClick: onClose, size: "small", edge: "end", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Close.default, {}) })
3982
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.IconButton, { onClick: onClose, size: "small", edge: "end", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Close.default, {}) })
3907
3983
  ] }),
3908
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material17.DialogContent, { dividers: true, sx: { px: 2, flexGrow: 1, py: 1 }, children: [
3909
- globalError && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material17.Alert, { severity: "error", sx: { mb: 2 }, children: globalError }),
3910
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material17.Box, { sx: { display: "flex", flexDirection: "column", gap: 0.5 }, children: tableDefinition.fields.map((field) => {
3984
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.DialogContent, { dividers: true, sx: { px: 2, flexGrow: 1, py: 1 }, children: [
3985
+ globalError && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.Alert, { severity: "error", sx: { mb: 2 }, children: globalError }),
3986
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.Box, { sx: { display: "flex", flexDirection: "column", gap: 0.5 }, children: tableDefinition.fields.filter((field) => campoDibujable(field) && !columnasOcultas.has(field.name)).map((field) => {
3911
3987
  const isFixed = fixedFields?.some((ff) => ff.fieldName === field.name);
3912
3988
  const isMandatory = field.nullable === false || tableDefinition.primaryKey.includes(field.name);
3913
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material17.Box, { sx: { width: "100%", maxWidth: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3989
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.Box, { sx: { width: "100%", maxWidth: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3914
3990
  TypedField,
3915
3991
  {
3916
3992
  fieldDef: field,
@@ -3924,12 +4000,12 @@ var VerticalEditorPage = ({
3924
4000
  ) }, field.name);
3925
4001
  }) })
3926
4002
  ] }),
3927
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material17.DialogActions, { sx: { px: 0, pb: 0, pt: 2, justifyContent: "space-between", alignItems: "center" }, children: [
3928
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material17.Box, { children: [
3929
- isSaving && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material17.CircularProgress, { size: 20, sx: { ml: 2 } }),
3930
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { marginLeft: 10, fontSize: "0.8rem", color: "#666" }, children: isSaving ? "Guardando..." : "Cambios auto-guardados" })
4003
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.DialogActions, { sx: { px: 0, pb: 0, pt: 2, justifyContent: "space-between", alignItems: "center" }, children: [
4004
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.Box, { children: [
4005
+ isSaving && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.CircularProgress, { size: 20, sx: { ml: 2 } }),
4006
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { marginLeft: 10, fontSize: "0.8rem", color: "#666" }, children: isSaving ? "Guardando..." : "Cambios auto-guardados" })
3931
4007
  ] }),
3932
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material17.Button, { variant: "outlined", onClick: onClose, children: "Cerrar" })
4008
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.Button, { variant: "outlined", onClick: onClose, children: "Cerrar" })
3933
4009
  ] })
3934
4010
  ] });
3935
4011
  };
@@ -4007,7 +4083,7 @@ var baseDelBundler = import_meta2.env?.BASE_URL ?? "/";
4007
4083
  var rutaBase = baseDelBundler.replace(/\/+$/, "");
4008
4084
 
4009
4085
  // src/components/grid/GenericDataGrid.tsx
4010
- var import_jsx_runtime21 = require("react/jsx-runtime");
4086
+ var import_jsx_runtime23 = require("react/jsx-runtime");
4011
4087
  var SUMMARY_ROW_HEIGHT = 35;
4012
4088
  var FILTER_ROW_HEIGHT = 35;
4013
4089
  var HEADER_ROW_HEIGHT = 30;
@@ -4026,9 +4102,9 @@ var esColumnaPropia = (columna) => "customType" in columna;
4026
4102
  var SIN_ANCESTROS = [];
4027
4103
  var cargasEnCurso = /* @__PURE__ */ new Map();
4028
4104
  var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
4029
- const theme = (0, import_material18.useTheme)();
4105
+ const theme = (0, import_material19.useTheme)();
4030
4106
  const { tableDefinition, row } = ancestor;
4031
- const columns = (0, import_react25.useMemo)(() => {
4107
+ const columns = (0, import_react26.useMemo)(() => {
4032
4108
  const filteredFields = tableDefinition.fields.filter(
4033
4109
  (field) => !fieldsToHide?.some((ff) => ff.fieldName === field.name)
4034
4110
  );
@@ -4039,8 +4115,8 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
4039
4115
  name: field.label || cambiarGuionesBajosPorEspacios(field.name),
4040
4116
  width: 150,
4041
4117
  editable: false,
4042
- renderHeaderCell: () => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Box, { sx: { p: 0.5, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4043
- import_material18.Typography,
4118
+ renderHeaderCell: () => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Box, { sx: { p: 0.5, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4119
+ import_material19.Typography,
4044
4120
  {
4045
4121
  variant: "caption",
4046
4122
  sx: {
@@ -4051,11 +4127,11 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
4051
4127
  children: field.label || cambiarGuionesBajosPorEspacios(field.name)
4052
4128
  }
4053
4129
  ) }),
4054
- renderCell: (props) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Box, { sx: { px: 1, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Typography, { variant: "body2", sx: { fontSize: "0.875rem" }, noWrap: true, children: String(props.row[field.name] ?? "") }) })
4130
+ renderCell: (props) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Box, { sx: { px: 1, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Typography, { variant: "body2", sx: { fontSize: "0.875rem" }, noWrap: true, children: String(props.row[field.name] ?? "") }) })
4055
4131
  };
4056
4132
  });
4057
4133
  }, [tableDefinition, fieldsToHide]);
4058
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_material18.Box, { sx: {
4134
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material19.Box, { sx: {
4059
4135
  mb: 1.5,
4060
4136
  ml: index * 4,
4061
4137
  // El primer ancestro (index 0) no tiene margen, los siguientes sí
@@ -4066,7 +4142,7 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
4066
4142
  boxShadow: theme.shadows[1],
4067
4143
  bgcolor: "background.paper"
4068
4144
  }, children: [
4069
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Box, { sx: {
4145
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Box, { sx: {
4070
4146
  bgcolor: "primary.main",
4071
4147
  color: "primary.contrastText",
4072
4148
  px: 1.5,
@@ -4077,8 +4153,8 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
4077
4153
  alignItems: "center",
4078
4154
  fontWeight: "bold",
4079
4155
  gap: 1
4080
- }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Typography, { variant: "subtitle2", component: "div", children: cambiarGuionesBajosPorEspacios(ancestor.tableName) }) }),
4081
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4156
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Typography, { variant: "subtitle2", component: "div", children: cambiarGuionesBajosPorEspacios(ancestor.tableName) }) }),
4157
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4082
4158
  import_react_data_grid.DataGrid,
4083
4159
  {
4084
4160
  className: "rdg-light",
@@ -4111,42 +4187,48 @@ var GenericDataGrid = ({
4111
4187
  altoMaximoDetalle
4112
4188
  }) => {
4113
4189
  const claveFixedFields = JSON.stringify(fixedFieldsRecibidos ?? null);
4114
- const fixedFields = (0, import_react25.useMemo)(() => fixedFieldsRecibidos, [claveFixedFields]);
4190
+ const fixedFields = (0, import_react26.useMemo)(() => fixedFieldsRecibidos, [claveFixedFields]);
4115
4191
  const claveParametros = JSON.stringify([filterColumnsRecibidos ?? null, tableDefRecibido ?? null, parameterFunctionsRecibido ?? null, pickRecibido ?? null]);
4116
- const parametros = (0, import_react25.useMemo)(
4192
+ const parametros = (0, import_react26.useMemo)(
4117
4193
  () => ({ filterColumns: filterColumnsRecibidos, tableDef: tableDefRecibido, parameterFunctions: parameterFunctionsRecibido, pick: pickRecibido }),
4118
4194
  [claveParametros]
4119
4195
  // eslint-disable-line react-hooks/exhaustive-deps
4120
4196
  );
4121
- const cacheHeredado = (0, import_react25.useContext)(CacheGrillasContext);
4122
- const [cachePropio] = (0, import_react25.useState)(() => /* @__PURE__ */ new Map());
4197
+ const cacheHeredado = (0, import_react26.useContext)(CacheGrillasContext);
4198
+ const [cachePropio] = (0, import_react26.useState)(() => /* @__PURE__ */ new Map());
4123
4199
  const cache = cacheHeredado ?? cachePropio;
4124
- const [guardada] = (0, import_react25.useState)(() => claveCache ? cache.get(claveCache) : void 0);
4125
- const claveCargadaRef = (0, import_react25.useRef)(guardada ? `${tableName}|${claveFixedFields}|${claveParametros}` : null);
4126
- const [tableDefinition, setTableDefinition] = (0, import_react25.useState)(guardada?.tableDefinition ?? null);
4127
- const [tableData, setTableData] = (0, import_react25.useState)(guardada?.tableData ?? []);
4128
- const [cargandoInicial, setCargandoInicial] = (0, import_react25.useState)(!guardada);
4129
- const [errorDeCarga, setErrorDeCarga] = (0, import_react25.useState)(null);
4130
- const [anchosCalculados, setAnchosCalculados] = (0, import_react25.useState)(() => guardada?.anchosCalculados ?? /* @__PURE__ */ new Map());
4131
- const [detallesAbiertos, setDetallesAbiertos] = (0, import_react25.useState)(guardada?.detallesAbiertos ?? []);
4132
- const [altosDetalle, setAltosDetalle] = (0, import_react25.useState)(() => guardada?.altosDetalle ?? /* @__PURE__ */ new Map());
4133
- const [anchosDetalle, setAnchosDetalle] = (0, import_react25.useState)(() => /* @__PURE__ */ new Map());
4134
- const [selectedRows, setSelectedRows] = (0, import_react25.useState)(() => /* @__PURE__ */ new Set());
4135
- const [, setSelectedCell] = (0, import_react25.useState)(void 0);
4136
- const [estadoGrilla] = (0, import_react25.useState)(crearEstadoGrilla);
4137
- const theme = (0, import_material18.useTheme)();
4138
- const [openDataGridOptions, setOpenDataGridOptions] = (0, import_react25.useState)(false);
4139
- const [dataGridOptionsAnchorEl, setDataGridOptionsAnchorEl] = (0, import_react25.useState)(null);
4140
- const [exitingRowIds, setExitingRowIds] = (0, import_react25.useState)(/* @__PURE__ */ new Set());
4200
+ const [guardada] = (0, import_react26.useState)(() => claveCache ? cache.get(claveCache) : void 0);
4201
+ const claveCargadaRef = (0, import_react26.useRef)(guardada ? `${tableName}|${claveFixedFields}|${claveParametros}` : null);
4202
+ const [tableDefinition, setTableDefinition] = (0, import_react26.useState)(guardada?.tableDefinition ?? null);
4203
+ const [tableData, setTableData] = (0, import_react26.useState)(guardada?.tableData ?? []);
4204
+ const [cargandoInicial, setCargandoInicial] = (0, import_react26.useState)(!guardada);
4205
+ const [errorDeCarga, setErrorDeCarga] = (0, import_react26.useState)(null);
4206
+ const [anchosCalculados, setAnchosCalculados] = (0, import_react26.useState)(() => guardada?.anchosCalculados ?? /* @__PURE__ */ new Map());
4207
+ const [columnasOcultas, setColumnasOcultas] = (0, import_react26.useState)(() => guardada?.columnasOcultas ?? []);
4208
+ const [openDialogoDeColumnas, setOpenDialogoDeColumnas] = (0, import_react26.useState)(false);
4209
+ const conjuntoDeOcultas = (0, import_react26.useMemo)(() => new Set(columnasOcultas), [columnasOcultas]);
4210
+ const ocultarColumna = (0, import_react26.useCallback)((columna) => setColumnasOcultas((anteriores) => anteriores.includes(columna) ? anteriores : [...anteriores, columna]), []);
4211
+ const alternarColumna = (0, import_react26.useCallback)((columna) => setColumnasOcultas((anteriores) => anteriores.includes(columna) ? anteriores.filter((oculta) => oculta !== columna) : [...anteriores, columna]), []);
4212
+ const abrirDialogoDeColumnas = (0, import_react26.useCallback)(() => setOpenDialogoDeColumnas(true), []);
4213
+ const [detallesAbiertos, setDetallesAbiertos] = (0, import_react26.useState)(guardada?.detallesAbiertos ?? []);
4214
+ const [altosDetalle, setAltosDetalle] = (0, import_react26.useState)(() => guardada?.altosDetalle ?? /* @__PURE__ */ new Map());
4215
+ const [anchosDetalle, setAnchosDetalle] = (0, import_react26.useState)(() => /* @__PURE__ */ new Map());
4216
+ const [selectedRows, setSelectedRows] = (0, import_react26.useState)(() => /* @__PURE__ */ new Set());
4217
+ const [, setSelectedCell] = (0, import_react26.useState)(void 0);
4218
+ const [estadoGrilla] = (0, import_react26.useState)(crearEstadoGrilla);
4219
+ const theme = (0, import_material19.useTheme)();
4220
+ const [openDataGridOptions, setOpenDataGridOptions] = (0, import_react26.useState)(false);
4221
+ const [dataGridOptionsAnchorEl, setDataGridOptionsAnchorEl] = (0, import_react26.useState)(null);
4222
+ const [exitingRowIds, setExitingRowIds] = (0, import_react26.useState)(/* @__PURE__ */ new Set());
4141
4223
  const { showError } = useSnackbar();
4142
4224
  const { username: usuario } = useClientContext();
4143
- const dataGridRef = (0, import_react25.useRef)(null);
4144
- const rowAtEditStartRef = (0, import_react25.useRef)(null);
4145
- const [openImportDialog, setOpenImportDialog] = (0, import_react25.useState)(false);
4146
- const [openExportDialog, setOpenExportDialog] = (0, import_react25.useState)(false);
4147
- const [columnWidths, setColumnWidths] = (0, import_react25.useState)(() => /* @__PURE__ */ new Map());
4225
+ const dataGridRef = (0, import_react26.useRef)(null);
4226
+ const rowAtEditStartRef = (0, import_react26.useRef)(null);
4227
+ const [openImportDialog, setOpenImportDialog] = (0, import_react26.useState)(false);
4228
+ const [openExportDialog, setOpenExportDialog] = (0, import_react26.useState)(false);
4229
+ const [columnWidths, setColumnWidths] = (0, import_react26.useState)(() => /* @__PURE__ */ new Map());
4148
4230
  const { callApi, callApiUpload, loading } = useApiCall();
4149
- const primaryKey = (0, import_react25.useMemo)(() => {
4231
+ const primaryKey = (0, import_react26.useMemo)(() => {
4150
4232
  if (!tableDefinition) return ["id"];
4151
4233
  return tableDefinition.primaryKey && tableDefinition.primaryKey.length > 0 ? tableDefinition.primaryKey : ["id"];
4152
4234
  }, [tableDefinition]);
@@ -4165,9 +4247,9 @@ var GenericDataGrid = ({
4165
4247
  summaryData,
4166
4248
  resetView
4167
4249
  } = useGridDataView({ tableData, tableDefinition });
4168
- const abiertos = (0, import_react25.useMemo)(() => new Set(detallesAbiertos), [detallesAbiertos]);
4169
- const filasDetalleRef = (0, import_react25.useRef)(/* @__PURE__ */ new Map());
4170
- const filasMostradas = (0, import_react25.useMemo)(() => {
4250
+ const abiertos = (0, import_react26.useMemo)(() => new Set(detallesAbiertos), [detallesAbiertos]);
4251
+ const filasDetalleRef = (0, import_react26.useRef)(/* @__PURE__ */ new Map());
4252
+ const filasMostradas = (0, import_react26.useMemo)(() => {
4171
4253
  const detailTables = tableDefinition?.detailTables ?? [];
4172
4254
  if (abiertos.size === 0 || detailTables.length === 0) return filteredRows;
4173
4255
  const anteriores = filasDetalleRef.current;
@@ -4194,8 +4276,8 @@ var GenericDataGrid = ({
4194
4276
  filasDetalleRef.current = nuevas;
4195
4277
  return filas;
4196
4278
  }, [filteredRows, abiertos, tableDefinition, primaryKey]);
4197
- const altoDeDetalle = (0, import_react25.useCallback)((clave) => altosDetalle.get(clave) ?? ALTO_INICIAL_DETALLE, [altosDetalle]);
4198
- const altoDetalles = (0, import_react25.useMemo)(
4279
+ const altoDeDetalle = (0, import_react26.useCallback)((clave) => altosDetalle.get(clave) ?? ALTO_INICIAL_DETALLE, [altosDetalle]);
4280
+ const altoDetalles = (0, import_react26.useMemo)(
4199
4281
  () => filasMostradas.reduce((total, row) => esFilaDetalle(row) ? total + altoDeDetalle(row.clave) : total, 0),
4200
4282
  [filasMostradas, altoDeDetalle]
4201
4283
  );
@@ -4241,9 +4323,9 @@ var GenericDataGrid = ({
4241
4323
  filasVisiblesMax,
4242
4324
  conPie
4243
4325
  });
4244
- const [contenidoDeCelda, setContenidoDeCelda] = (0, import_react25.useState)(null);
4245
- const verContenido = (0, import_react25.useCallback)((anclaje, texto) => setContenidoDeCelda({ anclaje, texto }), []);
4246
- const cerrarContenidoDeCelda = (0, import_react25.useCallback)(() => {
4326
+ const [contenidoDeCelda, setContenidoDeCelda] = (0, import_react26.useState)(null);
4327
+ const verContenido = (0, import_react26.useCallback)((anclaje, texto) => setContenidoDeCelda({ anclaje, texto }), []);
4328
+ const cerrarContenidoDeCelda = (0, import_react26.useCallback)(() => {
4247
4329
  const anclaje = contenidoDeCelda?.anclaje;
4248
4330
  setContenidoDeCelda(null);
4249
4331
  setTimeout(() => anclaje?.focus(), 0);
@@ -4259,8 +4341,8 @@ var GenericDataGrid = ({
4259
4341
  setSortColumns,
4260
4342
  verContenido
4261
4343
  });
4262
- const tableNameAnteriorRef = (0, import_react25.useRef)(tableName);
4263
- (0, import_react25.useEffect)(() => {
4344
+ const tableNameAnteriorRef = (0, import_react26.useRef)(tableName);
4345
+ (0, import_react26.useEffect)(() => {
4264
4346
  if (tableNameAnteriorRef.current === tableName) return;
4265
4347
  tableNameAnteriorRef.current = tableName;
4266
4348
  setDetallesAbiertos([]);
@@ -4274,7 +4356,7 @@ var GenericDataGrid = ({
4274
4356
  setExitingRowIds(/* @__PURE__ */ new Set());
4275
4357
  setColumnWidths(/* @__PURE__ */ new Map());
4276
4358
  }, [tableName, estadoGrilla, resetView]);
4277
- (0, import_react25.useEffect)(() => {
4359
+ (0, import_react26.useEffect)(() => {
4278
4360
  const claveCarga = `${tableName}|${claveFixedFields}|${claveParametros}`;
4279
4361
  if (claveCargadaRef.current === claveCarga) {
4280
4362
  if (guardada) setSortColumns(guardada.sortColumns);
@@ -4322,6 +4404,7 @@ var GenericDataGrid = ({
4322
4404
  setTableDefinition(definition);
4323
4405
  setSortColumns(getInitialSortColumns(definition));
4324
4406
  setAnchosCalculados(calcularAnchosDeColumnas(definition, data));
4407
+ setColumnasOcultas(columnasOcultasIniciales(definition));
4325
4408
  setTableData(data);
4326
4409
  const filasDeFiltros = parametros.filterColumns ?? aFiltrosIniciales(definition.filterColumns);
4327
4410
  if (filasDeFiltros.length > 1) console.warn(`'${tableName}': varias filas de filtros (alternativas) todav\xEDa no est\xE1n soportadas; se aplica la primera`);
@@ -4342,11 +4425,11 @@ var GenericDataGrid = ({
4342
4425
  vigente = false;
4343
4426
  };
4344
4427
  }, [tableName, claveFixedFields, fixedFields, claveParametros, parametros, showError, callApi, getInitialSortColumns, setSortColumns, aplicarFiltrosIniciales, guardada]);
4345
- (0, import_react25.useEffect)(() => {
4428
+ (0, import_react26.useEffect)(() => {
4346
4429
  if (!claveCache || !tableDefinition || cargandoInicial) return;
4347
- cache.set(claveCache, { tableDefinition, tableData, anchosCalculados, sortColumns, detallesAbiertos, altosDetalle });
4348
- }, [cache, claveCache, tableDefinition, tableData, anchosCalculados, sortColumns, detallesAbiertos, altosDetalle, cargandoInicial]);
4349
- (0, import_react25.useEffect)(() => {
4430
+ cache.set(claveCache, { tableDefinition, tableData, anchosCalculados, columnasOcultas, sortColumns, detallesAbiertos, altosDetalle });
4431
+ }, [cache, claveCache, tableDefinition, tableData, anchosCalculados, columnasOcultas, sortColumns, detallesAbiertos, altosDetalle, cargandoInicial]);
4432
+ (0, import_react26.useEffect)(() => {
4350
4433
  let timer = null;
4351
4434
  const desuscribir = estadoGrilla.suscribir(() => {
4352
4435
  const hayExitos = Array.from(estadoGrilla.obtenerFeedback().values()).some((f) => f.type === "success");
@@ -4371,11 +4454,11 @@ var GenericDataGrid = ({
4371
4454
  if (timer) clearTimeout(timer);
4372
4455
  };
4373
4456
  }, [estadoGrilla]);
4374
- const resetSortingDeLaTabla = (0, import_react25.useCallback)(() => {
4457
+ const resetSortingDeLaTabla = (0, import_react26.useCallback)(() => {
4375
4458
  if (tableDefinition) resetSorting(tableDefinition);
4376
4459
  }, [tableDefinition, resetSorting]);
4377
- const abrirImportacion = (0, import_react25.useCallback)(() => setOpenImportDialog(true), []);
4378
- const abrirExportacion = (0, import_react25.useCallback)(() => setOpenExportDialog(true), []);
4460
+ const abrirImportacion = (0, import_react26.useCallback)(() => setOpenImportDialog(true), []);
4461
+ const abrirExportacion = (0, import_react26.useCallback)(() => setOpenExportDialog(true), []);
4379
4462
  const { menuOptions } = useGridMenu({
4380
4463
  tableDefinition,
4381
4464
  tableName,
@@ -4384,13 +4467,14 @@ var GenericDataGrid = ({
4384
4467
  callApi,
4385
4468
  resetSorting: tableDefinition ? resetSortingDeLaTabla : void 0,
4386
4469
  triggerImport: abrirImportacion,
4387
- triggerExport: abrirExportacion
4470
+ triggerExport: abrirExportacion,
4471
+ abrirColumnas: abrirDialogoDeColumnas
4388
4472
  });
4389
- const abrirOpcionesDeGrilla = (0, import_react25.useCallback)((anchorEl) => {
4473
+ const abrirOpcionesDeGrilla = (0, import_react26.useCallback)((anchorEl) => {
4390
4474
  setDataGridOptionsAnchorEl(anchorEl);
4391
4475
  setOpenDataGridOptions(true);
4392
4476
  }, []);
4393
- const editarEnFicha = (0, import_react25.useCallback)((row) => {
4477
+ const editarEnFicha = (0, import_react26.useCallback)((row) => {
4394
4478
  rowAtEditStartRef.current = { ...row };
4395
4479
  handleVerticalEditRow(row);
4396
4480
  }, [handleVerticalEditRow]);
@@ -4398,6 +4482,8 @@ var GenericDataGrid = ({
4398
4482
  tableDefinition,
4399
4483
  anchosCalculados,
4400
4484
  fixedFields,
4485
+ columnasOcultas: conjuntoDeOcultas,
4486
+ ocultarColumna,
4401
4487
  primaryKey,
4402
4488
  setTableData,
4403
4489
  handleKeyPressInEditor,
@@ -4408,7 +4494,7 @@ var GenericDataGrid = ({
4408
4494
  toggleFilterVisibility,
4409
4495
  abrirOpcionesDeGrilla
4410
4496
  });
4411
- const abrirDetalleEnPestana = (0, import_react25.useCallback)((row, detailTable) => {
4497
+ const abrirDetalleEnPestana = (0, import_react26.useCallback)((row, detailTable) => {
4412
4498
  if (!onOpenDetail || !tableDefinition || !detailTable.table) return;
4413
4499
  const porCampo = /* @__PURE__ */ new Map();
4414
4500
  [...fixedFields ?? [], ...calcularFixedFieldsDetalle(detailTable, row)].forEach((ff) => porCampo.set(ff.fieldName, ff));
@@ -4418,12 +4504,12 @@ var GenericDataGrid = ({
4418
4504
  const newAncestors = [...ancestors, { tableName: tableDefinition.name, row, tableDefinition, fixedFields: allFixedFields }];
4419
4505
  onOpenDetail(detailTable.table, allFixedFields, label, newAncestors);
4420
4506
  }, [onOpenDetail, tableDefinition, fixedFields, ancestors]);
4421
- const abrirWScreenEnPestana = (0, import_react25.useCallback)((row, detailTable) => {
4507
+ const abrirWScreenEnPestana = (0, import_react26.useCallback)((row, detailTable) => {
4422
4508
  const parametros2 = new URLSearchParams();
4423
4509
  calcularFixedFieldsDetalle(detailTable, row).forEach((ff) => parametros2.set(ff.fieldName, String(ff.value)));
4424
4510
  window.open(`${window.location.origin}${rutaBase}/wScreens/${detailTable.wScreen}?${parametros2}`, "_blank");
4425
4511
  }, []);
4426
- const alternarDetalle = (0, import_react25.useCallback)((row, rowId, detailTable, enOtraPestana) => {
4512
+ const alternarDetalle = (0, import_react26.useCallback)((row, rowId, detailTable, enOtraPestana) => {
4427
4513
  if (enOtraPestana && detailTable.wScreen) {
4428
4514
  abrirWScreenEnPestana(row, detailTable);
4429
4515
  return;
@@ -4435,8 +4521,8 @@ var GenericDataGrid = ({
4435
4521
  const clave = claveDetalle(rowId, detailTable);
4436
4522
  setDetallesAbiertos((anteriores) => anteriores.includes(clave) ? anteriores.filter((c) => c !== clave) : [...anteriores, clave]);
4437
4523
  }, [onOpenDetail, abrirDetalleEnPestana, abrirWScreenEnPestana]);
4438
- const [medidas, setMedidas] = (0, import_react25.useState)(null);
4439
- (0, import_react25.useEffect)(() => {
4524
+ const [medidas, setMedidas] = (0, import_react26.useState)(null);
4525
+ (0, import_react26.useEffect)(() => {
4440
4526
  const elemento = dataGridRef.current?.element;
4441
4527
  if (!elemento) return;
4442
4528
  const medir = () => setMedidas((anteriores) => {
@@ -4449,8 +4535,8 @@ var GenericDataGrid = ({
4449
4535
  return () => observador.disconnect();
4450
4536
  }, [tableDefinition, cargandoInicial]);
4451
4537
  const anchoVisible = medidas?.ancho ?? null;
4452
- const [altoDeVentana, setAltoDeVentana] = (0, import_react25.useState)(null);
4453
- (0, import_react25.useEffect)(() => {
4538
+ const [altoDeVentana, setAltoDeVentana] = (0, import_react26.useState)(null);
4539
+ (0, import_react26.useEffect)(() => {
4454
4540
  if (anidada) return;
4455
4541
  const elemento = dataGridRef.current?.element;
4456
4542
  if (!elemento) return;
@@ -4459,25 +4545,25 @@ var GenericDataGrid = ({
4459
4545
  window.addEventListener("resize", calcular);
4460
4546
  return () => window.removeEventListener("resize", calcular);
4461
4547
  }, [anidada, tableDefinition, cargandoInicial]);
4462
- const altoDeContexto = (0, import_react25.useContext)(AltoDisponibleContext);
4548
+ const altoDeContexto = (0, import_react26.useContext)(AltoDisponibleContext);
4463
4549
  const altoDeEstaGrilla = anidada ? altoDisponible ?? (altoDeContexto === void 0 ? void 0 : altoDeContexto - ALTO_TITULO_ANIDADA) : altoDeVentana ?? void 0;
4464
4550
  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);
4465
- const cambiarAnchoDetalle = (0, import_react25.useCallback)((clave, ancho) => {
4551
+ const cambiarAnchoDetalle = (0, import_react26.useCallback)((clave, ancho) => {
4466
4552
  setAnchosDetalle((anteriores) => anteriores.get(clave) === ancho ? anteriores : new Map(anteriores).set(clave, ancho));
4467
4553
  }, []);
4468
- const cambiarAltoDetalle = (0, import_react25.useCallback)((clave, altoDeseado2) => {
4554
+ const cambiarAltoDetalle = (0, import_react26.useCallback)((clave, altoDeseado2) => {
4469
4555
  const alto = Math.min(Math.max(Math.round(altoDeseado2), ALTO_MINIMO_DETALLE), altoMaximoDetalleEfectivo ?? Infinity);
4470
4556
  setAltosDetalle((anteriores) => anteriores.get(clave) === alto ? anteriores : new Map(anteriores).set(clave, alto));
4471
4557
  }, [altoMaximoDetalleEfectivo]);
4472
- const renderDetalle = (0, import_react25.useCallback)((fila) => {
4558
+ const renderDetalle = (0, import_react26.useCallback)((fila) => {
4473
4559
  const { detailTable } = fila;
4474
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4560
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4475
4561
  "div",
4476
4562
  {
4477
4563
  className: "fpr-detalle",
4478
4564
  style: { maxWidth: anchoVisible ? anchoVisible - 2 : void 0 },
4479
4565
  onKeyDown: (e) => e.stopPropagation(),
4480
- children: detailTable.table ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4566
+ children: detailTable.table ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4481
4567
  GenericDataGrid,
4482
4568
  {
4483
4569
  tableName: detailTable.table,
@@ -4490,7 +4576,7 @@ var GenericDataGrid = ({
4490
4576
  onOpenDetail,
4491
4577
  ancestors: tableDefinition ? [...ancestors, { tableName: tableDefinition.name, row: fila.filaPadre, tableDefinition, fixedFields: fila.fixedFields }] : ancestors
4492
4578
  }
4493
- ) : detailTable.wScreen ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4579
+ ) : detailTable.wScreen ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4494
4580
  DetalleWScreen,
4495
4581
  {
4496
4582
  fila,
@@ -4498,7 +4584,7 @@ var GenericDataGrid = ({
4498
4584
  onAlto: (alto) => cambiarAltoDetalle(fila.clave, alto),
4499
4585
  onAncho: (ancho) => cambiarAnchoDetalle(fila.clave, ancho)
4500
4586
  }
4501
- ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_material18.Alert, { severity: "warning", children: [
4587
+ ) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material19.Alert, { severity: "warning", children: [
4502
4588
  "El detalle '",
4503
4589
  detailTable.abr,
4504
4590
  "' no tiene ni tabla ni wScreen."
@@ -4506,18 +4592,18 @@ var GenericDataGrid = ({
4506
4592
  }
4507
4593
  );
4508
4594
  }, [anchoVisible, claveCache, tableName, cambiarAltoDetalle, cambiarAnchoDetalle, altoMaximoDetalleEfectivo, onOpenDetail, tableDefinition, ancestors]);
4509
- const detallesGrilla = (0, import_react25.useMemo)(() => ({ abiertos, alternarDetalle, renderDetalle }), [abiertos, alternarDetalle, renderDetalle]);
4595
+ const detallesGrilla = (0, import_react26.useMemo)(() => ({ abiertos, alternarDetalle, renderDetalle }), [abiertos, alternarDetalle, renderDetalle]);
4510
4596
  const altoDeseado = cargandoInicial ? ALTO_INICIAL_DETALLE : gridHeight + ALTO_TITULO_ANIDADA + 8;
4511
- (0, import_react25.useEffect)(() => {
4597
+ (0, import_react26.useEffect)(() => {
4512
4598
  onAltoDeseado?.(altoDeseado);
4513
4599
  }, [onAltoDeseado, altoDeseado]);
4514
- const rowKeyGetter = (0, import_react25.useCallback)((row) => esFilaDetalle(row) ? `detalle:${row.clave}` : getPrimaryKeyValues(row, primaryKey), [primaryKey]);
4515
- const rowHeight = (0, import_react25.useCallback)((row) => esFilaDetalle(row) ? altoDeDetalle(row.clave) : ROW_HEIGHT, [altoDeDetalle]);
4516
- const rowClass = (0, import_react25.useCallback)(
4600
+ const rowKeyGetter = (0, import_react26.useCallback)((row) => esFilaDetalle(row) ? `detalle:${row.clave}` : getPrimaryKeyValues(row, primaryKey), [primaryKey]);
4601
+ const rowHeight = (0, import_react26.useCallback)((row) => esFilaDetalle(row) ? altoDeDetalle(row.clave) : ROW_HEIGHT, [altoDeDetalle]);
4602
+ const rowClass = (0, import_react26.useCallback)(
4517
4603
  (row) => esFilaDetalle(row) ? "fpr-fila-detalle" : exitingRowIds.has(getPrimaryKeyValues(row, primaryKey)) ? "fpr-fila-saliendo" : void 0,
4518
4604
  [exitingRowIds, primaryKey]
4519
4605
  );
4520
- const anchoContenido = (0, import_react25.useMemo)(() => {
4606
+ const anchoContenido = (0, import_react26.useMemo)(() => {
4521
4607
  if (!anidada || columns.length === 0) return void 0;
4522
4608
  const sumaColumnas = columns.reduce((total, col) => {
4523
4609
  const medido = columnWidths.get(col.key)?.width;
@@ -4527,12 +4613,12 @@ var GenericDataGrid = ({
4527
4613
  const anchoDetalleMax = detallesAbiertos.reduce((max, clave) => Math.max(max, anchosDetalle.get(clave) ?? 0), 0);
4528
4614
  return Math.max(ANCHO_MINIMO_ANIDADA, propio, anchoDetalleMax > 0 ? anchoDetalleMax + SANGRIA_DETALLE + (medidas?.barra ?? 0) + 2 : 0);
4529
4615
  }, [anidada, columns, columnWidths, medidas?.barra, detallesAbiertos, anchosDetalle]);
4530
- (0, import_react25.useEffect)(() => {
4616
+ (0, import_react26.useEffect)(() => {
4531
4617
  if (anchoContenido !== void 0) onAnchoDeseado?.(anchoContenido);
4532
4618
  }, [onAnchoDeseado, anchoContenido]);
4533
- const estiloGrilla = (0, import_react25.useMemo)(() => ({ height: "100%", width: "100%", boxSizing: "border-box", ...gridStyles }), [gridStyles]);
4534
- const bottomSummaryRows = (0, import_react25.useMemo)(() => conPie ? [bottomSummaryRow] : [], [conPie, bottomSummaryRow]);
4535
- const vistaGrilla = (0, import_react25.useMemo)(() => ({ isFilterRowVisible }), [isFilterRowVisible]);
4619
+ const estiloGrilla = (0, import_react26.useMemo)(() => ({ height: "100%", width: "100%", boxSizing: "border-box", ...gridStyles }), [gridStyles]);
4620
+ const bottomSummaryRows = (0, import_react26.useMemo)(() => conPie ? [bottomSummaryRow] : [], [conPie, bottomSummaryRow]);
4621
+ const vistaGrilla = (0, import_react26.useMemo)(() => ({ isFilterRowVisible }), [isFilterRowVisible]);
4536
4622
  const getFallBackMessage = () => {
4537
4623
  if (tableData.length === 0) {
4538
4624
  return "No hay filas para mostrar";
@@ -4544,19 +4630,19 @@ var GenericDataGrid = ({
4544
4630
  };
4545
4631
  const fallBackMessage = getFallBackMessage();
4546
4632
  if (cargandoInicial) {
4547
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_material18.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: [
4548
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.CircularProgress, {}),
4549
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Typography, { variant: "h6", sx: { ml: 2 }, children: "Cargando tabla..." })
4633
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material19.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: [
4634
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.CircularProgress, {}),
4635
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Typography, { variant: "h6", sx: { ml: 2 }, children: "Cargando tabla..." })
4550
4636
  ] });
4551
4637
  }
4552
4638
  if (errorDeCarga) {
4553
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Alert, { severity: "error", children: errorDeCarga }) });
4639
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Alert, { severity: "error", children: errorDeCarga }) });
4554
4640
  }
4555
4641
  if (!tableDefinition) {
4556
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Alert, { severity: "warning", children: "No se pudo cargar la definici\xF3n de la tabla." }) });
4642
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Alert, { severity: "warning", children: "No se pudo cargar la definici\xF3n de la tabla." }) });
4557
4643
  }
4558
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CacheGrillasContext.Provider, { value: cache, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_material18.Box, { sx: { pt: anidada ? 0 : 2, display: "flex", flexDirection: "column", height: "100%", boxSizing: "border-box", width: anchoContenido ?? void 0, maxWidth: "100%" }, children: [
4559
- !anidada && ancestors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Box, { sx: { px: 2, pt: 0, pb: 1, display: "flex", flexDirection: "column" }, children: ancestors.map((ancestor, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4644
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CacheGrillasContext.Provider, { value: cache, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material19.Box, { sx: { pt: anidada ? 0 : 2, display: "flex", flexDirection: "column", height: "100%", boxSizing: "border-box", width: anchoContenido ?? void 0, maxWidth: "100%" }, children: [
4645
+ !anidada && ancestors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Box, { sx: { px: 2, pt: 0, pb: 1, display: "flex", flexDirection: "column" }, children: ancestors.map((ancestor, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4560
4646
  StaticAncestorGrid,
4561
4647
  {
4562
4648
  ancestor,
@@ -4565,8 +4651,8 @@ var GenericDataGrid = ({
4565
4651
  },
4566
4652
  index
4567
4653
  )) }),
4568
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4569
- import_material18.Box,
4654
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4655
+ import_material19.Box,
4570
4656
  {
4571
4657
  sx: {
4572
4658
  backgroundColor: theme.palette.primary.main,
@@ -4588,17 +4674,17 @@ var GenericDataGrid = ({
4588
4674
  gap: 1
4589
4675
  },
4590
4676
  children: [
4591
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_material18.Typography, { variant: "subtitle2", component: "div", children: [
4677
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material19.Typography, { variant: "subtitle2", component: "div", children: [
4592
4678
  titulo ?? cambiarGuionesBajosPorEspacios(tableDefinition.title || tableDefinition.name),
4593
4679
  " - ",
4594
4680
  filteredRows.length === tableData.length ? `${tableData.length} registros` : `${filteredRows.length} (F)`
4595
4681
  ] }),
4596
- loading && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.CircularProgress, { size: 14, color: "inherit" })
4682
+ loading && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.CircularProgress, { size: 14, color: "inherit" })
4597
4683
  ]
4598
4684
  }
4599
4685
  ),
4600
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4601
- import_material18.Box,
4686
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4687
+ import_material19.Box,
4602
4688
  {
4603
4689
  sx: {
4604
4690
  // Una grilla anidada se acota con px (el alto que le dio la de arriba, o el de una wScreen): una wScreen
@@ -4616,7 +4702,7 @@ var GenericDataGrid = ({
4616
4702
  pb: anidada ? 0 : 3
4617
4703
  },
4618
4704
  children: [
4619
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EstadoGrillaContext.Provider, { value: estadoGrilla, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(VistaGrillaContext.Provider, { value: vistaGrilla, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DetallesGrillaContext.Provider, { value: detallesGrilla, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4705
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EstadoGrillaContext.Provider, { value: estadoGrilla, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(VistaGrillaContext.Provider, { value: vistaGrilla, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DetallesGrillaContext.Provider, { value: detallesGrilla, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4620
4706
  import_react_data_grid.DataGrid,
4621
4707
  {
4622
4708
  className: "rdg-light",
@@ -4646,8 +4732,8 @@ var GenericDataGrid = ({
4646
4732
  onCellKeyDown: handleCellKeyDown
4647
4733
  }
4648
4734
  ) }) }) }),
4649
- fallBackMessage && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4650
- import_material18.Box,
4735
+ fallBackMessage && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4736
+ import_material19.Box,
4651
4737
  {
4652
4738
  sx: {
4653
4739
  position: "absolute",
@@ -4663,24 +4749,35 @@ var GenericDataGrid = ({
4663
4749
  zIndex: tableData.length === 0 ? 10 : 1
4664
4750
  // Mantenemos el zIndex superior para el estado vacío total
4665
4751
  },
4666
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Typography, { variant: "body2", color: "textSecondary", children: fallBackMessage })
4752
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Typography, { variant: "body2", color: "textSecondary", children: fallBackMessage })
4667
4753
  }
4668
4754
  )
4669
4755
  ]
4670
4756
  }
4671
4757
  ),
4672
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4758
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4673
4759
  ExportDialog,
4674
4760
  {
4675
4761
  open: openExportDialog,
4676
4762
  onClose: () => setOpenExportDialog(false),
4677
4763
  tableDefinition,
4764
+ columnasOcultas: conjuntoDeOcultas,
4678
4765
  tableData,
4679
4766
  filteredRows,
4680
4767
  username: usuario || "anonymous"
4681
4768
  }
4682
4769
  ),
4683
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4770
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4771
+ DialogoDeColumnas,
4772
+ {
4773
+ open: openDialogoDeColumnas,
4774
+ onClose: () => setOpenDialogoDeColumnas(false),
4775
+ columnas: (tableDefinition?.fields ?? []).filter(campoDibujable).map((field) => field.name).filter((nombre) => !columnaOcultaPorFixedField(fixedFields, nombre)),
4776
+ ocultas: conjuntoDeOcultas,
4777
+ alternarColumna
4778
+ }
4779
+ ),
4780
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4684
4781
  ConfirmDialog,
4685
4782
  {
4686
4783
  open: openConfirmDialog,
@@ -4689,7 +4786,7 @@ var GenericDataGrid = ({
4689
4786
  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."
4690
4787
  }
4691
4788
  ),
4692
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4789
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4693
4790
  DataGridOptionsDialog,
4694
4791
  {
4695
4792
  open: openDataGridOptions,
@@ -4698,7 +4795,7 @@ var GenericDataGrid = ({
4698
4795
  anchorEl: dataGridOptionsAnchorEl
4699
4796
  }
4700
4797
  ),
4701
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4798
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4702
4799
  ImportDialog,
4703
4800
  {
4704
4801
  open: openImportDialog,
@@ -4707,20 +4804,21 @@ var GenericDataGrid = ({
4707
4804
  loading
4708
4805
  }
4709
4806
  ),
4710
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4711
- import_material18.Dialog,
4807
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4808
+ import_material19.Dialog,
4712
4809
  {
4713
4810
  open: openVerticalEditDialog,
4714
4811
  onClose: () => setOpenVerticalEditDialog(false),
4715
4812
  maxWidth: "sm",
4716
4813
  fullWidth: true,
4717
- children: rowToEditVertical && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4814
+ children: rowToEditVertical && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4718
4815
  VerticalEditorPage,
4719
4816
  {
4720
4817
  tableName,
4721
4818
  tableDefinition,
4722
4819
  initialData: rowToEditVertical,
4723
4820
  fixedFields,
4821
+ columnasOcultas: conjuntoDeOcultas,
4724
4822
  isNewRow: !!rowToEditVertical[NEW_ROW_INDICATOR],
4725
4823
  onSaveSuccess: (savedRow, isNewItem) => {
4726
4824
  setRowToEditVertical(savedRow);
@@ -4759,28 +4857,28 @@ var GenericDataGrid = ({
4759
4857
  )
4760
4858
  }
4761
4859
  ),
4762
- contenidoDeCelda && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(VentanaDeTexto, { anclaje: contenidoDeCelda.anclaje, texto: contenidoDeCelda.texto, editable: false, onAceptar: cerrarContenidoDeCelda, onCerrar: cerrarContenidoDeCelda })
4860
+ contenidoDeCelda && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(VentanaDeTexto, { anclaje: contenidoDeCelda.anclaje, texto: contenidoDeCelda.texto, editable: false, onAceptar: cerrarContenidoDeCelda, onCerrar: cerrarContenidoDeCelda })
4763
4861
  ] }) });
4764
4862
  };
4765
4863
  var GenericDataGrid_default = GenericDataGrid;
4766
4864
 
4767
4865
  // src/App.tsx
4768
- var import_react42 = __toESM(require("react"), 1);
4866
+ var import_react43 = __toESM(require("react"), 1);
4769
4867
  var import_react_router_dom15 = require("react-router-dom");
4770
4868
 
4771
4869
  // src/components/MainLayout.tsx
4772
- var import_react29 = require("react");
4870
+ var import_react30 = require("react");
4773
4871
  var import_react_router_dom4 = require("react-router-dom");
4774
- var import_material20 = require("@mui/material");
4872
+ var import_material21 = require("@mui/material");
4775
4873
 
4776
4874
  // src/contexts/AppContext.tsx
4777
- var import_react26 = require("react");
4875
+ var import_react27 = require("react");
4778
4876
  var import_react_router_dom = require("react-router-dom");
4779
4877
  var import_react_redux2 = require("react-redux");
4780
- var import_jsx_runtime22 = require("react/jsx-runtime");
4781
- var AuthContext = (0, import_react26.createContext)(void 0);
4878
+ var import_jsx_runtime24 = require("react/jsx-runtime");
4879
+ var AuthContext = (0, import_react27.createContext)(void 0);
4782
4880
  var useApp = () => {
4783
- const context = (0, import_react26.useContext)(AuthContext);
4881
+ const context = (0, import_react27.useContext)(AuthContext);
4784
4882
  if (!context) {
4785
4883
  throw new Error("useApp must be used within an AppProvider");
4786
4884
  }
@@ -4789,15 +4887,15 @@ var useApp = () => {
4789
4887
  };
4790
4888
  var AppProvider = ({ children, publicPaths = [] }) => {
4791
4889
  console.log("AppProvider rendered/re-rendered");
4792
- const [isLoggedIn, setIsLoggedIn] = (0, import_react26.useState)(false);
4793
- const [showSessionExpiredMessage, setShowSessionExpiredMessage] = (0, import_react26.useState)(false);
4794
- const isRedirectingRef = (0, import_react26.useRef)(false);
4795
- const huboSesionRef = (0, import_react26.useRef)(false);
4890
+ const [isLoggedIn, setIsLoggedIn] = (0, import_react27.useState)(false);
4891
+ const [showSessionExpiredMessage, setShowSessionExpiredMessage] = (0, import_react27.useState)(false);
4892
+ const isRedirectingRef = (0, import_react27.useRef)(false);
4893
+ const huboSesionRef = (0, import_react27.useRef)(false);
4796
4894
  const dispatch = (0, import_react_redux2.useDispatch)();
4797
4895
  const clientContext = (0, import_react_redux2.useSelector)((state) => state.clientContext);
4798
4896
  if (clientContext.status === "succeeded") huboSesionRef.current = true;
4799
4897
  const navigate = (0, import_react_router_dom.useNavigate)();
4800
- const handleExpiredSessionRedirect = (0, import_react26.useCallback)(() => {
4898
+ const handleExpiredSessionRedirect = (0, import_react27.useCallback)(() => {
4801
4899
  isRedirectingRef.current = true;
4802
4900
  setShowSessionExpiredMessage(false);
4803
4901
  setIsLoggedIn(false);
@@ -4807,11 +4905,11 @@ var AppProvider = ({ children, publicPaths = [] }) => {
4807
4905
  }, 2e3);
4808
4906
  }, [navigate]);
4809
4907
  const location = (0, import_react_router_dom.useLocation)();
4810
- const isCurrentPathPublic = (0, import_react26.useCallback)(() => {
4908
+ const isCurrentPathPublic = (0, import_react27.useCallback)(() => {
4811
4909
  const current = location.pathname;
4812
4910
  return publicPaths.some((path) => current === path || current.startsWith(`${path}/`));
4813
4911
  }, [location.pathname, publicPaths]);
4814
- const checkSession = (0, import_react26.useCallback)(async () => {
4912
+ const checkSession = (0, import_react27.useCallback)(async () => {
4815
4913
  if (isRedirectingRef.current) return;
4816
4914
  try {
4817
4915
  const response = await fetchApi("/keep-alive.json", { method: "GET" });
@@ -4849,14 +4947,14 @@ var AppProvider = ({ children, publicPaths = [] }) => {
4849
4947
  }
4850
4948
  }
4851
4949
  }, [dispatch, clientContext.status, showSessionExpiredMessage, isCurrentPathPublic]);
4852
- (0, import_react26.useEffect)(() => {
4950
+ (0, import_react27.useEffect)(() => {
4853
4951
  checkSession();
4854
4952
  const intervalId = setInterval(checkSession, 15 * 1e3);
4855
4953
  return () => {
4856
4954
  clearInterval(intervalId);
4857
4955
  };
4858
4956
  }, [checkSession]);
4859
- const authContextValue = (0, import_react26.useMemo)(() => ({
4957
+ const authContextValue = (0, import_react27.useMemo)(() => ({
4860
4958
  isLoggedIn,
4861
4959
  setIsLoggedIn,
4862
4960
  checkSession,
@@ -4871,7 +4969,7 @@ var AppProvider = ({ children, publicPaths = [] }) => {
4871
4969
  setShowSessionExpiredMessage,
4872
4970
  handleExpiredSessionRedirect
4873
4971
  ]);
4874
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AuthContext.Provider, { value: authContextValue, children });
4972
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AuthContext.Provider, { value: authContextValue, children });
4875
4973
  };
4876
4974
 
4877
4975
  // src/components/MainLayout.tsx
@@ -4880,8 +4978,8 @@ var import_Menu = __toESM(require("@mui/icons-material/Menu"), 1);
4880
4978
  var import_ChevronLeft = __toESM(require("@mui/icons-material/ChevronLeft"), 1);
4881
4979
 
4882
4980
  // src/components/SideMenu.tsx
4883
- var import_react27 = __toESM(require("react"), 1);
4884
- var import_material19 = require("@mui/material");
4981
+ var import_react28 = __toESM(require("react"), 1);
4982
+ var import_material20 = require("@mui/material");
4885
4983
  var import_ExpandLess = __toESM(require("@mui/icons-material/ExpandLess"), 1);
4886
4984
  var import_ExpandMore = __toESM(require("@mui/icons-material/ExpandMore"), 1);
4887
4985
  var import_TableChart = __toESM(require("@mui/icons-material/TableChart"), 1);
@@ -4895,12 +4993,43 @@ var import_react_router_dom2 = require("react-router-dom");
4895
4993
  var import_colors = require("@mui/material/colors");
4896
4994
 
4897
4995
  // src/utils/menuInicial.ts
4898
- function rutaDeItemDeMenu(item) {
4996
+ function rutaDeTablaDeMenu(camino) {
4997
+ return `/menu/${camino.map(encodeURIComponent).join("/")}`;
4998
+ }
4999
+ function gruposDeItem(menu, item) {
5000
+ for (const candidato of menu) {
5001
+ if (candidato === item) return [];
5002
+ if (candidato.menuType === "menu") {
5003
+ const grupos = gruposDeItem(candidato.menuContent, item);
5004
+ if (grupos) return [candidato.name, ...grupos];
5005
+ }
5006
+ }
5007
+ return void 0;
5008
+ }
5009
+ function itemDeCamino(menu, camino) {
5010
+ const [nombre, ...resto] = camino;
5011
+ const item = menu.find((candidato) => candidato.name === nombre && candidato.menuType === (resto.length ? "menu" : "table"));
5012
+ return item && resto.length ? itemDeCamino(item.menuContent, resto) : item;
5013
+ }
5014
+ function primeraTablaConNombre(menu, nombre) {
5015
+ for (const item of menu) {
5016
+ if (item.menuType === "table" && item.name === nombre) return item;
5017
+ const encontrado = item.menuType === "menu" ? primeraTablaConNombre(item.menuContent, nombre) : void 0;
5018
+ if (encontrado) return encontrado;
5019
+ }
5020
+ return void 0;
5021
+ }
5022
+ function itemDeRuta(menu, camino) {
5023
+ if (camino.length === 0) return void 0;
5024
+ const item = itemDeCamino(menu, camino) ?? primeraTablaConNombre(menu, camino[camino.length - 1]);
5025
+ return item;
5026
+ }
5027
+ function rutaDeItemDeMenu(item, grupos = []) {
4899
5028
  if (item.menuType === "table") {
4900
5029
  const consulta = new URLSearchParams();
4901
5030
  if (item.td) consulta.append("td", JSON.stringify(item.td));
4902
5031
  if (item.fc) consulta.append("fc", JSON.stringify(item.fc));
4903
- return `/menu/${item.name}${consulta.size ? `?${consulta.toString()}` : ""}`;
5032
+ return `${rutaDeTablaDeMenu([...grupos, item.name])}${consulta.size ? `?${consulta.toString()}` : ""}`;
4904
5033
  }
4905
5034
  if (item.menuType === "proc") return `/procedures/${item.name}`;
4906
5035
  if (wScreens[item.menuType] !== void 0) return `/wScreens/${item.menuType}`;
@@ -4914,8 +5043,8 @@ function itemInicial(menu) {
4914
5043
  }
4915
5044
 
4916
5045
  // src/components/SideMenu.tsx
4917
- var import_jsx_runtime23 = require("react/jsx-runtime");
4918
- var MenuListItem = ({ item, level, onMenuItemClick }) => {
5046
+ var import_jsx_runtime25 = require("react/jsx-runtime");
5047
+ var MenuListItem = ({ item, level, grupos = [], onMenuItemClick }) => {
4919
5048
  const navigate = (0, import_react_router_dom2.useNavigate)();
4920
5049
  const location = (0, import_react_router_dom2.useLocation)();
4921
5050
  const open = useSubMenuOpenState(item.name);
@@ -4924,7 +5053,7 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
4924
5053
  if (item.menuType === "menu") {
4925
5054
  dispatch(toggleSubMenu(item.name));
4926
5055
  } else {
4927
- navigate(rutaDeItemDeMenu(item));
5056
+ navigate(rutaDeItemDeMenu(item, grupos));
4928
5057
  if (onMenuItemClick) {
4929
5058
  onMenuItemClick();
4930
5059
  }
@@ -4933,17 +5062,17 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
4933
5062
  const getIcon = (item2) => {
4934
5063
  switch (item2.menuType) {
4935
5064
  case "table":
4936
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_TableChart.default, { sx: { color: import_colors.blue[700] } });
5065
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_TableChart.default, { sx: { color: import_colors.blue[700] } });
4937
5066
  case "proc":
4938
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_Dns.default, { sx: { color: import_colors.teal[700] } });
5067
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Dns.default, { sx: { color: import_colors.teal[700] } });
4939
5068
  case "menu":
4940
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_Folder.default, { sx: { color: import_colors.orange[800] } });
5069
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Folder.default, { sx: { color: import_colors.orange[800] } });
4941
5070
  default:
4942
5071
  const WScreenComponent = wScreens[item2.menuType];
4943
5072
  if (WScreenComponent !== void 0) {
4944
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_DesktopWindows.default, { sx: { color: import_colors.grey[700] } });
5073
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_DesktopWindows.default, { sx: { color: import_colors.grey[700] } });
4945
5074
  }
4946
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_WarningAmber3.default, { sx: { color: import_colors.red[500] } });
5075
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_WarningAmber3.default, { sx: { color: import_colors.red[500] } });
4947
5076
  }
4948
5077
  };
4949
5078
  const currentPath = location.pathname;
@@ -4951,37 +5080,38 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
4951
5080
  const pathParts = currentPath.split("/");
4952
5081
  const urlTableName = pathParts[1] === "table" ? pathParts[2] : null;
4953
5082
  if (item.menuType === "table") {
4954
- isSelected = currentPath === `/menu/${item.name}` || urlTableName === (item.table || item.name);
5083
+ isSelected = currentPath === rutaDeTablaDeMenu([...grupos, item.name]) || urlTableName === (item.table || item.name);
4955
5084
  } else if (item.menuType === "proc") {
4956
5085
  isSelected = currentPath === `/procedures/${item.name}`;
4957
5086
  } else if (item.menuType !== "menu") {
4958
5087
  isSelected = currentPath.startsWith(`/wScreens/${item.menuType}`) || currentPath.startsWith(`/wScreens-fallback/${item.menuType}`);
4959
5088
  }
4960
- const itemRef = import_react27.default.useRef(null);
4961
- (0, import_react27.useEffect)(() => {
5089
+ const itemRef = import_react28.default.useRef(null);
5090
+ (0, import_react28.useEffect)(() => {
4962
5091
  if (isSelected && itemRef.current) {
4963
5092
  itemRef.current.scrollIntoView({ behavior: "smooth", block: "nearest" });
4964
5093
  }
4965
5094
  }, [isSelected]);
4966
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { ref: itemRef, children: [
4967
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4968
- import_material19.ListItemButton,
5095
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { ref: itemRef, children: [
5096
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5097
+ import_material20.ListItemButton,
4969
5098
  {
4970
5099
  onClick: handleClick,
4971
5100
  sx: { pl: level * 2 },
4972
5101
  selected: isSelected,
4973
5102
  children: [
4974
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.ListItemIcon, { sx: { minWidth: "38px" }, children: getIcon(item) }),
4975
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.ListItemText, { primary: item.label || item.name }),
4976
- item.menuType === "menu" ? open ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ExpandLess.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ExpandMore.default, {}) : null
5103
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemIcon, { sx: { minWidth: "38px" }, children: getIcon(item) }),
5104
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemText, { primary: item.label || item.name }),
5105
+ item.menuType === "menu" ? open ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ExpandLess.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ExpandMore.default, {}) : null
4977
5106
  ]
4978
5107
  }
4979
5108
  ),
4980
- item.menuType === "menu" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Collapse, { in: open, timeout: "auto", unmountOnExit: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.List, { component: "div", disablePadding: true, children: item.menuContent.map((subItem) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5109
+ item.menuType === "menu" && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Collapse, { in: open, timeout: "auto", unmountOnExit: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.List, { component: "div", disablePadding: true, children: item.menuContent.map((subItem) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4981
5110
  MenuListItem,
4982
5111
  {
4983
5112
  item: subItem,
4984
5113
  level: level + 1,
5114
+ grupos: [...grupos, item.name],
4985
5115
  onMenuItemClick
4986
5116
  },
4987
5117
  subItem.name
@@ -5001,9 +5131,9 @@ var SideMenu = ({ onMenuItemClick }) => {
5001
5131
  dispatch(setAllSubMenusOpen(!isMostlyOpen));
5002
5132
  };
5003
5133
  if (!clientContext || !clientContext.menu) {
5004
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Box, { sx: { p: 2, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Typography, { variant: "body2", color: "text.secondary", children: "Cargando men\xFA..." }) });
5134
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Box, { sx: { p: 2, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Typography, { variant: "body2", color: "text.secondary", children: "Cargando men\xFA..." }) });
5005
5135
  }
5006
- (0, import_react27.useEffect)(() => {
5136
+ (0, import_react28.useEffect)(() => {
5007
5137
  if (!clientContext?.menu) return;
5008
5138
  const expandParents = (items, targetPath, parentNames = []) => {
5009
5139
  const pathParts = targetPath.split("/");
@@ -5011,7 +5141,7 @@ var SideMenu = ({ onMenuItemClick }) => {
5011
5141
  for (const item of items) {
5012
5142
  let matches = false;
5013
5143
  if (item.menuType === "table") {
5014
- matches = targetPath === `/menu/${item.name}` || urlTableName === (item.table || item.name);
5144
+ matches = targetPath === rutaDeTablaDeMenu([...parentNames, item.name]) || urlTableName === (item.table || item.name);
5015
5145
  } else if (item.menuType === "proc") {
5016
5146
  matches = targetPath === `/procedures/${item.name}`;
5017
5147
  } else if (item.menuType !== "menu") {
@@ -5032,13 +5162,13 @@ var SideMenu = ({ onMenuItemClick }) => {
5032
5162
  };
5033
5163
  expandParents(clientContext.menu, location.pathname);
5034
5164
  }, [location.pathname, clientContext, dispatch]);
5035
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material19.Box, { sx: { width: "100%", flexShrink: 0 }, children: [
5036
- clientContext.menu.some((item) => item.menuType === "menu") && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.ListItem, { disablePadding: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material19.ListItemButton, { onClick: handleToggleAllSubMenus, children: [
5037
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.ListItemIcon, { sx: { minWidth: "38px" }, children: isMostlyOpen ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_UnfoldLess.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_UnfoldMore.default, {}) }),
5038
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.ListItemText, { primary: isMostlyOpen ? "colapsar " : "expandir" })
5165
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_material20.Box, { sx: { width: "100%", flexShrink: 0 }, children: [
5166
+ clientContext.menu.some((item) => item.menuType === "menu") && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItem, { disablePadding: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_material20.ListItemButton, { onClick: handleToggleAllSubMenus, children: [
5167
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemIcon, { sx: { minWidth: "38px" }, children: isMostlyOpen ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_UnfoldLess.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_UnfoldMore.default, {}) }),
5168
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemText, { primary: isMostlyOpen ? "colapsar " : "expandir" })
5039
5169
  ] }) }),
5040
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.Divider, {}),
5041
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material19.List, { children: clientContext.menu.map((menuItem) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5170
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Divider, {}),
5171
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.List, { children: clientContext.menu.map((menuItem) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5042
5172
  MenuListItem,
5043
5173
  {
5044
5174
  item: menuItem,
@@ -5052,14 +5182,14 @@ var SideMenu = ({ onMenuItemClick }) => {
5052
5182
  var SideMenu_default = SideMenu;
5053
5183
 
5054
5184
  // src/hooks/useLogout.tsx
5055
- var import_react28 = require("react");
5185
+ var import_react29 = require("react");
5056
5186
  var import_react_router_dom3 = require("react-router-dom");
5057
5187
  var import_react_redux3 = require("react-redux");
5058
5188
  var useLogout = () => {
5059
5189
  const { setIsLoggedIn } = useApp();
5060
5190
  const dispatch = (0, import_react_redux3.useDispatch)();
5061
5191
  const navigate = (0, import_react_router_dom3.useNavigate)();
5062
- const logout = (0, import_react28.useCallback)(async () => {
5192
+ const logout = (0, import_react29.useCallback)(async () => {
5063
5193
  try {
5064
5194
  const response = await fetchApi("/logout", { method: "GET" });
5065
5195
  if (response.status === 401 || response.ok) {
@@ -5080,16 +5210,16 @@ var useLogout = () => {
5080
5210
  var useLogout_default = useLogout;
5081
5211
 
5082
5212
  // src/components/MainLayout.tsx
5083
- var import_jsx_runtime24 = require("react/jsx-runtime");
5213
+ var import_jsx_runtime26 = require("react/jsx-runtime");
5084
5214
  var drawerWidth = 240;
5085
5215
  var MainLayout = () => {
5086
5216
  const { clientContext } = useApp();
5087
5217
  const logout = useLogout_default();
5088
5218
  const isDrawerOpen = useIsDrawerOpen();
5089
5219
  const dispatch = useAppDispatch();
5090
- const theme = (0, import_material20.useTheme)();
5091
- const isMobile = (0, import_material20.useMediaQuery)(theme.breakpoints.down("sm"));
5092
- (0, import_react29.useEffect)(() => {
5220
+ const theme = (0, import_material21.useTheme)();
5221
+ const isMobile = (0, import_material21.useMediaQuery)(theme.breakpoints.down("sm"));
5222
+ (0, import_react30.useEffect)(() => {
5093
5223
  if (isMobile && isDrawerOpen) {
5094
5224
  dispatch(setDrawerOpen(false));
5095
5225
  }
@@ -5103,12 +5233,12 @@ var MainLayout = () => {
5103
5233
  }
5104
5234
  };
5105
5235
  if (!clientContext) {
5106
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Typography, { children: "Cargando dise\xF1o de la aplicaci\xF3n..." }) });
5236
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Typography, { children: "Cargando dise\xF1o de la aplicaci\xF3n..." }) });
5107
5237
  }
5108
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material20.Box, { sx: { display: "flex", height: "100vh" }, children: [
5109
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.CssBaseline, {}),
5110
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5111
- import_material20.AppBar,
5238
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_material21.Box, { sx: { display: "flex", height: "100vh" }, children: [
5239
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.CssBaseline, {}),
5240
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5241
+ import_material21.AppBar,
5112
5242
  {
5113
5243
  position: "fixed",
5114
5244
  sx: {
@@ -5126,9 +5256,9 @@ var MainLayout = () => {
5126
5256
  })
5127
5257
  }
5128
5258
  },
5129
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material20.Toolbar, { children: [
5130
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5131
- import_material20.IconButton,
5259
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_material21.Toolbar, { children: [
5260
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5261
+ import_material21.IconButton,
5132
5262
  {
5133
5263
  color: "inherit",
5134
5264
  "aria-label": "open drawer",
@@ -5137,10 +5267,10 @@ var MainLayout = () => {
5137
5267
  sx: {
5138
5268
  marginRight: 2
5139
5269
  },
5140
- children: isDrawerOpen ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ChevronLeft.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_Menu.default, {})
5270
+ children: isDrawerOpen ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ChevronLeft.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_Menu.default, {})
5141
5271
  }
5142
5272
  ),
5143
- !isDrawerOpen && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5273
+ !isDrawerOpen && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5144
5274
  "img",
5145
5275
  {
5146
5276
  src: `${envConfig.backendUrl}/img/logo-128.png`,
@@ -5148,22 +5278,22 @@ var MainLayout = () => {
5148
5278
  style: { height: "32px", marginRight: "12px", objectFit: "contain" }
5149
5279
  }
5150
5280
  ),
5151
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Typography, { variant: "h6", noWrap: true, component: "div", sx: { flexGrow: 1 }, children: isDrawerOpen ? "" : clientContext.config.title }),
5152
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Typography, { variant: "subtitle1", component: "div", sx: { mr: 2 }, children: clientContext.username }),
5153
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5154
- import_material20.Button,
5281
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Typography, { variant: "h6", noWrap: true, component: "div", sx: { flexGrow: 1 }, children: isDrawerOpen ? "" : clientContext.config.title }),
5282
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Typography, { variant: "subtitle1", component: "div", sx: { mr: 2 }, children: clientContext.username }),
5283
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5284
+ import_material21.Button,
5155
5285
  {
5156
5286
  color: "inherit",
5157
5287
  onClick: logout,
5158
- startIcon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_Logout.default, {}),
5288
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_Logout.default, {}),
5159
5289
  children: "Salir"
5160
5290
  }
5161
5291
  )
5162
5292
  ] })
5163
5293
  }
5164
5294
  ),
5165
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5166
- import_material20.Drawer,
5295
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5296
+ import_material21.Drawer,
5167
5297
  {
5168
5298
  variant: "persistent",
5169
5299
  anchor: "left",
@@ -5179,8 +5309,8 @@ var MainLayout = () => {
5179
5309
  }
5180
5310
  },
5181
5311
  children: [
5182
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5183
- import_material20.Toolbar,
5312
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5313
+ import_material21.Toolbar,
5184
5314
  {
5185
5315
  sx: {
5186
5316
  display: "flex",
@@ -5192,7 +5322,7 @@ var MainLayout = () => {
5192
5322
  gap: 1.5
5193
5323
  },
5194
5324
  children: [
5195
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5325
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5196
5326
  "img",
5197
5327
  {
5198
5328
  src: `${envConfig.backendUrl}/img/logo-128.png`,
@@ -5200,16 +5330,16 @@ var MainLayout = () => {
5200
5330
  style: { height: "32px", objectFit: "contain" }
5201
5331
  }
5202
5332
  ),
5203
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Typography, { variant: "h6", sx: { fontWeight: "bold" }, children: clientContext.config.title })
5333
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Typography, { variant: "h6", sx: { fontWeight: "bold" }, children: clientContext.config.title })
5204
5334
  ]
5205
5335
  }
5206
5336
  ),
5207
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SideMenu_default, { onMenuItemClick: handleDrawerCloseMobile })
5337
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SideMenu_default, { onMenuItemClick: handleDrawerCloseMobile })
5208
5338
  ]
5209
5339
  }
5210
5340
  ),
5211
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5212
- import_material20.Box,
5341
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5342
+ import_material21.Box,
5213
5343
  {
5214
5344
  component: "main",
5215
5345
  sx: {
@@ -5235,8 +5365,8 @@ var MainLayout = () => {
5235
5365
  width: isDrawerOpen ? `calc(100% - ${drawerWidth}px)` : "100%"
5236
5366
  },
5237
5367
  children: [
5238
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Toolbar, {}),
5239
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Box, { sx: { flex: 1, minHeight: 0, overflowY: "auto", display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_router_dom4.Outlet, {}) })
5368
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Toolbar, {}),
5369
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Box, { sx: { flex: 1, minHeight: 0, overflowY: "auto", display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_router_dom4.Outlet, {}) })
5240
5370
  ]
5241
5371
  }
5242
5372
  )
@@ -5245,8 +5375,8 @@ var MainLayout = () => {
5245
5375
  var MainLayout_default = MainLayout;
5246
5376
 
5247
5377
  // src/components/SessionExpiredMessage.tsx
5248
- var import_material21 = require("@mui/material");
5249
- var import_jsx_runtime25 = require("react/jsx-runtime");
5378
+ var import_material22 = require("@mui/material");
5379
+ var import_jsx_runtime27 = require("react/jsx-runtime");
5250
5380
  var style = {
5251
5381
  position: "absolute",
5252
5382
  top: "50%",
@@ -5265,8 +5395,8 @@ var SessionExpiredMessage = () => {
5265
5395
  const handleClose = () => {
5266
5396
  handleExpiredSessionRedirect();
5267
5397
  };
5268
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5269
- import_material21.Modal,
5398
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5399
+ import_material22.Modal,
5270
5400
  {
5271
5401
  open: showSessionExpiredMessage,
5272
5402
  onClose: () => {
@@ -5285,10 +5415,10 @@ var SessionExpiredMessage = () => {
5285
5415
  }
5286
5416
  }
5287
5417
  },
5288
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_material21.Box, { sx: style, children: [
5289
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material21.Typography, { id: "session-expired-modal-title", variant: "h6", component: "h2", gutterBottom: true, children: "\xA1Sesi\xF3n Expirada!" }),
5290
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material21.Typography, { 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." }),
5291
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material21.Button, { variant: "contained", color: "primary", onClick: handleClose, children: "Ir al Login" })
5418
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_material22.Box, { sx: style, children: [
5419
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material22.Typography, { id: "session-expired-modal-title", variant: "h6", component: "h2", gutterBottom: true, children: "\xA1Sesi\xF3n Expirada!" }),
5420
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material22.Typography, { 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." }),
5421
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material22.Button, { variant: "contained", color: "primary", onClick: handleClose, children: "Ir al Login" })
5292
5422
  ] })
5293
5423
  }
5294
5424
  );
@@ -5297,24 +5427,24 @@ var SessionExpiredMessage_default = SessionExpiredMessage;
5297
5427
 
5298
5428
  // src/pages/PantallaInicial.tsx
5299
5429
  var import_react_router_dom5 = require("react-router-dom");
5300
- var import_jsx_runtime26 = require("react/jsx-runtime");
5430
+ var import_jsx_runtime28 = require("react/jsx-runtime");
5301
5431
  var PantallaInicial = () => {
5302
5432
  const { clientContext } = useApp();
5303
5433
  const item = clientContext.menu ? itemInicial(clientContext.menu) : void 0;
5304
- return item ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_router_dom5.Navigate, { to: rutaDeItemDeMenu(item), replace: true }) : null;
5434
+ return item && clientContext.menu ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_router_dom5.Navigate, { to: rutaDeItemDeMenu(item, gruposDeItem(clientContext.menu, item)), replace: true }) : null;
5305
5435
  };
5306
5436
  var PantallaInicial_default = PantallaInicial;
5307
5437
 
5308
5438
  // src/pages/LogoutPage.tsx
5309
- var import_react30 = require("react");
5310
- var import_material22 = require("@mui/material");
5311
- var import_jsx_runtime27 = require("react/jsx-runtime");
5439
+ var import_react31 = require("react");
5440
+ var import_material23 = require("@mui/material");
5441
+ var import_jsx_runtime29 = require("react/jsx-runtime");
5312
5442
  var LogoutPage = () => {
5313
5443
  const logout = useLogout_default();
5314
- (0, import_react30.useEffect)(() => {
5444
+ (0, import_react31.useEffect)(() => {
5315
5445
  logout();
5316
5446
  }, [logout]);
5317
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_material22.Box, { sx: {
5447
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_material23.Box, { sx: {
5318
5448
  display: "flex",
5319
5449
  flexDirection: "column",
5320
5450
  justifyContent: "center",
@@ -5322,20 +5452,20 @@ var LogoutPage = () => {
5322
5452
  height: "100vh",
5323
5453
  textAlign: "center"
5324
5454
  }, children: [
5325
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material22.CircularProgress, { size: 60 }),
5326
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material22.Typography, { variant: "h6", sx: { mt: 2 }, children: "Cerrando sesi\xF3n..." })
5455
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_material23.CircularProgress, { size: 60 }),
5456
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_material23.Typography, { variant: "h6", sx: { mt: 2 }, children: "Cerrando sesi\xF3n..." })
5327
5457
  ] });
5328
5458
  };
5329
5459
  var LogoutPage_default = LogoutPage;
5330
5460
 
5331
5461
  // src/pages/LoginPage.tsx
5332
- var import_react31 = require("react");
5333
- var import_material23 = require("@mui/material");
5462
+ var import_react32 = require("react");
5463
+ var import_material24 = require("@mui/material");
5334
5464
  var import_react_hook_form = require("react-hook-form");
5335
5465
  var import_zod = require("@hookform/resolvers/zod");
5336
5466
  var z = __toESM(require("zod"), 1);
5337
5467
  var import_react_redux4 = require("react-redux");
5338
- var import_jsx_runtime28 = require("react/jsx-runtime");
5468
+ var import_jsx_runtime30 = require("react/jsx-runtime");
5339
5469
  var loginSchema = z.object({
5340
5470
  username: z.string().min(1, "El usuario es requerido"),
5341
5471
  // Añadir validación básica
@@ -5343,8 +5473,8 @@ var loginSchema = z.object({
5343
5473
  // Añadir validación básica
5344
5474
  });
5345
5475
  var LoginPage = () => {
5346
- const [loginError, setLoginError] = (0, import_react31.useState)(null);
5347
- const [isSubmitting, setIsSubmitting] = (0, import_react31.useState)(false);
5476
+ const [loginError, setLoginError] = (0, import_react32.useState)(null);
5477
+ const [isSubmitting, setIsSubmitting] = (0, import_react32.useState)(false);
5348
5478
  const { setIsLoggedIn, checkSession } = useApp();
5349
5479
  const dispatch = (0, import_react_redux4.useDispatch)();
5350
5480
  const {
@@ -5389,16 +5519,16 @@ var LoginPage = () => {
5389
5519
  setIsSubmitting(false);
5390
5520
  }
5391
5521
  };
5392
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5393
- import_material23.Box,
5522
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5523
+ import_material24.Box,
5394
5524
  {
5395
5525
  display: "flex",
5396
5526
  alignItems: "center",
5397
5527
  justifyContent: "center",
5398
5528
  minHeight: "100vh",
5399
5529
  bgcolor: "#f5f5f5",
5400
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5401
- import_material23.Box,
5530
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
5531
+ import_material24.Box,
5402
5532
  {
5403
5533
  width: "100%",
5404
5534
  maxWidth: "400px",
@@ -5407,7 +5537,7 @@ var LoginPage = () => {
5407
5537
  borderRadius: 8,
5408
5538
  boxShadow: 3,
5409
5539
  children: [
5410
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Box, { sx: { display: "flex", justifyContent: "center", mb: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5540
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Box, { sx: { display: "flex", justifyContent: "center", mb: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5411
5541
  "img",
5412
5542
  {
5413
5543
  src: `${envConfig.backendUrl}/img/login-logo-icon.png`,
@@ -5415,17 +5545,17 @@ var LoginPage = () => {
5415
5545
  style: { height: "192px", maxWidth: "100%", objectFit: "contain" }
5416
5546
  }
5417
5547
  ) }),
5418
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { variant: "h5", align: "center", gutterBottom: true, sx: { fontWeight: "bold", color: "primary.main" }, children: "Iniciar Sesi\xF3n" }),
5419
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-4", children: [
5420
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { children: [
5421
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("label", { htmlFor: "username", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Usuario" }) }),
5422
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5548
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Typography, { variant: "h5", align: "center", gutterBottom: true, sx: { fontWeight: "bold", color: "primary.main" }, children: "Iniciar Sesi\xF3n" }),
5549
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-4", children: [
5550
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
5551
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { htmlFor: "username", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Typography, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Usuario" }) }),
5552
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5423
5553
  import_react_hook_form.Controller,
5424
5554
  {
5425
5555
  name: "username",
5426
5556
  control,
5427
- render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5428
- import_material23.TextField,
5557
+ render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5558
+ import_material24.TextField,
5429
5559
  {
5430
5560
  ...field,
5431
5561
  type: "text",
@@ -5440,15 +5570,15 @@ var LoginPage = () => {
5440
5570
  }
5441
5571
  )
5442
5572
  ] }),
5443
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { children: [
5444
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("label", { htmlFor: "password", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Typography, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Contrase\xF1a" }) }),
5445
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5573
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
5574
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { htmlFor: "password", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Typography, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Contrase\xF1a" }) }),
5575
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5446
5576
  import_react_hook_form.Controller,
5447
5577
  {
5448
5578
  name: "password",
5449
5579
  control,
5450
- render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5451
- import_material23.TextField,
5580
+ render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5581
+ import_material24.TextField,
5452
5582
  {
5453
5583
  ...field,
5454
5584
  type: "password",
@@ -5463,14 +5593,14 @@ var LoginPage = () => {
5463
5593
  }
5464
5594
  )
5465
5595
  ] }),
5466
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.Button, { type: "submit", fullWidth: true, variant: "contained", color: "primary", disabled: isSubmitting, sx: { mt: 2 }, children: isSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
5467
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.CircularProgress, { size: 20, sx: { mr: 1 } }),
5596
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Button, { type: "submit", fullWidth: true, variant: "contained", color: "primary", disabled: isSubmitting, sx: { mt: 2 }, children: isSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
5597
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.CircularProgress, { size: 20, sx: { mr: 1 } }),
5468
5598
  "Iniciando sesi\xF3n..."
5469
5599
  ] }) : "Iniciar Sesi\xF3n" })
5470
5600
  ] }),
5471
- loginError && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_material23.Alert, { severity: "error", sx: { mt: 2, maxHeight: "200px" }, children: [
5601
+ loginError && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material24.Alert, { severity: "error", sx: { mt: 2, maxHeight: "200px" }, children: [
5472
5602
  " ",
5473
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material23.AlertTitle, { children: "Error" }),
5603
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.AlertTitle, { children: "Error" }),
5474
5604
  loginError
5475
5605
  ] })
5476
5606
  ]
@@ -5482,19 +5612,19 @@ var LoginPage = () => {
5482
5612
  var LoginPage_default = LoginPage;
5483
5613
 
5484
5614
  // src/components/ProcedureForm.tsx
5485
- var import_react32 = __toESM(require("react"), 1);
5615
+ var import_react33 = __toESM(require("react"), 1);
5486
5616
  var import_react_router_dom6 = require("react-router-dom");
5487
- var import_material25 = require("@mui/material");
5617
+ var import_material26 = require("@mui/material");
5488
5618
 
5489
5619
  // src/pages/procedure-results/SuccessDisplay.tsx
5490
- var import_material24 = require("@mui/material");
5491
- var import_jsx_runtime29 = require("react/jsx-runtime");
5620
+ var import_material25 = require("@mui/material");
5621
+ var import_jsx_runtime31 = require("react/jsx-runtime");
5492
5622
  var SuccessDisplay = ({ data }) => {
5493
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_material24.Paper, { elevation: 2, sx: { p: 2, mt: 2, bgcolor: "success.light", color: "success.contrastText" }, children: [
5494
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_material24.Typography, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: "\xA1Operaci\xF3n Exitosa!" }),
5495
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_material24.Typography, { variant: "body2", sx: { fontSize: "0.85rem" }, children: "Detalles del resultado:" }),
5496
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_material24.Box, { sx: { bgcolor: "success.dark", p: 1, borderRadius: 1, mt: 1, overflowX: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(data, null, 2) }) }),
5497
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_material24.Typography, { variant: "body2", sx: { fontSize: "0.8rem", mt: 1 }, children: "Puedes revisar los detalles anteriores o cerrar este mensaje." })
5623
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material25.Paper, { elevation: 2, sx: { p: 2, mt: 2, bgcolor: "success.light", color: "success.contrastText" }, children: [
5624
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Typography, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: "\xA1Operaci\xF3n Exitosa!" }),
5625
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Typography, { variant: "body2", sx: { fontSize: "0.85rem" }, children: "Detalles del resultado:" }),
5626
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Box, { sx: { bgcolor: "success.dark", p: 1, borderRadius: 1, mt: 1, overflowX: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(data, null, 2) }) }),
5627
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Typography, { variant: "body2", sx: { fontSize: "0.8rem", mt: 1 }, children: "Puedes revisar los detalles anteriores o cerrar este mensaje." })
5498
5628
  ] });
5499
5629
  };
5500
5630
  var SuccessDisplay_default = SuccessDisplay;
@@ -5508,22 +5638,22 @@ var extendResultsOk = (newComponents) => {
5508
5638
  };
5509
5639
 
5510
5640
  // src/components/ProcedureForm.tsx
5511
- var import_jsx_runtime30 = require("react/jsx-runtime");
5641
+ var import_jsx_runtime32 = require("react/jsx-runtime");
5512
5642
  var ProcedureForm = () => {
5513
5643
  const { procedureName } = (0, import_react_router_dom6.useParams)();
5514
5644
  const { clientContext } = useApp();
5515
5645
  const { callApi, loading: apiLoading, error: apiError } = useApiCall();
5516
- const [validationErrors, setValidationErrors] = (0, import_react32.useState)({});
5517
- const [successMessage, setSuccessMessage] = (0, import_react32.useState)(null);
5518
- const [executionLog, setExecutionLog] = (0, import_react32.useState)([]);
5519
- const [procedureResultData, setProcedureResultData] = (0, import_react32.useState)(null);
5520
- const procedure = (0, import_react32.useMemo)(() => {
5646
+ const [validationErrors, setValidationErrors] = (0, import_react33.useState)({});
5647
+ const [successMessage, setSuccessMessage] = (0, import_react33.useState)(null);
5648
+ const [executionLog, setExecutionLog] = (0, import_react33.useState)([]);
5649
+ const [procedureResultData, setProcedureResultData] = (0, import_react33.useState)(null);
5650
+ const procedure = (0, import_react33.useMemo)(() => {
5521
5651
  if (procedureName && clientContext?.procedure) {
5522
5652
  return clientContext.procedure[procedureName];
5523
5653
  }
5524
5654
  return void 0;
5525
5655
  }, [procedureName, clientContext]);
5526
- const [formValues, setFormValues] = (0, import_react32.useState)(() => {
5656
+ const [formValues, setFormValues] = (0, import_react33.useState)(() => {
5527
5657
  if (!procedure) return {};
5528
5658
  const initialValues = {};
5529
5659
  procedure.parameters.forEach((param) => {
@@ -5548,7 +5678,7 @@ var ProcedureForm = () => {
5548
5678
  });
5549
5679
  return initialValues;
5550
5680
  });
5551
- import_react32.default.useEffect(() => {
5681
+ import_react33.default.useEffect(() => {
5552
5682
  if (procedure) {
5553
5683
  setValidationErrors({});
5554
5684
  setSuccessMessage(null);
@@ -5578,11 +5708,11 @@ var ProcedureForm = () => {
5578
5708
  setExecutionLog([]);
5579
5709
  }
5580
5710
  }, [procedure]);
5581
- const addLogMessage = (0, import_react32.useCallback)((message, isError = false) => {
5711
+ const addLogMessage = (0, import_react33.useCallback)((message, isError = false) => {
5582
5712
  const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("es-AR");
5583
5713
  setExecutionLog((prev) => [...prev, `[${timestamp}] ${isError ? "ERROR: " : ""}${message}`]);
5584
5714
  }, []);
5585
- const handleChange = (0, import_react32.useCallback)((e, child) => {
5715
+ const handleChange = (0, import_react33.useCallback)((e, child) => {
5586
5716
  const { name, value } = e.target;
5587
5717
  let newValue = value;
5588
5718
  if (e.target.type === "checkbox") {
@@ -5704,7 +5834,7 @@ var ProcedureForm = () => {
5704
5834
  addLogMessage("Ejecuci\xF3n finalizada.");
5705
5835
  }
5706
5836
  };
5707
- const renderInputField = (0, import_react32.useCallback)((param) => {
5837
+ const renderInputField = (0, import_react33.useCallback)((param) => {
5708
5838
  const hasError = !!validationErrors[param.name];
5709
5839
  const errorMessage = validationErrors[param.name];
5710
5840
  const commonProps = {
@@ -5723,10 +5853,10 @@ var ProcedureForm = () => {
5723
5853
  sx: { fontSize: "0.8rem" }
5724
5854
  };
5725
5855
  if (param.options && param.options.length > 0) {
5726
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material25.FormControl, { fullWidth: true, margin: "dense", size: "small", error: hasError, required: commonProps.required, children: [
5727
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.InputLabel, { id: `${param.name}-label`, sx: { fontSize: "0.8rem" }, children: param.label || param.name }),
5728
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
5729
- import_material25.Select,
5856
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.FormControl, { fullWidth: true, margin: "dense", size: "small", error: hasError, required: commonProps.required, children: [
5857
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.InputLabel, { id: `${param.name}-label`, sx: { fontSize: "0.8rem" }, children: param.label || param.name }),
5858
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5859
+ import_material26.Select,
5730
5860
  {
5731
5861
  labelId: `${param.name}-label`,
5732
5862
  value: formValues[param.name] === void 0 ? "" : formValues[param.name],
@@ -5736,14 +5866,14 @@ var ProcedureForm = () => {
5736
5866
  label: param.label || param.name,
5737
5867
  disabled: apiLoading,
5738
5868
  sx: { fontSize: "0.8rem" },
5739
- renderValue: (selected) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Typography, { sx: { fontSize: "0.8rem" }, children: selected }),
5869
+ renderValue: (selected) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Typography, { sx: { fontSize: "0.8rem" }, children: selected }),
5740
5870
  children: [
5741
- (!commonProps.required || formValues[param.name] === "") && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.MenuItem, { value: "", sx: { fontSize: "0.8rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("em", { children: "Seleccione..." }) }),
5742
- param.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.MenuItem, { value: option, sx: { fontSize: "0.8rem" }, children: option }, option))
5871
+ (!commonProps.required || formValues[param.name] === "") && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.MenuItem, { value: "", sx: { fontSize: "0.8rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("em", { children: "Seleccione..." }) }),
5872
+ param.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.MenuItem, { value: option, sx: { fontSize: "0.8rem" }, children: option }, option))
5743
5873
  ]
5744
5874
  }
5745
5875
  ),
5746
- (param.description || errorMessage) && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.FormHelperText, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
5876
+ (param.description || errorMessage) && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.FormHelperText, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
5747
5877
  ] });
5748
5878
  }
5749
5879
  switch (param.typeName) {
@@ -5752,19 +5882,19 @@ var ProcedureForm = () => {
5752
5882
  case "tsrange":
5753
5883
  case "time_range":
5754
5884
  case "daterange":
5755
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.TextField, { type: "text", value: formValues[param.name] || "", ...commonProps });
5885
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.TextField, { type: "text", value: formValues[param.name] || "", ...commonProps });
5756
5886
  case "decimal":
5757
5887
  case "double":
5758
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.TextField, { type: "number", inputProps: { step: "any", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
5888
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.TextField, { type: "number", inputProps: { step: "any", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
5759
5889
  case "integer":
5760
5890
  case "bigint":
5761
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.TextField, { type: "number", inputProps: { step: "1", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
5891
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.TextField, { type: "number", inputProps: { step: "1", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
5762
5892
  case "boolean":
5763
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5764
- import_material25.FormControlLabel,
5893
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5894
+ import_material26.FormControlLabel,
5765
5895
  {
5766
- control: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5767
- import_material25.Checkbox,
5896
+ control: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5897
+ import_material26.Checkbox,
5768
5898
  {
5769
5899
  checked: !!formValues[param.name],
5770
5900
  onChange: handleChange,
@@ -5774,21 +5904,21 @@ var ProcedureForm = () => {
5774
5904
  size: "small"
5775
5905
  }
5776
5906
  ),
5777
- label: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Typography, { sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "inherit" }, children: param.label || param.name }),
5907
+ label: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Typography, { sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "inherit" }, children: param.label || param.name }),
5778
5908
  sx: { mt: 1, mb: 0 }
5779
5909
  }
5780
5910
  );
5781
5911
  case "date":
5782
5912
  case "timestamp":
5783
5913
  case "time":
5784
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.TextField, { type: param.typeName === "date" ? "date" : param.typeName === "timestamp" ? "datetime-local" : "time", value: formValues[param.name] || "", ...commonProps, InputLabelProps: { shrink: true, sx: { fontSize: "0.8rem" } } });
5914
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.TextField, { type: param.typeName === "date" ? "date" : param.typeName === "timestamp" ? "datetime-local" : "time", value: formValues[param.name] || "", ...commonProps, InputLabelProps: { shrink: true, sx: { fontSize: "0.8rem" } } });
5785
5915
  case "jsonb":
5786
5916
  case "jsona":
5787
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.TextField, { multiline: true, rows: 5, value: formValues[param.name] || "", ...commonProps, InputProps: { sx: { fontSize: "0.8rem" } } });
5917
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.TextField, { multiline: true, rows: 5, value: formValues[param.name] || "", ...commonProps, InputProps: { sx: { fontSize: "0.8rem" } } });
5788
5918
  case "bytea":
5789
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material25.FormControl, { fullWidth: true, margin: "dense", error: hasError, required: commonProps.required, children: [
5790
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Typography, { variant: "body2", color: "textSecondary", component: "label", htmlFor: param.name, sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "text.secondary" }, children: param.label || param.name }),
5791
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5919
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.FormControl, { fullWidth: true, margin: "dense", error: hasError, required: commonProps.required, children: [
5920
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Typography, { variant: "body2", color: "textSecondary", component: "label", htmlFor: param.name, sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "text.secondary" }, children: param.label || param.name }),
5921
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5792
5922
  "input",
5793
5923
  {
5794
5924
  type: "file",
@@ -5802,34 +5932,34 @@ var ProcedureForm = () => {
5802
5932
  style: { padding: "6px 0", fontSize: "0.8rem" }
5803
5933
  }
5804
5934
  ),
5805
- (param.description || errorMessage) && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.FormHelperText, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
5935
+ (param.description || errorMessage) && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.FormHelperText, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
5806
5936
  ] });
5807
5937
  default:
5808
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.TextField, { type: "text", value: formValues[param.name] || "", ...commonProps });
5938
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.TextField, { type: "text", value: formValues[param.name] || "", ...commonProps });
5809
5939
  }
5810
5940
  }, [formValues, handleChange, apiLoading, validationErrors]);
5811
- const ResultDisplayContent = (0, import_react32.useMemo)(() => {
5941
+ const ResultDisplayContent = (0, import_react33.useMemo)(() => {
5812
5942
  if (!procedureResultData || !procedure?.resultOk) return null;
5813
5943
  const ComponentToRender = resultsOk[procedure.resultOk];
5814
5944
  if (ComponentToRender) {
5815
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ComponentToRender, { data: procedureResultData });
5945
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ComponentToRender, { data: procedureResultData });
5816
5946
  } else {
5817
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material25.Paper, { elevation: 2, sx: { p: 2, mt: 0, bgcolor: "warning.light" }, children: [
5818
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material25.Typography, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: [
5947
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.Paper, { elevation: 2, sx: { p: 2, mt: 0, bgcolor: "warning.light" }, children: [
5948
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.Typography, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: [
5819
5949
  "el componente para resolver el resultOk: '",
5820
5950
  procedure.resultOk,
5821
5951
  "' definido en el procedure no existe o no est\xE1 mapeado."
5822
5952
  ] }),
5823
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Box, { sx: {
5953
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Box, { sx: {
5824
5954
  bgcolor: "warning.dark",
5825
5955
  p: 1,
5826
5956
  borderRadius: 1
5827
- }, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(procedureResultData, null, 2) }) })
5957
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(procedureResultData, null, 2) }) })
5828
5958
  ] });
5829
5959
  }
5830
5960
  }, [procedureResultData, procedure]);
5831
5961
  if (!procedure) {
5832
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material25.Box, { sx: {
5962
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.Box, { sx: {
5833
5963
  p: 2,
5834
5964
  width: "100%",
5835
5965
  boxSizing: "border-box",
@@ -5839,13 +5969,13 @@ var ProcedureForm = () => {
5839
5969
  boxShadow: 3,
5840
5970
  textAlign: "center"
5841
5971
  }, children: [
5842
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.CircularProgress, { sx: { mb: 2 } }),
5843
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Typography, { variant: "h6", color: "text.secondary", children: "Cargando procedimiento o no encontrado..." })
5972
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.CircularProgress, { sx: { mb: 2 } }),
5973
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Typography, { variant: "h6", color: "text.secondary", children: "Cargando procedimiento o no encontrado..." })
5844
5974
  ] });
5845
5975
  }
5846
5976
  return (
5847
5977
  // Esta es la Box más externa que ahora controlará el scroll
5848
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material25.Box, { sx: {
5978
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.Box, { sx: {
5849
5979
  p: 2,
5850
5980
  ml: 1,
5851
5981
  mt: 2,
@@ -5862,17 +5992,17 @@ var ProcedureForm = () => {
5862
5992
  overflowX: "hidden"
5863
5993
  // Oculta el scroll horizontal si no es necesario para el contenedor principal
5864
5994
  }, children: [
5865
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Typography, { variant: "h5", component: "h2", gutterBottom: true, align: "left", children: cambiarGuionesBajosPorEspacios(procedure.proceedLabel || procedure.action) }),
5866
- Object.values(validationErrors).some((err) => err !== null) && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material25.Alert, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: [
5995
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Typography, { variant: "h5", component: "h2", gutterBottom: true, align: "left", children: cambiarGuionesBajosPorEspacios(procedure.proceedLabel || procedure.action) }),
5996
+ Object.values(validationErrors).some((err) => err !== null) && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.Alert, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: [
5867
5997
  "Por favor, corrige los errores en el formulario antes de enviar.",
5868
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { children: Object.values(validationErrors).map((err, idx) => err && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("li", { children: err }, idx)) })
5998
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("ul", { children: Object.values(validationErrors).map((err, idx) => err && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("li", { children: err }, idx)) })
5869
5999
  ] }),
5870
- !Object.values(validationErrors).some((err) => err !== null) && apiError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Alert, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: apiError.message }),
5871
- !Object.values(validationErrors).some((err) => err !== null) && !apiError && successMessage && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Alert, { severity: "success", sx: { mb: 2, fontSize: "0.8rem" }, children: successMessage }),
5872
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("form", { onSubmit: handleSubmit, children: [
5873
- procedure.parameters.map((param) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { children: renderInputField(param) }, param.name)),
5874
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5875
- import_material25.Button,
6000
+ !Object.values(validationErrors).some((err) => err !== null) && apiError && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Alert, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: apiError.message }),
6001
+ !Object.values(validationErrors).some((err) => err !== null) && !apiError && successMessage && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Alert, { severity: "success", sx: { mb: 2, fontSize: "0.8rem" }, children: successMessage }),
6002
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("form", { onSubmit: handleSubmit, children: [
6003
+ procedure.parameters.map((param) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { children: renderInputField(param) }, param.name)),
6004
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6005
+ import_material26.Button,
5876
6006
  {
5877
6007
  type: "submit",
5878
6008
  variant: "contained",
@@ -5880,20 +6010,20 @@ var ProcedureForm = () => {
5880
6010
  disabled: apiLoading || Object.values(validationErrors).some((err) => err !== null),
5881
6011
  sx: { mt: 2 },
5882
6012
  size: "medium",
5883
- startIcon: apiLoading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.CircularProgress, { size: 20, color: "inherit" }) : null,
6013
+ startIcon: apiLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.CircularProgress, { size: 20, color: "inherit" }) : null,
5884
6014
  children: apiLoading ? "Ejecutando..." : procedure.proceedLabel || "Ejecutar"
5885
6015
  }
5886
6016
  )
5887
6017
  ] }),
5888
- ResultDisplayContent && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material25.Box, { sx: { mt: 2 }, children: [
6018
+ ResultDisplayContent && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.Box, { sx: { mt: 2 }, children: [
5889
6019
  " ",
5890
6020
  ResultDisplayContent
5891
6021
  ] }),
5892
- executionLog.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material25.Box, { sx: { mt: 3 }, children: [
5893
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Divider, { sx: { mb: 2 } }),
5894
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material25.Typography, { variant: "h6", gutterBottom: true, sx: { fontSize: "0.9rem" }, children: "Registro de Ejecuci\xF3n" }),
5895
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5896
- import_material25.Box,
6022
+ executionLog.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.Box, { sx: { mt: 3 }, children: [
6023
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Divider, { sx: { mb: 2 } }),
6024
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Typography, { variant: "h6", gutterBottom: true, sx: { fontSize: "0.9rem" }, children: "Registro de Ejecuci\xF3n" }),
6025
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6026
+ import_material26.Box,
5897
6027
  {
5898
6028
  sx: {
5899
6029
  bgcolor: "grey.100",
@@ -5906,8 +6036,8 @@ var ProcedureForm = () => {
5906
6036
  fontSize: "0.75rem",
5907
6037
  whiteSpace: "pre-wrap"
5908
6038
  },
5909
- children: executionLog.map((log, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5910
- import_material25.Typography,
6039
+ children: executionLog.map((log, index) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6040
+ import_material26.Typography,
5911
6041
  {
5912
6042
  component: "pre",
5913
6043
  sx: {
@@ -5929,12 +6059,12 @@ var ProcedureForm_default = ProcedureForm;
5929
6059
 
5930
6060
  // src/App.tsx
5931
6061
  var import_react_redux5 = require("react-redux");
5932
- var import_react43 = require("redux-persist/integration/react");
6062
+ var import_react44 = require("redux-persist/integration/react");
5933
6063
 
5934
6064
  // src/components/PrivateRoute.tsx
5935
- var import_react33 = require("react");
6065
+ var import_react34 = require("react");
5936
6066
  var import_react_router_dom7 = require("react-router-dom");
5937
- var import_jsx_runtime31 = require("react/jsx-runtime");
6067
+ var import_jsx_runtime33 = require("react/jsx-runtime");
5938
6068
  var PrivateRoute = ({ children }) => {
5939
6069
  const location = (0, import_react_router_dom7.useLocation)();
5940
6070
  const dispatch = useAppDispatch();
@@ -5942,7 +6072,7 @@ var PrivateRoute = ({ children }) => {
5942
6072
  const isAuthenticated = clientContextStatus === "succeeded";
5943
6073
  const isLoadingAuth = clientContextStatus === "loading";
5944
6074
  console.log(`[PrivateRoute] Render: Path=${location.pathname}, AuthStatus=${clientContextStatus}, IsAuthenticated=${isAuthenticated}, IsLoadingAuth=${isLoadingAuth}`);
5945
- (0, import_react33.useEffect)(() => {
6075
+ (0, import_react34.useEffect)(() => {
5946
6076
  console.log(`[PrivateRoute] Effect: Path=${location.pathname}, AuthStatus=${clientContextStatus}, IsAuthenticated=${isAuthenticated}, IsLoadingAuth=${isLoadingAuth}`);
5947
6077
  if (!isAuthenticated && !isLoadingAuth && location.pathname !== "/login") {
5948
6078
  const path = location.pathname + location.search + location.hash;
@@ -5958,19 +6088,19 @@ var PrivateRoute = ({ children }) => {
5958
6088
  }, [isAuthenticated, isLoadingAuth, location, dispatch, clientContextStatus]);
5959
6089
  if (isLoadingAuth) {
5960
6090
  console.log(`[PrivateRoute] Returning loading state...`);
5961
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { children: "Verificando autenticaci\xF3n..." });
6091
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { children: "Verificando autenticaci\xF3n..." });
5962
6092
  }
5963
6093
  if (!isAuthenticated) {
5964
6094
  console.log(`[PrivateRoute] User not authenticated, navigating to /login`);
5965
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_router_dom7.Navigate, { to: "/login", replace: true });
6095
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_router_dom7.Navigate, { to: "/login", replace: true });
5966
6096
  }
5967
6097
  console.log(`[PrivateRoute] User authenticated, rendering children.`);
5968
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_jsx_runtime31.Fragment, { children });
6098
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_jsx_runtime33.Fragment, { children });
5969
6099
  };
5970
6100
  var PrivateRoute_default = PrivateRoute;
5971
6101
 
5972
6102
  // src/components/InitialRedirectHandler.tsx
5973
- var import_react34 = require("react");
6103
+ var import_react35 = require("react");
5974
6104
  var import_react_router_dom8 = require("react-router-dom");
5975
6105
  var InitialRedirectHandler = () => {
5976
6106
  const location = (0, import_react_router_dom8.useLocation)();
@@ -5978,14 +6108,14 @@ var InitialRedirectHandler = () => {
5978
6108
  const dispatch = useAppDispatch();
5979
6109
  const redirectPath = useRedirectPath();
5980
6110
  const clientContextStatus = useClientContextStatus();
5981
- (0, import_react34.useEffect)(() => {
6111
+ (0, import_react35.useEffect)(() => {
5982
6112
  dispatch(setCurrentPath(location.pathname + location.search));
5983
6113
  }, [location, dispatch]);
5984
- const navegandoRef = (0, import_react34.useRef)(false);
5985
- (0, import_react34.useEffect)(() => {
6114
+ const navegandoRef = (0, import_react35.useRef)(false);
6115
+ (0, import_react35.useEffect)(() => {
5986
6116
  navegandoRef.current = false;
5987
6117
  }, [location.pathname]);
5988
- (0, import_react34.useEffect)(() => {
6118
+ (0, import_react35.useEffect)(() => {
5989
6119
  if (clientContextStatus === "succeeded") {
5990
6120
  if (redirectPath && redirectPath !== "/login") {
5991
6121
  console.log("Redirigiendo a la ruta guardada:", redirectPath);
@@ -6003,11 +6133,11 @@ var InitialRedirectHandler = () => {
6003
6133
  var InitialRedirectHandler_default = InitialRedirectHandler;
6004
6134
 
6005
6135
  // src/pages/GenericDataGridPage.tsx
6006
- var import_react35 = __toESM(require("react"), 1);
6136
+ var import_react36 = __toESM(require("react"), 1);
6007
6137
  var import_react_router_dom9 = require("react-router-dom");
6008
- var import_material26 = require("@mui/material");
6138
+ var import_material27 = require("@mui/material");
6009
6139
  var import_Close2 = __toESM(require("@mui/icons-material/Close"), 1);
6010
- var import_jsx_runtime32 = require("react/jsx-runtime");
6140
+ var import_jsx_runtime34 = require("react/jsx-runtime");
6011
6141
  var GenericDataGridPage = ({
6012
6142
  initialTableName,
6013
6143
  initialFixedFields = [],
@@ -6015,14 +6145,14 @@ var GenericDataGridPage = ({
6015
6145
  }) => {
6016
6146
  const { tableName: urlTableName } = (0, import_react_router_dom9.useParams)();
6017
6147
  const effectiveTableName = initialTableName || urlTableName;
6018
- const [tabs, setTabs] = (0, import_react35.useState)([]);
6019
- const [activeTabIdx, setActiveTabIdx] = (0, import_react35.useState)(0);
6148
+ const [tabs, setTabs] = (0, import_react36.useState)([]);
6149
+ const [activeTabIdx, setActiveTabIdx] = (0, import_react36.useState)(0);
6020
6150
  const ffKey = JSON.stringify(initialFixedFields);
6021
6151
  const location = (0, import_react_router_dom9.useLocation)();
6022
- const parametros = (0, import_react35.useMemo)(() => parametrosRecibidos ?? parametrosDeTabla(void 0, location.search), [parametrosRecibidos, location.search]);
6152
+ const parametros = (0, import_react36.useMemo)(() => parametrosRecibidos ?? parametrosDeTabla(void 0, location.search), [parametrosRecibidos, location.search]);
6023
6153
  const fixedFieldsIniciales = initialFixedFields.length > 0 ? initialFixedFields : parametros.fixedFields ?? [];
6024
6154
  const parametrosKey = JSON.stringify(parametros);
6025
- import_react35.default.useEffect(() => {
6155
+ import_react36.default.useEffect(() => {
6026
6156
  if (effectiveTableName) {
6027
6157
  setTabs([{
6028
6158
  id: `main-${effectiveTableName}-${ffKey}-${parametrosKey}`,
@@ -6036,7 +6166,7 @@ var GenericDataGridPage = ({
6036
6166
  setActiveTabIdx(0);
6037
6167
  }
6038
6168
  }, [effectiveTableName, ffKey, parametrosKey, location.key]);
6039
- const handleOpenDetail = (0, import_react35.useCallback)((tableName, fixedFields, label, ancestors) => {
6169
+ const handleOpenDetail = (0, import_react36.useCallback)((tableName, fixedFields, label, ancestors) => {
6040
6170
  const tabId = `${tableName}-${JSON.stringify(fixedFields)}`;
6041
6171
  setTabs((prevTabs) => {
6042
6172
  const existingTabIdx = prevTabs.findIndex((t) => t.id === tabId);
@@ -6058,26 +6188,26 @@ var GenericDataGridPage = ({
6058
6188
  else if (activeTabIdx === index) setActiveTabIdx(index - 1);
6059
6189
  };
6060
6190
  if (!effectiveTableName) {
6061
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Box, { p: 3, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Alert, { severity: "error", children: "No se especific\xF3 una tabla." }) });
6191
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material27.Box, { p: 3, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material27.Alert, { severity: "error", children: "No se especific\xF3 una tabla." }) });
6062
6192
  }
6063
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.Box, { sx: { width: "100%", height: "calc(100vh - 64px)", display: "flex", flexDirection: "column" }, children: [
6064
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Box, { sx: { borderBottom: 1, borderColor: "divider", bgcolor: "background.paper" }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Tabs, { value: activeTabIdx, onChange: (_, v) => setActiveTabIdx(v), variant: "scrollable", children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6065
- import_material26.Tab,
6193
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_material27.Box, { sx: { width: "100%", height: "calc(100vh - 64px)", display: "flex", flexDirection: "column" }, children: [
6194
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material27.Box, { sx: { borderBottom: 1, borderColor: "divider", bgcolor: "background.paper" }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material27.Tabs, { value: activeTabIdx, onChange: (_, v) => setActiveTabIdx(v), variant: "scrollable", children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6195
+ import_material27.Tab,
6066
6196
  {
6067
- label: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material26.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
6068
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.Typography, { variant: "caption", sx: { fontWeight: "bold" }, children: tab.label }),
6069
- index !== 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material26.IconButton, { size: "small", onClick: (e) => handleCloseTab(index, e), children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_Close2.default, { fontSize: "inherit" }) })
6197
+ label: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_material27.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
6198
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material27.Typography, { variant: "caption", sx: { fontWeight: "bold" }, children: tab.label }),
6199
+ index !== 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material27.IconButton, { size: "small", onClick: (e) => handleCloseTab(index, e), children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_Close2.default, { fontSize: "inherit" }) })
6070
6200
  ] })
6071
6201
  },
6072
6202
  tab.id
6073
6203
  )) }) }),
6074
- tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6075
- import_material26.Box,
6204
+ tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6205
+ import_material27.Box,
6076
6206
  {
6077
6207
  role: "tabpanel",
6078
6208
  hidden: activeTabIdx !== index,
6079
6209
  sx: { flexGrow: 1, display: activeTabIdx === index ? "flex" : "none", flexDirection: "column", overflow: "hidden" },
6080
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6210
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6081
6211
  GenericDataGrid_default,
6082
6212
  {
6083
6213
  tableName: tab.tableName,
@@ -6098,44 +6228,32 @@ var GenericDataGridPage = ({
6098
6228
  var GenericDataGridPage_default = GenericDataGridPage;
6099
6229
 
6100
6230
  // src/pages/PantallaDeRuta.tsx
6101
- var import_react36 = require("react");
6231
+ var import_react37 = require("react");
6102
6232
  var import_react_router_dom10 = require("react-router-dom");
6103
- var import_material27 = require("@mui/material");
6104
- var import_jsx_runtime33 = require("react/jsx-runtime");
6233
+ var import_material28 = require("@mui/material");
6234
+ var import_jsx_runtime35 = require("react/jsx-runtime");
6105
6235
  var PantallaDeRuta = ({ screenName }) => {
6106
6236
  const [busqueda] = (0, import_react_router_dom10.useSearchParams)();
6107
- const params = (0, import_react36.useMemo)(() => Object.fromEntries(busqueda.entries()), [busqueda]);
6237
+ const params = (0, import_react37.useMemo)(() => Object.fromEntries(busqueda.entries()), [busqueda]);
6108
6238
  const Pantalla = wScreens[screenName];
6109
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_material27.Box, { sx: { pt: 3, pl: 4 }, children: Pantalla ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Pantalla, { screenName, params }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FallbackWScreen, { screenName }) });
6239
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_material28.Box, { sx: { pt: 3, pl: 4 }, children: Pantalla ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Pantalla, { screenName, params }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(FallbackWScreen, { screenName }) });
6110
6240
  };
6111
6241
 
6112
6242
  // src/pages/MenuTablePage.tsx
6113
- var import_react37 = require("react");
6243
+ var import_react38 = require("react");
6114
6244
  var import_react_router_dom11 = require("react-router-dom");
6115
- var import_material28 = require("@mui/material");
6116
- var import_jsx_runtime34 = require("react/jsx-runtime");
6245
+ var import_material29 = require("@mui/material");
6246
+ var import_jsx_runtime36 = require("react/jsx-runtime");
6117
6247
  var MenuTablePage = () => {
6118
- const { menuName } = (0, import_react_router_dom11.useParams)();
6248
+ const { "*": menuName } = (0, import_react_router_dom11.useParams)();
6119
6249
  const { clientContext } = useApp();
6120
6250
  const { search } = (0, import_react_router_dom11.useLocation)();
6121
- const findMenuItem = (items, nameToFind) => {
6122
- for (const item of items) {
6123
- if (item.name === nameToFind && item.menuType === "table") {
6124
- return item;
6125
- }
6126
- if (item.menuType === "menu" && item.menuContent) {
6127
- const found = findMenuItem(item.menuContent, nameToFind);
6128
- if (found) return found;
6129
- }
6130
- }
6131
- return void 0;
6132
- };
6133
- const { currentTableName, currentFixedFields, parametros } = (0, import_react37.useMemo)(() => {
6251
+ const { currentTableName, currentFixedFields, parametros } = (0, import_react38.useMemo)(() => {
6134
6252
  let tableName = void 0;
6135
6253
  let fixedFields = [];
6136
6254
  let parametros2 = {};
6137
6255
  if (menuName && clientContext && clientContext.menu) {
6138
- const menuItem = findMenuItem(clientContext.menu, menuName);
6256
+ const menuItem = itemDeRuta(clientContext.menu, menuName.split("/").filter((tramo) => tramo !== ""));
6139
6257
  if (menuItem) {
6140
6258
  tableName = menuItem.table || menuItem.name;
6141
6259
  parametros2 = parametrosDeTabla(menuItem, search);
@@ -6151,12 +6269,12 @@ var MenuTablePage = () => {
6151
6269
  };
6152
6270
  }, [menuName, clientContext, search]);
6153
6271
  if (!currentTableName) {
6154
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material28.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_material28.Alert, { severity: "error", children: [
6155
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material28.Typography, { variant: "h6", children: "Error: No se pudo cargar la informaci\xF3n de la tabla." }),
6156
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material28.Typography, { variant: "body1", children: "Verifique la configuraci\xF3n del men\xFA o el nombre de la tabla en la URL." })
6272
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material29.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_material29.Alert, { severity: "error", children: [
6273
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material29.Typography, { variant: "h6", children: "Error: No se pudo cargar la informaci\xF3n de la tabla." }),
6274
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material29.Typography, { variant: "body1", children: "Verifique la configuraci\xF3n del men\xFA o el nombre de la tabla en la URL." })
6157
6275
  ] }) });
6158
6276
  }
6159
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6277
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6160
6278
  GenericDataGridPage_default,
6161
6279
  {
6162
6280
  initialTableName: currentTableName,
@@ -6168,9 +6286,9 @@ var MenuTablePage = () => {
6168
6286
  var MenuTablePage_default = MenuTablePage;
6169
6287
 
6170
6288
  // src/puente/PantallaBP.tsx
6171
- var import_react39 = require("react");
6289
+ var import_react40 = require("react");
6172
6290
  var import_react_router_dom12 = require("react-router-dom");
6173
- var import_material30 = require("@mui/material");
6291
+ var import_material31 = require("@mui/material");
6174
6292
 
6175
6293
  // src/puente/clienteBP.ts
6176
6294
  function extraerRecursos(html) {
@@ -6259,9 +6377,9 @@ async function cargarSinMemoria(urlBackend) {
6259
6377
  }
6260
6378
 
6261
6379
  // src/puente/ConsolaBP.tsx
6262
- var import_react38 = require("react");
6263
- var import_material29 = require("@mui/material");
6264
- var import_jsx_runtime35 = require("react/jsx-runtime");
6380
+ var import_react39 = require("react");
6381
+ var import_material30 = require("@mui/material");
6382
+ var import_jsx_runtime37 = require("react/jsx-runtime");
6265
6383
  var MARGEN_DE_REPETIDO_MS = 1e3;
6266
6384
  function descartarRepetidos(consola, agregados, ahora) {
6267
6385
  for (const nodo of agregados) {
@@ -6274,7 +6392,7 @@ function descartarRepetidos(consola, agregados, ahora) {
6274
6392
  }
6275
6393
  }
6276
6394
  var ConsolaBP = () => {
6277
- (0, import_react38.useEffect)(() => {
6395
+ (0, import_react39.useEffect)(() => {
6278
6396
  const consola = document.getElementById("mini-console");
6279
6397
  if (!consola) return;
6280
6398
  const observador = new MutationObserver(
@@ -6283,8 +6401,8 @@ var ConsolaBP = () => {
6283
6401
  observador.observe(consola, { childList: true });
6284
6402
  return () => observador.disconnect();
6285
6403
  }, []);
6286
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6287
- import_material29.Box,
6404
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6405
+ import_material30.Box,
6288
6406
  {
6289
6407
  id: "mini-console",
6290
6408
  sx: (tema) => ({
@@ -6380,7 +6498,7 @@ var habilitarPuenteBP = () => {
6380
6498
  var puenteBPHabilitado = () => habilitado;
6381
6499
 
6382
6500
  // src/puente/PantallaBP.tsx
6383
- var import_jsx_runtime36 = require("react/jsx-runtime");
6501
+ var import_jsx_runtime38 = require("react/jsx-runtime");
6384
6502
  function buscarItemDeMenu(items, tipo) {
6385
6503
  for (const item of items) {
6386
6504
  if (item.menuType === tipo) return item;
@@ -6393,12 +6511,12 @@ function buscarItemDeMenu(items, tipo) {
6393
6511
  }
6394
6512
  var PantallaBP = ({ nombre, direccion }) => {
6395
6513
  const { clientContext } = useApp();
6396
- const [cargando, setCargando] = (0, import_react39.useState)(true);
6397
- const [error, setError] = (0, import_react39.useState)(null);
6398
- const [noExiste, setNoExiste] = (0, import_react39.useState)(false);
6399
- const contenedor = (0, import_react39.useRef)(null);
6514
+ const [cargando, setCargando] = (0, import_react40.useState)(true);
6515
+ const [error, setError] = (0, import_react40.useState)(null);
6516
+ const [noExiste, setNoExiste] = (0, import_react40.useState)(false);
6517
+ const contenedor = (0, import_react40.useRef)(null);
6400
6518
  const menu = clientContext.menu;
6401
- (0, import_react39.useEffect)(() => {
6519
+ (0, import_react40.useEffect)(() => {
6402
6520
  const elemento = contenedor.current;
6403
6521
  if (!elemento) return;
6404
6522
  let vigente = true;
@@ -6429,14 +6547,14 @@ var PantallaBP = ({ nombre, direccion }) => {
6429
6547
  elemento.replaceChildren();
6430
6548
  };
6431
6549
  }, [nombre, direccion, menu]);
6432
- if (noExiste) return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(FallbackWScreen, { screenName: nombre });
6550
+ if (noExiste) return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FallbackWScreen, { screenName: nombre });
6433
6551
  return (
6434
6552
  // 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
6435
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_material30.Box, { sx: { position: "relative" }, children: [
6436
- cargando && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material30.CircularProgress, { size: 24, sx: { position: "absolute", top: 16, left: 16 } }),
6437
- error && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material30.Alert, { severity: "error", sx: { m: 2 }, children: error }),
6438
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { id: "main_layout", ref: contenedor }),
6439
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ConsolaBP, {})
6553
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_material31.Box, { sx: { position: "relative" }, children: [
6554
+ cargando && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material31.CircularProgress, { size: 24, sx: { position: "absolute", top: 16, left: 16 } }),
6555
+ error && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material31.Alert, { severity: "error", sx: { m: 2 }, children: error }),
6556
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { id: "main_layout", ref: contenedor }),
6557
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ConsolaBP, {})
6440
6558
  ] })
6441
6559
  );
6442
6560
  };
@@ -6444,37 +6562,37 @@ var PantallaDeRespaldo = () => {
6444
6562
  const { screenName = "" } = (0, import_react_router_dom12.useParams)();
6445
6563
  const { search } = (0, import_react_router_dom12.useLocation)();
6446
6564
  if (!puenteBPHabilitado()) {
6447
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material30.Box, { sx: { p: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(FallbackWScreen, { screenName }) });
6565
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material31.Box, { sx: { p: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FallbackWScreen, { screenName }) });
6448
6566
  }
6449
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_router_dom12.Navigate, { to: rutaDePantallaBP(screenName, search), replace: true });
6567
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom12.Navigate, { to: rutaDePantallaBP(screenName, search), replace: true });
6450
6568
  };
6451
6569
  var PaginaBP = () => {
6452
6570
  const { hash, search } = (0, import_react_router_dom12.useLocation)();
6453
6571
  const direccion = hash || search;
6454
6572
  const nombre = new URLSearchParams(direccion.replace(/^[#?]/, "")).get("w");
6455
- if (!puenteBPHabilitado()) return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_router_dom12.Navigate, { to: "/", replace: true });
6456
- if (!nombre) return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_material30.Box, { sx: { p: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_material30.Alert, { severity: "warning", children: [
6573
+ if (!puenteBPHabilitado()) return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom12.Navigate, { to: "/", replace: true });
6574
+ if (!nombre) return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material31.Box, { sx: { p: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_material31.Alert, { severity: "warning", children: [
6457
6575
  "Falta la pantalla de backend-plus (",
6458
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("code", { children: "#w=..." }),
6576
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("code", { children: "#w=..." }),
6459
6577
  ")."
6460
6578
  ] }) });
6461
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PantallaBP, { nombre, direccion }, nombre);
6579
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PantallaBP, { nombre, direccion }, nombre);
6462
6580
  };
6463
6581
 
6464
6582
  // src/puente/GrillaBP.tsx
6465
- var import_react40 = require("react");
6583
+ var import_react41 = require("react");
6466
6584
  var import_react_router_dom13 = require("react-router-dom");
6467
- var import_material31 = require("@mui/material");
6468
- var import_jsx_runtime37 = (
6585
+ var import_material32 = require("@mui/material");
6586
+ var import_jsx_runtime39 = (
6469
6587
  // 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
6470
6588
  require("react/jsx-runtime")
6471
6589
  );
6472
6590
  var GrillaBP = ({ tabla, fixedFields }) => {
6473
- const contenedor = (0, import_react40.useRef)(null);
6474
- const [cargando, setCargando] = (0, import_react40.useState)(true);
6475
- const [error, setError] = (0, import_react40.useState)(null);
6591
+ const contenedor = (0, import_react41.useRef)(null);
6592
+ const [cargando, setCargando] = (0, import_react41.useState)(true);
6593
+ const [error, setError] = (0, import_react41.useState)(null);
6476
6594
  const clave = JSON.stringify(fixedFields ?? []);
6477
- (0, import_react40.useEffect)(() => {
6595
+ (0, import_react41.useEffect)(() => {
6478
6596
  const elemento = contenedor.current;
6479
6597
  if (!elemento) return;
6480
6598
  let vigente = true;
@@ -6495,20 +6613,20 @@ var GrillaBP = ({ tabla, fixedFields }) => {
6495
6613
  elemento.replaceChildren();
6496
6614
  };
6497
6615
  }, [tabla, clave]);
6498
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_material31.Box, { sx: { position: "relative" }, children: [
6499
- cargando && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material31.CircularProgress, { size: 24, sx: { position: "absolute", top: 16, left: 16 } }),
6500
- error && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material31.Alert, { severity: "error", sx: { m: 2 }, children: error }),
6501
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { ref: contenedor }),
6502
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ConsolaBP, {})
6616
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_material32.Box, { sx: { position: "relative" }, children: [
6617
+ cargando && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_material32.CircularProgress, { size: 24, sx: { position: "absolute", top: 16, left: 16 } }),
6618
+ error && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_material32.Alert, { severity: "error", sx: { m: 2 }, children: error }),
6619
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { ref: contenedor }),
6620
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ConsolaBP, {})
6503
6621
  ] });
6504
6622
  };
6505
6623
  var PaginaGrillaBP = () => {
6506
6624
  const { tableName = "" } = (0, import_react_router_dom13.useParams)();
6507
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(GrillaBP, { tabla: tableName }, tableName);
6625
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(GrillaBP, { tabla: tableName }, tableName);
6508
6626
  };
6509
6627
 
6510
6628
  // src/puente/CapturaBP.tsx
6511
- var import_react41 = require("react");
6629
+ var import_react42 = require("react");
6512
6630
  var import_react_router_dom14 = require("react-router-dom");
6513
6631
 
6514
6632
  // src/puente/capturaDeNavegacion.ts
@@ -6555,61 +6673,61 @@ function capturarNavegacionBP(urlBackend, navegar) {
6555
6673
  // src/puente/CapturaBP.tsx
6556
6674
  var CapturaBP = () => {
6557
6675
  const navigate = (0, import_react_router_dom14.useNavigate)();
6558
- (0, import_react41.useEffect)(() => capturarNavegacionBP(envConfig.backendUrl, navigate), [navigate]);
6676
+ (0, import_react42.useEffect)(() => capturarNavegacionBP(envConfig.backendUrl, navigate), [navigate]);
6559
6677
  return null;
6560
6678
  };
6561
6679
 
6562
6680
  // src/App.tsx
6563
6681
  var import_type_store6 = __toESM(require("type-store"), 1);
6564
- var import_jsx_runtime38 = require("react/jsx-runtime");
6682
+ var import_jsx_runtime40 = require("react/jsx-runtime");
6565
6683
  var LocationTracker = () => {
6566
6684
  const location = (0, import_react_router_dom15.useLocation)();
6567
6685
  const dispatch = useAppDispatch();
6568
- (0, import_react42.useEffect)(() => {
6686
+ (0, import_react43.useEffect)(() => {
6569
6687
  dispatch(setCurrentPath(location.pathname + location.search));
6570
6688
  }, [location, dispatch]);
6571
6689
  return null;
6572
6690
  };
6573
6691
  function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout = MainLayout_default, unloggedLayout: UnloggedLayout }) {
6574
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
6575
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(InitialRedirectHandler_default, {}),
6576
- puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CapturaBP, {}),
6577
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_router_dom15.Routes, { children: [
6578
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_router_dom15.Route, { element: UnloggedLayout ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(UnloggedLayout, {}) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Outlet, {}), children: [
6579
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "/login", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(LoginPage_default, {}) }),
6580
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "/logout", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(LogoutPage_default, {}) }),
6692
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
6693
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(InitialRedirectHandler_default, {}),
6694
+ puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(CapturaBP, {}),
6695
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_router_dom15.Routes, { children: [
6696
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_router_dom15.Route, { element: UnloggedLayout ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(UnloggedLayout, {}) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Outlet, {}), children: [
6697
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "/login", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(LoginPage_default, {}) }),
6698
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "/logout", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(LogoutPage_default, {}) }),
6581
6699
  myUnloggedRoutes
6582
6700
  ] }),
6583
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_router_dom15.Route, { element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PrivateRoute_default, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Layout, {}) }), children: [
6584
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PantallaInicial_default, {}) }),
6585
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "/table/:tableName", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(GenericDataGridPage_default, {}) }),
6586
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "/menu/:menuName", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(MenuTablePage_default, {}) }),
6587
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "/procedures/:procedureName", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ProcedureForm_default, {}) }),
6588
- Object.keys(wScreens).map((screenName) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6701
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_router_dom15.Route, { element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PrivateRoute_default, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Layout, {}) }), children: [
6702
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PantallaInicial_default, {}) }),
6703
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "/table/:tableName", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(GenericDataGridPage_default, {}) }),
6704
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "/menu/*", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MenuTablePage_default, {}) }),
6705
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "/procedures/:procedureName", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ProcedureForm_default, {}) }),
6706
+ Object.keys(wScreens).map((screenName) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
6589
6707
  import_react_router_dom15.Route,
6590
6708
  {
6591
6709
  path: `/wScreens/${screenName}`,
6592
- element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PantallaDeRuta, { screenName })
6710
+ element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PantallaDeRuta, { screenName })
6593
6711
  },
6594
6712
  screenName
6595
6713
  )),
6596
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "/wScreens-fallback/:screenName", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PantallaDeRespaldo, {}) }),
6597
- puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "/bp/menu", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PaginaBP, {}) }),
6598
- puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "/bp/table/:tableName", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PaginaGrillaBP, {}) }),
6714
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "/wScreens-fallback/:screenName", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PantallaDeRespaldo, {}) }),
6715
+ puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "/bp/menu", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PaginaBP, {}) }),
6716
+ puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "/bp/table/:tableName", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PaginaGrillaBP, {}) }),
6599
6717
  myRoutes,
6600
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
6718
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
6601
6719
  ] }),
6602
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom15.Navigate, { to: "/", replace: true }) })
6720
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_router_dom15.Navigate, { to: "/", replace: true }) })
6603
6721
  ] })
6604
6722
  ] });
6605
6723
  }
6606
6724
  var FrontendPlusProviders = ({ children, publicPaths }) => {
6607
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_redux5.Provider, { store, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react43.PersistGate, { loading: null, persistor, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_router_dom15.BrowserRouter, { basename: rutaBase, children: [
6608
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(LocationTracker, {}),
6725
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_redux5.Provider, { store, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react44.PersistGate, { loading: null, persistor, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_router_dom15.BrowserRouter, { basename: rutaBase, children: [
6726
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(LocationTracker, {}),
6609
6727
  " ",
6610
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(AppProvider, { publicPaths, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(SnackbarProvider, { children: [
6728
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(AppProvider, { publicPaths, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(SnackbarProvider, { children: [
6611
6729
  children,
6612
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SessionExpiredMessage_default, {})
6730
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(SessionExpiredMessage_default, {})
6613
6731
  ] }) })
6614
6732
  ] }) }) });
6615
6733
  };
@@ -6623,7 +6741,7 @@ var App = ({
6623
6741
  myConditions,
6624
6742
  puenteBP
6625
6743
  }) => {
6626
- (0, import_react42.useMemo)(() => {
6744
+ (0, import_react43.useMemo)(() => {
6627
6745
  if (myClientSides) {
6628
6746
  extendClientSides(myClientSides);
6629
6747
  }
@@ -6640,7 +6758,7 @@ var App = ({
6640
6758
  habilitarPuenteBP();
6641
6759
  }
6642
6760
  }, [myClientSides, myResultsOk, myWScreens, myConditions, puenteBP]);
6643
- (0, import_react42.useEffect)(() => {
6761
+ (0, import_react43.useEffect)(() => {
6644
6762
  import_type_store6.default.messages = import_type_store6.default.i18n.messages.es;
6645
6763
  import_type_store6.default.locale = import_type_store6.default.i18n.locale.es;
6646
6764
  const link = document.querySelector("link[rel*='icon']") || document.createElement("link");
@@ -6649,11 +6767,11 @@ var App = ({
6649
6767
  link.href = `${envConfig.backendUrl}/img/logo-128.png`;
6650
6768
  document.getElementsByTagName("head")[0].appendChild(link);
6651
6769
  }, []);
6652
- const safePaths = import_react42.default.useMemo(() => {
6770
+ const safePaths = import_react43.default.useMemo(() => {
6653
6771
  const extracted = extractPathsFromRoutes(myUnloggedRoutes);
6654
6772
  return ["/login", "/logout", ...extracted];
6655
6773
  }, [myUnloggedRoutes]);
6656
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6774
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
6657
6775
  FrontendPlusReactRoutes,
6658
6776
  {
6659
6777
  myRoutes,