frontend-plus-react 0.7.0 → 0.8.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/CLAUDE.md +17 -1
- package/README.md +1 -0
- package/dist/index.cjs +614 -261
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +8 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +687 -334
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -456,8 +456,9 @@ var import_toolkit2 = require("@reduxjs/toolkit");
|
|
|
456
456
|
var initialState2 = {
|
|
457
457
|
currentPath: "/",
|
|
458
458
|
previousPath: null,
|
|
459
|
-
redirectPath: null
|
|
459
|
+
redirectPath: null,
|
|
460
460
|
// <--- Inicializamos en null
|
|
461
|
+
redirectUsername: null
|
|
461
462
|
};
|
|
462
463
|
var routerSlice = (0, import_toolkit2.createSlice)({
|
|
463
464
|
name: "router",
|
|
@@ -469,15 +470,20 @@ var routerSlice = (0, import_toolkit2.createSlice)({
|
|
|
469
470
|
},
|
|
470
471
|
setRedirectPath: (state, action) => {
|
|
471
472
|
state.redirectPath = action.payload;
|
|
473
|
+
if (action.payload === null) state.redirectUsername = null;
|
|
474
|
+
},
|
|
475
|
+
setRedirectUsername: (state, action) => {
|
|
476
|
+
state.redirectUsername = action.payload;
|
|
472
477
|
},
|
|
473
478
|
resetRouterState: (state) => {
|
|
474
479
|
state.currentPath = "/";
|
|
475
480
|
state.previousPath = null;
|
|
476
481
|
state.redirectPath = null;
|
|
482
|
+
state.redirectUsername = null;
|
|
477
483
|
}
|
|
478
484
|
}
|
|
479
485
|
});
|
|
480
|
-
var { setCurrentPath, setRedirectPath, resetRouterState } = routerSlice.actions;
|
|
486
|
+
var { setCurrentPath, setRedirectPath, setRedirectUsername, resetRouterState } = routerSlice.actions;
|
|
481
487
|
var routerSlice_default = routerSlice.reducer;
|
|
482
488
|
|
|
483
489
|
// src/store/menuUiSlice.ts
|
|
@@ -502,13 +508,23 @@ var menuUiSlice = (0, import_toolkit3.createSlice)({
|
|
|
502
508
|
toggleSubMenu: (state, action) => {
|
|
503
509
|
state.subMenuOpenStates[action.payload] = !state.subMenuOpenStates[action.payload];
|
|
504
510
|
},
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
for (const
|
|
508
|
-
if (
|
|
509
|
-
state.subMenuOpenStates[
|
|
511
|
+
/** Acordeón: abre un grupo y cierra a sus hermanos (con todo lo que tienen adentro). */
|
|
512
|
+
abrirGrupo: (state, action) => {
|
|
513
|
+
for (const clave of Object.keys(state.subMenuOpenStates)) {
|
|
514
|
+
if (action.payload.hermanos.some((hermano) => clave === hermano || clave.startsWith(hermano + "/"))) {
|
|
515
|
+
state.subMenuOpenStates[clave] = false;
|
|
510
516
|
}
|
|
511
517
|
}
|
|
518
|
+
state.subMenuOpenStates[action.payload.clave] = true;
|
|
519
|
+
},
|
|
520
|
+
/** Deja abiertos solo los grupos de este camino (el del ítem que se está mostrando). */
|
|
521
|
+
abrirCamino: (state, action) => {
|
|
522
|
+
for (const clave of Object.keys(state.subMenuOpenStates)) {
|
|
523
|
+
state.subMenuOpenStates[clave] = action.payload.includes(clave);
|
|
524
|
+
}
|
|
525
|
+
for (const clave of action.payload) {
|
|
526
|
+
state.subMenuOpenStates[clave] = true;
|
|
527
|
+
}
|
|
512
528
|
},
|
|
513
529
|
resetMenuUiState: (state) => {
|
|
514
530
|
Object.assign(state, initialState3);
|
|
@@ -520,8 +536,8 @@ var {
|
|
|
520
536
|
toggleDrawer,
|
|
521
537
|
setSubMenuOpen,
|
|
522
538
|
toggleSubMenu,
|
|
523
|
-
|
|
524
|
-
|
|
539
|
+
abrirGrupo,
|
|
540
|
+
abrirCamino,
|
|
525
541
|
resetMenuUiState
|
|
526
542
|
} = menuUiSlice.actions;
|
|
527
543
|
var menuUiSlice_default = menuUiSlice.reducer;
|
|
@@ -2048,9 +2064,10 @@ var defaultColumnHeaderCellRenderer = (props, fieldDef, ocultarColumna) => {
|
|
|
2048
2064
|
{
|
|
2049
2065
|
variant: "body2",
|
|
2050
2066
|
sx: {
|
|
2051
|
-
fontWeight:
|
|
2067
|
+
fontWeight: 500,
|
|
2068
|
+
color: "#37474f",
|
|
2052
2069
|
textDecoration: isPrimaryKey ? "underline" : "none",
|
|
2053
|
-
fontSize: "0.
|
|
2070
|
+
fontSize: "0.85rem",
|
|
2054
2071
|
textAlign: "left",
|
|
2055
2072
|
flexGrow: 1,
|
|
2056
2073
|
overflow: "hidden",
|
|
@@ -2076,22 +2093,20 @@ var ActionsColumnHeaderCell = ({
|
|
|
2076
2093
|
allowInsert && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2077
2094
|
import_material4.IconButton,
|
|
2078
2095
|
{
|
|
2079
|
-
color: "inherit",
|
|
2080
2096
|
onClick: () => handleAddRow(),
|
|
2081
2097
|
size: "small",
|
|
2082
2098
|
title: "A\xF1adir registro",
|
|
2083
|
-
sx: { p: 0.25 },
|
|
2084
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_Add.default, { sx: { fontSize: 18
|
|
2099
|
+
sx: { p: 0.25, color: "grey.800", "&:hover": { color: "success.main" } },
|
|
2100
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_Add.default, { sx: { fontSize: 18 } })
|
|
2085
2101
|
}
|
|
2086
2102
|
),
|
|
2087
2103
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2088
2104
|
import_material4.IconButton,
|
|
2089
2105
|
{
|
|
2090
|
-
color: "inherit",
|
|
2091
2106
|
onClick: toggleFilterVisibility,
|
|
2092
2107
|
size: "small",
|
|
2093
2108
|
title: isFilterRowVisible ? "Ocultar filtros" : "Mostrar filtros",
|
|
2094
|
-
sx: { p: 0.25 },
|
|
2109
|
+
sx: { p: 0.25, color: "grey.800" },
|
|
2095
2110
|
children: isFilterRowVisible ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_SearchOff.default, { sx: { fontSize: 18 } }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_Search.default, { sx: { fontSize: 18 } })
|
|
2096
2111
|
}
|
|
2097
2112
|
),
|
|
@@ -2101,7 +2116,7 @@ var ActionsColumnHeaderCell = ({
|
|
|
2101
2116
|
onClick: (event) => handleDataGridOptions(event),
|
|
2102
2117
|
size: "small",
|
|
2103
2118
|
title: "Opciones de esta tabla",
|
|
2104
|
-
sx: { p: 0.25 },
|
|
2119
|
+
sx: { p: 0.25, color: "grey.800" },
|
|
2105
2120
|
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_MoreVert.default, { sx: { fontSize: 20, variant: "filled", size: "small" } })
|
|
2106
2121
|
}
|
|
2107
2122
|
)
|
|
@@ -2582,9 +2597,12 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
2582
2597
|
"& .MuiOutlinedInput-root": {
|
|
2583
2598
|
backgroundColor: "background.paper",
|
|
2584
2599
|
height: FILTER_ROW_HEIGHT - 5,
|
|
2585
|
-
minWidth:
|
|
2600
|
+
minWidth: 30,
|
|
2586
2601
|
fontSize: "0.8rem",
|
|
2587
2602
|
padding: "0px"
|
|
2603
|
+
},
|
|
2604
|
+
"& .MuiOutlinedInput-input": {
|
|
2605
|
+
padding: "0 4px"
|
|
2588
2606
|
}
|
|
2589
2607
|
} : {
|
|
2590
2608
|
"& .MuiOutlinedInput-root": {
|
|
@@ -2608,7 +2626,10 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
2608
2626
|
};
|
|
2609
2627
|
|
|
2610
2628
|
// src/components/grid/FilterInputRender.tsx
|
|
2611
|
-
var import_jsx_runtime12 =
|
|
2629
|
+
var import_jsx_runtime12 = (
|
|
2630
|
+
// como en backend-plus, el operador es un símbolo chico y el campo se queda con el resto del ancho
|
|
2631
|
+
require("react/jsx-runtime")
|
|
2632
|
+
);
|
|
2612
2633
|
function FilterInputRenderer({
|
|
2613
2634
|
columnKey,
|
|
2614
2635
|
currentFilter,
|
|
@@ -2631,7 +2652,7 @@ function FilterInputRenderer({
|
|
|
2631
2652
|
[columnKey]: { operator: newOp, value: formattedVal }
|
|
2632
2653
|
}));
|
|
2633
2654
|
};
|
|
2634
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material9.Box, { sx: { mt: 0, display: "flex", alignItems: "center", gap:
|
|
2655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material9.Box, { sx: { mt: 0, display: "flex", alignItems: "center", gap: "2px", width: "100%" }, children: [
|
|
2635
2656
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2636
2657
|
"select",
|
|
2637
2658
|
{
|
|
@@ -2639,13 +2660,16 @@ function FilterInputRenderer({
|
|
|
2639
2660
|
onChange: (e) => handleFilterChange(e.target.value, val),
|
|
2640
2661
|
style: {
|
|
2641
2662
|
height: FILTER_ROW_HEIGHT - 5,
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2663
|
+
width: 22,
|
|
2664
|
+
flexShrink: 0,
|
|
2665
|
+
appearance: "none",
|
|
2666
|
+
backgroundColor: "#CEF",
|
|
2667
|
+
border: "none",
|
|
2645
2668
|
borderRadius: "4px",
|
|
2646
2669
|
fontSize: "0.8rem",
|
|
2647
|
-
padding:
|
|
2670
|
+
padding: 0,
|
|
2648
2671
|
textAlign: "center",
|
|
2672
|
+
textAlignLast: "center",
|
|
2649
2673
|
cursor: "pointer"
|
|
2650
2674
|
},
|
|
2651
2675
|
children: filterOperators.map((op) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: op.value, children: op.label }, op.value))
|
|
@@ -2696,7 +2720,7 @@ var defaultColumnSummaryCellRenderer = (props, fixedFields) => {
|
|
|
2696
2720
|
const { filters, setFilters } = row;
|
|
2697
2721
|
if (valorFijoDe(fixedFields, column.key)) return null;
|
|
2698
2722
|
const fieldDef = esColumnaPropia(column) && column.customType === "default" ? column.fieldDef : void 0;
|
|
2699
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Box, { sx: {
|
|
2723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Box, { sx: { position: "absolute", inset: 0, display: "flex", alignItems: "center", px: "2px" }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2700
2724
|
FilterInputRender_default,
|
|
2701
2725
|
{
|
|
2702
2726
|
columnKey: column.key,
|
|
@@ -2923,14 +2947,12 @@ var allColumnsCellRenderer = (props) => {
|
|
|
2923
2947
|
}
|
|
2924
2948
|
];
|
|
2925
2949
|
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.
|
|
2950
|
+
import_material13.IconButton,
|
|
2927
2951
|
{
|
|
2928
|
-
variant: "outlined",
|
|
2929
|
-
color: actionDef.color,
|
|
2930
2952
|
size: "small",
|
|
2931
2953
|
onClick: () => actionDef.handler(row),
|
|
2932
2954
|
title: actionDef.title,
|
|
2933
|
-
sx: { width: 22,
|
|
2955
|
+
sx: { width: 22, height: 22, p: 0, color: "grey.800", "&:hover": { color: `${actionDef.color}.main` } },
|
|
2934
2956
|
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(actionDef.icon, { sx: { fontSize: 18 } })
|
|
2935
2957
|
},
|
|
2936
2958
|
actionDef.action
|
|
@@ -3340,20 +3362,36 @@ function campoDibujable(field) {
|
|
|
3340
3362
|
|
|
3341
3363
|
// src/hooks/grid/useGridColumns.ts
|
|
3342
3364
|
var estimateTextWidth = (text) => text.length * 8 + 16;
|
|
3343
|
-
var
|
|
3365
|
+
var contextoDeMedida;
|
|
3366
|
+
var anchoDeTitulo = (texto) => {
|
|
3367
|
+
if (contextoDeMedida === void 0) {
|
|
3368
|
+
try {
|
|
3369
|
+
contextoDeMedida = document.createElement("canvas").getContext("2d");
|
|
3370
|
+
} catch {
|
|
3371
|
+
contextoDeMedida = null;
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
if (!contextoDeMedida) return texto.length * 9;
|
|
3375
|
+
contextoDeMedida.font = "bold 14.9px Roboto, Helvetica, Arial, sans-serif";
|
|
3376
|
+
return Math.ceil(contextoDeMedida.measureText(texto).width);
|
|
3377
|
+
};
|
|
3378
|
+
var EXTRA_TITULO = 8 + 20 + 4;
|
|
3379
|
+
var calcularAnchosDeColumnas = (tableDefinition, filas, anchoDisponible = Infinity) => {
|
|
3344
3380
|
const anchos = /* @__PURE__ */ new Map();
|
|
3381
|
+
const anchosConTituloCompleto = /* @__PURE__ */ new Map();
|
|
3345
3382
|
const muestra = filas.slice(0, 50);
|
|
3346
3383
|
tableDefinition.fields.forEach((fieldDef) => {
|
|
3347
3384
|
if (typeof fieldDef.width === "number" && fieldDef.width > 0) {
|
|
3348
3385
|
anchos.set(fieldDef.name, fieldDef.width);
|
|
3386
|
+
anchosConTituloCompleto.set(fieldDef.name, fieldDef.width);
|
|
3349
3387
|
return;
|
|
3350
3388
|
}
|
|
3351
3389
|
const headerLabel = fieldDef.label || fieldDef.name;
|
|
3352
3390
|
const type = fieldDef.typeName?.toLowerCase() || "";
|
|
3353
|
-
let typeMinWidth =
|
|
3354
|
-
if (type.includes("boolean") || type.includes("checkbox")) typeMinWidth =
|
|
3355
|
-
else if (type.includes("date") || type.includes("timestamp")) typeMinWidth =
|
|
3356
|
-
else if (type.includes("integer") || type.includes("numeric")) typeMinWidth =
|
|
3391
|
+
let typeMinWidth = 80;
|
|
3392
|
+
if (type.includes("boolean") || type.includes("checkbox")) typeMinWidth = 80;
|
|
3393
|
+
else if (type.includes("date") || type.includes("timestamp")) typeMinWidth = 120;
|
|
3394
|
+
else if (type.includes("integer") || type.includes("numeric")) typeMinWidth = 90;
|
|
3357
3395
|
const headerWidth = estimateTextWidth(headerLabel) + 20;
|
|
3358
3396
|
const typer = typerFrom(fieldDef);
|
|
3359
3397
|
const maxDataWidth = muestra.reduce((maxW, row) => {
|
|
@@ -3367,9 +3405,12 @@ var calcularAnchosDeColumnas = (tableDefinition, filas) => {
|
|
|
3367
3405
|
}
|
|
3368
3406
|
return Math.max(maxW, estimateTextWidth(texto));
|
|
3369
3407
|
}, 0);
|
|
3370
|
-
|
|
3408
|
+
const compacto = Math.min(Math.max(headerWidth, maxDataWidth, typeMinWidth), 500);
|
|
3409
|
+
anchos.set(fieldDef.name, compacto);
|
|
3410
|
+
anchosConTituloCompleto.set(fieldDef.name, Math.max(compacto, Math.min(anchoDeTitulo(cambiarGuionesBajosPorEspacios(headerLabel)) + EXTRA_TITULO, 500)));
|
|
3371
3411
|
});
|
|
3372
|
-
|
|
3412
|
+
const sumaCompleta = [...anchos.keys()].reduce((total, nombre) => total + (anchosConTituloCompleto.get(nombre) ?? 0), 0);
|
|
3413
|
+
return sumaCompleta <= anchoDisponible ? anchosConTituloCompleto : anchos;
|
|
3373
3414
|
};
|
|
3374
3415
|
var useGridColumns = ({
|
|
3375
3416
|
tableDefinition,
|
|
@@ -4094,6 +4135,7 @@ var ALTO_TITULO_ANIDADA = 26;
|
|
|
4094
4135
|
var ALTO_MINIMO_CUERPO_ANIDADA = 120;
|
|
4095
4136
|
var HOLGURA_ANIDADA = 24;
|
|
4096
4137
|
var ANCHO_MINIMO_ANIDADA = 240;
|
|
4138
|
+
var ANCHO_RESERVADO_PANTALLA = 320;
|
|
4097
4139
|
var SANGRIA_DETALLE = 28 + 8 + 3;
|
|
4098
4140
|
var MARGEN_INFERIOR_PAGINA = 24;
|
|
4099
4141
|
var PRIMERAS_FILAS_ANIDADA = 20;
|
|
@@ -4309,7 +4351,7 @@ var GenericDataGrid = ({
|
|
|
4309
4351
|
const firstDisplayCount = tableDefinition?.firstDisplayCount ?? PRIMERAS_FILAS_ANIDADA;
|
|
4310
4352
|
const firstDisplayOverLimit = tableDefinition?.firstDisplayOverLimit ?? LIMITE_PRIMERAS_FILAS_ANIDADA;
|
|
4311
4353
|
const filasVisiblesMax = anidada ? filteredRows.length <= firstDisplayOverLimit ? filteredRows.length : firstDisplayCount : void 0;
|
|
4312
|
-
const conPie =
|
|
4354
|
+
const conPie = !!tableDefinition?.fields.some((field) => field.aggregate);
|
|
4313
4355
|
const { gridHeight, bottomSummaryRow, summaryRows, filterHeight } = useGridLayout({
|
|
4314
4356
|
filteredRows,
|
|
4315
4357
|
isFilterRowVisible,
|
|
@@ -4403,7 +4445,7 @@ var GenericDataGrid = ({
|
|
|
4403
4445
|
const definition = parametros.tableDef ? fusionar(definicionDelServidor, parametros.tableDef) : definicionDelServidor;
|
|
4404
4446
|
setTableDefinition(definition);
|
|
4405
4447
|
setSortColumns(getInitialSortColumns(definition));
|
|
4406
|
-
setAnchosCalculados(calcularAnchosDeColumnas(definition, data));
|
|
4448
|
+
setAnchosCalculados(calcularAnchosDeColumnas(definition, data, window.innerWidth - ANCHO_RESERVADO_PANTALLA));
|
|
4407
4449
|
setColumnasOcultas(columnasOcultasIniciales(definition));
|
|
4408
4450
|
setTableData(data);
|
|
4409
4451
|
const filasDeFiltros = parametros.filterColumns ?? aFiltrosIniciales(definition.filterColumns);
|
|
@@ -4604,7 +4646,7 @@ var GenericDataGrid = ({
|
|
|
4604
4646
|
[exitingRowIds, primaryKey]
|
|
4605
4647
|
);
|
|
4606
4648
|
const anchoContenido = (0, import_react26.useMemo)(() => {
|
|
4607
|
-
if (
|
|
4649
|
+
if (columns.length === 0) return void 0;
|
|
4608
4650
|
const sumaColumnas = columns.reduce((total, col) => {
|
|
4609
4651
|
const medido = columnWidths.get(col.key)?.width;
|
|
4610
4652
|
return total + (typeof medido === "number" ? medido : typeof col.width === "number" ? col.width : 100);
|
|
@@ -4614,8 +4656,9 @@ var GenericDataGrid = ({
|
|
|
4614
4656
|
return Math.max(ANCHO_MINIMO_ANIDADA, propio, anchoDetalleMax > 0 ? anchoDetalleMax + SANGRIA_DETALLE + (medidas?.barra ?? 0) + 2 : 0);
|
|
4615
4657
|
}, [anidada, columns, columnWidths, medidas?.barra, detallesAbiertos, anchosDetalle]);
|
|
4616
4658
|
(0, import_react26.useEffect)(() => {
|
|
4617
|
-
if (anchoContenido !== void 0) onAnchoDeseado?.(anchoContenido);
|
|
4618
|
-
}, [onAnchoDeseado, anchoContenido]);
|
|
4659
|
+
if (anidada && anchoContenido !== void 0) onAnchoDeseado?.(anchoContenido);
|
|
4660
|
+
}, [onAnchoDeseado, anidada, anchoContenido]);
|
|
4661
|
+
const anchoExterior = anchoContenido === void 0 ? void 0 : anidada ? anchoContenido : anchoContenido - 2 + 32 + ancestors.length * 32;
|
|
4619
4662
|
const estiloGrilla = (0, import_react26.useMemo)(() => ({ height: "100%", width: "100%", boxSizing: "border-box", ...gridStyles }), [gridStyles]);
|
|
4620
4663
|
const bottomSummaryRows = (0, import_react26.useMemo)(() => conPie ? [bottomSummaryRow] : [], [conPie, bottomSummaryRow]);
|
|
4621
4664
|
const vistaGrilla = (0, import_react26.useMemo)(() => ({ isFilterRowVisible }), [isFilterRowVisible]);
|
|
@@ -4641,7 +4684,7 @@ var GenericDataGrid = ({
|
|
|
4641
4684
|
if (!tableDefinition) {
|
|
4642
4685
|
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." }) });
|
|
4643
4686
|
}
|
|
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:
|
|
4687
|
+
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: anchoExterior, maxWidth: "100%" }, children: [
|
|
4645
4688
|
!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)(
|
|
4646
4689
|
StaticAncestorGrid,
|
|
4647
4690
|
{
|
|
@@ -4738,7 +4781,7 @@ var GenericDataGrid = ({
|
|
|
4738
4781
|
sx: {
|
|
4739
4782
|
position: "absolute",
|
|
4740
4783
|
top: filterHeight + HEADER_ROW_HEIGHT + 1,
|
|
4741
|
-
bottom: anidada ? (conPie ? SUMMARY_ROW_HEIGHT : 0) + 4 : 102,
|
|
4784
|
+
bottom: anidada ? (conPie ? SUMMARY_ROW_HEIGHT : 0) + 4 : conPie ? 102 : 102 - SUMMARY_ROW_HEIGHT,
|
|
4742
4785
|
left: 18,
|
|
4743
4786
|
right: 0,
|
|
4744
4787
|
display: "flex",
|
|
@@ -4863,8 +4906,8 @@ var GenericDataGrid = ({
|
|
|
4863
4906
|
var GenericDataGrid_default = GenericDataGrid;
|
|
4864
4907
|
|
|
4865
4908
|
// src/App.tsx
|
|
4866
|
-
var
|
|
4867
|
-
var
|
|
4909
|
+
var import_react44 = __toESM(require("react"), 1);
|
|
4910
|
+
var import_react_router_dom18 = require("react-router-dom");
|
|
4868
4911
|
|
|
4869
4912
|
// src/components/MainLayout.tsx
|
|
4870
4913
|
var import_react30 = require("react");
|
|
@@ -4875,6 +4918,15 @@ var import_material21 = require("@mui/material");
|
|
|
4875
4918
|
var import_react27 = require("react");
|
|
4876
4919
|
var import_react_router_dom = require("react-router-dom");
|
|
4877
4920
|
var import_react_redux2 = require("react-redux");
|
|
4921
|
+
|
|
4922
|
+
// src/utils/cierreVoluntario.ts
|
|
4923
|
+
var cierreVoluntario = false;
|
|
4924
|
+
var marcarCierreVoluntario = (activo) => {
|
|
4925
|
+
cierreVoluntario = activo;
|
|
4926
|
+
};
|
|
4927
|
+
var huboCierreVoluntario = () => cierreVoluntario;
|
|
4928
|
+
|
|
4929
|
+
// src/contexts/AppContext.tsx
|
|
4878
4930
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4879
4931
|
var AuthContext = (0, import_react27.createContext)(void 0);
|
|
4880
4932
|
var useApp = () => {
|
|
@@ -4891,9 +4943,10 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4891
4943
|
const [showSessionExpiredMessage, setShowSessionExpiredMessage] = (0, import_react27.useState)(false);
|
|
4892
4944
|
const isRedirectingRef = (0, import_react27.useRef)(false);
|
|
4893
4945
|
const huboSesionRef = (0, import_react27.useRef)(false);
|
|
4946
|
+
const cierreVoluntarioRef = (0, import_react27.useRef)(false);
|
|
4894
4947
|
const dispatch = (0, import_react_redux2.useDispatch)();
|
|
4895
4948
|
const clientContext = (0, import_react_redux2.useSelector)((state) => state.clientContext);
|
|
4896
|
-
if (clientContext.status === "succeeded") huboSesionRef.current = true;
|
|
4949
|
+
if (clientContext.status === "succeeded" && !cierreVoluntarioRef.current) huboSesionRef.current = true;
|
|
4897
4950
|
const navigate = (0, import_react_router_dom.useNavigate)();
|
|
4898
4951
|
const handleExpiredSessionRedirect = (0, import_react27.useCallback)(() => {
|
|
4899
4952
|
isRedirectingRef.current = true;
|
|
@@ -4904,6 +4957,17 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4904
4957
|
isRedirectingRef.current = false;
|
|
4905
4958
|
}, 2e3);
|
|
4906
4959
|
}, [navigate]);
|
|
4960
|
+
const avisarCierreVoluntario = (0, import_react27.useCallback)((activo) => {
|
|
4961
|
+
cierreVoluntarioRef.current = activo;
|
|
4962
|
+
marcarCierreVoluntario(activo);
|
|
4963
|
+
if (activo) huboSesionRef.current = false;
|
|
4964
|
+
}, []);
|
|
4965
|
+
const limpiarContextoPorSesionPerdida = (0, import_react27.useCallback)(() => {
|
|
4966
|
+
if (clientContext.status === "succeeded" && clientContext.username !== "" && !cierreVoluntarioRef.current) {
|
|
4967
|
+
dispatch(setRedirectUsername(clientContext.username));
|
|
4968
|
+
}
|
|
4969
|
+
dispatch(clearClientContext());
|
|
4970
|
+
}, [dispatch, clientContext.status, clientContext.username]);
|
|
4907
4971
|
const location = (0, import_react_router_dom.useLocation)();
|
|
4908
4972
|
const isCurrentPathPublic = (0, import_react27.useCallback)(() => {
|
|
4909
4973
|
const current = location.pathname;
|
|
@@ -4929,8 +4993,8 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4929
4993
|
}
|
|
4930
4994
|
} else {
|
|
4931
4995
|
setIsLoggedIn(false);
|
|
4932
|
-
|
|
4933
|
-
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current) {
|
|
4996
|
+
limpiarContextoPorSesionPerdida();
|
|
4997
|
+
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current && !cierreVoluntarioRef.current) {
|
|
4934
4998
|
console.warn("Sesi\xF3n inv\xE1lida en ruta protegida. Mostrando modal.");
|
|
4935
4999
|
setShowSessionExpiredMessage(true);
|
|
4936
5000
|
} else {
|
|
@@ -4940,13 +5004,13 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4940
5004
|
} catch (error) {
|
|
4941
5005
|
console.error("Error checking session:", error);
|
|
4942
5006
|
setIsLoggedIn(false);
|
|
4943
|
-
|
|
5007
|
+
limpiarContextoPorSesionPerdida();
|
|
4944
5008
|
const isPublic = publicPaths.some((p) => location.pathname === p || location.pathname.startsWith(p + "/"));
|
|
4945
|
-
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current) {
|
|
5009
|
+
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current && !cierreVoluntarioRef.current) {
|
|
4946
5010
|
setShowSessionExpiredMessage(true);
|
|
4947
5011
|
}
|
|
4948
5012
|
}
|
|
4949
|
-
}, [dispatch, clientContext.status, showSessionExpiredMessage, isCurrentPathPublic]);
|
|
5013
|
+
}, [dispatch, clientContext.status, showSessionExpiredMessage, isCurrentPathPublic, limpiarContextoPorSesionPerdida]);
|
|
4950
5014
|
(0, import_react27.useEffect)(() => {
|
|
4951
5015
|
checkSession();
|
|
4952
5016
|
const intervalId = setInterval(checkSession, 15 * 1e3);
|
|
@@ -4960,20 +5024,24 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4960
5024
|
checkSession,
|
|
4961
5025
|
showSessionExpiredMessage,
|
|
4962
5026
|
setShowSessionExpiredMessage,
|
|
4963
|
-
handleExpiredSessionRedirect
|
|
5027
|
+
handleExpiredSessionRedirect,
|
|
5028
|
+
avisarCierreVoluntario
|
|
4964
5029
|
}), [
|
|
4965
5030
|
isLoggedIn,
|
|
4966
5031
|
setIsLoggedIn,
|
|
4967
5032
|
checkSession,
|
|
4968
5033
|
showSessionExpiredMessage,
|
|
4969
5034
|
setShowSessionExpiredMessage,
|
|
4970
|
-
handleExpiredSessionRedirect
|
|
5035
|
+
handleExpiredSessionRedirect,
|
|
5036
|
+
avisarCierreVoluntario
|
|
4971
5037
|
]);
|
|
4972
5038
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AuthContext.Provider, { value: authContextValue, children });
|
|
4973
5039
|
};
|
|
4974
5040
|
|
|
4975
5041
|
// src/components/MainLayout.tsx
|
|
5042
|
+
var import_react_router_dom5 = require("react-router-dom");
|
|
4976
5043
|
var import_Logout = __toESM(require("@mui/icons-material/Logout"), 1);
|
|
5044
|
+
var import_VpnKey = __toESM(require("@mui/icons-material/VpnKey"), 1);
|
|
4977
5045
|
var import_Menu = __toESM(require("@mui/icons-material/Menu"), 1);
|
|
4978
5046
|
var import_ChevronLeft = __toESM(require("@mui/icons-material/ChevronLeft"), 1);
|
|
4979
5047
|
|
|
@@ -4987,11 +5055,18 @@ var import_Folder = __toESM(require("@mui/icons-material/Folder"), 1);
|
|
|
4987
5055
|
var import_Dns = __toESM(require("@mui/icons-material/Dns"), 1);
|
|
4988
5056
|
var import_WarningAmber3 = __toESM(require("@mui/icons-material/WarningAmber"), 1);
|
|
4989
5057
|
var import_DesktopWindows = __toESM(require("@mui/icons-material/DesktopWindows"), 1);
|
|
4990
|
-
var
|
|
4991
|
-
var
|
|
5058
|
+
var import_Search3 = __toESM(require("@mui/icons-material/Search"), 1);
|
|
5059
|
+
var import_Clear = __toESM(require("@mui/icons-material/Clear"), 1);
|
|
4992
5060
|
var import_react_router_dom2 = require("react-router-dom");
|
|
4993
5061
|
var import_colors = require("@mui/material/colors");
|
|
4994
5062
|
|
|
5063
|
+
// src/puente/habilitacion.ts
|
|
5064
|
+
var habilitado = false;
|
|
5065
|
+
var habilitarPuenteBP = () => {
|
|
5066
|
+
habilitado = true;
|
|
5067
|
+
};
|
|
5068
|
+
var puenteBPHabilitado = () => habilitado;
|
|
5069
|
+
|
|
4995
5070
|
// src/utils/menuInicial.ts
|
|
4996
5071
|
function rutaDeTablaDeMenu(camino) {
|
|
4997
5072
|
return `/menu/${camino.map(encodeURIComponent).join("/")}`;
|
|
@@ -5042,16 +5117,93 @@ function itemInicial(menu) {
|
|
|
5042
5117
|
return elegido.menuType === "menu" ? itemInicial(elegido.menuContent) : elegido;
|
|
5043
5118
|
}
|
|
5044
5119
|
|
|
5120
|
+
// src/utils/busquedaDeMenu.ts
|
|
5121
|
+
function etiquetaDeItem(item) {
|
|
5122
|
+
return item.label || item.name;
|
|
5123
|
+
}
|
|
5124
|
+
function claveDeMenu(camino) {
|
|
5125
|
+
return camino.join("/");
|
|
5126
|
+
}
|
|
5127
|
+
function hojasDeMenu(menu, grupos = [], etiquetasDeGrupos = []) {
|
|
5128
|
+
return menu.flatMap(
|
|
5129
|
+
(item) => item.menuType === "menu" ? hojasDeMenu(item.menuContent, [...grupos, item.name], [...etiquetasDeGrupos, etiquetaDeItem(item)]) : [{ item, grupos, etiquetasDeGrupos, clave: claveDeMenu([...grupos, item.name]) }]
|
|
5130
|
+
);
|
|
5131
|
+
}
|
|
5132
|
+
function normalizarParaBuscar(texto) {
|
|
5133
|
+
return texto.normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/_/g, " ").toLowerCase();
|
|
5134
|
+
}
|
|
5135
|
+
function buscarEnMenu(hojas, consulta) {
|
|
5136
|
+
const palabras = normalizarParaBuscar(consulta).split(/\s+/).filter((palabra) => palabra !== "");
|
|
5137
|
+
if (palabras.length === 0) return [];
|
|
5138
|
+
const propias = [];
|
|
5139
|
+
const porGrupo = [];
|
|
5140
|
+
for (const hoja of hojas) {
|
|
5141
|
+
const propia = normalizarParaBuscar(`${etiquetaDeItem(hoja.item)} ${hoja.item.name}`);
|
|
5142
|
+
const completa = `${hoja.etiquetasDeGrupos.map(normalizarParaBuscar).join(" ")} ${propia}`;
|
|
5143
|
+
if (!palabras.every((palabra) => completa.includes(palabra))) continue;
|
|
5144
|
+
(palabras.every((palabra) => propia.includes(palabra)) ? propias : porGrupo).push(hoja);
|
|
5145
|
+
}
|
|
5146
|
+
return [...propias, ...porGrupo];
|
|
5147
|
+
}
|
|
5148
|
+
|
|
5045
5149
|
// src/components/SideMenu.tsx
|
|
5046
5150
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
5047
|
-
var
|
|
5151
|
+
var CLAVE_RECIENTES = "fpr.menu.recientes";
|
|
5152
|
+
var MAXIMO_RECIENTES = 4;
|
|
5153
|
+
var getIcon = (item, destacado = false) => {
|
|
5154
|
+
switch (item.menuType) {
|
|
5155
|
+
case "table":
|
|
5156
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_TableChart.default, { sx: destacado ? { color: import_colors.blue[700] } : void 0 });
|
|
5157
|
+
case "proc":
|
|
5158
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Dns.default, { sx: destacado ? { color: import_colors.teal[700] } : void 0 });
|
|
5159
|
+
case "menu":
|
|
5160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Folder.default, { sx: destacado ? { color: import_colors.orange[800] } : void 0 });
|
|
5161
|
+
default:
|
|
5162
|
+
if (wScreens[item.menuType] !== void 0 || puenteBPHabilitado()) {
|
|
5163
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_DesktopWindows.default, { sx: destacado ? { color: import_colors.indigo[500] } : void 0 });
|
|
5164
|
+
}
|
|
5165
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_WarningAmber3.default, { sx: destacado ? { color: import_colors.red[500] } : void 0 });
|
|
5166
|
+
}
|
|
5167
|
+
};
|
|
5168
|
+
var estaSeleccionado = (item, grupos, currentPath, hash = "") => {
|
|
5169
|
+
const pathParts = currentPath.split("/");
|
|
5170
|
+
const urlTableName = pathParts[1] === "table" ? pathParts[2] : null;
|
|
5171
|
+
if (item.menuType === "table") {
|
|
5172
|
+
return currentPath === rutaDeTablaDeMenu([...grupos, item.name]) || urlTableName === (item.table || item.name);
|
|
5173
|
+
} else if (item.menuType === "proc") {
|
|
5174
|
+
return currentPath === `/procedures/${item.name}`;
|
|
5175
|
+
} else if (item.menuType !== "menu") {
|
|
5176
|
+
return currentPath.startsWith(`/wScreens/${item.menuType}`) || currentPath.startsWith(`/wScreens-fallback/${item.menuType}`) || currentPath === "/bp/menu" && new URLSearchParams(hash.replace(/^[#?]/, "")).get("w") === item.menuType;
|
|
5177
|
+
}
|
|
5178
|
+
return false;
|
|
5179
|
+
};
|
|
5180
|
+
var leerRecientes = () => {
|
|
5181
|
+
try {
|
|
5182
|
+
const guardado = JSON.parse(localStorage.getItem(CLAVE_RECIENTES) ?? "[]");
|
|
5183
|
+
return Array.isArray(guardado) ? guardado.filter((clave) => typeof clave === "string") : [];
|
|
5184
|
+
} catch {
|
|
5185
|
+
return [];
|
|
5186
|
+
}
|
|
5187
|
+
};
|
|
5188
|
+
var guardarRecientes = (recientes) => {
|
|
5189
|
+
try {
|
|
5190
|
+
localStorage.setItem(CLAVE_RECIENTES, JSON.stringify(recientes));
|
|
5191
|
+
} catch {
|
|
5192
|
+
}
|
|
5193
|
+
};
|
|
5194
|
+
var MenuListItem = ({ item, level, grupos = [], hermanos = [], onMenuItemClick }) => {
|
|
5048
5195
|
const navigate = (0, import_react_router_dom2.useNavigate)();
|
|
5049
5196
|
const location = (0, import_react_router_dom2.useLocation)();
|
|
5050
|
-
const
|
|
5197
|
+
const clave = claveDeMenu([...grupos, item.name]);
|
|
5198
|
+
const open = useSubMenuOpenState(clave);
|
|
5051
5199
|
const dispatch = useAppDispatch();
|
|
5052
5200
|
const handleClick = () => {
|
|
5053
5201
|
if (item.menuType === "menu") {
|
|
5054
|
-
|
|
5202
|
+
if (open) {
|
|
5203
|
+
dispatch(setSubMenuOpen({ menuName: clave, isOpen: false }));
|
|
5204
|
+
} else {
|
|
5205
|
+
dispatch(abrirGrupo({ clave, hermanos }));
|
|
5206
|
+
}
|
|
5055
5207
|
} else {
|
|
5056
5208
|
navigate(rutaDeItemDeMenu(item, grupos));
|
|
5057
5209
|
if (onMenuItemClick) {
|
|
@@ -5059,39 +5211,14 @@ var MenuListItem = ({ item, level, grupos = [], onMenuItemClick }) => {
|
|
|
5059
5211
|
}
|
|
5060
5212
|
}
|
|
5061
5213
|
};
|
|
5062
|
-
const
|
|
5063
|
-
switch (item2.menuType) {
|
|
5064
|
-
case "table":
|
|
5065
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_TableChart.default, { sx: { color: import_colors.blue[700] } });
|
|
5066
|
-
case "proc":
|
|
5067
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Dns.default, { sx: { color: import_colors.teal[700] } });
|
|
5068
|
-
case "menu":
|
|
5069
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Folder.default, { sx: { color: import_colors.orange[800] } });
|
|
5070
|
-
default:
|
|
5071
|
-
const WScreenComponent = wScreens[item2.menuType];
|
|
5072
|
-
if (WScreenComponent !== void 0) {
|
|
5073
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_DesktopWindows.default, { sx: { color: import_colors.grey[700] } });
|
|
5074
|
-
}
|
|
5075
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_WarningAmber3.default, { sx: { color: import_colors.red[500] } });
|
|
5076
|
-
}
|
|
5077
|
-
};
|
|
5078
|
-
const currentPath = location.pathname;
|
|
5079
|
-
let isSelected = false;
|
|
5080
|
-
const pathParts = currentPath.split("/");
|
|
5081
|
-
const urlTableName = pathParts[1] === "table" ? pathParts[2] : null;
|
|
5082
|
-
if (item.menuType === "table") {
|
|
5083
|
-
isSelected = currentPath === rutaDeTablaDeMenu([...grupos, item.name]) || urlTableName === (item.table || item.name);
|
|
5084
|
-
} else if (item.menuType === "proc") {
|
|
5085
|
-
isSelected = currentPath === `/procedures/${item.name}`;
|
|
5086
|
-
} else if (item.menuType !== "menu") {
|
|
5087
|
-
isSelected = currentPath.startsWith(`/wScreens/${item.menuType}`) || currentPath.startsWith(`/wScreens-fallback/${item.menuType}`);
|
|
5088
|
-
}
|
|
5214
|
+
const isSelected = estaSeleccionado(item, grupos, location.pathname, location.hash);
|
|
5089
5215
|
const itemRef = import_react28.default.useRef(null);
|
|
5090
5216
|
(0, import_react28.useEffect)(() => {
|
|
5091
5217
|
if (isSelected && itemRef.current) {
|
|
5092
5218
|
itemRef.current.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
5093
5219
|
}
|
|
5094
5220
|
}, [isSelected]);
|
|
5221
|
+
const contenido = item.menuType === "menu" ? item.menuContent : [];
|
|
5095
5222
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { ref: itemRef, children: [
|
|
5096
5223
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
5097
5224
|
import_material20.ListItemButton,
|
|
@@ -5100,83 +5227,156 @@ var MenuListItem = ({ item, level, grupos = [], onMenuItemClick }) => {
|
|
|
5100
5227
|
sx: { pl: level * 2 },
|
|
5101
5228
|
selected: isSelected,
|
|
5102
5229
|
children: [
|
|
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
|
|
5230
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemIcon, { sx: { minWidth: "38px" }, children: getIcon(item, isSelected || open) }),
|
|
5231
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemText, { primary: etiquetaDeItem(item) }),
|
|
5105
5232
|
item.menuType === "menu" ? open ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ExpandLess.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ExpandMore.default, {}) : null
|
|
5106
5233
|
]
|
|
5107
5234
|
}
|
|
5108
5235
|
),
|
|
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:
|
|
5236
|
+
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: contenido.map((subItem) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5110
5237
|
MenuListItem,
|
|
5111
5238
|
{
|
|
5112
5239
|
item: subItem,
|
|
5113
5240
|
level: level + 1,
|
|
5114
5241
|
grupos: [...grupos, item.name],
|
|
5242
|
+
hermanos: contenido.filter((otro) => otro !== subItem).map((otro) => claveDeMenu([...grupos, item.name, otro.name])),
|
|
5115
5243
|
onMenuItemClick
|
|
5116
5244
|
},
|
|
5117
5245
|
subItem.name
|
|
5118
5246
|
)) }) })
|
|
5119
5247
|
] });
|
|
5120
5248
|
};
|
|
5249
|
+
var ItemPlano = ({ hoja, seleccionado, traerALaVista = false, onElegir }) => {
|
|
5250
|
+
const boton = (0, import_react28.useRef)(null);
|
|
5251
|
+
(0, import_react28.useEffect)(() => {
|
|
5252
|
+
if (traerALaVista && seleccionado) boton.current?.scrollIntoView({ block: "nearest" });
|
|
5253
|
+
}, [traerALaVista, seleccionado]);
|
|
5254
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_material20.ListItemButton, { dense: true, selected: seleccionado, onClick: () => onElegir(hoja), ref: boton, children: [
|
|
5255
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemIcon, { sx: { minWidth: "38px" }, children: getIcon(hoja.item, seleccionado) }),
|
|
5256
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5257
|
+
import_material20.ListItemText,
|
|
5258
|
+
{
|
|
5259
|
+
primary: etiquetaDeItem(hoja.item),
|
|
5260
|
+
secondary: hoja.etiquetasDeGrupos.join(" \u203A ") || void 0,
|
|
5261
|
+
secondaryTypographyProps: { noWrap: true }
|
|
5262
|
+
}
|
|
5263
|
+
)
|
|
5264
|
+
] });
|
|
5265
|
+
};
|
|
5121
5266
|
var SideMenu = ({ onMenuItemClick }) => {
|
|
5122
5267
|
const { clientContext } = useApp();
|
|
5123
5268
|
const navigate = (0, import_react_router_dom2.useNavigate)();
|
|
5124
5269
|
const location = (0, import_react_router_dom2.useLocation)();
|
|
5125
5270
|
const dispatch = useAppDispatch();
|
|
5126
|
-
const
|
|
5127
|
-
const
|
|
5128
|
-
const
|
|
5129
|
-
const
|
|
5130
|
-
const
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5271
|
+
const [consulta, setConsulta] = (0, import_react28.useState)("");
|
|
5272
|
+
const [indice, setIndice] = (0, import_react28.useState)(0);
|
|
5273
|
+
const [recientes, setRecientes] = (0, import_react28.useState)(leerRecientes);
|
|
5274
|
+
const campoDeBusqueda = (0, import_react28.useRef)(null);
|
|
5275
|
+
const menu = clientContext?.menu;
|
|
5276
|
+
const hojas = (0, import_react28.useMemo)(() => hojasDeMenu(menu ?? []), [menu]);
|
|
5277
|
+
const resultados = (0, import_react28.useMemo)(() => buscarEnMenu(hojas, consulta), [hojas, consulta]);
|
|
5278
|
+
(0, import_react28.useEffect)(() => {
|
|
5279
|
+
const alApretar = (evento) => {
|
|
5280
|
+
if ((evento.ctrlKey || evento.metaKey) && !evento.altKey && !evento.shiftKey && evento.key.toLowerCase() === "k") {
|
|
5281
|
+
evento.preventDefault();
|
|
5282
|
+
dispatch(setDrawerOpen(true));
|
|
5283
|
+
setTimeout(() => {
|
|
5284
|
+
campoDeBusqueda.current?.focus();
|
|
5285
|
+
campoDeBusqueda.current?.select();
|
|
5286
|
+
}, 50);
|
|
5287
|
+
}
|
|
5288
|
+
};
|
|
5289
|
+
window.addEventListener("keydown", alApretar);
|
|
5290
|
+
return () => window.removeEventListener("keydown", alApretar);
|
|
5291
|
+
}, [dispatch]);
|
|
5292
|
+
(0, import_react28.useEffect)(() => {
|
|
5293
|
+
const actual = hojas.find((hoja) => estaSeleccionado(hoja.item, hoja.grupos, location.pathname, location.hash));
|
|
5294
|
+
if (!actual) return;
|
|
5295
|
+
dispatch(abrirCamino(actual.grupos.map((_, i) => claveDeMenu(actual.grupos.slice(0, i + 1)))));
|
|
5296
|
+
setRecientes((anteriores) => {
|
|
5297
|
+
if (anteriores.includes(actual.clave)) return anteriores;
|
|
5298
|
+
const nuevos = [actual.clave, ...anteriores].slice(0, MAXIMO_RECIENTES);
|
|
5299
|
+
guardarRecientes(nuevos);
|
|
5300
|
+
return nuevos;
|
|
5301
|
+
});
|
|
5302
|
+
}, [location.pathname, location.hash, hojas, dispatch]);
|
|
5303
|
+
if (!menu) {
|
|
5134
5304
|
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..." }) });
|
|
5135
5305
|
}
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5306
|
+
const elegir = (hoja) => {
|
|
5307
|
+
navigate(rutaDeItemDeMenu(hoja.item, hoja.grupos));
|
|
5308
|
+
setConsulta("");
|
|
5309
|
+
setIndice(0);
|
|
5310
|
+
if (onMenuItemClick) {
|
|
5311
|
+
onMenuItemClick();
|
|
5312
|
+
}
|
|
5313
|
+
};
|
|
5314
|
+
const alApretarEnBusqueda = (evento) => {
|
|
5315
|
+
if (evento.key === "ArrowDown" || evento.key === "ArrowUp") {
|
|
5316
|
+
evento.preventDefault();
|
|
5317
|
+
if (resultados.length === 0) return;
|
|
5318
|
+
setIndice((actual) => (actual + (evento.key === "ArrowDown" ? 1 : -1) + resultados.length) % resultados.length);
|
|
5319
|
+
} else if (evento.key === "Enter") {
|
|
5320
|
+
evento.preventDefault();
|
|
5321
|
+
const hoja = resultados[indice];
|
|
5322
|
+
if (hoja) elegir(hoja);
|
|
5323
|
+
} else if (evento.key === "Escape" && consulta !== "") {
|
|
5324
|
+
evento.stopPropagation();
|
|
5325
|
+
setConsulta("");
|
|
5326
|
+
}
|
|
5327
|
+
};
|
|
5328
|
+
const hojasRecientes = recientes.map((clave) => hojas.find((hoja) => hoja.clave === clave)).filter((hoja) => hoja !== void 0);
|
|
5329
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_material20.Box, { sx: { width: "100%", flex: 1, minHeight: 0, display: "flex", flexDirection: "column" }, children: [
|
|
5330
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Box, { sx: { px: 1.5, py: 1, flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5331
|
+
import_material20.TextField,
|
|
5332
|
+
{
|
|
5333
|
+
inputRef: campoDeBusqueda,
|
|
5334
|
+
value: consulta,
|
|
5335
|
+
onChange: (evento) => {
|
|
5336
|
+
setConsulta(evento.target.value);
|
|
5337
|
+
setIndice(0);
|
|
5338
|
+
},
|
|
5339
|
+
onKeyDown: alApretarEnBusqueda,
|
|
5340
|
+
placeholder: "Buscar (Ctrl+K)",
|
|
5341
|
+
size: "small",
|
|
5342
|
+
fullWidth: true,
|
|
5343
|
+
autoComplete: "off",
|
|
5344
|
+
sx: { "& .MuiInputBase-input": { fontSize: "0.8rem" } },
|
|
5345
|
+
InputProps: {
|
|
5346
|
+
startAdornment: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.InputAdornment, { position: "start", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Search3.default, { fontSize: "small" }) }),
|
|
5347
|
+
endAdornment: consulta !== "" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.InputAdornment, { position: "end", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.IconButton, { size: "small", "aria-label": "borrar b\xFAsqueda", edge: "end", onClick: () => {
|
|
5348
|
+
setConsulta("");
|
|
5349
|
+
campoDeBusqueda.current?.focus();
|
|
5350
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Clear.default, { fontSize: "small" }) }) }) : void 0
|
|
5159
5351
|
}
|
|
5160
5352
|
}
|
|
5161
|
-
|
|
5162
|
-
};
|
|
5163
|
-
expandParents(clientContext.menu, location.pathname);
|
|
5164
|
-
}, [location.pathname, clientContext, dispatch]);
|
|
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" })
|
|
5169
|
-
] }) }),
|
|
5353
|
+
) }),
|
|
5170
5354
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Divider, {}),
|
|
5171
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.List, { children:
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5355
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Box, { sx: { flex: 1, minHeight: 0, overflowY: "auto" }, children: consulta.trim() !== "" ? resultados.length === 0 ? /* @__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: "Sin resultados" }) }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.List, { children: resultados.map((hoja, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemPlano, { hoja, seleccionado: i === indice, traerALaVista: true, onElegir: elegir }, hoja.clave)) }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
5356
|
+
hojasRecientes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
5357
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Typography, { variant: "overline", color: "text.secondary", sx: { display: "block", px: 2, pt: 1, lineHeight: 2 }, children: "Recientes" }),
|
|
5358
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.List, { disablePadding: true, children: hojasRecientes.map((hoja) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5359
|
+
ItemPlano,
|
|
5360
|
+
{
|
|
5361
|
+
hoja,
|
|
5362
|
+
seleccionado: estaSeleccionado(hoja.item, hoja.grupos, location.pathname, location.hash),
|
|
5363
|
+
onElegir: elegir
|
|
5364
|
+
},
|
|
5365
|
+
hoja.clave
|
|
5366
|
+
)) }),
|
|
5367
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Divider, {})
|
|
5368
|
+
] }),
|
|
5369
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.List, { children: menu.map((menuItem) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5370
|
+
MenuListItem,
|
|
5371
|
+
{
|
|
5372
|
+
item: menuItem,
|
|
5373
|
+
level: 1,
|
|
5374
|
+
hermanos: menu.filter((otro) => otro !== menuItem).map((otro) => claveDeMenu([otro.name])),
|
|
5375
|
+
onMenuItemClick
|
|
5376
|
+
},
|
|
5377
|
+
menuItem.name
|
|
5378
|
+
)) })
|
|
5379
|
+
] }) })
|
|
5180
5380
|
] });
|
|
5181
5381
|
};
|
|
5182
5382
|
var SideMenu_default = SideMenu;
|
|
@@ -5186,10 +5386,11 @@ var import_react29 = require("react");
|
|
|
5186
5386
|
var import_react_router_dom3 = require("react-router-dom");
|
|
5187
5387
|
var import_react_redux3 = require("react-redux");
|
|
5188
5388
|
var useLogout = () => {
|
|
5189
|
-
const { setIsLoggedIn } = useApp();
|
|
5389
|
+
const { setIsLoggedIn, avisarCierreVoluntario } = useApp();
|
|
5190
5390
|
const dispatch = (0, import_react_redux3.useDispatch)();
|
|
5191
5391
|
const navigate = (0, import_react_router_dom3.useNavigate)();
|
|
5192
5392
|
const logout = (0, import_react29.useCallback)(async () => {
|
|
5393
|
+
avisarCierreVoluntario(true);
|
|
5193
5394
|
try {
|
|
5194
5395
|
const response = await fetchApi("/logout", { method: "GET" });
|
|
5195
5396
|
if (response.status === 401 || response.ok) {
|
|
@@ -5202,9 +5403,10 @@ var useLogout = () => {
|
|
|
5202
5403
|
} finally {
|
|
5203
5404
|
setIsLoggedIn(false);
|
|
5204
5405
|
dispatch(clearClientContext());
|
|
5406
|
+
dispatch(setRedirectPath(null));
|
|
5205
5407
|
navigate("/login", { replace: true });
|
|
5206
5408
|
}
|
|
5207
|
-
}, [setIsLoggedIn, dispatch, navigate]);
|
|
5409
|
+
}, [setIsLoggedIn, avisarCierreVoluntario, dispatch, navigate]);
|
|
5208
5410
|
return logout;
|
|
5209
5411
|
};
|
|
5210
5412
|
var useLogout_default = useLogout;
|
|
@@ -5215,6 +5417,7 @@ var drawerWidth = 240;
|
|
|
5215
5417
|
var MainLayout = () => {
|
|
5216
5418
|
const { clientContext } = useApp();
|
|
5217
5419
|
const logout = useLogout_default();
|
|
5420
|
+
const navigate = (0, import_react_router_dom5.useNavigate)();
|
|
5218
5421
|
const isDrawerOpen = useIsDrawerOpen();
|
|
5219
5422
|
const dispatch = useAppDispatch();
|
|
5220
5423
|
const theme = (0, import_material21.useTheme)();
|
|
@@ -5280,6 +5483,7 @@ var MainLayout = () => {
|
|
|
5280
5483
|
),
|
|
5281
5484
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Typography, { variant: "h6", noWrap: true, component: "div", sx: { flexGrow: 1 }, children: isDrawerOpen ? "" : clientContext.config.title }),
|
|
5282
5485
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Typography, { variant: "subtitle1", component: "div", sx: { mr: 2 }, children: clientContext.username }),
|
|
5486
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.IconButton, { color: "inherit", title: "Cambiar contrase\xF1a", "aria-label": "cambiar contrase\xF1a", onClick: () => navigate("/chpass"), sx: { mr: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_VpnKey.default, {}) }),
|
|
5283
5487
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5284
5488
|
import_material21.Button,
|
|
5285
5489
|
{
|
|
@@ -5304,8 +5508,9 @@ var MainLayout = () => {
|
|
|
5304
5508
|
"& .MuiDrawer-paper": {
|
|
5305
5509
|
width: drawerWidth,
|
|
5306
5510
|
boxSizing: "border-box",
|
|
5307
|
-
|
|
5308
|
-
|
|
5511
|
+
overflow: "hidden",
|
|
5512
|
+
display: "flex",
|
|
5513
|
+
flexDirection: "column"
|
|
5309
5514
|
}
|
|
5310
5515
|
},
|
|
5311
5516
|
children: [
|
|
@@ -5317,6 +5522,8 @@ var MainLayout = () => {
|
|
|
5317
5522
|
alignItems: "center",
|
|
5318
5523
|
justifyContent: "flex-start",
|
|
5319
5524
|
px: 1,
|
|
5525
|
+
flexShrink: 0,
|
|
5526
|
+
// el logo queda fijo: solo scrollea la lista del menú
|
|
5320
5527
|
fontSize: "1.3rem",
|
|
5321
5528
|
minHeight: theme.mixins.toolbar.minHeight,
|
|
5322
5529
|
gap: 1.5
|
|
@@ -5426,12 +5633,12 @@ var SessionExpiredMessage = () => {
|
|
|
5426
5633
|
var SessionExpiredMessage_default = SessionExpiredMessage;
|
|
5427
5634
|
|
|
5428
5635
|
// src/pages/PantallaInicial.tsx
|
|
5429
|
-
var
|
|
5636
|
+
var import_react_router_dom6 = require("react-router-dom");
|
|
5430
5637
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
5431
5638
|
var PantallaInicial = () => {
|
|
5432
5639
|
const { clientContext } = useApp();
|
|
5433
5640
|
const item = clientContext.menu ? itemInicial(clientContext.menu) : void 0;
|
|
5434
|
-
return item && clientContext.menu ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5641
|
+
return item && clientContext.menu ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_router_dom6.Navigate, { to: rutaDeItemDeMenu(item, gruposDeItem(clientContext.menu, item)), replace: true }) : null;
|
|
5435
5642
|
};
|
|
5436
5643
|
var PantallaInicial_default = PantallaInicial;
|
|
5437
5644
|
|
|
@@ -5461,6 +5668,17 @@ var LogoutPage_default = LogoutPage;
|
|
|
5461
5668
|
// src/pages/LoginPage.tsx
|
|
5462
5669
|
var import_react32 = require("react");
|
|
5463
5670
|
var import_material24 = require("@mui/material");
|
|
5671
|
+
var import_react_router_dom7 = require("react-router-dom");
|
|
5672
|
+
|
|
5673
|
+
// src/pages/configuracionLogin.ts
|
|
5674
|
+
var RUTA_POR_OMISION = "/new-pass";
|
|
5675
|
+
var rutaDeRecuperarClave = null;
|
|
5676
|
+
var configurarRecuperarClave = (recuperarClave) => {
|
|
5677
|
+
rutaDeRecuperarClave = recuperarClave === true ? RUTA_POR_OMISION : typeof recuperarClave === "string" && recuperarClave !== "" ? recuperarClave : null;
|
|
5678
|
+
};
|
|
5679
|
+
var rutaParaRecuperarClave = () => rutaDeRecuperarClave;
|
|
5680
|
+
|
|
5681
|
+
// src/pages/LoginPage.tsx
|
|
5464
5682
|
var import_react_hook_form = require("react-hook-form");
|
|
5465
5683
|
var import_zod = require("@hookform/resolvers/zod");
|
|
5466
5684
|
var z = __toESM(require("zod"), 1);
|
|
@@ -5475,7 +5693,10 @@ var loginSchema = z.object({
|
|
|
5475
5693
|
var LoginPage = () => {
|
|
5476
5694
|
const [loginError, setLoginError] = (0, import_react32.useState)(null);
|
|
5477
5695
|
const [isSubmitting, setIsSubmitting] = (0, import_react32.useState)(false);
|
|
5478
|
-
const
|
|
5696
|
+
const estadoDeLaRuta = (0, import_react_router_dom7.useLocation)().state;
|
|
5697
|
+
const claveCambiada = typeof estadoDeLaRuta === "object" && estadoDeLaRuta !== null && "claveCambiada" in estadoDeLaRuta && estadoDeLaRuta.claveCambiada === true;
|
|
5698
|
+
const rutaDeRecuperarClave2 = rutaParaRecuperarClave();
|
|
5699
|
+
const { setIsLoggedIn, checkSession, avisarCierreVoluntario } = useApp();
|
|
5479
5700
|
const dispatch = (0, import_react_redux4.useDispatch)();
|
|
5480
5701
|
const {
|
|
5481
5702
|
control,
|
|
@@ -5507,6 +5728,7 @@ var LoginPage = () => {
|
|
|
5507
5728
|
const errorText = "Credenciales incorrectas o error al iniciar sesi\xF3n";
|
|
5508
5729
|
throw new Error(errorText);
|
|
5509
5730
|
}
|
|
5731
|
+
avisarCierreVoluntario(false);
|
|
5510
5732
|
setIsLoggedIn(true);
|
|
5511
5733
|
await dispatch(fetchClientContext()).unwrap();
|
|
5512
5734
|
console.log("Login exitoso y clientContext cargado.");
|
|
@@ -5546,58 +5768,77 @@ var LoginPage = () => {
|
|
|
5546
5768
|
}
|
|
5547
5769
|
) }),
|
|
5548
5770
|
/* @__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)(
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5771
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
5772
|
+
"form",
|
|
5773
|
+
{
|
|
5774
|
+
onSubmit: handleSubmit(onSubmit),
|
|
5775
|
+
className: "space-y-4",
|
|
5776
|
+
onKeyDown: (evento) => {
|
|
5777
|
+
if (evento.key !== "Enter" || evento.shiftKey || evento.ctrlKey || evento.altKey || evento.metaKey) return;
|
|
5778
|
+
if (!(evento.target instanceof HTMLInputElement)) return;
|
|
5779
|
+
evento.preventDefault();
|
|
5780
|
+
if (!isSubmitting) void handleSubmit(onSubmit)();
|
|
5781
|
+
},
|
|
5782
|
+
children: [
|
|
5783
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
5784
|
+
/* @__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" }) }),
|
|
5785
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5786
|
+
import_react_hook_form.Controller,
|
|
5559
5787
|
{
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5788
|
+
name: "username",
|
|
5789
|
+
control,
|
|
5790
|
+
render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5791
|
+
import_material24.TextField,
|
|
5792
|
+
{
|
|
5793
|
+
...field,
|
|
5794
|
+
type: "text",
|
|
5795
|
+
id: "username",
|
|
5796
|
+
autoComplete: "username",
|
|
5797
|
+
placeholder: "Ingresa tu usuario",
|
|
5798
|
+
fullWidth: true,
|
|
5799
|
+
margin: "normal",
|
|
5800
|
+
error: !!errors.username,
|
|
5801
|
+
helperText: errors.username?.message,
|
|
5802
|
+
disabled: isSubmitting
|
|
5803
|
+
}
|
|
5804
|
+
)
|
|
5568
5805
|
}
|
|
5569
5806
|
)
|
|
5570
|
-
}
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5576
|
-
import_react_hook_form.Controller,
|
|
5577
|
-
{
|
|
5578
|
-
name: "password",
|
|
5579
|
-
control,
|
|
5580
|
-
render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5581
|
-
import_material24.TextField,
|
|
5807
|
+
] }),
|
|
5808
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
5809
|
+
/* @__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" }) }),
|
|
5810
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5811
|
+
import_react_hook_form.Controller,
|
|
5582
5812
|
{
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5813
|
+
name: "password",
|
|
5814
|
+
control,
|
|
5815
|
+
render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5816
|
+
import_material24.TextField,
|
|
5817
|
+
{
|
|
5818
|
+
...field,
|
|
5819
|
+
type: "password",
|
|
5820
|
+
id: "password",
|
|
5821
|
+
autoComplete: "current-password",
|
|
5822
|
+
placeholder: "Ingresa tu contrase\xF1a",
|
|
5823
|
+
fullWidth: true,
|
|
5824
|
+
margin: "normal",
|
|
5825
|
+
error: !!errors.password,
|
|
5826
|
+
helperText: errors.password?.message,
|
|
5827
|
+
disabled: isSubmitting
|
|
5828
|
+
}
|
|
5829
|
+
)
|
|
5591
5830
|
}
|
|
5592
5831
|
)
|
|
5593
|
-
}
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5832
|
+
] }),
|
|
5833
|
+
/* @__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: [
|
|
5834
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.CircularProgress, { size: 20, sx: { mr: 1 } }),
|
|
5835
|
+
"Iniciando sesi\xF3n..."
|
|
5836
|
+
] }) : "Iniciar Sesi\xF3n" })
|
|
5837
|
+
]
|
|
5838
|
+
}
|
|
5839
|
+
),
|
|
5840
|
+
rutaDeRecuperarClave2 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Box, { sx: { mt: 2, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Link, { href: `${envConfig.backendUrl}${rutaDeRecuperarClave2}`, variant: "body2", underline: "hover", children: "Me olvid\xE9 la clave / es mi primer ingreso" }) }),
|
|
5841
|
+
claveCambiada && !loginError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Alert, { severity: "success", sx: { mt: 2 }, children: "La contrase\xF1a se cambi\xF3. Ingres\xE1 con la clave nueva." }),
|
|
5601
5842
|
loginError && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material24.Alert, { severity: "error", sx: { mt: 2, maxHeight: "200px" }, children: [
|
|
5602
5843
|
" ",
|
|
5603
5844
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.AlertTitle, { children: "Error" }),
|
|
@@ -5613,7 +5854,7 @@ var LoginPage_default = LoginPage;
|
|
|
5613
5854
|
|
|
5614
5855
|
// src/components/ProcedureForm.tsx
|
|
5615
5856
|
var import_react33 = __toESM(require("react"), 1);
|
|
5616
|
-
var
|
|
5857
|
+
var import_react_router_dom8 = require("react-router-dom");
|
|
5617
5858
|
var import_material26 = require("@mui/material");
|
|
5618
5859
|
|
|
5619
5860
|
// src/pages/procedure-results/SuccessDisplay.tsx
|
|
@@ -5640,7 +5881,7 @@ var extendResultsOk = (newComponents) => {
|
|
|
5640
5881
|
// src/components/ProcedureForm.tsx
|
|
5641
5882
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5642
5883
|
var ProcedureForm = () => {
|
|
5643
|
-
const { procedureName } = (0,
|
|
5884
|
+
const { procedureName } = (0, import_react_router_dom8.useParams)();
|
|
5644
5885
|
const { clientContext } = useApp();
|
|
5645
5886
|
const { callApi, loading: apiLoading, error: apiError } = useApiCall();
|
|
5646
5887
|
const [validationErrors, setValidationErrors] = (0, import_react33.useState)({});
|
|
@@ -6058,15 +6299,15 @@ var ProcedureForm = () => {
|
|
|
6058
6299
|
var ProcedureForm_default = ProcedureForm;
|
|
6059
6300
|
|
|
6060
6301
|
// src/App.tsx
|
|
6061
|
-
var
|
|
6062
|
-
var
|
|
6302
|
+
var import_react_redux6 = require("react-redux");
|
|
6303
|
+
var import_react45 = require("redux-persist/integration/react");
|
|
6063
6304
|
|
|
6064
6305
|
// src/components/PrivateRoute.tsx
|
|
6065
6306
|
var import_react34 = require("react");
|
|
6066
|
-
var
|
|
6307
|
+
var import_react_router_dom9 = require("react-router-dom");
|
|
6067
6308
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
6068
6309
|
var PrivateRoute = ({ children }) => {
|
|
6069
|
-
const location = (0,
|
|
6310
|
+
const location = (0, import_react_router_dom9.useLocation)();
|
|
6070
6311
|
const dispatch = useAppDispatch();
|
|
6071
6312
|
const clientContextStatus = useClientContextStatus();
|
|
6072
6313
|
const isAuthenticated = clientContextStatus === "succeeded";
|
|
@@ -6074,7 +6315,7 @@ var PrivateRoute = ({ children }) => {
|
|
|
6074
6315
|
console.log(`[PrivateRoute] Render: Path=${location.pathname}, AuthStatus=${clientContextStatus}, IsAuthenticated=${isAuthenticated}, IsLoadingAuth=${isLoadingAuth}`);
|
|
6075
6316
|
(0, import_react34.useEffect)(() => {
|
|
6076
6317
|
console.log(`[PrivateRoute] Effect: Path=${location.pathname}, AuthStatus=${clientContextStatus}, IsAuthenticated=${isAuthenticated}, IsLoadingAuth=${isLoadingAuth}`);
|
|
6077
|
-
if (!isAuthenticated && !isLoadingAuth && location.pathname !== "/login") {
|
|
6318
|
+
if (!isAuthenticated && !isLoadingAuth && location.pathname !== "/login" && !huboCierreVoluntario()) {
|
|
6078
6319
|
const path = location.pathname + location.search + location.hash;
|
|
6079
6320
|
console.log(`[PrivateRoute] ACTION: Dispatching setRedirectPath(${path})`);
|
|
6080
6321
|
dispatch(setRedirectPath(path));
|
|
@@ -6092,7 +6333,7 @@ var PrivateRoute = ({ children }) => {
|
|
|
6092
6333
|
}
|
|
6093
6334
|
if (!isAuthenticated) {
|
|
6094
6335
|
console.log(`[PrivateRoute] User not authenticated, navigating to /login`);
|
|
6095
|
-
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
6336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_router_dom9.Navigate, { to: "/login", replace: true });
|
|
6096
6337
|
}
|
|
6097
6338
|
console.log(`[PrivateRoute] User authenticated, rendering children.`);
|
|
6098
6339
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_jsx_runtime33.Fragment, { children });
|
|
@@ -6101,13 +6342,15 @@ var PrivateRoute_default = PrivateRoute;
|
|
|
6101
6342
|
|
|
6102
6343
|
// src/components/InitialRedirectHandler.tsx
|
|
6103
6344
|
var import_react35 = require("react");
|
|
6104
|
-
var
|
|
6345
|
+
var import_react_router_dom10 = require("react-router-dom");
|
|
6105
6346
|
var InitialRedirectHandler = () => {
|
|
6106
|
-
const location = (0,
|
|
6107
|
-
const navigate = (0,
|
|
6347
|
+
const location = (0, import_react_router_dom10.useLocation)();
|
|
6348
|
+
const navigate = (0, import_react_router_dom10.useNavigate)();
|
|
6108
6349
|
const dispatch = useAppDispatch();
|
|
6109
6350
|
const redirectPath = useRedirectPath();
|
|
6110
6351
|
const clientContextStatus = useClientContextStatus();
|
|
6352
|
+
const username = useAppSelector((state) => state.clientContext.username);
|
|
6353
|
+
const redirectUsername = useAppSelector((state) => state.router.redirectUsername);
|
|
6111
6354
|
(0, import_react35.useEffect)(() => {
|
|
6112
6355
|
dispatch(setCurrentPath(location.pathname + location.search));
|
|
6113
6356
|
}, [location, dispatch]);
|
|
@@ -6117,7 +6360,9 @@ var InitialRedirectHandler = () => {
|
|
|
6117
6360
|
}, [location.pathname]);
|
|
6118
6361
|
(0, import_react35.useEffect)(() => {
|
|
6119
6362
|
if (clientContextStatus === "succeeded") {
|
|
6120
|
-
if (redirectPath && redirectPath !== "/login") {
|
|
6363
|
+
if (redirectPath && redirectPath !== "/login" && redirectUsername && redirectUsername !== username) {
|
|
6364
|
+
dispatch(setRedirectPath(null));
|
|
6365
|
+
} else if (redirectPath && redirectPath !== "/login") {
|
|
6121
6366
|
console.log("Redirigiendo a la ruta guardada:", redirectPath);
|
|
6122
6367
|
navegandoRef.current = true;
|
|
6123
6368
|
navigate(redirectPath);
|
|
@@ -6127,14 +6372,14 @@ var InitialRedirectHandler = () => {
|
|
|
6127
6372
|
navigate("/");
|
|
6128
6373
|
}
|
|
6129
6374
|
}
|
|
6130
|
-
}, [clientContextStatus, redirectPath, location.pathname, navigate, dispatch]);
|
|
6375
|
+
}, [clientContextStatus, redirectPath, redirectUsername, username, location.pathname, navigate, dispatch]);
|
|
6131
6376
|
return null;
|
|
6132
6377
|
};
|
|
6133
6378
|
var InitialRedirectHandler_default = InitialRedirectHandler;
|
|
6134
6379
|
|
|
6135
6380
|
// src/pages/GenericDataGridPage.tsx
|
|
6136
6381
|
var import_react36 = __toESM(require("react"), 1);
|
|
6137
|
-
var
|
|
6382
|
+
var import_react_router_dom11 = require("react-router-dom");
|
|
6138
6383
|
var import_material27 = require("@mui/material");
|
|
6139
6384
|
var import_Close2 = __toESM(require("@mui/icons-material/Close"), 1);
|
|
6140
6385
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
@@ -6143,12 +6388,12 @@ var GenericDataGridPage = ({
|
|
|
6143
6388
|
initialFixedFields = [],
|
|
6144
6389
|
parametros: parametrosRecibidos
|
|
6145
6390
|
}) => {
|
|
6146
|
-
const { tableName: urlTableName } = (0,
|
|
6391
|
+
const { tableName: urlTableName } = (0, import_react_router_dom11.useParams)();
|
|
6147
6392
|
const effectiveTableName = initialTableName || urlTableName;
|
|
6148
6393
|
const [tabs, setTabs] = (0, import_react36.useState)([]);
|
|
6149
6394
|
const [activeTabIdx, setActiveTabIdx] = (0, import_react36.useState)(0);
|
|
6150
6395
|
const ffKey = JSON.stringify(initialFixedFields);
|
|
6151
|
-
const location = (0,
|
|
6396
|
+
const location = (0, import_react_router_dom11.useLocation)();
|
|
6152
6397
|
const parametros = (0, import_react36.useMemo)(() => parametrosRecibidos ?? parametrosDeTabla(void 0, location.search), [parametrosRecibidos, location.search]);
|
|
6153
6398
|
const fixedFieldsIniciales = initialFixedFields.length > 0 ? initialFixedFields : parametros.fixedFields ?? [];
|
|
6154
6399
|
const parametrosKey = JSON.stringify(parametros);
|
|
@@ -6229,11 +6474,11 @@ var GenericDataGridPage_default = GenericDataGridPage;
|
|
|
6229
6474
|
|
|
6230
6475
|
// src/pages/PantallaDeRuta.tsx
|
|
6231
6476
|
var import_react37 = require("react");
|
|
6232
|
-
var
|
|
6477
|
+
var import_react_router_dom12 = require("react-router-dom");
|
|
6233
6478
|
var import_material28 = require("@mui/material");
|
|
6234
6479
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
6235
6480
|
var PantallaDeRuta = ({ screenName }) => {
|
|
6236
|
-
const [busqueda] = (0,
|
|
6481
|
+
const [busqueda] = (0, import_react_router_dom12.useSearchParams)();
|
|
6237
6482
|
const params = (0, import_react37.useMemo)(() => Object.fromEntries(busqueda.entries()), [busqueda]);
|
|
6238
6483
|
const Pantalla = wScreens[screenName];
|
|
6239
6484
|
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 }) });
|
|
@@ -6241,13 +6486,13 @@ var PantallaDeRuta = ({ screenName }) => {
|
|
|
6241
6486
|
|
|
6242
6487
|
// src/pages/MenuTablePage.tsx
|
|
6243
6488
|
var import_react38 = require("react");
|
|
6244
|
-
var
|
|
6489
|
+
var import_react_router_dom13 = require("react-router-dom");
|
|
6245
6490
|
var import_material29 = require("@mui/material");
|
|
6246
6491
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
6247
6492
|
var MenuTablePage = () => {
|
|
6248
|
-
const { "*": menuName } = (0,
|
|
6493
|
+
const { "*": menuName } = (0, import_react_router_dom13.useParams)();
|
|
6249
6494
|
const { clientContext } = useApp();
|
|
6250
|
-
const { search } = (0,
|
|
6495
|
+
const { search } = (0, import_react_router_dom13.useLocation)();
|
|
6251
6496
|
const { currentTableName, currentFixedFields, parametros } = (0, import_react38.useMemo)(() => {
|
|
6252
6497
|
let tableName = void 0;
|
|
6253
6498
|
let fixedFields = [];
|
|
@@ -6287,7 +6532,7 @@ var MenuTablePage_default = MenuTablePage;
|
|
|
6287
6532
|
|
|
6288
6533
|
// src/puente/PantallaBP.tsx
|
|
6289
6534
|
var import_react40 = require("react");
|
|
6290
|
-
var
|
|
6535
|
+
var import_react_router_dom14 = require("react-router-dom");
|
|
6291
6536
|
var import_material31 = require("@mui/material");
|
|
6292
6537
|
|
|
6293
6538
|
// src/puente/clienteBP.ts
|
|
@@ -6490,13 +6735,6 @@ function resolverPantallaBP(myOwn, nombre, contenedor) {
|
|
|
6490
6735
|
return null;
|
|
6491
6736
|
}
|
|
6492
6737
|
|
|
6493
|
-
// src/puente/habilitacion.ts
|
|
6494
|
-
var habilitado = false;
|
|
6495
|
-
var habilitarPuenteBP = () => {
|
|
6496
|
-
habilitado = true;
|
|
6497
|
-
};
|
|
6498
|
-
var puenteBPHabilitado = () => habilitado;
|
|
6499
|
-
|
|
6500
6738
|
// src/puente/PantallaBP.tsx
|
|
6501
6739
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
6502
6740
|
function buscarItemDeMenu(items, tipo) {
|
|
@@ -6559,18 +6797,18 @@ var PantallaBP = ({ nombre, direccion }) => {
|
|
|
6559
6797
|
);
|
|
6560
6798
|
};
|
|
6561
6799
|
var PantallaDeRespaldo = () => {
|
|
6562
|
-
const { screenName = "" } = (0,
|
|
6563
|
-
const { search } = (0,
|
|
6800
|
+
const { screenName = "" } = (0, import_react_router_dom14.useParams)();
|
|
6801
|
+
const { search } = (0, import_react_router_dom14.useLocation)();
|
|
6564
6802
|
if (!puenteBPHabilitado()) {
|
|
6565
6803
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material31.Box, { sx: { p: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FallbackWScreen, { screenName }) });
|
|
6566
6804
|
}
|
|
6567
|
-
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
6805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom14.Navigate, { to: rutaDePantallaBP(screenName, search), replace: true });
|
|
6568
6806
|
};
|
|
6569
6807
|
var PaginaBP = () => {
|
|
6570
|
-
const { hash, search } = (0,
|
|
6808
|
+
const { hash, search } = (0, import_react_router_dom14.useLocation)();
|
|
6571
6809
|
const direccion = hash || search;
|
|
6572
6810
|
const nombre = new URLSearchParams(direccion.replace(/^[#?]/, "")).get("w");
|
|
6573
|
-
if (!puenteBPHabilitado()) return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
6811
|
+
if (!puenteBPHabilitado()) return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom14.Navigate, { to: "/", replace: true });
|
|
6574
6812
|
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: [
|
|
6575
6813
|
"Falta la pantalla de backend-plus (",
|
|
6576
6814
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("code", { children: "#w=..." }),
|
|
@@ -6581,7 +6819,7 @@ var PaginaBP = () => {
|
|
|
6581
6819
|
|
|
6582
6820
|
// src/puente/GrillaBP.tsx
|
|
6583
6821
|
var import_react41 = require("react");
|
|
6584
|
-
var
|
|
6822
|
+
var import_react_router_dom15 = require("react-router-dom");
|
|
6585
6823
|
var import_material32 = require("@mui/material");
|
|
6586
6824
|
var import_jsx_runtime39 = (
|
|
6587
6825
|
// 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
|
|
@@ -6621,13 +6859,13 @@ var GrillaBP = ({ tabla, fixedFields }) => {
|
|
|
6621
6859
|
] });
|
|
6622
6860
|
};
|
|
6623
6861
|
var PaginaGrillaBP = () => {
|
|
6624
|
-
const { tableName = "" } = (0,
|
|
6862
|
+
const { tableName = "" } = (0, import_react_router_dom15.useParams)();
|
|
6625
6863
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(GrillaBP, { tabla: tableName }, tableName);
|
|
6626
6864
|
};
|
|
6627
6865
|
|
|
6628
6866
|
// src/puente/CapturaBP.tsx
|
|
6629
6867
|
var import_react42 = require("react");
|
|
6630
|
-
var
|
|
6868
|
+
var import_react_router_dom16 = require("react-router-dom");
|
|
6631
6869
|
|
|
6632
6870
|
// src/puente/capturaDeNavegacion.ts
|
|
6633
6871
|
function apiDeNavegacion() {
|
|
@@ -6672,62 +6910,175 @@ function capturarNavegacionBP(urlBackend, navegar) {
|
|
|
6672
6910
|
|
|
6673
6911
|
// src/puente/CapturaBP.tsx
|
|
6674
6912
|
var CapturaBP = () => {
|
|
6675
|
-
const navigate = (0,
|
|
6913
|
+
const navigate = (0, import_react_router_dom16.useNavigate)();
|
|
6676
6914
|
(0, import_react42.useEffect)(() => capturarNavegacionBP(envConfig.backendUrl, navigate), [navigate]);
|
|
6677
6915
|
return null;
|
|
6678
6916
|
};
|
|
6679
6917
|
|
|
6918
|
+
// src/pages/CambiarClavePage.tsx
|
|
6919
|
+
var import_react43 = require("react");
|
|
6920
|
+
var import_material33 = require("@mui/material");
|
|
6921
|
+
var import_react_router_dom17 = require("react-router-dom");
|
|
6922
|
+
var import_react_redux5 = require("react-redux");
|
|
6923
|
+
|
|
6924
|
+
// src/utils/cambiarClave.ts
|
|
6925
|
+
var MENSAJE_POR_OMISION = "No se pudo cambiar la contrase\xF1a";
|
|
6926
|
+
function resultadoDeCambioDeClave(urlFinal, html) {
|
|
6927
|
+
if (/\/login\/?(\?.*)?$/.test(urlFinal)) return { ok: true };
|
|
6928
|
+
const mensajes = Array.from(new DOMParser().parseFromString(html, "text/html").querySelectorAll(".error-message")).map((elemento) => (elemento.textContent ?? "").trim()).filter((mensaje) => mensaje !== "");
|
|
6929
|
+
return { ok: false, mensaje: mensajes.join("\n") || MENSAJE_POR_OMISION };
|
|
6930
|
+
}
|
|
6931
|
+
|
|
6932
|
+
// src/pages/CambiarClavePage.tsx
|
|
6933
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
6934
|
+
var CambiarClavePage = () => {
|
|
6935
|
+
const { clientContext, setIsLoggedIn, avisarCierreVoluntario } = useApp();
|
|
6936
|
+
const dispatch = (0, import_react_redux5.useDispatch)();
|
|
6937
|
+
const navigate = (0, import_react_router_dom17.useNavigate)();
|
|
6938
|
+
const [claveActual, setClaveActual] = (0, import_react43.useState)("");
|
|
6939
|
+
const [claveNueva, setClaveNueva] = (0, import_react43.useState)("");
|
|
6940
|
+
const [claveRepetida, setClaveRepetida] = (0, import_react43.useState)("");
|
|
6941
|
+
const [error, setError] = (0, import_react43.useState)(null);
|
|
6942
|
+
const [enviando, setEnviando] = (0, import_react43.useState)(false);
|
|
6943
|
+
const enviar = async (evento) => {
|
|
6944
|
+
evento.preventDefault();
|
|
6945
|
+
setError(null);
|
|
6946
|
+
if (claveNueva !== claveRepetida) {
|
|
6947
|
+
setError("La clave nueva y su repetici\xF3n no coinciden");
|
|
6948
|
+
return;
|
|
6949
|
+
}
|
|
6950
|
+
setEnviando(true);
|
|
6951
|
+
avisarCierreVoluntario(true);
|
|
6952
|
+
try {
|
|
6953
|
+
const respuesta = await fetchApi("/chpass", {
|
|
6954
|
+
method: "POST",
|
|
6955
|
+
body: new URLSearchParams({ oldPassword: claveActual, newPassword: claveNueva, repPassword: claveRepetida })
|
|
6956
|
+
});
|
|
6957
|
+
const resultado = resultadoDeCambioDeClave(respuesta.url, await respuesta.text());
|
|
6958
|
+
if (!resultado.ok) {
|
|
6959
|
+
avisarCierreVoluntario(false);
|
|
6960
|
+
setError(resultado.mensaje);
|
|
6961
|
+
return;
|
|
6962
|
+
}
|
|
6963
|
+
setIsLoggedIn(false);
|
|
6964
|
+
dispatch(clearClientContext());
|
|
6965
|
+
dispatch(setRedirectPath(null));
|
|
6966
|
+
navigate("/login", { replace: true, state: { claveCambiada: true } });
|
|
6967
|
+
} catch (err) {
|
|
6968
|
+
avisarCierreVoluntario(false);
|
|
6969
|
+
setError(mensajeDeError(err, "No se pudo cambiar la contrase\xF1a"));
|
|
6970
|
+
} finally {
|
|
6971
|
+
setEnviando(false);
|
|
6972
|
+
}
|
|
6973
|
+
};
|
|
6974
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.Box, { sx: { p: 3, display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_material33.Box, { component: "form", onSubmit: enviar, sx: { width: "100%", maxWidth: 420 }, children: [
|
|
6975
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.Typography, { variant: "h5", gutterBottom: true, children: "Cambiar contrase\xF1a" }),
|
|
6976
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.TextField, { label: "Usuario", value: clientContext?.username ?? "", fullWidth: true, margin: "normal", disabled: true, autoComplete: "username" }),
|
|
6977
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
6978
|
+
import_material33.TextField,
|
|
6979
|
+
{
|
|
6980
|
+
label: "Contrase\xF1a actual",
|
|
6981
|
+
type: "password",
|
|
6982
|
+
value: claveActual,
|
|
6983
|
+
onChange: (e) => setClaveActual(e.target.value),
|
|
6984
|
+
fullWidth: true,
|
|
6985
|
+
margin: "normal",
|
|
6986
|
+
autoFocus: true,
|
|
6987
|
+
required: true,
|
|
6988
|
+
autoComplete: "current-password",
|
|
6989
|
+
disabled: enviando
|
|
6990
|
+
}
|
|
6991
|
+
),
|
|
6992
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
6993
|
+
import_material33.TextField,
|
|
6994
|
+
{
|
|
6995
|
+
label: "Contrase\xF1a nueva",
|
|
6996
|
+
type: "password",
|
|
6997
|
+
value: claveNueva,
|
|
6998
|
+
onChange: (e) => setClaveNueva(e.target.value),
|
|
6999
|
+
fullWidth: true,
|
|
7000
|
+
margin: "normal",
|
|
7001
|
+
required: true,
|
|
7002
|
+
autoComplete: "new-password",
|
|
7003
|
+
disabled: enviando
|
|
7004
|
+
}
|
|
7005
|
+
),
|
|
7006
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
7007
|
+
import_material33.TextField,
|
|
7008
|
+
{
|
|
7009
|
+
label: "Repetir contrase\xF1a nueva",
|
|
7010
|
+
type: "password",
|
|
7011
|
+
value: claveRepetida,
|
|
7012
|
+
onChange: (e) => setClaveRepetida(e.target.value),
|
|
7013
|
+
fullWidth: true,
|
|
7014
|
+
margin: "normal",
|
|
7015
|
+
required: true,
|
|
7016
|
+
autoComplete: "new-password",
|
|
7017
|
+
disabled: enviando
|
|
7018
|
+
}
|
|
7019
|
+
),
|
|
7020
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.Alert, { severity: "error", sx: { mt: 1, whiteSpace: "pre-line" }, children: error }),
|
|
7021
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_material33.Box, { sx: { display: "flex", gap: 1, justifyContent: "flex-end", mt: 2 }, children: [
|
|
7022
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.Button, { onClick: () => navigate(-1), disabled: enviando, children: "Cancelar" }),
|
|
7023
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.Button, { type: "submit", variant: "contained", disabled: enviando, children: enviando ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.CircularProgress, { size: 20 }) : "Cambiar contrase\xF1a" })
|
|
7024
|
+
] }),
|
|
7025
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.Typography, { variant: "caption", color: "text.secondary", sx: { display: "block", mt: 2 }, children: "Al cambiarla se cierra la sesi\xF3n: hay que ingresar de nuevo con la clave nueva." })
|
|
7026
|
+
] }) });
|
|
7027
|
+
};
|
|
7028
|
+
var CambiarClavePage_default = CambiarClavePage;
|
|
7029
|
+
|
|
6680
7030
|
// src/App.tsx
|
|
6681
7031
|
var import_type_store6 = __toESM(require("type-store"), 1);
|
|
6682
|
-
var
|
|
7032
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
6683
7033
|
var LocationTracker = () => {
|
|
6684
|
-
const location = (0,
|
|
7034
|
+
const location = (0, import_react_router_dom18.useLocation)();
|
|
6685
7035
|
const dispatch = useAppDispatch();
|
|
6686
|
-
(0,
|
|
7036
|
+
(0, import_react44.useEffect)(() => {
|
|
6687
7037
|
dispatch(setCurrentPath(location.pathname + location.search));
|
|
6688
7038
|
}, [location, dispatch]);
|
|
6689
7039
|
return null;
|
|
6690
7040
|
};
|
|
6691
7041
|
function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout = MainLayout_default, unloggedLayout: UnloggedLayout }) {
|
|
6692
|
-
return /* @__PURE__ */ (0,
|
|
6693
|
-
/* @__PURE__ */ (0,
|
|
6694
|
-
puenteBPHabilitado() && /* @__PURE__ */ (0,
|
|
6695
|
-
/* @__PURE__ */ (0,
|
|
6696
|
-
/* @__PURE__ */ (0,
|
|
6697
|
-
/* @__PURE__ */ (0,
|
|
6698
|
-
/* @__PURE__ */ (0,
|
|
7042
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
|
|
7043
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(InitialRedirectHandler_default, {}),
|
|
7044
|
+
puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(CapturaBP, {}),
|
|
7045
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_router_dom18.Routes, { children: [
|
|
7046
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_router_dom18.Route, { element: UnloggedLayout ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(UnloggedLayout, {}) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Outlet, {}), children: [
|
|
7047
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/login", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LoginPage_default, {}) }),
|
|
7048
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/logout", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LogoutPage_default, {}) }),
|
|
6699
7049
|
myUnloggedRoutes
|
|
6700
7050
|
] }),
|
|
6701
|
-
/* @__PURE__ */ (0,
|
|
6702
|
-
/* @__PURE__ */ (0,
|
|
6703
|
-
/* @__PURE__ */ (0,
|
|
6704
|
-
/* @__PURE__ */ (0,
|
|
6705
|
-
/* @__PURE__ */ (0,
|
|
6706
|
-
|
|
6707
|
-
|
|
7051
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_router_dom18.Route, { element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PrivateRoute_default, { children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Layout, {}) }), children: [
|
|
7052
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PantallaInicial_default, {}) }),
|
|
7053
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/table/:tableName", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(GenericDataGridPage_default, {}) }),
|
|
7054
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/menu/*", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(MenuTablePage_default, {}) }),
|
|
7055
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/procedures/:procedureName", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ProcedureForm_default, {}) }),
|
|
7056
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/chpass", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(CambiarClavePage_default, {}) }),
|
|
7057
|
+
Object.keys(wScreens).map((screenName) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7058
|
+
import_react_router_dom18.Route,
|
|
6708
7059
|
{
|
|
6709
7060
|
path: `/wScreens/${screenName}`,
|
|
6710
|
-
element: /* @__PURE__ */ (0,
|
|
7061
|
+
element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PantallaDeRuta, { screenName })
|
|
6711
7062
|
},
|
|
6712
7063
|
screenName
|
|
6713
7064
|
)),
|
|
6714
|
-
/* @__PURE__ */ (0,
|
|
6715
|
-
puenteBPHabilitado() && /* @__PURE__ */ (0,
|
|
6716
|
-
puenteBPHabilitado() && /* @__PURE__ */ (0,
|
|
7065
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/wScreens-fallback/:screenName", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PantallaDeRespaldo, {}) }),
|
|
7066
|
+
puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/bp/menu", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PaginaBP, {}) }),
|
|
7067
|
+
puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/bp/table/:tableName", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PaginaGrillaBP, {}) }),
|
|
6717
7068
|
myRoutes,
|
|
6718
|
-
/* @__PURE__ */ (0,
|
|
7069
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
|
|
6719
7070
|
] }),
|
|
6720
|
-
/* @__PURE__ */ (0,
|
|
7071
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Navigate, { to: "/", replace: true }) })
|
|
6721
7072
|
] })
|
|
6722
7073
|
] });
|
|
6723
7074
|
}
|
|
6724
7075
|
var FrontendPlusProviders = ({ children, publicPaths }) => {
|
|
6725
|
-
return /* @__PURE__ */ (0,
|
|
6726
|
-
/* @__PURE__ */ (0,
|
|
7076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_redux6.Provider, { store, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react45.PersistGate, { loading: null, persistor, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_router_dom18.BrowserRouter, { basename: rutaBase, children: [
|
|
7077
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LocationTracker, {}),
|
|
6727
7078
|
" ",
|
|
6728
|
-
/* @__PURE__ */ (0,
|
|
7079
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(AppProvider, { publicPaths, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(SnackbarProvider, { children: [
|
|
6729
7080
|
children,
|
|
6730
|
-
/* @__PURE__ */ (0,
|
|
7081
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SessionExpiredMessage_default, {})
|
|
6731
7082
|
] }) })
|
|
6732
7083
|
] }) }) });
|
|
6733
7084
|
};
|
|
@@ -6739,9 +7090,10 @@ var App = ({
|
|
|
6739
7090
|
myClientSides,
|
|
6740
7091
|
myResultsOk,
|
|
6741
7092
|
myConditions,
|
|
6742
|
-
puenteBP
|
|
7093
|
+
puenteBP,
|
|
7094
|
+
recuperarClave
|
|
6743
7095
|
}) => {
|
|
6744
|
-
(0,
|
|
7096
|
+
(0, import_react44.useMemo)(() => {
|
|
6745
7097
|
if (myClientSides) {
|
|
6746
7098
|
extendClientSides(myClientSides);
|
|
6747
7099
|
}
|
|
@@ -6757,8 +7109,9 @@ var App = ({
|
|
|
6757
7109
|
if (puenteBP) {
|
|
6758
7110
|
habilitarPuenteBP();
|
|
6759
7111
|
}
|
|
6760
|
-
|
|
6761
|
-
|
|
7112
|
+
configurarRecuperarClave(recuperarClave);
|
|
7113
|
+
}, [myClientSides, myResultsOk, myWScreens, myConditions, puenteBP, recuperarClave]);
|
|
7114
|
+
(0, import_react44.useEffect)(() => {
|
|
6762
7115
|
import_type_store6.default.messages = import_type_store6.default.i18n.messages.es;
|
|
6763
7116
|
import_type_store6.default.locale = import_type_store6.default.i18n.locale.es;
|
|
6764
7117
|
const link = document.querySelector("link[rel*='icon']") || document.createElement("link");
|
|
@@ -6767,11 +7120,11 @@ var App = ({
|
|
|
6767
7120
|
link.href = `${envConfig.backendUrl}/img/logo-128.png`;
|
|
6768
7121
|
document.getElementsByTagName("head")[0].appendChild(link);
|
|
6769
7122
|
}, []);
|
|
6770
|
-
const safePaths =
|
|
7123
|
+
const safePaths = import_react44.default.useMemo(() => {
|
|
6771
7124
|
const extracted = extractPathsFromRoutes(myUnloggedRoutes);
|
|
6772
7125
|
return ["/login", "/logout", ...extracted];
|
|
6773
7126
|
}, [myUnloggedRoutes]);
|
|
6774
|
-
return /* @__PURE__ */ (0,
|
|
7127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
6775
7128
|
FrontendPlusReactRoutes,
|
|
6776
7129
|
{
|
|
6777
7130
|
myRoutes,
|