diff --git a/docs/plugins/customization.md b/docs/plugins/customization.md index 566b843def..e9a92d1021 100644 --- a/docs/plugins/customization.md +++ b/docs/plugins/customization.md @@ -18,8 +18,12 @@ customizable elements. For example ```typescript jsx const plugin = createPlugin({ id: 'my-plugin', - options: { - createButtonTitle: 'Create', + configure(options?: PluginInputOptions): PluginOptions { + const defaultOptions = { createButtonTitle: 'Create' }; + if (!options) { + return defaultOptions; + } + return { ...defaultOptions, ...options }; }, }); ``` @@ -50,8 +54,7 @@ plugin. Example: ```typescript jsx import { myPlugin } from '@backstage/my-plugin'; -myPlugin.reconfigure((options: CatalogPageOptionsProps) => ({ - ...options, +myPlugin.reconfigure({ createButtonTitle: 'Maybe Create', -})); +}); ``` diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 2499055e7d..35c61f2f16 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -97,7 +97,6 @@ import * as plugins from './plugins'; import { techDocsPage } from './components/techdocs/TechDocsPage'; import { ApacheAirflowPage } from '@backstage/plugin-apache-airflow'; import { PermissionedRoute } from '@backstage/plugin-permission-react'; -import { AnyPluginOptions } from '@backstage/core-plugin-api'; import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common'; const app = createApp({ diff --git a/packages/core-plugin-api/src/extensions/extensions.tsx b/packages/core-plugin-api/src/extensions/extensions.tsx index af883b428e..c0d54af2c1 100644 --- a/packages/core-plugin-api/src/extensions/extensions.tsx +++ b/packages/core-plugin-api/src/extensions/extensions.tsx @@ -236,12 +236,6 @@ export function createReactExtension< | { id?: string } | undefined; - const renderComponent = () => ( - - - - ); - return ( }> @@ -252,7 +246,11 @@ export function createReactExtension< ...(mountPoint && { routeRef: mountPoint.id }), }} > - {renderComponent()} + + + diff --git a/packages/core-plugin-api/src/plugin/Plugin.tsx b/packages/core-plugin-api/src/plugin/Plugin.tsx index 07d3cf64cd..fb2f304b46 100644 --- a/packages/core-plugin-api/src/plugin/Plugin.tsx +++ b/packages/core-plugin-api/src/plugin/Plugin.tsx @@ -20,9 +20,9 @@ import { Extension, AnyRoutes, AnyExternalRoutes, - AnyPluginOptions, + PluginOptions, + PluginInputOptions, PluginFeatureFlagConfig, - ReconfigureFunction, } from './types'; import { AnyApiFactory } from '../apis'; @@ -32,16 +32,9 @@ import { AnyApiFactory } from '../apis'; export class PluginImpl< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, - PluginOptions extends AnyPluginOptions, -> implements BackstagePlugin +> implements BackstagePlugin { - constructor( - private readonly config: PluginConfig< - Routes, - ExternalRoutes, - PluginOptions - >, - ) {} + constructor(private readonly config: PluginConfig) {} getId(): string { return this.config.id; @@ -67,13 +60,16 @@ export class PluginImpl< return extension.expose(this); } - reconfigure(fn: ReconfigureFunction): void { - if (this.config.options) { - this.config.options = fn(this.config.options) as PluginOptions; + reconfigure(options: PluginInputOptions): void { + if (this.config.configure) { + this.config.options = this.config.configure(options); } } getPluginOptions(): PluginOptions { + if (this.config.configure && !this.config.options) { + this.config.options = this.config.configure(); + } return this.config.options ?? ({} as PluginOptions); } @@ -91,9 +87,8 @@ export class PluginImpl< export function createPlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, - PluginOptions extends AnyPluginOptions = {}, >( - config: PluginConfig, -): BackstagePlugin { + config: PluginConfig, +): BackstagePlugin { return new PluginImpl(config); } diff --git a/packages/core-plugin-api/src/plugin/index.ts b/packages/core-plugin-api/src/plugin/index.ts index 5885fb1bc6..6826ba37c6 100644 --- a/packages/core-plugin-api/src/plugin/index.ts +++ b/packages/core-plugin-api/src/plugin/index.ts @@ -17,7 +17,8 @@ export { createPlugin } from './Plugin'; export type { AnyExternalRoutes, - AnyPluginOptions, + PluginOptions, + PluginInputOptions, AnyRoutes, BackstagePlugin, Extension, diff --git a/packages/core-plugin-api/src/plugin/types.ts b/packages/core-plugin-api/src/plugin/types.ts index 51cd00b2b0..fa8778ce93 100644 --- a/packages/core-plugin-api/src/plugin/types.ts +++ b/packages/core-plugin-api/src/plugin/types.ts @@ -49,12 +49,8 @@ export type AnyExternalRoutes = { [name: string]: ExternalRouteRef }; * * @public */ -export type AnyPluginOptions = { [name: string]: unknown }; -export type AnyPluginInputOptions = { [name: string]: unknown }; - -export type ReconfigureFunction = ( - options: AnyPluginInputOptions, -) => AnyPluginOptions; +export type PluginOptions = { [name: string]: unknown }; +export type PluginInputOptions = { [name: string]: unknown }; /** * Plugin type. @@ -64,7 +60,6 @@ export type ReconfigureFunction = ( export type BackstagePlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, - PluginOptions extends AnyPluginOptions = { [name: string]: any }, > = { getId(): string; getApis(): Iterable; @@ -74,7 +69,7 @@ export type BackstagePlugin< getFeatureFlags(): Iterable; provide(extension: Extension): T; getPluginOptions(): PluginOptions; - reconfigure(fn: ReconfigureFunction): void; + reconfigure(options: PluginInputOptions): void; routes: Routes; externalRoutes: ExternalRoutes; }; @@ -97,7 +92,6 @@ export type PluginFeatureFlagConfig = { export type PluginConfig< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, - PluginOptions extends AnyPluginOptions, > = { id: string; apis?: Iterable; @@ -105,6 +99,7 @@ export type PluginConfig< externalRoutes?: ExternalRoutes; featureFlags?: PluginFeatureFlagConfig[]; options?: PluginOptions; + configure?(options?: PluginInputOptions): PluginOptions; }; /** diff --git a/plugins/catalog/src/plugin.ts b/plugins/catalog/src/plugin.ts index 1b9083e7ca..61612c404b 100644 --- a/plugins/catalog/src/plugin.ts +++ b/plugins/catalog/src/plugin.ts @@ -30,6 +30,8 @@ import { discoveryApiRef, fetchApiRef, storageApiRef, + PluginOptions, + PluginInputOptions, } from '@backstage/core-plugin-api'; import { DefaultStarredEntitiesApi } from './apis'; import { AboutCardProps } from './components/AboutCard'; @@ -72,6 +74,13 @@ export const catalogPlugin = createPlugin({ createComponent: createComponentRouteRef, viewTechDoc: viewTechDocRouteRef, }, + configure(options?: PluginInputOptions): PluginOptions { + const defaultOptions = { createButtonTitle: 'Create' }; + if (!options) { + return defaultOptions; + } + return { ...defaultOptions, ...options }; + }, }); /** @public */