diff --git a/frontend/src/modules/AppWrapper.tsx b/frontend/src/modules/AppWrapper.tsx index 17442bd495..11e53cd04d 100644 --- a/frontend/src/modules/AppWrapper.tsx +++ b/frontend/src/modules/AppWrapper.tsx @@ -17,6 +17,7 @@ import { SettingsPage, IntstrumentationPage, } from "Src/pages"; +import { RouteProvider } from "./RouteProvider"; const App = () => { const { status } = useThemeSwitcher(); @@ -30,42 +31,38 @@ const App = () => { }> - - - - - ( - - )} - /> - - - - - - { - return localStorage.getItem(IS_LOGGED_IN) === "yes" ? ( - - ) : ( - - ); - }} - /> - + + + + + + + + + + + + { + return localStorage.getItem(IS_LOGGED_IN) === "yes" ? ( + + ) : ( + + ); + }} + /> + + diff --git a/frontend/src/modules/BaseLayout.tsx b/frontend/src/modules/BaseLayout.tsx index a36ac96e66..43df370f49 100644 --- a/frontend/src/modules/BaseLayout.tsx +++ b/frontend/src/modules/BaseLayout.tsx @@ -1,15 +1,55 @@ -import React, { ReactNode } from "react"; +import React, { ReactNode, useEffect } from "react"; import { Layout } from "antd"; import SideNav from "./Nav/SideNav"; import TopNav from "./Nav/TopNav"; +import { useLocation } from "react-router-dom"; +import ROUTES from "Src/constants/routes"; +import { useRoute } from "./RouteProvider"; + const { Content, Footer } = Layout; interface BaseLayoutProps { children: ReactNode; } +interface RouteObj { + [key: string]: { + route: string; + isLoaded: boolean; + }; +} const BaseLayout: React.FC = ({ children }) => { + const location = useLocation(); + const { dispatch } = useRoute(); + + /* + Create a routes obj with values as + { + SERVICE_MAP: { + route: '/service-map', + isLoaded: false + } + */ + const routes: RouteObj = {}; + Object.keys(ROUTES).map((items) => { + routes[items] = { + route: `${ROUTES[items]}`, + isLoaded: false, + }; + }); + + useEffect(() => { + /* + Update the isLoaded property in routes obj + if the route matches the current pathname + */ + Object.keys(ROUTES).map((items) => { + routes[items].isLoaded = routes[items].route === location.pathname; + }); + dispatch({ type: "UPDATE", payload: routes }); + }, [location]); + return ( diff --git a/frontend/src/modules/RouteProvider.tsx b/frontend/src/modules/RouteProvider.tsx new file mode 100644 index 0000000000..2894e8fe3f --- /dev/null +++ b/frontend/src/modules/RouteProvider.tsx @@ -0,0 +1,51 @@ +import React, { useContext, createContext, ReactNode, Dispatch } from "react"; + +type State = { + [key: string]: { + route: string; + isLoaded: boolean; + }; +}; + +type Action = { + type: "UPDATE"; + payload: State; +}; + +interface ContextType { + state: State; + dispatch: Dispatch; +} + +const RouteContext = createContext(null); + +interface RouteProviderProps { + children: ReactNode; +} + +const updateLocation = (state: State, action: Action): State => { + if (action.type === "UPDATE") { + return { + ...state, + ...action.payload, + }; + } + return { + ...state, + }; +}; + +const RouteProvider: React.FC = ({ children }) => { + const [state, dispatch] = React.useReducer(updateLocation, {}); + const value = { state, dispatch }; + return {children}; +}; + +const useRoute = (): ContextType => { + const context = useContext(RouteContext); + if (context === undefined) { + throw new Error("useRoute must be used within a RouteProvider"); + } + return context as ContextType; +}; +export { RouteProvider, useRoute }; diff --git a/frontend/src/modules/Servicemap/ServiceMap.tsx b/frontend/src/modules/Servicemap/ServiceMap.tsx index 1e0ac23fba..8306a35ada 100644 --- a/frontend/src/modules/Servicemap/ServiceMap.tsx +++ b/frontend/src/modules/Servicemap/ServiceMap.tsx @@ -1,6 +1,6 @@ -import React, { useEffect, useRef } from "react"; +import React, { useContext, useEffect, useRef } from "react"; import { connect } from "react-redux"; -import { RouteComponentProps, useLocation } from "react-router-dom"; +import { RouteComponentProps } from "react-router-dom"; import { GlobalTime, serviceMapStore, @@ -14,6 +14,7 @@ import { StoreState } from "../../store/reducers"; import { getZoomPx, getGraphData, getTooltip, transformLabel } from "./utils"; import SelectService from "./SelectService"; import { ForceGraph2D } from "react-force-graph"; +import { useRoute } from "../RouteProvider"; const Container = styled.div` .force-graph-container .graph-tooltip { @@ -54,16 +55,17 @@ export interface graphDataType { const ServiceMap = (props: ServiceMapProps) => { const fgRef = useRef(); - const location = useLocation(); + const { state } = useRoute(); + const { getDetailedServiceMapItems, getServiceMapItems, globalTime, serviceMap, - componentPath, } = props; + useEffect(() => { - if (location.pathname === componentPath) { + if (state.SERVICE_MAP.isLoaded) { getServiceMapItems(globalTime); getDetailedServiceMapItems(globalTime); }