Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 83 additions & 24 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import MainContextProvider from "./contexts/mainContext";
import ProjectSheet from "./pages/projectSheet";
import DeploymentSheet from "./pages/deploymentSheet";
import DeviceMenuPage from "./pages/deviceMenu";
import DeviceSheet from "./components/deviceSheet/deviceSheetMain";
import DeviceSheetPage from "./pages/deviceSheet";
import { theme } from "./theme";
import { LinearProgress, ThemeProvider } from "@mui/material";
Expand All @@ -18,9 +17,9 @@ import SiteMenuPage from "./pages/siteMenu";
import SiteSheetPage from "./pages/siteSheet";
import SnackContextProvider from "./contexts/snackContext";
import { AuthContext } from "./contexts/AuthContextProvider";
import { useContext } from "react";
import { useContext} from "react";
import FilesContextProvider from "./contexts/filesContext";
;
import RouteWrapper from "./components/RouteWrapper";

// Env var processed by nginx
OpenAPI.BASE = window._env_.REACT_APP_API_PATH || "/api/v1";
Expand All @@ -39,43 +38,103 @@ function App() {
<I18nextProvider i18n={i18n}>
<BrowserRouter>
<Routes>
<Route path="/" element={<Main />}></Route>
{/* <Route path="/project/:projectId" element={<Project />}></Route> */}
<Route
path="/"
element={
<RouteWrapper>
<Main />
</RouteWrapper>
}
/>
{/* <Route path="/project/:projectId" element={<Project />} /> */}
<Route
path="/project/:projectId"
element={<ProjectSheet />}
></Route>
<Route path="/sites/" element={<SiteMenuPage />}></Route>
<Route path="/devices/" element={<DeviceMenuPage />}></Route>
element={
<RouteWrapper>
<ProjectSheet />
</RouteWrapper>
}
/>
<Route
path="/sites/"
element={
<RouteWrapper>
<SiteMenuPage />
</RouteWrapper>
}
/>
<Route
path="/devices/"
element={
<RouteWrapper>
<DeviceMenuPage />
</RouteWrapper>
}
/>
<Route
path="/devices/:deviceId"
element={<DeviceSheetPage />}
></Route>
element={
<RouteWrapper>
<DeviceSheetPage />
</RouteWrapper>
}
/>
<Route
path="/sites/:siteId"
element={<SiteSheetPage />}
></Route>
element={
<RouteWrapper>
<SiteSheetPage />
</RouteWrapper>
}
/>
<Route
path="deployment/:deploymentId"
element={<Deployment />}
></Route>
element={
<RouteWrapper>
<Deployment />
</RouteWrapper>
}
/>
<Route
path="/project/:projectId/deployment/:deploymentId/details"
element={<DeploymentSheet number={0} />}
></Route>
element={
<RouteWrapper>
<DeploymentSheet number={0} />
</RouteWrapper>
}
/>
<Route
path="/project/:projectId/deployment/:deploymentId/medias"
element={<DeploymentSheet number={1} />}
></Route>
element={
<RouteWrapper>
<DeploymentSheet number={1} />
</RouteWrapper>
}
/>
<Route
path="/project/:projectId/deployment/:deploymentId/medias/:imageId"
element={<Annotation />}
></Route>
element={
<RouteWrapper>
<Annotation />
</RouteWrapper>
}
/>
<Route
path="/project/:projectId/deployment/:deploymentId/details/:imageId"
element={<Annotation />}
></Route>
<Route path="*" element={<Main />}></Route>
element={
<RouteWrapper>
<Annotation />
</RouteWrapper>
}
/>
<Route
path="*"
element={
<RouteWrapper>
<Main />
</RouteWrapper>
}
/>
</Routes>
</BrowserRouter>
</I18nextProvider>
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/components/RouteWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useRefreshToken } from "../hooks/useRefreshToken";

/**
* A wrapper around the element rendered by the React Router <Route> component.
*
* Useful to trigger code when the route changes.
*/
const RouteWrapper = ({children}: {children: React.ReactNode}) => {
useRefreshToken();

return (
<>{children}</>
);
}

export default RouteWrapper;
40 changes: 40 additions & 0 deletions frontend/src/hooks/useRefreshToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useState, useEffect, useContext } from 'react';
import { useLocation } from 'react-router-dom';

import { OpenAPI } from '../client';
import { AuthContext } from '../contexts/AuthContextProvider';
import keycloak from '../keycloak';;


const TOKEN_MIN_VALIDITY = 120;


export const useRefreshToken = () => {
const [pending, setPending] = useState(true);
const location = useLocation();
const { logout } = useContext(AuthContext);

const onTokenRefresh = (token: string | undefined) => {
if (token) {
OpenAPI.TOKEN = token;
}
}

useEffect(() => {
const refreshToken = async () => {
try {
const refreshed = await keycloak.updateToken(TOKEN_MIN_VALIDITY);
if (refreshed) {
onTokenRefresh(keycloak.token);
}
setPending(false);
} catch (error) {
logout();
}
}

refreshToken();
}, [location]);

return { pending };
};