frontend-plugin-api: make header actions a element[]

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2026-02-17 12:35:20 +01:00
parent c37e2bf6d4
commit b7ae1243e0
22 changed files with 47 additions and 46 deletions
+5 -5
View File
@@ -1722,7 +1722,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{
path: string;
title?: string;
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
loader?: () => Promise<JSX_2.Element>;
routeRef?: RouteRef;
noHeader?: boolean;
};
@@ -1735,7 +1735,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{
optional: true;
}
>
| ExtensionDataRef_2<JSX_2, 'core.reactElement', {}>
| ExtensionDataRef_2<JSX_2.Element, 'core.reactElement', {}>
| ExtensionDataRef_2<
string,
'core.title',
@@ -1752,7 +1752,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{
>;
inputs: {
pages: ExtensionInput_2<
| ConfigurableExtensionDataRef_2<JSX_2, 'core.reactElement', {}>
| ConfigurableExtensionDataRef_2<JSX_2.Element, 'core.reactElement', {}>
| ConfigurableExtensionDataRef_2<string, 'core.routing.path', {}>
| ConfigurableExtensionDataRef_2<
RouteRef<AnyRouteRefParams_2>,
@@ -1804,7 +1804,7 @@ export interface PageLayoutProps {
// (undocumented)
children?: ReactNode;
// (undocumented)
headerActions?: ReactNode;
headerActions?: Array<JSX.Element | null>;
// (undocumented)
icon?: IconElement;
// (undocumented)
@@ -1853,7 +1853,7 @@ export const PluginHeaderActionBlueprint: ExtensionBlueprint_2<{
// @public
export type PluginHeaderActionsApi = {
getPluginHeaderActions(pluginId: string): ReactNode[];
getPluginHeaderActions(pluginId: string): Array<JSX_2.Element | null>;
};
// @public
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { ReactNode } from 'react';
import { JSX } from 'react';
import { createApiRef } from '../system';
/**
@@ -32,7 +32,7 @@ export type PluginHeaderActionsApi = {
/**
* Returns the header actions for a given plugin.
*/
getPluginHeaderActions(pluginId: string): ReactNode[];
getPluginHeaderActions(pluginId: string): Array<JSX.Element | null>;
};
/**
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { ReactNode } from 'react';
import { JSX } from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import { IconElement } from '../icons/types';
import { RouteRef } from '../routing';
@@ -27,15 +27,6 @@ import { ExtensionBoundary, PageLayout, PageTab } from '../components';
import { useApi } from '../apis/system';
import { pluginHeaderActionsApiRef } from '../apis/definitions/PluginHeaderActionsApi';
function usePluginHeaderActions(pluginId: string): ReactNode {
const pluginHeaderActionsApi = useApi(pluginHeaderActionsApiRef);
const actions = pluginHeaderActionsApi.getPluginHeaderActions(pluginId);
if (actions.length === 0) {
return undefined;
}
return <>{actions}</>;
}
/**
* Creates extensions that are routable React page components.
*
@@ -93,7 +84,9 @@ export const PageBlueprint = createExtensionBlueprint({
if (params.loader) {
const loader = params.loader;
const PageContent = () => {
const headerActions = usePluginHeaderActions(pluginId);
const headerActionsApi = useApi(pluginHeaderActionsApiRef);
const headerActions = headerActionsApi.getPluginHeaderActions(pluginId);
return (
<PageLayout
title={title}
@@ -123,7 +116,9 @@ export const PageBlueprint = createExtensionBlueprint({
const PageContent = () => {
const firstPagePath = inputs.pages[0]?.get(coreExtensionData.routePath);
const headerActions = usePluginHeaderActions(pluginId);
const headerActionsApi = useApi(pluginHeaderActionsApiRef);
const headerActions = headerActionsApi.getPluginHeaderActions(pluginId);
return (
<PageLayout
@@ -154,7 +149,8 @@ export const PageBlueprint = createExtensionBlueprint({
yield coreExtensionData.reactElement(<PageContent />);
} else {
const PageContent = () => {
const headerActions = usePluginHeaderActions(pluginId);
const headerActionsApi = useApi(pluginHeaderActionsApiRef);
const headerActions = headerActionsApi.getPluginHeaderActions(pluginId);
return (
<PageLayout title={title} icon={icon} headerActions={headerActions} />
);
@@ -38,7 +38,7 @@ export interface PageLayoutProps {
title?: string;
icon?: IconElement;
noHeader?: boolean;
headerActions?: ReactNode;
headerActions?: Array<JSX.Element | null>;
tabs?: PageTab[];
children?: ReactNode;
}