From 4dba3594ae1a4819a09c13892e103bc8e6de1bc9 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Fri, 4 Jun 2021 17:12:51 +0200 Subject: [PATCH] Deprecate entityRef in output and move it into links, filter empty links Signed-off-by: Oliver Sand --- .../schema/kinds/Template.v1beta2.schema.json | 8 +++- .../v1beta2-demo/template.yaml | 8 +++- .../TaskPage/TaskPageLinks.test.tsx | 18 +++++++-- .../src/components/TaskPage/TaskPageLinks.tsx | 40 +++++++++++-------- plugins/scaffolder/src/types.ts | 4 +- 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json b/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json index 01a012e5aa..b14cdb8ee0 100644 --- a/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json +++ b/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json @@ -146,7 +146,7 @@ "description": "A list of external hyperlinks, typically pointing to resources created or updated by the template", "items": { "type": "object", - "required": ["url"], + "required": [], "properties": { "url": { "type": "string", @@ -154,6 +154,12 @@ "examples": ["https://github.com/my-org/my-new-repo"], "minLength": 1 }, + "entityRef": { + "type": "string", + "description": "An entity reference to an entity in the catalog.", + "examples": ["Component:default/my-app"], + "minLength": 1 + }, "title": { "type": "string", "description": "A user friendly display name for the link.", diff --git a/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template.yaml b/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template.yaml index f15bef6f75..86f41b43d2 100644 --- a/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template.yaml +++ b/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template.yaml @@ -99,5 +99,9 @@ spec: listWorkspace: true output: - remoteUrl: '{{ steps.publish.output.remoteUrl }}' - entityRef: '{{ steps.register.output.entityRef }}' + links: + - title: Repository + url: '{{ steps.publish.output.remoteUrl }}' + - title: Open in catalog + icon: 'catalog' + entityRef: '{{ steps.register.output.entityRef }}' diff --git a/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.test.tsx b/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.test.tsx index cd51488242..230df903da 100644 --- a/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.test.tsx +++ b/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.test.tsx @@ -14,10 +14,10 @@ * limitations under the License. */ +import { entityRouteRef } from '@backstage/plugin-catalog-react'; +import { renderInTestApp } from '@backstage/test-utils'; import React from 'react'; import { TaskPageLinks } from './TaskPageLinks'; -import { renderInTestApp } from '@backstage/test-utils'; -import { entityRouteRef } from '@backstage/plugin-catalog-react'; describe('TaskPageLinks', () => { beforeEach(() => {}); @@ -68,9 +68,11 @@ describe('TaskPageLinks', () => { links: [ { url: 'https://first.url', title: 'Cool link 1' }, { url: 'https://second.url', title: 'Cool link 2' }, + { entityRef: 'Component:default/my-app', title: 'Open in catalog' }, + { title: 'Skipped' }, ], }; - const { findByText } = await renderInTestApp( + const { findByText, queryByText } = await renderInTestApp( , { mountedRoutes: { @@ -88,5 +90,15 @@ describe('TaskPageLinks', () => { expect(element).toBeInTheDocument(); expect(element).toHaveAttribute('href', 'https://second.url'); + + element = await findByText('Open in catalog'); + + expect(element).toBeInTheDocument(); + expect(element).toHaveAttribute( + 'href', + '/catalog/default/Component/my-app', + ); + + expect(queryByText('Skipped')).not.toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.tsx b/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.tsx index c0b55193c2..394d755424 100644 --- a/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.tsx +++ b/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.tsx @@ -14,21 +14,21 @@ * limitations under the License. */ -import React from 'react'; import { parseEntityName } from '@backstage/catalog-model'; import { IconComponent, IconKey, useApp, useRouteRef } from '@backstage/core'; -import { IconLink } from './IconLink'; import { entityRouteRef } from '@backstage/plugin-catalog-react'; import { Box } from '@material-ui/core'; import LanguageIcon from '@material-ui/icons/Language'; +import React from 'react'; import { TaskOutput } from '../../types'; +import { IconLink } from './IconLink'; type TaskPageLinksProps = { output: TaskOutput; }; export const TaskPageLinks = ({ output }: TaskPageLinksProps) => { - const { entityRef, remoteUrl } = output; + const { entityRef: entityRefOutput, remoteUrl } = output; let { links = [] } = output; const app = useApp(); const entityRoute = useRouteRef(entityRouteRef); @@ -40,12 +40,10 @@ export const TaskPageLinks = ({ output }: TaskPageLinksProps) => { links = [{ url: remoteUrl, title: 'Repo' }, ...links]; } - if (entityRef) { - const entityName = parseEntityName(entityRef); - const target = entityRoute(entityName); + if (entityRefOutput) { links = [ { - url: target, + entityRef: entityRefOutput, title: 'Open in catalog', icon: 'catalog', }, @@ -55,15 +53,25 @@ export const TaskPageLinks = ({ output }: TaskPageLinksProps) => { return ( - {links.map(({ url, title, icon }, i) => ( - - ))} + {links + .filter(({ url, entityRef }) => url || entityRef) + .map(({ url, entityRef, title, icon }) => { + if (entityRef) { + const entityName = parseEntityName(entityRef); + const target = entityRoute(entityName); + return { title, icon, url: target }; + } + return { title, icon, url: url! }; + }) + .map(({ url, title, icon }, i) => ( + + ))} ); }; diff --git a/plugins/scaffolder/src/types.ts b/plugins/scaffolder/src/types.ts index e821d8fa9c..0a34450678 100644 --- a/plugins/scaffolder/src/types.ts +++ b/plugins/scaffolder/src/types.ts @@ -66,12 +66,14 @@ export type ListActionsResponse = Array<{ }>; type OutputLink = { - url: string; title?: string; icon?: string; + url?: string; + entityRef?: string; }; export type TaskOutput = { + /** @deprecated use the `links` property to link out to relevant resources */ entityRef?: string; /** @deprecated use the `links` property to link out to relevant resources */ remoteUrl?: string;