diff --git a/packages/app-next-example-plugin/src/plugin.tsx b/packages/app-next-example-plugin/src/plugin.tsx
index 7c41405c59..818e8abc84 100644
--- a/packages/app-next-example-plugin/src/plugin.tsx
+++ b/packages/app-next-example-plugin/src/plugin.tsx
@@ -16,13 +16,15 @@
import React from 'react';
import {
- createPageExtension,
+ PageBlueprint,
createFrontendPlugin,
} from '@backstage/frontend-plugin-api';
-export const ExamplePage = createPageExtension({
- defaultPath: '/example',
- loader: () => import('./Component').then(m => ),
+export const ExamplePage = PageBlueprint.make({
+ params: {
+ defaultPath: '/example',
+ loader: () => import('./Component').then(m => ),
+ },
});
/** @public */
diff --git a/plugins/api-docs/src/alpha.tsx b/plugins/api-docs/src/alpha.tsx
index 4d803b3991..216666be8f 100644
--- a/plugins/api-docs/src/alpha.tsx
+++ b/plugins/api-docs/src/alpha.tsx
@@ -18,12 +18,11 @@ import React from 'react';
import Grid from '@material-ui/core/Grid';
import {
- createApiExtension,
+ ApiBlueprint,
+ NavItemBlueprint,
+ PageBlueprint,
createApiFactory,
- createNavItemExtension,
- createPageExtension,
createFrontendPlugin,
- createSchemaFromZod,
} from '@backstage/frontend-plugin-api';
import {
@@ -31,10 +30,6 @@ import {
convertLegacyRouteRef,
} from '@backstage/core-compat-api';
-import {
- createEntityCardExtension,
- createEntityContentExtension,
-} from '@backstage/plugin-catalog-react/alpha';
import {
ApiEntity,
parseEntityRef,
@@ -46,161 +41,190 @@ import { rootRoute, registerComponentRouteRef } from './routes';
import { apiDocsConfigRef } from './config';
import { AppIcon } from '@backstage/core-components';
-const apiDocsNavItem = createNavItemExtension({
- title: 'APIs',
- routeRef: convertLegacyRouteRef(rootRoute),
- icon: () => compatWrapper(),
-});
+import {
+ EntityCardBlueprint,
+ EntityContentBlueprint,
+} from '@backstage/plugin-catalog-react/alpha';
-const apiDocsConfigApi = createApiExtension({
- factory: createApiFactory({
- api: apiDocsConfigRef,
- deps: {},
- factory: () => {
- const definitionWidgets = defaultDefinitionWidgets();
- return {
- getApiDefinitionWidget: (apiEntity: ApiEntity) => {
- return definitionWidgets.find(d => d.type === apiEntity.spec.type);
- },
- };
- },
- }),
-});
-
-const apiDocsExplorerPage = createPageExtension({
- defaultPath: '/api-docs',
- routeRef: convertLegacyRouteRef(rootRoute),
- // Mapping DefaultApiExplorerPageProps to config
- configSchema: createSchemaFromZod(z =>
- z.object({
- path: z.string().default('/api-docs'),
- initiallySelectedFilter: z.enum(['owned', 'starred', 'all']).optional(),
- // Ommiting columns and actions for now as their types are too complex to map to zod
- }),
- ),
- loader: ({ config }) =>
- import('./components/ApiExplorerPage').then(m =>
- compatWrapper(
- ,
- ),
- ),
-});
-
-const apiDocsHasApisEntityCard = createEntityCardExtension({
- name: 'has-apis',
- // Ommiting configSchema for now
- // We are skipping variants and columns are too complex to map to zod
- // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
- filter: entity => {
- return (
- entity.kind === 'Component' &&
- entity.relations?.some(
- ({ type, targetRef }) =>
- type.toLocaleLowerCase('en-US') === RELATION_HAS_PART &&
- parseEntityRef(targetRef).kind === 'API',
- )!!
- );
+const apiDocsNavItem = NavItemBlueprint.make({
+ params: {
+ title: 'APIs',
+ routeRef: convertLegacyRouteRef(rootRoute),
+ icon: () => compatWrapper(),
},
- loader: () =>
- import('./components/ApisCards').then(m =>
- compatWrapper(),
- ),
});
-const apiDocsDefinitionEntityCard = createEntityCardExtension({
+const apiDocsConfigApi = ApiBlueprint.make({
+ namespace: 'api-docs',
+ params: {
+ factory: createApiFactory({
+ api: apiDocsConfigRef,
+ deps: {},
+ factory: () => {
+ const definitionWidgets = defaultDefinitionWidgets();
+ return {
+ getApiDefinitionWidget: (apiEntity: ApiEntity) => {
+ return definitionWidgets.find(d => d.type === apiEntity.spec.type);
+ },
+ };
+ },
+ }),
+ },
+});
+
+const apiDocsExplorerPage = PageBlueprint.makeWithOverrides({
+ config: {
+ schema: {
+ // Ommiting columns and actions for now as their types are too complex to map to zod
+ initiallySelectedFilter: z =>
+ z.enum(['owned', 'starred', 'all']).optional(),
+ },
+ },
+ factory(originalFactory, { config }) {
+ return originalFactory({
+ defaultPath: '/api-docs',
+ routeRef: convertLegacyRouteRef(rootRoute),
+ loader: () =>
+ import('./components/ApiExplorerPage').then(m =>
+ compatWrapper(
+ ,
+ ),
+ ),
+ });
+ },
+});
+
+const apiDocsHasApisEntityCard = EntityCardBlueprint.make({
+ name: 'has-apis',
+ params: {
+ // Ommiting configSchema for now
+ // We are skipping variants and columns are too complex to map to zod
+ // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
+ filter: entity => {
+ return (
+ entity.kind === 'Component' &&
+ entity.relations?.some(
+ ({ type, targetRef }) =>
+ type.toLocaleLowerCase('en-US') === RELATION_HAS_PART &&
+ parseEntityRef(targetRef).kind === 'API',
+ )!!
+ );
+ },
+ loader: () =>
+ import('./components/ApisCards').then(m =>
+ compatWrapper(),
+ ),
+ },
+});
+
+const apiDocsDefinitionEntityCard = EntityCardBlueprint.make({
name: 'definition',
- filter: 'kind:api',
- loader: () =>
- import('./components/ApiDefinitionCard').then(m =>
- compatWrapper(),
- ),
+ params: {
+ filter: 'kind:api',
+ loader: () =>
+ import('./components/ApiDefinitionCard').then(m =>
+ compatWrapper(),
+ ),
+ },
});
-const apiDocsConsumedApisEntityCard = createEntityCardExtension({
+const apiDocsConsumedApisEntityCard = EntityCardBlueprint.make({
name: 'consumed-apis',
- // Ommiting configSchema for now
- // We are skipping variants and columns are too complex to map to zod
- // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
- filter: 'kind:component',
- loader: () =>
- import('./components/ApisCards').then(m =>
- compatWrapper(),
- ),
+ params: {
+ // Ommiting configSchema for now
+ // We are skipping variants and columns are too complex to map to zod
+ // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
+ filter: 'kind:component',
+ loader: () =>
+ import('./components/ApisCards').then(m =>
+ compatWrapper(),
+ ),
+ },
});
-const apiDocsProvidedApisEntityCard = createEntityCardExtension({
+const apiDocsProvidedApisEntityCard = EntityCardBlueprint.make({
name: 'provided-apis',
- // Ommiting configSchema for now
- // We are skipping variants and columns are too complex to map to zod
- // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
- filter: 'kind:component',
- loader: () =>
- import('./components/ApisCards').then(m =>
- compatWrapper(),
- ),
+ params: {
+ // Ommiting configSchema for now
+ // We are skipping variants and columns are too complex to map to zod
+ // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
+ filter: 'kind:component',
+ loader: () =>
+ import('./components/ApisCards').then(m =>
+ compatWrapper(),
+ ),
+ },
});
-const apiDocsConsumingComponentsEntityCard = createEntityCardExtension({
+const apiDocsConsumingComponentsEntityCard = EntityCardBlueprint.make({
name: 'consuming-components',
- // Ommiting configSchema for now
- // We are skipping variants
- // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
- filter: 'kind:api',
- loader: () =>
- import('./components/ComponentsCards').then(m =>
- compatWrapper(),
- ),
+ params: {
+ // Ommiting configSchema for now
+ // We are skipping variants
+ // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
+ filter: 'kind:api',
+ loader: () =>
+ import('./components/ComponentsCards').then(m =>
+ compatWrapper(),
+ ),
+ },
});
-const apiDocsProvidingComponentsEntityCard = createEntityCardExtension({
+const apiDocsProvidingComponentsEntityCard = EntityCardBlueprint.make({
name: 'providing-components',
- // Ommiting configSchema for now
- // We are skipping variants
- // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
- filter: 'kind:api',
- loader: () =>
- import('./components/ComponentsCards').then(m =>
- compatWrapper(),
- ),
+ params: {
+ // Ommiting configSchema for now
+ // We are skipping variants
+ // See: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252
+ filter: 'kind:api',
+ loader: () =>
+ import('./components/ComponentsCards').then(m =>
+ compatWrapper(),
+ ),
+ },
});
-const apiDocsDefinitionEntityContent = createEntityContentExtension({
+const apiDocsDefinitionEntityContent = EntityContentBlueprint.make({
name: 'definition',
- defaultPath: '/defintion',
- defaultTitle: 'Definition',
- filter: 'kind:api',
- loader: async () =>
- import('./components/ApiDefinitionCard').then(m =>
- compatWrapper(
-
-
-
-
- ,
+ params: {
+ defaultPath: '/defintion',
+ defaultTitle: 'Definition',
+ filter: 'kind:api',
+ loader: async () =>
+ import('./components/ApiDefinitionCard').then(m =>
+ compatWrapper(
+
+
+
+
+ ,
+ ),
),
- ),
+ },
});
-const apiDocsApisEntityContent = createEntityContentExtension({
+const apiDocsApisEntityContent = EntityContentBlueprint.make({
name: 'apis',
- defaultPath: '/apis',
- defaultTitle: 'APIs',
- filter: 'kind:component',
- loader: async () =>
- import('./components/ApisCards').then(m =>
- compatWrapper(
-
-
-
-
-
-
-
- ,
+ params: {
+ defaultPath: '/apis',
+ defaultTitle: 'APIs',
+ filter: 'kind:component',
+ loader: async () =>
+ import('./components/ApisCards').then(m =>
+ compatWrapper(
+
+
+
+
+
+
+
+ ,
+ ),
),
- ),
+ },
});
export default createFrontendPlugin({
diff --git a/plugins/home/src/alpha.tsx b/plugins/home/src/alpha.tsx
index e31fe833f6..ce96b18943 100644
--- a/plugins/home/src/alpha.tsx
+++ b/plugins/home/src/alpha.tsx
@@ -20,7 +20,7 @@ import {
coreExtensionData,
createExtensionDataRef,
createExtensionInput,
- createPageExtension,
+ PageBlueprint,
createFrontendPlugin,
createRouteRef,
} from '@backstage/frontend-plugin-api';
@@ -35,31 +35,34 @@ export const titleExtensionDataRef = createExtensionDataRef().with({
id: 'title',
});
-const homePage = createPageExtension({
- defaultPath: '/home',
- routeRef: rootRouteRef,
+const homePage = PageBlueprint.makeWithOverrides({
inputs: {
props: createExtensionInput(
- {
- children: coreExtensionData.reactElement.optional(),
- title: titleExtensionDataRef.optional(),
- },
-
+ [
+ coreExtensionData.reactElement.optional(),
+ titleExtensionDataRef.optional(),
+ ],
{
singleton: true,
optional: true,
},
),
},
- loader: ({ inputs }) =>
- import('./components/').then(m =>
- compatWrapper(
- ,
- ),
- ),
+ factory: (originalFactory, { inputs }) => {
+ return originalFactory({
+ defaultPath: '/home',
+ routeRef: rootRouteRef,
+ loader: () =>
+ import('./components/').then(m =>
+ compatWrapper(
+ ,
+ ),
+ ),
+ });
+ },
});
/**
diff --git a/plugins/kubernetes/src/alpha/pages.tsx b/plugins/kubernetes/src/alpha/pages.tsx
index 8b5db150bd..a58ffec94f 100644
--- a/plugins/kubernetes/src/alpha/pages.tsx
+++ b/plugins/kubernetes/src/alpha/pages.tsx
@@ -16,18 +16,20 @@
import React from 'react'; // Add this line to import React
-import { createPageExtension } from '@backstage/frontend-plugin-api';
+import { PageBlueprint } from '@backstage/frontend-plugin-api';
import {
compatWrapper,
convertLegacyRouteRef,
} from '@backstage/core-compat-api';
import { rootCatalogKubernetesRouteRef } from '../plugin';
-export const kubernetesPage = createPageExtension({
- defaultPath: '/kubernetes',
- // you can reuse the existing routeRef
- // by wrapping into the convertLegacyRouteRef.
- routeRef: convertLegacyRouteRef(rootCatalogKubernetesRouteRef),
- // these inputs usually match the props required by the component.
- loader: () => import('../Router').then(m => compatWrapper()),
+export const kubernetesPage = PageBlueprint.make({
+ params: {
+ defaultPath: '/kubernetes',
+ // you can reuse the existing routeRef
+ // by wrapping into the convertLegacyRouteRef.
+ routeRef: convertLegacyRouteRef(rootCatalogKubernetesRouteRef),
+ // these inputs usually match the props required by the component.
+ loader: () => import('../Router').then(m => compatWrapper()),
+ },
});