From b88968fada25843a3b692017c91ba8c86b342f3f Mon Sep 17 00:00:00 2001 From: jrwpatterson Date: Wed, 9 Aug 2023 08:04:19 +1000 Subject: [PATCH 1/8] feat(techdocs) allow referencing other entities for techdocs Signed-off-by: jrwpatterson --- .../well-known-annotations.md | 15 +++ .../src/components/AboutCard/AboutCard.tsx | 93 ++++++++++++------- plugins/techdocs/src/EntityPageDocs.tsx | 23 ++++- plugins/techdocs/src/Router.tsx | 20 ++-- 4 files changed, 105 insertions(+), 46 deletions(-) diff --git a/docs/features/software-catalog/well-known-annotations.md b/docs/features/software-catalog/well-known-annotations.md index 0a4f5ee400..651520cd28 100644 --- a/docs/features/software-catalog/well-known-annotations.md +++ b/docs/features/software-catalog/well-known-annotations.md @@ -100,6 +100,21 @@ alongside the entity's source code, the value of this annotation can point to an absolute URL, matching the location reference string format outlined above, for example: `url:https://github.com/backstage/backstage/tree/master` +### backstage.io/techdocs-ref + +```yaml +# Example: +metadata: + annotations: + backstage.io/techdocs-external-ref: component:default/example +``` + +The value of this annotation informs of an external entity that owns the TechDocs. +This allows you to reference TechDocs from a single source without either duplicating +the TechDocs in the TechDocs page or needing multiple builds of the same docs. + +This is for situations where you have complex systems where they share a single repo, and likely a single TechDoc location. + ### backstage.io/view-url, backstage.io/edit-url ```yaml diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx index 06cc020e51..6c28660144 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx @@ -16,32 +16,10 @@ import { ANNOTATION_EDIT_URL, ANNOTATION_LOCATION, + CompoundEntityRef, DEFAULT_NAMESPACE, stringifyEntityRef, } from '@backstage/catalog-model'; -import { - HeaderIconLinkRow, - IconLinkVerticalProps, - InfoCardVariants, - Link, -} from '@backstage/core-components'; -import { - alertApiRef, - errorApiRef, - useApi, - useApp, - useRouteRef, -} from '@backstage/core-plugin-api'; -import { - ScmIntegrationIcon, - scmIntegrationsApiRef, -} from '@backstage/integration-react'; -import { - catalogApiRef, - getEntitySourceLocation, - useEntity, -} from '@backstage/plugin-catalog-react'; -import { isTemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { Card, CardContent, @@ -50,14 +28,38 @@ import { IconButton, makeStyles, } from '@material-ui/core'; -import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; +import { + HeaderIconLinkRow, + IconLinkVerticalProps, + InfoCardVariants, + Link, +} from '@backstage/core-components'; +import React, { useCallback } from 'react'; +import { + ScmIntegrationIcon, + scmIntegrationsApiRef, +} from '@backstage/integration-react'; +import { + alertApiRef, + errorApiRef, + useApi, + useApp, + useRouteRef, +} from '@backstage/core-plugin-api'; +import { + catalogApiRef, + getEntitySourceLocation, + useEntity, +} from '@backstage/plugin-catalog-react'; +import { createFromTemplateRouteRef, viewTechDocRouteRef } from '../../routes'; + +import { AboutContent } from './AboutContent'; import CachedIcon from '@material-ui/icons/Cached'; +import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; import DocsIcon from '@material-ui/icons/Description'; import EditIcon from '@material-ui/icons/Edit'; -import React, { useCallback } from 'react'; - -import { createFromTemplateRouteRef, viewTechDocRouteRef } from '../../routes'; -import { AboutContent } from './AboutContent'; +import { isTemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; +import { parseEntityRef } from '@backstage/catalog-model'; const useStyles = makeStyles({ gridItemCard: { @@ -110,6 +112,19 @@ export function AboutCard(props: AboutCardProps) { const entityMetadataEditUrl = entity.metadata.annotations?.[ANNOTATION_EDIT_URL]; + let techdocsRef: CompoundEntityRef | undefined; + + if (entity.metadata.annotations?.['backstage.io/techdocs-external-ref']) { + try { + techdocsRef = parseEntityRef( + entity.metadata.annotations?.['backstage.io/techdocs-external-ref'], + ); + // not a fan of this but we don't care if the parseEntityRef fails + } catch { + techdocsRef = undefined; + } + } + const viewInSource: IconLinkVerticalProps = { label: 'View Source', disabled: !entitySourceLocation, @@ -119,16 +134,24 @@ export function AboutCard(props: AboutCardProps) { const viewInTechDocs: IconLinkVerticalProps = { label: 'View TechDocs', disabled: - !entity.metadata.annotations?.['backstage.io/techdocs-ref'] || - !viewTechdocLink, + !( + entity.metadata.annotations?.['backstage.io/techdocs-ref'] || + entity.metadata.annotations?.['backstage.io/techdocs-external-ref'] + ) || !viewTechdocLink, icon: , href: viewTechdocLink && - viewTechdocLink({ - namespace: entity.metadata.namespace || DEFAULT_NAMESPACE, - kind: entity.kind, - name: entity.metadata.name, - }), + (techdocsRef + ? viewTechdocLink({ + namespace: techdocsRef.namespace || DEFAULT_NAMESPACE, + kind: techdocsRef.kind, + name: techdocsRef.name, + }) + : viewTechdocLink({ + namespace: entity.metadata.namespace || DEFAULT_NAMESPACE, + kind: entity.kind, + name: entity.metadata.name, + })), }; const subHeaderLinks = [viewInSource, viewInTechDocs]; diff --git a/plugins/techdocs/src/EntityPageDocs.tsx b/plugins/techdocs/src/EntityPageDocs.tsx index b0e529f9a5..56c1341aa2 100644 --- a/plugins/techdocs/src/EntityPageDocs.tsx +++ b/plugins/techdocs/src/EntityPageDocs.tsx @@ -14,18 +14,31 @@ * limitations under the License. */ +import { + Entity, + getCompoundEntityRef, + parseEntityRef, +} from '@backstage/catalog-model'; + import React from 'react'; - -import { Entity, getCompoundEntityRef } from '@backstage/catalog-model'; - import { TechDocsReaderPage } from './plugin'; -import { TechDocsReaderPageSubheader } from './reader/components/TechDocsReaderPageSubheader'; import { TechDocsReaderPageContent } from './reader/components/TechDocsReaderPageContent'; +import { TechDocsReaderPageSubheader } from './reader/components/TechDocsReaderPageSubheader'; type EntityPageDocsProps = { entity: Entity }; export const EntityPageDocs = ({ entity }: EntityPageDocsProps) => { - const entityRef = getCompoundEntityRef(entity); + let entityRef = getCompoundEntityRef(entity); + + if (entity.metadata.annotations?.['backstage.io/techdocs-external-ref']) { + try { + entityRef = parseEntityRef( + entity.metadata.annotations?.['backstage.io/techdocs-external-ref'], + ); + } catch { + // not a fan of this but we don't care if the parseEntityRef fails + } + } return ( diff --git a/plugins/techdocs/src/Router.tsx b/plugins/techdocs/src/Router.tsx index f821da2a9f..5c967a54e8 100644 --- a/plugins/techdocs/src/Router.tsx +++ b/plugins/techdocs/src/Router.tsx @@ -18,22 +18,24 @@ import React, { PropsWithChildren } from 'react'; import { Route, Routes, useRoutes } from 'react-router-dom'; import { Entity } from '@backstage/catalog-model'; -import { useEntity } from '@backstage/plugin-catalog-react'; -import { MissingAnnotationEmptyState } from '@backstage/core-components'; - import { EntityPageDocs } from './EntityPageDocs'; +import { MissingAnnotationEmptyState } from '@backstage/core-components'; import { TechDocsIndexPage } from './home/components/TechDocsIndexPage'; import { TechDocsReaderPage } from './reader/components/TechDocsReaderPage'; +import { useEntity } from '@backstage/plugin-catalog-react'; const TECHDOCS_ANNOTATION = 'backstage.io/techdocs-ref'; +const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-external-ref'; + /** * Helper that takes in entity and returns true/false if TechDocs is available for the entity * * @public */ export const isTechDocsAvailable = (entity: Entity) => - Boolean(entity?.metadata?.annotations?.[TECHDOCS_ANNOTATION]); + Boolean(entity?.metadata?.annotations?.[TECHDOCS_ANNOTATION]) || + Boolean(entity?.metadata?.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]); /** * Responsible for registering routes for TechDocs, TechDocs Homepage and separate TechDocs page @@ -75,10 +77,16 @@ export const EmbeddedDocsRouter = (props: PropsWithChildren<{}>) => { }, ]); - const projectId = entity.metadata.annotations?.[TECHDOCS_ANNOTATION]; + const projectId = + entity.metadata.annotations?.[TECHDOCS_ANNOTATION] || + entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]; if (!projectId) { - return ; + return ( + + ); } return element; From e44f45ac4515add4f978f1a4c917af1a464329f7 Mon Sep 17 00:00:00 2001 From: jrwpatterson Date: Wed, 9 Aug 2023 08:22:13 +1000 Subject: [PATCH 2/8] feat(techdocs) update documentation and add change set Signed-off-by: jrwpatterson --- .changeset/modern-trees-add.md | 6 +++++ docs/features/techdocs/how-to-guides.md | 29 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 .changeset/modern-trees-add.md diff --git a/.changeset/modern-trees-add.md b/.changeset/modern-trees-add.md new file mode 100644 index 0000000000..64b36c3adb --- /dev/null +++ b/.changeset/modern-trees-add.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs': minor +'@backstage/plugin-catalog': minor +--- + +This change allows a new annotation of `backstage.io/techdocs-external-ref` this ref allows you to reference another entity for its TechDocs. This allows you have a single TechDoc for all items in a system, for example you might have a frontend and a backend in the same repo. This would allow you to have TechDocs build under a `System` entity while referencing the system e.g.: `backstage.io/techdocs-external-ref: system:default/example` that will show the systems docs in both the TechDocs button and the TechDocs tab without needing to do duplicate builds and filling the TechDocs page with garbage. diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index ab554db3bd..0ab89ed9b6 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -678,3 +678,32 @@ entity. If the value of this annotation is `'local'`, the TechDocs backend will and publish the documentation for them. If the value of the `company.com/techdocs-builder` annotation is anything other than `'local'`, the user is responsible for publishing documentation to the appropriate location in the TechDocs external storage. + +## Reference another components TechDocs + +In systems where you might have multiple entities for example a System with a Website and an API, when served from a Monorepo you might want to keep the TechDocs in one location in the repository. + +In this case you can add the `backstage.io/techdocs-external-ref` annotation and point to the owners `entityRef` and use its TechDocs. This allows the Subcomponents to read the parents docs, filling the TechDocs link on the `AboutCard` element and the Techdocs tab + +```yaml +apiVersion: backstage.io/v1alpha1 +kind: System +metadata: + name: example + namespace: default + title: Example + description: This is the parent entity + annotations: + backstage.io/techdocs-ref: dir:. + +--- +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: example-platfrom + title: Example Application Platform + namespace: default + description: This is the child entity + annotations: + backstage.io/techdocs-external-ref: system:default/example +``` From 876a340a20f0fa8389160437f11b5aaf659a55f2 Mon Sep 17 00:00:00 2001 From: jrwpatterson Date: Wed, 9 Aug 2023 08:33:04 +1000 Subject: [PATCH 3/8] feat(techdocs) add test Signed-off-by: jrwpatterson --- .../components/AboutCard/AboutCard.test.tsx | 81 ++++++++++++++++--- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx index e8d2657e9f..2e5642ec54 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx @@ -14,24 +14,25 @@ * limitations under the License. */ -import { RELATION_OWNED_BY } from '@backstage/catalog-model'; -import { ConfigReader } from '@backstage/core-app-api'; +import { + CatalogApi, + EntityProvider, + catalogApiRef, + entityRouteRef, +} from '@backstage/plugin-catalog-react'; import { ScmIntegrationsApi, scmIntegrationsApiRef, } from '@backstage/integration-react'; -import { - catalogApiRef, - EntityProvider, - CatalogApi, - entityRouteRef, -} from '@backstage/plugin-catalog-react'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import userEvent from '@testing-library/user-event'; -import { screen } from '@testing-library/react'; -import React from 'react'; +import { TestApiProvider, renderInTestApp } from '@backstage/test-utils'; import { createFromTemplateRouteRef, viewTechDocRouteRef } from '../../routes'; + import { AboutCard } from './AboutCard'; +import { ConfigReader } from '@backstage/core-app-api'; +import { RELATION_OWNED_BY } from '@backstage/catalog-model'; +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; describe('', () => { const catalogApi: jest.Mocked = { @@ -347,6 +348,62 @@ describe('', () => { ).not.toBeInTheDocument(); }); + it('renders techdocs lin when 3rdparty', async () => { + const entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'software', + annotations: { + 'backstage.io/techdocs-external-ref': 'system:default/example', + }, + }, + spec: { + owner: 'guest', + type: 'service', + lifecycle: 'production', + }, + }; + + await renderInTestApp( + + + + + , + { + mountedRoutes: { + '/docs/:namespace/:kind/:name': viewTechDocRouteRef, + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + expect(screen.getByText('View TechDocs').closest('a')).toHaveAttribute( + 'href', + '/docs/default/System/example', + ); + }); + it('renders techdocs link', async () => { const entity = { apiVersion: 'v1', From 42e3cc29cc3a8937b805d316555d949e8d052c48 Mon Sep 17 00:00:00 2001 From: jrwpatterson Date: Wed, 9 Aug 2023 12:58:18 +1000 Subject: [PATCH 4/8] feat(techdocs) fix test Signed-off-by: jrwpatterson --- plugins/catalog/src/components/AboutCard/AboutCard.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx index 2e5642ec54..036507ada7 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx @@ -400,7 +400,7 @@ describe('', () => { expect(screen.getByText('View TechDocs').closest('a')).toHaveAttribute( 'href', - '/docs/default/System/example', + '/docs/default/system/example', ); }); From b516f70b83df00eaeddbdabc118d41796e08cfdf Mon Sep 17 00:00:00 2001 From: jrwpatterson Date: Fri, 11 Aug 2023 08:03:21 +1000 Subject: [PATCH 5/8] Changes the chosen annotation to Signed-off-by: jrwpatterson --- .changeset/modern-trees-add.md | 2 +- docs/features/software-catalog/well-known-annotations.md | 4 ++-- docs/features/techdocs/how-to-guides.md | 4 ++-- plugins/catalog/src/components/AboutCard/AboutCard.test.tsx | 2 +- plugins/catalog/src/components/AboutCard/AboutCard.tsx | 6 +++--- plugins/techdocs/src/EntityPageDocs.tsx | 4 ++-- plugins/techdocs/src/Router.tsx | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.changeset/modern-trees-add.md b/.changeset/modern-trees-add.md index 64b36c3adb..bb5ea78a5b 100644 --- a/.changeset/modern-trees-add.md +++ b/.changeset/modern-trees-add.md @@ -3,4 +3,4 @@ '@backstage/plugin-catalog': minor --- -This change allows a new annotation of `backstage.io/techdocs-external-ref` this ref allows you to reference another entity for its TechDocs. This allows you have a single TechDoc for all items in a system, for example you might have a frontend and a backend in the same repo. This would allow you to have TechDocs build under a `System` entity while referencing the system e.g.: `backstage.io/techdocs-external-ref: system:default/example` that will show the systems docs in both the TechDocs button and the TechDocs tab without needing to do duplicate builds and filling the TechDocs page with garbage. +This change allows a new annotation of `backstage.io/techdocs-entity` this ref allows you to reference another entity for its TechDocs. This allows you have a single TechDoc for all items in a system, for example you might have a frontend and a backend in the same repo. This would allow you to have TechDocs build under a `System` entity while referencing the system e.g.: `backstage.io/techdocs-entity: system:default/example` that will show the systems docs in both the TechDocs button and the TechDocs tab without needing to do duplicate builds and filling the TechDocs page with garbage. diff --git a/docs/features/software-catalog/well-known-annotations.md b/docs/features/software-catalog/well-known-annotations.md index 651520cd28..70f5ff5e14 100644 --- a/docs/features/software-catalog/well-known-annotations.md +++ b/docs/features/software-catalog/well-known-annotations.md @@ -100,13 +100,13 @@ alongside the entity's source code, the value of this annotation can point to an absolute URL, matching the location reference string format outlined above, for example: `url:https://github.com/backstage/backstage/tree/master` -### backstage.io/techdocs-ref +### backstage.io/techdocs-entity ```yaml # Example: metadata: annotations: - backstage.io/techdocs-external-ref: component:default/example + backstage.io/techdocs-entity: component:default/example ``` The value of this annotation informs of an external entity that owns the TechDocs. diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 0ab89ed9b6..1eaaa02c6d 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -683,7 +683,7 @@ documentation to the appropriate location in the TechDocs external storage. In systems where you might have multiple entities for example a System with a Website and an API, when served from a Monorepo you might want to keep the TechDocs in one location in the repository. -In this case you can add the `backstage.io/techdocs-external-ref` annotation and point to the owners `entityRef` and use its TechDocs. This allows the Subcomponents to read the parents docs, filling the TechDocs link on the `AboutCard` element and the Techdocs tab +In this case you can add the `backstage.io/techdocs-entity` annotation and point to the owners `entityRef` and use its TechDocs. This allows the Subcomponents to read the parents docs, filling the TechDocs link on the `AboutCard` element and the Techdocs tab ```yaml apiVersion: backstage.io/v1alpha1 @@ -705,5 +705,5 @@ metadata: namespace: default description: This is the child entity annotations: - backstage.io/techdocs-external-ref: system:default/example + backstage.io/techdocs-entity: system:default/example ``` diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx index 036507ada7..1679e2ddf5 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx @@ -355,7 +355,7 @@ describe('', () => { metadata: { name: 'software', annotations: { - 'backstage.io/techdocs-external-ref': 'system:default/example', + 'backstage.io/techdocs-entity': 'system:default/example', }, }, spec: { diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx index 6c28660144..6a782cffc1 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx @@ -114,10 +114,10 @@ export function AboutCard(props: AboutCardProps) { let techdocsRef: CompoundEntityRef | undefined; - if (entity.metadata.annotations?.['backstage.io/techdocs-external-ref']) { + if (entity.metadata.annotations?.['backstage.io/techdocs-entity']) { try { techdocsRef = parseEntityRef( - entity.metadata.annotations?.['backstage.io/techdocs-external-ref'], + entity.metadata.annotations?.['backstage.io/techdocs-entity'], ); // not a fan of this but we don't care if the parseEntityRef fails } catch { @@ -136,7 +136,7 @@ export function AboutCard(props: AboutCardProps) { disabled: !( entity.metadata.annotations?.['backstage.io/techdocs-ref'] || - entity.metadata.annotations?.['backstage.io/techdocs-external-ref'] + entity.metadata.annotations?.['backstage.io/techdocs-entity'] ) || !viewTechdocLink, icon: , href: diff --git a/plugins/techdocs/src/EntityPageDocs.tsx b/plugins/techdocs/src/EntityPageDocs.tsx index 56c1341aa2..3d9aced9f3 100644 --- a/plugins/techdocs/src/EntityPageDocs.tsx +++ b/plugins/techdocs/src/EntityPageDocs.tsx @@ -30,10 +30,10 @@ type EntityPageDocsProps = { entity: Entity }; export const EntityPageDocs = ({ entity }: EntityPageDocsProps) => { let entityRef = getCompoundEntityRef(entity); - if (entity.metadata.annotations?.['backstage.io/techdocs-external-ref']) { + if (entity.metadata.annotations?.['backstage.io/techdocs-entity']) { try { entityRef = parseEntityRef( - entity.metadata.annotations?.['backstage.io/techdocs-external-ref'], + entity.metadata.annotations?.['backstage.io/techdocs-entity'], ); } catch { // not a fan of this but we don't care if the parseEntityRef fails diff --git a/plugins/techdocs/src/Router.tsx b/plugins/techdocs/src/Router.tsx index 5c967a54e8..3a0d2515d8 100644 --- a/plugins/techdocs/src/Router.tsx +++ b/plugins/techdocs/src/Router.tsx @@ -26,7 +26,7 @@ import { useEntity } from '@backstage/plugin-catalog-react'; const TECHDOCS_ANNOTATION = 'backstage.io/techdocs-ref'; -const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-external-ref'; +const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-entity'; /** * Helper that takes in entity and returns true/false if TechDocs is available for the entity From 0299919d86a8c160814ea32fe64722106fc9e967 Mon Sep 17 00:00:00 2001 From: jrwpatterson Date: Mon, 28 Aug 2023 08:00:23 +1000 Subject: [PATCH 6/8] feat(Techdocs) fix the annotations Signed-off-by: jrwpatterson --- .../catalog/src/components/AboutCard/AboutCard.tsx | 12 ++++++++---- plugins/techdocs/src/EntityPageDocs.tsx | 6 ++++-- plugins/techdocs/src/Router.tsx | 2 +- yarn.lock | 6 +++--- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx index 6a782cffc1..34aa463c39 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx @@ -61,6 +61,10 @@ import EditIcon from '@material-ui/icons/Edit'; import { isTemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { parseEntityRef } from '@backstage/catalog-model'; +const TECHDOCS_ANNOTATION = 'backstage.io/techdocs-ref'; + +const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-entity'; + const useStyles = makeStyles({ gridItemCard: { display: 'flex', @@ -114,10 +118,10 @@ export function AboutCard(props: AboutCardProps) { let techdocsRef: CompoundEntityRef | undefined; - if (entity.metadata.annotations?.['backstage.io/techdocs-entity']) { + if (entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]) { try { techdocsRef = parseEntityRef( - entity.metadata.annotations?.['backstage.io/techdocs-entity'], + entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION], ); // not a fan of this but we don't care if the parseEntityRef fails } catch { @@ -135,8 +139,8 @@ export function AboutCard(props: AboutCardProps) { label: 'View TechDocs', disabled: !( - entity.metadata.annotations?.['backstage.io/techdocs-ref'] || - entity.metadata.annotations?.['backstage.io/techdocs-entity'] + entity.metadata.annotations?.[TECHDOCS_ANNOTATION] || + entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION] ) || !viewTechdocLink, icon: , href: diff --git a/plugins/techdocs/src/EntityPageDocs.tsx b/plugins/techdocs/src/EntityPageDocs.tsx index 3d9aced9f3..af184bb1a8 100644 --- a/plugins/techdocs/src/EntityPageDocs.tsx +++ b/plugins/techdocs/src/EntityPageDocs.tsx @@ -25,15 +25,17 @@ import { TechDocsReaderPage } from './plugin'; import { TechDocsReaderPageContent } from './reader/components/TechDocsReaderPageContent'; import { TechDocsReaderPageSubheader } from './reader/components/TechDocsReaderPageSubheader'; +const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-entity'; + type EntityPageDocsProps = { entity: Entity }; export const EntityPageDocs = ({ entity }: EntityPageDocsProps) => { let entityRef = getCompoundEntityRef(entity); - if (entity.metadata.annotations?.['backstage.io/techdocs-entity']) { + if (entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]) { try { entityRef = parseEntityRef( - entity.metadata.annotations?.['backstage.io/techdocs-entity'], + entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION], ); } catch { // not a fan of this but we don't care if the parseEntityRef fails diff --git a/plugins/techdocs/src/Router.tsx b/plugins/techdocs/src/Router.tsx index 3a0d2515d8..b06fec8fb7 100644 --- a/plugins/techdocs/src/Router.tsx +++ b/plugins/techdocs/src/Router.tsx @@ -84,7 +84,7 @@ export const EmbeddedDocsRouter = (props: PropsWithChildren<{}>) => { if (!projectId) { return ( ); } diff --git a/yarn.lock b/yarn.lock index 40bb6fcaa8..ae6b5bac8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21147,9 +21147,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001400": - version: 1.0.30001407 - resolution: "caniuse-lite@npm:1.0.30001407" - checksum: e1c449d22f120a708accc956c1780f1da01af6c226cb6a324e531dc9f26f53075bff98e6c9cfce806157cdeede459aa8de03a3407b05f71d292a57b2910018b1 + version: 1.0.30001522 + resolution: "caniuse-lite@npm:1.0.30001522" + checksum: 56e3551c02ae595085114073cf242f7d9d54d32255c80893ca9098a44f44fc6eef353936f234f31c7f4cb894dd2b6c9c4626e30649ee29e04d70aa127eeefeb0 languageName: node linkType: hard From 60e43818f410ac3caa4e8f3fb7c2a60413357c18 Mon Sep 17 00:00:00 2001 From: jrwpatterson Date: Mon, 28 Aug 2023 09:30:38 +1000 Subject: [PATCH 7/8] fix(techdocs) prettier Signed-off-by: jrwpatterson --- plugins/techdocs/src/Router.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/techdocs/src/Router.tsx b/plugins/techdocs/src/Router.tsx index b06fec8fb7..814bf3cf65 100644 --- a/plugins/techdocs/src/Router.tsx +++ b/plugins/techdocs/src/Router.tsx @@ -82,11 +82,7 @@ export const EmbeddedDocsRouter = (props: PropsWithChildren<{}>) => { entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]; if (!projectId) { - return ( - - ); + return ; } return element; From 49dfda74d0b2401cd16e9bf28e303d954890f352 Mon Sep 17 00:00:00 2001 From: jrwpatterson Date: Mon, 28 Aug 2023 15:17:20 +1000 Subject: [PATCH 8/8] add to adopters Signed-off-by: jrwpatterson --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index 6668d471bb..de516f1f4f 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -257,3 +257,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Zenklub](https://www.zenklub.com.br) | [@zenklub](https://github.com/zenklub), [@gioufop](https://github.com/gioufop) | Developer portal, services catalog and centralization of metrics from Grafana Stack and AWS. Furthermore, centralization of documentation and infra details like Tools, Network services and so on. | | [Platzi](https://platzi.com/) | [@juancarestre](https://github.com/juancarestre/), [Engineering at Platzi](https://github.com/PlatziDev/) | Backstage allow our developers to get easily engaged with all the internal components, technical documentations and software templates. All new developers reduce its onboarding time via Backstage, and after a couple of integrations it allowed us to create new components with in a couple of clicks. | | [idealo](https://idealo.de) | [Wanis Fahmy](https://github.com/wanisfahmyDE), [Sajjad Pervaiz](https://github.com/sjvaiz), [Tim Heurich](https://github.com/theurichde) | Backstage is our Internal developer portal. Along with other plugins, We use the software catalog, TechDocs and explore plugins to manage, discover and document our software components and platform products. | +| [V2 Digital](https://v2.digital) | [Joe Patterson](https://github.com/jrwpatterson)| We will be using it to be a corporate dashboard plus our software catalog. |