Merge pull request #1508 from spotify/emmaindal/techdocs-base-components
techdocs: base components + basic docs not found page
This commit is contained in:
@@ -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);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
import React from 'react';
|
||||
import { useShadowDom } from '..';
|
||||
import { useAsync } from 'react-use';
|
||||
import { useLocation, useParams, useNavigate } from 'react-router-dom';
|
||||
import { AsyncState } from 'react-use/lib/useAsync';
|
||||
|
||||
import { Grid } from '@material-ui/core';
|
||||
import { Header, Content, ItemCard } from '@backstage/core';
|
||||
import { useLocation, useParams, useNavigate } from 'react-router-dom';
|
||||
|
||||
import transformer, {
|
||||
addBaseUrl,
|
||||
@@ -31,10 +30,15 @@ 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 useFetch = (url: string): AsyncState<string | Error> => {
|
||||
const state = useAsync(async () => {
|
||||
const response = await fetch(url);
|
||||
if (response.status === 404) {
|
||||
return new Error('Page not found');
|
||||
}
|
||||
const raw = await response.text();
|
||||
return raw;
|
||||
}, [url]);
|
||||
@@ -67,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,
|
||||
@@ -116,39 +124,13 @@ export const Reader = () => {
|
||||
}
|
||||
}, [shadowDomRef, state, componentId, path, navigate]);
|
||||
|
||||
if (state.value instanceof Error) return <TechDocsNotFound />;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header
|
||||
title={componentId ?? 'Documentation'}
|
||||
subtitle={componentId ?? 'Documentation available in Backstage'}
|
||||
/>
|
||||
|
||||
<Content>
|
||||
{componentId ? (
|
||||
<div ref={shadowDomRef} />
|
||||
) : (
|
||||
<Grid container>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<ItemCard
|
||||
onClick={() => 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. "
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<ItemCard
|
||||
onClick={() => 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. "
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</Content>
|
||||
<TechDocsPageWrapper title={componentId} subtitle={componentId}>
|
||||
<div ref={shadowDomRef} />
|
||||
</TechDocsPageWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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', () => {
|
||||
const { getByTestId, queryByText } = render(
|
||||
wrapInTestApp(<TechDocsHome />),
|
||||
);
|
||||
|
||||
// Header
|
||||
expect(queryByText('Documentation')).toBeInTheDocument();
|
||||
expect(
|
||||
queryByText(/Documentation available in Backstage/i),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Explore Content
|
||||
expect(getByTestId('docs-explore')).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
type DocumentationSite = {
|
||||
title: string;
|
||||
description: string;
|
||||
tags: Array<string>;
|
||||
path: string;
|
||||
btnLabel: string;
|
||||
};
|
||||
|
||||
const documentationSites: Array<DocumentationSite> = [
|
||||
{
|
||||
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();
|
||||
|
||||
return (
|
||||
<>
|
||||
<TechDocsPageWrapper
|
||||
title="Documentation"
|
||||
subtitle="Documentation available in Backstage"
|
||||
>
|
||||
<Grid container data-testid="docs-explore">
|
||||
{documentationSites.map((site: DocumentationSite, index: number) => (
|
||||
<Grid key={index} item xs={12} sm={6} md={3}>
|
||||
<ItemCard
|
||||
onClick={() => navigate(site.path)}
|
||||
tags={site.tags}
|
||||
title={site.title}
|
||||
label={site.btnLabel}
|
||||
description={site.description}
|
||||
/>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</TechDocsPageWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -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(<TechDocsNotFound />));
|
||||
expect(queryByText(/error: documentation not found/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -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 (
|
||||
<TechDocsPageWrapper
|
||||
title="Documentation"
|
||||
subtitle="Documentation available in Backstage"
|
||||
>
|
||||
<Typography>Error: Documentation not found</Typography>
|
||||
<Typography>Path: {window.location.pathname}</Typography>
|
||||
<Button color="primary" onClick={() => window.history.back()}>
|
||||
Go back
|
||||
</Button>
|
||||
</TechDocsPageWrapper>
|
||||
);
|
||||
};
|
||||
@@ -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(
|
||||
<TechDocsPageWrapper title="test-title" subtitle="test-subtitle">
|
||||
<TechDocsHome />
|
||||
</TechDocsPageWrapper>,
|
||||
),
|
||||
);
|
||||
expect(queryByText(/test-title/i)).toBeInTheDocument();
|
||||
expect(queryByText(/test-subtitle/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -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 (
|
||||
<>
|
||||
<Header title={title} subtitle={subtitle} />
|
||||
<Content>{children}</Content>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user