core-app-api: allow path props in route elements
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-app-api': patch
|
||||
---
|
||||
|
||||
When using React Router v6 stable, it is now possible for components within the `Route` element tree to have `path` props, although they will be ignored.
|
||||
@@ -453,18 +453,19 @@ describe('discovery', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw elements within element prop contains a path', () => {
|
||||
expect(() => {
|
||||
traverseElementTree({
|
||||
root: <Route path="foo" element={<Extension3 path="bar" />} />,
|
||||
discoverers: [childDiscoverer, routeElementDiscoverer],
|
||||
collectors: {
|
||||
routing: routingV2Collector,
|
||||
},
|
||||
});
|
||||
}).toThrow(
|
||||
'Elements within the element prop tree may not have paths, found "bar"',
|
||||
);
|
||||
it('should ignore path props within route elements', () => {
|
||||
const { routing } = traverseElementTree({
|
||||
root: <Route path="foo" element={<Extension1 path="bar" />} />,
|
||||
discoverers: [childDiscoverer, routeElementDiscoverer],
|
||||
collectors: {
|
||||
routing: routingV2Collector,
|
||||
},
|
||||
});
|
||||
expect(sortedEntries(routing.paths)).toEqual([[ref1, 'foo']]);
|
||||
expect(sortedEntries(routing.parents)).toEqual([[ref1, undefined]]);
|
||||
expect(routing.objects).toEqual([
|
||||
routeObj('foo', [ref1], [], undefined, plugin),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should throw when a routable extension does not have a path set', () => {
|
||||
|
||||
@@ -53,6 +53,8 @@ interface RoutingV2CollectorContext {
|
||||
isElementAncestor?: boolean;
|
||||
}
|
||||
|
||||
// This collects all the mount points and their plugins within an element tree.
|
||||
// Unlike regular traversal this ignores all other things, like path props and mount point gatherers.
|
||||
function collectSubTree(
|
||||
node: ReactNode,
|
||||
entries = new Array<{ routeRef: RouteRef; plugin?: BackstagePlugin }>(),
|
||||
@@ -62,12 +64,6 @@ function collectSubTree(
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.props.path) {
|
||||
throw new Error(
|
||||
`Elements within the element prop tree may not have paths, found "${element.props.path}"`,
|
||||
);
|
||||
}
|
||||
|
||||
const routeRef = getComponentData<RouteRef>(element, 'core.mountPoint');
|
||||
if (routeRef) {
|
||||
const plugin = getComponentData<BackstagePlugin>(element, 'core.plugin');
|
||||
@@ -87,6 +83,16 @@ export const routingV2Collector = createCollector(
|
||||
objects: new Array<BackstageRouteObject>(),
|
||||
}),
|
||||
(acc, node, parent, ctx?: RoutingV2CollectorContext) => {
|
||||
// If we're in an element prop, ignore everything
|
||||
if (ctx?.isElementAncestor) {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
// Start ignoring everything if we enter an element prop
|
||||
if (parent?.props.element === node) {
|
||||
return { ...ctx, isElementAncestor: true };
|
||||
}
|
||||
|
||||
const pathProp: unknown = node.props?.path;
|
||||
|
||||
const mountPoint = getComponentData<RouteRef>(node, 'core.mountPoint');
|
||||
@@ -98,15 +104,6 @@ export const routingV2Collector = createCollector(
|
||||
);
|
||||
}
|
||||
|
||||
// If we're in an element prop, ignore everything
|
||||
if (ctx?.isElementAncestor) {
|
||||
return ctx;
|
||||
}
|
||||
// Start ignoring everything if we enter an element prop
|
||||
if (parent?.props.element === node) {
|
||||
return { ...ctx, isElementAncestor: true };
|
||||
}
|
||||
|
||||
const parentChildren = ctx?.obj?.children ?? acc.objects;
|
||||
|
||||
if (pathProp !== undefined) {
|
||||
|
||||
Reference in New Issue
Block a user