chore: saving state in the form

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2022-06-23 14:02:53 +02:00
parent aebb40f178
commit 5b7f8fb442
2 changed files with 142 additions and 1 deletions
@@ -0,0 +1,136 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { TemplateParameterSchema } from '../../../types';
import { Stepper } from './Stepper';
import { renderInTestApp } from '@backstage/test-utils';
import { fireEvent } from '@testing-library/react';
describe('Stepper', () => {
it('should render the step titles for each step of the manifest', async () => {
const manifest: TemplateParameterSchema = {
steps: [
{ title: 'Step 1', schema: { properties: {} } },
{ title: 'Step 2', schema: { properties: {} } },
],
title: 'React JSON Schema Form Test',
};
const { getByText } = await renderInTestApp(
<Stepper manifest={manifest} extensions={[]} />,
);
for (const step of manifest.steps) {
expect(getByText(step.title)).toBeInTheDocument();
}
});
it('should render next / review button', async () => {
const manifest: TemplateParameterSchema = {
steps: [
{ title: 'Step 1', schema: { properties: {} } },
{ title: 'Step 2', schema: { properties: {} } },
],
title: 'React JSON Schema Form Test',
};
const { getByText } = await renderInTestApp(
<Stepper manifest={manifest} extensions={[]} />,
);
expect(getByText('Next')).toBeInTheDocument();
await fireEvent.click(getByText('Next'));
expect(getByText('Review')).toBeInTheDocument();
});
it('should remember the state of the form when cycling through the pages', async () => {
const manifest: TemplateParameterSchema = {
steps: [
{
title: 'Step 1',
schema: {
properties: {
name: {
type: 'string',
},
},
},
},
{
title: 'Step 2',
schema: {
properties: {
description: {
type: 'string',
},
},
},
},
],
title: 'React JSON Schema Form Test',
};
const { getByRole, getByText } = await renderInTestApp(
<Stepper manifest={manifest} extensions={[]} />,
);
await fireEvent.change(getByRole('textbox', { name: 'name' }), {
target: { value: 'im a test value' },
});
await fireEvent.click(getByText('Next'));
await fireEvent.click(getByText('Back'));
expect(getByRole('textbox', { name: 'name' })).toHaveValue(
'im a test value',
);
});
it('should render custom field extensions properly', async () => {
const MockComponent = () => {
return <h1>im a custom field extension</h1>;
};
const manifest: TemplateParameterSchema = {
title: 'Custom Fields',
steps: [
{
title: 'Test',
schema: {
properties: {
name: {
type: 'string',
'ui:field': 'Mock',
},
},
},
},
],
};
const { getByText } = await renderInTestApp(
<Stepper
manifest={manifest}
extensions={[{ name: 'Mock', component: MockComponent }]}
/>,
);
expect(getByText('im a custom field extension')).toBeInTheDocument();
});
});
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { JsonObject } from '@backstage/types';
import {
Stepper as MuiStepper,
Step as MuiStep,
@@ -51,6 +52,7 @@ const Form = withTheme(MuiTheme);
export const Stepper = (props: StepperProps) => {
const { steps } = useTemplateSchema(props.manifest);
const [activeStep, setActiveStep] = useState(0);
const [formState, setFormState] = useState({});
const styles = useStyles();
const extensions = useMemo(() => {
@@ -62,8 +64,10 @@ export const Stepper = (props: StepperProps) => {
const handleBack = () => {
setActiveStep(prevActiveStep => prevActiveStep - 1);
};
const handleNext = () => {
const handleNext = ({ formData }: { formData: JsonObject }) => {
setActiveStep(prevActiveStep => prevActiveStep + 1);
setFormState(current => ({ ...current, ...formData }));
};
return (
@@ -77,6 +81,7 @@ export const Stepper = (props: StepperProps) => {
</MuiStepper>
<div className={styles.formWrapper}>
<Form
formData={formState}
schema={steps[activeStep].schema}
uiSchema={steps[activeStep].uiSchema}
onSubmit={handleNext}