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 */