Merge pull request #1354 from spotify/shmidt-i/load-scaffolder-templates-from-api

Scaffolder: load data from catalog api
This commit is contained in:
Ivan Shmidt
2020-06-26 10:51:31 +02:00
committed by GitHub
6 changed files with 95 additions and 68 deletions
@@ -4,6 +4,10 @@ metadata:
name: react-ssr-template
title: React SSR Template
description: Next.js application skeleton for creating isomorphic web applications.
tags:
- Recommended
- React
spec:
type: cookiecutter
processor: cookiecutter
type: website
path: '.'
@@ -0,0 +1,13 @@
apiVersion: backstage.io/v1alpha1
kind: Template
metadata:
name: springboot-template
title: Spring Boot Service
description: Standard Spring Boot (Java) microservice with recommended configuration.
tags:
- Recommended
- Java
spec:
processor: cookiecutter
type: service
path: '.'
+10 -6
View File
@@ -1,8 +1,12 @@
#!/usr/bin/env bash
curl \
--location \
--request POST 'localhost:7000/catalog/locations' \
--header 'Content-Type: application/json' \
--data-raw "{\"type\": \"file\", \"target\": \"$(pwd)/sample-templates/react-ssr-template/template.yaml\"}"
for URL in \
'react-ssr-template' \
'springboot-template' \
; do \
curl \
--location \
--request POST 'localhost:7000/catalog/locations' \
--header 'Content-Type: application/json' \
--data-raw "{\"type\": \"file\", \"target\": \"$(pwd)/sample-templates/${URL}/template.yaml\"}"
done
+4 -1
View File
@@ -21,6 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.12",
"@backstage/plugin-catalog": "^0.1.1-alpha.12",
"@backstage/core": "^0.1.1-alpha.12",
"@backstage/theme": "^0.1.1-alpha.12",
"@material-ui/core": "^4.9.1",
@@ -29,7 +31,8 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "6.0.0-alpha.5",
"react-use": "^14.2.0"
"react-use": "^14.2.0",
"swr": "^0.2.2"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.12",
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import React from 'react';
import React, { useEffect } from 'react';
import {
Lifecycle,
Content,
@@ -23,33 +23,39 @@ import {
SupportButton,
Page,
pageTheme,
useApi,
errorApiRef,
} from '@backstage/core';
import { Button, Grid, Link, Typography } from '@material-ui/core';
import { catalogApiRef } from '@backstage/plugin-catalog';
import {
Typography,
Link,
Button,
Grid,
LinearProgress,
} from '@material-ui/core';
import { Link as RouterLink } from 'react-router-dom';
import TemplateCard from '../TemplateCard';
import useStaleWhileRevalidate from 'swr';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
// TODO(blam): Connect to backend
const STATIC_DATA = [
{
id: 'springboot-template',
type: 'service',
name: 'Spring Boot Service',
tags: ['Recommended', 'Java'],
description:
'Standard Spring Boot (Java) microservice with recommended configuration.',
ownerId: 'spotify',
},
{
id: 'react-ssr-template',
type: 'website',
name: 'SSR React Website',
tags: ['Recommended', 'React'],
description:
'Next.js application skeleton for creating isomorphic web applications.',
ownerId: 'spotify',
},
];
const ScaffolderPage: React.FC<{}> = () => {
const catalogApi = useApi(catalogApiRef);
const errorApi = useApi(errorApiRef);
const { data: templates, isValidating, error } = useStaleWhileRevalidate(
'templates/all',
async () =>
catalogApi.getEntities({ kind: 'Template' }) as Promise<
TemplateEntityV1alpha1[]
>,
);
useEffect(() => {
if (!error) return;
errorApi.post(error);
}, [error, errorApi]);
return (
<Page theme={pageTheme.home}>
<Header
@@ -84,18 +90,24 @@ const ScaffolderPage: React.FC<{}> = () => {
</Link>
.
</Typography>
{!templates && isValidating && <LinearProgress />}
<Grid container>
{STATIC_DATA.map(item => {
return (
<TemplateCard
key={item.id}
title={item.name}
type={item.type}
description={item.description}
tags={item.tags}
/>
);
})}
{templates &&
templates.map(template => {
return (
<Grid item xs={12} sm={6} md={3}>
<TemplateCard
key={template.metadata.uid}
title={`${
(template.metadata.title || template.metadata.name) ?? ''
}`}
type={template.spec.type ?? ''}
description={template.metadata.description ?? '-'}
tags={(template.metadata?.tags as string[]) ?? []}
/>
</Grid>
);
})}
</Grid>
</Content>
</Page>
@@ -14,14 +14,7 @@
* limitations under the License.
*/
import React, { FC } from 'react';
import {
Button,
Card,
Chip,
Grid,
Typography,
makeStyles,
} from '@material-ui/core';
import { Button, Card, Chip, Typography, makeStyles } from '@material-ui/core';
const useStyles = makeStyles(theme => ({
header: {
@@ -59,25 +52,23 @@ const TemplateCard: FC<TemplateCardProps> = ({
const classes = useStyles();
return (
<Grid item xs={12} sm={6} md={3}>
<Card>
<div className={classes.header}>
<Typography variant="subtitle2">{type}</Typography>
<Typography variant="h6">{title}</Typography>
<Card>
<div className={classes.header}>
<Typography variant="subtitle2">{type}</Typography>
<Typography variant="h6">{title}</Typography>
</div>
<div className={classes.content}>
{tags?.map(tag => (
<Chip label={tag} key={tag} />
))}
<Typography variant="body2" paragraph className={classes.description}>
{description}
</Typography>
<div className={classes.footer}>
<Button color="primary">Choose</Button>
</div>
<div className={classes.content}>
{tags?.map(tag => (
<Chip label={tag} />
))}
<Typography variant="body2" paragraph className={classes.description}>
{description}
</Typography>
<div className={classes.footer}>
<Button color="primary">Choose</Button>
</div>
</div>
</Card>
</Grid>
</div>
</Card>
);
};