diff --git a/plugins/catalog/src/components/EntityNotFound/EntityNotFound.tsx b/plugins/catalog/src/components/EntityNotFound/EntityNotFound.tsx new file mode 100644 index 0000000000..c7560c6894 --- /dev/null +++ b/plugins/catalog/src/components/EntityNotFound/EntityNotFound.tsx @@ -0,0 +1,61 @@ +/* + * 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 { Grid, Button, Typography } from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; +import { BackstageTheme } from '@backstage/theme'; + +import { Illo } from './Illo'; + +const useStyles = makeStyles(theme => ({ + container: { + paddingTop: theme.spacing(24), + paddingLeft: theme.spacing(8), + }, + title: { + paddingBottom: theme.spacing(2), + }, + body: { + paddingBottom: theme.spacing(6), + }, +})); + +export const EntityNotFound = () => { + const classes = useStyles(); + + return ( + + + + + Entity was not found + + + Want to help us build this? Check out our Getting Started + documentation. + + + + + ); +}; diff --git a/plugins/catalog/src/components/EntityNotFound/Illo.jsx b/plugins/catalog/src/components/EntityNotFound/Illo.jsx new file mode 100644 index 0000000000..36b8d84f5d --- /dev/null +++ b/plugins/catalog/src/components/EntityNotFound/Illo.jsx @@ -0,0 +1,33 @@ +/* + * 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 { makeStyles } from '@material-ui/core'; +import IlloSvgUrl from './illo.svg'; + +const useStyles = makeStyles({ + illo: { + maxWidth: '60%', + top: 100, + right: 20, + position: 'absolute', + }, +}); + +export const Illo = () => { + const classes = useStyles(); + return ; +}; diff --git a/plugins/catalog/src/components/EntityNotFound/illo.svg b/plugins/catalog/src/components/EntityNotFound/illo.svg new file mode 100644 index 0000000000..df97dfe063 --- /dev/null +++ b/plugins/catalog/src/components/EntityNotFound/illo.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/catalog/src/components/EntityNotFound/index.ts b/plugins/catalog/src/components/EntityNotFound/index.ts new file mode 100644 index 0000000000..613ea7b36d --- /dev/null +++ b/plugins/catalog/src/components/EntityNotFound/index.ts @@ -0,0 +1,16 @@ +/* + * 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. + */ +export { EntityNotFound } from './EntityNotFound'; diff --git a/plugins/catalog/src/components/Router.tsx b/plugins/catalog/src/components/Router.tsx index 61855f56d9..c6e706c15b 100644 --- a/plugins/catalog/src/components/Router.tsx +++ b/plugins/catalog/src/components/Router.tsx @@ -15,6 +15,7 @@ */ import React, { ComponentType } from 'react'; import { CatalogPage } from './CatalogPage'; +import { EntityNotFound } from './EntityNotFound'; import { EntityPageLayout } from './EntityPageLayout'; import { Route, Routes } from 'react-router'; import { entityRoute, rootRoute } from '../routes'; @@ -45,9 +46,10 @@ const DefaultEntityPage = () => ( ); const EntityPageSwitch = ({ EntityPage }: { EntityPage: ComponentType }) => { - const { entity } = useEntity(); + const { entity, loading, error } = useEntity(); // Loading and error states - if (!entity) return ; + if (loading) return ; + if (error || (!loading && !entity)) return ; // Otherwise EntityPage provided from the App // Note that EntityPage will include EntityPageLayout already diff --git a/plugins/catalog/src/hooks/useEntity.ts b/plugins/catalog/src/hooks/useEntity.ts index 53b1cff73a..77ea8c1569 100644 --- a/plugins/catalog/src/hooks/useEntity.ts +++ b/plugins/catalog/src/hooks/useEntity.ts @@ -20,8 +20,6 @@ import { catalogApiRef } from '../api/types'; import { useAsync } from 'react-use'; import { Entity } from '@backstage/catalog-model'; -const REDIRECT_DELAY = 2000; - type EntityLoadingStatus = { entity?: Entity; loading: boolean; @@ -47,13 +45,6 @@ export const useEntityFromUrl = (): EntityLoadingStatus => { ); useEffect(() => { - if (error || (!loading && !entity)) { - errorApi.post(new Error('Entity not found!')); - setTimeout(() => { - navigate('/'); - }, REDIRECT_DELAY); - } - if (!name) { errorApi.post(new Error('No name provided!')); navigate('/'); @@ -67,6 +58,10 @@ export const useEntityFromUrl = (): EntityLoadingStatus => { * Always going to return an entity, or throw an error if not a descendant of a EntityProvider. */ export const useEntity = () => { - const { entity } = useContext<{ entity: Entity }>(EntityContext as any); - return { entity }; + const { entity, loading, error } = useContext<{ + entity: Entity; + loading: boolean; + error: Error; + }>(EntityContext as any); + return { entity, loading, error }; };