Merge pull request #146 from spotify/nikek/fetch-example
add async data fetching & rendering to example page
This commit is contained in:
@@ -12,5 +12,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@spotify/web-scripts": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@material-ui/lab": "4.0.0-alpha.45"
|
||||
}
|
||||
}
|
||||
|
||||
+26
-16
@@ -1,7 +1,7 @@
|
||||
import React, { FC } from 'react';
|
||||
import { Typography, makeStyles, Theme } from '@material-ui/core';
|
||||
|
||||
import { Typography, Grid, makeStyles, Theme } from '@material-ui/core';
|
||||
import { InfoCard, Header, Page, theme } from '@spotify-backstage/core';
|
||||
import ExampleFetchComponent from '../ExampleFetchComponent';
|
||||
|
||||
const useStyles = makeStyles<Theme>(theme => ({
|
||||
mainContentArea: {
|
||||
@@ -18,23 +18,33 @@ const useStyles = makeStyles<Theme>(theme => ({
|
||||
|
||||
const ExampleComponent: FC<{}> = () => {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Page theme={theme.home}>
|
||||
<div className={classes.mainContentArea}>
|
||||
<Header
|
||||
title="Welcome to {{ id }}!"
|
||||
subtitle="Optional subtitle"
|
||||
></Header>
|
||||
<div className={classes.pageBody}>
|
||||
<Typography variant="h3" className={classes.title}>
|
||||
Plugin page title
|
||||
</Typography>
|
||||
<InfoCard title="Information card" maxWidth>
|
||||
<Typography variant="body1">
|
||||
All content should be wrapped in a card like this.
|
||||
</Typography>
|
||||
</InfoCard>
|
||||
</div>
|
||||
<Header title="Welcome to {{ id }}!" subtitle="Optional subtitle"></Header>
|
||||
<Grid
|
||||
container
|
||||
spacing={3}
|
||||
direction={'column'}
|
||||
className={classes.pageBody}
|
||||
>
|
||||
<Grid item>
|
||||
<Typography variant="h3">Plugin page title</Typography>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<InfoCard title="Information card" maxWidth>
|
||||
<Typography variant="body1">
|
||||
All content should be wrapped in a card like this.
|
||||
</Typography>
|
||||
</InfoCard>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<InfoCard title="Example User List (fetching data from randomuser.me)">
|
||||
<ExampleFetchComponent />
|
||||
</InfoCard>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
</Page>
|
||||
);
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import ExampleFetchComponent from './ExampleFetchComponent';
|
||||
|
||||
describe('ExampleFetchComponent', () => {
|
||||
it('should render', () => {
|
||||
const rendered = render(<ExampleFetchComponent />);
|
||||
expect(rendered.getByTestId('progress')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
import React, { FC } from 'react';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Table from '@material-ui/core/Table';
|
||||
import TableBody from '@material-ui/core/TableBody';
|
||||
import TableCell from '@material-ui/core/TableCell';
|
||||
import TableContainer from '@material-ui/core/TableContainer';
|
||||
import TableHead from '@material-ui/core/TableHead';
|
||||
import TableRow from '@material-ui/core/TableRow';
|
||||
import LinearProgress from '@material-ui/core/LinearProgress';
|
||||
import Alert from '@material-ui/lab/Alert';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
const useStyles = makeStyles({
|
||||
table: {
|
||||
minWidth: 650,
|
||||
},
|
||||
});
|
||||
|
||||
type User = {
|
||||
gender: string; // "male"
|
||||
name: {
|
||||
title: string; //"Mr",
|
||||
first: string; // "Duane",
|
||||
last: string; //"Reed"
|
||||
};
|
||||
location: object; // {street: {number: 5060, name: "Hickory Creek Dr"}, city: "Albany", state: "New South Wales",…}
|
||||
email: string; // "duane.reed@example.com"
|
||||
login: object; // {uuid: "4b785022-9a23-4ab9-8a23-cb3fb43969a9", username: "blackdog796", password: "patch",…}
|
||||
dob: object; // {date: "1983-06-22T12:30:23.016Z", age: 37}
|
||||
registered: object; // {date: "2006-06-13T18:48:28.037Z", age: 14}
|
||||
phone: string; //"07-2154-5651"
|
||||
cell: string; // "0405-592-879"
|
||||
id: {
|
||||
name: string; // "TFN",
|
||||
value: string; // "796260432"
|
||||
};
|
||||
picture: object; //{large: "https://randomuser.me/api/portraits/men/95.jpg",…}
|
||||
nat: string; // "AU"
|
||||
};
|
||||
|
||||
type DenseTableProps = {
|
||||
users: User[];
|
||||
};
|
||||
|
||||
export const DenseTable: FC<DenseTableProps> = ({ users }) => {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<TableContainer>
|
||||
<Table className={classes.table} size="small" aria-label="a dense table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Name</TableCell>
|
||||
<TableCell>Email</TableCell>
|
||||
<TableCell>Nationality</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{users.map(user => (
|
||||
<TableRow key={user.email}>
|
||||
<TableCell>
|
||||
{user.name.first} {user.name.last}
|
||||
</TableCell>
|
||||
<TableCell>{user.email}</TableCell>
|
||||
<TableCell>{user.nat}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const ExampleFetchComponent: FC<{}> = () => {
|
||||
const { value, loading, error } = useAsync(async (): Promise<User[]> => {
|
||||
const response = await fetch('https://randomuser.me/api/?results=100');
|
||||
const data = await response.json();
|
||||
return data.results;
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return <LinearProgress data-testid="progress" />;
|
||||
} else if (error) {
|
||||
return <Alert severity="error">{error.message}</Alert>;
|
||||
} else {
|
||||
return <DenseTable users={value || []} />;
|
||||
}
|
||||
};
|
||||
|
||||
export default ExampleFetchComponent;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { default } from './ExampleFetchComponent';
|
||||
+12
-1
@@ -2308,6 +2308,17 @@
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.4.4"
|
||||
|
||||
"@material-ui/lab@4.0.0-alpha.45":
|
||||
version "4.0.0-alpha.45"
|
||||
resolved "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.45.tgz#6e1abbdd6e44b9ef7b3eff8ef892a3da5dc52f10"
|
||||
integrity sha512-zT6kUU87SHsPukiu3tlWg8V6o0tGS38c1b/xst/kPqX6eLbfqrROyxhHn1A8ZtHmqga1AKQdv/1llQoG80Afww==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.4.4"
|
||||
"@material-ui/utils" "^4.7.1"
|
||||
clsx "^1.0.4"
|
||||
prop-types "^15.7.2"
|
||||
react-is "^16.8.0"
|
||||
|
||||
"@material-ui/styles@^4.9.0":
|
||||
version "4.9.0"
|
||||
resolved "https://registry.npmjs.org/@material-ui/styles/-/styles-4.9.0.tgz#10c31859f6868cfa9d3adf6b6c3e32c9d676bc76"
|
||||
@@ -5057,7 +5068,7 @@ clone@^1.0.2:
|
||||
resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
||||
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
|
||||
|
||||
clsx@^1.0.2:
|
||||
clsx@^1.0.2, clsx@^1.0.4:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702"
|
||||
integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA==
|
||||
|
||||
Reference in New Issue
Block a user