diff --git a/packages/app-example-plugin/report.api.md b/packages/app-example-plugin/report.api.md index d6059e7d05..70b3446a2b 100644 --- a/packages/app-example-plugin/report.api.md +++ b/packages/app-example-plugin/report.api.md @@ -91,7 +91,7 @@ const examplePlugin: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef; noHeader?: boolean; }; diff --git a/packages/frontend-plugin-api/report.api.md b/packages/frontend-plugin-api/report.api.md index 50ebf01a31..44a2ab3ced 100644 --- a/packages/frontend-plugin-api/report.api.md +++ b/packages/frontend-plugin-api/report.api.md @@ -1722,7 +1722,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{ path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef; noHeader?: boolean; }; @@ -1735,7 +1735,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{ optional: true; } > - | ExtensionDataRef_2 + | ExtensionDataRef_2 | ExtensionDataRef_2< string, 'core.title', @@ -1752,7 +1752,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{ >; inputs: { pages: ExtensionInput_2< - | ConfigurableExtensionDataRef_2 + | ConfigurableExtensionDataRef_2 | ConfigurableExtensionDataRef_2 | ConfigurableExtensionDataRef_2< RouteRef, @@ -1804,7 +1804,7 @@ export interface PageLayoutProps { // (undocumented) children?: ReactNode; // (undocumented) - headerActions?: ReactNode; + headerActions?: Array; // (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; }; // @public diff --git a/packages/frontend-plugin-api/src/apis/definitions/PluginHeaderActionsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/PluginHeaderActionsApi.ts index 6f235148c6..4f8f5e2053 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/PluginHeaderActionsApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/PluginHeaderActionsApi.ts @@ -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; }; /** diff --git a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx index bb4c569138..cfba1dccec 100644 --- a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx +++ b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx @@ -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 ( { const firstPagePath = inputs.pages[0]?.get(coreExtensionData.routePath); - const headerActions = usePluginHeaderActions(pluginId); + + const headerActionsApi = useApi(pluginHeaderActionsApiRef); + const headerActions = headerActionsApi.getPluginHeaderActions(pluginId); return ( ); } else { const PageContent = () => { - const headerActions = usePluginHeaderActions(pluginId); + const headerActionsApi = useApi(pluginHeaderActionsApiRef); + const headerActions = headerActionsApi.getPluginHeaderActions(pluginId); return ( ); diff --git a/packages/frontend-plugin-api/src/components/PageLayout.tsx b/packages/frontend-plugin-api/src/components/PageLayout.tsx index 89bf6670cc..20d57321f6 100644 --- a/packages/frontend-plugin-api/src/components/PageLayout.tsx +++ b/packages/frontend-plugin-api/src/components/PageLayout.tsx @@ -38,7 +38,7 @@ export interface PageLayoutProps { title?: string; icon?: IconElement; noHeader?: boolean; - headerActions?: ReactNode; + headerActions?: Array; tabs?: PageTab[]; children?: ReactNode; } diff --git a/plugins/api-docs/report-alpha.api.md b/plugins/api-docs/report-alpha.api.md index 97292b10d7..de6388ed2b 100644 --- a/plugins/api-docs/report-alpha.api.md +++ b/plugins/api-docs/report-alpha.api.md @@ -567,7 +567,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/app-visualizer/report.api.md b/plugins/app-visualizer/report.api.md index 4d6b16d729..e0e3f26dd2 100644 --- a/plugins/app-visualizer/report.api.md +++ b/plugins/app-visualizer/report.api.md @@ -113,7 +113,7 @@ const visualizerPlugin: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef; noHeader?: boolean; }; diff --git a/plugins/app/src/apis/PluginHeaderActionsApi/DefaultPluginHeaderActionsApi.tsx b/plugins/app/src/apis/PluginHeaderActionsApi/DefaultPluginHeaderActionsApi.tsx index fc823fe315..869ddf503e 100644 --- a/plugins/app/src/apis/PluginHeaderActionsApi/DefaultPluginHeaderActionsApi.tsx +++ b/plugins/app/src/apis/PluginHeaderActionsApi/DefaultPluginHeaderActionsApi.tsx @@ -14,9 +14,12 @@ * limitations under the License. */ -import { ReactNode } from 'react'; +import { JSX } from 'react'; import { type PluginHeaderActionsApi } from '@backstage/frontend-plugin-api'; +// Stable reference +const EMPTY_ACTIONS = new Array(); + type ActionInput = { element: JSX.Element; pluginId: string; @@ -28,16 +31,18 @@ type ActionInput = { * @internal */ export class DefaultPluginHeaderActionsApi implements PluginHeaderActionsApi { - constructor(private readonly actionsByPlugin: Map) {} + constructor( + private readonly actionsByPlugin: Map>, + ) {} - getPluginHeaderActions(pluginId: string): ReactNode[] { - return this.actionsByPlugin.get(pluginId) ?? []; + getPluginHeaderActions(pluginId: string): Array { + return this.actionsByPlugin.get(pluginId) ?? EMPTY_ACTIONS; } static fromActions( actions: Array, ): DefaultPluginHeaderActionsApi { - const actionsByPlugin = new Map(); + const actionsByPlugin = new Map>(); for (const action of actions) { let pluginActions = actionsByPlugin.get(action.pluginId); diff --git a/plugins/auth/report.api.md b/plugins/auth/report.api.md index bb859bf300..a281d265dc 100644 --- a/plugins/auth/report.api.md +++ b/plugins/auth/report.api.md @@ -92,7 +92,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef; noHeader?: boolean; }; diff --git a/plugins/catalog-graph/report-alpha.api.md b/plugins/catalog-graph/report-alpha.api.md index 5346f83664..f11aa9a21b 100644 --- a/plugins/catalog-graph/report-alpha.api.md +++ b/plugins/catalog-graph/report-alpha.api.md @@ -242,7 +242,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/catalog-import/report-alpha.api.md b/plugins/catalog-import/report-alpha.api.md index d51ba2aa29..ba841a7f70 100644 --- a/plugins/catalog-import/report-alpha.api.md +++ b/plugins/catalog-import/report-alpha.api.md @@ -185,7 +185,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/catalog-unprocessed-entities/report-alpha.api.md b/plugins/catalog-unprocessed-entities/report-alpha.api.md index bbb679db98..30b115f07e 100644 --- a/plugins/catalog-unprocessed-entities/report-alpha.api.md +++ b/plugins/catalog-unprocessed-entities/report-alpha.api.md @@ -134,7 +134,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/catalog/report-alpha.api.md b/plugins/catalog/report-alpha.api.md index e859896b31..c2d856561f 100644 --- a/plugins/catalog/report-alpha.api.md +++ b/plugins/catalog/report-alpha.api.md @@ -1084,7 +1084,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; @@ -1266,7 +1266,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/devtools/report-alpha.api.md b/plugins/devtools/report-alpha.api.md index 87538d1021..6c3cfab581 100644 --- a/plugins/devtools/report-alpha.api.md +++ b/plugins/devtools/report-alpha.api.md @@ -150,7 +150,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/home/report-alpha.api.md b/plugins/home/report-alpha.api.md index 84b60dd7ff..48f7853cd7 100644 --- a/plugins/home/report-alpha.api.md +++ b/plugins/home/report-alpha.api.md @@ -198,7 +198,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef; noHeader?: boolean; }; diff --git a/plugins/kubernetes/report-alpha.api.md b/plugins/kubernetes/report-alpha.api.md index 60f1c2aefa..86b824b2f4 100644 --- a/plugins/kubernetes/report-alpha.api.md +++ b/plugins/kubernetes/report-alpha.api.md @@ -232,7 +232,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/mui-to-bui/report.api.md b/plugins/mui-to-bui/report.api.md index bddefc53bc..302804d432 100644 --- a/plugins/mui-to-bui/report.api.md +++ b/plugins/mui-to-bui/report.api.md @@ -106,7 +106,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/notifications/report-alpha.api.md b/plugins/notifications/report-alpha.api.md index aad05cac8f..7ec24ef81e 100644 --- a/plugins/notifications/report-alpha.api.md +++ b/plugins/notifications/report-alpha.api.md @@ -112,7 +112,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/scaffolder/report-alpha.api.md b/plugins/scaffolder/report-alpha.api.md index a3e19502fa..943b139cb9 100644 --- a/plugins/scaffolder/report-alpha.api.md +++ b/plugins/scaffolder/report-alpha.api.md @@ -276,7 +276,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/search/report-alpha.api.md b/plugins/search/report-alpha.api.md index 55e8ca58ce..98a47d6b1e 100644 --- a/plugins/search/report-alpha.api.md +++ b/plugins/search/report-alpha.api.md @@ -185,7 +185,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef; noHeader?: boolean; }; @@ -355,7 +355,7 @@ export const searchPage: OverridableExtensionDefinition<{ path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef; noHeader?: boolean; }; diff --git a/plugins/techdocs/report-alpha.api.md b/plugins/techdocs/report-alpha.api.md index db59166f54..5cf7b4fd7a 100644 --- a/plugins/techdocs/report-alpha.api.md +++ b/plugins/techdocs/report-alpha.api.md @@ -352,7 +352,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; @@ -445,7 +445,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef_2; noHeader?: boolean; }; diff --git a/plugins/user-settings/report-alpha.api.md b/plugins/user-settings/report-alpha.api.md index f26414fd75..11ffee9229 100644 --- a/plugins/user-settings/report-alpha.api.md +++ b/plugins/user-settings/report-alpha.api.md @@ -124,7 +124,7 @@ const _default: OverridableFrontendPlugin< path: string; title?: string; icon?: IconElement; - loader?: () => Promise; + loader?: () => Promise; routeRef?: RouteRef; noHeader?: boolean; };