diff --git a/.changeset/chatty-seals-tap.md b/.changeset/chatty-seals-tap.md new file mode 100644 index 0000000000..384a89e6ce --- /dev/null +++ b/.changeset/chatty-seals-tap.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog': patch +'example-app': patch +--- + +Add link from Template entity to the scaffolder launch page for the template in the AboutCard. diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index bc9eac8c64..0efcafba26 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -142,6 +142,7 @@ const app = createApp({ bind(catalogPlugin.externalRoutes, { createComponent: scaffolderPlugin.routes.root, viewTechDoc: techdocsPlugin.routes.docRoot, + selectedTemplateRoute: scaffolderPlugin.routes.selectedTemplate, }); bind(apiDocsPlugin.externalRoutes, { registerApi: catalogImportPlugin.routes.importPage, diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 21983f762e..16176b9662 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -40,6 +40,7 @@ "@backstage/integration-react": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", + "@backstage/plugin-scaffolder-common": "workspace:^", "@backstage/plugin-search-common": "workspace:^", "@backstage/plugin-search-react": "workspace:^", "@backstage/theme": "workspace:^", diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx index cb48be2b26..4be201b555 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx @@ -49,12 +49,14 @@ import { IconButton, makeStyles, } from '@material-ui/core'; +import AddIcon from '@material-ui/icons/Add'; import CachedIcon from '@material-ui/icons/Cached'; import DocsIcon from '@material-ui/icons/Description'; import EditIcon from '@material-ui/icons/Edit'; import React, { useCallback } from 'react'; -import { viewTechDocRouteRef } from '../../routes'; +import { selectedTemplateRouteRef, viewTechDocRouteRef } from '../../routes'; import { AboutContent } from './AboutContent'; +import { isTemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; const useStyles = makeStyles({ gridItemCard: { @@ -97,6 +99,7 @@ export function AboutCard(props: AboutCardProps) { const alertApi = useApi(alertApiRef); const errorApi = useApi(errorApiRef); const viewTechdocLink = useRouteRef(viewTechDocRouteRef); + const templateRoute = useRouteRef(selectedTemplateRouteRef); const entitySourceLocation = getEntitySourceLocation( entity, @@ -126,6 +129,23 @@ export function AboutCard(props: AboutCardProps) { }), }; + const subHeaderLinks = [viewInSource, viewInTechDocs]; + + if (isTemplateEntityV1beta3(entity)) { + const launchTemplate: IconLinkVerticalProps = { + label: 'Launch Template', + icon: , + href: + templateRoute && + templateRoute({ + templateName: entity.metadata.name, + namespace: entity.metadata.namespace || DEFAULT_NAMESPACE, + }), + }; + + subHeaderLinks.push(launchTemplate); + } + let cardClass = ''; if (variant === 'gridItem') { cardClass = classes.gridItemCard; @@ -179,7 +199,7 @@ export function AboutCard(props: AboutCardProps) { } - subheader={} + subheader={} /> diff --git a/plugins/catalog/src/plugin.ts b/plugins/catalog/src/plugin.ts index ea6ddcaff2..22c85a755d 100644 --- a/plugins/catalog/src/plugin.ts +++ b/plugins/catalog/src/plugin.ts @@ -21,7 +21,11 @@ import { entityRouteRef, starredEntitiesApiRef, } from '@backstage/plugin-catalog-react'; -import { createComponentRouteRef, viewTechDocRouteRef } from './routes'; +import { + createComponentRouteRef, + selectedTemplateRouteRef, + viewTechDocRouteRef, +} from './routes'; import { createApiFactory, createComponentExtension, @@ -77,6 +81,7 @@ export const catalogPlugin = createPlugin({ externalRoutes: { createComponent: createComponentRouteRef, viewTechDoc: viewTechDocRouteRef, + selectedTemplateRoute: selectedTemplateRouteRef, }, __experimentalConfigure( options?: CatalogInputPluginOptions, diff --git a/plugins/catalog/src/routes.ts b/plugins/catalog/src/routes.ts index 5c0d195d74..2d9667d8e2 100644 --- a/plugins/catalog/src/routes.ts +++ b/plugins/catalog/src/routes.ts @@ -30,6 +30,12 @@ export const viewTechDocRouteRef = createExternalRouteRef({ params: ['namespace', 'kind', 'name'], }); +export const selectedTemplateRouteRef = createExternalRouteRef({ + id: 'selected-template', + optional: true, + params: ['namespace', 'templateName'], +}); + export const rootRouteRef = createRouteRef({ id: 'catalog', }); diff --git a/yarn.lock b/yarn.lock index 2e6f814cf5..6ce19fdede 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5739,6 +5739,7 @@ __metadata: "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" "@backstage/plugin-permission-react": "workspace:^" + "@backstage/plugin-scaffolder-common": "workspace:^" "@backstage/plugin-search-common": "workspace:^" "@backstage/plugin-search-react": "workspace:^" "@backstage/test-utils": "workspace:^"