From 38be01f506baeeeeb5a8cfc252e05df4db6a8c24 Mon Sep 17 00:00:00 2001 From: Fredrik Strand Oseberg Date: Wed, 25 Jan 2023 13:12:31 +0100 Subject: [PATCH] fix: redirect only happening on root path with replace (#2981) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a fix for overeager redirects, now we will redirect on the root path and replace on our redirects from login. Co-authored-by: Gastón Fournier --- frontend/src/component/App.tsx | 60 +++---------------- frontend/src/component/InitialRedirect.tsx | 39 ++++++++++++ .../__snapshots__/routes.test.tsx.snap | 7 --- frontend/src/component/menu/routes.ts | 7 --- .../src/component/user/DemoAuth/DemoAuth.tsx | 2 +- frontend/src/component/user/HostedAuth.tsx | 2 +- frontend/src/component/user/PasswordAuth.tsx | 2 +- .../component/user/SimpleAuth/SimpleAuth.tsx | 2 +- 8 files changed, 51 insertions(+), 70 deletions(-) create mode 100644 frontend/src/component/InitialRedirect.tsx diff --git a/frontend/src/component/App.tsx b/frontend/src/component/App.tsx index 4744827bf6..b32b9b8c47 100644 --- a/frontend/src/component/App.tsx +++ b/frontend/src/component/App.tsx @@ -1,5 +1,5 @@ -import { Suspense, useCallback, useEffect, useState, useRef } from 'react'; -import { Route, Routes, useNavigate } from 'react-router-dom'; +import { Suspense } from 'react'; +import { Route, Routes } from 'react-router-dom'; import { ErrorBoundary } from 'react-error-boundary'; import { Error } from 'component/layout/Error/Error'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; @@ -16,47 +16,10 @@ import { useAuthDetails } from 'hooks/api/getters/useAuth/useAuthDetails'; import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser'; import { SplashPageRedirect } from 'component/splash/SplashPageRedirect/SplashPageRedirect'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; -import useProjects from '../hooks/api/getters/useProjects/useProjects'; -import { useLastViewedProject } from '../hooks/useLastViewedProject'; + import MaintenanceBanner from './maintenance/MaintenanceBanner'; import { styled } from '@mui/material'; - -const InitialRedirect = () => { - const { lastViewed } = useLastViewedProject(); - const { projects, loading } = useProjects(); - const navigate = useNavigate(); - const ref = useRef<{ redirected: boolean }>({ redirected: false }); - - // Redirect based on project and last viewed - const getRedirect = useCallback(() => { - if (projects && lastViewed) { - return `/projects/${lastViewed}`; - } - - if (projects && !lastViewed && projects.length === 1) { - return `/projects/${projects[0].id}`; - } - - return '/projects'; - }, [lastViewed, projects]); - - const redirect = () => { - ref.current = { redirected: true }; - navigate(getRedirect(), { replace: true }); - }; - - useEffect(() => { - if (ref.current?.redirected === true) return; - - redirect(); - }, [getRedirect]); - - if (loading) { - return ; - } - - return <>; -}; +import { InitialRedirect } from './InitialRedirect'; const StyledContainer = styled('div')(() => ({ '& ul': { @@ -115,22 +78,15 @@ export const App = () => { } /> ))} + } + /> } /> - {/* Only redirect if we are not in test mode */} - } - /> diff --git a/frontend/src/component/InitialRedirect.tsx b/frontend/src/component/InitialRedirect.tsx new file mode 100644 index 0000000000..bad3d15768 --- /dev/null +++ b/frontend/src/component/InitialRedirect.tsx @@ -0,0 +1,39 @@ +import { useCallback, useEffect, useContext } from 'react'; +import { useNavigate } from 'react-router-dom'; +import useProjects from '../hooks/api/getters/useProjects/useProjects'; +import { useLastViewedProject } from '../hooks/useLastViewedProject'; +import UIContext from 'contexts/UIContext'; +import Loader from './common/Loader/Loader'; + +export const InitialRedirect = () => { + const { lastViewed } = useLastViewedProject(); + const { projects, loading } = useProjects(); + const navigate = useNavigate(); + + // Redirect based on project and last viewed + const getRedirect = useCallback(() => { + if (projects && lastViewed) { + return `/projects/${lastViewed}`; + } + + if (projects && !lastViewed && projects.length === 1) { + return `/projects/${projects[0].id}`; + } + + return '/projects'; + }, [lastViewed, projects]); + + const redirect = () => { + navigate(getRedirect(), { replace: true }); + }; + + useEffect(() => { + redirect(); + }, [getRedirect]); + + if (loading) { + return ; + } + + return null; +}; diff --git a/frontend/src/component/menu/__tests__/__snapshots__/routes.test.tsx.snap b/frontend/src/component/menu/__tests__/__snapshots__/routes.test.tsx.snap index 9408f17e41..5bb2a14ee6 100644 --- a/frontend/src/component/menu/__tests__/__snapshots__/routes.test.tsx.snap +++ b/frontend/src/component/menu/__tests__/__snapshots__/routes.test.tsx.snap @@ -2,13 +2,6 @@ exports[`returns all baseRoutes 1`] = ` [ - { - "component": [Function], - "menu": {}, - "path": "/", - "title": "Unleash", - "type": "protected", - }, { "component": [Function], "isStandalone": true, diff --git a/frontend/src/component/menu/routes.ts b/frontend/src/component/menu/routes.ts index febeecbb20..18fe253943 100644 --- a/frontend/src/component/menu/routes.ts +++ b/frontend/src/component/menu/routes.ts @@ -45,13 +45,6 @@ import { LazyProject } from 'component/project/Project/LazyProject'; import { AdminRedirect } from 'component/admin/AdminRedirect'; export const routes: IRoute[] = [ - { - path: '/', - title: 'Unleash', - component: ProjectListNew, - type: 'protected', - menu: {}, - }, // Splash { path: '/splash/:splashId', diff --git a/frontend/src/component/user/DemoAuth/DemoAuth.tsx b/frontend/src/component/user/DemoAuth/DemoAuth.tsx index f619f0cba2..d3bc1e8b8b 100644 --- a/frontend/src/component/user/DemoAuth/DemoAuth.tsx +++ b/frontend/src/component/user/DemoAuth/DemoAuth.tsx @@ -28,7 +28,7 @@ const DemoAuth: VFC = ({ authDetails, redirect }) => { try { await emailAuth(authDetails.path, email); refetchUser(); - navigate(redirect); + navigate(redirect, { replace: true }); } catch (error) { setToastApiError(formatUnknownError(error)); } diff --git a/frontend/src/component/user/HostedAuth.tsx b/frontend/src/component/user/HostedAuth.tsx index 5c3178fc00..1e9f77b760 100644 --- a/frontend/src/component/user/HostedAuth.tsx +++ b/frontend/src/component/user/HostedAuth.tsx @@ -71,7 +71,7 @@ const HostedAuth: VFC = ({ authDetails, redirect }) => { try { await passwordAuth(authDetails.path, username, password); refetchUser(); - navigate(redirect); + navigate(redirect, { replace: true }); } catch (error: any) { if ( error instanceof NotFoundError || diff --git a/frontend/src/component/user/PasswordAuth.tsx b/frontend/src/component/user/PasswordAuth.tsx index aec5cb365d..1eb945ecae 100644 --- a/frontend/src/component/user/PasswordAuth.tsx +++ b/frontend/src/component/user/PasswordAuth.tsx @@ -71,7 +71,7 @@ const PasswordAuth: VFC = ({ authDetails, redirect }) => { try { await passwordAuth(authDetails.path, username, password); refetchUser(); - navigate(redirect); + navigate(redirect, { replace: true }); } catch (error: any) { if ( error instanceof NotFoundError || diff --git a/frontend/src/component/user/SimpleAuth/SimpleAuth.tsx b/frontend/src/component/user/SimpleAuth/SimpleAuth.tsx index 3cb7078790..9568c41b1c 100644 --- a/frontend/src/component/user/SimpleAuth/SimpleAuth.tsx +++ b/frontend/src/component/user/SimpleAuth/SimpleAuth.tsx @@ -27,7 +27,7 @@ const SimpleAuth: VFC = ({ authDetails, redirect }) => { try { await emailAuth(authDetails.path, email); refetchUser(); - navigate(redirect); + navigate(redirect, { replace: true }); } catch (error) { setToastApiError(formatUnknownError(error)); }