Migrate NFS pages to HeaderPage

Always render the plugin header for page blueprints and move page-level actions into the Backstage UI header pattern for affected NFS pages.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
This commit is contained in:
Patrik Oldsberg
2026-03-07 12:36:16 +01:00
parent b3466f6f78
commit aa29b508d1
58 changed files with 1474 additions and 556 deletions
+2 -2
View File
@@ -68,8 +68,8 @@ export const devToolsPage = PageBlueprint.makeWithOverrides({
title: content.get(coreExtensionData.title),
children: content.get(coreExtensionData.reactElement),
}));
return import('../components/DevToolsPage').then(m => (
<m.DevToolsPage contents={contents} />
return import('../components/DevToolsPage/DevToolsPage').then(m => (
<m.NfsDevToolsPage contents={contents} />
));
},
});
@@ -21,7 +21,10 @@ import {
import { ConfigContent } from '../Content';
import { devToolsTaskSchedulerReadPermission } from '@backstage/plugin-devtools-common/alpha';
import { DevToolsLayout } from '../DevToolsLayout';
import {
DevToolsLayout,
NfsDevToolsLayout,
} from '../DevToolsLayout/DevToolsLayout';
import { InfoContent } from '../Content';
import { RequirePermission } from '@backstage/plugin-permission-react';
import { ScheduledTasksContent } from '../Content/ScheduledTasksContent';
@@ -56,3 +59,32 @@ export const DefaultDevToolsPage = ({ contents }: DevToolsPageProps) => (
))}
</DevToolsLayout>
);
export const NfsDefaultDevToolsPage = ({ contents }: DevToolsPageProps) => (
<NfsDevToolsLayout>
<DevToolsLayout.Route path="info" title="Info">
<RequirePermission permission={devToolsInfoReadPermission}>
<InfoContent />
</RequirePermission>
</DevToolsLayout.Route>
<DevToolsLayout.Route path="config" title="Config">
<RequirePermission permission={devToolsConfigReadPermission}>
<ConfigContent />
</RequirePermission>
</DevToolsLayout.Route>
<DevToolsLayout.Route path="scheduled-tasks" title="Scheduled Tasks">
<RequirePermission permission={devToolsTaskSchedulerReadPermission}>
<ScheduledTasksContent />
</RequirePermission>
</DevToolsLayout.Route>
{contents?.map((content, index) => (
<DevToolsLayout.Route
key={`extension-${index}`}
path={content.path}
title={content.title}
>
{content.children}
</DevToolsLayout.Route>
))}
</NfsDevToolsLayout>
);
@@ -15,6 +15,7 @@
*/
import { Header, Page, RoutedTabs } from '@backstage/core-components';
import { HeaderPage } from '@backstage/ui';
import {
attachComponentData,
useElementFilter,
@@ -82,4 +83,28 @@ export const DevToolsLayout = ({
);
};
export const NfsDevToolsLayout = ({
children,
title,
subtitle,
}: DevToolsLayoutProps) => {
const routes = useElementFilter(children, elements =>
elements
.selectByComponentData({
key: dataKey,
withStrictError:
'Child of DevToolsLayout must be an DevToolsLayout.Route',
})
.getElements<SubRoute>()
.map(child => child.props),
);
return (
<>
<HeaderPage title={title ?? 'Backstage DevTools'} subtitle={subtitle} />
<RoutedTabs routes={routes} />
</>
);
};
DevToolsLayout.Route = Route;
@@ -16,6 +16,7 @@
import { useOutlet } from 'react-router-dom';
import { DefaultDevToolsPage } from '../DefaultDevToolsPage';
import { NfsDefaultDevToolsPage } from '../DefaultDevToolsPage/DefaultDevToolsPage';
import { ReactElement } from 'react';
/**
@@ -39,3 +40,9 @@ export const DevToolsPage = ({ contents }: DevToolsPageProps) => {
return <>{outlet || <DefaultDevToolsPage contents={contents} />}</>;
};
export const NfsDevToolsPage = ({ contents }: DevToolsPageProps) => {
const outlet = useOutlet();
return <>{outlet || <NfsDefaultDevToolsPage contents={contents} />}</>;
};