@@ -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 => <m.Component />),
|
||||
export const ExamplePage = PageBlueprint.make({
|
||||
params: {
|
||||
defaultPath: '/example',
|
||||
loader: () => import('./Component').then(m => <m.Component />),
|
||||
},
|
||||
});
|
||||
|
||||
/** @public */
|
||||
|
||||
+162
-138
@@ -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(<AppIcon id="kind:api" />),
|
||||
});
|
||||
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(
|
||||
<m.ApiExplorerIndexPage
|
||||
initiallySelectedFilter={config.initiallySelectedFilter}
|
||||
/>,
|
||||
),
|
||||
),
|
||||
});
|
||||
|
||||
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(<AppIcon id="kind:api" />),
|
||||
},
|
||||
loader: () =>
|
||||
import('./components/ApisCards').then(m =>
|
||||
compatWrapper(<m.HasApisCard />),
|
||||
),
|
||||
});
|
||||
|
||||
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(
|
||||
<m.ApiExplorerIndexPage
|
||||
initiallySelectedFilter={config.initiallySelectedFilter}
|
||||
/>,
|
||||
),
|
||||
),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
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(<m.HasApisCard />),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
const apiDocsDefinitionEntityCard = EntityCardBlueprint.make({
|
||||
name: 'definition',
|
||||
filter: 'kind:api',
|
||||
loader: () =>
|
||||
import('./components/ApiDefinitionCard').then(m =>
|
||||
compatWrapper(<m.ApiDefinitionCard />),
|
||||
),
|
||||
params: {
|
||||
filter: 'kind:api',
|
||||
loader: () =>
|
||||
import('./components/ApiDefinitionCard').then(m =>
|
||||
compatWrapper(<m.ApiDefinitionCard />),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
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(<m.ConsumedApisCard />),
|
||||
),
|
||||
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(<m.ConsumedApisCard />),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
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(<m.ProvidedApisCard />),
|
||||
),
|
||||
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(<m.ProvidedApisCard />),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
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(<m.ConsumingComponentsCard />),
|
||||
),
|
||||
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(<m.ConsumingComponentsCard />),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
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(<m.ProvidingComponentsCard />),
|
||||
),
|
||||
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(<m.ProvidingComponentsCard />),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
const apiDocsDefinitionEntityContent = createEntityContentExtension({
|
||||
const apiDocsDefinitionEntityContent = EntityContentBlueprint.make({
|
||||
name: 'definition',
|
||||
defaultPath: '/defintion',
|
||||
defaultTitle: 'Definition',
|
||||
filter: 'kind:api',
|
||||
loader: async () =>
|
||||
import('./components/ApiDefinitionCard').then(m =>
|
||||
compatWrapper(
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<m.ApiDefinitionCard />
|
||||
</Grid>
|
||||
</Grid>,
|
||||
params: {
|
||||
defaultPath: '/defintion',
|
||||
defaultTitle: 'Definition',
|
||||
filter: 'kind:api',
|
||||
loader: async () =>
|
||||
import('./components/ApiDefinitionCard').then(m =>
|
||||
compatWrapper(
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<m.ApiDefinitionCard />
|
||||
</Grid>
|
||||
</Grid>,
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
const apiDocsApisEntityContent = createEntityContentExtension({
|
||||
const apiDocsApisEntityContent = EntityContentBlueprint.make({
|
||||
name: 'apis',
|
||||
defaultPath: '/apis',
|
||||
defaultTitle: 'APIs',
|
||||
filter: 'kind:component',
|
||||
loader: async () =>
|
||||
import('./components/ApisCards').then(m =>
|
||||
compatWrapper(
|
||||
<Grid container spacing={3} alignItems="stretch">
|
||||
<Grid item xs={12}>
|
||||
<m.ProvidedApisCard />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<m.ConsumedApisCard />
|
||||
</Grid>
|
||||
</Grid>,
|
||||
params: {
|
||||
defaultPath: '/apis',
|
||||
defaultTitle: 'APIs',
|
||||
filter: 'kind:component',
|
||||
loader: async () =>
|
||||
import('./components/ApisCards').then(m =>
|
||||
compatWrapper(
|
||||
<Grid container spacing={3} alignItems="stretch">
|
||||
<Grid item xs={12}>
|
||||
<m.ProvidedApisCard />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<m.ConsumedApisCard />
|
||||
</Grid>
|
||||
</Grid>,
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
export default createFrontendPlugin({
|
||||
|
||||
+21
-18
@@ -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<string>().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(
|
||||
<m.HomepageCompositionRoot
|
||||
children={inputs.props?.output.children}
|
||||
title={inputs.props?.output.title}
|
||||
/>,
|
||||
),
|
||||
),
|
||||
factory: (originalFactory, { inputs }) => {
|
||||
return originalFactory({
|
||||
defaultPath: '/home',
|
||||
routeRef: rootRouteRef,
|
||||
loader: () =>
|
||||
import('./components/').then(m =>
|
||||
compatWrapper(
|
||||
<m.HomepageCompositionRoot
|
||||
children={inputs.props?.get(coreExtensionData.reactElement)}
|
||||
title={inputs.props?.get(titleExtensionDataRef)}
|
||||
/>,
|
||||
),
|
||||
),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -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(<m.Router />)),
|
||||
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(<m.Router />)),
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user