frontend-plus-react 0.4.1 → 0.4.2
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 +2 -1
- package/dist/index.cjs +103 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +80 -58
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -94,8 +94,9 @@ Para no perder lo que la grilla de `backend-plus` ya hace y que acá todavía no
|
|
|
94
94
|
- Tres cosas que el cliente de `backend-plus` necesita y que el puente hace: un `<base href>` en la base-url (arma sus direcciones relativas a la página), el global `my` igual a `myOwn`, y llamar a `myOwn.autoSetup()` a mano (él lo hace al evento `load`, que ya pasó).
|
|
95
95
|
- Una wScreen de `backend-plus` puede ser una función, un objeto con `mainFunction`, o un objeto con `parameters` y `mainAction` (como `abrir_encuesta` de dmencu: muestra el formulario de parámetros). `resolverPantallaBP` reproduce el `showPage` de my-menu.js para las tres.
|
|
96
96
|
- **Las pantallas de `backend-plus` viven en una sola ruta, `/bp/menu#w=<pantalla>&...`** (`PaginaBP`; `/wScreens-fallback/:nombre` redirige ahí). Se parece a `<base-url>/menu` **a propósito**: BP y las aplicaciones arman direcciones a partir de la ubicación (`location.origin + location.pathname + '/../menu#w=...'` en un `history.replaceState` + `location.reload()`, como el «Cerrar» de una encuesta de dmencu; `location.pathname + '#w=...'` para abrir en otra pestaña) y así caen en esta misma ruta, que lee los parámetros del hash (o de la query) como BP. Con otra ruta, esas direcciones salen de `/react`. En producción, el servidor tiene que devolver el `index.html` también para `/react/bp/menu`.
|
|
97
|
-
- **Lo que BP manda a páginas del backend se resuelve adentro** (`capturaDeNavegacion.ts`,
|
|
97
|
+
- **Lo que BP manda a páginas del backend se resuelve adentro** (`capturaDeNavegacion.ts`, montado una sola vez por `CapturaBP` mientras el puente está encendido, **no** solo mientras hay una pantalla de BP: su cliente sigue vivo después de salir de ella y sus avisos quedan en el `body`; por ejemplo el de «Iniciar sesión» de `my-inform-net-status.js`, un `<a href="login">` que sin la captura llevaba a `<base-url>/login` y, con la sesión abierta, a `<base-url>/menu`, el BP nativo): clics en `<a>` (a nivel documento, también en diálogos) y, donde existe la Navigation API, cualquier `location.href = ...`. `rutaDeEnlaceBP` traduce `<base-url>/menu#w=...` a `/bp/menu#w=...`, y `login`/`logout` a los de la aplicación. El clic se corta con `stopPropagation`: el botón «proceder» de BP tiene además un `onclick` propio (`history.pushState` a `<base-url>/menu#...` y `showPage`) que dejaría la URL fuera de la aplicación y daría un error de BP. También se traduce `history.replaceState`: al editar un parámetro de una pantalla (`myOwn.replaceAddrParams`) BP reescribe la dirección a `menu#...` y, con el `<base>`, la aplicación quedaba en `<base-url>/menu` (un F5 y se salía de `/react`); `replaceState` no pasa por la Navigation API. Los enlaces `menu#i=...` (ítems del menú de BP, sin `w`) no se traducen. Los parámetros se leen con `myOwn.UriSearchToObject`, no con `URLSearchParams`: `up`, `ff` y `detailing` tienen su propio formato y llegan como objetos.
|
|
98
98
|
- **Los scripts de `backend-plus` se inyectan recién cuando la ventana terminó de cargar** (`esperarCargaDeVentana`): su `load` ejecuta `showPage`, que acá falla (no hay `#total-layout`). Y su manejador de errores (`myOwn.log`) deja el mensaje como primer hijo del `body` cuando no hay un `#mini-console`, lo que **corre toda la aplicación hacia abajo** durante 30 s. Era el «espacio entre el menú y el contenido» que aparecía con F5 y a veces no.
|
|
99
|
+
- **La aplicación no está atada a la ruta `/react`.** `my-menu.js` escucha `popstate` y, si la dirección no termina en `/react`, ejecuta `showPage()` (falla igual que el `load`); lo marca como `//TODO: desacoplar de BP`. El puente lo evita sin tocar `backend-plus`: mientras inyecta los scripts, `sinEscuchasDeVentana(['popstate'], ...)` ignora que registren ese evento (la navegación es del router). Si backend-plus agrega otro enganche así, se ve como un error en `ConsolaBP`. Sin el puente (`puenteBP` apagado) no se carga nada de `backend-plus` y la base-url de la aplicación es la que quiera. **Sin probar en navegador** (se probó el filtro en Vitest; falta atrás/adelante contra un backend real).
|
|
99
100
|
- **`ConsolaBP`** ofrece ese `#mini-console` (dentro de `PantallaBP` y `GrillaBP`): los mensajes y errores de `backend-plus` se ven como avisos flotantes arriba a la derecha, debajo de la AppBar, sin ocupar lugar. BP registra algunos errores **dos veces** (el de una llamada ajax lo registra `my-ajax.js` y el `catch` de «proceder», en `my-menu.js`, lo repite; pasa también en BP nativo): si llega un aviso igual a uno que llegó hace menos de 1 s, se descarta (`descartarRepetidos`). Sin contador: el error se ve una vez. Las hojas de estilo del backend y de las aplicaciones también estilizan `#mini-console` (por id, con `top`, `width: 100%`, `max-height`...): por eso `ConsolaBP` usa `&#mini-console` y repone esos valores.
|
|
100
101
|
- Las wScreens de `backend-plus` dibujan en `#main_layout`: `PantallaBP` le da ese contenedor y le pasa lo que declara su ítem de menú más la query string. Mientras está montada no puede haber otro elemento con ese id.
|
|
101
102
|
- `rutaBase` (`src/rutaBase.ts`) toma el `base` del bundler: es el `basename` del router y el prefijo de las pestañas nuevas (Ctrl+click en un detalle `wScreen`).
|
package/dist/index.cjs
CHANGED
|
@@ -4190,7 +4190,7 @@ var GenericDataGrid = ({
|
|
|
4190
4190
|
var GenericDataGrid_default = GenericDataGrid;
|
|
4191
4191
|
|
|
4192
4192
|
// src/App.tsx
|
|
4193
|
-
var
|
|
4193
|
+
var import_react39 = __toESM(require("react"), 1);
|
|
4194
4194
|
var import_react_router_dom15 = require("react-router-dom");
|
|
4195
4195
|
|
|
4196
4196
|
// src/components/MainLayout.tsx
|
|
@@ -4759,7 +4759,6 @@ var import_material20 = require("@mui/material");
|
|
|
4759
4759
|
var import_react_hook_form = require("react-hook-form");
|
|
4760
4760
|
var import_zod = require("@hookform/resolvers/zod");
|
|
4761
4761
|
var z = __toESM(require("zod"), 1);
|
|
4762
|
-
var import_react_router_dom6 = require("react-router-dom");
|
|
4763
4762
|
var import_react_redux4 = require("react-redux");
|
|
4764
4763
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4765
4764
|
var loginSchema = z.object({
|
|
@@ -4769,7 +4768,6 @@ var loginSchema = z.object({
|
|
|
4769
4768
|
// Añadir validación básica
|
|
4770
4769
|
});
|
|
4771
4770
|
var LoginPage = () => {
|
|
4772
|
-
const navigate = (0, import_react_router_dom6.useNavigate)();
|
|
4773
4771
|
const [loginError, setLoginError] = (0, import_react28.useState)(null);
|
|
4774
4772
|
const [isSubmitting, setIsSubmitting] = (0, import_react28.useState)(false);
|
|
4775
4773
|
const { setIsLoggedIn, checkSession } = useApp();
|
|
@@ -4807,7 +4805,6 @@ var LoginPage = () => {
|
|
|
4807
4805
|
setIsLoggedIn(true);
|
|
4808
4806
|
await dispatch(fetchClientContext()).unwrap();
|
|
4809
4807
|
console.log("Login exitoso y clientContext cargado.");
|
|
4810
|
-
navigate("/");
|
|
4811
4808
|
reset();
|
|
4812
4809
|
} catch (error) {
|
|
4813
4810
|
console.error("Error al iniciar sesi\xF3n:", error);
|
|
@@ -4911,7 +4908,7 @@ var LoginPage_default = LoginPage;
|
|
|
4911
4908
|
|
|
4912
4909
|
// src/components/ProcedureForm.tsx
|
|
4913
4910
|
var import_react29 = __toESM(require("react"), 1);
|
|
4914
|
-
var
|
|
4911
|
+
var import_react_router_dom6 = require("react-router-dom");
|
|
4915
4912
|
var import_material22 = require("@mui/material");
|
|
4916
4913
|
|
|
4917
4914
|
// src/pages/procedure-results/SuccessDisplay.tsx
|
|
@@ -4938,7 +4935,7 @@ var extendResultsOk = (newComponents) => {
|
|
|
4938
4935
|
// src/components/ProcedureForm.tsx
|
|
4939
4936
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
4940
4937
|
var ProcedureForm = () => {
|
|
4941
|
-
const { procedureName } = (0,
|
|
4938
|
+
const { procedureName } = (0, import_react_router_dom6.useParams)();
|
|
4942
4939
|
const { clientContext } = useApp();
|
|
4943
4940
|
const { callApi, loading: apiLoading, error: apiError } = useApiCall();
|
|
4944
4941
|
const [validationErrors, setValidationErrors] = (0, import_react29.useState)({});
|
|
@@ -5357,14 +5354,14 @@ var ProcedureForm_default = ProcedureForm;
|
|
|
5357
5354
|
|
|
5358
5355
|
// src/App.tsx
|
|
5359
5356
|
var import_react_redux5 = require("react-redux");
|
|
5360
|
-
var
|
|
5357
|
+
var import_react40 = require("redux-persist/integration/react");
|
|
5361
5358
|
|
|
5362
5359
|
// src/components/PrivateRoute.tsx
|
|
5363
5360
|
var import_react30 = require("react");
|
|
5364
|
-
var
|
|
5361
|
+
var import_react_router_dom7 = require("react-router-dom");
|
|
5365
5362
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
5366
5363
|
var PrivateRoute = ({ children }) => {
|
|
5367
|
-
const location = (0,
|
|
5364
|
+
const location = (0, import_react_router_dom7.useLocation)();
|
|
5368
5365
|
const dispatch = useAppDispatch();
|
|
5369
5366
|
const clientContextStatus = useClientContextStatus();
|
|
5370
5367
|
const isAuthenticated = clientContextStatus === "succeeded";
|
|
@@ -5390,7 +5387,7 @@ var PrivateRoute = ({ children }) => {
|
|
|
5390
5387
|
}
|
|
5391
5388
|
if (!isAuthenticated) {
|
|
5392
5389
|
console.log(`[PrivateRoute] User not authenticated, navigating to /login`);
|
|
5393
|
-
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5390
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_router_dom7.Navigate, { to: "/login", replace: true });
|
|
5394
5391
|
}
|
|
5395
5392
|
console.log(`[PrivateRoute] User authenticated, rendering children.`);
|
|
5396
5393
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_jsx_runtime28.Fragment, { children });
|
|
@@ -5399,10 +5396,10 @@ var PrivateRoute_default = PrivateRoute;
|
|
|
5399
5396
|
|
|
5400
5397
|
// src/components/InitialRedirectHandler.tsx
|
|
5401
5398
|
var import_react31 = require("react");
|
|
5402
|
-
var
|
|
5399
|
+
var import_react_router_dom8 = require("react-router-dom");
|
|
5403
5400
|
var InitialRedirectHandler = () => {
|
|
5404
|
-
const location = (0,
|
|
5405
|
-
const navigate = (0,
|
|
5401
|
+
const location = (0, import_react_router_dom8.useLocation)();
|
|
5402
|
+
const navigate = (0, import_react_router_dom8.useNavigate)();
|
|
5406
5403
|
const dispatch = useAppDispatch();
|
|
5407
5404
|
const redirectPath = useRedirectPath();
|
|
5408
5405
|
const clientContextStatus = useClientContextStatus();
|
|
@@ -5432,7 +5429,7 @@ var InitialRedirectHandler_default = InitialRedirectHandler;
|
|
|
5432
5429
|
|
|
5433
5430
|
// src/pages/GenericDataGridPage.tsx
|
|
5434
5431
|
var import_react32 = __toESM(require("react"), 1);
|
|
5435
|
-
var
|
|
5432
|
+
var import_react_router_dom9 = require("react-router-dom");
|
|
5436
5433
|
var import_material23 = require("@mui/material");
|
|
5437
5434
|
var import_Close2 = __toESM(require("@mui/icons-material/Close"), 1);
|
|
5438
5435
|
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
@@ -5440,12 +5437,12 @@ var GenericDataGridPage = ({
|
|
|
5440
5437
|
initialTableName,
|
|
5441
5438
|
initialFixedFields = []
|
|
5442
5439
|
}) => {
|
|
5443
|
-
const { tableName: urlTableName } = (0,
|
|
5440
|
+
const { tableName: urlTableName } = (0, import_react_router_dom9.useParams)();
|
|
5444
5441
|
const effectiveTableName = initialTableName || urlTableName;
|
|
5445
5442
|
const [tabs, setTabs] = (0, import_react32.useState)([]);
|
|
5446
5443
|
const [activeTabIdx, setActiveTabIdx] = (0, import_react32.useState)(0);
|
|
5447
5444
|
const ffKey = JSON.stringify(initialFixedFields);
|
|
5448
|
-
const location = (0,
|
|
5445
|
+
const location = (0, import_react_router_dom9.useLocation)();
|
|
5449
5446
|
import_react32.default.useEffect(() => {
|
|
5450
5447
|
if (effectiveTableName) {
|
|
5451
5448
|
setTabs([{
|
|
@@ -5518,11 +5515,11 @@ var GenericDataGridPage_default = GenericDataGridPage;
|
|
|
5518
5515
|
|
|
5519
5516
|
// src/pages/PantallaDeRuta.tsx
|
|
5520
5517
|
var import_react33 = require("react");
|
|
5521
|
-
var
|
|
5518
|
+
var import_react_router_dom10 = require("react-router-dom");
|
|
5522
5519
|
var import_material24 = require("@mui/material");
|
|
5523
5520
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
5524
5521
|
var PantallaDeRuta = ({ screenName }) => {
|
|
5525
|
-
const [busqueda] = (0,
|
|
5522
|
+
const [busqueda] = (0, import_react_router_dom10.useSearchParams)();
|
|
5526
5523
|
const params = (0, import_react33.useMemo)(() => Object.fromEntries(busqueda.entries()), [busqueda]);
|
|
5527
5524
|
const Pantalla = wScreens[screenName];
|
|
5528
5525
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Box, { sx: { pt: 3, pl: 4 }, children: Pantalla ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Pantalla, { screenName, params }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(FallbackWScreen, { screenName }) });
|
|
@@ -5530,7 +5527,7 @@ var PantallaDeRuta = ({ screenName }) => {
|
|
|
5530
5527
|
|
|
5531
5528
|
// src/pages/MenuTablePage.tsx
|
|
5532
5529
|
var import_react34 = require("react");
|
|
5533
|
-
var
|
|
5530
|
+
var import_react_router_dom11 = require("react-router-dom");
|
|
5534
5531
|
var import_material25 = require("@mui/material");
|
|
5535
5532
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
5536
5533
|
function fixedFieldsDeMenu(ff) {
|
|
@@ -5541,7 +5538,7 @@ function fixedFieldsDeMenu(ff) {
|
|
|
5541
5538
|
return Object.entries(ff).map(([fieldName, value]) => ({ fieldName, value }));
|
|
5542
5539
|
}
|
|
5543
5540
|
var MenuTablePage = () => {
|
|
5544
|
-
const { menuName } = (0,
|
|
5541
|
+
const { menuName } = (0, import_react_router_dom11.useParams)();
|
|
5545
5542
|
const { clientContext } = useApp();
|
|
5546
5543
|
const findMenuItem = (items, nameToFind) => {
|
|
5547
5544
|
for (const item of items) {
|
|
@@ -5590,7 +5587,7 @@ var MenuTablePage_default = MenuTablePage;
|
|
|
5590
5587
|
|
|
5591
5588
|
// src/puente/PantallaBP.tsx
|
|
5592
5589
|
var import_react36 = require("react");
|
|
5593
|
-
var
|
|
5590
|
+
var import_react_router_dom12 = require("react-router-dom");
|
|
5594
5591
|
var import_material27 = require("@mui/material");
|
|
5595
5592
|
|
|
5596
5593
|
// src/puente/clienteBP.ts
|
|
@@ -5625,6 +5622,24 @@ function esperarCargaDeVentana() {
|
|
|
5625
5622
|
if (document.readyState === "complete") return Promise.resolve();
|
|
5626
5623
|
return new Promise((resolver) => window.addEventListener("load", () => resolver(), { once: true }));
|
|
5627
5624
|
}
|
|
5625
|
+
async function sinEscuchasDeVentana(tipos, inyectar) {
|
|
5626
|
+
const original = window.addEventListener;
|
|
5627
|
+
const filtrada = function(tipo, escucha, opciones) {
|
|
5628
|
+
if (tipos.includes(tipo)) return;
|
|
5629
|
+
original.call(this, tipo, escucha, opciones);
|
|
5630
|
+
};
|
|
5631
|
+
window.addEventListener = filtrada;
|
|
5632
|
+
try {
|
|
5633
|
+
return await inyectar();
|
|
5634
|
+
} finally {
|
|
5635
|
+
if (window.addEventListener === filtrada) window.addEventListener = original;
|
|
5636
|
+
}
|
|
5637
|
+
}
|
|
5638
|
+
async function cargarScripts(rutas) {
|
|
5639
|
+
for (const ruta of rutas) {
|
|
5640
|
+
await cargarScript(ruta);
|
|
5641
|
+
}
|
|
5642
|
+
}
|
|
5628
5643
|
var carga = null;
|
|
5629
5644
|
function cargarClienteBP(urlBackend) {
|
|
5630
5645
|
if (!carga) {
|
|
@@ -5653,9 +5668,7 @@ async function cargarSinMemoria(urlBackend) {
|
|
|
5653
5668
|
document.head.appendChild(enlace);
|
|
5654
5669
|
});
|
|
5655
5670
|
await esperarCargaDeVentana();
|
|
5656
|
-
|
|
5657
|
-
await cargarScript(ruta);
|
|
5658
|
-
}
|
|
5671
|
+
await sinEscuchasDeVentana(["popstate"], () => cargarScripts(recursos.scripts));
|
|
5659
5672
|
const myOwn = window.myOwn;
|
|
5660
5673
|
if (!myOwn) throw new Error("El backend no defini\xF3 myOwn.");
|
|
5661
5674
|
window.my = myOwn;
|
|
@@ -5777,47 +5790,6 @@ function resolverPantallaBP(myOwn, nombre, contenedor) {
|
|
|
5777
5790
|
return null;
|
|
5778
5791
|
}
|
|
5779
5792
|
|
|
5780
|
-
// src/puente/capturaDeNavegacion.ts
|
|
5781
|
-
function apiDeNavegacion() {
|
|
5782
|
-
const api = Reflect.get(window, "navigation");
|
|
5783
|
-
return typeof api === "object" && api !== null && "addEventListener" in api && typeof api.addEventListener === "function" ? api : null;
|
|
5784
|
-
}
|
|
5785
|
-
function capturarNavegacionBP(urlBackend, navegar) {
|
|
5786
|
-
const alHacerClick = (evento) => {
|
|
5787
|
-
if (evento.defaultPrevented || evento.button !== 0 || evento.ctrlKey || evento.metaKey || evento.shiftKey) return;
|
|
5788
|
-
const enlace = evento.target instanceof Element ? evento.target.closest("a[href]") : null;
|
|
5789
|
-
if (!enlace || enlace.hasAttribute("download") || (enlace.getAttribute("target") ?? "_self") !== "_self") return;
|
|
5790
|
-
const ruta = rutaDeEnlaceBP(enlace.getAttribute("href") ?? "", document.baseURI, urlBackend);
|
|
5791
|
-
if (ruta) {
|
|
5792
|
-
evento.preventDefault();
|
|
5793
|
-
evento.stopPropagation();
|
|
5794
|
-
navegar(ruta);
|
|
5795
|
-
}
|
|
5796
|
-
};
|
|
5797
|
-
document.addEventListener("click", alHacerClick, true);
|
|
5798
|
-
const navegacion = apiDeNavegacion();
|
|
5799
|
-
const alNavegar = (evento) => {
|
|
5800
|
-
if (!evento.cancelable || evento.destination.sameDocument || evento.downloadRequest !== null) return;
|
|
5801
|
-
const ruta = rutaDeEnlaceBP(evento.destination.url, document.baseURI, urlBackend);
|
|
5802
|
-
if (ruta) {
|
|
5803
|
-
evento.preventDefault();
|
|
5804
|
-
navegar(ruta);
|
|
5805
|
-
}
|
|
5806
|
-
};
|
|
5807
|
-
navegacion?.addEventListener("navigate", alNavegar);
|
|
5808
|
-
const reemplazarOriginal = history.replaceState;
|
|
5809
|
-
const reemplazar = (estado, titulo, url) => {
|
|
5810
|
-
const ruta = url === void 0 || url === null ? null : rutaDeEnlaceBP(String(url), document.baseURI, urlBackend);
|
|
5811
|
-
reemplazarOriginal.call(history, estado, titulo, ruta === null ? url : rutaBase + ruta);
|
|
5812
|
-
};
|
|
5813
|
-
history.replaceState = reemplazar;
|
|
5814
|
-
return () => {
|
|
5815
|
-
if (history.replaceState === reemplazar) history.replaceState = reemplazarOriginal;
|
|
5816
|
-
document.removeEventListener("click", alHacerClick, true);
|
|
5817
|
-
navegacion?.removeEventListener("navigate", alNavegar);
|
|
5818
|
-
};
|
|
5819
|
-
}
|
|
5820
|
-
|
|
5821
5793
|
// src/puente/habilitacion.ts
|
|
5822
5794
|
var habilitado = false;
|
|
5823
5795
|
var habilitarPuenteBP = () => {
|
|
@@ -5838,7 +5810,6 @@ function buscarItemDeMenu(items, tipo) {
|
|
|
5838
5810
|
return void 0;
|
|
5839
5811
|
}
|
|
5840
5812
|
var PantallaBP = ({ nombre, direccion }) => {
|
|
5841
|
-
const navigate = (0, import_react_router_dom13.useNavigate)();
|
|
5842
5813
|
const { clientContext } = useApp();
|
|
5843
5814
|
const [cargando, setCargando] = (0, import_react36.useState)(true);
|
|
5844
5815
|
const [error, setError] = (0, import_react36.useState)(null);
|
|
@@ -5852,7 +5823,6 @@ var PantallaBP = ({ nombre, direccion }) => {
|
|
|
5852
5823
|
setError(null);
|
|
5853
5824
|
setNoExiste(false);
|
|
5854
5825
|
setCargando(true);
|
|
5855
|
-
const dejarDeCapturar = capturarNavegacionBP(envConfig.backendUrl, navigate);
|
|
5856
5826
|
cargarClienteBP(envConfig.backendUrl).then((myOwn) => {
|
|
5857
5827
|
if (!vigente) return;
|
|
5858
5828
|
setCargando(false);
|
|
@@ -5874,10 +5844,9 @@ var PantallaBP = ({ nombre, direccion }) => {
|
|
|
5874
5844
|
});
|
|
5875
5845
|
return () => {
|
|
5876
5846
|
vigente = false;
|
|
5877
|
-
dejarDeCapturar();
|
|
5878
5847
|
elemento.replaceChildren();
|
|
5879
5848
|
};
|
|
5880
|
-
}, [nombre, direccion, menu
|
|
5849
|
+
}, [nombre, direccion, menu]);
|
|
5881
5850
|
if (noExiste) return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FallbackWScreen, { screenName: nombre });
|
|
5882
5851
|
return (
|
|
5883
5852
|
// 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
|
|
@@ -5890,18 +5859,18 @@ var PantallaBP = ({ nombre, direccion }) => {
|
|
|
5890
5859
|
);
|
|
5891
5860
|
};
|
|
5892
5861
|
var PantallaDeRespaldo = () => {
|
|
5893
|
-
const { screenName = "" } = (0,
|
|
5894
|
-
const { search } = (0,
|
|
5862
|
+
const { screenName = "" } = (0, import_react_router_dom12.useParams)();
|
|
5863
|
+
const { search } = (0, import_react_router_dom12.useLocation)();
|
|
5895
5864
|
if (!puenteBPHabilitado()) {
|
|
5896
5865
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_material27.Box, { sx: { p: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FallbackWScreen, { screenName }) });
|
|
5897
5866
|
}
|
|
5898
|
-
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_router_dom12.Navigate, { to: rutaDePantallaBP(screenName, search), replace: true });
|
|
5899
5868
|
};
|
|
5900
5869
|
var PaginaBP = () => {
|
|
5901
|
-
const { hash, search } = (0,
|
|
5870
|
+
const { hash, search } = (0, import_react_router_dom12.useLocation)();
|
|
5902
5871
|
const direccion = hash || search;
|
|
5903
5872
|
const nombre = new URLSearchParams(direccion.replace(/^[#?]/, "")).get("w");
|
|
5904
|
-
if (!puenteBPHabilitado()) return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5873
|
+
if (!puenteBPHabilitado()) return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_router_dom12.Navigate, { to: "/", replace: true });
|
|
5905
5874
|
if (!nombre) return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_material27.Box, { sx: { p: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_material27.Alert, { severity: "warning", children: [
|
|
5906
5875
|
"Falta la pantalla de backend-plus (",
|
|
5907
5876
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("code", { children: "#w=..." }),
|
|
@@ -5912,7 +5881,7 @@ var PaginaBP = () => {
|
|
|
5912
5881
|
|
|
5913
5882
|
// src/puente/GrillaBP.tsx
|
|
5914
5883
|
var import_react37 = require("react");
|
|
5915
|
-
var
|
|
5884
|
+
var import_react_router_dom13 = require("react-router-dom");
|
|
5916
5885
|
var import_material28 = require("@mui/material");
|
|
5917
5886
|
var import_jsx_runtime34 = (
|
|
5918
5887
|
// 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
|
|
@@ -5952,17 +5921,69 @@ var GrillaBP = ({ tabla, fixedFields }) => {
|
|
|
5952
5921
|
] });
|
|
5953
5922
|
};
|
|
5954
5923
|
var PaginaGrillaBP = () => {
|
|
5955
|
-
const { tableName = "" } = (0,
|
|
5924
|
+
const { tableName = "" } = (0, import_react_router_dom13.useParams)();
|
|
5956
5925
|
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(GrillaBP, { tabla: tableName }, tableName);
|
|
5957
5926
|
};
|
|
5958
5927
|
|
|
5928
|
+
// src/puente/CapturaBP.tsx
|
|
5929
|
+
var import_react38 = require("react");
|
|
5930
|
+
var import_react_router_dom14 = require("react-router-dom");
|
|
5931
|
+
|
|
5932
|
+
// src/puente/capturaDeNavegacion.ts
|
|
5933
|
+
function apiDeNavegacion() {
|
|
5934
|
+
const api = Reflect.get(window, "navigation");
|
|
5935
|
+
return typeof api === "object" && api !== null && "addEventListener" in api && typeof api.addEventListener === "function" ? api : null;
|
|
5936
|
+
}
|
|
5937
|
+
function capturarNavegacionBP(urlBackend, navegar) {
|
|
5938
|
+
const alHacerClick = (evento) => {
|
|
5939
|
+
if (evento.defaultPrevented || evento.button !== 0 || evento.ctrlKey || evento.metaKey || evento.shiftKey) return;
|
|
5940
|
+
const enlace = evento.target instanceof Element ? evento.target.closest("a[href]") : null;
|
|
5941
|
+
if (!enlace || enlace.hasAttribute("download") || (enlace.getAttribute("target") ?? "_self") !== "_self") return;
|
|
5942
|
+
const ruta = rutaDeEnlaceBP(enlace.getAttribute("href") ?? "", document.baseURI, urlBackend);
|
|
5943
|
+
if (ruta) {
|
|
5944
|
+
evento.preventDefault();
|
|
5945
|
+
evento.stopPropagation();
|
|
5946
|
+
navegar(ruta);
|
|
5947
|
+
}
|
|
5948
|
+
};
|
|
5949
|
+
document.addEventListener("click", alHacerClick, true);
|
|
5950
|
+
const navegacion = apiDeNavegacion();
|
|
5951
|
+
const alNavegar = (evento) => {
|
|
5952
|
+
if (!evento.cancelable || evento.destination.sameDocument || evento.downloadRequest !== null) return;
|
|
5953
|
+
const ruta = rutaDeEnlaceBP(evento.destination.url, document.baseURI, urlBackend);
|
|
5954
|
+
if (ruta) {
|
|
5955
|
+
evento.preventDefault();
|
|
5956
|
+
navegar(ruta);
|
|
5957
|
+
}
|
|
5958
|
+
};
|
|
5959
|
+
navegacion?.addEventListener("navigate", alNavegar);
|
|
5960
|
+
const reemplazarOriginal = history.replaceState;
|
|
5961
|
+
const reemplazar = (estado, titulo, url) => {
|
|
5962
|
+
const ruta = url === void 0 || url === null ? null : rutaDeEnlaceBP(String(url), document.baseURI, urlBackend);
|
|
5963
|
+
reemplazarOriginal.call(history, estado, titulo, ruta === null ? url : rutaBase + ruta);
|
|
5964
|
+
};
|
|
5965
|
+
history.replaceState = reemplazar;
|
|
5966
|
+
return () => {
|
|
5967
|
+
if (history.replaceState === reemplazar) history.replaceState = reemplazarOriginal;
|
|
5968
|
+
document.removeEventListener("click", alHacerClick, true);
|
|
5969
|
+
navegacion?.removeEventListener("navigate", alNavegar);
|
|
5970
|
+
};
|
|
5971
|
+
}
|
|
5972
|
+
|
|
5973
|
+
// src/puente/CapturaBP.tsx
|
|
5974
|
+
var CapturaBP = () => {
|
|
5975
|
+
const navigate = (0, import_react_router_dom14.useNavigate)();
|
|
5976
|
+
(0, import_react38.useEffect)(() => capturarNavegacionBP(envConfig.backendUrl, navigate), [navigate]);
|
|
5977
|
+
return null;
|
|
5978
|
+
};
|
|
5979
|
+
|
|
5959
5980
|
// src/App.tsx
|
|
5960
5981
|
var import_type_store6 = __toESM(require("type-store"), 1);
|
|
5961
5982
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
5962
5983
|
var LocationTracker = () => {
|
|
5963
5984
|
const location = (0, import_react_router_dom15.useLocation)();
|
|
5964
5985
|
const dispatch = useAppDispatch();
|
|
5965
|
-
(0,
|
|
5986
|
+
(0, import_react39.useEffect)(() => {
|
|
5966
5987
|
dispatch(setCurrentPath(location.pathname + location.search));
|
|
5967
5988
|
}, [location, dispatch]);
|
|
5968
5989
|
return null;
|
|
@@ -5970,6 +5991,7 @@ var LocationTracker = () => {
|
|
|
5970
5991
|
function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout = MainLayout_default, unloggedLayout: UnloggedLayout }) {
|
|
5971
5992
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
|
|
5972
5993
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(InitialRedirectHandler_default, {}),
|
|
5994
|
+
puenteBPHabilitado() && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(CapturaBP, {}),
|
|
5973
5995
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_react_router_dom15.Routes, { children: [
|
|
5974
5996
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_react_router_dom15.Route, { element: UnloggedLayout ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(UnloggedLayout, {}) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_router_dom15.Outlet, {}), children: [
|
|
5975
5997
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_router_dom15.Route, { path: "/login", element: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(LoginPage_default, {}) }),
|
|
@@ -6000,7 +6022,7 @@ function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout =
|
|
|
6000
6022
|
] });
|
|
6001
6023
|
}
|
|
6002
6024
|
var FrontendPlusProviders = ({ children, publicPaths }) => {
|
|
6003
|
-
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_redux5.Provider, { store, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_redux5.Provider, { store, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react40.PersistGate, { loading: null, persistor, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_react_router_dom15.BrowserRouter, { basename: rutaBase, children: [
|
|
6004
6026
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(LocationTracker, {}),
|
|
6005
6027
|
" ",
|
|
6006
6028
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(AppProvider, { publicPaths, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(SnackbarProvider, { children: [
|
|
@@ -6019,7 +6041,7 @@ var App = ({
|
|
|
6019
6041
|
myConditions,
|
|
6020
6042
|
puenteBP
|
|
6021
6043
|
}) => {
|
|
6022
|
-
(0,
|
|
6044
|
+
(0, import_react39.useMemo)(() => {
|
|
6023
6045
|
if (myClientSides) {
|
|
6024
6046
|
extendClientSides(myClientSides);
|
|
6025
6047
|
}
|
|
@@ -6036,7 +6058,7 @@ var App = ({
|
|
|
6036
6058
|
habilitarPuenteBP();
|
|
6037
6059
|
}
|
|
6038
6060
|
}, [myClientSides, myResultsOk, myWScreens, myConditions, puenteBP]);
|
|
6039
|
-
(0,
|
|
6061
|
+
(0, import_react39.useEffect)(() => {
|
|
6040
6062
|
import_type_store6.default.messages = import_type_store6.default.i18n.messages.es;
|
|
6041
6063
|
import_type_store6.default.locale = import_type_store6.default.i18n.locale.es;
|
|
6042
6064
|
const link = document.querySelector("link[rel*='icon']") || document.createElement("link");
|
|
@@ -6045,7 +6067,7 @@ var App = ({
|
|
|
6045
6067
|
link.href = `${envConfig.backendUrl}/img/logo-128.png`;
|
|
6046
6068
|
document.getElementsByTagName("head")[0].appendChild(link);
|
|
6047
6069
|
}, []);
|
|
6048
|
-
const safePaths =
|
|
6070
|
+
const safePaths = import_react39.default.useMemo(() => {
|
|
6049
6071
|
const extracted = extractPathsFromRoutes(myUnloggedRoutes);
|
|
6050
6072
|
return ["/login", "/logout", ...extracted];
|
|
6051
6073
|
}, [myUnloggedRoutes]);
|