Merge remote-tracking branch 'upstream/master'

This commit is contained in:
NetPenguins
2020-09-12 09:10:07 -04:00
331 changed files with 9921 additions and 3831 deletions
+7 -4
View File
@@ -30,6 +30,8 @@ export class ScaffolderApi {
}
/**
* Executes the scaffolding of a component, given a template and its
* parameter values.
*
* @param template Template entity for the scaffolder to use. New project is going to be created out of this template.
* @param values Parameters for the template, e.g. name, description
@@ -49,7 +51,9 @@ export class ScaffolderApi {
});
if (response.status !== 201) {
throw new Error(await response.text());
const status = `${response.status} ${response.statusText}`;
const body = await response.text();
throw new Error(`Backend request failed, ${status} ${body.trim()}`);
}
const { id } = await response.json();
@@ -57,9 +61,8 @@ export class ScaffolderApi {
}
async getJob(jobId: string) {
const url = `${await this.discoveryApi.getBaseUrl(
'scaffolder',
)}/v1/job/${encodeURIComponent(jobId)}`;
const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');
const url = `${baseUrl}/v1/job/${encodeURIComponent(jobId)}`;
return fetch(url).then(x => x.json());
}
}
@@ -13,16 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
Box,
Accordion,
AccordionDetails,
AccordionSummary,
Box,
CircularProgress,
LinearProgress,
Typography,
} from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
import cn from 'classnames';
import moment from 'moment';
import React, { Suspense, useEffect, useState } from 'react';
@@ -37,8 +40,7 @@ const useStyles = makeStyles(theme => ({
},
button: {
order: -1,
marginRight: 0,
marginLeft: '-20px',
margin: '0 1em 0 -20px',
},
cardContent: {
backgroundColor: theme.palette.background.default,
@@ -109,7 +111,7 @@ export const JobStage = ({ endedAt, startedAt, name, log, status }: Props) => {
onChange={(_, newState) => setExpanded(newState)}
>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
expandIcon={expanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}
aria-controls={`panel-${name}-content`}
id={`panel-${name}-header`}
IconButtonProps={{
@@ -117,7 +119,8 @@ export const JobStage = ({ endedAt, startedAt, name, log, status }: Props) => {
}}
>
<Typography variant="button">
{name} {timeElapsed && `(${timeElapsed})`}
{name} {timeElapsed && `(${timeElapsed})`}{' '}
{startedAt && !endedAt && <CircularProgress size="1em" />}
</Typography>
</AccordionSummary>
<AccordionDetails className={classes.accordionDetails}>
@@ -51,7 +51,7 @@ export const JobStatusModal = ({
return (
<Dialog open onClose={onClose} fullWidth>
<DialogTitle id="responsive-dialog-title">
Creating component...
Creating Component...
</DialogTitle>
<DialogContent>
{!job ? (
@@ -26,9 +26,10 @@ import {
Progress,
SupportButton,
useApi,
WarningPanel,
} from '@backstage/core';
import { catalogApiRef } from '@backstage/plugin-catalog';
import { Button, Grid, Typography, Link } from '@material-ui/core';
import { Button, Grid, Link, Typography } from '@material-ui/core';
import React, { useEffect } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import useStaleWhileRevalidate from 'swr';
@@ -46,7 +47,8 @@ const getTemplateCardProps = (
tags: (template.metadata?.tags as string[]) ?? [],
};
};
export const ScaffolderPage: React.FC<{}> = () => {
export const ScaffolderPage = () => {
const catalogApi = useApi(catalogApiRef);
const errorApi = useApi(errorApiRef);
@@ -66,23 +68,23 @@ export const ScaffolderPage: React.FC<{}> = () => {
return (
<Page theme={pageTheme.home}>
<Header
pageTitleOverride="Create a new component"
pageTitleOverride="Create a New Component"
title={
<>
Create a new component <Lifecycle alpha shorthand />
Create a New Component <Lifecycle alpha shorthand />
</>
}
subtitle="Create new software components using standard templates"
/>
<Content>
<ContentHeader title="Available templates">
<ContentHeader title="Available Templates">
<Button
variant="contained"
color="primary"
component={RouterLink}
to="/register-component"
>
Register existing component
Register Existing Component
</Button>
<SupportButton>
Create new software components using standard templates. Different
@@ -101,16 +103,16 @@ export const ScaffolderPage: React.FC<{}> = () => {
</Typography>
)}
{error && (
<Typography variant="body2">
<WarningPanel>
Oops! Something went wrong loading the templates: {error.message}
</Typography>
</WarningPanel>
)}
<Grid container>
{templates &&
templates?.length > 0 &&
templates.map(template => {
return (
<Grid item xs={12} sm={6} md={3}>
<Grid key={template.metadata.uid} item xs={12} sm={6} md={3}>
<TemplateCard {...getTemplateCardProps(template)} />
</Grid>
);
@@ -23,8 +23,8 @@ const useStyles = makeStyles(theme => ({
header: {
color: theme.palette.common.white,
padding: theme.spacing(2, 2, 6),
backgroundImage: (props: { gradientStart: string; gradientStop: string }) =>
`linear-gradient(-137deg, ${props.gradientStart} 0%, ${props.gradientStop} 100%)`,
backgroundImage: (props: { backgroundImage: string }) =>
props.backgroundImage,
},
content: {
padding: theme.spacing(2),
@@ -56,8 +56,7 @@ export const TemplateCard = ({
name,
}: TemplateCardProps) => {
const theme = pageTheme[type] ?? pageTheme.other;
const [gradientStart, gradientStop] = theme.colors;
const classes = useStyles({ gradientStart, gradientStop });
const classes = useStyles({ backgroundImage: theme.backgroundImage });
const href = generatePath(templateRoute.path, { templateName: name });
return (
@@ -91,8 +91,12 @@ export const TemplatePage = () => {
const handleClose = () => setJobId(null);
const handleCreate = async () => {
const job = await scaffolderApi.scaffold(template!, formState);
setJobId(job);
try {
const job = await scaffolderApi.scaffold(template!, formState);
setJobId(job);
} catch (e) {
errorApi.post(e);
}
};
const [entity, setEntity] = React.useState<TemplateEntityV1alpha1 | null>(
@@ -157,7 +161,7 @@ export const TemplatePage = () => {
/>
)}
{template && (
<InfoCard title={template.metadata.title as string} noPadding>
<InfoCard title={template.metadata.title} noPadding>
<MultistepJsonForm
formData={formState}
onChange={handleChange}
+13 -1
View File
@@ -14,13 +14,25 @@
* limitations under the License.
*/
import { createPlugin } from '@backstage/core';
import {
createPlugin,
createApiFactory,
discoveryApiRef,
} from '@backstage/core';
import { ScaffolderPage } from './components/ScaffolderPage';
import { TemplatePage } from './components/TemplatePage';
import { rootRoute, templateRoute } from './routes';
import { scaffolderApiRef, ScaffolderApi } from './api';
export const plugin = createPlugin({
id: 'scaffolder',
apis: [
createApiFactory({
api: scaffolderApiRef,
deps: { discoveryApi: discoveryApiRef },
factory: ({ discoveryApi }) => new ScaffolderApi({ discoveryApi }),
}),
],
register({ router }) {
router.addRoute(rootRoute, ScaffolderPage);
router.addRoute(templateRoute, TemplatePage);