frontend-plus-react 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -277,7 +277,10 @@ declare const FrontendPlusProviders: React$1.FC<{
277
277
  children: React$1.ReactNode;
278
278
  publicPaths: string[];
279
279
  }>;
280
- declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk, myConditions }: AppProps) => react_jsx_runtime.JSX.Element;
280
+ declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk, myConditions, puenteBP }: AppProps & {
281
+ /** Las wScreens que la aplicación no registró se piden al cliente de backend-plus (mismo origen que el backend) */
282
+ puenteBP?: boolean;
283
+ }) => react_jsx_runtime.JSX.Element;
281
284
 
282
285
  declare const MainLayout: React$1.FC;
283
286
 
@@ -316,4 +319,13 @@ type ResultComponentMap = {
316
319
  declare let resultsOk: ResultComponentMap;
317
320
  declare const extendResultsOk: (newComponents: ResultComponentMap) => void;
318
321
 
319
- export { type Ancestor, App, type AppContextType, type AppProps, AppProvider, type AppProviderProps, type CallApiOptions, type CellFeedback, type CellFeedbackMap, type ClientContextState, type ClientSideProps, type ClientSidesMap, type CondicionDeDetalle, type CondicionesMap, ConfirmDialog, type ConfirmDialogProps, type CustomCellProps, type CustomHeaderCellProps, DOM_TEMP_ID, type DataGridOption, type EntradaDeTotal, type FetchApiOptions, type FilaDeDatos, type FilaDeFiltros, type FilaDeResumen, type FilaDeTotales, type FilterRendererProps, type FiltroDeColumna, type FiltrosDeGrilla, type FixedField, FrontendPlusProviders, FrontendPlusReactRoutes, GenericDataGrid, type GenericDataGridForDetailProps, type GenericDataGridProps$1 as GenericDataGridProps, type InputRendererProps, MainLayout, type MenuListItemProps, type MenuUiState, type ParametrosDeProcedimiento, type PrivateRouteProps, type ResultOkProps, type ResultsOksMap, type RouterState, type SideMenuProps, type SnackbarContextType, SnackbarProvider, type SnackbarProviderProps, type SnackbarState, type TeclaDeEditor, type UseApiCallResult, type WScreenMap, type WScreenProps, cambiarGuionesBajosPorEspacios, clientSides, extendClientSides, extendConditions, extendResultsOk, extendWScreens, extractPathsFromRoutes, resultsOk as resultComponents, useApiCall, useApiCallWithoutSnackbar, useApp, useLogout, useSnackbar, wScreens };
322
+ interface GrillaBPProps {
323
+ tabla: string;
324
+ fixedFields?: FixedField[];
325
+ }
326
+ /** La grilla de backend-plus (`myOwn.tableGrid`) dentro de una página React: conserva todo lo que ya hace esa grilla */
327
+ declare const GrillaBP: React$1.FC<GrillaBPProps>;
328
+
329
+ declare const habilitarPuenteBP: () => void;
330
+
331
+ export { type Ancestor, App, type AppContextType, type AppProps, AppProvider, type AppProviderProps, type CallApiOptions, type CellFeedback, type CellFeedbackMap, type ClientContextState, type ClientSideProps, type ClientSidesMap, type CondicionDeDetalle, type CondicionesMap, ConfirmDialog, type ConfirmDialogProps, type CustomCellProps, type CustomHeaderCellProps, DOM_TEMP_ID, type DataGridOption, type EntradaDeTotal, type FetchApiOptions, type FilaDeDatos, type FilaDeFiltros, type FilaDeResumen, type FilaDeTotales, type FilterRendererProps, type FiltroDeColumna, type FiltrosDeGrilla, type FixedField, FrontendPlusProviders, FrontendPlusReactRoutes, GenericDataGrid, type GenericDataGridForDetailProps, type GenericDataGridProps$1 as GenericDataGridProps, GrillaBP, type InputRendererProps, MainLayout, type MenuListItemProps, type MenuUiState, type ParametrosDeProcedimiento, type PrivateRouteProps, type ResultOkProps, type ResultsOksMap, type RouterState, type SideMenuProps, type SnackbarContextType, SnackbarProvider, type SnackbarProviderProps, type SnackbarState, type TeclaDeEditor, type UseApiCallResult, type WScreenMap, type WScreenProps, cambiarGuionesBajosPorEspacios, clientSides, extendClientSides, extendConditions, extendResultsOk, extendWScreens, extractPathsFromRoutes, habilitarPuenteBP, resultsOk as resultComponents, useApiCall, useApiCallWithoutSnackbar, useApp, useLogout, useSnackbar, wScreens };
package/dist/index.d.ts CHANGED
@@ -277,7 +277,10 @@ declare const FrontendPlusProviders: React$1.FC<{
277
277
  children: React$1.ReactNode;
278
278
  publicPaths: string[];
279
279
  }>;
280
- declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk, myConditions }: AppProps) => react_jsx_runtime.JSX.Element;
280
+ declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk, myConditions, puenteBP }: AppProps & {
281
+ /** Las wScreens que la aplicación no registró se piden al cliente de backend-plus (mismo origen que el backend) */
282
+ puenteBP?: boolean;
283
+ }) => react_jsx_runtime.JSX.Element;
281
284
 
