@@ -22,12 +22,13 @@ import {
|
||||
Button,
|
||||
makeStyles,
|
||||
} from '@material-ui/core';
|
||||
import { FormValidation, withTheme } from '@rjsf/core';
|
||||
import { FieldValidation, withTheme } from '@rjsf/core';
|
||||
import { Theme as MuiTheme } from '@rjsf/material-ui';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { FieldExtensionOptions } from '../../../extensions';
|
||||
import { TemplateParameterSchema } from '../../../types';
|
||||
import { createAsyncValidator } from './createAsyncValidators';
|
||||
import { createFieldValidation } from './schema';
|
||||
import { useTemplateSchema } from './useTemplateSchema';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
@@ -56,7 +57,9 @@ export const Stepper = (props: StepperProps) => {
|
||||
const apiHolder = useApiHolder();
|
||||
const [activeStep, setActiveStep] = useState(0);
|
||||
const [formState, setFormState] = useState({});
|
||||
const [errors, setErrors] = useState<undefined | FormValidation>();
|
||||
const [errors, setErrors] = useState<
|
||||
undefined | Record<string, FieldValidation>
|
||||
>();
|
||||
const styles = useStyles();
|
||||
|
||||
const extensions = useMemo(() => {
|
||||
@@ -72,7 +75,8 @@ export const Stepper = (props: StepperProps) => {
|
||||
}, [props.extensions]);
|
||||
|
||||
const validator = useMemo(() => {
|
||||
return createAsyncValidator(steps[activeStep].originalSchema, validators, {
|
||||
const { mergedSchema } = steps[activeStep];
|
||||
return createAsyncValidator(mergedSchema, validators, {
|
||||
apiHolder,
|
||||
});
|
||||
}, [steps, activeStep, validators, apiHolder]);
|
||||
@@ -86,25 +90,13 @@ export const Stepper = (props: StepperProps) => {
|
||||
|
||||
const errorContext: any = {};
|
||||
for (const [key] of Object.entries(formData)) {
|
||||
const localFieldContext = {
|
||||
__errors: [] as string[],
|
||||
addError: (message: string) => {
|
||||
localFieldContext.__errors.push(message);
|
||||
},
|
||||
};
|
||||
errorContext[key] = localFieldContext;
|
||||
errorContext[key] = createFieldValidation();
|
||||
}
|
||||
|
||||
const returnedValidation = await validator(
|
||||
formData,
|
||||
errorContext as FormValidation,
|
||||
);
|
||||
const returnedValidation = await validator(formData);
|
||||
|
||||
const hasErrors = Object.values(returnedValidation).some(i => {
|
||||
if ('__errors' in i) {
|
||||
return i.__errors.length > 0;
|
||||
}
|
||||
return false;
|
||||
return i.__errors.length > 0;
|
||||
});
|
||||
|
||||
if (hasErrors) {
|
||||
|
||||
@@ -14,15 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FieldValidation, FormValidation } from '@rjsf/core';
|
||||
import { FieldValidation } from '@rjsf/core';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { ApiHolder } from '@backstage/core-plugin-api';
|
||||
import { CustomFieldValidator } from '../../../extensions';
|
||||
import { Draft07 as JSONSchema } from 'json-schema-library';
|
||||
|
||||
function isObject(obj: unknown): obj is JsonObject {
|
||||
return typeof obj === 'object' && obj !== null && !Array.isArray(obj);
|
||||
}
|
||||
import { createFieldValidation } from './schema';
|
||||
|
||||
export const createAsyncValidator = (
|
||||
rootSchema: JsonObject,
|
||||
@@ -43,12 +40,7 @@ export const createAsyncValidator = (
|
||||
if (definitionInSchema && 'ui:field' in definitionInSchema) {
|
||||
const validator = validators[definitionInSchema['ui:field']];
|
||||
if (validator) {
|
||||
const fieldValidation = {
|
||||
__errors: [] as string[],
|
||||
addError: (message: string) => {
|
||||
fieldValidation.__errors.push(message);
|
||||
},
|
||||
};
|
||||
const fieldValidation = createFieldValidation();
|
||||
await validator(value, fieldValidation, context);
|
||||
formValidation[key] = fieldValidation;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { UiSchema } from '@rjsf/core';
|
||||
import { FieldValidation, UiSchema } from '@rjsf/core';
|
||||
|
||||
function isObject(value: unknown): value is JsonObject {
|
||||
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
||||
@@ -110,3 +110,19 @@ export const extractSchemaFromStep = (
|
||||
extractUiSchema(returnSchema, uiSchema);
|
||||
return { uiSchema, schema: returnSchema };
|
||||
};
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
* Creates a field validation object for use in react jsonschema form
|
||||
* @returns {FieldValidation} A field validation object that can be used to validate a field
|
||||
*/
|
||||
export const createFieldValidation = (): FieldValidation => {
|
||||
const fieldValidation: FieldValidation = {
|
||||
__errors: [] as string[],
|
||||
addError: (message: string) => {
|
||||
fieldValidation.__errors.push(message);
|
||||
},
|
||||
};
|
||||
|
||||
return fieldValidation;
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ export const useTemplateSchema = (
|
||||
): {
|
||||
steps: {
|
||||
uiSchema: UiSchema;
|
||||
originalSchema: JsonObject;
|
||||
mergedSchema: JsonObject;
|
||||
schema: JsonObject;
|
||||
title: string;
|
||||
description?: string;
|
||||
@@ -34,7 +34,7 @@ export const useTemplateSchema = (
|
||||
const steps = manifest.steps.map(({ title, description, schema }) => ({
|
||||
title,
|
||||
description,
|
||||
originalSchema: schema,
|
||||
mergedSchema: schema,
|
||||
...extractSchemaFromStep(schema),
|
||||
}));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user