From d2ddde21081da2b0396ad0ab9d093c860392e7c8 Mon Sep 17 00:00:00 2001 From: Paul Cowan Date: Fri, 23 Dec 2022 16:36:52 +0000 Subject: [PATCH] add ScaffolderLayouts to NextScaffolderPage Signed-off-by: Paul Cowan --- .changeset/silly-turkeys-hang.md | 5 +++ .../next/components/Stepper/Stepper.test.tsx | 43 +++++++++++++++++++ .../src/next/components/Stepper/Stepper.tsx | 14 +++--- .../src/next/hooks/useTemplateSchema.test.tsx | 38 ++++++++++++++++ plugins/scaffolder-react/src/next/types.ts | 19 ++++++++ .../src/next/Router/Router.test.tsx | 1 + plugins/scaffolder/src/next/Router/Router.tsx | 8 ++-- plugins/scaffolder/src/next/types.ts | 22 +++++++++- 8 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 .changeset/silly-turkeys-hang.md diff --git a/.changeset/silly-turkeys-hang.md b/.changeset/silly-turkeys-hang.md new file mode 100644 index 0000000000..e2345fb35d --- /dev/null +++ b/.changeset/silly-turkeys-hang.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Add `ScaffolderLayouts` to `NextScaffolderPage` diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx index 5dbce3243f..57ff949c62 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx @@ -392,4 +392,47 @@ describe('Stepper', () => { await fireEvent.click(getByRole('button', { name: 'Make' })); }); }); + + describe('Scaffolder Layouts', () => { + it('should render the step in the scaffolder layout', async () => { + const ScaffolderLayout: LayoutTemplate = ({ properties }) => ( + <> +

A Scaffolder Layout

+ {properties.map((prop, i) => ( +
{prop.content}
+ ))} + + ); + + const manifest: TemplateParameterSchema = { + steps: [ + { + title: 'Step 1', + schema: { + type: 'object', + 'ui:ObjectFieldTemplate': 'Layout', + properties: { + field1: { + type: 'string', + }, + }, + }, + }, + ], + title: 'scaffolder layouts', + }; + + const { getByText, getByRole } = await renderInTestApp( + , + ); + + expect(getByText('A Scaffolder Layout')).toBeInTheDocument(); + expect(getByRole('textbox', { name: 'field1' })).toBeInTheDocument(); + }); + }); }); diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 950c9720de..c2c4f06ffd 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -28,11 +28,14 @@ import React, { useCallback, useMemo, useState, type ReactNode } from 'react'; import { NextFieldExtensionOptions } from '../../extensions'; import { TemplateParameterSchema } from '../../../types'; import { createAsyncValidators } from './createAsyncValidators'; -import type { FormProps } from '../../types'; +import type { FormProps, LayoutOptions } from '../../types'; import { ReviewState, type ReviewStateProps } from '../ReviewState'; import { useTemplateSchema } from '../../hooks/useTemplateSchema'; import { useFormDataFromQuery } from '../../hooks/useFormDataFromQuery'; import validator from '@rjsf/validator-ajv6'; +import { useFormDataFromQuery } from '../../hooks'; +import type { FormProps } from '../../types'; +import { selectedTemplateRouteRef } from '../../../routes'; const useStyles = makeStyles(theme => ({ backButton: { @@ -65,6 +68,7 @@ export type StepperProps = { createButtonText?: ReactNode; reviewButtonText?: ReactNode; }; + layouts?: LayoutOptions[]; }; // TODO(blam): We require here, as the types in this package depend on @rjsf/core explicitly @@ -76,17 +80,15 @@ const Form = withTheme(require('@rjsf/material-ui-v5').Theme); * The `Stepper` component is the Wizard that is rendered when a user selects a template * @alpha */ - export const Stepper = (stepperProps: StepperProps) => { - const { components = {}, ...props } = stepperProps; + const { layouts = [], components = {}, ...props } = stepperProps; const { ReviewStateComponent = ReviewState, createButtonText = 'Create', reviewButtonText = 'Review', } = components; - const analytics = useAnalytics(); - const { steps } = useTemplateSchema(props.manifest); + const { steps } = useTemplateSchema(props.manifest, layouts); const apiHolder = useApiHolder(); const [activeStep, setActiveStep] = useState(0); const [formState, setFormState] = useFormDataFromQuery(props.initialState); @@ -177,7 +179,7 @@ export const Stepper = (stepperProps: StepperProps) => { fields={extensions} showErrorList={false} onChange={handleChange} - {...(props.FormProps ?? {})} + {...(formProps ?? {})} >