From cabd540abbaefbe78da61f5a03a798217d8fbe2f Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Wed, 1 Jul 2020 21:21:53 +0200 Subject: [PATCH 1/6] refactor(techdocs): basic techdocs not found, split out components from reader --- plugins/techdocs/src/plugin.ts | 3 +- .../techdocs/src/reader/components/Reader.tsx | 42 +++----------- .../reader/components/TechDocsHome.test.tsx | 36 ++++++++++++ .../src/reader/components/TechDocsHome.tsx | 55 +++++++++++++++++++ .../components/TechDocsNotFound.test.tsx | 26 +++++++++ .../reader/components/TechDocsNotFound.tsx | 34 ++++++++++++ .../components/TechDocsPageWrapper.test.tsx | 34 ++++++++++++ .../reader/components/TechDocsPageWrapper.tsx | 37 +++++++++++++ 8 files changed, 232 insertions(+), 35 deletions(-) create mode 100644 plugins/techdocs/src/reader/components/TechDocsHome.test.tsx create mode 100644 plugins/techdocs/src/reader/components/TechDocsHome.tsx create mode 100644 plugins/techdocs/src/reader/components/TechDocsNotFound.test.tsx create mode 100644 plugins/techdocs/src/reader/components/TechDocsNotFound.tsx create mode 100644 plugins/techdocs/src/reader/components/TechDocsPageWrapper.test.tsx create mode 100644 plugins/techdocs/src/reader/components/TechDocsPageWrapper.tsx diff --git a/plugins/techdocs/src/plugin.ts b/plugins/techdocs/src/plugin.ts index 89a5ddeb73..a96f7e5502 100644 --- a/plugins/techdocs/src/plugin.ts +++ b/plugins/techdocs/src/plugin.ts @@ -30,6 +30,7 @@ */ import { createPlugin, createRouteRef } from '@backstage/core'; +import { TechDocsHome } from './reader/components/TechDocsHome'; import { Reader } from './reader/components/Reader'; export const rootRouteRef = createRouteRef({ @@ -45,7 +46,7 @@ export const rootDocsRouteRef = createRouteRef({ export const plugin = createPlugin({ id: 'techdocs', register({ router }) { - router.addRoute(rootRouteRef, Reader); + router.addRoute(rootRouteRef, TechDocsHome); router.addRoute(rootDocsRouteRef, Reader); }, }); diff --git a/plugins/techdocs/src/reader/components/Reader.tsx b/plugins/techdocs/src/reader/components/Reader.tsx index 6398d86515..aa42eaffc7 100644 --- a/plugins/techdocs/src/reader/components/Reader.tsx +++ b/plugins/techdocs/src/reader/components/Reader.tsx @@ -19,9 +19,6 @@ import { useShadowDom } from '..'; import { useAsync } from 'react-use'; import { useLocation, useParams, useNavigate } from 'react-router-dom'; -import { Grid } from '@material-ui/core'; -import { Header, Content, ItemCard } from '@backstage/core'; - import transformer, { addBaseUrl, rewriteDocLinks, @@ -31,10 +28,13 @@ import transformer, { } from '../transformers'; import { docStorageURL } from '../../config'; import URLFormatter from '../urlFormatter'; +import { TechDocsNotFound } from './TechDocsNotFound'; +import { TechDocsPageWrapper } from './TechDocsPageWrapper'; const useFetch = (url: string) => { const state = useAsync(async () => { const response = await fetch(url); + if (response.status === 404) return '404'; const raw = await response.text(); return raw; }, [url]); @@ -116,39 +116,13 @@ export const Reader = () => { } }, [shadowDomRef, state, componentId, path, navigate]); + if (state.value === '404') return ; + return ( <> -
- - - {componentId ? ( -
- ) : ( - - - navigate('/docs/mkdocs')} - tags={['Developer Tool']} - title="MkDocs" - label="Read Docs" - description="MkDocs is a fast, simple and downright gorgeous static site generator that's geared towards building project documentation. " - /> - - - navigate('/docs/backstage-microsite')} - tags={['Service']} - title="Backstage" - label="Read Docs" - description="Getting started guides, API Overview, documentation around how to Create a Plugin and more. " - /> - - - )} - + +
+ ); }; diff --git a/plugins/techdocs/src/reader/components/TechDocsHome.test.tsx b/plugins/techdocs/src/reader/components/TechDocsHome.test.tsx new file mode 100644 index 0000000000..2140541033 --- /dev/null +++ b/plugins/techdocs/src/reader/components/TechDocsHome.test.tsx @@ -0,0 +1,36 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TechDocsHome } from './TechDocsHome'; +import React from 'react'; +import { render } from '@testing-library/react'; +import { wrapInTestApp } from '@backstage/test-utils'; + +describe('TechDocs Home', () => { + it('should render a TechDocs home page', async () => { + const { getByTestId, queryByText } = render( + wrapInTestApp(), + ); + + // Header + expect(queryByText('Documentation')).toBeInTheDocument(); + expect( + queryByText(/Documentation available in Backstage/i), + ).toBeInTheDocument(); + + // Explore Content + expect(getByTestId('docs-explore')).toBeDefined(); + }); +}); diff --git a/plugins/techdocs/src/reader/components/TechDocsHome.tsx b/plugins/techdocs/src/reader/components/TechDocsHome.tsx new file mode 100644 index 0000000000..9e51b5f582 --- /dev/null +++ b/plugins/techdocs/src/reader/components/TechDocsHome.tsx @@ -0,0 +1,55 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Grid } from '@material-ui/core'; +import { ItemCard } from '@backstage/core'; +import { TechDocsPageWrapper } from './TechDocsPageWrapper'; + +export const TechDocsHome = () => { + const navigate = useNavigate(); + + return ( + <> + + + + navigate('/docs/mkdocs')} + tags={['Developer Tool']} + title="MkDocs" + label="Read Docs" + description="MkDocs is a fast, simple and downright gorgeous static site generator that's geared towards building project documentation. " + /> + + + navigate('/docs/backstage-microsite')} + tags={['Service']} + title="Backstage" + label="Read Docs" + description="Getting started guides, API Overview, documentation around how to Create a Plugin and more. " + /> + + + + + ); +}; diff --git a/plugins/techdocs/src/reader/components/TechDocsNotFound.test.tsx b/plugins/techdocs/src/reader/components/TechDocsNotFound.test.tsx new file mode 100644 index 0000000000..1d3fbaf0d5 --- /dev/null +++ b/plugins/techdocs/src/reader/components/TechDocsNotFound.test.tsx @@ -0,0 +1,26 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TechDocsNotFound } from './TechDocsNotFound'; +import React from 'react'; +import { render } from '@testing-library/react'; +import { wrapInTestApp } from '@backstage/test-utils'; + +describe('TechDocs Not Found', () => { + it('should render a Documentation not found page', async () => { + const { queryByText } = render(wrapInTestApp()); + expect(queryByText(/Error: Documentation not found/i)).toBeInTheDocument(); + }); +}); diff --git a/plugins/techdocs/src/reader/components/TechDocsNotFound.tsx b/plugins/techdocs/src/reader/components/TechDocsNotFound.tsx new file mode 100644 index 0000000000..2a961b5bc0 --- /dev/null +++ b/plugins/techdocs/src/reader/components/TechDocsNotFound.tsx @@ -0,0 +1,34 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { Typography, Button } from '@material-ui/core'; +import { TechDocsPageWrapper } from './TechDocsPageWrapper'; + +export const TechDocsNotFound = () => { + return ( + + Error: Documentation not found + Path: {window.location.pathname} + + + ); +}; diff --git a/plugins/techdocs/src/reader/components/TechDocsPageWrapper.test.tsx b/plugins/techdocs/src/reader/components/TechDocsPageWrapper.test.tsx new file mode 100644 index 0000000000..d4cc49c919 --- /dev/null +++ b/plugins/techdocs/src/reader/components/TechDocsPageWrapper.test.tsx @@ -0,0 +1,34 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TechDocsPageWrapper } from './TechDocsPageWrapper'; +import { TechDocsHome } from './TechDocsHome'; +import React from 'react'; +import { render } from '@testing-library/react'; +import { wrapInTestApp } from '@backstage/test-utils'; + +describe('TechDocs Page Wrapper', () => { + it('should render a TechDocs Page Wrapper', async () => { + const { queryByText } = render( + wrapInTestApp( + + + , + ), + ); + expect(queryByText(/test-title/i)).toBeInTheDocument(); + expect(queryByText(/test-subtitle/i)).toBeInTheDocument(); + }); +}); diff --git a/plugins/techdocs/src/reader/components/TechDocsPageWrapper.tsx b/plugins/techdocs/src/reader/components/TechDocsPageWrapper.tsx new file mode 100644 index 0000000000..abb702535b --- /dev/null +++ b/plugins/techdocs/src/reader/components/TechDocsPageWrapper.tsx @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { Header, Content } from '@backstage/core'; + +type TechDocsPageWrapperProps = { + title: string; + subtitle: string; + children: any; +}; + +export const TechDocsPageWrapper = ({ + children, + title, + subtitle, +}: TechDocsPageWrapperProps) => { + return ( + <> +
+ {children} + + ); +}; From 6f3a8ee90a30d7c037db77adc2885fc5baa5ad1b Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Fri, 3 Jul 2020 11:37:37 +0200 Subject: [PATCH 2/6] fix(test): remove async Co-authored-by: Bilawal Hameed --- plugins/techdocs/src/reader/components/TechDocsHome.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs/src/reader/components/TechDocsHome.test.tsx b/plugins/techdocs/src/reader/components/TechDocsHome.test.tsx index 2140541033..dd31e6a318 100644 --- a/plugins/techdocs/src/reader/components/TechDocsHome.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsHome.test.tsx @@ -19,7 +19,7 @@ import { render } from '@testing-library/react'; import { wrapInTestApp } from '@backstage/test-utils'; describe('TechDocs Home', () => { - it('should render a TechDocs home page', async () => { + it('should render a TechDocs home page', () => { const { getByTestId, queryByText } = render( wrapInTestApp(), ); From 3e3dff511bcc4a0f78a504ba96c045e38a044c17 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Fri, 3 Jul 2020 11:38:27 +0200 Subject: [PATCH 3/6] fix(test): change to lowercase Co-authored-by: Bilawal Hameed --- .../techdocs/src/reader/components/TechDocsNotFound.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs/src/reader/components/TechDocsNotFound.test.tsx b/plugins/techdocs/src/reader/components/TechDocsNotFound.test.tsx index 1d3fbaf0d5..7792164b14 100644 --- a/plugins/techdocs/src/reader/components/TechDocsNotFound.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsNotFound.test.tsx @@ -21,6 +21,6 @@ import { wrapInTestApp } from '@backstage/test-utils'; describe('TechDocs Not Found', () => { it('should render a Documentation not found page', async () => { const { queryByText } = render(wrapInTestApp()); - expect(queryByText(/Error: Documentation not found/i)).toBeInTheDocument(); + expect(queryByText(/error: documentation not found/i)).toBeInTheDocument(); }); }); From 3229b16ce8e51622377f679ba0d1b1d3eea9b283 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Fri, 3 Jul 2020 11:50:31 +0200 Subject: [PATCH 4/6] fix(techdocs-home): move docs sites mock data to array --- .../src/reader/components/TechDocsHome.tsx | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/plugins/techdocs/src/reader/components/TechDocsHome.tsx b/plugins/techdocs/src/reader/components/TechDocsHome.tsx index 9e51b5f582..3f9763912c 100644 --- a/plugins/techdocs/src/reader/components/TechDocsHome.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsHome.tsx @@ -20,6 +20,32 @@ import { Grid } from '@material-ui/core'; import { ItemCard } from '@backstage/core'; import { TechDocsPageWrapper } from './TechDocsPageWrapper'; +type DocumentationSite = { + title: string; + description: string; + tags: Array; + path: string; + btnLabel: string; +}; + +const documentationSites: Array = [ + { + title: 'MkDocs', + description: + "MkDocs is a fast, simple and downright gorgeous static site generator that's geared towards building project documentation. ", + tags: ['Developer Tool'], + path: '/docs/mkdocs', + btnLabel: 'Read Docs', + }, + { + title: 'Backstage Docs', + description: + 'Getting started guides, API Overview, documentation around how to Create a Plugin and more. ', + tags: ['Service'], + path: '/docs/backstage-microsite', + btnLabel: 'Read Docs', + }, +]; export const TechDocsHome = () => { const navigate = useNavigate(); @@ -30,24 +56,17 @@ export const TechDocsHome = () => { subtitle="Documentation available in Backstage" > - - navigate('/docs/mkdocs')} - tags={['Developer Tool']} - title="MkDocs" - label="Read Docs" - description="MkDocs is a fast, simple and downright gorgeous static site generator that's geared towards building project documentation. " - /> - - - navigate('/docs/backstage-microsite')} - tags={['Service']} - title="Backstage" - label="Read Docs" - description="Getting started guides, API Overview, documentation around how to Create a Plugin and more. " - /> - + {documentationSites.map((site: DocumentationSite, index: number) => ( + + navigate(site.path)} + tags={site.tags} + title={site.title} + label={site.btnLabel} + description={site.description} + /> + + ))} From eaf1d0a09dc4e08b6526b8af5c9b9a5e9d6e4739 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Fri, 3 Jul 2020 11:51:19 +0200 Subject: [PATCH 5/6] fix(techdocs-404): throw error --- plugins/techdocs/src/reader/components/Reader.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/techdocs/src/reader/components/Reader.tsx b/plugins/techdocs/src/reader/components/Reader.tsx index aa42eaffc7..72ef752e34 100644 --- a/plugins/techdocs/src/reader/components/Reader.tsx +++ b/plugins/techdocs/src/reader/components/Reader.tsx @@ -34,7 +34,9 @@ import { TechDocsPageWrapper } from './TechDocsPageWrapper'; const useFetch = (url: string) => { const state = useAsync(async () => { const response = await fetch(url); - if (response.status === 404) return '404'; + if (response.status === 404) { + return new Error('Page not found'); + } const raw = await response.text(); return raw; }, [url]); @@ -116,7 +118,7 @@ export const Reader = () => { } }, [shadowDomRef, state, componentId, path, navigate]); - if (state.value === '404') return ; + if (state.value instanceof Error) return ; return ( <> From 8945b51114f3996ce641c1aebdd9ec29dfb9c876 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Fri, 3 Jul 2020 12:06:14 +0200 Subject: [PATCH 6/6] fix(useFetch): use AsyncState type --- plugins/techdocs/src/reader/components/Reader.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/techdocs/src/reader/components/Reader.tsx b/plugins/techdocs/src/reader/components/Reader.tsx index 72ef752e34..995d9dc99f 100644 --- a/plugins/techdocs/src/reader/components/Reader.tsx +++ b/plugins/techdocs/src/reader/components/Reader.tsx @@ -17,6 +17,8 @@ import React from 'react'; import { useShadowDom } from '..'; import { useAsync } from 'react-use'; +import { AsyncState } from 'react-use/lib/useAsync'; + import { useLocation, useParams, useNavigate } from 'react-router-dom'; import transformer, { @@ -31,7 +33,7 @@ import URLFormatter from '../urlFormatter'; import { TechDocsNotFound } from './TechDocsNotFound'; import { TechDocsPageWrapper } from './TechDocsPageWrapper'; -const useFetch = (url: string) => { +const useFetch = (url: string): AsyncState => { const state = useAsync(async () => { const response = await fetch(url); if (response.status === 404) { @@ -69,7 +71,11 @@ export const Reader = () => { React.useEffect(() => { const divElement = shadowDomRef.current; - if (divElement?.shadowRoot && state.value) { + if ( + divElement?.shadowRoot && + state.value && + !(state.value instanceof Error) + ) { const transformedElement = transformer(state.value, [ addBaseUrl({ docStorageURL,