From 0ed86cc838fc9b49ce83014130086e8ff31129bc Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Wed, 19 Jul 2023 17:56:17 +0200 Subject: [PATCH] Account for sub-route context inheritance Signed-off-by: Eric Peterson --- .../src/routing/RouteTracker.test.tsx | 31 +++++++++++++++++-- .../core-app-api/src/routing/RouteTracker.tsx | 14 +++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/packages/core-app-api/src/routing/RouteTracker.test.tsx b/packages/core-app-api/src/routing/RouteTracker.test.tsx index 695e5bbf38..25d5cfbcfb 100644 --- a/packages/core-app-api/src/routing/RouteTracker.test.tsx +++ b/packages/core-app-api/src/routing/RouteTracker.test.tsx @@ -39,6 +39,7 @@ describe('RouteTracker', () => { }); const plugin0 = createPlugin({ id: 'home' }); const plugin1 = createPlugin({ id: 'plugin1' }); + const plugin2 = createPlugin({ id: 'plugin2' }); const routeObjects: BackstageRouteObject[] = [ { @@ -61,7 +62,7 @@ describe('RouteTracker', () => { path: '/path2/:param', element:
hi there
, routeRefs: new Set([routeRef2]), - plugins: new Set(), + plugins: new Set([plugin2]), caseSensitive: false, children: [MATCH_ALL_ROUTE], }, @@ -124,7 +125,7 @@ describe('RouteTracker', () => { }, context: { extension: 'App', - pluginId: 'root', + pluginId: 'plugin2', routeRef: 'route2', }, subject: '/path2/hello', @@ -179,7 +180,7 @@ describe('RouteTracker', () => { }); }); - it('should return default context when no plugin/routeRef is on the route', async () => { + it('should return default context when it would have otherwise matched on the root path', async () => { render( @@ -206,4 +207,28 @@ describe('RouteTracker', () => { value: undefined, }); }); + + it('should return parent route context on navigating to a sub-route', async () => { + render( + + + + + , + ); + + expect(mockedAnalytics.captureEvent).toHaveBeenCalledWith({ + action: 'navigate', + attributes: { + param: 'param-value', + }, + context: { + extension: 'App', + pluginId: 'plugin2', + routeRef: 'route2', + }, + subject: '/path2/param-value/sub-route', + value: undefined, + }); + }); }); diff --git a/packages/core-app-api/src/routing/RouteTracker.tsx b/packages/core-app-api/src/routing/RouteTracker.tsx index bed72b6134..69903268ac 100644 --- a/packages/core-app-api/src/routing/RouteTracker.tsx +++ b/packages/core-app-api/src/routing/RouteTracker.tsx @@ -38,9 +38,11 @@ const getExtensionContext = ( const matches = matchRoutes(routes, { pathname }); // Of the matching routes, get the last (e.g. most specific) instance of - // the BackstageRouteObject. - const routeMatch = matches?.pop(); - + // the BackstageRouteObject that contains a routeRef. Filtering by routeRef + // ensures subRouteRefs are aligned to their parent routes' context. + const routeMatch = matches + ?.filter(match => match?.route.routeRefs?.size > 0) + .pop(); const routeObject = routeMatch?.route; // If there is no route object, then allow inheritance of default context. @@ -48,6 +50,12 @@ const getExtensionContext = ( return undefined; } + // If the matched route is the root route (no path), and the pathname is + // not the path of the homepage, then inherit from the default context. + if (routeObject.path === '' && pathname !== '/') { + return undefined; + } + // If there is a single route ref, use it. let routeRef: RouteRef | undefined; if (routeObject.routeRefs.size === 1) {