move ui:ObjectFieldTemplate resolution to useTransformSchemaToProps

Signed-off-by: Paul Cowan <paul.cowan@cutting.scot>
This commit is contained in:
Paul Cowan
2023-01-03 12:22:04 +00:00
parent a772d50bcd
commit 6e82e68b94
6 changed files with 107 additions and 43 deletions
@@ -33,6 +33,8 @@ import { ReviewState, type ReviewStateProps } from '../ReviewState';
import { useTemplateSchema } from '../../hooks/useTemplateSchema';
import validator from '@rjsf/validator-ajv6';
import { useFormDataFromQuery } from '../../hooks';
import type { FormProps, NextLayoutOptions } from '../../types';
import { useTransformSchemaToProps } from './useTransformSchemaToProps';
const useStyles = makeStyles(theme => ({
backButton: {
@@ -85,7 +87,7 @@ export const Stepper = (stepperProps: StepperProps) => {
reviewButtonText = 'Review',
} = components;
const analytics = useAnalytics();
const { steps } = useTemplateSchema(props.manifest, layouts);
const { steps } = useTemplateSchema(props.manifest);
const apiHolder = useApiHolder();
const [activeStep, setActiveStep] = useState(0);
const [formState, setFormState] = useFormDataFromQuery(props.initialState);
@@ -151,6 +153,8 @@ export const Stepper = (stepperProps: StepperProps) => {
setFormState(current => ({ ...current, ...formData }));
};
const currentStep = useTransformSchemaToProps(steps[activeStep], layouts);
return (
<>
<MuiStepper activeStep={activeStep} alternativeLabel variant="elevation">
@@ -170,8 +174,8 @@ export const Stepper = (stepperProps: StepperProps) => {
extraErrors={errors as unknown as ErrorSchema}
formData={formState}
formContext={{ formData: formState }}
schema={steps[activeStep].schema}
uiSchema={steps[activeStep].uiSchema}
schema={currentStep.schema}
uiSchema={currentStep.uiSchema}
onSubmit={handleNext}
fields={extensions}
showErrorList={false}
@@ -0,0 +1,46 @@
/*
* Copyright 2023 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 { type NextLayoutOptions } from '../../types';
import { type ParsedTemplateSchema } from './useTemplateSchema';
export const useTransformSchemaToProps = (
step: ParsedTemplateSchema,
layouts: NextLayoutOptions[] = [],
): ParsedTemplateSchema => {
const objectFieldTemplate = step?.uiSchema['ui:ObjectFieldTemplate'] as
| string
| undefined;
if (typeof objectFieldTemplate !== 'string') {
return step;
}
const Layout = layouts.find(
layout => layout.name === objectFieldTemplate,
)?.component;
if (!Layout) {
return step;
}
return {
...step,
uiSchema: {
...step.uiSchema,
['ui:ObjectFieldTemplate']: Layout,
},
};
};
@@ -233,42 +233,4 @@ describe('useTemplateSchema', () => {
});
});
});
it('should replace ui:ObjectFieldTemplate with actual component', () => {
const layouts = [{ name: 'TwoColumn', component: jest.fn() }];
const manifest: TemplateParameterSchema = {
title: 'Test Template',
description: 'Test Template Description',
steps: [
{
title: 'Step 1',
description: 'Step 1 Description',
schema: {
type: 'object',
'ui:ObjectFieldTemplate': 'TwoColumn',
properties: {
field1: {
type: 'string',
},
},
},
},
],
};
const { result } = renderHook(() => useTemplateSchema(manifest, layouts), {
wrapper: ({ children }) => (
<TestApiProvider
apis={[[featureFlagsApiRef, { isActive: () => true }]]}
>
{children}
</TestApiProvider>
),
});
const [{ uiSchema }] = result.current.steps;
expect(uiSchema['ui:ObjectFieldTemplate']).toEqual(layouts[0].component);
});
});
+1 -1
View File
@@ -16,7 +16,7 @@
import type { FormProps } from '@rjsf/core';
/**
* The field template from \@rjsf/core which is a react component that gets passed \@rjsf/core field related props.
* The field template from `@rjsf/core` which is a react component that gets passed `@rjsf/core` field related props.
*
* @public
*/
@@ -0,0 +1,52 @@
/*
* Copyright 2023 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 { renderHook } from '@testing-library/react-hooks';
import { TestApiProvider } from '@backstage/test-utils';
import { type ParsedTemplateSchema } from './Stepper/useTemplateSchema';
import { useTransformSchemaToProps } from './Stepper/useTransformSchemaToProps';
describe('useTransformSchemaToProps', () => {
it('should replace ui:ObjectFieldTemplate with actual component', () => {
const layouts = [{ name: 'TwoColumn', component: jest.fn() }];
const step: ParsedTemplateSchema = {
title: 'Fill in some steps',
mergedSchema: {},
schema: {},
uiSchema: {
'ui:ObjectFieldTemplate': 'TwoColumn' as any,
name: {
'ui:field': 'EntityNamePicker',
'ui:autofocus': true,
},
},
};
const { result } = renderHook(
() => useTransformSchemaToProps(step, layouts),
{
wrapper: ({ children }) => (
<TestApiProvider apis={[]}>{children}</TestApiProvider>
),
},
);
const { uiSchema } = result.current;
expect(uiSchema['ui:ObjectFieldTemplate']).toEqual(layouts[0].component);
});
});
+1 -1
View File
@@ -23,7 +23,7 @@
import type { FormProps as SchemaFormProps } from '@rjsf/core-v5';
/**
* The field template from \@rjsf/core which is a react component that gets passed \@rjsf/core field related props.
* The field template from `@rjsf/core` which is a react component that gets passed `@rjsf/core` field related props.
*
* @alpha
*/