From 1776e7be25f624a366c390bd939f54cc4fec7d4d Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 5 Oct 2023 15:34:12 +0200 Subject: [PATCH 1/9] feat(frontend-app-api): add default translation api impl Signed-off-by: Camila Belo --- .../frontend-app-api/src/wiring/createApp.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 8b411ac38b..e770a6b4c1 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -492,6 +492,21 @@ function createApiHolder( factory: () => AppThemeSelector.createWithStorage(themeExtensions), }); + factoryRegistry.register('static', { + api: appLanguageApiRef, + deps: {}, + factory: () => AppLanguageSelector.createWithStorage(), + }); + + factoryRegistry.register('default', { + api: translationApiRef, + deps: { languageApi: appLanguageApiRef }, + factory: ({ languageApi }) => + I18nextTranslationApi.create({ + languageApi, + }), + }); + factoryRegistry.register('static', { api: configApiRef, deps: {}, From e6c9103935b092de3afe9046d8d92406e63594b4 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 4 Oct 2023 10:11:29 +0200 Subject: [PATCH 2/9] feat(catalog): create index page and sidebar item Signed-off-by: Camila Belo --- plugins/catalog/src/alpha.tsx | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/plugins/catalog/src/alpha.tsx b/plugins/catalog/src/alpha.tsx index 5e78a52f9b..e34830f21d 100644 --- a/plugins/catalog/src/alpha.tsx +++ b/plugins/catalog/src/alpha.tsx @@ -14,6 +14,8 @@ * limitations under the License. */ +import React from 'react'; +import HomeIcon from '@material-ui/icons/Home'; import { createApiFactory, discoveryApiRef, @@ -22,8 +24,11 @@ import { } from '@backstage/core-plugin-api'; import { CatalogClient } from '@backstage/catalog-client'; import { + createSchemaFromZod, createApiExtension, + createPageExtension, createPlugin, + createNavItemExtension, } from '@backstage/frontend-plugin-api'; import { catalogApiRef, @@ -31,6 +36,7 @@ import { } from '@backstage/plugin-catalog-react'; import { createSearchResultListItemExtension } from '@backstage/plugin-search-react/alpha'; import { DefaultStarredEntitiesApi } from './apis'; +import { rootRouteRef } from './routes'; /** @alpha */ export const CatalogApi = createApiExtension({ @@ -65,6 +71,41 @@ export const CatalogSearchResultListItemExtension = ), }); +/** @alpha */ +export const CatalogIndexPage = createPageExtension({ + id: 'catalog', + routeRef: rootRouteRef, + configSchema: createSchemaFromZod(z => + z.object({ + path: z.string().default('/catalog'), + initialKind: z.string().default('component'), + initiallySelectedFilter: z + .enum(['owned', 'starred', 'all']) + .default('owned'), + ownerPickerMode: z.enum(['owners-only', 'all']).optional(), + }), + ), + loader: async ({ config }) => { + const { CatalogPage } = await import('./components/CatalogPage'); + const { ownerPickerMode, initialKind, initiallySelectedFilter } = config; + + return ( + + ); + }, +}); + +const CatalogNavItem = createNavItemExtension({ + id: 'catalog.nav.index', + routeRef: rootRouteRef, + title: 'Catalog', + icon: HomeIcon, +}); + /** @alpha */ export default createPlugin({ id: 'catalog', @@ -72,5 +113,7 @@ export default createPlugin({ CatalogApi, StarredEntitiesApi, CatalogSearchResultListItemExtension, + CatalogNavItem, + CatalogIndexPage, ], }); From 5dc00a5d8890d6504600e8556d1c6dd602fabaa3 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 5 Oct 2023 15:08:24 +0200 Subject: [PATCH 3/9] feat(catalog): create index page filters Signed-off-by: Camila Belo --- plugins/catalog/src/alpha.tsx | 202 ++++++++++++++++-- .../CatalogPage/DefaultCatalogPage.tsx | 22 +- 2 files changed, 197 insertions(+), 27 deletions(-) diff --git a/plugins/catalog/src/alpha.tsx b/plugins/catalog/src/alpha.tsx index e34830f21d..86ff0a1846 100644 --- a/plugins/catalog/src/alpha.tsx +++ b/plugins/catalog/src/alpha.tsx @@ -29,14 +29,24 @@ import { createPageExtension, createPlugin, createNavItemExtension, + createExtension, + coreExtensionData, + AnyExtensionInputMap, + PortableSchema, + ExtensionBoundary, + createExtensionInput, } from '@backstage/frontend-plugin-api'; import { + AsyncEntityProvider, catalogApiRef, + entityRouteRef, starredEntitiesApiRef, } from '@backstage/plugin-catalog-react'; import { createSearchResultListItemExtension } from '@backstage/plugin-search-react/alpha'; import { DefaultStarredEntitiesApi } from './apis'; import { rootRouteRef } from './routes'; +import { Progress } from '@backstage/core-components'; +import { useEntityFromUrl } from './components/CatalogEntityPage/useEntityFromUrl'; /** @alpha */ export const CatalogApi = createApiExtension({ @@ -72,30 +82,175 @@ export const CatalogSearchResultListItemExtension = }); /** @alpha */ -export const CatalogIndexPage = createPageExtension({ - id: 'catalog', - routeRef: rootRouteRef, +export function createCatalogFilterExtension< + TInputs extends AnyExtensionInputMap, + TConfig = never, +>(options: { + id: string; + inputs?: TInputs; + configSchema?: PortableSchema; + loader: (options: { config: TConfig }) => Promise; +}) { + return createExtension({ + id: `catalog.filter.${options.id}`, + attachTo: { id: 'catalog', input: 'filters' }, + inputs: options.inputs ?? {}, + configSchema: options.configSchema, + output: { + element: coreExtensionData.reactElement, + }, + factory({ bind, config, source }) { + const LazyComponent = React.lazy(() => + options + .loader({ config }) + .then(element => ({ default: () => element })), + ); + + bind({ + element: ( + + }> + + + + ), + }); + }, + }); +} + +/** @alpha */ +export const CatalogEntityTagFilter = createCatalogFilterExtension({ + id: 'entity.tag', + loader: async () => { + const { EntityTagPicker } = await import('@backstage/plugin-catalog-react'); + return ; + }, +}); + +/** @alpha */ +export const CatalogEntityKindFilter = createCatalogFilterExtension({ + id: 'entity.kind', configSchema: createSchemaFromZod(z => z.object({ - path: z.string().default('/catalog'), - initialKind: z.string().default('component'), - initiallySelectedFilter: z - .enum(['owned', 'starred', 'all']) - .default('owned'), - ownerPickerMode: z.enum(['owners-only', 'all']).optional(), + initialFilter: z.string().default('component'), }), ), loader: async ({ config }) => { - const { CatalogPage } = await import('./components/CatalogPage'); - const { ownerPickerMode, initialKind, initiallySelectedFilter } = config; - - return ( - + const { EntityKindPicker } = await import( + '@backstage/plugin-catalog-react' ); + return ; + }, +}); + +/** @alpha */ +export const CatalogEntityTypeFilter = createCatalogFilterExtension({ + id: 'entity.type', + loader: async () => { + const { EntityTypePicker } = await import( + '@backstage/plugin-catalog-react' + ); + return ; + }, +}); + +/** @alpha */ +export const CatalogEntityOwnerFilter = createCatalogFilterExtension({ + id: 'entity.mode', + configSchema: createSchemaFromZod(z => + z.object({ + mode: z.enum(['owners-only', 'all']).optional(), + }), + ), + loader: async ({ config }) => { + const { EntityOwnerPicker } = await import( + '@backstage/plugin-catalog-react' + ); + return ; + }, +}); + +/** @alpha */ +export const CatalogEntityNamespaceFilter = createCatalogFilterExtension({ + id: 'entity.namespace', + loader: async () => { + const { EntityNamespacePicker } = await import( + '@backstage/plugin-catalog-react' + ); + return ; + }, +}); + +/** @alpha */ +export const CatalogEntityLifecycleFilter = createCatalogFilterExtension({ + id: 'entity.lifecycle', + loader: async () => { + const { EntityLifecyclePicker } = await import( + '@backstage/plugin-catalog-react' + ); + return ; + }, +}); + +/** @alpha */ +export const CatalogEntityProcessingStatusFilter = createCatalogFilterExtension( + { + id: 'entity.processing.status', + loader: async () => { + const { EntityProcessingStatusPicker } = await import( + '@backstage/plugin-catalog-react' + ); + return ; + }, + }, +); + +/** @alpha */ +export const CatalogUserListFilter = createCatalogFilterExtension({ + id: 'user.list', + configSchema: createSchemaFromZod(z => + z.object({ + initialFilter: z.enum(['owned', 'starred', 'all']).default('owned'), + }), + ), + loader: async ({ config }) => { + const { UserListPicker } = await import('@backstage/plugin-catalog-react'); + return ; + }, +}); + +/** @alpha */ +export const CatalogIndexPage = createPageExtension({ + id: 'catalog', + defaultPath: '/catalog', + routeRef: rootRouteRef, + inputs: { + filters: createExtensionInput({ + element: coreExtensionData.reactElement, + }), + }, + loader: async ({ inputs }) => { + const { DefaultCatalogPage } = await import('./components/CatalogPage'); + const filters = inputs.filters.map(filter => filter.element); + return ; + }, +}); + +/** @alpha */ +export const CatalogEntityPage = createPageExtension({ + id: 'catalog:entity', + defaultPath: '/catalog/:namespace/:kind/:name', + routeRef: entityRouteRef, + loader: async () => { + const Component = () => { + return ( + +
🚧 Work In Progress
+
+ ); + }; + return ; }, }); @@ -113,7 +268,16 @@ export default createPlugin({ CatalogApi, StarredEntitiesApi, CatalogSearchResultListItemExtension, - CatalogNavItem, + CatalogEntityKindFilter, + CatalogEntityTypeFilter, + CatalogUserListFilter, + CatalogEntityOwnerFilter, + CatalogEntityLifecycleFilter, + CatalogEntityTagFilter, + CatalogEntityProcessingStatusFilter, + CatalogEntityNamespaceFilter, CatalogIndexPage, + CatalogEntityPage, + CatalogNavItem, ], }); diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index fb9b282d57..7d75ce4b1d 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -57,6 +57,7 @@ export interface DefaultCatalogPageProps { tableOptions?: TableProps['options']; emptyContent?: ReactNode; ownerPickerMode?: EntityOwnerPickerProps['mode']; + filters?: ReactNode; } export function DefaultCatalogPage(props: DefaultCatalogPageProps) { @@ -68,6 +69,7 @@ export function DefaultCatalogPage(props: DefaultCatalogPageProps) { tableOptions = {}, emptyContent, ownerPickerMode, + filters, } = props; const orgName = useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage'; @@ -87,14 +89,18 @@ export function DefaultCatalogPage(props: DefaultCatalogPageProps) { - - - - - - - - + {filters ?? ( + <> + + + + + + + + + + )} Date: Thu, 5 Oct 2023 16:08:04 +0200 Subject: [PATCH 4/9] chore: add changeset files Signed-off-by: Camila Belo --- .changeset/new-beers-drive.md | 7 +++++++ .changeset/sharp-falcons-clean.md | 5 +++++ 2 files changed, 12 insertions(+) create mode 100644 .changeset/new-beers-drive.md create mode 100644 .changeset/sharp-falcons-clean.md diff --git a/.changeset/new-beers-drive.md b/.changeset/new-beers-drive.md new file mode 100644 index 0000000000..370734b7c5 --- /dev/null +++ b/.changeset/new-beers-drive.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Create declarative extensions for the `Catalog` plugin; this initial plugin preset contains sidebar item, index page and filter extensions, all distributed via `/alpha` subpath. + +The `EntityPage` will be migrated in a follow-up patch. diff --git a/.changeset/sharp-falcons-clean.md b/.changeset/sharp-falcons-clean.md new file mode 100644 index 0000000000..bc247be451 --- /dev/null +++ b/.changeset/sharp-falcons-clean.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': patch +--- + +Register default implementation for the `Translation API` on the new `createApp`. From a4444632f0919c18e4e33bca26259e6f77d5c313 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 18 Oct 2023 12:06:24 +0200 Subject: [PATCH 5/9] refactor(catalog): create base catalog page component Signed-off-by: Camila Belo --- plugins/catalog/src/alpha.tsx | 4 +- .../CatalogPage/DefaultCatalogPage.tsx | 108 ++++++++++-------- .../src/components/CatalogPage/index.ts | 7 +- 3 files changed, 68 insertions(+), 51 deletions(-) diff --git a/plugins/catalog/src/alpha.tsx b/plugins/catalog/src/alpha.tsx index 86ff0a1846..3cc34b5c96 100644 --- a/plugins/catalog/src/alpha.tsx +++ b/plugins/catalog/src/alpha.tsx @@ -231,9 +231,9 @@ export const CatalogIndexPage = createPageExtension({ }), }, loader: async ({ inputs }) => { - const { DefaultCatalogPage } = await import('./components/CatalogPage'); + const { BaseCatalogPage } = await import('./components/CatalogPage'); const filters = inputs.filters.map(filter => filter.element); - return ; + return {filters}} />; }, }); diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index 7d75ce4b1d..e50c69b8ec 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -44,33 +44,15 @@ import { CatalogTable, CatalogTableRow } from '../CatalogTable'; import { catalogTranslationRef } from '../../translation'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -/** - * Props for root catalog pages. - * - * @public - */ -export interface DefaultCatalogPageProps { - initiallySelectedFilter?: UserListFilterKind; - columns?: TableColumn[]; - actions?: TableProps['actions']; - initialKind?: string; - tableOptions?: TableProps['options']; - emptyContent?: ReactNode; - ownerPickerMode?: EntityOwnerPickerProps['mode']; - filters?: ReactNode; +/** @internal */ +export interface BaseCatalogPageProps { + filters: ReactNode; + content?: ReactNode; } -export function DefaultCatalogPage(props: DefaultCatalogPageProps) { - const { - columns, - actions, - initiallySelectedFilter = 'owned', - initialKind = 'component', - tableOptions = {}, - emptyContent, - ownerPickerMode, - filters, - } = props; +/** @internal */ +export function BaseCatalogPage(props: BaseCatalogPageProps) { + const { filters, content = } = props; const orgName = useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage'; const createComponentLink = useRouteRef(createComponentRouteRef); @@ -88,31 +70,63 @@ export function DefaultCatalogPage(props: DefaultCatalogPageProps) { - - {filters ?? ( - <> - - - - - - - - - - )} - - - - + {filters} + {content} ); } + +/** + * Props for root catalog pages. + * + * @public + */ +export interface DefaultCatalogPageProps { + initiallySelectedFilter?: UserListFilterKind; + columns?: TableColumn[]; + actions?: TableProps['actions']; + initialKind?: string; + tableOptions?: TableProps['options']; + emptyContent?: ReactNode; + ownerPickerMode?: EntityOwnerPickerProps['mode']; +} + +export function DefaultCatalogPage(props: DefaultCatalogPageProps) { + const { + columns, + actions, + initiallySelectedFilter = 'owned', + initialKind = 'component', + tableOptions = {}, + emptyContent, + ownerPickerMode, + } = props; + + return ( + + + + + + + + + + + } + content={ + + } + /> + ); +} diff --git a/plugins/catalog/src/components/CatalogPage/index.ts b/plugins/catalog/src/components/CatalogPage/index.ts index 9a3d083f41..258fedf15c 100644 --- a/plugins/catalog/src/components/CatalogPage/index.ts +++ b/plugins/catalog/src/components/CatalogPage/index.ts @@ -15,5 +15,8 @@ */ export { CatalogPage } from './CatalogPage'; -export { DefaultCatalogPage } from './DefaultCatalogPage'; -export type { DefaultCatalogPageProps } from './DefaultCatalogPage'; +export { BaseCatalogPage, DefaultCatalogPage } from './DefaultCatalogPage'; +export type { + BaseCatalogPageProps, + DefaultCatalogPageProps, +} from './DefaultCatalogPage'; From 0194963f0f0d96188a69ff81d74e9a9aef2f863e Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 18 Oct 2023 12:07:15 +0200 Subject: [PATCH 6/9] refactor(catalog): remove extensions exports Signed-off-by: Camila Belo --- plugins/catalog/src/alpha.tsx | 46 +++++++++++++---------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/plugins/catalog/src/alpha.tsx b/plugins/catalog/src/alpha.tsx index 3cc34b5c96..0a6a093b7a 100644 --- a/plugins/catalog/src/alpha.tsx +++ b/plugins/catalog/src/alpha.tsx @@ -119,8 +119,7 @@ export function createCatalogFilterExtension< }); } -/** @alpha */ -export const CatalogEntityTagFilter = createCatalogFilterExtension({ +const CatalogEntityTagFilter = createCatalogFilterExtension({ id: 'entity.tag', loader: async () => { const { EntityTagPicker } = await import('@backstage/plugin-catalog-react'); @@ -128,8 +127,7 @@ export const CatalogEntityTagFilter = createCatalogFilterExtension({ }, }); -/** @alpha */ -export const CatalogEntityKindFilter = createCatalogFilterExtension({ +const CatalogEntityKindFilter = createCatalogFilterExtension({ id: 'entity.kind', configSchema: createSchemaFromZod(z => z.object({ @@ -144,8 +142,7 @@ export const CatalogEntityKindFilter = createCatalogFilterExtension({ }, }); -/** @alpha */ -export const CatalogEntityTypeFilter = createCatalogFilterExtension({ +const CatalogEntityTypeFilter = createCatalogFilterExtension({ id: 'entity.type', loader: async () => { const { EntityTypePicker } = await import( @@ -155,8 +152,7 @@ export const CatalogEntityTypeFilter = createCatalogFilterExtension({ }, }); -/** @alpha */ -export const CatalogEntityOwnerFilter = createCatalogFilterExtension({ +const CatalogEntityOwnerFilter = createCatalogFilterExtension({ id: 'entity.mode', configSchema: createSchemaFromZod(z => z.object({ @@ -171,8 +167,7 @@ export const CatalogEntityOwnerFilter = createCatalogFilterExtension({ }, }); -/** @alpha */ -export const CatalogEntityNamespaceFilter = createCatalogFilterExtension({ +const CatalogEntityNamespaceFilter = createCatalogFilterExtension({ id: 'entity.namespace', loader: async () => { const { EntityNamespacePicker } = await import( @@ -182,8 +177,7 @@ export const CatalogEntityNamespaceFilter = createCatalogFilterExtension({ }, }); -/** @alpha */ -export const CatalogEntityLifecycleFilter = createCatalogFilterExtension({ +const CatalogEntityLifecycleFilter = createCatalogFilterExtension({ id: 'entity.lifecycle', loader: async () => { const { EntityLifecyclePicker } = await import( @@ -193,21 +187,17 @@ export const CatalogEntityLifecycleFilter = createCatalogFilterExtension({ }, }); -/** @alpha */ -export const CatalogEntityProcessingStatusFilter = createCatalogFilterExtension( - { - id: 'entity.processing.status', - loader: async () => { - const { EntityProcessingStatusPicker } = await import( - '@backstage/plugin-catalog-react' - ); - return ; - }, +const CatalogEntityProcessingStatusFilter = createCatalogFilterExtension({ + id: 'entity.processing.status', + loader: async () => { + const { EntityProcessingStatusPicker } = await import( + '@backstage/plugin-catalog-react' + ); + return ; }, -); +}); -/** @alpha */ -export const CatalogUserListFilter = createCatalogFilterExtension({ +const CatalogUserListFilter = createCatalogFilterExtension({ id: 'user.list', configSchema: createSchemaFromZod(z => z.object({ @@ -220,8 +210,7 @@ export const CatalogUserListFilter = createCatalogFilterExtension({ }, }); -/** @alpha */ -export const CatalogIndexPage = createPageExtension({ +const CatalogIndexPage = createPageExtension({ id: 'catalog', defaultPath: '/catalog', routeRef: rootRouteRef, @@ -237,8 +226,7 @@ export const CatalogIndexPage = createPageExtension({ }, }); -/** @alpha */ -export const CatalogEntityPage = createPageExtension({ +const CatalogEntityPage = createPageExtension({ id: 'catalog:entity', defaultPath: '/catalog/:namespace/:kind/:name', routeRef: entityRouteRef, From 14e135c0f10e30f7abec2b83dfe48728aad034c6 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Sun, 15 Oct 2023 10:06:27 +0200 Subject: [PATCH 7/9] feat(catalog): provide external routes Signed-off-by: Camila Belo --- packages/app-next/app-config.yaml | 2 ++ plugins/catalog/src/alpha.tsx | 23 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index eaaa2b0560..6f6081fece 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -4,6 +4,8 @@ app: routes: bindings: plugin.pages.externalRoutes.pageX: plugin.pages.routes.pageX + # waiting for https://github.com/backstage/backstage/pull/20605 + # catalog.externalRoutes.viewTechDoc: techdocs.routes.docRoot extensions: - apis.plugin.graphiql.browse.gitlab: true diff --git a/plugins/catalog/src/alpha.tsx b/plugins/catalog/src/alpha.tsx index 0a6a093b7a..bc568cafd2 100644 --- a/plugins/catalog/src/alpha.tsx +++ b/plugins/catalog/src/alpha.tsx @@ -22,6 +22,7 @@ import { fetchApiRef, storageApiRef, } from '@backstage/core-plugin-api'; +import { convertLegacyRouteRef } from '@backstage/core-plugin-api/alpha'; import { CatalogClient } from '@backstage/catalog-client'; import { createSchemaFromZod, @@ -44,7 +45,12 @@ import { } from '@backstage/plugin-catalog-react'; import { createSearchResultListItemExtension } from '@backstage/plugin-search-react/alpha'; import { DefaultStarredEntitiesApi } from './apis'; -import { rootRouteRef } from './routes'; +import { + createComponentRouteRef, + createFromTemplateRouteRef, + rootRouteRef, + viewTechDocRouteRef, +} from './routes'; import { Progress } from '@backstage/core-components'; import { useEntityFromUrl } from './components/CatalogEntityPage/useEntityFromUrl'; @@ -213,7 +219,7 @@ const CatalogUserListFilter = createCatalogFilterExtension({ const CatalogIndexPage = createPageExtension({ id: 'catalog', defaultPath: '/catalog', - routeRef: rootRouteRef, + routeRef: convertLegacyRouteRef(rootRouteRef), inputs: { filters: createExtensionInput({ element: coreExtensionData.reactElement, @@ -229,7 +235,7 @@ const CatalogIndexPage = createPageExtension({ const CatalogEntityPage = createPageExtension({ id: 'catalog:entity', defaultPath: '/catalog/:namespace/:kind/:name', - routeRef: entityRouteRef, + routeRef: convertLegacyRouteRef(entityRouteRef), loader: async () => { const Component = () => { return ( @@ -244,7 +250,7 @@ const CatalogEntityPage = createPageExtension({ const CatalogNavItem = createNavItemExtension({ id: 'catalog.nav.index', - routeRef: rootRouteRef, + routeRef: convertLegacyRouteRef(rootRouteRef), title: 'Catalog', icon: HomeIcon, }); @@ -252,6 +258,15 @@ const CatalogNavItem = createNavItemExtension({ /** @alpha */ export default createPlugin({ id: 'catalog', + routes: { + catalogIndex: convertLegacyRouteRef(rootRouteRef), + catalogEntity: convertLegacyRouteRef(entityRouteRef), + }, + externalRoutes: { + viewTechDoc: convertLegacyRouteRef(viewTechDocRouteRef), + createComponent: convertLegacyRouteRef(createComponentRouteRef), + createFromTemplate: convertLegacyRouteRef(createFromTemplateRouteRef), + }, extensions: [ CatalogApi, StarredEntitiesApi, From fbd1f5e972c754b149bc7e0e2791d95a9c4f2fe6 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 18 Oct 2023 12:41:15 +0200 Subject: [PATCH 8/9] chore(catalog): update api reports Signed-off-by: Camila Belo --- plugins/catalog/alpha-api-report.md | 46 ++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/plugins/catalog/alpha-api-report.md b/plugins/catalog/alpha-api-report.md index db76a2e0f3..aba33fc092 100644 --- a/plugins/catalog/alpha-api-report.md +++ b/plugins/catalog/alpha-api-report.md @@ -3,8 +3,14 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// + +import { AnyExtensionInputMap } from '@backstage/frontend-plugin-api'; import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { Extension } from '@backstage/frontend-plugin-api'; +import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; +import { PortableSchema } from '@backstage/frontend-plugin-api'; +import { RouteRef } from '@backstage/frontend-plugin-api'; // @alpha (undocumented) export const CatalogApi: Extension<{}>; @@ -15,7 +21,45 @@ export const CatalogSearchResultListItemExtension: Extension<{ }>; // @alpha (undocumented) -const _default: BackstagePlugin<{}, {}>; +export function createCatalogFilterExtension< + TInputs extends AnyExtensionInputMap, + TConfig = never, +>(options: { + id: string; + inputs?: TInputs; + configSchema?: PortableSchema; + loader: (options: { config: TConfig }) => Promise; +}): Extension; + +// @alpha (undocumented) +const _default: BackstagePlugin< + { + catalogIndex: RouteRef; + catalogEntity: RouteRef<{ + name: string; + kind: string; + namespace: string; + }>; + }, + { + viewTechDoc: ExternalRouteRef< + { + name: string; + kind: string; + namespace: string; + }, + true + >; + createComponent: ExternalRouteRef; + createFromTemplate: ExternalRouteRef< + { + namespace: string; + templateName: string; + }, + true + >; + } +>; export default _default; // @alpha (undocumented) From 95f0d3f5a054ecf3b31afb515432036df99fc82a Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 18 Oct 2023 13:44:26 +0200 Subject: [PATCH 9/9] refactor(catalog): use better pege extension ids Signed-off-by: Camila Belo --- plugins/catalog/src/alpha.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/catalog/src/alpha.tsx b/plugins/catalog/src/alpha.tsx index bc568cafd2..6eda8c3d26 100644 --- a/plugins/catalog/src/alpha.tsx +++ b/plugins/catalog/src/alpha.tsx @@ -99,7 +99,7 @@ export function createCatalogFilterExtension< }) { return createExtension({ id: `catalog.filter.${options.id}`, - attachTo: { id: 'catalog', input: 'filters' }, + attachTo: { id: 'plugin.catalog.page.index', input: 'filters' }, inputs: options.inputs ?? {}, configSchema: options.configSchema, output: { @@ -217,7 +217,7 @@ const CatalogUserListFilter = createCatalogFilterExtension({ }); const CatalogIndexPage = createPageExtension({ - id: 'catalog', + id: 'plugin.catalog.page.index', defaultPath: '/catalog', routeRef: convertLegacyRouteRef(rootRouteRef), inputs: { @@ -233,7 +233,7 @@ const CatalogIndexPage = createPageExtension({ }); const CatalogEntityPage = createPageExtension({ - id: 'catalog:entity', + id: 'plugin.catalog.page.entity', defaultPath: '/catalog/:namespace/:kind/:name', routeRef: convertLegacyRouteRef(entityRouteRef), loader: async () => {