From f9ef6326fda71823cdfdfb2dfd6f9582d717493c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 13 Dec 2023 15:54:49 +0100 Subject: [PATCH] frontend-plugin-api: move out several coreExtensionData refs Signed-off-by: Patrik Oldsberg --- .changeset/unlucky-islands-joke.md | 5 ++ .changeset/violet-clouds-press.md | 5 ++ .../frontend-app-api/src/extensions/Core.tsx | 9 +- .../src/extensions/CoreNav.tsx | 16 ++-- .../src/extensions/CoreRouter.tsx | 5 +- .../src/wiring/createApp.test.tsx | 10 +-- .../frontend-app-api/src/wiring/createApp.tsx | 12 ++- packages/frontend-plugin-api/api-report.md | 90 ++++++++++++++----- .../src/extensions/createApiExtension.ts | 10 ++- .../extensions/createComponentExtension.tsx | 12 ++- .../src/extensions/createNavItemExtension.tsx | 14 ++- .../src/extensions/createNavLogoExtension.tsx | 12 ++- .../extensions/createSignInPageExtension.tsx | 13 +-- .../src/extensions/createThemeExtension.ts | 10 ++- .../extensions/createTranslationExtension.ts | 2 +- .../src/extensions/index.ts | 1 + .../src/wiring/coreExtensionData.ts | 29 +----- .../frontend-plugin-api/src/wiring/index.ts | 6 +- 18 files changed, 167 insertions(+), 94 deletions(-) create mode 100644 .changeset/unlucky-islands-joke.md create mode 100644 .changeset/violet-clouds-press.md diff --git a/.changeset/unlucky-islands-joke.md b/.changeset/unlucky-islands-joke.md new file mode 100644 index 0000000000..f165e2c460 --- /dev/null +++ b/.changeset/unlucky-islands-joke.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-plugin-api': minor +--- + +Moved several extension data references from `coreExtensionData` to their respective extension creators. diff --git a/.changeset/violet-clouds-press.md b/.changeset/violet-clouds-press.md new file mode 100644 index 0000000000..b2a46026fe --- /dev/null +++ b/.changeset/violet-clouds-press.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': patch +--- + +Updates to match the new `coreExtensionData` structure. diff --git a/packages/frontend-app-api/src/extensions/Core.tsx b/packages/frontend-app-api/src/extensions/Core.tsx index 6c6e208b5b..99780e231c 100644 --- a/packages/frontend-app-api/src/extensions/Core.tsx +++ b/packages/frontend-app-api/src/extensions/Core.tsx @@ -16,8 +16,11 @@ import { coreExtensionData, + createApiExtension, + createComponentExtension, createExtension, createExtensionInput, + createThemeExtension, createTranslationExtension, } from '@backstage/frontend-plugin-api'; @@ -26,13 +29,13 @@ export const Core = createExtension({ attachTo: { id: 'root', input: 'default' }, // ignored inputs: { apis: createExtensionInput({ - api: coreExtensionData.apiFactory, + api: createApiExtension.factoryDataRef, }), themes: createExtensionInput({ - theme: coreExtensionData.theme, + theme: createThemeExtension.themeDataRef, }), components: createExtensionInput({ - component: coreExtensionData.component, + component: createComponentExtension.componentDataRef, }), translations: createExtensionInput({ translation: createTranslationExtension.translationDataRef, diff --git a/packages/frontend-app-api/src/extensions/CoreNav.tsx b/packages/frontend-app-api/src/extensions/CoreNav.tsx index ab9f29a15d..12e6b08989 100644 --- a/packages/frontend-app-api/src/extensions/CoreNav.tsx +++ b/packages/frontend-app-api/src/extensions/CoreNav.tsx @@ -19,9 +19,9 @@ import { createExtension, coreExtensionData, createExtensionInput, - LogoElements, - NavTarget, useRouteRef, + createNavItemExtension, + createNavLogoExtension, } from '@backstage/frontend-plugin-api'; import { makeStyles } from '@material-ui/core'; import { @@ -52,7 +52,9 @@ const useSidebarLogoStyles = makeStyles({ }, }); -const SidebarLogo = (props: LogoElements) => { +const SidebarLogo = ( + props: (typeof createNavLogoExtension.logoElementsDataRef)['T'], +) => { const classes = useSidebarLogoStyles(); const { isOpen } = useSidebarOpenState(); @@ -67,7 +69,9 @@ const SidebarLogo = (props: LogoElements) => { ); }; -const SidebarNavItem = (props: NavTarget) => { +const SidebarNavItem = ( + props: (typeof createNavItemExtension.targetDataRef)['T'], +) => { const { icon: Icon, title, routeRef } = props; const to = useRouteRef(routeRef)(); // TODO: Support opening modal, for example, the search one @@ -80,11 +84,11 @@ export const CoreNav = createExtension({ attachTo: { id: 'core/layout', input: 'nav' }, inputs: { items: createExtensionInput({ - target: coreExtensionData.navTarget, + target: createNavItemExtension.targetDataRef, }), logos: createExtensionInput( { - elements: coreExtensionData.logoElements, + elements: createNavLogoExtension.logoElementsDataRef, }, { singleton: true, diff --git a/packages/frontend-app-api/src/extensions/CoreRouter.tsx b/packages/frontend-app-api/src/extensions/CoreRouter.tsx index 4dc73c91af..3abb7756bc 100644 --- a/packages/frontend-app-api/src/extensions/CoreRouter.tsx +++ b/packages/frontend-app-api/src/extensions/CoreRouter.tsx @@ -19,6 +19,7 @@ import { coreExtensionData, createExtension, createExtensionInput, + createSignInPageExtension, } from '@backstage/frontend-plugin-api'; import { ConfigApi, @@ -31,8 +32,6 @@ import { InternalAppContext } from '../wiring/InternalAppContext'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { AppIdentityProxy } from '../../../core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy'; import { BrowserRouter } from 'react-router-dom'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { signInPageComponentDataRef } from '../../../frontend-plugin-api/src/extensions/createSignInPageExtension'; import { RouteTracker } from '../routing/RouteTracker'; export const CoreRouter = createExtension({ @@ -42,7 +41,7 @@ export const CoreRouter = createExtension({ inputs: { signInPage: createExtensionInput( { - component: signInPageComponentDataRef, + component: createSignInPageExtension.componentDataRef, }, { singleton: true, optional: true }, ), diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx index 32773de7e1..9126b9a954 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx @@ -201,13 +201,13 @@ describe('createApp', () => { ] components [ - - - + + + ] themes [ - - + + ] " `); diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index c1c1e3e283..1c3146575b 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -23,6 +23,10 @@ import { ComponentRef, componentsApiRef, coreExtensionData, + createApiExtension, + createComponentExtension, + createNavItemExtension, + createThemeExtension, createTranslationExtension, ExtensionDataRef, ExtensionOverrides, @@ -194,7 +198,7 @@ export function createExtensionTree(options: { return this.getExtensionAttachments('core/nav', 'items') .map((node, index) => { - const target = node.getData(coreExtensionData.navTarget); + const target = node.getData(createNavItemExtension.targetDataRef); if (!target) { return null; } @@ -365,13 +369,13 @@ function createApiHolder( const pluginApis = tree.root.edges.attachments .get('apis') - ?.map(e => e.instance?.getData(coreExtensionData.apiFactory)) + ?.map(e => e.instance?.getData(createApiExtension.factoryDataRef)) .filter((x): x is AnyApiFactory => !!x) ?? []; const themeExtensions = tree.root.edges.attachments .get('themes') - ?.map(e => e.instance?.getData(coreExtensionData.theme)) + ?.map(e => e.instance?.getData(createThemeExtension.themeDataRef)) .filter((x): x is AppTheme => !!x) ?? []; const translationResources = @@ -412,7 +416,7 @@ function createApiHolder( const componentsExtensions = tree.root.edges.attachments .get('components') - ?.map(e => e.instance?.getData(coreExtensionData.component)) + ?.map(e => e.instance?.getData(createComponentExtension.componentDataRef)) .filter(x => !!x) ?? []; const componentsMap = componentsExtensions.reduce( diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 6bd3000867..e0330d22e7 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -347,18 +347,7 @@ export type CoreErrorBoundaryFallbackProps = { export const coreExtensionData: { reactElement: ConfigurableExtensionDataRef; routePath: ConfigurableExtensionDataRef; - apiFactory: ConfigurableExtensionDataRef; routeRef: ConfigurableExtensionDataRef, {}>; - navTarget: ConfigurableExtensionDataRef; - theme: ConfigurableExtensionDataRef; - logoElements: ConfigurableExtensionDataRef; - component: ConfigurableExtensionDataRef< - { - ref: ComponentRef; - impl: ComponentType; - }, - {} - >; }; // @public (undocumented) @@ -391,6 +380,12 @@ export function createApiExtension< }, ): ExtensionDefinition; +// @public (undocumented) +export namespace createApiExtension { + const // (undocumented) + factoryDataRef: ConfigurableExtensionDataRef; +} + export { createApiFactory }; export { createApiRef }; @@ -421,6 +416,18 @@ export function createComponentExtension< }; }): ExtensionDefinition; +// @public (undocumented) +export namespace createComponentExtension { + const // (undocumented) + componentDataRef: ConfigurableExtensionDataRef< + { + ref: ComponentRef; + impl: ComponentType; + }, + {} + >; +} + // @public (undocumented) export function createExtension< TOutput extends AnyExtensionDataMap, @@ -527,6 +534,39 @@ export function createNavItemExtension(options: { title: string; }>; +// @public (undocumented) +export namespace createNavItemExtension { + const // (undocumented) + targetDataRef: ConfigurableExtensionDataRef< + { + title: string; + icon: IconComponent_2; + routeRef: RouteRef; + }, + {} + >; +} + +// @public +export function createNavLogoExtension(options: { + name?: string; + namespace?: string; + logoIcon: JSX.Element; + logoFull: JSX.Element; +}): ExtensionDefinition; + +// @public (undocumented) +export namespace createNavLogoExtension { + const // (undocumented) + logoElementsDataRef: ConfigurableExtensionDataRef< + { + logoIcon?: JSX.Element | undefined; + logoFull?: JSX.Element | undefined; + }, + {} + >; +} + // @public export function createPageExtension< TConfig extends { @@ -611,6 +651,15 @@ export function createSignInPageExtension< }) => Promise>; }): ExtensionDefinition; +// @public (undocumented) +export namespace createSignInPageExtension { + const // (undocumented) + componentDataRef: ConfigurableExtensionDataRef< + React_2.ComponentType, + {} + >; +} + // @public export function createSubRouteRef< Path extends string, @@ -625,6 +674,12 @@ export function createThemeExtension( theme: AppTheme, ): ExtensionDefinition; +// @public (undocumented) +export namespace createThemeExtension { + const // (undocumented) + themeDataRef: ConfigurableExtensionDataRef; +} + // @public (undocumented) export function createTranslationExtension(options: { name?: string; @@ -848,21 +903,8 @@ export { IdentityApi }; export { identityApiRef }; -// @public (undocumented) -export type LogoElements = { - logoIcon?: JSX_2.Element; - logoFull?: JSX_2.Element; -}; - export { microsoftAuthApiRef }; -// @public (undocumented) -export type NavTarget = { - title: string; - icon: IconComponent_2; - routeRef: RouteRef; -}; - export { OAuthApi }; export { OAuthRequestApi }; diff --git a/packages/frontend-plugin-api/src/extensions/createApiExtension.ts b/packages/frontend-plugin-api/src/extensions/createApiExtension.ts index bbaef3c849..e941c4f2a0 100644 --- a/packages/frontend-plugin-api/src/extensions/createApiExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createApiExtension.ts @@ -19,7 +19,7 @@ import { PortableSchema } from '../schema'; import { ResolvedExtensionInputs, createExtension, - coreExtensionData, + createExtensionDataRef, } from '../wiring'; import { AnyExtensionInputMap } from '../wiring/createExtension'; import { Expand } from '../types'; @@ -59,7 +59,7 @@ export function createApiExtension< inputs: extensionInputs, configSchema, output: { - api: coreExtensionData.apiFactory, + api: createApiExtension.factoryDataRef, }, factory({ config, inputs }) { if (typeof factory === 'function') { @@ -69,3 +69,9 @@ export function createApiExtension< }, }); } + +/** @public */ +export namespace createApiExtension { + export const factoryDataRef = + createExtensionDataRef('core.api.factory'); +} diff --git a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx index 816dee6054..c3bcf9bc0e 100644 --- a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx @@ -18,8 +18,8 @@ import React, { lazy, ComponentType } from 'react'; import { AnyExtensionInputMap, ResolvedExtensionInputs, - coreExtensionData, createExtension, + createExtensionDataRef, } from '../wiring'; import { Expand } from '../types'; import { PortableSchema } from '../schema'; @@ -59,7 +59,7 @@ export function createComponentExtension< disabled: options.disabled, configSchema: options.configSchema, output: { - component: coreExtensionData.component, + component: createComponentExtension.componentDataRef, }, factory({ config, inputs, node }) { let ExtensionComponent: ComponentType; @@ -88,3 +88,11 @@ export function createComponentExtension< }, }); } + +/** @public */ +export namespace createComponentExtension { + export const componentDataRef = createExtensionDataRef<{ + ref: ComponentRef; + impl: ComponentType; + }>('core.component.component'); +} diff --git a/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx b/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx index 207778fbd7..d2062c74c5 100644 --- a/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx @@ -16,7 +16,7 @@ import { IconComponent } from '@backstage/core-plugin-api'; import { createSchemaFromZod } from '../schema/createSchemaFromZod'; -import { coreExtensionData, createExtension } from '../wiring'; +import { createExtension, createExtensionDataRef } from '../wiring'; import { RouteRef } from '../routing'; /** @@ -42,7 +42,7 @@ export function createNavItemExtension(options: { }), ), output: { - navTarget: coreExtensionData.navTarget, + navTarget: createNavItemExtension.targetDataRef, }, factory: ({ config }) => ({ navTarget: { @@ -53,3 +53,13 @@ export function createNavItemExtension(options: { }), }); } + +/** @public */ +export namespace createNavItemExtension { + // TODO(Rugvip): Should this be broken apart into separate refs? title/icon/routeRef + export const targetDataRef = createExtensionDataRef<{ + title: string; + icon: IconComponent; + routeRef: RouteRef; + }>('core.nav-item.target'); +} diff --git a/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx b/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx index 878764bad7..8e2454ddc3 100644 --- a/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { coreExtensionData, createExtension } from '../wiring'; +import { createExtension, createExtensionDataRef } from '../wiring'; /** * Helper for creating extensions for a nav logos. @@ -33,7 +33,7 @@ export function createNavLogoExtension(options: { namespace: options?.namespace, attachTo: { id: 'core/nav', input: 'logos' }, output: { - logos: coreExtensionData.logoElements, + logos: createNavLogoExtension.logoElementsDataRef, }, factory: () => { return { @@ -45,3 +45,11 @@ export function createNavLogoExtension(options: { }, }); } + +/** @public */ +export namespace createNavLogoExtension { + export const logoElementsDataRef = createExtensionDataRef<{ + logoIcon?: JSX.Element; + logoFull?: JSX.Element; + }>('core.nav-logo.logo-elements'); +} diff --git a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx index d04c29fb9b..ee993b1bc0 100644 --- a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx @@ -27,10 +27,6 @@ import { import { Expand } from '../types'; import { SignInPageProps } from '@backstage/core-plugin-api'; -/** @internal */ -export const signInPageComponentDataRef = - createExtensionDataRef>('core.signInPage'); - /** * * @public @@ -59,7 +55,7 @@ export function createSignInPageExtension< inputs: options.inputs, disabled: options.disabled, output: { - component: signInPageComponentDataRef, + component: createSignInPageExtension.componentDataRef, }, factory({ config, inputs, node }) { const ExtensionComponent = lazy(() => @@ -78,3 +74,10 @@ export function createSignInPageExtension< }, }); } + +/** @public */ +export namespace createSignInPageExtension { + export const componentDataRef = createExtensionDataRef< + ComponentType + >('core.sign-in-page.component'); +} diff --git a/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts b/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts index 5554a08874..dd6c2f742f 100644 --- a/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { createExtension, coreExtensionData } from '../wiring'; +import { createExtension, createExtensionDataRef } from '../wiring'; import { AppTheme } from '@backstage/core-plugin-api'; /** @public */ @@ -25,8 +25,14 @@ export function createThemeExtension(theme: AppTheme) { name: theme.id, attachTo: { id: 'core', input: 'themes' }, output: { - theme: coreExtensionData.theme, + theme: createThemeExtension.themeDataRef, }, factory: () => ({ theme }), }); } + +/** @public */ +export namespace createThemeExtension { + export const themeDataRef = + createExtensionDataRef('core.theme.theme'); +} diff --git a/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts b/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts index 59cc87948f..3db29cdeb5 100644 --- a/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts @@ -38,5 +38,5 @@ export function createTranslationExtension(options: { export namespace createTranslationExtension { export const translationDataRef = createExtensionDataRef< TranslationResource | TranslationMessages - >('core.translationResource'); + >('core.translation.translation'); } diff --git a/packages/frontend-plugin-api/src/extensions/index.ts b/packages/frontend-plugin-api/src/extensions/index.ts index 80ad0290dd..fd2e38de49 100644 --- a/packages/frontend-plugin-api/src/extensions/index.ts +++ b/packages/frontend-plugin-api/src/extensions/index.ts @@ -17,6 +17,7 @@ export { createApiExtension } from './createApiExtension'; export { createPageExtension } from './createPageExtension'; export { createNavItemExtension } from './createNavItemExtension'; +export { createNavLogoExtension } from './createNavLogoExtension'; export { createSignInPageExtension } from './createSignInPageExtension'; export { createThemeExtension } from './createThemeExtension'; export { createComponentExtension } from './createComponentExtension'; diff --git a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts index d52a672679..a6ff41f6b0 100644 --- a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts +++ b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts @@ -14,40 +14,13 @@ * limitations under the License. */ -import { ComponentType, JSX } from 'react'; -import { - AnyApiFactory, - AppTheme, - IconComponent, -} from '@backstage/core-plugin-api'; +import { JSX } from 'react'; import { RouteRef } from '../routing'; -import { ComponentRef } from '../components'; import { createExtensionDataRef } from './createExtensionDataRef'; -/** @public */ -export type NavTarget = { - title: string; - icon: IconComponent; - routeRef: RouteRef; -}; - -/** @public */ -export type LogoElements = { - logoIcon?: JSX.Element; - logoFull?: JSX.Element; -}; - /** @public */ export const coreExtensionData = { reactElement: createExtensionDataRef('core.reactElement'), routePath: createExtensionDataRef('core.routing.path'), - apiFactory: createExtensionDataRef('core.api.factory'), routeRef: createExtensionDataRef('core.routing.ref'), - navTarget: createExtensionDataRef('core.nav.target'), - theme: createExtensionDataRef('core.theme'), - logoElements: createExtensionDataRef('core.logos'), - component: createExtensionDataRef<{ - ref: ComponentRef; - impl: ComponentType; - }>('core.component'), }; diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index 3f33910ca7..9438dcb20c 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -export { - coreExtensionData, - type LogoElements, - type NavTarget, -} from './coreExtensionData'; +export { coreExtensionData } from './coreExtensionData'; export { createExtension, type Extension,