frontend-plus-react 0.7.0 → 0.8.1
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 +18 -1
- package/README.md +1 -0
- package/dist/index.cjs +619 -262
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +19 -1
- 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 +692 -335
- 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;
|
|
@@ -1425,8 +1441,12 @@ function BotonDetalle({ row, rowId, detailTable, deshabilitado }) {
|
|
|
1425
1441
|
import_material3.IconButton,
|
|
1426
1442
|
{
|
|
1427
1443
|
size: "small",
|
|
1444
|
+
sx: { width: 24, height: 24, p: 0 },
|
|
1428
1445
|
disabled: deshabilitado,
|
|
1429
1446
|
onClick: (e) => alternarDetalle(row, rowId, detailTable, e.ctrlKey || e.metaKey),
|
|
1447
|
+
onMouseDown: (e) => {
|
|
1448
|
+
if (e.button === 1) e.preventDefault();
|
|
1449
|
+
},
|
|
1430
1450
|
onAuxClick: (e) => {
|
|
1431
1451
|
if (e.button === 1) alternarDetalle(row, rowId, detailTable, true);
|
|
1432
1452
|
},
|
|
@@ -2048,9 +2068,10 @@ var defaultColumnHeaderCellRenderer = (props, fieldDef, ocultarColumna) => {
|
|
|
2048
2068
|
{
|
|
2049
2069
|
variant: "body2",
|
|
2050
2070
|
sx: {
|
|
2051
|
-
fontWeight:
|
|
2071
|
+
fontWeight: 500,
|
|
2072
|
+
color: "#37474f",
|
|
2052
2073
|
textDecoration: isPrimaryKey ? "underline" : "none",
|
|
2053
|
-
fontSize: "0.
|
|
2074
|
+
fontSize: "0.85rem",
|
|
2054
2075
|
textAlign: "left",
|
|
2055
2076
|
flexGrow: 1,
|
|
2056
2077
|
overflow: "hidden",
|
|
@@ -2076,22 +2097,20 @@ var ActionsColumnHeaderCell = ({
|
|
|
2076
2097
|
allowInsert && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2077
2098
|
import_material4.IconButton,
|
|
2078
2099
|
{
|
|
2079
|
-
color: "inherit",
|
|
2080
2100
|
onClick: () => handleAddRow(),
|
|
2081
2101
|
size: "small",
|
|
2082
2102
|
title: "A\xF1adir registro",
|
|
2083
|
-
sx: { p: 0.25 },
|
|
2084
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_Add.default, { sx: { fontSize: 18
|
|
2103
|
+
sx: { p: 0.25, color: "grey.800", "&:hover": { color: "success.main" } },
|
|
2104
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_Add.default, { sx: { fontSize: 18 } })
|
|
2085
2105
|
}
|
|
2086
2106
|
),
|
|
2087
2107
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2088
2108
|
import_material4.IconButton,
|
|
2089
2109
|
{
|
|
2090
|
-
color: "inherit",
|
|
2091
2110
|
onClick: toggleFilterVisibility,
|
|
2092
2111
|
size: "small",
|
|
2093
2112
|
title: isFilterRowVisible ? "Ocultar filtros" : "Mostrar filtros",
|
|
2094
|
-
sx: { p: 0.25 },
|
|
2113
|
+
sx: { p: 0.25, color: "grey.800" },
|
|
2095
2114
|
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
2115
|
}
|
|
2097
2116
|
),
|
|
@@ -2101,13 +2120,13 @@ var ActionsColumnHeaderCell = ({
|
|
|
2101
2120
|
onClick: (event) => handleDataGridOptions(event),
|
|
2102
2121
|
size: "small",
|
|
2103
2122
|
title: "Opciones de esta tabla",
|
|
2104
|
-
sx: { p: 0.25 },
|
|
2123
|
+
sx: { p: 0.25, color: "grey.800" },
|
|
2105
2124
|
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_MoreVert.default, { sx: { fontSize: 20, variant: "filled", size: "small" } })
|
|
2106
2125
|
}
|
|
2107
2126
|
)
|
|
2108
2127
|
] });
|
|
2109
2128
|
};
|
|
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() }) });
|
|
2129
|
+
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.Box, { sx: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.Typography, { variant: "caption", sx: { fontSize: "0.75rem", fontWeight: "bold" }, children: detailTable.abr.toUpperCase() }) }) });
|
|
2111
2130
|
|
|
2112
2131
|
// src/components/grid/FilterInputRender.tsx
|
|
2113
2132
|
var import_material9 = require("@mui/material");
|
|
@@ -2582,9 +2601,12 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
2582
2601
|
"& .MuiOutlinedInput-root": {
|
|
2583
2602
|
backgroundColor: "background.paper",
|
|
2584
2603
|
height: FILTER_ROW_HEIGHT - 5,
|
|
2585
|
-
minWidth:
|
|
2604
|
+
minWidth: 30,
|
|
2586
2605
|
fontSize: "0.8rem",
|
|
2587
2606
|
padding: "0px"
|
|
2607
|
+
},
|
|
2608
|
+
"& .MuiOutlinedInput-input": {
|
|
2609
|
+
padding: "0 4px"
|
|
2588
2610
|
}
|
|
2589
2611
|
} : {
|
|
2590
2612
|
"& .MuiOutlinedInput-root": {
|
|
@@ -2608,7 +2630,10 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
2608
2630
|
};
|
|
2609
2631
|
|
|
2610
2632
|
// src/components/grid/FilterInputRender.tsx
|
|
2611
|
-
var import_jsx_runtime12 =
|
|
2633
|
+
var import_jsx_runtime12 = (
|
|
2634
|
+
// como en backend-plus, el operador es un símbolo chico y el campo se queda con el resto del ancho
|
|
2635
|
+
require("react/jsx-runtime")
|
|
2636
|
+
);
|
|
2612
2637
|
function FilterInputRenderer({
|
|
2613
2638
|
columnKey,
|
|
2614
2639
|
currentFilter,
|
|
@@ -2631,7 +2656,7 @@ function FilterInputRenderer({
|
|
|
2631
2656
|
[columnKey]: { operator: newOp, value: formattedVal }
|
|
2632
2657
|
}));
|
|
2633
2658
|
};
|
|
2634
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material9.Box, { sx: { mt: 0, display: "flex", alignItems: "center", gap:
|
|
2659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material9.Box, { sx: { mt: 0, display: "flex", alignItems: "center", gap: "2px", width: "100%" }, children: [
|
|
2635
2660
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2636
2661
|
"select",
|
|
2637
2662
|
{
|
|
@@ -2639,13 +2664,16 @@ function FilterInputRenderer({
|
|
|
2639
2664
|
onChange: (e) => handleFilterChange(e.target.value, val),
|
|
2640
2665
|
style: {
|
|
2641
2666
|
height: FILTER_ROW_HEIGHT - 5,
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2667
|
+
width: 22,
|
|
2668
|
+
flexShrink: 0,
|
|
2669
|
+
appearance: "none",
|
|
2670
|
+
backgroundColor: "#CEF",
|
|
2671
|
+
border: "none",
|
|
2645
2672
|
borderRadius: "4px",
|
|
2646
2673
|
fontSize: "0.8rem",
|
|
2647
|
-
padding:
|
|
2674
|
+
padding: 0,
|
|
2648
2675
|
textAlign: "center",
|
|
2676
|
+
textAlignLast: "center",
|
|
2649
2677
|
cursor: "pointer"
|
|
2650
2678
|
},
|
|
2651
2679
|
children: filterOperators.map((op) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: op.value, children: op.label }, op.value))
|
|
@@ -2696,7 +2724,7 @@ var defaultColumnSummaryCellRenderer = (props, fixedFields) => {
|
|
|
2696
2724
|
const { filters, setFilters } = row;
|
|
2697
2725
|
if (valorFijoDe(fixedFields, column.key)) return null;
|
|
2698
2726
|
const fieldDef = esColumnaPropia(column) && column.customType === "default" ? column.fieldDef : void 0;
|
|
2699
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Box, { sx: {
|
|
2727
|
+
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
2728
|
FilterInputRender_default,
|
|
2701
2729
|
{
|
|
2702
2730
|
columnKey: column.key,
|
|
@@ -2923,14 +2951,12 @@ var allColumnsCellRenderer = (props) => {
|
|
|
2923
2951
|
}
|
|
2924
2952
|
];
|
|
2925
2953
|
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.
|
|
2954
|
+
import_material13.IconButton,
|
|
2927
2955
|
{
|
|
2928
|
-
variant: "outlined",
|
|
2929
|
-
color: actionDef.color,
|
|
2930
2956
|
size: "small",
|
|
2931
2957
|
onClick: () => actionDef.handler(row),
|
|
2932
2958
|
title: actionDef.title,
|
|
2933
|
-
sx: { width: 22,
|
|
2959
|
+
sx: { width: 22, height: 22, p: 0, color: "grey.800", "&:hover": { color: `${actionDef.color}.main` } },
|
|
2934
2960
|
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(actionDef.icon, { sx: { fontSize: 18 } })
|
|
2935
2961
|
},
|
|
2936
2962
|
actionDef.action
|
|
@@ -3340,20 +3366,36 @@ function campoDibujable(field) {
|
|
|
3340
3366
|
|
|
3341
3367
|
// src/hooks/grid/useGridColumns.ts
|
|
3342
3368
|
var estimateTextWidth = (text) => text.length * 8 + 16;
|
|
3343
|
-
var
|
|
3369
|
+
var contextoDeMedida;
|
|
3370
|
+
var anchoDeTitulo = (texto) => {
|
|
3371
|
+
if (contextoDeMedida === void 0) {
|
|
3372
|
+
try {
|
|
3373
|
+
contextoDeMedida = document.createElement("canvas").getContext("2d");
|
|
3374
|
+
} catch {
|
|
3375
|
+
contextoDeMedida = null;
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
if (!contextoDeMedida) return texto.length * 9;
|
|
3379
|
+
contextoDeMedida.font = "bold 14.9px Roboto, Helvetica, Arial, sans-serif";
|
|
3380
|
+
return Math.ceil(contextoDeMedida.measureText(texto).width);
|
|
3381
|
+
};
|
|
3382
|
+
var EXTRA_TITULO = 8 + 20 + 4;
|
|
3383
|
+
var calcularAnchosDeColumnas = (tableDefinition, filas, anchoDisponible = Infinity) => {
|
|
3344
3384
|
const anchos = /* @__PURE__ */ new Map();
|
|
3385
|
+
const anchosConTituloCompleto = /* @__PURE__ */ new Map();
|
|
3345
3386
|
const muestra = filas.slice(0, 50);
|
|
3346
3387
|
tableDefinition.fields.forEach((fieldDef) => {
|
|
3347
3388
|
if (typeof fieldDef.width === "number" && fieldDef.width > 0) {
|
|
3348
3389
|
anchos.set(fieldDef.name, fieldDef.width);
|
|
3390
|
+
anchosConTituloCompleto.set(fieldDef.name, fieldDef.width);
|
|
3349
3391
|
return;
|
|
3350
3392
|
}
|
|
3351
3393
|
const headerLabel = fieldDef.label || fieldDef.name;
|
|
3352
3394
|
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 =
|
|
3395
|
+
let typeMinWidth = 80;
|
|
3396
|
+
if (type.includes("boolean") || type.includes("checkbox")) typeMinWidth = 80;
|
|
3397
|
+
else if (type.includes("date") || type.includes("timestamp")) typeMinWidth = 120;
|
|
3398
|
+
else if (type.includes("integer") || type.includes("numeric")) typeMinWidth = 90;
|
|
3357
3399
|
const headerWidth = estimateTextWidth(headerLabel) + 20;
|
|
3358
3400
|
const typer = typerFrom(fieldDef);
|
|
3359
3401
|
const maxDataWidth = muestra.reduce((maxW, row) => {
|
|
@@ -3367,9 +3409,12 @@ var calcularAnchosDeColumnas = (tableDefinition, filas) => {
|
|
|
3367
3409
|
}
|
|
3368
3410
|
return Math.max(maxW, estimateTextWidth(texto));
|
|
3369
3411
|
}, 0);
|
|
3370
|
-
|
|
3412
|
+
const compacto = Math.min(Math.max(headerWidth, maxDataWidth, typeMinWidth), 500);
|
|
3413
|
+
anchos.set(fieldDef.name, compacto);
|
|
3414
|
+
anchosConTituloCompleto.set(fieldDef.name, Math.max(compacto, Math.min(anchoDeTitulo(cambiarGuionesBajosPorEspacios(headerLabel)) + EXTRA_TITULO, 500)));
|
|
3371
3415
|
});
|
|
3372
|
-
|
|
3416
|
+
const sumaCompleta = [...anchos.keys()].reduce((total, nombre) => total + (anchosConTituloCompleto.get(nombre) ?? 0), 0);
|
|
3417
|
+
return sumaCompleta <= anchoDisponible ? anchosConTituloCompleto : anchos;
|
|
3373
3418
|
};
|
|
3374
3419
|
var useGridColumns = ({
|
|
3375
3420
|
tableDefinition,
|
|
@@ -4094,6 +4139,7 @@ var ALTO_TITULO_ANIDADA = 26;
|
|
|
4094
4139
|
var ALTO_MINIMO_CUERPO_ANIDADA = 120;
|
|
4095
4140
|
var HOLGURA_ANIDADA = 24;
|
|
4096
4141
|
var ANCHO_MINIMO_ANIDADA = 240;
|
|
4142
|
+
var ANCHO_RESERVADO_PANTALLA = 320;
|
|
4097
4143
|
var SANGRIA_DETALLE = 28 + 8 + 3;
|
|
4098
4144
|
var MARGEN_INFERIOR_PAGINA = 24;
|
|
4099
4145
|
var PRIMERAS_FILAS_ANIDADA = 20;
|
|
@@ -4309,7 +4355,7 @@ var GenericDataGrid = ({
|
|
|
4309
4355
|
const firstDisplayCount = tableDefinition?.firstDisplayCount ?? PRIMERAS_FILAS_ANIDADA;
|
|
4310
4356
|
const firstDisplayOverLimit = tableDefinition?.firstDisplayOverLimit ?? LIMITE_PRIMERAS_FILAS_ANIDADA;
|
|
4311
4357
|
const filasVisiblesMax = anidada ? filteredRows.length <= firstDisplayOverLimit ? filteredRows.length : firstDisplayCount : void 0;
|
|
4312
|
-
const conPie =
|
|
4358
|
+
const conPie = !!tableDefinition?.fields.some((field) => field.aggregate);
|
|
4313
4359
|
const { gridHeight, bottomSummaryRow, summaryRows, filterHeight } = useGridLayout({
|
|
4314
4360
|
filteredRows,
|
|
4315
4361
|
isFilterRowVisible,
|
|
@@ -4403,7 +4449,7 @@ var GenericDataGrid = ({
|
|
|
4403
4449
|
const definition = parametros.tableDef ? fusionar(definicionDelServidor, parametros.tableDef) : definicionDelServidor;
|
|
4404
4450
|
setTableDefinition(definition);
|
|
4405
4451
|
setSortColumns(getInitialSortColumns(definition));
|
|
4406
|
-
setAnchosCalculados(calcularAnchosDeColumnas(definition, data));
|
|
4452
|
+
setAnchosCalculados(calcularAnchosDeColumnas(definition, data, window.innerWidth - ANCHO_RESERVADO_PANTALLA));
|
|
4407
4453
|
setColumnasOcultas(columnasOcultasIniciales(definition));
|
|
4408
4454
|
setTableData(data);
|
|
4409
4455
|
const filasDeFiltros = parametros.filterColumns ?? aFiltrosIniciales(definition.filterColumns);
|
|
@@ -4604,7 +4650,7 @@ var GenericDataGrid = ({
|
|
|
4604
4650
|
[exitingRowIds, primaryKey]
|
|
4605
4651
|
);
|
|
4606
4652
|
const anchoContenido = (0, import_react26.useMemo)(() => {
|
|
4607
|
-
if (
|
|
4653
|
+
if (columns.length === 0) return void 0;
|
|
4608
4654
|
const sumaColumnas = columns.reduce((total, col) => {
|
|
4609
4655
|
const medido = columnWidths.get(col.key)?.width;
|
|
4610
4656
|
return total + (typeof medido === "number" ? medido : typeof col.width === "number" ? col.width : 100);
|
|
@@ -4614,8 +4660,9 @@ var GenericDataGrid = ({
|
|
|
4614
4660
|
return Math.max(ANCHO_MINIMO_ANIDADA, propio, anchoDetalleMax > 0 ? anchoDetalleMax + SANGRIA_DETALLE + (medidas?.barra ?? 0) + 2 : 0);
|
|
4615
4661
|
}, [anidada, columns, columnWidths, medidas?.barra, detallesAbiertos, anchosDetalle]);
|
|
4616
4662
|
(0, import_react26.useEffect)(() => {
|
|
4617
|
-
if (anchoContenido !== void 0) onAnchoDeseado?.(anchoContenido);
|
|
4618
|
-
}, [onAnchoDeseado, anchoContenido]);
|
|
4663
|
+
if (anidada && anchoContenido !== void 0) onAnchoDeseado?.(anchoContenido);
|
|
4664
|
+
}, [onAnchoDeseado, anidada, anchoContenido]);
|
|
4665
|
+
const anchoExterior = anchoContenido === void 0 ? void 0 : anidada ? anchoContenido : anchoContenido - 2 + 32 + ancestors.length * 32;
|
|
4619
4666
|
const estiloGrilla = (0, import_react26.useMemo)(() => ({ height: "100%", width: "100%", boxSizing: "border-box", ...gridStyles }), [gridStyles]);
|
|
4620
4667
|
const bottomSummaryRows = (0, import_react26.useMemo)(() => conPie ? [bottomSummaryRow] : [], [conPie, bottomSummaryRow]);
|
|
4621
4668
|
const vistaGrilla = (0, import_react26.useMemo)(() => ({ isFilterRowVisible }), [isFilterRowVisible]);
|
|
@@ -4641,7 +4688,7 @@ var GenericDataGrid = ({
|
|
|
4641
4688
|
if (!tableDefinition) {
|
|
4642
4689
|
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
4690
|
}
|
|
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:
|
|
4691
|
+
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
4692
|
!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
4693
|
StaticAncestorGrid,
|
|
4647
4694
|
{
|
|
@@ -4738,7 +4785,7 @@ var GenericDataGrid = ({
|
|
|
4738
4785
|
sx: {
|
|
4739
4786
|
position: "absolute",
|
|
4740
4787
|
top: filterHeight + HEADER_ROW_HEIGHT + 1,
|
|
4741
|
-
bottom: anidada ? (conPie ? SUMMARY_ROW_HEIGHT : 0) + 4 : 102,
|
|
4788
|
+
bottom: anidada ? (conPie ? SUMMARY_ROW_HEIGHT : 0) + 4 : conPie ? 102 : 102 - SUMMARY_ROW_HEIGHT,
|
|
4742
4789
|
left: 18,
|
|
4743
4790
|
right: 0,
|
|
4744
4791
|
display: "flex",
|
|
@@ -4863,8 +4910,8 @@ var GenericDataGrid = ({
|
|
|
4863
4910
|
var GenericDataGrid_default = GenericDataGrid;
|
|
4864
4911
|
|
|
4865
4912
|
// src/App.tsx
|
|
4866
|
-
var
|
|
4867
|
-
var
|
|
4913
|
+
var import_react44 = __toESM(require("react"), 1);
|
|
4914
|
+
var import_react_router_dom18 = require("react-router-dom");
|
|
4868
4915
|
|
|
4869
4916
|
// src/components/MainLayout.tsx
|
|
4870
4917
|
var import_react30 = require("react");
|
|
@@ -4875,6 +4922,15 @@ var import_material21 = require("@mui/material");
|
|
|
4875
4922
|
var import_react27 = require("react");
|
|
4876
4923
|
var import_react_router_dom = require("react-router-dom");
|
|
4877
4924
|
var import_react_redux2 = require("react-redux");
|
|
4925
|
+
|
|
4926
|
+
// src/utils/cierreVoluntario.ts
|
|
4927
|
+
var cierreVoluntario = false;
|
|
4928
|
+
var marcarCierreVoluntario = (activo) => {
|
|
4929
|
+
cierreVoluntario = activo;
|
|
4930
|
+
};
|
|
4931
|
+
var huboCierreVoluntario = () => cierreVoluntario;
|
|
4932
|
+
|
|
4933
|
+
// src/contexts/AppContext.tsx
|
|
4878
4934
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4879
4935
|
var AuthContext = (0, import_react27.createContext)(void 0);
|
|
4880
4936
|
var useApp = () => {
|
|
@@ -4891,9 +4947,10 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4891
4947
|
const [showSessionExpiredMessage, setShowSessionExpiredMessage] = (0, import_react27.useState)(false);
|
|
4892
4948
|
const isRedirectingRef = (0, import_react27.useRef)(false);
|
|
4893
4949
|
const huboSesionRef = (0, import_react27.useRef)(false);
|
|
4950
|
+
const cierreVoluntarioRef = (0, import_react27.useRef)(false);
|
|
4894
4951
|
const dispatch = (0, import_react_redux2.useDispatch)();
|
|
4895
4952
|
const clientContext = (0, import_react_redux2.useSelector)((state) => state.clientContext);
|
|
4896
|
-
if (clientContext.status === "succeeded") huboSesionRef.current = true;
|
|
4953
|
+
if (clientContext.status === "succeeded" && !cierreVoluntarioRef.current) huboSesionRef.current = true;
|
|
4897
4954
|
const navigate = (0, import_react_router_dom.useNavigate)();
|
|
4898
4955
|
const handleExpiredSessionRedirect = (0, import_react27.useCallback)(() => {
|
|
4899
4956
|
isRedirectingRef.current = true;
|
|
@@ -4904,6 +4961,17 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4904
4961
|
isRedirectingRef.current = false;
|
|
4905
4962
|
}, 2e3);
|
|
4906
4963
|
}, [navigate]);
|
|
4964
|
+
const avisarCierreVoluntario = (0, import_react27.useCallback)((activo) => {
|
|
4965
|
+
cierreVoluntarioRef.current = activo;
|
|
4966
|
+
marcarCierreVoluntario(activo);
|
|
4967
|
+
if (activo) huboSesionRef.current = false;
|
|
4968
|
+
}, []);
|
|
4969
|
+
const limpiarContextoPorSesionPerdida = (0, import_react27.useCallback)(() => {
|
|
4970
|
+
if (clientContext.status === "succeeded" && clientContext.username !== "" && !cierreVoluntarioRef.current) {
|
|
4971
|
+
dispatch(setRedirectUsername(clientContext.username));
|
|
4972
|
+
}
|
|
4973
|
+
dispatch(clearClientContext());
|
|
4974
|
+
}, [dispatch, clientContext.status, clientContext.username]);
|
|
4907
4975
|
const location = (0, import_react_router_dom.useLocation)();
|
|
4908
4976
|
const isCurrentPathPublic = (0, import_react27.useCallback)(() => {
|
|
4909
4977
|
const current = location.pathname;
|
|
@@ -4929,8 +4997,8 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4929
4997
|
}
|
|
4930
4998
|
} else {
|
|
4931
4999
|
setIsLoggedIn(false);
|
|
4932
|
-
|
|
4933
|
-
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current) {
|
|
5000
|
+
limpiarContextoPorSesionPerdida();
|
|
5001
|
+
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current && !cierreVoluntarioRef.current) {
|
|
4934
5002
|
console.warn("Sesi\xF3n inv\xE1lida en ruta protegida. Mostrando modal.");
|
|
4935
5003
|
setShowSessionExpiredMessage(true);
|
|
4936
5004
|
} else {
|
|
@@ -4940,13 +5008,13 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4940
5008
|
} catch (error) {
|
|
4941
5009
|
console.error("Error checking session:", error);
|
|
4942
5010
|
setIsLoggedIn(false);
|
|
4943
|
-
|
|
5011
|
+
limpiarContextoPorSesionPerdida();
|
|
4944
5012
|
const isPublic = publicPaths.some((p) => location.pathname === p || location.pathname.startsWith(p + "/"));
|
|
4945
|
-
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current) {
|
|
5013
|
+
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current && !cierreVoluntarioRef.current) {
|
|
4946
5014
|
setShowSessionExpiredMessage(true);
|
|
4947
5015
|
}
|
|
4948
5016
|
}
|
|
4949
|
-
}, [dispatch, clientContext.status, showSessionExpiredMessage, isCurrentPathPublic]);
|
|
5017
|
+
}, [dispatch, clientContext.status, showSessionExpiredMessage, isCurrentPathPublic, limpiarContextoPorSesionPerdida]);
|
|
4950
5018
|
(0, import_react27.useEffect)(() => {
|
|
4951
5019
|
checkSession();
|
|
4952
5020
|
const intervalId = setInterval(checkSession, 15 * 1e3);
|
|
@@ -4960,20 +5028,24 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
4960
5028
|
checkSession,
|
|
4961
5029
|
showSessionExpiredMessage,
|
|
4962
5030
|
setShowSessionExpiredMessage,
|
|
4963
|
-
handleExpiredSessionRedirect
|
|
5031
|
+
handleExpiredSessionRedirect,
|
|
5032
|
+
avisarCierreVoluntario
|
|
4964
5033
|
}), [
|
|
4965
5034
|
isLoggedIn,
|
|
4966
5035
|
setIsLoggedIn,
|
|
4967
5036
|
checkSession,
|
|
4968
5037
|
showSessionExpiredMessage,
|
|
4969
5038
|
setShowSessionExpiredMessage,
|
|
4970
|
-
handleExpiredSessionRedirect
|
|
5039
|
+
handleExpiredSessionRedirect,
|
|
5040
|
+
avisarCierreVoluntario
|
|
4971
5041
|
]);
|
|
4972
5042
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AuthContext.Provider, { value: authContextValue, children });
|
|
4973
5043
|
};
|
|
4974
5044
|
|
|
4975
5045
|
// src/components/MainLayout.tsx
|
|
5046
|
+
var import_react_router_dom5 = require("react-router-dom");
|
|
4976
5047
|
var import_Logout = __toESM(require("@mui/icons-material/Logout"), 1);
|
|
5048
|
+
var import_VpnKey = __toESM(require("@mui/icons-material/VpnKey"), 1);
|
|
4977
5049
|
var import_Menu = __toESM(require("@mui/icons-material/Menu"), 1);
|
|
4978
5050
|
var import_ChevronLeft = __toESM(require("@mui/icons-material/ChevronLeft"), 1);
|
|
4979
5051
|
|
|
@@ -4987,11 +5059,18 @@ var import_Folder = __toESM(require("@mui/icons-material/Folder"), 1);
|
|
|
4987
5059
|
var import_Dns = __toESM(require("@mui/icons-material/Dns"), 1);
|
|
4988
5060
|
var import_WarningAmber3 = __toESM(require("@mui/icons-material/WarningAmber"), 1);
|
|
4989
5061
|
var import_DesktopWindows = __toESM(require("@mui/icons-material/DesktopWindows"), 1);
|
|
4990
|
-
var
|
|
4991
|
-
var
|
|
5062
|
+
var import_Search3 = __toESM(require("@mui/icons-material/Search"), 1);
|
|
5063
|
+
var import_Clear = __toESM(require("@mui/icons-material/Clear"), 1);
|
|
4992
5064
|
var import_react_router_dom2 = require("react-router-dom");
|
|
4993
5065
|
var import_colors = require("@mui/material/colors");
|
|
4994
5066
|
|
|
5067
|
+
// src/puente/habilitacion.ts
|
|
5068
|
+
var habilitado = false;
|
|
5069
|
+
var habilitarPuenteBP = () => {
|
|
5070
|
+
habilitado = true;
|
|
5071
|
+
};
|
|
5072
|
+
var puenteBPHabilitado = () => habilitado;
|
|
5073
|
+
|
|
4995
5074
|
// src/utils/menuInicial.ts
|
|
4996
5075
|
function rutaDeTablaDeMenu(camino) {
|
|
4997
5076
|
return `/menu/${camino.map(encodeURIComponent).join("/")}`;
|
|
@@ -5042,16 +5121,93 @@ function itemInicial(menu) {
|
|
|
5042
5121
|
return elegido.menuType === "menu" ? itemInicial(elegido.menuContent) : elegido;
|
|
5043
5122
|
}
|
|
5044
5123
|
|
|
5124
|
+
// src/utils/busquedaDeMenu.ts
|
|
5125
|
+
function etiquetaDeItem(item) {
|
|
5126
|
+
return item.label || item.name;
|
|
5127
|
+
}
|
|
5128
|
+
function claveDeMenu(camino) {
|
|
5129
|
+
return camino.join("/");
|
|
5130
|
+
}
|
|
5131
|
+
function hojasDeMenu(menu, grupos = [], etiquetasDeGrupos = []) {
|
|
5132
|
+
return menu.flatMap(
|
|
5133
|
+
(item) => item.menuType === "menu" ? hojasDeMenu(item.menuContent, [...grupos, item.name], [...etiquetasDeGrupos, etiquetaDeItem(item)]) : [{ item, grupos, etiquetasDeGrupos, clave: claveDeMenu([...grupos, item.name]) }]
|
|
5134
|
+
);
|
|
5135
|
+
}
|
|
5136
|
+
function normalizarParaBuscar(texto) {
|
|
5137
|
+
return texto.normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/_/g, " ").toLowerCase();
|
|
5138
|
+
}
|
|
5139
|
+
function buscarEnMenu(hojas, consulta) {
|
|
5140
|
+
const palabras = normalizarParaBuscar(consulta).split(/\s+/).filter((palabra) => palabra !== "");
|
|
5141
|
+
if (palabras.length === 0) return [];
|
|
5142
|
+
const propias = [];
|
|
5143
|
+
const porGrupo = [];
|
|
5144
|
+
for (const hoja of hojas) {
|
|
5145
|
+
const propia = normalizarParaBuscar(`${etiquetaDeItem(hoja.item)} ${hoja.item.name}`);
|
|
5146
|
+
const completa = `${hoja.etiquetasDeGrupos.map(normalizarParaBuscar).join(" ")} ${propia}`;
|
|
5147
|
+
if (!palabras.every((palabra) => completa.includes(palabra))) continue;
|
|
5148
|
+
(palabras.every((palabra) => propia.includes(palabra)) ? propias : porGrupo).push(hoja);
|
|
5149
|
+
}
|
|
5150
|
+
return [...propias, ...porGrupo];
|
|
5151
|
+
}
|
|
5152
|
+
|
|
5045
5153
|
// src/components/SideMenu.tsx
|
|
5046
5154
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
5047
|
-
var
|
|
5155
|
+
var CLAVE_RECIENTES = "fpr.menu.recientes";
|
|
5156
|
+
var MAXIMO_RECIENTES = 4;
|
|
5157
|
+
var getIcon = (item, destacado = false) => {
|
|
5158
|
+
switch (item.menuType) {
|
|
5159
|
+
case "table":
|
|
5160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_TableChart.default, { sx: destacado ? { color: import_colors.blue[700] } : void 0 });
|
|
5161
|
+
case "proc":
|
|
5162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Dns.default, { sx: destacado ? { color: import_colors.teal[700] } : void 0 });
|
|
5163
|
+
case "menu":
|
|
5164
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Folder.default, { sx: destacado ? { color: import_colors.orange[800] } : void 0 });
|
|
5165
|
+
default:
|
|
5166
|
+
if (wScreens[item.menuType] !== void 0 || puenteBPHabilitado()) {
|
|
5167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_DesktopWindows.default, { sx: destacado ? { color: import_colors.indigo[500] } : void 0 });
|
|
5168
|
+
}
|
|
5169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_WarningAmber3.default, { sx: destacado ? { color: import_colors.red[500] } : void 0 });
|
|
5170
|
+
}
|
|
5171
|
+
};
|
|
5172
|
+
var estaSeleccionado = (item, grupos, currentPath, hash = "") => {
|
|
5173
|
+
const pathParts = currentPath.split("/");
|
|
5174
|
+
const urlTableName = pathParts[1] === "table" ? pathParts[2] : null;
|
|
5175
|
+
if (item.menuType === "table") {
|
|
5176
|
+
return currentPath === rutaDeTablaDeMenu([...grupos, item.name]) || urlTableName === (item.table || item.name);
|
|
5177
|
+
} else if (item.menuType === "proc") {
|
|
5178
|
+
return currentPath === `/procedures/${item.name}`;
|
|
5179
|
+
} else if (item.menuType !== "menu") {
|
|
5180
|
+
return currentPath.startsWith(`/wScreens/${item.menuType}`) || currentPath.startsWith(`/wScreens-fallback/${item.menuType}`) || currentPath === "/bp/menu" && new URLSearchParams(hash.replace(/^[#?]/, "")).get("w") === item.menuType;
|
|
5181
|
+
}
|
|
5182
|
+
return false;
|
|
5183
|
+
};
|
|
5184
|
+
var leerRecientes = () => {
|
|
5185
|
+
try {
|
|
5186
|
+
const guardado = JSON.parse(localStorage.getItem(CLAVE_RECIENTES) ?? "[]");
|
|
5187
|
+
return Array.isArray(guardado) ? guardado.filter((clave) => typeof clave === "string") : [];
|
|
5188
|
+
} catch {
|
|
5189
|
+
return [];
|
|
5190
|
+
}
|
|
5191
|
+
};
|
|
5192
|
+
var guardarRecientes = (recientes) => {
|
|
5193
|
+
try {
|
|
5194
|
+
localStorage.setItem(CLAVE_RECIENTES, JSON.stringify(recientes));
|
|
5195
|
+
} catch {
|
|
5196
|
+
}
|
|
5197
|
+
};
|
|
5198
|
+
var MenuListItem = ({ item, level, grupos = [], hermanos = [], onMenuItemClick }) => {
|
|
5048
5199
|
const navigate = (0, import_react_router_dom2.useNavigate)();
|
|
5049
5200
|
const location = (0, import_react_router_dom2.useLocation)();
|
|
5050
|
-
const
|
|
5201
|
+
const clave = claveDeMenu([...grupos, item.name]);
|
|
5202
|
+
const open = useSubMenuOpenState(clave);
|
|
5051
5203
|
const dispatch = useAppDispatch();
|
|
5052
5204
|
const handleClick = () => {
|
|
5053
5205
|
if (item.menuType === "menu") {
|
|
5054
|
-
|
|
5206
|
+
if (open) {
|
|
5207
|
+
dispatch(setSubMenuOpen({ menuName: clave, isOpen: false }));
|
|
5208
|
+
} else {
|
|
5209
|
+
dispatch(abrirGrupo({ clave, hermanos }));
|
|
5210
|
+
}
|
|
5055
5211
|
} else {
|
|
5056
5212
|
navigate(rutaDeItemDeMenu(item, grupos));
|
|
5057
5213
|
if (onMenuItemClick) {
|
|
@@ -5059,39 +5215,14 @@ var MenuListItem = ({ item, level, grupos = [], onMenuItemClick }) => {
|
|
|
5059
5215
|
}
|
|
5060
5216
|
}
|
|
5061
5217
|
};
|
|
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
|
-
}
|
|
5218
|
+
const isSelected = estaSeleccionado(item, grupos, location.pathname, location.hash);
|
|
5089
5219
|
const itemRef = import_react28.default.useRef(null);
|
|
5090
5220
|
(0, import_react28.useEffect)(() => {
|
|
5091
5221
|
if (isSelected && itemRef.current) {
|
|
5092
5222
|
itemRef.current.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
5093
5223
|
}
|
|
5094
5224
|
}, [isSelected]);
|
|
5225
|
+
const contenido = item.menuType === "menu" ? item.menuContent : [];
|
|
5095
5226
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { ref: itemRef, children: [
|
|
5096
5227
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
5097
5228
|
import_material20.ListItemButton,
|
|
@@ -5100,83 +5231,156 @@ var MenuListItem = ({ item, level, grupos = [], onMenuItemClick }) => {
|
|
|
5100
5231
|
sx: { pl: level * 2 },
|
|
5101
5232
|
selected: isSelected,
|
|
5102
5233
|
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
|
|
5234
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemIcon, { sx: { minWidth: "38px" }, children: getIcon(item, isSelected || open) }),
|
|
5235
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemText, { primary: etiquetaDeItem(item) }),
|
|
5105
5236
|
item.menuType === "menu" ? open ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ExpandLess.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ExpandMore.default, {}) : null
|
|
5106
5237
|
]
|
|
5107
5238
|
}
|
|
5108
5239
|
),
|
|
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:
|
|
5240
|
+
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
5241
|
MenuListItem,
|
|
5111
5242
|
{
|
|
5112
5243
|
item: subItem,
|
|
5113
5244
|
level: level + 1,
|
|
5114
5245
|
grupos: [...grupos, item.name],
|
|
5246
|
+
hermanos: contenido.filter((otro) => otro !== subItem).map((otro) => claveDeMenu([...grupos, item.name, otro.name])),
|
|
5115
5247
|
onMenuItemClick
|
|
5116
5248
|
},
|
|
5117
5249
|
subItem.name
|
|
5118
5250
|
)) }) })
|
|
5119
5251
|
] });
|
|
5120
5252
|
};
|
|
5253
|
+
var ItemPlano = ({ hoja, seleccionado, traerALaVista = false, onElegir }) => {
|
|
5254
|
+
const boton = (0, import_react28.useRef)(null);
|
|
5255
|
+
(0, import_react28.useEffect)(() => {
|
|
5256
|
+
if (traerALaVista && seleccionado) boton.current?.scrollIntoView({ block: "nearest" });
|
|
5257
|
+
}, [traerALaVista, seleccionado]);
|
|
5258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_material20.ListItemButton, { dense: true, selected: seleccionado, onClick: () => onElegir(hoja), ref: boton, children: [
|
|
5259
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.ListItemIcon, { sx: { minWidth: "38px" }, children: getIcon(hoja.item, seleccionado) }),
|
|
5260
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5261
|
+
import_material20.ListItemText,
|
|
5262
|
+
{
|
|
5263
|
+
primary: etiquetaDeItem(hoja.item),
|
|
5264
|
+
secondary: hoja.etiquetasDeGrupos.join(" \u203A ") || void 0,
|
|
5265
|
+
secondaryTypographyProps: { noWrap: true }
|
|
5266
|
+
}
|
|
5267
|
+
)
|
|
5268
|
+
] });
|
|
5269
|
+
};
|
|
5121
5270
|
var SideMenu = ({ onMenuItemClick }) => {
|
|
5122
5271
|
const { clientContext } = useApp();
|
|
5123
5272
|
const navigate = (0, import_react_router_dom2.useNavigate)();
|
|
5124
5273
|
const location = (0, import_react_router_dom2.useLocation)();
|
|
5125
5274
|
const dispatch = useAppDispatch();
|
|
5126
|
-
const
|
|
5127
|
-
const
|
|
5128
|
-
const
|
|
5129
|
-
const
|
|
5130
|
-
const
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5275
|
+
const [consulta, setConsulta] = (0, import_react28.useState)("");
|
|
5276
|
+
const [indice, setIndice] = (0, import_react28.useState)(0);
|
|
5277
|
+
const [recientes, setRecientes] = (0, import_react28.useState)(leerRecientes);
|
|
5278
|
+
const campoDeBusqueda = (0, import_react28.useRef)(null);
|
|
5279
|
+
const menu = clientContext?.menu;
|
|
5280
|
+
const hojas = (0, import_react28.useMemo)(() => hojasDeMenu(menu ?? []), [menu]);
|
|
5281
|
+
const resultados = (0, import_react28.useMemo)(() => buscarEnMenu(hojas, consulta), [hojas, consulta]);
|
|
5282
|
+
(0, import_react28.useEffect)(() => {
|
|
5283
|
+
const alApretar = (evento) => {
|
|
5284
|
+
if ((evento.ctrlKey || evento.metaKey) && !evento.altKey && !evento.shiftKey && evento.key.toLowerCase() === "k") {
|
|
5285
|
+
evento.preventDefault();
|
|
5286
|
+
dispatch(setDrawerOpen(true));
|
|
5287
|
+
setTimeout(() => {
|
|
5288
|
+
campoDeBusqueda.current?.focus();
|
|
5289
|
+
campoDeBusqueda.current?.select();
|
|
5290
|
+
}, 50);
|
|
5291
|
+
}
|
|
5292
|
+
};
|
|
5293
|
+
window.addEventListener("keydown", alApretar);
|
|
5294
|
+
return () => window.removeEventListener("keydown", alApretar);
|
|
5295
|
+
}, [dispatch]);
|
|
5296
|
+
(0, import_react28.useEffect)(() => {
|
|
5297
|
+
const actual = hojas.find((hoja) => estaSeleccionado(hoja.item, hoja.grupos, location.pathname, location.hash));
|
|
5298
|
+
if (!actual) return;
|
|
5299
|
+
dispatch(abrirCamino(actual.grupos.map((_, i) => claveDeMenu(actual.grupos.slice(0, i + 1)))));
|
|
5300
|
+
setRecientes((anteriores) => {
|
|
5301
|
+
if (anteriores.includes(actual.clave)) return anteriores;
|
|
5302
|
+
const nuevos = [actual.clave, ...anteriores].slice(0, MAXIMO_RECIENTES);
|
|
5303
|
+
guardarRecientes(nuevos);
|
|
5304
|
+
return nuevos;
|
|
5305
|
+
});
|
|
5306
|
+
}, [location.pathname, location.hash, hojas, dispatch]);
|
|
5307
|
+
if (!menu) {
|
|
5134
5308
|
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
5309
|
}
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5310
|
+
const elegir = (hoja) => {
|
|
5311
|
+
navigate(rutaDeItemDeMenu(hoja.item, hoja.grupos));
|
|
5312
|
+
setConsulta("");
|
|
5313
|
+
setIndice(0);
|
|
5314
|
+
if (onMenuItemClick) {
|
|
5315
|
+
onMenuItemClick();
|
|
5316
|
+
}
|
|
5317
|
+
};
|
|
5318
|
+
const alApretarEnBusqueda = (evento) => {
|
|
5319
|
+
if (evento.key === "ArrowDown" || evento.key === "ArrowUp") {
|
|
5320
|
+
evento.preventDefault();
|
|
5321
|
+
if (resultados.length === 0) return;
|
|
5322
|
+
setIndice((actual) => (actual + (evento.key === "ArrowDown" ? 1 : -1) + resultados.length) % resultados.length);
|
|
5323
|
+
} else if (evento.key === "Enter") {
|
|
5324
|
+
evento.preventDefault();
|
|
5325
|
+
const hoja = resultados[indice];
|
|
5326
|
+
if (hoja) elegir(hoja);
|
|
5327
|
+
} else if (evento.key === "Escape" && consulta !== "") {
|
|
5328
|
+
evento.stopPropagation();
|
|
5329
|
+
setConsulta("");
|
|
5330
|
+
}
|
|
5331
|
+
};
|
|
5332
|
+
const hojasRecientes = recientes.map((clave) => hojas.find((hoja) => hoja.clave === clave)).filter((hoja) => hoja !== void 0);
|
|
5333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_material20.Box, { sx: { width: "100%", flex: 1, minHeight: 0, display: "flex", flexDirection: "column" }, children: [
|
|
5334
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Box, { sx: { px: 1.5, py: 1, flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5335
|
+
import_material20.TextField,
|
|
5336
|
+
{
|
|
5337
|
+
inputRef: campoDeBusqueda,
|
|
5338
|
+
value: consulta,
|
|
5339
|
+
onChange: (evento) => {
|
|
5340
|
+
setConsulta(evento.target.value);
|
|
5341
|
+
setIndice(0);
|
|
5342
|
+
},
|
|
5343
|
+
onKeyDown: alApretarEnBusqueda,
|
|
5344
|
+
placeholder: "Buscar (Ctrl+K)",
|
|
5345
|
+
size: "small",
|
|
5346
|
+
fullWidth: true,
|
|
5347
|
+
autoComplete: "off",
|
|
5348
|
+
sx: { "& .MuiInputBase-input": { fontSize: "0.8rem" } },
|
|
5349
|
+
InputProps: {
|
|
5350
|
+
startAdornment: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.InputAdornment, { position: "start", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Search3.default, { fontSize: "small" }) }),
|
|
5351
|
+
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: () => {
|
|
5352
|
+
setConsulta("");
|
|
5353
|
+
campoDeBusqueda.current?.focus();
|
|
5354
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_Clear.default, { fontSize: "small" }) }) }) : void 0
|
|
5159
5355
|
}
|
|
5160
5356
|
}
|
|
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
|
-
] }) }),
|
|
5357
|
+
) }),
|
|
5170
5358
|
/* @__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
|
-
|
|
5359
|
+
/* @__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: [
|
|
5360
|
+
hojasRecientes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
5361
|
+
/* @__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" }),
|
|
5362
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.List, { disablePadding: true, children: hojasRecientes.map((hoja) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5363
|
+
ItemPlano,
|
|
5364
|
+
{
|
|
5365
|
+
hoja,
|
|
5366
|
+
seleccionado: estaSeleccionado(hoja.item, hoja.grupos, location.pathname, location.hash),
|
|
5367
|
+
onElegir: elegir
|
|
5368
|
+
},
|
|
5369
|
+
hoja.clave
|
|
5370
|
+
)) }),
|
|
5371
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.Divider, {})
|
|
5372
|
+
] }),
|
|
5373
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_material20.List, { children: menu.map((menuItem) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5374
|
+
MenuListItem,
|
|
5375
|
+
{
|
|
5376
|
+
item: menuItem,
|
|
5377
|
+
level: 1,
|
|
5378
|
+
hermanos: menu.filter((otro) => otro !== menuItem).map((otro) => claveDeMenu([otro.name])),
|
|
5379
|
+
onMenuItemClick
|
|
5380
|
+
},
|
|
5381
|
+
menuItem.name
|
|
5382
|
+
)) })
|
|
5383
|
+
] }) })
|
|
5180
5384
|
] });
|
|
5181
5385
|
};
|
|
5182
5386
|
var SideMenu_default = SideMenu;
|
|
@@ -5186,10 +5390,11 @@ var import_react29 = require("react");
|
|
|
5186
5390
|
var import_react_router_dom3 = require("react-router-dom");
|
|
5187
5391
|
var import_react_redux3 = require("react-redux");
|
|
5188
5392
|
var useLogout = () => {
|
|
5189
|
-
const { setIsLoggedIn } = useApp();
|
|
5393
|
+
const { setIsLoggedIn, avisarCierreVoluntario } = useApp();
|
|
5190
5394
|
const dispatch = (0, import_react_redux3.useDispatch)();
|
|
5191
5395
|
const navigate = (0, import_react_router_dom3.useNavigate)();
|
|
5192
5396
|
const logout = (0, import_react29.useCallback)(async () => {
|
|
5397
|
+
avisarCierreVoluntario(true);
|
|
5193
5398
|
try {
|
|
5194
5399
|
const response = await fetchApi("/logout", { method: "GET" });
|
|
5195
5400
|
if (response.status === 401 || response.ok) {
|
|
@@ -5202,9 +5407,10 @@ var useLogout = () => {
|
|
|
5202
5407
|
} finally {
|
|
5203
5408
|
setIsLoggedIn(false);
|
|
5204
5409
|
dispatch(clearClientContext());
|
|
5410
|
+
dispatch(setRedirectPath(null));
|
|
5205
5411
|
navigate("/login", { replace: true });
|
|
5206
5412
|
}
|
|
5207
|
-
}, [setIsLoggedIn, dispatch, navigate]);
|
|
5413
|
+
}, [setIsLoggedIn, avisarCierreVoluntario, dispatch, navigate]);
|
|
5208
5414
|
return logout;
|
|
5209
5415
|
};
|
|
5210
5416
|
var useLogout_default = useLogout;
|
|
@@ -5215,6 +5421,7 @@ var drawerWidth = 240;
|
|
|
5215
5421
|
var MainLayout = () => {
|
|
5216
5422
|
const { clientContext } = useApp();
|
|
5217
5423
|
const logout = useLogout_default();
|
|
5424
|
+
const navigate = (0, import_react_router_dom5.useNavigate)();
|
|
5218
5425
|
const isDrawerOpen = useIsDrawerOpen();
|
|
5219
5426
|
const dispatch = useAppDispatch();
|
|
5220
5427
|
const theme = (0, import_material21.useTheme)();
|
|
@@ -5280,6 +5487,7 @@ var MainLayout = () => {
|
|
|
5280
5487
|
),
|
|
5281
5488
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Typography, { variant: "h6", noWrap: true, component: "div", sx: { flexGrow: 1 }, children: isDrawerOpen ? "" : clientContext.config.title }),
|
|
5282
5489
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material21.Typography, { variant: "subtitle1", component: "div", sx: { mr: 2 }, children: clientContext.username }),
|
|
5490
|
+
/* @__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
5491
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5284
5492
|
import_material21.Button,
|
|
5285
5493
|
{
|
|
@@ -5304,8 +5512,9 @@ var MainLayout = () => {
|
|
|
5304
5512
|
"& .MuiDrawer-paper": {
|
|
5305
5513
|
width: drawerWidth,
|
|
5306
5514
|
boxSizing: "border-box",
|
|
5307
|
-
|
|
5308
|
-
|
|
5515
|
+
overflow: "hidden",
|
|
5516
|
+
display: "flex",
|
|
5517
|
+
flexDirection: "column"
|
|
5309
5518
|
}
|
|
5310
5519
|
},
|
|
5311
5520
|
children: [
|
|
@@ -5317,6 +5526,8 @@ var MainLayout = () => {
|
|
|
5317
5526
|
alignItems: "center",
|
|
5318
5527
|
justifyContent: "flex-start",
|
|
5319
5528
|
px: 1,
|
|
5529
|
+
flexShrink: 0,
|
|
5530
|
+
// el logo queda fijo: solo scrollea la lista del menú
|
|
5320
5531
|
fontSize: "1.3rem",
|
|
5321
5532
|
minHeight: theme.mixins.toolbar.minHeight,
|
|
5322
5533
|
gap: 1.5
|
|
@@ -5426,12 +5637,12 @@ var SessionExpiredMessage = () => {
|
|
|
5426
5637
|
var SessionExpiredMessage_default = SessionExpiredMessage;
|
|
5427
5638
|
|
|
5428
5639
|
// src/pages/PantallaInicial.tsx
|
|
5429
|
-
var
|
|
5640
|
+
var import_react_router_dom6 = require("react-router-dom");
|
|
5430
5641
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
5431
5642
|
var PantallaInicial = () => {
|
|
5432
5643
|
const { clientContext } = useApp();
|
|
5433
5644
|
const item = clientContext.menu ? itemInicial(clientContext.menu) : void 0;
|
|
5434
|
-
return item && clientContext.menu ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5645
|
+
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
5646
|
};
|
|
5436
5647
|
var PantallaInicial_default = PantallaInicial;
|
|
5437
5648
|
|
|
@@ -5461,6 +5672,17 @@ var LogoutPage_default = LogoutPage;
|
|
|
5461
5672
|
// src/pages/LoginPage.tsx
|
|
5462
5673
|
var import_react32 = require("react");
|
|
5463
5674
|
var import_material24 = require("@mui/material");
|
|
5675
|
+
var import_react_router_dom7 = require("react-router-dom");
|
|
5676
|
+
|
|
5677
|
+
// src/pages/configuracionLogin.ts
|
|
5678
|
+
var RUTA_POR_OMISION = "/new-pass";
|
|
5679
|
+
var rutaDeRecuperarClave = null;
|
|
5680
|
+
var configurarRecuperarClave = (recuperarClave) => {
|
|
5681
|
+
rutaDeRecuperarClave = recuperarClave === true ? RUTA_POR_OMISION : typeof recuperarClave === "string" && recuperarClave !== "" ? recuperarClave : null;
|
|
5682
|
+
};
|
|
5683
|
+
var rutaParaRecuperarClave = () => rutaDeRecuperarClave;
|
|
5684
|
+
|
|
5685
|
+
// src/pages/LoginPage.tsx
|
|
5464
5686
|
var import_react_hook_form = require("react-hook-form");
|
|
5465
5687
|
var import_zod = require("@hookform/resolvers/zod");
|
|
5466
5688
|
var z = __toESM(require("zod"), 1);
|
|
@@ -5475,7 +5697,10 @@ var loginSchema = z.object({
|
|
|
5475
5697
|
var LoginPage = () => {
|
|
5476
5698
|
const [loginError, setLoginError] = (0, import_react32.useState)(null);
|
|
5477
5699
|
const [isSubmitting, setIsSubmitting] = (0, import_react32.useState)(false);
|
|
5478
|
-
const
|
|
5700
|
+
const estadoDeLaRuta = (0, import_react_router_dom7.useLocation)().state;
|
|
5701
|
+
const claveCambiada = typeof estadoDeLaRuta === "object" && estadoDeLaRuta !== null && "claveCambiada" in estadoDeLaRuta && estadoDeLaRuta.claveCambiada === true;
|
|
5702
|
+
const rutaDeRecuperarClave2 = rutaParaRecuperarClave();
|
|
5703
|
+
const { setIsLoggedIn, checkSession, avisarCierreVoluntario } = useApp();
|
|
5479
5704
|
const dispatch = (0, import_react_redux4.useDispatch)();
|
|
5480
5705
|
const {
|
|
5481
5706
|
control,
|
|
@@ -5507,6 +5732,7 @@ var LoginPage = () => {
|
|
|
5507
5732
|
const errorText = "Credenciales incorrectas o error al iniciar sesi\xF3n";
|
|
5508
5733
|
throw new Error(errorText);
|
|
5509
5734
|
}
|
|
5735
|
+
avisarCierreVoluntario(false);
|
|
5510
5736
|
setIsLoggedIn(true);
|
|
5511
5737
|
await dispatch(fetchClientContext()).unwrap();
|
|
5512
5738
|
console.log("Login exitoso y clientContext cargado.");
|
|
@@ -5546,58 +5772,77 @@ var LoginPage = () => {
|
|
|
5546
5772
|
}
|
|
5547
5773
|
) }),
|
|
5548
5774
|
/* @__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
|
-
|
|
5775
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
5776
|
+
"form",
|
|
5777
|
+
{
|
|
5778
|
+
onSubmit: handleSubmit(onSubmit),
|
|
5779
|
+
className: "space-y-4",
|
|
5780
|
+
onKeyDown: (evento) => {
|
|
5781
|
+
if (evento.key !== "Enter" || evento.shiftKey || evento.ctrlKey || evento.altKey || evento.metaKey) return;
|
|
5782
|
+
if (!(evento.target instanceof HTMLInputElement)) return;
|
|
5783
|
+
evento.preventDefault();
|
|
5784
|
+
if (!isSubmitting) void handleSubmit(onSubmit)();
|
|
5785
|
+
},
|
|
5786
|
+
children: [
|
|
5787
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
5788
|
+
/* @__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" }) }),
|
|
5789
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5790
|
+
import_react_hook_form.Controller,
|
|
5559
5791
|
{
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5792
|
+
name: "username",
|
|
5793
|
+
control,
|
|
5794
|
+
render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5795
|
+
import_material24.TextField,
|
|
5796
|
+
{
|
|
5797
|
+
...field,
|
|
5798
|
+
type: "text",
|
|
5799
|
+
id: "username",
|
|
5800
|
+
autoComplete: "username",
|
|
5801
|
+
placeholder: "Ingresa tu usuario",
|
|
5802
|
+
fullWidth: true,
|
|
5803
|
+
margin: "normal",
|
|
5804
|
+
error: !!errors.username,
|
|
5805
|
+
helperText: errors.username?.message,
|
|
5806
|
+
disabled: isSubmitting
|
|
5807
|
+
}
|
|
5808
|
+
)
|
|
5568
5809
|
}
|
|
5569
5810
|
)
|
|
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,
|
|
5811
|
+
] }),
|
|
5812
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
5813
|
+
/* @__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" }) }),
|
|
5814
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5815
|
+
import_react_hook_form.Controller,
|
|
5582
5816
|
{
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5817
|
+
name: "password",
|
|
5818
|
+
control,
|
|
5819
|
+
render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5820
|
+
import_material24.TextField,
|
|
5821
|
+
{
|
|
5822
|
+
...field,
|
|
5823
|
+
type: "password",
|
|
5824
|
+
id: "password",
|
|
5825
|
+
autoComplete: "current-password",
|
|
5826
|
+
placeholder: "Ingresa tu contrase\xF1a",
|
|
5827
|
+
fullWidth: true,
|
|
5828
|
+
margin: "normal",
|
|
5829
|
+
error: !!errors.password,
|
|
5830
|
+
helperText: errors.password?.message,
|
|
5831
|
+
disabled: isSubmitting
|
|
5832
|
+
}
|
|
5833
|
+
)
|
|
5591
5834
|
}
|
|
5592
5835
|
)
|
|
5593
|
-
}
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5836
|
+
] }),
|
|
5837
|
+
/* @__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: [
|
|
5838
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.CircularProgress, { size: 20, sx: { mr: 1 } }),
|
|
5839
|
+
"Iniciando sesi\xF3n..."
|
|
5840
|
+
] }) : "Iniciar Sesi\xF3n" })
|
|
5841
|
+
]
|
|
5842
|
+
}
|
|
5843
|
+
),
|
|
5844
|
+
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" }) }),
|
|
5845
|
+
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
5846
|
loginError && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material24.Alert, { severity: "error", sx: { mt: 2, maxHeight: "200px" }, children: [
|
|
5602
5847
|
" ",
|
|
5603
5848
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.AlertTitle, { children: "Error" }),
|
|
@@ -5613,7 +5858,7 @@ var LoginPage_default = LoginPage;
|
|
|
5613
5858
|
|
|
5614
5859
|
// src/components/ProcedureForm.tsx
|
|
5615
5860
|
var import_react33 = __toESM(require("react"), 1);
|
|
5616
|
-
var
|
|
5861
|
+
var import_react_router_dom8 = require("react-router-dom");
|
|
5617
5862
|
var import_material26 = require("@mui/material");
|
|
5618
5863
|
|
|
5619
5864
|
// src/pages/procedure-results/SuccessDisplay.tsx
|
|
@@ -5640,7 +5885,7 @@ var extendResultsOk = (newComponents) => {
|
|
|
5640
5885
|
// src/components/ProcedureForm.tsx
|
|
5641
5886
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5642
5887
|
var ProcedureForm = () => {
|
|
5643
|
-
const { procedureName } = (0,
|
|
5888
|
+
const { procedureName } = (0, import_react_router_dom8.useParams)();
|
|
5644
5889
|
const { clientContext } = useApp();
|
|
5645
5890
|
const { callApi, loading: apiLoading, error: apiError } = useApiCall();
|
|
5646
5891
|
const [validationErrors, setValidationErrors] = (0, import_react33.useState)({});
|
|
@@ -6058,15 +6303,15 @@ var ProcedureForm = () => {
|
|
|
6058
6303
|
var ProcedureForm_default = ProcedureForm;
|
|
6059
6304
|
|
|
6060
6305
|
// src/App.tsx
|
|
6061
|
-
var
|
|
6062
|
-
var
|
|
6306
|
+
var import_react_redux6 = require("react-redux");
|
|
6307
|
+
var import_react45 = require("redux-persist/integration/react");
|
|
6063
6308
|
|
|
6064
6309
|
// src/components/PrivateRoute.tsx
|
|
6065
6310
|
var import_react34 = require("react");
|
|
6066
|
-
var
|
|
6311
|
+
var import_react_router_dom9 = require("react-router-dom");
|
|
6067
6312
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
6068
6313
|
var PrivateRoute = ({ children }) => {
|
|
6069
|
-
const location = (0,
|
|
6314
|
+
const location = (0, import_react_router_dom9.useLocation)();
|
|
6070
6315
|
const dispatch = useAppDispatch();
|
|
6071
6316
|
const clientContextStatus = useClientContextStatus();
|
|
6072
6317
|
const isAuthenticated = clientContextStatus === "succeeded";
|
|
@@ -6074,7 +6319,7 @@ var PrivateRoute = ({ children }) => {
|
|
|
6074
6319
|
console.log(`[PrivateRoute] Render: Path=${location.pathname}, AuthStatus=${clientContextStatus}, IsAuthenticated=${isAuthenticated}, IsLoadingAuth=${isLoadingAuth}`);
|
|
6075
6320
|
(0, import_react34.useEffect)(() => {
|
|
6076
6321
|
console.log(`[PrivateRoute] Effect: Path=${location.pathname}, AuthStatus=${clientContextStatus}, IsAuthenticated=${isAuthenticated}, IsLoadingAuth=${isLoadingAuth}`);
|
|
6077
|
-
if (!isAuthenticated && !isLoadingAuth && location.pathname !== "/login") {
|
|
6322
|
+
if (!isAuthenticated && !isLoadingAuth && location.pathname !== "/login" && !huboCierreVoluntario()) {
|
|
6078
6323
|
const path = location.pathname + location.search + location.hash;
|
|
6079
6324
|
console.log(`[PrivateRoute] ACTION: Dispatching setRedirectPath(${path})`);
|
|
6080
6325
|
dispatch(setRedirectPath(path));
|
|
@@ -6092,7 +6337,7 @@ var PrivateRoute = ({ children }) => {
|
|
|
6092
6337
|
}
|
|
6093
6338
|
if (!isAuthenticated) {
|
|
6094
6339
|
console.log(`[PrivateRoute] User not authenticated, navigating to /login`);
|
|
6095
|
-
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
6340
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_router_dom9.Navigate, { to: "/login", replace: true });
|
|
6096
6341
|
}
|
|
6097
6342
|
console.log(`[PrivateRoute] User authenticated, rendering children.`);
|
|
6098
6343
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_jsx_runtime33.Fragment, { children });
|
|
@@ -6101,13 +6346,15 @@ var PrivateRoute_default = PrivateRoute;
|
|
|
6101
6346
|
|
|
6102
6347
|
// src/components/InitialRedirectHandler.tsx
|
|
6103
6348
|
var import_react35 = require("react");
|
|
6104
|
-
var
|
|
6349
|
+
var import_react_router_dom10 = require("react-router-dom");
|
|
6105
6350
|
var InitialRedirectHandler = () => {
|
|
6106
|
-
const location = (0,
|
|
6107
|
-
const navigate = (0,
|
|
6351
|
+
const location = (0, import_react_router_dom10.useLocation)();
|
|
6352
|
+
const navigate = (0, import_react_router_dom10.useNavigate)();
|
|
6108
6353
|
const dispatch = useAppDispatch();
|
|
6109
6354
|
const redirectPath = useRedirectPath();
|
|
6110
6355
|
const clientContextStatus = useClientContextStatus();
|
|
6356
|
+
const username = useAppSelector((state) => state.clientContext.username);
|
|
6357
|
+
const redirectUsername = useAppSelector((state) => state.router.redirectUsername);
|
|
6111
6358
|
(0, import_react35.useEffect)(() => {
|
|
6112
6359
|
dispatch(setCurrentPath(location.pathname + location.search));
|
|
6113
6360
|
}, [location, dispatch]);
|
|
@@ -6117,7 +6364,9 @@ var InitialRedirectHandler = () => {
|
|
|
6117
6364
|
}, [location.pathname]);
|
|
6118
6365
|
(0, import_react35.useEffect)(() => {
|
|
6119
6366
|
if (clientContextStatus === "succeeded") {
|
|
6120
|
-
if (redirectPath && redirectPath !== "/login") {
|
|
6367
|
+
if (redirectPath && redirectPath !== "/login" && redirectUsername && redirectUsername !== username) {
|
|
6368
|
+
dispatch(setRedirectPath(null));
|
|
6369
|
+
} else if (redirectPath && redirectPath !== "/login") {
|
|
6121
6370
|
console.log("Redirigiendo a la ruta guardada:", redirectPath);
|
|
6122
6371
|
navegandoRef.current = true;
|
|
6123
6372
|
navigate(redirectPath);
|
|
@@ -6127,14 +6376,14 @@ var InitialRedirectHandler = () => {
|
|
|
6127
6376
|
navigate("/");
|
|
6128
6377
|
}
|
|
6129
6378
|
}
|
|
6130
|
-
}, [clientContextStatus, redirectPath, location.pathname, navigate, dispatch]);
|
|
6379
|
+
}, [clientContextStatus, redirectPath, redirectUsername, username, location.pathname, navigate, dispatch]);
|
|
6131
6380
|
return null;
|
|
6132
6381
|
};
|
|
6133
6382
|
var InitialRedirectHandler_default = InitialRedirectHandler;
|
|
6134
6383
|
|
|
6135
6384
|
// src/pages/GenericDataGridPage.tsx
|
|
6136
6385
|
var import_react36 = __toESM(require("react"), 1);
|
|
6137
|
-
var
|
|
6386
|
+
var import_react_router_dom11 = require("react-router-dom");
|
|
6138
6387
|
var import_material27 = require("@mui/material");
|
|
6139
6388
|
var import_Close2 = __toESM(require("@mui/icons-material/Close"), 1);
|
|
6140
6389
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
@@ -6143,12 +6392,12 @@ var GenericDataGridPage = ({
|
|
|
6143
6392
|
initialFixedFields = [],
|
|
6144
6393
|
parametros: parametrosRecibidos
|
|
6145
6394
|
}) => {
|
|
6146
|
-
const { tableName: urlTableName } = (0,
|
|
6395
|
+
const { tableName: urlTableName } = (0, import_react_router_dom11.useParams)();
|
|
6147
6396
|
const effectiveTableName = initialTableName || urlTableName;
|
|
6148
6397
|
const [tabs, setTabs] = (0, import_react36.useState)([]);
|
|
6149
6398
|
const [activeTabIdx, setActiveTabIdx] = (0, import_react36.useState)(0);
|
|
6150
6399
|
const ffKey = JSON.stringify(initialFixedFields);
|
|
6151
|
-
const location = (0,
|
|
6400
|
+
const location = (0, import_react_router_dom11.useLocation)();
|
|
6152
6401
|
const parametros = (0, import_react36.useMemo)(() => parametrosRecibidos ?? parametrosDeTabla(void 0, location.search), [parametrosRecibidos, location.search]);
|
|
6153
6402
|
const fixedFieldsIniciales = initialFixedFields.length > 0 ? initialFixedFields : parametros.fixedFields ?? [];
|
|
6154
6403
|
const parametrosKey = JSON.stringify(parametros);
|
|
@@ -6229,11 +6478,11 @@ var GenericDataGridPage_default = GenericDataGridPage;
|
|
|
6229
6478
|
|
|
6230
6479
|
// src/pages/PantallaDeRuta.tsx
|
|
6231
6480
|
var import_react37 = require("react");
|
|
6232
|
-
var
|
|
6481
|
+
var import_react_router_dom12 = require("react-router-dom");
|
|
6233
6482
|
var import_material28 = require("@mui/material");
|
|
6234
6483
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
6235
6484
|
var PantallaDeRuta = ({ screenName }) => {
|
|
6236
|
-
const [busqueda] = (0,
|
|
6485
|
+
const [busqueda] = (0, import_react_router_dom12.useSearchParams)();
|
|
6237
6486
|
const params = (0, import_react37.useMemo)(() => Object.fromEntries(busqueda.entries()), [busqueda]);
|
|
6238
6487
|
const Pantalla = wScreens[screenName];
|
|
6239
6488
|
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 +6490,13 @@ var PantallaDeRuta = ({ screenName }) => {
|
|
|
6241
6490
|
|
|
6242
6491
|
// src/pages/MenuTablePage.tsx
|
|
6243
6492
|
var import_react38 = require("react");
|
|
6244
|
-
var
|
|
6493
|
+
var import_react_router_dom13 = require("react-router-dom");
|
|
6245
6494
|
var import_material29 = require("@mui/material");
|
|
6246
6495
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
6247
6496
|
var MenuTablePage = () => {
|
|
6248
|
-
const { "*": menuName } = (0,
|
|
6497
|
+
const { "*": menuName } = (0, import_react_router_dom13.useParams)();
|
|
6249
6498
|
const { clientContext } = useApp();
|
|
6250
|
-
const { search } = (0,
|
|
6499
|
+
const { search } = (0, import_react_router_dom13.useLocation)();
|
|
6251
6500
|
const { currentTableName, currentFixedFields, parametros } = (0, import_react38.useMemo)(() => {
|
|
6252
6501
|
let tableName = void 0;
|
|
6253
6502
|
let fixedFields = [];
|
|
@@ -6287,7 +6536,7 @@ var MenuTablePage_default = MenuTablePage;
|
|
|
6287
6536
|
|
|
6288
6537
|
// src/puente/PantallaBP.tsx
|
|
6289
6538
|
var import_react40 = require("react");
|
|
6290
|
-
var
|
|
6539
|
+
var import_react_router_dom14 = require("react-router-dom");
|
|
6291
6540
|
var import_material31 = require("@mui/material");
|
|
6292
6541
|
|
|
6293
6542
|
// src/puente/clienteBP.ts
|
|
@@ -6490,13 +6739,6 @@ function resolverPantallaBP(myOwn, nombre, contenedor) {
|
|
|
6490
6739
|
return null;
|
|
6491
6740
|
}
|
|
6492
6741
|
|
|
6493
|
-
// src/puente/habilitacion.ts
|
|
6494
|
-
var habilitado = false;
|
|
6495
|
-
var habilitarPuenteBP = () => {
|
|
6496
|
-
habilitado = true;
|
|
6497
|
-
};
|
|
6498
|
-
var puenteBPHabilitado = () => habilitado;
|
|
6499
|
-
|
|
6500
6742
|
// src/puente/PantallaBP.tsx
|
|
6501
6743
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
6502
6744
|
function buscarItemDeMenu(items, tipo) {
|
|
@@ -6559,18 +6801,18 @@ var PantallaBP = ({ nombre, direccion }) => {
|
|
|
6559
6801
|
);
|
|
6560
6802
|
};
|
|
6561
6803
|
var PantallaDeRespaldo = () => {
|
|
6562
|
-
const { screenName = "" } = (0,
|
|
6563
|
-
const { search } = (0,
|
|
6804
|
+
const { screenName = "" } = (0, import_react_router_dom14.useParams)();
|
|
6805
|
+
const { search } = (0, import_react_router_dom14.useLocation)();
|
|
6564
6806
|
if (!puenteBPHabilitado()) {
|
|
6565
6807
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material31.Box, { sx: { p: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FallbackWScreen, { screenName }) });
|
|
6566
6808
|
}
|
|
6567
|
-
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
6809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom14.Navigate, { to: rutaDePantallaBP(screenName, search), replace: true });
|
|
6568
6810
|
};
|
|
6569
6811
|
var PaginaBP = () => {
|
|
6570
|
-
const { hash, search } = (0,
|
|
6812
|
+
const { hash, search } = (0, import_react_router_dom14.useLocation)();
|
|
6571
6813
|
const direccion = hash || search;
|
|
6572
6814
|
const nombre = new URLSearchParams(direccion.replace(/^[#?]/, "")).get("w");
|
|
6573
|
-
if (!puenteBPHabilitado()) return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
6815
|
+
if (!puenteBPHabilitado()) return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_router_dom14.Navigate, { to: "/", replace: true });
|
|
6574
6816
|
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
6817
|
"Falta la pantalla de backend-plus (",
|
|
6576
6818
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("code", { children: "#w=..." }),
|
|
@@ -6581,7 +6823,7 @@ var PaginaBP = () => {
|
|
|
6581
6823
|
|
|
6582
6824
|
// src/puente/GrillaBP.tsx
|
|
6583
6825
|
var import_react41 = require("react");
|
|
6584
|
-
var
|
|
6826
|
+
var import_react_router_dom15 = require("react-router-dom");
|
|
6585
6827
|
var import_material32 = require("@mui/material");
|
|
6586
6828
|
var import_jsx_runtime39 = (
|
|
6587
6829
|
// 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 +6863,13 @@ var GrillaBP = ({ tabla, fixedFields }) => {
|
|
|
6621
6863
|
] });
|
|
6622
6864
|
};
|
|
6623
6865
|
var PaginaGrillaBP = () => {
|
|
6624
|
-
const { tableName = "" } = (0,
|
|
6866
|
+
const { tableName = "" } = (0, import_react_router_dom15.useParams)();
|
|
6625
6867
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(GrillaBP, { tabla: tableName }, tableName);
|
|
6626
6868
|
};
|
|
6627
6869
|
|
|
6628
6870
|
// src/puente/CapturaBP.tsx
|
|
6629
6871
|
var import_react42 = require("react");
|
|
6630
|
-
var
|
|
6872
|
+
var import_react_router_dom16 = require("react-router-dom");
|
|
6631
6873
|
|
|
6632
6874
|
// src/puente/capturaDeNavegacion.ts
|
|
6633
6875
|
function apiDeNavegacion() {
|
|
@@ -6672,62 +6914,175 @@ function capturarNavegacionBP(urlBackend, navegar) {
|
|
|
6672
6914
|
|
|
6673
6915
|
// src/puente/CapturaBP.tsx
|
|
6674
6916
|
var CapturaBP = () => {
|
|
6675
|
-
const navigate = (0,
|
|
6917
|
+
const navigate = (0, import_react_router_dom16.useNavigate)();
|
|
6676
6918
|
(0, import_react42.useEffect)(() => capturarNavegacionBP(envConfig.backendUrl, navigate), [navigate]);
|
|
6677
6919
|
return null;
|
|
6678
6920
|
};
|
|
6679
6921
|
|
|
6922
|
+
// src/pages/CambiarClavePage.tsx
|
|
6923
|
+
var import_react43 = require("react");
|
|
6924
|
+
var import_material33 = require("@mui/material");
|
|
6925
|
+
var import_react_router_dom17 = require("react-router-dom");
|
|
6926
|
+
var import_react_redux5 = require("react-redux");
|
|
6927
|
+
|
|
6928
|
+
// src/utils/cambiarClave.ts
|
|
6929
|
+
var MENSAJE_POR_OMISION = "No se pudo cambiar la contrase\xF1a";
|
|
6930
|
+
function resultadoDeCambioDeClave(urlFinal, html) {
|
|
6931
|
+
if (/\/login\/?(\?.*)?$/.test(urlFinal)) return { ok: true };
|
|
6932
|
+
const mensajes = Array.from(new DOMParser().parseFromString(html, "text/html").querySelectorAll(".error-message")).map((elemento) => (elemento.textContent ?? "").trim()).filter((mensaje) => mensaje !== "");
|
|
6933
|
+
return { ok: false, mensaje: mensajes.join("\n") || MENSAJE_POR_OMISION };
|
|
6934
|
+
}
|
|
6935
|
+
|
|
6936
|
+
// src/pages/CambiarClavePage.tsx
|
|
6937
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
6938
|
+
var CambiarClavePage = () => {
|
|
6939
|
+
const { clientContext, setIsLoggedIn, avisarCierreVoluntario } = useApp();
|
|
6940
|
+
const dispatch = (0, import_react_redux5.useDispatch)();
|
|
6941
|
+
const navigate = (0, import_react_router_dom17.useNavigate)();
|
|
6942
|
+
const [claveActual, setClaveActual] = (0, import_react43.useState)("");
|
|
6943
|
+
const [claveNueva, setClaveNueva] = (0, import_react43.useState)("");
|
|
6944
|
+
const [claveRepetida, setClaveRepetida] = (0, import_react43.useState)("");
|
|
6945
|
+
const [error, setError] = (0, import_react43.useState)(null);
|
|
6946
|
+
const [enviando, setEnviando] = (0, import_react43.useState)(false);
|
|
6947
|
+
const enviar = async (evento) => {
|
|
6948
|
+
evento.preventDefault();
|
|
6949
|
+
setError(null);
|
|
6950
|
+
if (claveNueva !== claveRepetida) {
|
|
6951
|
+
setError("La clave nueva y su repetici\xF3n no coinciden");
|
|
6952
|
+
return;
|
|
6953
|
+
}
|
|
6954
|
+
setEnviando(true);
|
|
6955
|
+
avisarCierreVoluntario(true);
|
|
6956
|
+
try {
|
|
6957
|
+
const respuesta = await fetchApi("/chpass", {
|
|
6958
|
+
method: "POST",
|
|
6959
|
+
body: new URLSearchParams({ oldPassword: claveActual, newPassword: claveNueva, repPassword: claveRepetida })
|
|
6960
|
+
});
|
|
6961
|
+
const resultado = resultadoDeCambioDeClave(respuesta.url, await respuesta.text());
|
|
6962
|
+
if (!resultado.ok) {
|
|
6963
|
+
avisarCierreVoluntario(false);
|
|
6964
|
+
setError(resultado.mensaje);
|
|
6965
|
+
return;
|
|
6966
|
+
}
|
|
6967
|
+
setIsLoggedIn(false);
|
|
6968
|
+
dispatch(clearClientContext());
|
|
6969
|
+
dispatch(setRedirectPath(null));
|
|
6970
|
+
navigate("/login", { replace: true, state: { claveCambiada: true } });
|
|
6971
|
+
} catch (err) {
|
|
6972
|
+
avisarCierreVoluntario(false);
|
|
6973
|
+
setError(mensajeDeError(err, "No se pudo cambiar la contrase\xF1a"));
|
|
6974
|
+
} finally {
|
|
6975
|
+
setEnviando(false);
|
|
6976
|
+
}
|
|
6977
|
+
};
|
|
6978
|
+
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: [
|
|
6979
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.Typography, { variant: "h5", gutterBottom: true, children: "Cambiar contrase\xF1a" }),
|
|
6980
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.TextField, { label: "Usuario", value: clientContext?.username ?? "", fullWidth: true, margin: "normal", disabled: true, autoComplete: "username" }),
|
|
6981
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
6982
|
+
import_material33.TextField,
|
|
6983
|
+
{
|
|
6984
|
+
label: "Contrase\xF1a actual",
|
|
6985
|
+
type: "password",
|
|
6986
|
+
value: claveActual,
|
|
6987
|
+
onChange: (e) => setClaveActual(e.target.value),
|
|
6988
|
+
fullWidth: true,
|
|
6989
|
+
margin: "normal",
|
|
6990
|
+
autoFocus: true,
|
|
6991
|
+
required: true,
|
|
6992
|
+
autoComplete: "current-password",
|
|
6993
|
+
disabled: enviando
|
|
6994
|
+
}
|
|
6995
|
+
),
|
|
6996
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
6997
|
+
import_material33.TextField,
|
|
6998
|
+
{
|
|
6999
|
+
label: "Contrase\xF1a nueva",
|
|
7000
|
+
type: "password",
|
|
7001
|
+
value: claveNueva,
|
|
7002
|
+
onChange: (e) => setClaveNueva(e.target.value),
|
|
7003
|
+
fullWidth: true,
|
|
7004
|
+
margin: "normal",
|
|
7005
|
+
required: true,
|
|
7006
|
+
autoComplete: "new-password",
|
|
7007
|
+
disabled: enviando
|
|
7008
|
+
}
|
|
7009
|
+
),
|
|
7010
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
7011
|
+
import_material33.TextField,
|
|
7012
|
+
{
|
|
7013
|
+
label: "Repetir contrase\xF1a nueva",
|
|
7014
|
+
type: "password",
|
|
7015
|
+
value: claveRepetida,
|
|
7016
|
+
onChange: (e) => setClaveRepetida(e.target.value),
|
|
7017
|
+
fullWidth: true,
|
|
7018
|
+
margin: "normal",
|
|
7019
|
+
required: true,
|
|
7020
|
+
autoComplete: "new-password",
|
|
7021
|
+
disabled: enviando
|
|
7022
|
+
}
|
|
7023
|
+
),
|
|
7024
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.Alert, { severity: "error", sx: { mt: 1, whiteSpace: "pre-line" }, children: error }),
|
|
7025
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_material33.Box, { sx: { display: "flex", gap: 1, justifyContent: "flex-end", mt: 2 }, children: [
|
|
7026
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_material33.Button, { onClick: () => navigate(-1), disabled: enviando, children: "Cancelar" }),
|
|
7027
|
+
/* @__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" })
|
|
7028
|
+
] }),
|
|
7029
|
+
/* @__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." })
|
|
7030
|
+
] }) });
|
|
7031
|
+
};
|
|
7032
|
+
var CambiarClavePage_default = CambiarClavePage;
|
|
7033
|
+
|
|
6680
7034
|
// src/App.tsx
|
|
6681
7035
|
var import_type_store6 = __toESM(require("type-store"), 1);
|
|
6682
|
-
var
|
|
7036
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
6683
7037
|
var LocationTracker = () => {
|
|
6684
|
-
const location = (0,
|
|
7038
|
+
const location = (0, import_react_router_dom18.useLocation)();
|
|
6685
7039
|
const dispatch = useAppDispatch();
|
|
6686
|
-
(0,
|
|
7040
|
+
(0, import_react44.useEffect)(() => {
|
|
6687
7041
|
dispatch(setCurrentPath(location.pathname + location.search));
|
|
6688
7042
|
}, [location, dispatch]);
|
|
6689
7043
|
return null;
|
|
6690
7044
|
};
|
|
6691
7045
|
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,
|
|
7046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
|
|
7047
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(InitialRedirectHandler_default, {}),
|
|
7048
|
+
puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(CapturaBP, {}),
|
|
7049
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_router_dom18.Routes, { children: [
|
|
7050
|
+
/* @__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: [
|
|
7051
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/login", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LoginPage_default, {}) }),
|
|
7052
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/logout", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LogoutPage_default, {}) }),
|
|
6699
7053
|
myUnloggedRoutes
|
|
6700
7054
|
] }),
|
|
6701
|
-
/* @__PURE__ */ (0,
|
|
6702
|
-
/* @__PURE__ */ (0,
|
|
6703
|
-
/* @__PURE__ */ (0,
|
|
6704
|
-
/* @__PURE__ */ (0,
|
|
6705
|
-
/* @__PURE__ */ (0,
|
|
6706
|
-
|
|
6707
|
-
|
|
7055
|
+
/* @__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: [
|
|
7056
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PantallaInicial_default, {}) }),
|
|
7057
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/table/:tableName", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(GenericDataGridPage_default, {}) }),
|
|
7058
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/menu/*", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(MenuTablePage_default, {}) }),
|
|
7059
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/procedures/:procedureName", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ProcedureForm_default, {}) }),
|
|
7060
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/chpass", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(CambiarClavePage_default, {}) }),
|
|
7061
|
+
Object.keys(wScreens).map((screenName) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7062
|
+
import_react_router_dom18.Route,
|
|
6708
7063
|
{
|
|
6709
7064
|
path: `/wScreens/${screenName}`,
|
|
6710
|
-
element: /* @__PURE__ */ (0,
|
|
7065
|
+
element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PantallaDeRuta, { screenName })
|
|
6711
7066
|
},
|
|
6712
7067
|
screenName
|
|
6713
7068
|
)),
|
|
6714
|
-
/* @__PURE__ */ (0,
|
|
6715
|
-
puenteBPHabilitado() && /* @__PURE__ */ (0,
|
|
6716
|
-
puenteBPHabilitado() && /* @__PURE__ */ (0,
|
|
7069
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/wScreens-fallback/:screenName", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PantallaDeRespaldo, {}) }),
|
|
7070
|
+
puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_router_dom18.Route, { path: "/bp/menu", element: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PaginaBP, {}) }),
|
|
7071
|
+
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
7072
|
myRoutes,
|
|
6718
|
-
/* @__PURE__ */ (0,
|
|
7073
|
+
/* @__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
7074
|
] }),
|
|
6720
|
-
/* @__PURE__ */ (0,
|
|
7075
|
+
/* @__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
7076
|
] })
|
|
6722
7077
|
] });
|
|
6723
7078
|
}
|
|
6724
7079
|
var FrontendPlusProviders = ({ children, publicPaths }) => {
|
|
6725
|
-
return /* @__PURE__ */ (0,
|
|
6726
|
-
/* @__PURE__ */ (0,
|
|
7080
|
+
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: [
|
|
7081
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LocationTracker, {}),
|
|
6727
7082
|
" ",
|
|
6728
|
-
/* @__PURE__ */ (0,
|
|
7083
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(AppProvider, { publicPaths, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(SnackbarProvider, { children: [
|
|
6729
7084
|
children,
|
|
6730
|
-
/* @__PURE__ */ (0,
|
|
7085
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SessionExpiredMessage_default, {})
|
|
6731
7086
|
] }) })
|
|
6732
7087
|
] }) }) });
|
|
6733
7088
|
};
|
|
@@ -6739,9 +7094,10 @@ var App = ({
|
|
|
6739
7094
|
myClientSides,
|
|
6740
7095
|
myResultsOk,
|
|
6741
7096
|
myConditions,
|
|
6742
|
-
puenteBP
|
|
7097
|
+
puenteBP,
|
|
7098
|
+
recuperarClave
|
|
6743
7099
|
}) => {
|
|
6744
|
-
(0,
|
|
7100
|
+
(0, import_react44.useMemo)(() => {
|
|
6745
7101
|
if (myClientSides) {
|
|
6746
7102
|
extendClientSides(myClientSides);
|
|
6747
7103
|
}
|
|
@@ -6757,8 +7113,9 @@ var App = ({
|
|
|
6757
7113
|
if (puenteBP) {
|
|
6758
7114
|
habilitarPuenteBP();
|
|
6759
7115
|
}
|
|
6760
|
-
|
|
6761
|
-
|
|
7116
|
+
configurarRecuperarClave(recuperarClave);
|
|
7117
|
+
}, [myClientSides, myResultsOk, myWScreens, myConditions, puenteBP, recuperarClave]);
|
|
7118
|
+
(0, import_react44.useEffect)(() => {
|
|
6762
7119
|
import_type_store6.default.messages = import_type_store6.default.i18n.messages.es;
|
|
6763
7120
|
import_type_store6.default.locale = import_type_store6.default.i18n.locale.es;
|
|
6764
7121
|
const link = document.querySelector("link[rel*='icon']") || document.createElement("link");
|
|
@@ -6767,11 +7124,11 @@ var App = ({
|
|
|
6767
7124
|
link.href = `${envConfig.backendUrl}/img/logo-128.png`;
|
|
6768
7125
|
document.getElementsByTagName("head")[0].appendChild(link);
|
|
6769
7126
|
}, []);
|
|
6770
|
-
const safePaths =
|
|
7127
|
+
const safePaths = import_react44.default.useMemo(() => {
|
|
6771
7128
|
const extracted = extractPathsFromRoutes(myUnloggedRoutes);
|
|
6772
7129
|
return ["/login", "/logout", ...extracted];
|
|
6773
7130
|
}, [myUnloggedRoutes]);
|
|
6774
|
-
return /* @__PURE__ */ (0,
|
|
7131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
6775
7132
|
FrontendPlusReactRoutes,
|
|
6776
7133
|
{
|
|
6777
7134
|
myRoutes,
|