frontend-plus-react 0.1.15 → 0.1.17

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.ts CHANGED
@@ -9,6 +9,7 @@ interface WScreenProps {
9
9
  screenName: string;
10
10
  }
11
11
  declare let wScreens: Record<string, React$1.FC<WScreenProps>>;
12
+ declare const extendWScreens: (newWScreens: Record<string, React$1.FC<WScreenProps>>) => void;
12
13
 
13
14
  interface ClientSideProps extends RenderCellProps<any, any> {
14
15
  fieldDefinition: FieldDefinition;
@@ -25,18 +26,31 @@ type ResultComponentMap = {
25
26
  [key: string]: React$1.FC<ResultOkProps>;
26
27
  };
27
28
  declare let resultsOk: ResultComponentMap;
29
+ declare const extendResultsOk: (newComponents: ResultComponentMap) => void;
28
30
 
29
- interface FrontendPlusReactRoutesProps {
31
+ interface RoutesProps {
30
32
  myRoutes?: React$1.ReactNode;
31
- }
32
- declare function FrontendPlusReactRoutes({ myRoutes }: FrontendPlusReactRoutesProps): react_jsx_runtime.JSX.Element;
33
+ myUnloggedRoutes?: React$1.ReactNode;
34
+ layout?: React$1.ComponentType;
35
+ unloggedLayout?: React$1.ComponentType;
36
+ }
37
+ declare function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout, unloggedLayout: UnloggedLayout }: RoutesProps): react_jsx_runtime.JSX.Element;
38
+ type WScreenMap = Record<string, React$1.FC<WScreenProps>>;
39
+ type ClientSidesMap = Record<string, React$1.FC<ClientSideProps>>;
40
+ type ResultsOksMap = Record<string, React$1.FC<ResultOkProps>>;
33
41
  interface AppProps {
34
42
  myRoutes?: React$1.ReactNode;
35
- myWScreens?: Record<string, React$1.FC<WScreenProps>>;
36
- myClientSides?: Record<string, React$1.FC<ClientSideProps>>;
37
- myResultsOk?: Record<string, React$1.FC<ResultOkProps>>;
38
- }
39
- declare const App: ({ myRoutes, myWScreens, myClientSides, myResultsOk }: AppProps) => react_jsx_runtime.JSX.Element;
43
+ myUnloggedRoutes?: React$1.ReactNode;
44
+ unloggedLayout?: React$1.ComponentType;
45
+ myWScreens?: WScreenMap;
46
+ myClientSides?: ClientSidesMap;
47
+ myResultsOk?: ResultsOksMap;
48
+ }
49
+ declare const FrontendPlusProviders: React$1.FC<{
50
+ children: React$1.ReactNode;
51
+ publicPaths: string[];
52
+ }>;
53
+ declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk }: AppProps) => react_jsx_runtime.JSX.Element;
40
54
 