282
285
  declare const MainLayout: React$1.FC;
283
286
 
@@ -316,4 +319,13 @@ type ResultComponentMap = {
316
319
  declare let resultsOk: ResultComponentMap;
317
320
  declare const extendResultsOk: (newComponents: ResultComponentMap) => void;
318
321
 
319
- export { type Ancestor, App, type AppContextType, type AppProps, AppProvider, type AppProviderProps, type CallApiOptions, type CellFeedback, type CellFeedbackMap, type ClientContextState, type ClientSideProps, type ClientSidesMap, type CondicionDeDetalle, type CondicionesMap, ConfirmDialog, type ConfirmDialogProps, type CustomCellProps, type CustomHeaderCellProps, DOM_TEMP_ID, type DataGridOption, type EntradaDeTotal, type FetchApiOptions, type FilaDeDatos, type FilaDeFiltros, type FilaDeResumen, type FilaDeTotales, type FilterRendererProps, type FiltroDeColumna, type FiltrosDeGrilla, type FixedField, FrontendPlusProviders, FrontendPlusReactRoutes, GenericDataGrid, type GenericDataGridForDetailProps, type GenericDataGridProps$1 as GenericDataGridProps, type InputRendererProps, MainLayout, type MenuListItemProps, type MenuUiState, type ParametrosDeProcedimiento, type PrivateRouteProps, type ResultOkProps, type ResultsOksMap, type RouterState, type SideMenuProps, type SnackbarContextType, SnackbarProvider, type SnackbarProviderProps, type SnackbarState, type TeclaDeEditor, type UseApiCallResult, type WScreenMap, type WScreenProps, cambiarGuionesBajosPorEspacios, clientSides, extendClientSides, extendConditions, extendResultsOk, extendWScreens, extractPathsFromRoutes, resultsOk as resultComponents, useApiCall, useApiCallWithoutSnackbar, useApp, useLogout, useSnackbar, wScreens };
322
+ interface GrillaBPProps {
323
+ tabla: string;
324
+ fixedFields?: FixedField[];
325
+ }
326
+ /** La grilla de backend-plus (`myOwn.tableGrid`) dentro de una página React: conserva todo lo que ya hace esa grilla */
327
+ declare const GrillaBP: React$1.FC<GrillaBPProps>;
328
+
329
+ declare const habilitarPuenteBP: () => void;
330
+
331
+ export { type Ancestor, App, type AppContextType, type AppProps, AppProvider, type AppProviderProps, type CallApiOptions, type CellFeedback, type CellFeedbackMap, type ClientContextState, type ClientSideProps, type ClientSidesMap, type CondicionDeDetalle, type CondicionesMap, ConfirmDialog, type ConfirmDialogProps, type CustomCellProps, type CustomHeaderCellProps, DOM_TEMP_ID, type DataGridOption, type EntradaDeTotal, type FetchApiOptions, type FilaDeDatos, type FilaDeFiltros, type FilaDeResumen, type FilaDeTotales, type FilterRendererProps, type FiltroDeColumna, type FiltrosDeGrilla, type FixedField, FrontendPlusProviders, FrontendPlusReactRoutes, GenericDataGrid, type GenericDataGridForDetailProps, type GenericDataGridProps$1 as GenericDataGridProps, GrillaBP, type InputRendererProps, MainLayout, type MenuListItemProps, type MenuUiState, type ParametrosDeProcedimiento, type PrivateRouteProps, type ResultOkProps, type ResultsOksMap, type RouterState, type SideMenuProps, type SnackbarContextType, SnackbarProvider, type SnackbarProviderProps, type SnackbarState, type TeclaDeEditor, type UseApiCallResult, type WScreenMap, type WScreenProps, cambiarGuionesBajosPorEspacios, clientSides, extendClientSides, extendConditions, extendResultsOk, extendWScreens, extractPathsFromRoutes, habilitarPuenteBP, resultsOk as resultComponents, useApiCall, useApiCallWithoutSnackbar, useApp, useLogout, useSnackbar, wScreens };
package/dist/index.js CHANGED
@@ -3457,6 +3457,10 @@ var VerticalEditorPage = ({
3457
3457
  ] });
3458
3458
  };
3459
3459
 
