chore: starting to build some things for the wizard page component
Signed-off-by: blam <ben@blam.sh> Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -28,7 +28,7 @@ import {
|
||||
import { useElementFilter } from '@backstage/core-plugin-api';
|
||||
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
|
||||
import { TemplateGroupFilter } from '../TemplateListPage/TemplateGroups';
|
||||
import { selectedTemplateRouteRef } from '../../routes';
|
||||
import { nextSelectedTemplateRouteRef } from '../../routes';
|
||||
|
||||
/**
|
||||
* The Props for the Scaffolder Router
|
||||
@@ -87,7 +87,7 @@ export const Router = (props: PropsWithChildren<NextRouterProps>) => {
|
||||
/>
|
||||
|
||||
<Route
|
||||
path={selectedTemplateRouteRef.path}
|
||||
path={nextSelectedTemplateRouteRef.path}
|
||||
element={
|
||||
<SecretsContextProvider>
|
||||
<TemplateWizardPage customFieldExtensions={fieldExtensions} />
|
||||
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
getEntityRelations,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { useRouteRef } from '@backstage/core-plugin-api';
|
||||
import { selectedTemplateRouteRef } from '../../../routes';
|
||||
import { nextSelectedTemplateRouteRef } from '../../../routes';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
|
||||
const useStyles = makeStyles<BackstageTheme>(theme => ({
|
||||
@@ -46,10 +46,11 @@ const useStyles = makeStyles<BackstageTheme>(theme => ({
|
||||
display: '-webkit-box',
|
||||
'-webkit-line-clamp': 10,
|
||||
'-webkit-box-orient': 'vertical',
|
||||
},
|
||||
markdown: {
|
||||
/** to make the styles for React Markdown not leak into the description */
|
||||
'& p:first-child': {
|
||||
'& :first-child': {
|
||||
marginTop: 0,
|
||||
marginBottom: theme.spacing(2),
|
||||
},
|
||||
},
|
||||
label: {
|
||||
@@ -94,9 +95,14 @@ export const TemplateCard = (props: TemplateCardProps) => {
|
||||
const { template } = props;
|
||||
const styles = useStyles();
|
||||
const ownedByRelations = getEntityRelations(template, RELATION_OWNED_BY);
|
||||
const templateRoute = useRouteRef(selectedTemplateRouteRef);
|
||||
const { name, namespace } = parseEntityRef(stringifyEntityRef(template));
|
||||
const href = templateRoute({ templateName: name, namespace: namespace });
|
||||
const templateRoute = useRouteRef(nextSelectedTemplateRouteRef);
|
||||
const { name, namespace } = parseEntityRef(
|
||||
stringifyEntityRef(props.template),
|
||||
);
|
||||
const href = templateRoute({
|
||||
templateName: name,
|
||||
namespace: namespace,
|
||||
});
|
||||
|
||||
return (
|
||||
<Card>
|
||||
@@ -104,6 +110,7 @@ export const TemplateCard = (props: TemplateCardProps) => {
|
||||
<CardContent>
|
||||
<Box className={styles.box}>
|
||||
<MarkdownContent
|
||||
className={styles.markdown}
|
||||
content={template.metadata.description ?? 'No description'}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@@ -56,11 +56,11 @@ export const TemplateListPage = (props: TemplateListPageProps) => {
|
||||
|
||||
return (
|
||||
<EntityListProvider>
|
||||
<Page themeId="home">
|
||||
<Page themeId="website">
|
||||
<Header
|
||||
pageTitleOverride="Create a New Component"
|
||||
title="Create a New Component"
|
||||
subtitle="Create new software components using standard templates"
|
||||
pageTitleOverride="Create a new component"
|
||||
title="Create a new component"
|
||||
subtitle="Create new software components using standard templates in your organization"
|
||||
/>
|
||||
<Content>
|
||||
<ContentHeader title="Available Templates">
|
||||
|
||||
@@ -14,24 +14,85 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { Page, Header, Lifecycle } from '@backstage/core-components';
|
||||
import {
|
||||
Page,
|
||||
Header,
|
||||
Content,
|
||||
Progress,
|
||||
InfoCard,
|
||||
MarkdownContent,
|
||||
} from '@backstage/core-components';
|
||||
import { FieldExtensionOptions } from '../../extensions';
|
||||
import { useParams } from 'react-router';
|
||||
import { stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { scaffolderApiRef } from '../../api';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
|
||||
export interface TemplateWizardPageProps {
|
||||
customFieldExtensions: FieldExtensionOptions<any, any>[];
|
||||
}
|
||||
|
||||
const useStyles = makeStyles<BackstageTheme>(theme => ({
|
||||
markdown: {
|
||||
/** to make the styles for React Markdown not leak into the description */
|
||||
'& :first-child': {
|
||||
marginTop: 0,
|
||||
},
|
||||
'& :last-child': {
|
||||
marginBottom: 0,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const useTemplateParameterSchema = (templateRef: string) => {
|
||||
const scaffolderApi = useApi(scaffolderApiRef);
|
||||
const { value, loading, error } = useAsync(
|
||||
() => scaffolderApi.getTemplateParameterSchema(templateRef),
|
||||
[scaffolderApi, templateRef],
|
||||
);
|
||||
|
||||
return { manifest: value, loading, error };
|
||||
};
|
||||
|
||||
export const TemplateWizardPage = (_props: TemplateWizardPageProps) => {
|
||||
const styles = useStyles();
|
||||
const { templateName, namespace } = useParams();
|
||||
const { loading, manifest, error } = useTemplateParameterSchema(
|
||||
stringifyEntityRef({
|
||||
kind: 'Template',
|
||||
namespace,
|
||||
name: templateName,
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
<Page themeId="tool">
|
||||
<Page themeId="website">
|
||||
<Header
|
||||
pageTitleOverride="Create a new component"
|
||||
title={
|
||||
<>
|
||||
Create a New Component <Lifecycle shorthand />
|
||||
</>
|
||||
}
|
||||
title="Create a new component"
|
||||
subtitle="Create new software components using standard templates in your organization"
|
||||
/>
|
||||
<Content>
|
||||
{loading && <Progress />}
|
||||
{manifest && (
|
||||
<InfoCard
|
||||
title={manifest.title}
|
||||
subheader={
|
||||
<MarkdownContent
|
||||
className={styles.markdown}
|
||||
content={manifest.description ?? 'No description'}
|
||||
/>
|
||||
}
|
||||
noPadding
|
||||
titleTypographyProps={{ component: 'h2' }}
|
||||
>
|
||||
asd
|
||||
</InfoCard>
|
||||
)}
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -43,6 +43,12 @@ export const selectedTemplateRouteRef = createSubRouteRef({
|
||||
path: '/templates/:namespace/:templateName',
|
||||
});
|
||||
|
||||
export const nextSelectedTemplateRouteRef = createSubRouteRef({
|
||||
id: 'scaffolder/next/selected-template',
|
||||
parent: rootRouteRef,
|
||||
path: '/templates/:namespace/:templateName',
|
||||
});
|
||||
|
||||
export const scaffolderTaskRouteRef = createSubRouteRef({
|
||||
id: 'scaffolder/task',
|
||||
parent: rootRouteRef,
|
||||
|
||||
@@ -79,8 +79,10 @@ export type ScaffolderTaskOutput = {
|
||||
*/
|
||||
export type TemplateParameterSchema = {
|
||||
title: string;
|
||||
description?: string;
|
||||
steps: Array<{
|
||||
title: string;
|
||||
description?: string;
|
||||
schema: JsonObject;
|
||||
}>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user