mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Routing: Replace Redirect component with Navigate (#94072)
* Routing: Replace Redirect with Navigate * Use replace state * Update routes.tsx * Fix test
This commit is contained in:
parent
28d9cc7310
commit
f55f7f2634
@ -1,8 +1,8 @@
|
||||
import { Action, KBarProvider } from 'kbar';
|
||||
import { Component, ComponentType } from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { Redirect, Switch, RouteComponentProps } from 'react-router-dom';
|
||||
import { CompatRoute } from 'react-router-dom-v5-compat';
|
||||
import { Switch, RouteComponentProps } from 'react-router-dom';
|
||||
import { CompatRoute, Navigate } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { config, navigationLogger, reportInteraction } from '@grafana/runtime';
|
||||
import { ErrorBoundaryAlert, GlobalStyles, PortalContainer } from '@grafana/ui';
|
||||
@ -67,7 +67,7 @@ export class AppWrapper extends Component<AppWrapperProps, AppWrapperState> {
|
||||
// TODO[Router]: test this logic
|
||||
if (roles?.length) {
|
||||
if (!roles.some((r: string) => contextSrv.hasRole(r))) {
|
||||
return <Redirect to="/" />;
|
||||
return <Navigate replace to="/" />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { css } from '@emotion/css';
|
||||
import history from 'history';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Prompt, Redirect } from 'react-router-dom';
|
||||
import { Prompt } from 'react-router-dom';
|
||||
import { Navigate } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { Button, Modal } from '@grafana/ui';
|
||||
|
||||
@ -80,7 +81,7 @@ export const FormPrompt = ({ confirmRedirect, onDiscard, onLocationChange }: Pro
|
||||
return (
|
||||
<>
|
||||
<Prompt when={true} message={handleRedirect} />
|
||||
{blockedLocation && changesDiscarded && <Redirect to={blockedLocation} />}
|
||||
{blockedLocation && changesDiscarded && <Navigate replace to={blockedLocation} />}
|
||||
<UnsavedChangesModal isOpen={modalIsOpen} onDiscard={onDiscardChanges} onBackToForm={onBackToForm} />
|
||||
</>
|
||||
);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Redirect, Route, Switch, useRouteMatch } from 'react-router-dom';
|
||||
import { Route, Switch, useRouteMatch } from 'react-router-dom';
|
||||
import { Navigate } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { NavModelItem } from '@grafana/data';
|
||||
import { useGetMuteTiming } from 'app/features/alerting/unified/components/mute-timings/useMuteTimings';
|
||||
@ -23,7 +24,7 @@ const EditTimingRoute = () => {
|
||||
});
|
||||
|
||||
if (!name) {
|
||||
return <Redirect to="/alerting/routes" />;
|
||||
return <Navigate replace to="/alerting/routes" />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -12,9 +12,9 @@ import { getRulesSourceByName } from './utils/datasource';
|
||||
|
||||
jest.mock('./hooks/useCombinedRule');
|
||||
jest.mock('./utils/datasource');
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
Redirect: jest.fn(({}) => `Redirected`),
|
||||
jest.mock('react-router-dom-v5-compat', () => ({
|
||||
...jest.requireActual('react-router-dom-v5-compat'),
|
||||
Navigate: jest.fn(({}) => `Redirected`),
|
||||
}));
|
||||
|
||||
jest.mock('react-use', () => ({
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { useMemo } from 'react';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import { Navigate } from 'react-router-dom-v5-compat';
|
||||
import { useLocation } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
@ -53,7 +53,7 @@ export function RedirectToRuleViewer(): JSX.Element | null {
|
||||
} = useCloudCombinedRulesMatching(name, sourceName, { namespace, groupName: group });
|
||||
|
||||
if (!name || !sourceName) {
|
||||
return <Redirect to="/notfound" />;
|
||||
return <Navigate replace to="/notfound" />;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
@ -95,7 +95,7 @@ export function RedirectToRuleViewer(): JSX.Element | null {
|
||||
if (rules.length === 1) {
|
||||
const [rule] = rules;
|
||||
const to = createViewLink(rulesSource, rule, '/alerting/list').replace(subUrl, '');
|
||||
return <Redirect to={to} />;
|
||||
return <Navigate replace to={to} />;
|
||||
}
|
||||
|
||||
if (rules.length === 0) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { forwardRef, useState } from 'react';
|
||||
import { Redirect, useLocation } from 'react-router-dom';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { Navigate } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { Button, ConfirmModal } from '@grafana/ui';
|
||||
import { RuleIdentifier } from 'app/types/unified-alerting';
|
||||
@ -33,7 +34,7 @@ export function RedirectToCloneRule({
|
||||
returnTo: redirectTo ? returnTo : '',
|
||||
});
|
||||
|
||||
return <Redirect to={`/alerting/new?` + queryParams.toString()} push />;
|
||||
return <Navigate to={`/alerting/new?` + queryParams.toString()} replace={false} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Redirect, Route, Switch, useLocation } from 'react-router-dom';
|
||||
import { Route, Switch, useLocation } from 'react-router-dom';
|
||||
import { Navigate } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { DataSourcesRoutesContext } from 'app/features/datasources/state';
|
||||
import { StoreState, useSelector } from 'app/types';
|
||||
@ -16,7 +17,8 @@ import {
|
||||
function RedirectToAddNewConnection() {
|
||||
const { search } = useLocation();
|
||||
return (
|
||||
<Redirect
|
||||
<Navigate
|
||||
replace
|
||||
to={{
|
||||
pathname: ROUTES.AddNewConnection,
|
||||
search,
|
||||
@ -40,7 +42,7 @@ export default function Connections() {
|
||||
>
|
||||
<Switch>
|
||||
{/* Redirect to "Add new connection" by default */}
|
||||
<Route exact sensitive path={ROUTES.Base} component={() => <Redirect to={ROUTES.AddNewConnection} />} />
|
||||
<Route exact sensitive path={ROUTES.Base} component={() => <Navigate replace to={ROUTES.AddNewConnection} />} />
|
||||
<Route exact sensitive path={ROUTES.DataSources} component={DataSourcesListPage} />
|
||||
<Route exact sensitive path={ROUTES.DataSourcesNew} component={NewDataSourcePage} />
|
||||
<Route exact sensitive path={ROUTES.DataSourcesDetails} component={DataSourceDetailsPage} />
|
||||
@ -54,11 +56,14 @@ export default function Connections() {
|
||||
|
||||
{/* Redirect from earlier routes to updated routes */}
|
||||
<Route exact path={ROUTES.ConnectDataOutdated} component={RedirectToAddNewConnection} />
|
||||
<Redirect from={`${ROUTES.Base}/your-connections/:page`} to={`${ROUTES.Base}/:page`} />
|
||||
<Redirect from={ROUTES.YourConnectionsOutdated} to={ROUTES.DataSources} />
|
||||
<Route
|
||||
path={`${ROUTES.Base}/your-connections/:page`}
|
||||
component={() => <Navigate replace to={`${ROUTES.Base}/:page`} />}
|
||||
/>
|
||||
<Route path={ROUTES.YourConnectionsOutdated} component={() => <Navigate replace to={ROUTES.DataSources} />} />
|
||||
|
||||
{/* Not found */}
|
||||
<Route component={() => <Redirect to="/notfound" />} />
|
||||
<Route component={() => <Navigate replace to="/notfound" />} />
|
||||
</Switch>
|
||||
</DataSourcesRoutesContext.Provider>
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { useState } from 'react';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import { Navigate } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { SceneComponentProps, sceneGraph, SceneObject, SceneObjectBase, SceneObjectState } from '@grafana/scenes';
|
||||
@ -57,7 +57,7 @@ export class DataTrailsHome extends SceneObjectBase<DataTrailsHomeState> {
|
||||
// If there are no recent trails, don't show home page and create a new trail
|
||||
if (!getTrailStore().recent.length) {
|
||||
const trail = newMetricsTrail(getDatasourceForNewTrail());
|
||||
return <Redirect to={getUrlForTrail(trail)} />;
|
||||
return <Navigate replace to={getUrlForTrail(trail)} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Redirect, RouteComponentProps } from 'react-router-dom';
|
||||
import { Navigate, useParams } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { isTruthy } from '@grafana/data';
|
||||
import { NavLandingPage } from 'app/core/components/NavLandingPage/NavLandingPage';
|
||||
@ -107,23 +107,19 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
},
|
||||
{
|
||||
path: DATASOURCES_ROUTES.List,
|
||||
component: () => <Redirect to={CONNECTIONS_ROUTES.DataSources} />,
|
||||
component: () => <Navigate replace to={CONNECTIONS_ROUTES.DataSources} />,
|
||||
},
|
||||
{
|
||||
path: DATASOURCES_ROUTES.Edit,
|
||||
component: (props: RouteComponentProps<{ uid: string }>) => (
|
||||
<Redirect to={CONNECTIONS_ROUTES.DataSourcesEdit.replace(':uid', props.match.params.uid)} />
|
||||
),
|
||||
component: DataSourceEditRoute,
|
||||
},
|
||||
{
|
||||
path: DATASOURCES_ROUTES.Dashboards,
|
||||
component: (props: RouteComponentProps<{ uid: string }>) => (
|
||||
<Redirect to={CONNECTIONS_ROUTES.DataSourcesDashboards.replace(':uid', props.match.params.uid)} />
|
||||
),
|
||||
component: DataSourceDashboardRoute,
|
||||
},
|
||||
{
|
||||
path: DATASOURCES_ROUTES.New,
|
||||
component: () => <Redirect to={CONNECTIONS_ROUTES.DataSourcesNew} />,
|
||||
component: () => <Navigate replace to={CONNECTIONS_ROUTES.DataSourcesNew} />,
|
||||
},
|
||||
{
|
||||
path: '/datasources/correlations',
|
||||
@ -219,7 +215,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
{
|
||||
path: '/org/users',
|
||||
// Org users page has been combined with admin users
|
||||
component: () => <Redirect to={'/admin/users'} />,
|
||||
component: () => <Navigate replace to={'/admin/users'} />,
|
||||
},
|
||||
{
|
||||
path: '/org/users/invite',
|
||||
@ -292,7 +288,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
() =>
|
||||
import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/AuthProvidersListPage')
|
||||
)
|
||||
: () => <Redirect to="/admin" />,
|
||||
: () => <Navigate replace to="/admin" />,
|
||||
},
|
||||
{
|
||||
path: '/admin/authentication/ldap',
|
||||
@ -309,7 +305,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
? SafeDynamicImport(
|
||||
() => import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/ProviderConfigPage')
|
||||
)
|
||||
: () => <Redirect to="/admin" />,
|
||||
: () => <Navigate replace to="/admin" />,
|
||||
},
|
||||
{
|
||||
path: '/admin/settings',
|
||||
@ -357,7 +353,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
? SafeDynamicImport(
|
||||
() => import(/* webpackChunkName: "AdminFeatureTogglesPage" */ 'app/features/admin/AdminFeatureTogglesPage')
|
||||
)
|
||||
: () => <Redirect to="/admin" />,
|
||||
: () => <Navigate replace to="/admin" />,
|
||||
},
|
||||
{
|
||||
path: '/admin/storage/:path*',
|
||||
@ -398,7 +394,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
{
|
||||
path: '/verify',
|
||||
component: !config.verifyEmailEnabled
|
||||
? () => <Redirect to="/signup" />
|
||||
? () => <Navigate replace to="/signup" />
|
||||
: SafeDynamicImport(
|
||||
() => import(/* webpackChunkName "VerifyEmailPage"*/ 'app/core/components/Signup/VerifyEmailPage')
|
||||
),
|
||||
@ -408,7 +404,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
{
|
||||
path: '/signup',
|
||||
component: config.disableUserSignUp
|
||||
? () => <Redirect to="/login" />
|
||||
? () => <Navigate replace to="/login" />
|
||||
: SafeDynamicImport(() => import(/* webpackChunkName "SignupPage"*/ 'app/core/components/Signup/SignupPage')),
|
||||
pageClass: 'login-page',
|
||||
chromeless: true,
|
||||
@ -556,3 +552,13 @@ export function getSupportBundleRoutes(cfg = config): RouteDescriptor[] {
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function DataSourceDashboardRoute() {
|
||||
const { uid = '' } = useParams();
|
||||
return <Navigate replace to={CONNECTIONS_ROUTES.DataSourcesDashboards.replace(':uid', uid)} />;
|
||||
}
|
||||
|
||||
function DataSourceEditRoute() {
|
||||
const { uid = '' } = useParams();
|
||||
return <Navigate replace to={CONNECTIONS_ROUTES.DataSourcesEdit.replace(':uid', uid)} />;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user