diff --git a/.changeset/ten-mammals-invite.md b/.changeset/ten-mammals-invite.md index a29e38d476..431af9460b 100644 --- a/.changeset/ten-mammals-invite.md +++ b/.changeset/ten-mammals-invite.md @@ -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` and explicitly disabled v7 future flags to suppress deprecation warnings. diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.tsx index 10b36b68b4..eeb0e02353 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.tsx @@ -211,8 +211,8 @@ export function renderInTestApp( {children} diff --git a/packages/frontend-test-utils/src/app/renderTestApp.tsx b/packages/frontend-test-utils/src/app/renderTestApp.tsx index 858ad462f4..f470be7dbb 100644 --- a/packages/frontend-test-utils/src/app/renderTestApp.tsx +++ b/packages/frontend-test-utils/src/app/renderTestApp.tsx @@ -153,8 +153,8 @@ export function renderTestApp( {children} diff --git a/plugins/app/src/extensions/AppRoot.tsx b/plugins/app/src/extensions/AppRoot.tsx index 079fc582db..08eaa50bd9 100644 --- a/plugins/app/src/extensions/AppRoot.tsx +++ b/plugins/app/src/extensions/AppRoot.tsx @@ -202,8 +202,8 @@ function DefaultRouter(props: PropsWithChildren<{}>) { {props.children} diff --git a/plugins/app/src/extensions/AppRoutes.tsx b/plugins/app/src/extensions/AppRoutes.tsx index bd96e6e9b1..ddd7962004 100644 --- a/plugins/app/src/extensions/AppRoutes.tsx +++ b/plugins/app/src/extensions/AppRoutes.tsx @@ -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: , - children: [ - { - index: true, - element: routeElement, - }, - { - path: '*', - element: routeElement, - }, - ], - }; - } - - // Non-root routes: parent route with splat child - const normalizedPath = routePath.replace(/\/$/, ''); return { - path: normalizedPath, - element: , - children: [ - { - index: true, - element: routeElement, - }, - { - path: '*', - element: routeElement, - }, - ], + path: + routePath === '/' + ? routePath + : `${routePath.replace(/\/$/, '')}/*`, + + element: route.get(coreExtensionData.reactElement), }; }), { diff --git a/plugins/catalog/src/alpha/components/EntityTabs/EntityTabs.tsx b/plugins/catalog/src/alpha/components/EntityTabs/EntityTabs.tsx index f0088f688f..ed737266a5 100644 --- a/plugins/catalog/src/alpha/components/EntityTabs/EntityTabs.tsx +++ b/plugins/catalog/src/alpha/components/EntityTabs/EntityTabs.tsx @@ -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: , - 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 {