41
55
  interface CellFeedback {
42
56
  rowId: string;
@@ -107,9 +121,11 @@ interface AppContextType {
107
121
  checkSession: () => Promise<void>;
108
122
  showSessionExpiredMessage: boolean;
109
123
  setShowSessionExpiredMessage: (show: boolean) => void;
124
+ handleExpiredSessionRedirect: () => void;
110
125
  }
111
126
  interface AppProviderProps {
112
127
  children: ReactNode;
128
+ publicPaths?: string[];
113
129
  }
114
130
  interface PrivateRouteProps {
115
131
  children: ReactNode;
@@ -184,10 +200,12 @@ declare const useApp: () => {
184
200
  checkSession: () => Promise<void>;
185
201
  showSessionExpiredMessage: boolean;
186
202
  setShowSessionExpiredMessage: (show: boolean) => void;
203
+ handleExpiredSessionRedirect: () => void;
187
204
  };
188
205
  declare const AppProvider: React$1.FC<AppProviderProps>;
189
206
 
190
207
  declare const useApiCall: <T = any>() => UseApiCallResult<T>;
208
+ declare const useApiCallWithoutSnackbar: <T = any>() => UseApiCallResult<T>;
191
209
 
192
210
  /**
193
211
  * Hook personalizado para manejar la lógica de cierre de sesión.
@@ -198,4 +216,4 @@ declare const useLogout: () => () => Promise<void>;
198
216
 
199
217
  declare const cambiarGuionesBajosPorEspacios: (texto: string) => string;
200
218
 
201
- export { App, type AppContextType, type AppProps, AppProvider, type AppProviderProps, type CellFeedback, type CellFeedbackMap, type ClientContextState, ConfirmDialog, type ConfirmDialogProps, type CustomCellProps, type CustomHeaderCellProps, type FetchApiOptions, type FilterRendererProps, type FixedField, FrontendPlusReactRoutes, GenericDataGrid, type GenericDataGridForDetailProps, type GenericDataGridProps$1 as GenericDataGridProps, type InputRendererProps, MainLayout, type MenuListItemProps, type MenuUiState, type PrivateRouteProps, type RouterState, type SideMenuProps, type SnackbarContextType, SnackbarProvider, type SnackbarProviderProps, type SnackbarState, type UseApiCallResult, cambiarGuionesBajosPorEspacios, clientSides, extendClientSides, resultsOk as resultComponents, useApiCall, useApp, useLogout, useSnackbar, wScreens };
219
+ export { App, type AppContextType, type AppProps, AppProvider, type AppProviderProps, type CellFeedback, type CellFeedbackMap, type ClientContextState, type ClientSideProps, type ClientSidesMap, ConfirmDialog, type ConfirmDialogProps, type CustomCellProps, type CustomHeaderCellProps, type FetchApiOptions, type FilterRendererProps, type FixedField, FrontendPlusProviders, FrontendPlusReactRoutes, GenericDataGrid, type GenericDataGridForDetailProps, type GenericDataGridProps$1 as GenericDataGridProps, type InputRendererProps, MainLayout, type MenuListItemProps, type MenuUiState, type PrivateRouteProps, type ResultOkProps, type ResultsOksMap, type RouterState, type SideMenuProps, type SnackbarContextType, SnackbarProvider, type SnackbarProviderProps, type SnackbarState, type UseApiCallResult, type WScreenMap, type WScreenProps, cambiarGuionesBajosPorEspacios, clientSides, extendClientSides, extendResultsOk, extendWScreens, resultsOk as resultComponents, useApiCall, useApiCallWithoutSnackbar, useApp, useLogout, useSnackbar, wScreens };
package/dist/index.js CHANGED
@@ -757,12 +757,9 @@ var useApiCall = () => {
757
757
  const { showSnackbar } = useSnackbar();
758
758
  const [loading, setLoading] = useState2(false);
759
759
  const [error, setError] = useState2(null);
760
- const callApi = useCallback2(async (procedureName, params, opts) => {
760
+ const callApi = useCallback2(async (procedureName, params) => {
761
761
  setLoading(true);
762
762
  setError(null);
763
- const defaultOpts = { ...{
764
- reportOnSnackbar: true
765
- }, ...opts };
766
763
  try {
767
764
  const result = await executeBackendProcedure(procedureName, params);
768
765
  return result === null ? void 0 : result;
@@ -774,9 +771,7 @@ var useApiCall = () => {
774
771
  } else if (err instanceof Error) {
775
772
  snackbarMessage = err.message;
776
773
  }
777
- if (defaultOpts.reportOnSnackbar) {
778
- showSnackbar(snackbarMessage, "error");
779
- }
774
+ showSnackbar(snackbarMessage, "error");
780
775
  throw err;
781
776
  } finally {
782
777
  setLoading(false);
@@ -784,6 +779,25 @@ var useApiCall = () => {
784
779
  }, [showSnackbar]);
785
780
  return { callApi, loading, error };
786
781
  };
782
+ var useApiCallWithoutSnackbar = () => {
783
+ const [loading, setLoading] = useState2(false);
784
+ const [error, setError] = useState2(null);
785
+ const callApi = useCallback2(async (procedureName, params) => {
786
+ setLoading(true);
787
+ setError(null);
788
+ try {
789
+ const result = await executeBackendProcedure(procedureName, params);
790
+ return result === null ? void 0 : result;
791
+ } catch (err) {
792
+ setError(err);
793
+ console.error(`Error en la llamada API (WithoutSnackbar) para ${procedureName}:`, err);
794
+ throw err;
795
+ } finally {
796
+ setLoading(false);
797
+ }
798
+ }, []);
799
+ return { callApi, loading, error };
800
+ };
787
801
 
788
802
  // src/components/grid/GenericDataGrid.tsx
789
803
  import { CircularProgress as CircularProgress2, Typography as Typography5, Box as Box8, Alert, useTheme as useTheme3 } from "@mui/material";
@@ -2513,8 +2527,8 @@ var GenericDataGrid = ({
2513
2527
  var GenericDataGrid_default = GenericDataGrid;
2514
2528
 
2515
2529
  // src/App.tsx
2516
- import React11, { useEffect as useEffect7 } from "react";
2517
- import { BrowserRouter, Routes, Route, useLocation as useLocation4, Navigate as Navigate2 } from "react-router-dom";
2530
+ import React12, { useEffect as useEffect7 } from "react";
2531
+ import { BrowserRouter, Routes, Route, useLocation as useLocation5, Navigate as Navigate2, Outlet as Outlet2 } from "react-router-dom";
2518
2532
 
2519
2533
  // src/components/MainLayout.tsx
2520
2534
  import { useEffect as useEffect3 } from "react";
@@ -2533,8 +2547,8 @@ import {
2533
2547
  } from "@mui/material";
2534
2548
 
2535
2549
  // src/contexts/AppContext.tsx
2536
- import { createContext as createContext2, useContext as useContext2, useState as useState6, useEffect as useEffect2, useCallback as useCallback5, useMemo as useMemo3 } from "react";
2537
- import { useNavigate } from "react-router-dom";
2550
+ import { createContext as createContext2, useContext as useContext2, useState as useState6, useEffect as useEffect2, useCallback as useCallback5, useMemo as useMemo3, useRef as useRef2 } from "react";
2551
+ import { useLocation, useNavigate } from "react-router-dom";
2538
2552
  import { useSelector as useSelector2, useDispatch as useDispatch2 } from "react-redux";
2539
2553
  import { jsx as jsx15 } from "react/jsx-runtime";
2540
2554
  var AuthContext = createContext2(void 0);
@@ -2546,16 +2560,33 @@ var useApp = () => {
2546
2560
  const clientContext = useSelector2((state) => state.clientContext);
2547
2561
  return { ...context, clientContext };
2548
2562
  };
2549
- var AppProvider = ({ children }) => {
2563
+ var AppProvider = ({ children, publicPaths = [] }) => {
2550
2564
  console.log("AppProvider rendered/re-rendered");
2551
2565
  const [isLoggedIn, setIsLoggedIn] = useState6(false);
2552
2566
  const [showSessionExpiredMessage, setShowSessionExpiredMessage] = useState6(false);
2567
+ const isRedirectingRef = useRef2(false);
2553
2568
  const dispatch = useDispatch2();
2554
2569
  const clientContext = useSelector2((state) => state.clientContext);
2555
2570
  const navigate = useNavigate();
2571
+ const handleExpiredSessionRedirect = useCallback5(() => {
2572
+ isRedirectingRef.current = true;
2573
+ setShowSessionExpiredMessage(false);
2574
+ setIsLoggedIn(false);
2575
+ navigate("/login", { replace: true });
2576
+ setTimeout(() => {
2577
+ isRedirectingRef.current = false;
2578
+ }, 2e3);
2579
+ }, [navigate]);
2580
+ const location = useLocation();
2581
+ const isCurrentPathPublic = useCallback5(() => {
2582
+ const current = location.pathname;
2583
+ return publicPaths.some((path) => current === path || current.startsWith(`${path}/`));
2584
+ }, [location.pathname, publicPaths]);
2556
2585
  const checkSession = useCallback5(async () => {
2586
+ if (isRedirectingRef.current) return;
2557
2587
  try {
2558
2588
  const response = await fetchApi("/keep-alive.json", { method: "GET" });
2589
+ if (isRedirectingRef.current) return;
2559
2590
  if (response.ok) {
2560
2591
  setIsLoggedIn(true);
2561
2592
  setShowSessionExpiredMessage(false);
@@ -2571,15 +2602,19 @@ var AppProvider = ({ children }) => {
2571
2602
  } else {
2572
2603
  setIsLoggedIn(false);
2573
2604
  dispatch(clearClientContext());
2574
- if (!showSessionExpiredMessage && window.location.pathname !== "/login") {
2605
+ if (!showSessionExpiredMessage && !isCurrentPathPublic()) {
2606
+ console.warn("Sesi\xF3n inv\xE1lida en ruta protegida. Mostrando modal.");
2575
2607
  setShowSessionExpiredMessage(true);
2608
+ } else {
2609
+ console.log("Sesi\xF3n inv\xE1lida, pero estamos en ruta p\xFAblica. Todo bien.");
2576
2610
  }
2577
2611
  }
2578
2612
  } catch (error) {
2579
2613
  console.error("Error checking session:", error);
2580
2614
  setIsLoggedIn(false);
2581
2615
  dispatch(clearClientContext());
2582
- if (!showSessionExpiredMessage && window.location.pathname !== "/login") {
2616
+ const isPublic = publicPaths.some((p) => location.pathname === p || location.pathname.startsWith(p + "/"));
2617
+ if (!showSessionExpiredMessage && !isCurrentPathPublic()) {
2583
2618
  setShowSessionExpiredMessage(true);
2584
2619
  }
2585
2620
  }
@@ -2596,13 +2631,15 @@ var AppProvider = ({ children }) => {
2596
2631
  setIsLoggedIn,
2597
2632
  checkSession,
2598
2633
  showSessionExpiredMessage,
2599
- setShowSessionExpiredMessage
2634
+ setShowSessionExpiredMessage,
2635
+ handleExpiredSessionRedirect
2600
2636
  }), [
2601
2637
  isLoggedIn,
2602
2638
  setIsLoggedIn,
2603
2639
  checkSession,
2604
2640
  showSessionExpiredMessage,
2605
- setShowSessionExpiredMessage
2641
+ setShowSessionExpiredMessage,
2642
+ handleExpiredSessionRedirect
2606
2643
  ]);
2607
2644
  return /* @__PURE__ */ jsx15(AuthContext.Provider, { value: authContextValue, children });
2608
2645
  };
@@ -2624,7 +2661,7 @@ import WarningAmberIcon3 from "@mui/icons-material/WarningAmber";
2624
2661
  import DesktopWindowsIcon from "@mui/icons-material/DesktopWindows";
2625
2662
  import UnfoldMoreIcon from "@mui/icons-material/UnfoldMore";
2626
2663
  import UnfoldLessIcon from "@mui/icons-material/UnfoldLess";
2627
- import { useNavigate as useNavigate2, useLocation } from "react-router-dom";
2664
+ import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
2628
2665
  import { blue, orange, teal, red, grey } from "@mui/material/colors";
2629
2666
 
2630
2667
  // src/pages/WScreens.tsx
@@ -2668,7 +2705,7 @@ var extendWScreens = (newWScreens) => {
2668
2705
  import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
2669
2706
  var MenuListItem = ({ item, level, onMenuItemClick }) => {
2670
2707
  const navigate = useNavigate2();
2671
- const location = useLocation();
2708
+ const location = useLocation2();
2672
2709
  const open = useSubMenuOpenState(item.name);
2673
2710
  const dispatch = useAppDispatch();
2674
2711
  const handleClick = () => {
@@ -2756,7 +2793,7 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
2756
2793
  var SideMenu = ({ onMenuItemClick }) => {
2757
2794
  const { clientContext } = useApp();
2758
2795
  const navigate = useNavigate2();
2759
- const location = useLocation();
2796
+ const location = useLocation2();
2760
2797
  const dispatch = useAppDispatch();
2761
2798
  const subMenuOpenStates = useAppSelector((state) => state.menuUi.subMenuOpenStates);
2762
2799
  const allSubMenusKeys = Object.keys(subMenuOpenStates);
@@ -2977,7 +3014,6 @@ var MainLayout_default = MainLayout;
2977
3014
 
2978
3015
  // src/components/SessionExpiredMessage.tsx
2979
3016
  import { Box as Box12, Typography as Typography9, Button as Button5, Modal } from "@mui/material";
2980
- import { useNavigate as useNavigate4 } from "react-router-dom";
2981
3017
  import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
2982
3018
  var style = {
2983
3019
  position: "absolute",
@@ -2993,12 +3029,9 @@ var style = {
2993
3029
  borderRadius: 2
2994
3030
  };
2995
3031
  var SessionExpiredMessage = () => {
2996
- const { showSessionExpiredMessage, setShowSessionExpiredMessage, setIsLoggedIn } = useApp();
2997
- const navigate = useNavigate4();
3032
+ const { showSessionExpiredMessage, setShowSessionExpiredMessage, setIsLoggedIn, handleExpiredSessionRedirect } = useApp();
2998
3033
  const handleClose = () => {
2999
- setShowSessionExpiredMessage(false);
3000
- setIsLoggedIn(false);
3001
- navigate("/login", { replace: true });
3034
+ handleExpiredSessionRedirect();
3002
3035
  };
3003
3036
  return /* @__PURE__ */ jsx19(
3004
3037
  Modal,
@@ -3071,7 +3104,7 @@ import { Button as Button6, TextField, Typography as Typography12, Alert as Aler
3071
3104
  import { useForm, Controller } from "react-hook-form";
3072
3105
  import { zodResolver } from "@hookform/resolvers/zod";
3073
3106
  import * as z from "zod";
3074
- import { useNavigate as useNavigate5 } from "react-router-dom";
3107
+ import { useNavigate as useNavigate4 } from "react-router-dom";
3075
3108
  import { useDispatch as useDispatch4 } from "react-redux";
3076
3109
  import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
3077
3110
  var loginSchema = z.object({
@@ -3081,7 +3114,7 @@ var loginSchema = z.object({
3081
3114
  // Añadir validación básica
3082
3115
  });
3083
3116
  var LoginPage = () => {
3084
- const navigate = useNavigate5();
3117
+ const navigate = useNavigate4();
3085
3118
  const [loginError, setLoginError] = useState7(null);
3086
3119
  const [isSubmitting, setIsSubmitting] = useState7(false);
3087
3120
  const { setIsLoggedIn, checkSession } = useApp();
@@ -3681,10 +3714,10 @@ import { PersistGate } from "redux-persist/integration/react";
3681
3714
 
3682
3715
  // src/components/PrivateRoute.tsx
3683
3716
  import { useEffect as useEffect5 } from "react";
3684
- import { Navigate, useLocation as useLocation2 } from "react-router-dom";
3717
+ import { Navigate, useLocation as useLocation3 } from "react-router-dom";
3685
3718
  import { Fragment as Fragment4, jsx as jsx25 } from "react/jsx-runtime";
3686
3719
  var PrivateRoute = ({ children }) => {
3687
- const location = useLocation2();
3720
+ const location = useLocation3();
3688
3721
  const dispatch = useAppDispatch();
3689
3722
  const clientContextStatus = useClientContextStatus();
3690
3723
  const isAuthenticated = clientContextStatus === "succeeded";
@@ -3719,10 +3752,10 @@ var PrivateRoute_default = PrivateRoute;
3719
3752
 
3720
3753
  // src/components/InitialRedirectHandler.tsx
3721
3754
  import { useEffect as useEffect6 } from "react";
3722
- import { useLocation as useLocation3, useNavigate as useNavigate6 } from "react-router-dom";
3755
+ import { useLocation as useLocation4, useNavigate as useNavigate5 } from "react-router-dom";
3723
3756
  var InitialRedirectHandler = () => {
3724
- const location = useLocation3();
3725
- const navigate = useNavigate6();
3757
+ const location = useLocation4();
3758
+ const navigate = useNavigate5();
3726
3759
  const dispatch = useAppDispatch();
3727
3760
  const redirectPath = useRedirectPath();
3728
3761
  const clientContextStatus = useClientContextStatus();
@@ -3824,22 +3857,43 @@ var MenuTablePage_default = MenuTablePage;
3824
3857
 
3825
3858
  // src/App.tsx
3826
3859
  import { Box as Box20 } from "@mui/material";
3860
+
3861
+ // src/utils/routeUtils.ts
3862
+ import { Children, isValidElement } from "react";
3863
+ var extractPathsFromRoutes = (node) => {
3864
+ const paths = [];
3865
+ Children.forEach(node, (child) => {
3866
+ if (!isValidElement(child)) return;
3867
+ if (child.props.path) {
3868
+ paths.push(child.props.path);
3869
+ }
3870
+ if (child.props.children) {
3871
+ paths.push(...extractPathsFromRoutes(child.props.children));
3872
+ }
3873
+ });
3874
+ return paths;
3875
+ };
3876
+
3877
+ // src/App.tsx
3827
3878
  import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
3828
3879
  var LocationTracker = () => {
3829
- const location = useLocation4();
3880
+ const location = useLocation5();
3830
3881
  const dispatch = useAppDispatch();
3831
3882
  useEffect7(() => {
3832
3883
  dispatch(setCurrentPath(location.pathname + location.search));
3833
3884
  }, [location, dispatch]);
3834
3885
  return null;
3835
3886
  };
3836
- function FrontendPlusReactRoutes({ myRoutes }) {
3887
+ function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout = MainLayout_default, unloggedLayout: UnloggedLayout }) {
3837
3888
  return /* @__PURE__ */ jsxs18(Routes, { children: [
3838
- /* @__PURE__ */ jsx28(Route, { path: "/login", element: /* @__PURE__ */ jsx28(LoginPage_default, {}) }),
3839
- /* @__PURE__ */ jsx28(Route, { path: "/logout", element: /* @__PURE__ */ jsx28(LogoutPage_default, {}) }),
3889
+ /* @__PURE__ */ jsxs18(Route, { element: UnloggedLayout ? /* @__PURE__ */ jsx28(UnloggedLayout, {}) : /* @__PURE__ */ jsx28(Outlet2, {}), children: [
3890
+ /* @__PURE__ */ jsx28(Route, { path: "/login", element: /* @__PURE__ */ jsx28(LoginPage_default, {}) }),
3891
+ /* @__PURE__ */ jsx28(Route, { path: "/logout", element: /* @__PURE__ */ jsx28(LogoutPage_default, {}) }),
3892
+ myUnloggedRoutes
3893
+ ] }),
3840
3894
  /* @__PURE__ */ jsxs18(Route, { element: /* @__PURE__ */ jsxs18(PrivateRoute_default, { children: [
3841
3895
  /* @__PURE__ */ jsx28(InitialRedirectHandler_default, {}),
3842
- /* @__PURE__ */ jsx28(MainLayout_default, {})
3896
+ /* @__PURE__ */ jsx28(Layout, {})
3843
3897
  ] }), children: [
3844
3898
  /* @__PURE__ */ jsx28(Route, { path: "/", element: /* @__PURE__ */ jsx28(HomePage_default, {}) }),
3845
3899
  /* @__PURE__ */ jsx28(Route, { path: "/home", element: /* @__PURE__ */ jsx28(HomePage_default, {}) }),
@@ -3850,12 +3904,12 @@ function FrontendPlusReactRoutes({ myRoutes }) {
3850
3904
  Route,
3851
3905
  {
3852
3906
  path: `/wScreens/${screenName}`,
3853
- element: React11.createElement(
3907
+ element: React12.createElement(
3854
3908
  Box20,
3855
3909
  {
3856
3910
  sx: { pt: 3, pl: 4 }
3857
3911
  },
3858
- React11.createElement(wScreens[screenName], { screenName })
3912
+ React12.createElement(wScreens[screenName], { screenName })
3859
3913
  )
3860
3914
  },
3861
3915
  screenName
@@ -3867,14 +3921,26 @@ function FrontendPlusReactRoutes({ myRoutes }) {
3867
3921
  element: /* @__PURE__ */ jsx28(Box20, { sx: { p: 3 }, children: /* @__PURE__ */ jsx28(FallbackWScreen, { screenName: ":screenName" }) })
3868
3922
  }
3869
3923
  ),
3924
+ myRoutes,
3870
3925
  /* @__PURE__ */ jsx28(Route, { path: "*", element: /* @__PURE__ */ jsx28("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
3871
3926
  ] }),
3872
- myRoutes,
3873
3927
  /* @__PURE__ */ jsx28(Route, { path: "*", element: /* @__PURE__ */ jsx28(Navigate2, { to: "/", replace: true }) })
3874
3928
  ] });
3875
3929
  }
3930
+ var FrontendPlusProviders = ({ children, publicPaths }) => {
3931
+ return /* @__PURE__ */ jsx28(Provider, { store, children: /* @__PURE__ */ jsx28(PersistGate, { loading: null, persistor, children: /* @__PURE__ */ jsxs18(BrowserRouter, { children: [
3932
+ /* @__PURE__ */ jsx28(LocationTracker, {}),
3933
+ " ",
3934
+ /* @__PURE__ */ jsx28(AppProvider, { publicPaths, children: /* @__PURE__ */ jsxs18(SnackbarProvider, { children: [
3935
+ children,
3936
+ /* @__PURE__ */ jsx28(SessionExpiredMessage_default, {})
3937
+ ] }) })
3938
+ ] }) }) });
3939
+ };
3876
3940
  var App = ({
3877
3941
  myRoutes,
3942
+ myUnloggedRoutes,
3943
+ unloggedLayout,
3878
3944
  myWScreens,
3879
3945
  myClientSides,
3880
3946
  myResultsOk
@@ -3890,24 +3956,25 @@ var App = ({
3890
3956
  extendWScreens(myWScreens);
3891
3957
  }
3892
3958
  }, [myClientSides, myResultsOk, myWScreens]);
3893
- return /* @__PURE__ */ jsx28(Provider, { store, children: /* @__PURE__ */ jsx28(PersistGate, { loading: null, persistor, children: /* @__PURE__ */ jsxs18(BrowserRouter, { children: [
3894
- /* @__PURE__ */ jsx28(LocationTracker, {}),
3895
- /* @__PURE__ */ jsx28(AppProvider, { children: /* @__PURE__ */ jsxs18(SnackbarProvider, { children: [
3896
- /* @__PURE__ */ jsx28(
3897
- FrontendPlusReactRoutes,
3898
- {
3899
- myRoutes
3900
- }
3901
- ),
3902
- /* @__PURE__ */ jsx28(SessionExpiredMessage_default, {})
3903
- ] }) })
3904
- ] }) }) });
3959
+ const safePaths = React12.useMemo(() => {
3960
+ const extracted = extractPathsFromRoutes(myUnloggedRoutes);
3961
+ return ["/login", "/logout", ...extracted];
3962
+ }, [myUnloggedRoutes]);
3963
+ return /* @__PURE__ */ jsx28(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ jsx28(
3964
+ FrontendPlusReactRoutes,
3965
+ {
3966
+ myRoutes,
3967
+ myUnloggedRoutes,
3968
+ unloggedLayout
3969
+ }
3970
+ ) });
3905
3971
  };
3906
3972
  var App_default = App;
3907
3973
  export {
3908
3974
  App_default as App,
3909
3975
  AppProvider,
3910
3976
  ConfirmDialog,
3977
+ FrontendPlusProviders,
3911
3978
  FrontendPlusReactRoutes,
3912
3979
  GenericDataGrid_default as GenericDataGrid,
3913
3980
  MainLayout_default as MainLayout,
@@ -3915,8 +3982,11 @@ export {
3915
3982
  cambiarGuionesBajosPorEspacios,
3916
3983
  clientSides,
3917
3984
  extendClientSides,
3985
+ extendResultsOk,
3986
+ extendWScreens,
3918
3987
  resultsOk as resultComponents,
3919
3988
  useApiCall,
3989
+ useApiCallWithoutSnackbar,
3920
3990
  useApp,
3921
3991
  useLogout_default as useLogout,
3922
3992
  useSnackbar,