/* * Copyright 2021-2025 Avaiga Private Limited * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ import React, { useEffect, useReducer, useState } from "react"; import axios from "axios"; import Box from "@mui/material/Box"; import CircularProgress from "@mui/material/CircularProgress"; import CssBaseline from "@mui/material/CssBaseline"; import { ThemeProvider } from "@mui/system"; import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFnsV3"; import { SnackbarProvider } from "notistack"; import { HelmetProvider } from "react-helmet-async"; import { BrowserRouter, Route, Routes } from "react-router"; import { ErrorBoundary } from "react-error-boundary"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import { PageContext, TaipyContext } from "../context/taipyContext"; import { createBlockAction, createSetLocationsAction, initializeWebSocket, INITIAL_STATE, retrieveBlockUi, taipyInitialize, taipyReducer, } from "../context/taipyReducers"; import UIBlocker from "./Taipy/UIBlocker"; import Navigate from "./Taipy/Navigate"; import Menu from "./Taipy/Menu"; import TaipyNotification from "./Taipy/Notification"; import GuiDownload from "./Taipy/GuiDownload"; import ErrorFallback from "../utils/ErrorBoundary"; import MainPage from "./pages/MainPage"; import TaipyRendered from "./pages/TaipyRendered"; import NotFound404 from "./pages/NotFound404"; import { getBaseURL } from "../utils"; import { useLocalStorageWithEvent } from "../hooks"; interface AxiosRouter { router: string; locations: Record; blockUI: boolean; } const mainSx = { flexGrow: 1, bgcolor: "background.default" }; const containerSx = { display: "flex" }; const progressSx = { position: "fixed", bottom: "1em", right: "1em" }; const pageStore = {}; const Router = () => { const [state, dispatch] = useReducer(taipyReducer, INITIAL_STATE, taipyInitialize); const [routes, setRoutes] = useState>({}); const refresh = !!Object.keys(routes).length; const themeClass = "taipy-" + state.theme.palette.mode; const baseURL = getBaseURL(); useLocalStorageWithEvent(dispatch, state.id); useEffect(() => { if (refresh) { // no need to access the backend again, the routes are static return; } if (!state.isSocketConnected) { // initialize only when there is an existing ws connection // --> assuring that there is a session data scope on the backend return; } // Fetch Flask Rendered JSX React Router axios .get("taipy-init", { params: { client_id: state.id || "", v: window.taipyVersion } }) .then((result) => { dispatch(createSetLocationsAction(result.data.locations)); setRoutes(result.data.locations); result.data.blockUI && dispatch(createBlockAction(retrieveBlockUi())); }) .catch((error) => { // Fallback router if there is any error setRoutes({ "/": "/TaiPy_root_page" }); console.log(error); }); }, [refresh, state.isSocketConnected, state.id]); useEffect(() => { initializeWebSocket(state.socket, dispatch); }, [state.socket]); useEffect(() => { const classes = [themeClass]; document.body.classList.forEach((cls) => { if (!cls.startsWith("taipy-")) { classes.push(cls); } }); document.body.className = classes.join(" "); }, [themeClass]); return ( {Object.keys(routes).length ? ( path !== "/" )} /> } > {Object.entries(routes) .filter(([path]) => path !== "/") .map(([path, name]) => ( } /> ))} } /> ) : null} {state.ackList.length ? ( ) : null} ); }; export default Router;