3460
+ // src/rutaBase.ts
3461
+ var baseDelBundler = import.meta.env?.BASE_URL ?? "/";
3462
+ var rutaBase = baseDelBundler.replace(/\/+$/, "");
3463
+
3460
3464
  // src/components/grid/GenericDataGrid.tsx
3461
3465
  import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
3462
3466
  var SUMMARY_ROW_HEIGHT = 35;
@@ -3846,7 +3850,7 @@ var GenericDataGrid = ({
3846
3850
  const abrirWScreenEnPestana = useCallback11((row, detailTable) => {
3847
3851
  const parametros = new URLSearchParams();
3848
3852
  calcularFixedFieldsDetalle(detailTable, row).forEach((ff) => parametros.set(ff.fieldName, String(ff.value)));
3849
- window.open(`${window.location.origin}/wScreens/${detailTable.wScreen}?${parametros}`, "_blank");
3853
+ window.open(`${window.location.origin}${rutaBase}/wScreens/${detailTable.wScreen}?${parametros}`, "_blank");
3850
3854
  }, []);
3851
3855
  const alternarDetalle = useCallback11((row, rowId, detailTable, enOtraPestana) => {
3852
3856
  if (enOtraPestana && detailTable.wScreen) {
@@ -4189,8 +4193,8 @@ var GenericDataGrid = ({
4189
4193
  var GenericDataGrid_default = GenericDataGrid;
4190
4194
 
4191
4195
  // src/App.tsx
4192
- import React25, { useEffect as useEffect13, useMemo as useMemo14 } from "react";
4193
- import { BrowserRouter, Routes, Route, useLocation as useLocation6, Navigate as Navigate2, Outlet as Outlet2 } from "react-router-dom";
4196
+ import React27, { useEffect as useEffect15, useMemo as useMemo14 } from "react";
4197
+ import { BrowserRouter, Routes, Route, useLocation as useLocation7, Navigate as Navigate3, Outlet as Outlet2 } from "react-router-dom";
4194
4198
 
4195
4199
  // src/components/MainLayout.tsx
4196
4200
  import { useEffect as useEffect8 } from "react";
@@ -5632,62 +5636,330 @@ var MenuTablePage = () => {
5632
5636
  };
5633
5637
  var MenuTablePage_default = MenuTablePage;
5634
5638
 
5639
+ // src/puente/PantallaBP.tsx
5640
+ import { useEffect as useEffect13, useRef as useRef9, useState as useState17 } from "react";
5641
+ import { Navigate as Navigate2, useLocation as useLocation6, useNavigate as useNavigate6, useParams as useParams4 } from "react-router-dom";
5642
+ import { Alert as Alert7, Box as Box24, CircularProgress as CircularProgress8 } from "@mui/material";
5643
+
5644
+ // src/puente/clienteBP.ts
5645
+ function extraerRecursos(html) {
5646
+ const documento = new DOMParser().parseFromString(html, "text/html");
5647
+ const referencias = (selector, atributo) => Array.from(documento.querySelectorAll(selector)).map((elemento) => elemento.getAttribute(atributo)).filter((ruta) => !!ruta);
5648
+ return {
5649
+ hojasDeEstilo: referencias("link[rel=stylesheet]", "href"),
5650
+ scripts: referencias("script[src]", "src")
5651
+ };
5652
+ }
5653
+ function fijarBase(urlBackend) {
5654
+ const href = new URL(urlBackend.replace(/\/*$/, "/"), window.location.href).href;
5655
+ let base = document.querySelector("base");
5656
+ if (!base) {
5657
+ base = document.createElement("base");
5658
+ document.head.prepend(base);
5659
+ }
5660
+ base.href = href;
5661
+ }
5662
+ function cargarScript(ruta) {
5663
+ return new Promise((resolver, rechazar) => {
5664
+ const script = document.createElement("script");
5665
+ script.async = false;
5666
+ script.src = ruta;
5667
+ script.onload = () => resolver();
5668
+ script.onerror = () => rechazar(new Error(`No se pudo cargar ${ruta}`));
5669
+ document.head.appendChild(script);
5670
+ });
5671
+ }
5672
+ var carga = null;
5673
+ function cargarClienteBP(urlBackend) {
5674
+ if (!carga) {
5675
+ carga = cargarSinMemoria(urlBackend).catch((error) => {
5676
+ carga = null;
5677
+ throw error;
5678
+ });
5679
+ }
5680
+ return carga;
5681
+ }
5682
+ async function cargarSinMemoria(urlBackend) {
5683
+ const destino = new URL(urlBackend, window.location.href);
5684
+ if (destino.origin !== window.location.origin) {
5685
+ throw new Error(`El cliente de backend-plus solo se puede usar desde el mismo origen que el backend (${destino.origin} no es ${window.location.origin}).`);
5686
+ }
5687
+ fijarBase(urlBackend);
5688
+ const respuesta = await fetch(`${destino.pathname.replace(/\/*$/, "")}/menu`, { credentials: "include" });
5689
+ if (!respuesta.ok || /\/login\/?$/.test(new URL(respuesta.url).pathname)) {
5690
+ throw new Error("No hay una sesi\xF3n iniciada en el backend.");
5691
+ }
5692
+ const recursos = extraerRecursos(await respuesta.text());
5693
+ recursos.hojasDeEstilo.forEach((ruta) => {
5694
+ const enlace = document.createElement("link");
5695
+ enlace.rel = "stylesheet";
5696
+ enlace.href = ruta;
5697
+ document.head.appendChild(enlace);
5698
+ });
5699
+ for (const ruta of recursos.scripts) {
5700
+ await cargarScript(ruta);
5701
+ }
5702
+ const myOwn = window.myOwn;
5703
+ if (!myOwn) throw new Error("El backend no defini\xF3 myOwn.");
5704
+ window.my = myOwn;
5705
+ await myOwn.autoSetup();
5706
+ return myOwn;
5707
+ }
5708
+
5709
+ // src/puente/pantallaDeBP.ts
5710
+ var RUTA_PANTALLA_BP = "/bp/menu";
5711
+ function rutaDePantallaBP(nombre, parametros = "") {
5712
+ const resto = parametros.replace(/^[#?]/, "").replace(/(^|&)w=[^&]*/, "").replace(/^&/, "");
5713
+ return `${RUTA_PANTALLA_BP}#w=${encodeURIComponent(nombre)}${resto ? `&${resto}` : ""}`;
5714
+ }
5715
+ function rutaDeEnlaceBP(href, baseDelDocumento, urlBackend) {
5716
+ const enlace = new URL(href, baseDelDocumento);
5717
+ const base = `${urlBackend.replace(/\/*$/, "/")}`;
5718
+ const pagina = (nombre2) => new URL(`${base}${nombre2}`, baseDelDocumento);
5719
+ if (enlace.origin !== pagina("menu").origin) return null;
5720
+ if (enlace.pathname === pagina("login").pathname) return "/login";
5721
+ if (enlace.pathname === pagina("logout").pathname) return "/logout";
5722
+ if (enlace.pathname !== pagina("menu").pathname) return null;
5723
+ const texto = (enlace.hash || enlace.search).slice(1);
5724
+ const nombre = new URLSearchParams(texto).get("w");
5725
+ return nombre ? rutaDePantallaBP(nombre, texto) : null;
5726
+ }
5727
+ function resolverPantallaBP(myOwn, nombre, contenedor) {
5728
+ const registrada = myOwn.wScreens[nombre];
5729
+ if (!registrada) return null;
5730
+ if (typeof registrada === "function") {
5731
+ return { definicion: { mainFunction: registrada }, ejecutar: registrada };
5732
+ }
5733
+ if (registrada.mainFunction) {
5734
+ return { definicion: registrada, ejecutar: registrada.mainFunction };
5735
+ }
5736
+ const { parameters, mainAction, resultClass, proceedLabel } = registrada;
5737
+ const procAux = myOwn.wScreens.procAux;
5738
+ const mostrarParametros = typeof procAux === "object" ? procAux.showParams : void 0;
5739
+ if (parameters && mostrarParametros) {
5740
+ return {
5741
+ definicion: registrada,
5742
+ ejecutar: (parametros) => mostrarParametros({ parameters, resultClass, proceedLabel }, contenedor, parametros, mainAction)
5743
+ };
5744
+ }
5745
+ return null;
5746
+ }
5747
+
5748
+ // src/puente/capturaDeNavegacion.ts
5749
+ function apiDeNavegacion() {
5750
+ const api = Reflect.get(window, "navigation");
5751
+ return typeof api === "object" && api !== null && "addEventListener" in api && typeof api.addEventListener === "function" ? api : null;
5752
+ }
5753
+ function capturarNavegacionBP(urlBackend, navegar) {
5754
+ const alHacerClick = (evento) => {
5755
+ if (evento.defaultPrevented || evento.button !== 0 || evento.ctrlKey || evento.metaKey || evento.shiftKey) return;
5756
+ const enlace = evento.target instanceof Element ? evento.target.closest("a[href]") : null;
5757
+ if (!enlace || enlace.hasAttribute("download") || (enlace.getAttribute("target") ?? "_self") !== "_self") return;
5758
+ const ruta = rutaDeEnlaceBP(enlace.getAttribute("href") ?? "", document.baseURI, urlBackend);
5759
+ if (ruta) {
5760
+ evento.preventDefault();
5761
+ evento.stopPropagation();
5762
+ navegar(ruta);
5763
+ }
5764
+ };
5765
+ document.addEventListener("click", alHacerClick, true);
5766
+ const navegacion = apiDeNavegacion();
5767
+ const alNavegar = (evento) => {
5768
+ if (!evento.cancelable || evento.destination.sameDocument || evento.downloadRequest !== null) return;
5769
+ const ruta = rutaDeEnlaceBP(evento.destination.url, document.baseURI, urlBackend);
5770
+ if (ruta) {
5771
+ evento.preventDefault();
5772
+ navegar(ruta);
5773
+ }
5774
+ };
5775
+ navegacion?.addEventListener("navigate", alNavegar);
5776
+ return () => {
5777
+ document.removeEventListener("click", alHacerClick, true);
5778
+ navegacion?.removeEventListener("navigate", alNavegar);
5779
+ };
5780
+ }
5781
+
5782
+ // src/puente/habilitacion.ts
5783
+ var habilitado = false;
5784
+ var habilitarPuenteBP = () => {
5785
+ habilitado = true;
5786
+ };
5787
+ var puenteBPHabilitado = () => habilitado;
5788
+
5789
+ // src/puente/PantallaBP.tsx
5790
+ import { jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
5791
+ function buscarItemDeMenu(items, tipo) {
5792
+ for (const item of items) {
5793
+ if (item.menuType === tipo) return item;
5794
+ if (item.menuType === "menu") {
5795
+ const encontrado = buscarItemDeMenu(item.menuContent, tipo);
5796
+ if (encontrado) return encontrado;
5797
+ }
5798
+ }
5799
+ return void 0;
5800
+ }
5801
+ var PantallaBP = ({ nombre, direccion }) => {
5802
+ const navigate = useNavigate6();
5803
+ const { clientContext } = useApp();
5804
+ const [cargando, setCargando] = useState17(true);
5805
+ const [error, setError] = useState17(null);
5806
+ const [noExiste, setNoExiste] = useState17(false);
5807
+ const contenedor = useRef9(null);
5808
+ const menu = clientContext.menu;
5809
+ useEffect13(() => {
5810
+ const elemento = contenedor.current;
5811
+ if (!elemento) return;
5812
+ let vigente = true;
5813
+ setError(null);
5814
+ setNoExiste(false);
5815
+ setCargando(true);
5816
+ const dejarDeCapturar = capturarNavegacionBP(envConfig.backendUrl, navigate);
5817
+ cargarClienteBP(envConfig.backendUrl).then((myOwn) => {
5818
+ if (!vigente) return;
5819
+ setCargando(false);
5820
+ const pantalla = resolverPantallaBP(myOwn, nombre, elemento);
5821
+ if (!pantalla) {
5822
+ setNoExiste(true);
5823
+ return;
5824
+ }
5825
+ elemento.replaceChildren();
5826
+ const item = menu ? buscarItemDeMenu(menu, nombre) : void 0;
5827
+ const desdeLaDireccion = myOwn.UriSearchToObject?.(direccion) ?? Object.fromEntries(new URLSearchParams(direccion.replace(/^[#?]/, "")).entries());
5828
+ const parametros = { ...item, ...desdeLaDireccion };
5829
+ myOwn.preDisplayPage?.(parametros, pantalla.definicion, nombre);
5830
+ pantalla.ejecutar.call(myOwn, parametros);
5831
+ }).catch((err) => {
5832
+ if (!vigente) return;
5833
+ setCargando(false);
5834
+ setError(mensajeDeError(err));
5835
+ });
5836
+ return () => {
5837
+ vigente = false;
5838
+ dejarDeCapturar();
5839
+ elemento.replaceChildren();
5840
+ };
5841
+ }, [nombre, direccion, menu, navigate]);
5842
+ if (noExiste) return /* @__PURE__ */ jsx32(FallbackWScreen, { screenName: nombre });
5843
+ return /* @__PURE__ */ jsxs24(Box24, { children: [
5844
+ cargando && /* @__PURE__ */ jsx32(CircularProgress8, { size: 24, sx: { m: 2 } }),
5845
+ error && /* @__PURE__ */ jsx32(Alert7, { severity: "error", sx: { m: 2 }, children: error }),
5846
+ /* @__PURE__ */ jsx32("div", { id: "main_layout", ref: contenedor })
5847
+ ] });
5848
+ };
5849
+ var PantallaDeRespaldo = () => {
5850
+ const { screenName = "" } = useParams4();
5851
+ const { search } = useLocation6();
5852
+ if (!puenteBPHabilitado()) {
5853
+ return /* @__PURE__ */ jsx32(Box24, { sx: { p: 3 }, children: /* @__PURE__ */ jsx32(FallbackWScreen, { screenName }) });
5854
+ }
5855
+ return /* @__PURE__ */ jsx32(Navigate2, { to: rutaDePantallaBP(screenName, search), replace: true });
5856
+ };
5857
+ var PaginaBP = () => {
5858
+ const { hash, search } = useLocation6();
5859
+ const direccion = hash || search;
5860
+ const nombre = new URLSearchParams(direccion.replace(/^[#?]/, "")).get("w");
5861
+ if (!puenteBPHabilitado()) return /* @__PURE__ */ jsx32(Navigate2, { to: "/", replace: true });
5862
+ if (!nombre) return /* @__PURE__ */ jsx32(Box24, { sx: { p: 3 }, children: /* @__PURE__ */ jsxs24(Alert7, { severity: "warning", children: [
5863
+ "Falta la pantalla de backend-plus (",
5864
+ /* @__PURE__ */ jsx32("code", { children: "#w=..." }),
5865
+ ")."
5866
+ ] }) });
5867
+ return /* @__PURE__ */ jsx32(PantallaBP, { nombre, direccion }, nombre);
5868
+ };
5869
+
5870
+ // src/puente/GrillaBP.tsx
5871
+ import { useEffect as useEffect14, useRef as useRef10, useState as useState18 } from "react";
5872
+ import { useParams as useParams5 } from "react-router-dom";
5873
+ import { Alert as Alert8, Box as Box25, CircularProgress as CircularProgress9 } from "@mui/material";
5874
+ import { jsx as jsx33, jsxs as jsxs25 } from "react/jsx-runtime";
5875
+ var GrillaBP = ({ tabla, fixedFields }) => {
5876
+ const contenedor = useRef10(null);
5877
+ const [cargando, setCargando] = useState18(true);
5878
+ const [error, setError] = useState18(null);
5879
+ const clave = JSON.stringify(fixedFields ?? []);
5880
+ useEffect14(() => {
5881
+ const elemento = contenedor.current;
5882
+ if (!elemento) return;
5883
+ let vigente = true;
5884
+ setError(null);
5885
+ setCargando(true);
5886
+ cargarClienteBP(envConfig.backendUrl).then((myOwn) => {
5887
+ if (!vigente) return;
5888
+ setCargando(false);
5889
+ elemento.replaceChildren();
5890
+ myOwn.tableGrid(tabla, elemento, { fixedFields: JSON.parse(clave) });
5891
+ }).catch((err) => {
5892
+ if (!vigente) return;
5893
+ setCargando(false);
5894
+ setError(mensajeDeError(err));
5895
+ });
5896
+ return () => {
5897
+ vigente = false;
5898
+ elemento.replaceChildren();
5899
+ };
5900
+ }, [tabla, clave]);
5901
+ return /* @__PURE__ */ jsxs25(Box25, { children: [
5902
+ cargando && /* @__PURE__ */ jsx33(CircularProgress9, { size: 24, sx: { m: 2 } }),
5903
+ error && /* @__PURE__ */ jsx33(Alert8, { severity: "error", sx: { m: 2 }, children: error }),
5904
+ /* @__PURE__ */ jsx33("div", { ref: contenedor })
5905
+ ] });
5906
+ };
5907
+ var PaginaGrillaBP = () => {
5908
+ const { tableName = "" } = useParams5();
5909
+ return /* @__PURE__ */ jsx33(GrillaBP, { tabla: tableName }, tableName);
5910
+ };
5911
+
5635
5912
  // src/App.tsx
5636
- import { Box as Box24 } from "@mui/material";
5637
5913
  import typeStore6 from "type-store";
5638
- import { Fragment as Fragment5, jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
5914
+ import { Fragment as Fragment5, jsx as jsx34, jsxs as jsxs26 } from "react/jsx-runtime";
5639
5915
  var LocationTracker = () => {
5640
- const location = useLocation6();
5916
+ const location = useLocation7();
5641
5917
  const dispatch = useAppDispatch();
5642
- useEffect13(() => {
5918
+ useEffect15(() => {
5643
5919
  dispatch(setCurrentPath(location.pathname + location.search));
5644
5920
  }, [location, dispatch]);
5645
5921
  return null;
5646
5922
  };
5647
5923
  function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout = MainLayout_default, unloggedLayout: UnloggedLayout }) {
5648
- return /* @__PURE__ */ jsxs24(Fragment5, { children: [
5649
- /* @__PURE__ */ jsx32(InitialRedirectHandler_default, {}),
5650
- /* @__PURE__ */ jsxs24(Routes, { children: [
5651
- /* @__PURE__ */ jsxs24(Route, { element: UnloggedLayout ? /* @__PURE__ */ jsx32(UnloggedLayout, {}) : /* @__PURE__ */ jsx32(Outlet2, {}), children: [
5652
- /* @__PURE__ */ jsx32(Route, { path: "/login", element: /* @__PURE__ */ jsx32(LoginPage_default, {}) }),
5653
- /* @__PURE__ */ jsx32(Route, { path: "/logout", element: /* @__PURE__ */ jsx32(LogoutPage_default, {}) }),
5924
+ return /* @__PURE__ */ jsxs26(Fragment5, { children: [
5925
+ /* @__PURE__ */ jsx34(InitialRedirectHandler_default, {}),
5926
+ /* @__PURE__ */ jsxs26(Routes, { children: [
5927
+ /* @__PURE__ */ jsxs26(Route, { element: UnloggedLayout ? /* @__PURE__ */ jsx34(UnloggedLayout, {}) : /* @__PURE__ */ jsx34(Outlet2, {}), children: [
5928
+ /* @__PURE__ */ jsx34(Route, { path: "/login", element: /* @__PURE__ */ jsx34(LoginPage_default, {}) }),
5929
+ /* @__PURE__ */ jsx34(Route, { path: "/logout", element: /* @__PURE__ */ jsx34(LogoutPage_default, {}) }),
5654
5930
  myUnloggedRoutes
5655
5931
  ] }),
5656
- /* @__PURE__ */ jsxs24(Route, { element: /* @__PURE__ */ jsx32(PrivateRoute_default, { children: /* @__PURE__ */ jsx32(Layout, {}) }), children: [
5657
- /* @__PURE__ */ jsx32(Route, { path: "/", element: /* @__PURE__ */ jsx32(HomePage_default, {}) }),
5658
- /* @__PURE__ */ jsx32(Route, { path: "/home", element: /* @__PURE__ */ jsx32(HomePage_default, {}) }),
5659
- /* @__PURE__ */ jsx32(Route, { path: "/table/:tableName", element: /* @__PURE__ */ jsx32(GenericDataGridPage_default, {}) }),
5660
- /* @__PURE__ */ jsx32(Route, { path: "/menu/:menuName", element: /* @__PURE__ */ jsx32(MenuTablePage_default, {}) }),
5661
- /* @__PURE__ */ jsx32(Route, { path: "/procedures/:procedureName", element: /* @__PURE__ */ jsx32(ProcedureForm_default, {}) }),
5662
- Object.keys(wScreens).map((screenName) => /* @__PURE__ */ jsx32(
5932
+ /* @__PURE__ */ jsxs26(Route, { element: /* @__PURE__ */ jsx34(PrivateRoute_default, { children: /* @__PURE__ */ jsx34(Layout, {}) }), children: [
5933
+ /* @__PURE__ */ jsx34(Route, { path: "/", element: /* @__PURE__ */ jsx34(HomePage_default, {}) }),
5934
+ /* @__PURE__ */ jsx34(Route, { path: "/home", element: /* @__PURE__ */ jsx34(HomePage_default, {}) }),
5935
+ /* @__PURE__ */ jsx34(Route, { path: "/table/:tableName", element: /* @__PURE__ */ jsx34(GenericDataGridPage_default, {}) }),
5936
+ /* @__PURE__ */ jsx34(Route, { path: "/menu/:menuName", element: /* @__PURE__ */ jsx34(MenuTablePage_default, {}) }),
5937
+ /* @__PURE__ */ jsx34(Route, { path: "/procedures/:procedureName", element: /* @__PURE__ */ jsx34(ProcedureForm_default, {}) }),
5938
+ Object.keys(wScreens).map((screenName) => /* @__PURE__ */ jsx34(
5663
5939
  Route,
5664
5940
  {
5665
5941
  path: `/wScreens/${screenName}`,
5666
- element: /* @__PURE__ */ jsx32(PantallaDeRuta, { screenName })
5942
+ element: /* @__PURE__ */ jsx34(PantallaDeRuta, { screenName })
5667
5943
  },
5668
5944
  screenName
5669
5945
  )),
5670
- /* @__PURE__ */ jsx32(
5671
- Route,
5672
- {
5673
- path: "/wScreens-fallback/:screenName",
5674
- element: /* @__PURE__ */ jsx32(Box24, { sx: { p: 3 }, children: /* @__PURE__ */ jsx32(FallbackWScreen, { screenName: ":screenName" }) })
5675
- }
5676
- ),
5946
+ /* @__PURE__ */ jsx34(Route, { path: "/wScreens-fallback/:screenName", element: /* @__PURE__ */ jsx34(PantallaDeRespaldo, {}) }),
5947
+ puenteBPHabilitado() && /* @__PURE__ */ jsx34(Route, { path: "/bp/menu", element: /* @__PURE__ */ jsx34(PaginaBP, {}) }),
5948
+ puenteBPHabilitado() && /* @__PURE__ */ jsx34(Route, { path: "/bp/table/:tableName", element: /* @__PURE__ */ jsx34(PaginaGrillaBP, {}) }),
5677
5949
  myRoutes,
5678
- /* @__PURE__ */ jsx32(Route, { path: "*", element: /* @__PURE__ */ jsx32("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
5950
+ /* @__PURE__ */ jsx34(Route, { path: "*", element: /* @__PURE__ */ jsx34("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
5679
5951
  ] }),
5680
- /* @__PURE__ */ jsx32(Route, { path: "*", element: /* @__PURE__ */ jsx32(Navigate2, { to: "/", replace: true }) })
5952
+ /* @__PURE__ */ jsx34(Route, { path: "*", element: /* @__PURE__ */ jsx34(Navigate3, { to: "/", replace: true }) })
5681
5953
  ] })
5682
5954
  ] });
5683
5955
  }
5684
5956
  var FrontendPlusProviders = ({ children, publicPaths }) => {
5685
- return /* @__PURE__ */ jsx32(Provider, { store, children: /* @__PURE__ */ jsx32(PersistGate, { loading: null, persistor, children: /* @__PURE__ */ jsxs24(BrowserRouter, { children: [
5686
- /* @__PURE__ */ jsx32(LocationTracker, {}),
5957
+ return /* @__PURE__ */ jsx34(Provider, { store, children: /* @__PURE__ */ jsx34(PersistGate, { loading: null, persistor, children: /* @__PURE__ */ jsxs26(BrowserRouter, { basename: rutaBase, children: [
5958
+ /* @__PURE__ */ jsx34(LocationTracker, {}),
5687
5959
  " ",
5688
- /* @__PURE__ */ jsx32(AppProvider, { publicPaths, children: /* @__PURE__ */ jsxs24(SnackbarProvider, { children: [
5960
+ /* @__PURE__ */ jsx34(AppProvider, { publicPaths, children: /* @__PURE__ */ jsxs26(SnackbarProvider, { children: [
5689
5961
  children,
5690
- /* @__PURE__ */ jsx32(SessionExpiredMessage_default, {})
5962
+ /* @__PURE__ */ jsx34(SessionExpiredMessage_default, {})
5691
5963
  ] }) })
5692
5964
  ] }) }) });
5693
5965
  };
@@ -5698,7 +5970,8 @@ var App = ({
5698
5970
  myWScreens,
5699
5971
  myClientSides,
5700
5972
  myResultsOk,
5701
- myConditions
5973
+ myConditions,
5974
+ puenteBP
5702
5975
  }) => {
5703
5976
  useMemo14(() => {
5704
5977
  if (myClientSides) {
@@ -5713,8 +5986,11 @@ var App = ({
5713
5986
  if (myConditions) {
5714
5987
  extendConditions(myConditions);
5715
5988
  }
5716
- }, [myClientSides, myResultsOk, myWScreens, myConditions]);
5717
- useEffect13(() => {
5989
+ if (puenteBP) {
5990
+ habilitarPuenteBP();
5991
+ }
5992
+ }, [myClientSides, myResultsOk, myWScreens, myConditions, puenteBP]);
5993
+ useEffect15(() => {
5718
5994
  typeStore6.messages = typeStore6.i18n.messages.es;
5719
5995
  typeStore6.locale = typeStore6.i18n.locale.es;
5720
5996
  const link = document.querySelector("link[rel*='icon']") || document.createElement("link");
@@ -5723,11 +5999,11 @@ var App = ({
5723
5999
  link.href = `${envConfig.backendUrl}/img/logo-128.png`;
5724
6000
  document.getElementsByTagName("head")[0].appendChild(link);
5725
6001
  }, []);
5726
- const safePaths = React25.useMemo(() => {
6002
+ const safePaths = React27.useMemo(() => {
5727
6003
  const extracted = extractPathsFromRoutes(myUnloggedRoutes);
5728
6004
  return ["/login", "/logout", ...extracted];
5729
6005
  }, [myUnloggedRoutes]);
5730
- return /* @__PURE__ */ jsx32(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ jsx32(
6006
+ return /* @__PURE__ */ jsx34(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ jsx34(
5731
6007
  FrontendPlusReactRoutes,
5732
6008
  {
5733
6009
  myRoutes,
@@ -5745,6 +6021,7 @@ export {
5745
6021
  FrontendPlusProviders,
5746
6022
  FrontendPlusReactRoutes,
5747
6023
  GenericDataGrid_default as GenericDataGrid,
6024
+ GrillaBP,
5748
6025
  MainLayout_default as MainLayout,
5749
6026
  SnackbarProvider,
5750
6027
  cambiarGuionesBajosPorEspacios,
@@ -5754,6 +6031,7 @@ export {
5754
6031
  extendResultsOk,
5755
6032
  extendWScreens,
5756
6033
  extractPathsFromRoutes,
6034
+ habilitarPuenteBP,
5757
6035
  resultsOk as resultComponents,
5758
6036
  useApiCall,
5759
6037
  useApiCallWithoutSnackbar,