diff --git a/public/app/AppWrapper.tsx b/public/app/AppWrapper.tsx index 768a0ff0dff..91a9e5efd4b 100644 --- a/public/app/AppWrapper.tsx +++ b/public/app/AppWrapper.tsx @@ -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 { // TODO[Router]: test this logic if (roles?.length) { if (!roles.some((r: string) => contextSrv.hasRole(r))) { - return ; + return ; } } diff --git a/public/app/core/components/FormPrompt/FormPrompt.tsx b/public/app/core/components/FormPrompt/FormPrompt.tsx index dac60471129..7e5edbc4cb7 100644 --- a/public/app/core/components/FormPrompt/FormPrompt.tsx +++ b/public/app/core/components/FormPrompt/FormPrompt.tsx @@ -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 ( <> - {blockedLocation && changesDiscarded && } + {blockedLocation && changesDiscarded && } ); diff --git a/public/app/features/alerting/unified/MuteTimings.tsx b/public/app/features/alerting/unified/MuteTimings.tsx index 08e10eb1b66..10deee135e4 100644 --- a/public/app/features/alerting/unified/MuteTimings.tsx +++ b/public/app/features/alerting/unified/MuteTimings.tsx @@ -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 ; + return ; } return ( diff --git a/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx b/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx index 3372d095755..fa32c6e3bf9 100644 --- a/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx +++ b/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx @@ -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', () => ({ diff --git a/public/app/features/alerting/unified/RedirectToRuleViewer.tsx b/public/app/features/alerting/unified/RedirectToRuleViewer.tsx index 9462ea4686f..e5375ad9133 100644 --- a/public/app/features/alerting/unified/RedirectToRuleViewer.tsx +++ b/public/app/features/alerting/unified/RedirectToRuleViewer.tsx @@ -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 ; + return ; } 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 ; + return ; } if (rules.length === 0) { diff --git a/public/app/features/alerting/unified/components/rules/CloneRule.tsx b/public/app/features/alerting/unified/components/rules/CloneRule.tsx index 646aace7945..cb0d0cdbc80 100644 --- a/public/app/features/alerting/unified/components/rules/CloneRule.tsx +++ b/public/app/features/alerting/unified/components/rules/CloneRule.tsx @@ -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 ; + return ; } return ( diff --git a/public/app/features/connections/Connections.tsx b/public/app/features/connections/Connections.tsx index 600dbb958c0..fd0a97b1125 100644 --- a/public/app/features/connections/Connections.tsx +++ b/public/app/features/connections/Connections.tsx @@ -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 to "Add new connection" by default */} - } /> + } /> @@ -54,11 +56,14 @@ export default function Connections() { {/* Redirect from earlier routes to updated routes */} - - + } + /> + } /> {/* Not found */} - } /> + } /> ); diff --git a/public/app/features/trails/DataTrailsHome.tsx b/public/app/features/trails/DataTrailsHome.tsx index 3c77390f6a7..59f11dea664 100644 --- a/public/app/features/trails/DataTrailsHome.tsx +++ b/public/app/features/trails/DataTrailsHome.tsx @@ -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 { // 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 ; + return ; } return ( diff --git a/public/app/routes/routes.tsx b/public/app/routes/routes.tsx index 261b3cf5726..b496c73550c 100644 --- a/public/app/routes/routes.tsx +++ b/public/app/routes/routes.tsx @@ -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: () => , + component: () => , }, { path: DATASOURCES_ROUTES.Edit, - component: (props: RouteComponentProps<{ uid: string }>) => ( - - ), + component: DataSourceEditRoute, }, { path: DATASOURCES_ROUTES.Dashboards, - component: (props: RouteComponentProps<{ uid: string }>) => ( - - ), + component: DataSourceDashboardRoute, }, { path: DATASOURCES_ROUTES.New, - component: () => , + component: () => , }, { path: '/datasources/correlations', @@ -219,7 +215,7 @@ export function getAppRoutes(): RouteDescriptor[] { { path: '/org/users', // Org users page has been combined with admin users - component: () => , + component: () => , }, { path: '/org/users/invite', @@ -292,7 +288,7 @@ export function getAppRoutes(): RouteDescriptor[] { () => import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/AuthProvidersListPage') ) - : () => , + : () => , }, { path: '/admin/authentication/ldap', @@ -309,7 +305,7 @@ export function getAppRoutes(): RouteDescriptor[] { ? SafeDynamicImport( () => import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/ProviderConfigPage') ) - : () => , + : () => , }, { path: '/admin/settings', @@ -357,7 +353,7 @@ export function getAppRoutes(): RouteDescriptor[] { ? SafeDynamicImport( () => import(/* webpackChunkName: "AdminFeatureTogglesPage" */ 'app/features/admin/AdminFeatureTogglesPage') ) - : () => , + : () => , }, { path: '/admin/storage/:path*', @@ -398,7 +394,7 @@ export function getAppRoutes(): RouteDescriptor[] { { path: '/verify', component: !config.verifyEmailEnabled - ? () => + ? () => : SafeDynamicImport( () => import(/* webpackChunkName "VerifyEmailPage"*/ 'app/core/components/Signup/VerifyEmailPage') ), @@ -408,7 +404,7 @@ export function getAppRoutes(): RouteDescriptor[] { { path: '/signup', component: config.disableUserSignUp - ? () => + ? () => : 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 ; +} + +function DataSourceEditRoute() { + const { uid = '' } = useParams(); + return ; +}