mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-24 17:51:14 +02:00
fix: redirect only happening on root path with replace (#2981)
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 <gaston@getunleash.ai>
This commit is contained in:
parent
99f45b4248
commit
38be01f506
@ -1,5 +1,5 @@
|
|||||||
import { Suspense, useCallback, useEffect, useState, useRef } from 'react';
|
import { Suspense } from 'react';
|
||||||
import { Route, Routes, useNavigate } from 'react-router-dom';
|
import { Route, Routes } from 'react-router-dom';
|
||||||
import { ErrorBoundary } from 'react-error-boundary';
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
import { Error } from 'component/layout/Error/Error';
|
import { Error } from 'component/layout/Error/Error';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
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 { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser';
|
||||||
import { SplashPageRedirect } from 'component/splash/SplashPageRedirect/SplashPageRedirect';
|
import { SplashPageRedirect } from 'component/splash/SplashPageRedirect/SplashPageRedirect';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
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 MaintenanceBanner from './maintenance/MaintenanceBanner';
|
||||||
import { styled } from '@mui/material';
|
import { styled } from '@mui/material';
|
||||||
|
import { InitialRedirect } from './InitialRedirect';
|
||||||
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 <Loader />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const StyledContainer = styled('div')(() => ({
|
const StyledContainer = styled('div')(() => ({
|
||||||
'& ul': {
|
'& ul': {
|
||||||
@ -115,22 +78,15 @@ export const App = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
<Route
|
||||||
|
path="/"
|
||||||
|
element={<InitialRedirect />}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="*"
|
path="*"
|
||||||
element={<NotFound />}
|
element={<NotFound />}
|
||||||
/>
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
{/* Only redirect if we are not in test mode */}
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={
|
|
||||||
!(
|
|
||||||
import.meta.env
|
|
||||||
.VITE_TEST_REDIRECT ===
|
|
||||||
'true'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
show={<InitialRedirect />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FeedbackNPS openUrl="http://feedback.unleash.run" />
|
<FeedbackNPS openUrl="http://feedback.unleash.run" />
|
||||||
|
|
||||||
|
39
frontend/src/component/InitialRedirect.tsx
Normal file
39
frontend/src/component/InitialRedirect.tsx
Normal file
@ -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 <Loader />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
@ -2,13 +2,6 @@
|
|||||||
|
|
||||||
exports[`returns all baseRoutes 1`] = `
|
exports[`returns all baseRoutes 1`] = `
|
||||||
[
|
[
|
||||||
{
|
|
||||||
"component": [Function],
|
|
||||||
"menu": {},
|
|
||||||
"path": "/",
|
|
||||||
"title": "Unleash",
|
|
||||||
"type": "protected",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"isStandalone": true,
|
"isStandalone": true,
|
||||||
|
@ -45,13 +45,6 @@ import { LazyProject } from 'component/project/Project/LazyProject';
|
|||||||
import { AdminRedirect } from 'component/admin/AdminRedirect';
|
import { AdminRedirect } from 'component/admin/AdminRedirect';
|
||||||
|
|
||||||
export const routes: IRoute[] = [
|
export const routes: IRoute[] = [
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
title: 'Unleash',
|
|
||||||
component: ProjectListNew,
|
|
||||||
type: 'protected',
|
|
||||||
menu: {},
|
|
||||||
},
|
|
||||||
// Splash
|
// Splash
|
||||||
{
|
{
|
||||||
path: '/splash/:splashId',
|
path: '/splash/:splashId',
|
||||||
|
@ -28,7 +28,7 @@ const DemoAuth: VFC<IDemoAuthProps> = ({ authDetails, redirect }) => {
|
|||||||
try {
|
try {
|
||||||
await emailAuth(authDetails.path, email);
|
await emailAuth(authDetails.path, email);
|
||||||
refetchUser();
|
refetchUser();
|
||||||
navigate(redirect);
|
navigate(redirect, { replace: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setToastApiError(formatUnknownError(error));
|
setToastApiError(formatUnknownError(error));
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ const HostedAuth: VFC<IHostedAuthProps> = ({ authDetails, redirect }) => {
|
|||||||
try {
|
try {
|
||||||
await passwordAuth(authDetails.path, username, password);
|
await passwordAuth(authDetails.path, username, password);
|
||||||
refetchUser();
|
refetchUser();
|
||||||
navigate(redirect);
|
navigate(redirect, { replace: true });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (
|
if (
|
||||||
error instanceof NotFoundError ||
|
error instanceof NotFoundError ||
|
||||||
|
@ -71,7 +71,7 @@ const PasswordAuth: VFC<IPasswordAuthProps> = ({ authDetails, redirect }) => {
|
|||||||
try {
|
try {
|
||||||
await passwordAuth(authDetails.path, username, password);
|
await passwordAuth(authDetails.path, username, password);
|
||||||
refetchUser();
|
refetchUser();
|
||||||
navigate(redirect);
|
navigate(redirect, { replace: true });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (
|
if (
|
||||||
error instanceof NotFoundError ||
|
error instanceof NotFoundError ||
|
||||||
|
@ -27,7 +27,7 @@ const SimpleAuth: VFC<ISimpleAuthProps> = ({ authDetails, redirect }) => {
|
|||||||
try {
|
try {
|
||||||
await emailAuth(authDetails.path, email);
|
await emailAuth(authDetails.path, email);
|
||||||
refetchUser();
|
refetchUser();
|
||||||
navigate(redirect);
|
navigate(redirect, { replace: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setToastApiError(formatUnknownError(error));
|
setToastApiError(formatUnknownError(error));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user