Merge pull request #33389 from backstage/rugvip/nfs-header-page-migration

plugins: migrate NFS pages to HeaderPage
This commit is contained in:
Patrik Oldsberg
2026-03-17 22:16:12 +01:00
committed by GitHub
39 changed files with 1049 additions and 476 deletions
+1
View File
@@ -66,6 +66,7 @@
"@backstage/plugin-user-settings-common": "workspace:^",
"@backstage/theme": "workspace:^",
"@backstage/types": "workspace:^",
"@backstage/ui": "workspace:^",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.61",
+120 -5
View File
@@ -45,6 +45,8 @@ const _default: OverridableFrontendPlugin<
};
}>;
'page:user-settings': OverridableExtensionDefinition<{
kind: 'page';
name: undefined;
config: {
path: string | undefined;
title: string | undefined;
@@ -108,6 +110,44 @@ const _default: OverridableFrontendPlugin<
internal: false;
}
>;
};
params: {
path: string;
title?: string;
icon?: IconElement;
loader?: () => Promise<JSX_2.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
}>;
'sub-page:user-settings/auth-providers': OverridableExtensionDefinition<{
config: {
path: string | undefined;
title: string | undefined;
};
configInput: {
title?: string | undefined;
path?: string | undefined;
};
output:
| ExtensionDataRef<string, 'core.routing.path', {}>
| ExtensionDataRef<
RouteRef<AnyRouteRefParams>,
'core.routing.ref',
{
optional: true;
}
>
| ExtensionDataRef<JSX_2.Element, 'core.reactElement', {}>
| ExtensionDataRef<string, 'core.title', {}>
| ExtensionDataRef<
IconElement,
'core.icon',
{
optional: true;
}
>;
inputs: {
providerSettings: ExtensionInput<
ConfigurableExtensionDataRef<JSX_2.Element, 'core.reactElement', {}>,
{
@@ -117,15 +157,90 @@ const _default: OverridableFrontendPlugin<
}
>;
};
kind: 'page';
name: undefined;
kind: 'sub-page';
name: 'auth-providers';
params: {
path: string;
title?: string;
title: string;
icon?: IconElement;
loader?: () => Promise<JSX_2.Element>;
loader: () => Promise<JSX.Element>;
routeRef?: RouteRef;
};
}>;
'sub-page:user-settings/feature-flags': OverridableExtensionDefinition<{
kind: 'sub-page';
name: 'feature-flags';
config: {
path: string | undefined;
title: string | undefined;
};
configInput: {
title?: string | undefined;
path?: string | undefined;
};
output:
| ExtensionDataRef<string, 'core.routing.path', {}>
| ExtensionDataRef<
RouteRef<AnyRouteRefParams>,
'core.routing.ref',
{
optional: true;
}
>
| ExtensionDataRef<JSX_2.Element, 'core.reactElement', {}>
| ExtensionDataRef<string, 'core.title', {}>
| ExtensionDataRef<
IconElement,
'core.icon',
{
optional: true;
}
>;
inputs: {};
params: {
path: string;
title: string;
icon?: IconElement;
loader: () => Promise<JSX.Element>;
routeRef?: RouteRef;
};
}>;
'sub-page:user-settings/general': OverridableExtensionDefinition<{
kind: 'sub-page';
name: 'general';
config: {
path: string | undefined;
title: string | undefined;
};
configInput: {
title?: string | undefined;
path?: string | undefined;
};
output:
| ExtensionDataRef<string, 'core.routing.path', {}>
| ExtensionDataRef<
RouteRef<AnyRouteRefParams>,
'core.routing.ref',
{
optional: true;
}
>
| ExtensionDataRef<JSX_2.Element, 'core.reactElement', {}>
| ExtensionDataRef<string, 'core.title', {}>
| ExtensionDataRef<
IconElement,
'core.icon',
{
optional: true;
}
>;
inputs: {};
params: {
path: string;
title: string;
icon?: IconElement;
loader: () => Promise<JSX.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
}>;
}
+57 -10
View File
@@ -19,7 +19,9 @@ import {
createFrontendPlugin,
PageBlueprint,
NavItemBlueprint,
SubPageBlueprint,
} from '@backstage/frontend-plugin-api';
import { Content } from '@backstage/core-components';
import SettingsIcon from '@material-ui/icons/Settings';
import { settingsRouteRef } from './plugin';
@@ -31,7 +33,30 @@ import { userSettingsTranslationRef as _userSettingsTranslationRef } from './tra
*/
export const userSettingsTranslationRef = _userSettingsTranslationRef;
const userSettingsPage = PageBlueprint.makeWithOverrides({
const userSettingsPage = PageBlueprint.make({
params: {
path: '/settings',
routeRef: settingsRouteRef,
title: 'Settings',
},
});
const generalSettingsPage = SubPageBlueprint.make({
name: 'general',
params: {
path: 'general',
title: 'General',
loader: () =>
import('./components/General').then(m => (
<Content>
<m.UserSettingsGeneral />
</Content>
)),
},
});
const authProvidersSettingsPage = SubPageBlueprint.makeWithOverrides({
name: 'auth-providers',
inputs: {
providerSettings: createExtensionInput([coreExtensionData.reactElement], {
singleton: true,
@@ -40,20 +65,36 @@ const userSettingsPage = PageBlueprint.makeWithOverrides({
},
factory(originalFactory, { inputs }) {
return originalFactory({
path: '/settings',
routeRef: settingsRouteRef,
path: 'auth-providers',
title: 'Authentication Providers',
loader: () =>
import('./components/SettingsPage').then(m => (
<m.SettingsPage
providerSettings={inputs.providerSettings?.get(
coreExtensionData.reactElement,
)}
/>
import('./components/AuthProviders').then(m => (
<Content>
<m.UserSettingsAuthProviders
providerSettings={inputs.providerSettings?.get(
coreExtensionData.reactElement,
)}
/>
</Content>
)),
});
},
});
const featureFlagsSettingsPage = SubPageBlueprint.make({
name: 'feature-flags',
params: {
path: 'feature-flags',
title: 'Feature Flags',
loader: () =>
import('./components/FeatureFlags').then(m => (
<Content>
<m.UserSettingsFeatureFlags />
</Content>
)),
},
});
/** @alpha */
export const settingsNavItem = NavItemBlueprint.make({
params: {
@@ -71,7 +112,13 @@ export default createFrontendPlugin({
title: 'Settings',
icon: <SettingsIcon fontSize="inherit" />,
info: { packageJson: () => import('../package.json') },
extensions: [userSettingsPage, settingsNavItem],
extensions: [
userSettingsPage,
generalSettingsPage,
authProvidersSettingsPage,
featureFlagsSettingsPage,
settingsNavItem,
],
routes: {
root: settingsRouteRef,
},
@@ -18,7 +18,8 @@ import { ReactElement } from 'react';
import { UserSettingsAuthProviders } from '../AuthProviders';
import { UserSettingsFeatureFlags } from '../FeatureFlags';
import { UserSettingsGeneral } from '../General';
import { SettingsLayout, SettingsLayoutRouteProps } from '../SettingsLayout';
import { SettingsLayoutRouteProps } from '../SettingsLayout';
import { SettingsLayout } from '../SettingsLayout/SettingsLayout';
import { useTranslationRef } from '@backstage/frontend-plugin-api';
import { userSettingsTranslationRef } from '../../translation';