diff --git a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx
index 7daf876ac1..bf2e6d8135 100644
--- a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx
+++ b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx
@@ -15,7 +15,7 @@
*/
import { JSX } from 'react';
-import { Routes, Route, Navigate, useResolvedPath } from 'react-router-dom';
+import { Routes, Route, Navigate } from 'react-router-dom';
import { IconElement } from '../icons/types';
import { RouteRef } from '../routing';
import {
@@ -72,7 +72,6 @@ export const PageBlueprint = createExtensionBlueprint({
{ config, node, inputs },
) {
const title = config.title ?? params.title;
- const routePath = config.path ?? params.path;
const icon = params.icon;
const pluginId = node.spec.plugin.pluginId;
const noHeader = params.noHeader ?? false;
@@ -80,7 +79,7 @@ export const PageBlueprint = createExtensionBlueprint({
title ?? node.spec.plugin.title ?? node.spec.plugin.pluginId;
const resolvedIcon = icon ?? node.spec.plugin.icon;
- yield coreExtensionData.routePath(routePath);
+ yield coreExtensionData.routePath(config.path ?? params.path);
if (params.loader) {
const loader = params.loader;
const PageContent = () => {
@@ -100,34 +99,24 @@ export const PageBlueprint = createExtensionBlueprint({
};
yield coreExtensionData.reactElement();
} else if (inputs.pages.length > 0) {
+ // Parent page with sub-pages - render header with tabs
+ const tabs: PageLayoutTab[] = inputs.pages.map(page => {
+ const path = page.get(coreExtensionData.routePath);
+ const tabTitle = page.get(coreExtensionData.title);
+ const tabIcon = page.get(coreExtensionData.icon);
+ return {
+ id: path,
+ label: tabTitle || path,
+ icon: tabIcon,
+ href: path,
+ };
+ });
+
const PageContent = () => {
const firstPagePath = inputs.pages[0]?.get(coreExtensionData.routePath);
+
const headerActionsApi = useApi(pluginHeaderActionsApiRef);
const headerActions = headerActionsApi.getPluginHeaderActions(pluginId);
- const parentPath = useResolvedPath('.').pathname.replace(/\/$/, '');
- const staticParentPath =
- routePath.startsWith('/') &&
- !routePath.includes('/:') &&
- !routePath.includes('*')
- ? routePath.replace(/\/$/, '')
- : undefined;
- const tabs: PageLayoutTab[] = inputs.pages.map(page => {
- const path = page.get(coreExtensionData.routePath);
- const tabTitle = page.get(coreExtensionData.title);
- const tabIcon = page.get(coreExtensionData.icon);
- const tabPath = path.replace(/^\/+/, '');
- const basePath = staticParentPath ?? parentPath ?? '';
- const href = path.startsWith('/')
- ? path
- : `${basePath}/${tabPath}`.replace(/\/{2,}/g, '/');
-
- return {
- id: path,
- label: tabTitle || path,
- icon: tabIcon,
- href,
- };
- });
return (
(props: PageLayoutProps) => {
const { title, icon, noHeader, headerActions, tabs, children } = props;
- const tabsWithMatchStrategy = useMemo(
+ // TODO(Rugvip): Different solution to this path handling would be good
+ const parentPath = useResolvedPath('.').pathname.replace(/\/$/, '');
+ const resolvedTabs = useMemo(
() =>
tabs?.map(tab => ({
...tab,
+ href: tab.href.startsWith('/')
+ ? tab.href
+ : `${parentPath}/${tab.href}`.replace(/\/{2,}/g, '/'),
matchStrategy: 'prefix' as const,
})),
- [tabs],
+ [tabs, parentPath],
);
if (noHeader) {
@@ -93,7 +99,7 @@ export const PageLayout = SwappableComponentBlueprint.make({
{children}