diff --git a/plugins/scaffolder/src/alpha.tsx b/plugins/scaffolder/src/alpha.tsx index d1240e19e2..3136626f47 100644 --- a/plugins/scaffolder/src/alpha.tsx +++ b/plugins/scaffolder/src/alpha.tsx @@ -16,14 +16,14 @@ import React from 'react'; import { - createApiExtension, createApiFactory, - createNavItemExtension, - createPageExtension, createFrontendPlugin, discoveryApiRef, fetchApiRef, identityApiRef, + ApiBlueprint, + PageBlueprint, + NavItemBlueprint, } from '@backstage/frontend-plugin-api'; import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; import { @@ -51,36 +51,42 @@ export { type TemplateWizardPageProps, } from './next'; -const scaffolderApi = createApiExtension({ - factory: createApiFactory({ - api: scaffolderApiRef, - deps: { - discoveryApi: discoveryApiRef, - scmIntegrationsApi: scmIntegrationsApiRef, - fetchApi: fetchApiRef, - identityApi: identityApiRef, - }, - factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) => - new ScaffolderClient({ - discoveryApi, - scmIntegrationsApi, - fetchApi, - identityApi, - }), - }), +const scaffolderApi = ApiBlueprint.make({ + params: { + factory: createApiFactory({ + api: scaffolderApiRef, + deps: { + discoveryApi: discoveryApiRef, + scmIntegrationsApi: scmIntegrationsApiRef, + fetchApi: fetchApiRef, + identityApi: identityApiRef, + }, + factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) => + new ScaffolderClient({ + discoveryApi, + scmIntegrationsApi, + fetchApi, + identityApi, + }), + }), + }, }); -const scaffolderPage = createPageExtension({ - routeRef: convertLegacyRouteRef(rootRouteRef), - defaultPath: '/create', - loader: () => - import('./components/Router').then(m => compatWrapper()), +const scaffolderPage = PageBlueprint.make({ + params: { + routeRef: convertLegacyRouteRef(rootRouteRef), + defaultPath: '/create', + loader: () => + import('./components/Router').then(m => compatWrapper()), + }, }); -const scaffolderNavItem = createNavItemExtension({ - routeRef: convertLegacyRouteRef(rootRouteRef), - title: 'Create...', - icon: CreateComponentIcon, +const scaffolderNavItem = NavItemBlueprint.make({ + params: { + routeRef: convertLegacyRouteRef(rootRouteRef), + title: 'Create...', + icon: CreateComponentIcon, + }, }); /** @alpha */ diff --git a/plugins/search/src/alpha.tsx b/plugins/search/src/alpha.tsx index dbb98691c9..90fc394f9d 100644 --- a/plugins/search/src/alpha.tsx +++ b/plugins/search/src/alpha.tsx @@ -38,11 +38,10 @@ import { import { createFrontendPlugin, - createApiExtension, - createPageExtension, + ApiBlueprint, createExtensionInput, - createNavItemExtension, - createSchemaFromZod, + PageBlueprint, + NavItemBlueprint, } from '@backstage/frontend-plugin-api'; import { @@ -62,7 +61,7 @@ import { } from '@backstage/plugin-search-react'; import { SearchResult } from '@backstage/plugin-search-common'; import { searchApiRef } from '@backstage/plugin-search-react'; -import { createSearchResultListItemExtension } from '@backstage/plugin-search-react/alpha'; +import { SearchResultListItemBlueprint } from '@backstage/plugin-search-react/alpha'; import { rootRouteRef } from './plugin'; import { SearchClient } from './apis'; @@ -75,13 +74,15 @@ import { } from '@backstage/core-compat-api'; /** @alpha */ -export const searchApi = createApiExtension({ - factory: createApiFactory({ - api: searchApiRef, - deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, - factory: ({ discoveryApi, fetchApi }) => - new SearchClient({ discoveryApi, fetchApi }), - }), +export const searchApi = ApiBlueprint.make({ + params: { + factory: createApiFactory({ + api: searchApiRef, + deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, + factory: ({ discoveryApi, fetchApi }) => + new SearchClient({ discoveryApi, fetchApi }), + }), + }, }); const useSearchPageStyles = makeStyles((theme: Theme) => ({ @@ -97,143 +98,152 @@ const useSearchPageStyles = makeStyles((theme: Theme) => ({ })); /** @alpha */ -export const searchPage = createPageExtension({ - routeRef: convertLegacyRouteRef(rootRouteRef), - configSchema: createSchemaFromZod(z => - z.object({ - path: z.string().default('/search'), - noTrack: z.boolean().default(false), - }), - ), - inputs: { - items: createExtensionInput({ - item: createSearchResultListItemExtension.itemDataRef, - }), +export const searchPage = PageBlueprint.makeWithOverrides({ + config: { + schema: { + noTrack: z => z.boolean().default(false), + }, }, - loader: async ({ config, inputs }) => { - const getResultItemComponent = (result: SearchResult) => { - const value = inputs.items.find(item => - item?.output.item.predicate?.(result), - ); - return value?.output.item.component ?? DefaultResultListItem; - }; + inputs: { + items: createExtensionInput([SearchResultListItemBlueprint.dataRefs.item]), + }, + factory(originalFactory, { config, inputs }) { + return originalFactory({ + defaultPath: '/search', + routeRef: convertLegacyRouteRef(rootRouteRef), + loader: async () => { + const getResultItemComponent = (result: SearchResult) => { + const value = inputs.items.find(item => + item + ?.get(SearchResultListItemBlueprint.dataRefs.item) + .predicate?.(result), + ); + return ( + value?.get(SearchResultListItemBlueprint.dataRefs.item).component ?? + DefaultResultListItem + ); + }; - const Component = () => { - const classes = useSearchPageStyles(); - const { isMobile } = useSidebarPinState(); - const { types } = useSearch(); - const catalogApi = useApi(catalogApiRef); + const Component = () => { + const classes = useSearchPageStyles(); + const { isMobile } = useSidebarPinState(); + const { types } = useSearch(); + const catalogApi = useApi(catalogApiRef); - return ( - - {!isMobile &&
} - - - - - - {!isMobile && ( - - , - }, - { - value: 'techdocs', - name: 'Documentation', - icon: , - }, - ]} - /> - - {types.includes('techdocs') && ( - { - // Return a list of entities which are documented. - const { items } = await catalogApi.getEntities({ - fields: ['metadata.name'], - filter: { - 'metadata.annotations.backstage.io/techdocs-ref': - CATALOG_FILTER_EXISTS, - }, - }); - - const names = items.map( - entity => entity.metadata.name, - ); - names.sort(); - return names; - }} + return ( + + {!isMobile &&
} + + + + + + {!isMobile && ( + + , + }, + { + value: 'techdocs', + name: 'Documentation', + icon: , + }, + ]} /> - )} - - - - - )} - - - - {({ results }) => ( - <> - {results.map((result, index) => { - const { noTrack } = config; - const { document, ...rest } = result; - const SearchResultListItem = - getResultItemComponent(result); - return ( - - ); - })} - - )} - - - - - - - ); - }; + + {types.includes('techdocs') && ( + { + // Return a list of entities which are documented. + const { items } = await catalogApi.getEntities({ + fields: ['metadata.name'], + filter: { + 'metadata.annotations.backstage.io/techdocs-ref': + CATALOG_FILTER_EXISTS, + }, + }); - return compatWrapper( - - - - , - ); + const names = items.map( + entity => entity.metadata.name, + ); + names.sort(); + return names; + }} + /> + )} + + + + + )} + + + + {({ results }) => ( + <> + {results.map((result, index) => { + const { noTrack } = config; + const { document, ...rest } = result; + const SearchResultListItem = + getResultItemComponent(result); + return ( + + ); + })} + + )} + + + + + + + ); + }; + + return compatWrapper( + + + + , + ); + }, + }); }, }); /** @alpha */ -export const searchNavItem = createNavItemExtension({ - routeRef: convertLegacyRouteRef(rootRouteRef), - title: 'Search', - icon: SearchIcon, +export const searchNavItem = NavItemBlueprint.make({ + params: { + routeRef: convertLegacyRouteRef(rootRouteRef), + title: 'Search', + icon: SearchIcon, + }, }); /** @alpha */