From 3bbb4d98c65ab5140180184c3845b4f953a28047 Mon Sep 17 00:00:00 2001 From: Jonathan Ash Date: Fri, 28 Jan 2022 16:27:47 +0000 Subject: [PATCH 1/4] Added the option to supply a custom error page to TechDocsPage Signed-off-by: Jonathan Ash --- .changeset/healthy-shoes-flash.md | 5 ++ .../reader/components/TechDocsPage.test.tsx | 58 +++++++++++++++++++ .../src/reader/components/TechDocsPage.tsx | 10 +++- 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 .changeset/healthy-shoes-flash.md diff --git a/.changeset/healthy-shoes-flash.md b/.changeset/healthy-shoes-flash.md new file mode 100644 index 0000000000..8ca1006635 --- /dev/null +++ b/.changeset/healthy-shoes-flash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': minor +--- + +Added ability for to display a custom error page component via prop "NotFoundPage" diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx index b297466a62..5dfa104a25 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx @@ -173,4 +173,62 @@ describe('', () => { expect(rendered.getByText('A custom header')).toBeInTheDocument(); }); }); + + it('should render a custom error page if supplied', async () => { + const CustomErrorPage = ({ errorMessage }: { errorMessage: string }) => ( +
{errorMessage}
+ ); + + useParams.mockReturnValue({ + entityRef: 'Component::backstage', + }); + + const scmIntegrationsApi: ScmIntegrationsApi = + ScmIntegrationsApi.fromConfig( + new ConfigReader({ + integrations: {}, + }), + ); + const techdocsApi: Partial = { + getEntityMetadata: () => + Promise.reject({ + name: 'error', + message: 'error message', + }), + getTechDocsMetadata: () => + Promise.resolve({ + site_name: 'string', + site_description: 'string', + }), + }; + + const techdocsStorageApi: Partial = { + getEntityDocs: (): Promise => Promise.resolve('String'), + getBaseUrl: (): Promise => Promise.resolve('String'), + getApiOrigin: (): Promise => Promise.resolve('String'), + }; + const searchApi = { + query: () => + Promise.resolve({ + results: [], + }), + }; + const apiRegistry = TestApiRegistry.from( + [scmIntegrationsApiRef, scmIntegrationsApi], + [techdocsApiRef, techdocsApi], + [techdocsStorageApiRef, techdocsStorageApi], + [searchApiRef, searchApi], + ); + + await act(async () => { + const rendered = render( + wrapInTestApp( + + + , + ), + ); + expect(await rendered.findByText('error message')).toBeInTheDocument(); + }); + }); }); diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.tsx index aae88d406e..1fb75f8d76 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPage.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPage.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useState, ComponentType } from 'react'; import { useOutlet } from 'react-router'; import { useParams } from 'react-router-dom'; import useAsync from 'react-use/lib/useAsync'; @@ -39,9 +39,13 @@ export type TechDocsPageRenderFunction = ({ export type TechDocsPageProps = { children?: TechDocsPageRenderFunction | React.ReactNode; + NotFoundPage?: ComponentType<{errorMessage: string}> }; -export const TechDocsPage = ({ children }: TechDocsPageProps) => { +export const TechDocsPage = ({ + children, + NotFoundPage = TechDocsNotFound, +}: TechDocsPageProps) => { const outlet = useOutlet(); const [documentReady, setDocumentReady] = useState(false); @@ -67,7 +71,7 @@ export const TechDocsPage = ({ children }: TechDocsPageProps) => { }, [setDocumentReady]); if (entityMetadataError) { - return ; + return ; } if (!children) return outlet || ; From d125e82723049c27cc5c55f0effa735e2ec94fb5 Mon Sep 17 00:00:00 2001 From: Jonathan Ash Date: Wed, 16 Feb 2022 11:36:16 +0000 Subject: [PATCH 2/4] Changed TechdocsReaderPage to use NotFoundErrorPage from createApp Signed-off-by: Jonathan Ash --- .../reader/components/TechDocsPage.test.tsx | 58 ------------------- .../src/reader/components/TechDocsPage.tsx | 16 ++--- 2 files changed, 5 insertions(+), 69 deletions(-) diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx index 5dfa104a25..b297466a62 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx @@ -173,62 +173,4 @@ describe('', () => { expect(rendered.getByText('A custom header')).toBeInTheDocument(); }); }); - - it('should render a custom error page if supplied', async () => { - const CustomErrorPage = ({ errorMessage }: { errorMessage: string }) => ( -
{errorMessage}
- ); - - useParams.mockReturnValue({ - entityRef: 'Component::backstage', - }); - - const scmIntegrationsApi: ScmIntegrationsApi = - ScmIntegrationsApi.fromConfig( - new ConfigReader({ - integrations: {}, - }), - ); - const techdocsApi: Partial = { - getEntityMetadata: () => - Promise.reject({ - name: 'error', - message: 'error message', - }), - getTechDocsMetadata: () => - Promise.resolve({ - site_name: 'string', - site_description: 'string', - }), - }; - - const techdocsStorageApi: Partial = { - getEntityDocs: (): Promise => Promise.resolve('String'), - getBaseUrl: (): Promise => Promise.resolve('String'), - getApiOrigin: (): Promise => Promise.resolve('String'), - }; - const searchApi = { - query: () => - Promise.resolve({ - results: [], - }), - }; - const apiRegistry = TestApiRegistry.from( - [scmIntegrationsApiRef, scmIntegrationsApi], - [techdocsApiRef, techdocsApi], - [techdocsStorageApiRef, techdocsStorageApi], - [searchApiRef, searchApi], - ); - - await act(async () => { - const rendered = render( - wrapInTestApp( - - - , - ), - ); - expect(await rendered.findByText('error message')).toBeInTheDocument(); - }); - }); }); diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.tsx index 1fb75f8d76..c351f88f6e 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPage.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPage.tsx @@ -14,16 +14,15 @@ * limitations under the License. */ -import React, { useCallback, useState, ComponentType } from 'react'; +import React, { useCallback, useState } from 'react'; import { useOutlet } from 'react-router'; import { useParams } from 'react-router-dom'; import useAsync from 'react-use/lib/useAsync'; import { techdocsApiRef } from '../../api'; -import { TechDocsNotFound } from './TechDocsNotFound'; import { LegacyTechDocsPage } from './LegacyTechDocsPage'; import { TechDocsEntityMetadata, TechDocsMetadata } from '../../types'; import { EntityName } from '@backstage/catalog-model'; -import { useApi } from '@backstage/core-plugin-api'; +import { useApi, useApp } from '@backstage/core-plugin-api'; import { Page } from '@backstage/core-components'; export type TechDocsPageRenderFunction = ({ @@ -39,13 +38,10 @@ export type TechDocsPageRenderFunction = ({ export type TechDocsPageProps = { children?: TechDocsPageRenderFunction | React.ReactNode; - NotFoundPage?: ComponentType<{errorMessage: string}> }; -export const TechDocsPage = ({ - children, - NotFoundPage = TechDocsNotFound, -}: TechDocsPageProps) => { +export const TechDocsPage = ({ children }: TechDocsPageProps) => { + const NotFoundErrorPage = useApp().getComponents().NotFoundErrorPage; const outlet = useOutlet(); const [documentReady, setDocumentReady] = useState(false); @@ -70,9 +66,7 @@ export const TechDocsPage = ({ setDocumentReady(true); }, [setDocumentReady]); - if (entityMetadataError) { - return ; - } + if (entityMetadataError) return ; if (!children) return outlet || ; From 8c767a0fb18b4e18c78c492e0826eddba6044069 Mon Sep 17 00:00:00 2001 From: Jonathan Ash Date: Wed, 16 Feb 2022 11:58:18 +0000 Subject: [PATCH 3/4] Updated changeset Signed-off-by: Jonathan Ash --- .changeset/healthy-shoes-flash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/healthy-shoes-flash.md b/.changeset/healthy-shoes-flash.md index 8ca1006635..7e1619e9ec 100644 --- a/.changeset/healthy-shoes-flash.md +++ b/.changeset/healthy-shoes-flash.md @@ -2,4 +2,4 @@ '@backstage/plugin-techdocs': minor --- -Added ability for to display a custom error page component via prop "NotFoundPage" +Changed to use from createApp From 3675e7120c7fc9935ee73c2bc27bb7af5ed893f3 Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Mon, 21 Feb 2022 17:12:50 +0100 Subject: [PATCH 4/4] Minor feedback Signed-off-by: Eric Peterson --- .changeset/healthy-shoes-flash.md | 2 +- plugins/techdocs/src/reader/components/TechDocsPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/healthy-shoes-flash.md b/.changeset/healthy-shoes-flash.md index 7e1619e9ec..5e255020da 100644 --- a/.changeset/healthy-shoes-flash.md +++ b/.changeset/healthy-shoes-flash.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-techdocs': minor +'@backstage/plugin-techdocs': patch --- Changed to use from createApp diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.tsx index c351f88f6e..d96bed6b60 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPage.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPage.tsx @@ -41,7 +41,7 @@ export type TechDocsPageProps = { }; export const TechDocsPage = ({ children }: TechDocsPageProps) => { - const NotFoundErrorPage = useApp().getComponents().NotFoundErrorPage; + const { NotFoundErrorPage } = useApp().getComponents(); const outlet = useOutlet(); const [documentReady, setDocumentReady] = useState(false);