From d19a827ef1c74510d84c307c0028274f041145ef Mon Sep 17 00:00:00 2001 From: Brian Forbis Date: Fri, 16 Jun 2023 16:58:28 -0400 Subject: [PATCH] Add dynamic yaml example to MissingAnnotation component Signed-off-by: Brian Forbis --- .changeset/yellow-rings-invent.md | 5 ++ packages/core-components/package.json | 2 + .../MissingAnnotationEmptyState.tsx | 75 ++++++++++--------- yarn.lock | 2 + 4 files changed, 50 insertions(+), 34 deletions(-) create mode 100644 .changeset/yellow-rings-invent.md diff --git a/.changeset/yellow-rings-invent.md b/.changeset/yellow-rings-invent.md new file mode 100644 index 0000000000..f0335ff492 --- /dev/null +++ b/.changeset/yellow-rings-invent.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +MissingAnnotationEmptyState component can now dynamically generate a YAML example based off the current entity being used. diff --git a/packages/core-components/package.json b/packages/core-components/package.json index d8cc5057ff..e68320ad0c 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -33,9 +33,11 @@ "start": "backstage-cli package start" }, "dependencies": { + "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", + "@backstage/plugin-catalog-react": "workspace:^", "@backstage/theme": "workspace:^", "@backstage/version-bridge": "workspace:^", "@date-io/core": "^1.3.13", diff --git a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx index 9fc9eee959..d7c8558614 100644 --- a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx +++ b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx @@ -25,23 +25,8 @@ import { CodeSnippet } from '../CodeSnippet'; import { Link } from '../Link'; import { EmptyState } from './EmptyState'; -const COMPONENT_YAML_TEMPLATE = `apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: example - description: example.com - annotations: - ANNOTATION: value -spec: - type: website - lifecycle: production - owner: user:guest`; - -const ANNOTATION_REGEXP = /^.*ANNOTATION.*$/m; -const ANNOTATION_YAML = COMPONENT_YAML_TEMPLATE.match(ANNOTATION_REGEXP)![0]; -const ANNOTATION_LINE = COMPONENT_YAML_TEMPLATE.split('\n').findIndex(line => - ANNOTATION_REGEXP.test(line), -); +import { useEntity } from '@backstage/plugin-catalog-react'; +import { Entity } from '@backstage/catalog-model'; type Props = { annotation: string | string[]; @@ -62,19 +47,38 @@ const useStyles = makeStyles( { name: 'BackstageMissingAnnotationEmptyState' }, ); -function generateLineNumbers(lineCount: number) { - return Array.from(Array(lineCount + 1).keys(), i => i + ANNOTATION_LINE); +function generateYamlExample( + entity: Entity, + annotations: string[], +): { yamlText: string; lineNumbers: number[] } { + const kind = entity.kind || 'Component'; + const name = entity.metadata.name || 'example'; + const type = entity.spec?.type || 'website'; + const owner = entity.spec?.owner || 'user:default/guest'; + + const yamlText = `apiVersion: backstage.io/v1alpha1 +kind: ${kind} +metadata: + name: ${name} + annotations:${annotations.map(ann => `\n ${ann}: value`).join('')} +spec: + type: ${type} + owner: ${owner}`; + + let line = 6; // Line 6 is the line number that annotations are added to. + const lineNumbers: number[] = []; + annotations.forEach(() => { + lineNumbers.push(line); + line++; + }); + + return { + yamlText, + lineNumbers, + }; } -function generateComponentYaml(annotations: string[]) { - const annotationYaml = annotations - .map(ann => ANNOTATION_YAML.replace('ANNOTATION', ann)) - .join('\n'); - - return COMPONENT_YAML_TEMPLATE.replace(ANNOTATION_YAML, annotationYaml); -} - -function generateDescription(annotations: string[]) { +function generateDescription(annotations: string[], entityKind = 'Component') { const isSingular = annotations.length <= 1; return ( <> @@ -87,13 +91,14 @@ function generateDescription(annotations: string[]) { ))}{' '} {isSingular ? 'is' : 'are'} missing. You need to add the{' '} - {isSingular ? 'annotation' : 'annotations'} to your component if you want - to enable this tool. + {isSingular ? 'annotation' : 'annotations'} to your {entityKind} if you + want to enable this tool. ); } export function MissingAnnotationEmptyState(props: Props) { + const { entity } = useEntity(); const { annotation, readMoreUrl } = props; const annotations = Array.isArray(annotation) ? annotation : [annotation]; const url = @@ -101,23 +106,25 @@ export function MissingAnnotationEmptyState(props: Props) { 'https://backstage.io/docs/features/software-catalog/well-known-annotations'; const classes = useStyles(); + const entityKind = entity.kind || 'Component'; + const { yamlText, lineNumbers } = generateYamlExample(entity, annotations); return ( - Add the annotation to your component YAML as shown in the + Add the annotation to your {entityKind} YAML as shown in the highlighted example below: diff --git a/yarn.lock b/yarn.lock index b22617f10b..3272752df8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3973,11 +3973,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: + "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/core-app-api": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/plugin-catalog-react": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" "@backstage/version-bridge": "workspace:^"