diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml b/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml index 6834f0d1b6..124d1575ce 100644 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml +++ b/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml @@ -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: '.' diff --git a/plugins/scaffolder-backend/sample-templates/springboot-template/template.yaml b/plugins/scaffolder-backend/sample-templates/springboot-template/template.yaml new file mode 100644 index 0000000000..681e8e7f51 --- /dev/null +++ b/plugins/scaffolder-backend/sample-templates/springboot-template/template.yaml @@ -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: '.' diff --git a/plugins/scaffolder-backend/scripts/mock-data b/plugins/scaffolder-backend/scripts/mock-data index be3fa2b6cf..594bd76607 100755 --- a/plugins/scaffolder-backend/scripts/mock-data +++ b/plugins/scaffolder-backend/scripts/mock-data @@ -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 diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 65322c31d6..1bccd6a738 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -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", diff --git a/plugins/scaffolder/src/components/ScaffolderPage/index.tsx b/plugins/scaffolder/src/components/ScaffolderPage/index.tsx index d675b59f52..2f9774757b 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/index.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/index.tsx @@ -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 (
= () => { . + {!templates && isValidating && } - {STATIC_DATA.map(item => { - return ( - - ); - })} + {templates && + templates.map(template => { + return ( + + + + ); + })} diff --git a/plugins/scaffolder/src/components/TemplateCard.tsx b/plugins/scaffolder/src/components/TemplateCard.tsx index 56d8907f7b..6d47f05693 100644 --- a/plugins/scaffolder/src/components/TemplateCard.tsx +++ b/plugins/scaffolder/src/components/TemplateCard.tsx @@ -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 = ({ const classes = useStyles(); return ( - - -
- {type} - {title} + +
+ {type} + {title} +
+
+ {tags?.map(tag => ( + + ))} + + {description} + +
+
-
- {tags?.map(tag => ( - - ))} - - {description} - -
- -
-
- - +
+
); };