Merge pull request #15290 from dagda1/add-missing-transform-errors-prop

pass through transformErrors to TemplateWizardPage
This commit is contained in:
Ben Lambert
2022-12-20 11:21:56 +01:00
committed by GitHub
10 changed files with 76 additions and 18 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Pass through `transformErrors` to `TemplateWizardPage`
+7 -4
View File
@@ -11,7 +11,6 @@ import { BackstagePlugin } from '@backstage/core-plugin-api';
import { ComponentType } from 'react';
import { DiscoveryApi } from '@backstage/core-plugin-api';
import { Entity } from '@backstage/catalog-model';
import type { ErrorTransformer } from '@rjsf/utils';
import { Extension } from '@backstage/core-plugin-api';
import { ExternalRouteRef } from '@backstage/core-plugin-api';
import { FetchApi } from '@backstage/core-plugin-api';
@@ -19,7 +18,8 @@ import { FieldProps } from '@rjsf/core';
import { FieldProps as FieldProps_2 } from '@rjsf/utils';
import { FieldValidation } from '@rjsf/core';
import { FieldValidation as FieldValidation_2 } from '@rjsf/utils';
import type { FormProps } from '@rjsf/core';
import type { FormProps as FormProps_2 } from '@rjsf/core';
import type { FormProps as FormProps_3 } from '@rjsf/core-v5';
import { IdentityApi } from '@backstage/core-plugin-api';
import { JsonObject } from '@backstage/types';
import { JSONSchema7 } from 'json-schema';
@@ -167,6 +167,9 @@ export interface FieldSchema<TReturn, TUiOptions> {
readonly uiOptionsType: TUiOptions;
}
// @alpha
export type FormProps = Pick<FormProps_3, 'transformErrors'>;
// @public
export type LayoutComponent<_TInputProps> = () => null;
@@ -179,7 +182,7 @@ export interface LayoutOptions<P = any> {
}
// @public
export type LayoutTemplate<T = any> = FormProps<T>['ObjectFieldTemplate'];
export type LayoutTemplate<T = any> = FormProps_2<T>['ObjectFieldTemplate'];
// @public
export type ListActionsResponse = Array<{
@@ -264,7 +267,7 @@ export type NextRouterProps = {
TaskPageComponent?: React_2.ComponentType<{}>;
};
groups?: TemplateGroupFilter[];
transformErrors?: ErrorTransformer;
FormProps?: FormProps;
};
// @alpha
+1
View File
@@ -74,6 +74,7 @@ export type { TaskPageProps } from './components/TaskPage';
export { NextScaffolderPage } from './plugin';
export type { NextRouterProps } from './next';
export type { TemplateGroupFilter } from './next';
export type { FormProps } from './next';
export {
createNextScaffolderFieldExtension,
type NextCustomFieldValidator,
@@ -54,6 +54,27 @@ describe('Router', () => {
expect(TemplateWizardPage).toHaveBeenCalled();
});
it('should pass through the transformErrors property', async () => {
const transformErrorsMock = jest.fn();
await renderInTestApp(
<Router FormProps={{ transformErrors: transformErrorsMock }} />,
{
routeEntries: ['/templates/default/foo'],
},
);
const mock = TemplateWizardPage as jest.Mock;
const [
{
FormProps: { transformErrors },
},
] = mock.mock.calls[0];
expect(transformErrors).toEqual(transformErrors);
});
it('should extract the fieldExtensions and pass them through', async () => {
const mockComponent = () => null;
const CustomFieldExtension = scaffolderPlugin.provide(
@@ -30,7 +30,7 @@ import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
import { TemplateGroupFilter } from '../TemplateListPage/TemplateGroups';
import { nextSelectedTemplateRouteRef } from '../../routes';
import { SecretsContextProvider } from '../../components/secrets/SecretsContext';
import type { ErrorTransformer } from '@rjsf/utils';
import type { FormProps } from '../types';
/**
* The Props for the Scaffolder Router
@@ -45,7 +45,7 @@ export type NextRouterProps = {
TaskPageComponent?: React.ComponentType<{}>;
};
groups?: TemplateGroupFilter[];
transformErrors?: ErrorTransformer;
FormProps?: FormProps;
};
/**
@@ -93,7 +93,10 @@ export const Router = (props: PropsWithChildren<NextRouterProps>) => {
path={nextSelectedTemplateRouteRef.path}
element={
<SecretsContextProvider>
<TemplateWizardPage customFieldExtensions={fieldExtensions} />
<TemplateWizardPage
customFieldExtensions={fieldExtensions}
FormProps={props.FormProps}
/>
</SecretsContextProvider>
}
/>
@@ -174,7 +174,7 @@ describe('Stepper', () => {
manifest={manifest}
extensions={[]}
onComplete={jest.fn()}
transformErrors={transformErrors}
FormProps={{ transformErrors }}
/>,
);
@@ -36,9 +36,9 @@ import { useTemplateSchema } from './useTemplateSchema';
import { ReviewState } from './ReviewState';
import validator from '@rjsf/validator-ajv8';
import { selectedTemplateRouteRef } from '../../../routes';
import type { ErrorTransformer } from '@rjsf/utils';
import { getDefaultFormState } from '@rjsf/utils';
import { useFormData } from './useFormData';
import { FormProps } from '../../types';
const useStyles = makeStyles(theme => ({
backButton: {
@@ -55,12 +55,12 @@ const useStyles = makeStyles(theme => ({
},
}));
export interface StepperProps {
export type StepperProps = {
manifest: TemplateParameterSchema;
extensions: NextFieldExtensionOptions<any, any>[];
onComplete: (values: Record<string, JsonValue>) => Promise<void>;
transformErrors?: ErrorTransformer;
}
FormProps?: FormProps;
};
// TODO(blam): We require here, as the types in this package depend on @rjsf/core explicitly
// which is what we're using here as the default types, it needs to depend on @rjsf/core-v5 because
@@ -165,7 +165,7 @@ export const Stepper = (props: StepperProps) => {
onSubmit={handleNext}
fields={extensions}
showErrorList={false}
transformErrors={props.transformErrors}
{...(props.FormProps ?? {})}
>
<div className={styles.footer}>
<Button
@@ -44,12 +44,12 @@ import {
} from '../../routes';
import { SecretsContext } from '../../components/secrets/SecretsContext';
import { JsonValue } from '@backstage/types';
import type { ErrorTransformer } from '@rjsf/utils';
import type { FormProps } from '../types';
export interface TemplateWizardPageProps {
export type TemplateWizardPageProps = {
customFieldExtensions: NextFieldExtensionOptions<any, any>[];
transformErrors?: ErrorTransformer;
}
FormProps?: FormProps;
};
const useStyles = makeStyles<BackstageTheme>(() => ({
markdown: {
@@ -139,7 +139,7 @@ export const TemplateWizardPage = (props: TemplateWizardPageProps) => {
manifest={manifest}
extensions={props.customFieldExtensions}
onComplete={onComplete}
transformErrors={props.transformErrors}
FormProps={props.FormProps}
/>
</InfoCard>
)}
+2
View File
@@ -16,3 +16,5 @@
export * from './Router';
export * from './TemplateListPage';
export * from './TemplateWizardPage';
export type { FormProps } from './types';
+23
View File
@@ -0,0 +1,23 @@
/*
* 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 type { FormProps as SchemaFormProps } from '@rjsf/core-v5';
/**
* Any `@rjsf/core` form properties that are publicly exposed to the `NextScaffolderpage`
*
* @alpha
*/
export type FormProps = Pick<SchemaFormProps, 'transformErrors'>;