feat: 404 page for entity not found

This commit is contained in:
Shashank Bairy R
2020-09-25 23:28:00 +05:30
parent 8140f4ace6
commit 10fc1ab08c
6 changed files with 186 additions and 8 deletions
@@ -0,0 +1,90 @@
/*
* 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, { FC } from 'react';
import { Grid, Button, Typography } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import {
Header,
Page,
Content,
ContentHeader,
HeaderLabel,
pageTheme,
SupportButton,
} from '@backstage/core';
import { BackstageTheme } from '@backstage/theme';
import { Illo } from './Illo';
const useStyles = makeStyles<BackstageTheme>(theme => ({
container: {
paddingTop: theme.spacing(6),
},
title: {
paddingBottom: theme.spacing(2),
},
body: {
paddingBottom: theme.spacing(4),
},
}));
export const EntityNotFound: FC<{}> = () => {
const classes = useStyles();
return (
<Page theme={pageTheme.tool}>
<Illo />
<Header title="Component" subtitle="Component information">
<HeaderLabel label="Owner" value="Spotify" />
<HeaderLabel label="Lifecycle" value="Alpha" />
</Header>
<Content>
<ContentHeader
title="Component Name"
description="Subtitle for component"
>
<Button
variant="contained"
color="primary"
onClick={() => window.location.reload()}
>
Refresh
</Button>
<SupportButton>All your software catalog entities</SupportButton>
</ContentHeader>
<Grid container className={classes.container}>
<Grid item xs={12} sm={6}>
<Typography variant="h4" className={classes.title}>
Entity was not found
</Typography>
<Typography variant="body1" className={classes.body}>
Want to help us build this? Check out our Getting Started
documentation.{' '}
</Typography>
<Button
variant="contained"
color="primary"
href="https://backstage.io/docs"
>
DOCS
</Button>
</Grid>
</Grid>
</Content>
</Page>
);
};
@@ -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: 200,
right: 20,
position: 'absolute',
},
});
export const Illo = () => {
const classes = useStyles();
return <img src={IlloSvgUrl} className={classes.illo} alt="" />;
};
@@ -0,0 +1,37 @@
<svg width="687" height="421" viewBox="0 0 687 421" fill="none"
xmlns="http://www.w3.org/2000/svg">
<rect x="16.231" y="114.353" width="407.223" height="48.4618" rx="24.2309" transform="rotate(-10.5556 16.231 114.353)" fill="#D9D9D9"/>
<rect x="56.5332" y="151.306" width="337.679" height="48.4618" rx="24.2309" transform="rotate(-10.5556 56.5332 151.306)" fill="#D9D9D9"/>
<rect x="54.707" y="274.403" width="441.061" height="48.4618" rx="24.2309" transform="rotate(-10.5556 54.707 274.403)" fill="#D9D9D9"/>
<rect x="38.1221" y="321.956" width="440.421" height="48.4618" rx="24.2309" transform="rotate(-10.5556 38.1221 321.956)" fill="#D9D9D9"/>
<rect x="213.923" y="147.109" width="435.885" height="48.4618" rx="24.2309" transform="rotate(-10.5556 213.923 147.109)" fill="#D9D9D9"/>
<rect x="199.842" y="194.196" width="431.054" height="48.4618" rx="24.2309" transform="rotate(-10.5556 199.842 194.196)" fill="#D9D9D9"/>
<rect x="235.299" y="292.946" width="394.936" height="48.4618" rx="24.2309" transform="rotate(-10.5556 235.299 292.946)" fill="#D9D9D9"/>
<rect x="199.862" y="344.013" width="456.282" height="48.4618" rx="24.2309" transform="rotate(-10.5556 199.862 344.013)" fill="#D9D9D9"/>
<g filter="url(#filter0_d)">
<rect x="126" y="67" width="461" height="286" rx="10" fill="#F8F8F8"/>
<rect x="154" y="91" width="90" height="67.2827" fill="#D9D9D9"/>
<rect x="154" y="175.354" width="90" height="69.2911" fill="#D9D9D9"/>
<rect x="154" y="261.717" width="90" height="67.2827" fill="#D9D9D9"/>
<rect x="259" y="91" width="90" height="67.2827" fill="#D9D9D9"/>
<rect x="364" y="91" width="90" height="67.2827" fill="#D9D9D9"/>
<rect x="364" y="175.354" width="90" height="69.2911" fill="#EEEEEE"/>
<rect x="364" y="261.717" width="90" height="67.2827" fill="#D9D9D9"/>
<rect x="259" y="175.354" width="90" height="69.2911" fill="#D9D9D9"/>
<rect x="259" y="261.717" width="90" height="67.2827" fill="#D9D9D9"/>
<rect x="469" y="91" width="90" height="67.2827" fill="#D9D9D9"/>
<rect x="469" y="175.354" width="90" height="69.2911" fill="#D9D9D9"/>
<rect x="469" y="261.717" width="90" height="67.2827" fill="#D9D9D9"/>
</g>
<defs>
<filter id="filter0_d" x="116" y="59" width="485" height="310" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dx="2" dy="4"/>
<feGaussianBlur stdDeviation="6"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -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';
+2 -1
View File
@@ -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';
@@ -47,7 +48,7 @@ const DefaultEntityPage = () => (
const EntityPageSwitch = ({ EntityPage }: { EntityPage: ComponentType }) => {
const { entity } = useEntity();
// Loading and error states
if (!entity) return <EntityPageLayout />;
if (!entity) return <EntityNotFound />;
// Otherwise EntityPage provided from the App
// Note that EntityPage will include EntityPageLayout already
+8 -7
View File
@@ -20,7 +20,7 @@ import { catalogApiRef } from '../api/types';
import { useAsync } from 'react-use';
import { Entity } from '@backstage/catalog-model';
const REDIRECT_DELAY = 2000;
// const REDIRECT_DELAY = 2000;
type EntityLoadingStatus = {
entity?: Entity;
@@ -47,12 +47,13 @@ export const useEntityFromUrl = (): EntityLoadingStatus => {
);
useEffect(() => {
if (error || (!loading && !entity)) {
errorApi.post(new Error('Entity not found!'));
setTimeout(() => {
navigate('/');
}, REDIRECT_DELAY);
}
// Commenting to check EntityNotFound page
// if (error || (!loading && !entity)) {
// errorApi.post(new Error('Entity not found!'));
// setTimeout(() => {
// navigate('/');
// }, REDIRECT_DELAY);
// }
if (!name) {
errorApi.post(new Error('No name provided!'));