Revert react-router v7 future flags from #31818
Roll back the v7_relativeSplatPath and v7_startTransition future flags and the Outlet-based route structure, keeping the version bump to react-router-dom@^6.30.2. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -53,4 +53,4 @@
|
||||
'@backstage/plugin-org': patch
|
||||
---
|
||||
|
||||
Prepare for React Router v7 migration by updating to v6.30.2 across all NFS packages and enabling v7 future flags. Convert routes from splat paths to parent/child structure with Outlet components.
|
||||
Updated `react-router-dom` peer dependency to `^6.30.2`.
|
||||
|
||||
@@ -208,13 +208,7 @@ export function renderInTestApp<const TApiPairs extends any[] = any[]>(
|
||||
RouterBlueprint.make({
|
||||
params: {
|
||||
component: ({ children }) => (
|
||||
<MemoryRouter
|
||||
initialEntries={options?.initialRouteEntries}
|
||||
future={{
|
||||
v7_relativeSplatPath: true,
|
||||
v7_startTransition: true,
|
||||
}}
|
||||
>
|
||||
<MemoryRouter initialEntries={options?.initialRouteEntries}>
|
||||
{children}
|
||||
</MemoryRouter>
|
||||
),
|
||||
|
||||
@@ -150,13 +150,7 @@ export function renderTestApp<const TApiPairs extends any[] = any[]>(
|
||||
RouterBlueprint.make({
|
||||
params: {
|
||||
component: ({ children }) => (
|
||||
<MemoryRouter
|
||||
initialEntries={options?.initialRouteEntries}
|
||||
future={{
|
||||
v7_relativeSplatPath: true,
|
||||
v7_startTransition: true,
|
||||
}}
|
||||
>
|
||||
<MemoryRouter initialEntries={options?.initialRouteEntries}>
|
||||
{children}
|
||||
</MemoryRouter>
|
||||
),
|
||||
|
||||
@@ -198,17 +198,7 @@ export interface AppRouterProps {
|
||||
function DefaultRouter(props: PropsWithChildren<{}>) {
|
||||
const configApi = useApi(configApiRef);
|
||||
const basePath = getBasePath(configApi);
|
||||
return (
|
||||
<BrowserRouter
|
||||
basename={basePath}
|
||||
future={{
|
||||
v7_relativeSplatPath: true,
|
||||
v7_startTransition: true,
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</BrowserRouter>
|
||||
);
|
||||
return <BrowserRouter basename={basePath}>{props.children}</BrowserRouter>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
createExtensionInput,
|
||||
NotFoundErrorPage,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { useRoutes, Outlet } from 'react-router-dom';
|
||||
import { useRoutes } from 'react-router-dom';
|
||||
|
||||
export const AppRoutes = createExtension({
|
||||
name: 'routes',
|
||||
@@ -38,42 +38,14 @@ export const AppRoutes = createExtension({
|
||||
const element = useRoutes([
|
||||
...inputs.routes.map(route => {
|
||||
const routePath = route.get(coreExtensionData.routePath);
|
||||
const routeElement = route.get(coreExtensionData.reactElement);
|
||||
|
||||
// For v7_relativeSplatPath: convert splat paths to parent/child structure
|
||||
if (routePath === '/') {
|
||||
// Root route: parent with index and splat children
|
||||
return {
|
||||
path: '/',
|
||||
element: <Outlet />,
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: routeElement,
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
element: routeElement,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
// Non-root routes: parent route with splat child
|
||||
const normalizedPath = routePath.replace(/\/$/, '');
|
||||
return {
|
||||
path: normalizedPath,
|
||||
element: <Outlet />,
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: routeElement,
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
element: routeElement,
|
||||
},
|
||||
],
|
||||
path:
|
||||
routePath === '/'
|
||||
? routePath
|
||||
: `${routePath.replace(/\/$/, '')}/*`,
|
||||
|
||||
element: route.get(coreExtensionData.reactElement),
|
||||
};
|
||||
}),
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import { ReactElement, useMemo } from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { matchRoutes, useParams, useRoutes, Outlet } from 'react-router-dom';
|
||||
import { matchRoutes, useParams, useRoutes } from 'react-router-dom';
|
||||
import { EntityTabsPanel } from './EntityTabsPanel';
|
||||
import { EntityTabsList } from './EntityTabsList';
|
||||
import { EntityContentGroupDefinitions } from '@backstage/plugin-catalog-react/alpha';
|
||||
@@ -35,25 +35,17 @@ export function useSelectedSubRoute(subRoutes: SubRoute[]): {
|
||||
} {
|
||||
const params = useParams();
|
||||
|
||||
// For v7_relativeSplatPath: convert splat paths to parent/child structure
|
||||
const routes = subRoutes.map(({ path, children }) => ({
|
||||
caseSensitive: false,
|
||||
path: path,
|
||||
element: <Outlet />,
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: children,
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
element: children,
|
||||
},
|
||||
],
|
||||
path: `${path}/*`,
|
||||
element: children,
|
||||
}));
|
||||
|
||||
// Sort routes by path length (longest first) for proper matching
|
||||
const sortedRoutes = routes.sort((a, b) => b.path.localeCompare(a.path));
|
||||
// TODO: remove once react-router updated
|
||||
const sortedRoutes = routes.sort((a, b) =>
|
||||
// remove "/*" symbols from path end before comparing
|
||||
b.path.replace(/\/\*$/, '').localeCompare(a.path.replace(/\/\*$/, '')),
|
||||
);
|
||||
|
||||
const element = useRoutes(sortedRoutes) ?? subRoutes[0]?.children;
|
||||
|
||||
@@ -67,7 +59,7 @@ export function useSelectedSubRoute(subRoutes: SubRoute[]): {
|
||||
|
||||
const [matchedRoute] = matchRoutes(sortedRoutes, currentRoute) ?? [];
|
||||
const foundIndex = matchedRoute
|
||||
? subRoutes.findIndex(t => t.path === matchedRoute.route.path)
|
||||
? subRoutes.findIndex(t => `${t.path}/*` === matchedRoute.route.path)
|
||||
: 0;
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user