frontend-plugin-api: added noHeader param for page blueprint

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2026-02-13 13:59:04 +01:00
parent d2705be180
commit 4d2b2642c0
22 changed files with 46 additions and 9 deletions
@@ -93,6 +93,7 @@ const examplePlugin: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
}>;
}
@@ -1757,6 +1757,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
output:
| ExtensionDataRef_2<string, 'core.routing.path', {}>
@@ -1840,6 +1841,8 @@ export interface PageLayoutProps {
// (undocumented)
icon?: IconElement;
// (undocumented)
noHeader?: boolean;
// (undocumented)
tabs?: PageTab[];
// (undocumented)
title?: string;
@@ -77,6 +77,10 @@ export const PageBlueprint = createExtensionBlueprint({
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
/**
* Hide the default plugin page header, making the page fill up all available space.
*/
noHeader?: boolean;
},
{ config, node, inputs },
) {
@@ -87,6 +91,7 @@ export const PageBlueprint = createExtensionBlueprint({
node.spec.plugin.pluginId;
const icon = params.icon ?? node.spec.plugin.icon;
const pluginId = node.spec.plugin.pluginId;
const noHeader = params.noHeader ?? false;
yield coreExtensionData.routePath(config.path ?? params.path);
if (params.loader) {
@@ -94,7 +99,12 @@ export const PageBlueprint = createExtensionBlueprint({
const PageContent = () => {
const headerActions = useHeaderActions(pluginId);
return (
<PageLayout title={title} icon={icon} headerActions={headerActions}>
<PageLayout
title={title}
icon={icon}
noHeader={noHeader}
headerActions={headerActions}
>
{ExtensionBoundary.lazy(node, loader)}
</PageLayout>
);
@@ -37,6 +37,7 @@ export interface PageTab {
export interface PageLayoutProps {
title?: string;
icon?: IconElement;
noHeader?: boolean;
headerActions?: ReactNode;
tabs?: PageTab[];
children?: ReactNode;
+1
View File
@@ -569,6 +569,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
}
+2 -1
View File
@@ -130,8 +130,9 @@ const visualizerPlugin: OverridableFrontendPlugin<
path: string;
title?: string;
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
loader?: () => Promise<JSX.Element /** @public */>;
routeRef?: RouteRef;
noHeader?: boolean;
};
}>;
'sub-page:app-visualizer/details': OverridableExtensionDefinition<{
+9 -7
View File
@@ -73,18 +73,20 @@ export const PageLayout = SwappableComponentBlueprint.make({
define({
component: SwappablePageLayout,
loader: () => (props: PageLayoutProps) => {
const { title, icon, headerActions, tabs, children } = props;
const { title, icon, noHeader, headerActions, tabs, children } = props;
return (
<Flex
direction="column"
style={{ flexGrow: 1, minHeight: 0, gap: 0 }}
>
<Header
title={title}
icon={icon}
tabs={tabs}
customActions={headerActions}
/>
{!noHeader && (
<Header
title={title}
icon={icon}
tabs={tabs}
customActions={headerActions}
/>
)}
<main
style={{
flex: '1 1 0',
+1
View File
@@ -94,6 +94,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
}>;
}
@@ -244,6 +244,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
}
@@ -187,6 +187,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
}
@@ -136,6 +136,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
}
+2
View File
@@ -1086,6 +1086,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
'page:catalog/entity': OverridableExtensionDefinition<{
@@ -1267,6 +1268,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
'search-result-list-item:catalog': OverridableExtensionDefinition<{
+1
View File
@@ -152,6 +152,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
}
+1
View File
@@ -200,6 +200,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
}>;
}
+1
View File
@@ -63,6 +63,7 @@ const homePage = PageBlueprint.makeWithOverrides({
factory(originalFactory, { node, inputs }) {
return originalFactory({
path: '/home',
noHeader: true,
routeRef: rootRouteRef,
loader: async () => {
const LazyDefaultLayout = reactLazy(() =>
+1
View File
@@ -234,6 +234,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
}
+1
View File
@@ -108,6 +108,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
}
@@ -114,6 +114,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
}
+1
View File
@@ -278,6 +278,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
'scaffolder-form-field:scaffolder/entity-name-picker': OverridableExtensionDefinition<{
+2
View File
@@ -187,6 +187,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
}>;
}
@@ -356,6 +357,7 @@ export const searchPage: OverridableExtensionDefinition<{
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
}>;
+2
View File
@@ -354,6 +354,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
'page:techdocs/reader': OverridableExtensionDefinition<{
@@ -446,6 +447,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef_2;
noHeader?: boolean;
};
}>;
'search-result-list-item:techdocs': OverridableExtensionDefinition<{
@@ -126,6 +126,7 @@ const _default: OverridableFrontendPlugin<
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
}>;
}