mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-25 17:04:54 +00:00
fix(ui): json schema form field validation (#11867)
* fix(ui): json schema form field validation * address comment * fix: duplicate key issue * add unit test
This commit is contained in:
parent
ce9a10dd32
commit
cec1c295a7
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* 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 { FieldErrorProps } from '@rjsf/utils';
|
||||
import { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { FieldErrorTemplate } from './FieldErrorTemplate';
|
||||
|
||||
describe('FieldErrorTemplate', () => {
|
||||
it('renders error list correctly', () => {
|
||||
const errors = ['Error 1', 'Error 2'];
|
||||
const schema = { $id: 'schema-id' };
|
||||
const idSchema = { $id: 'id-schema-id' };
|
||||
|
||||
const { container } = render(
|
||||
<FieldErrorTemplate
|
||||
errors={errors}
|
||||
idSchema={idSchema as FieldErrorProps['idSchema']}
|
||||
registry={{} as FieldErrorProps['registry']}
|
||||
schema={schema}
|
||||
/>
|
||||
);
|
||||
|
||||
const errorItems = container.querySelectorAll(
|
||||
'.ant-form-item-explain-error'
|
||||
);
|
||||
|
||||
expect(errorItems).toHaveLength(errors.length);
|
||||
|
||||
errorItems.forEach((item, index) => {
|
||||
expect(item.textContent).toBe(errors[index]);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders null when errors are empty', () => {
|
||||
const errors: string[] = [];
|
||||
const schema = { $id: 'schema-id' };
|
||||
const idSchema = { $id: 'id-schema-id' };
|
||||
|
||||
const { container } = render(
|
||||
<FieldErrorTemplate
|
||||
errors={errors}
|
||||
idSchema={idSchema as FieldErrorProps['idSchema']}
|
||||
registry={{} as FieldErrorProps['registry']}
|
||||
schema={schema}
|
||||
/>
|
||||
);
|
||||
|
||||
const errorItems = container.querySelectorAll(
|
||||
'.ant-form-item-explain-error'
|
||||
);
|
||||
|
||||
expect(errorItems).toHaveLength(0);
|
||||
});
|
||||
});
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* 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 { FieldErrorProps } from '@rjsf/utils';
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, { FC } from 'react';
|
||||
|
||||
export const FieldErrorTemplate: FC<FieldErrorProps> = (props) => {
|
||||
const errorList = [...new Set(props.errors ?? [])];
|
||||
|
||||
if (isEmpty(errorList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ul>
|
||||
{errorList.map((error) => (
|
||||
<li
|
||||
className="ant-form-item-explain-error"
|
||||
key={`${props.schema.$id}-${props.idSchema.$id}`}>
|
||||
{error}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -17,6 +17,7 @@ import { Button } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { ArrayFieldTemplate } from 'components/JSONSchemaTemplate/ArrayFieldTemplate';
|
||||
import DescriptionFieldTemplate from 'components/JSONSchemaTemplate/DescriptionFieldTemplate';
|
||||
import { FieldErrorTemplate } from 'components/JSONSchemaTemplate/FieldErrorTemplate/FieldErrorTemplate';
|
||||
import { ObjectFieldTemplate } from 'components/JSONSchemaTemplate/ObjectFieldTemplate';
|
||||
import PasswordWidget from 'components/JsonSchemaWidgets/PasswordWidget';
|
||||
import { ServiceCategory } from 'enums/service.enum';
|
||||
@ -123,6 +124,7 @@ const FormBuilder: FunctionComponent<Props> = ({
|
||||
ArrayFieldTemplate: ArrayFieldTemplate,
|
||||
ObjectFieldTemplate: ObjectFieldTemplate,
|
||||
DescriptionFieldTemplate: DescriptionFieldTemplate,
|
||||
FieldErrorTemplate: FieldErrorTemplate,
|
||||
}}
|
||||
transformErrors={transformErrors}
|
||||
uiSchema={uiSchema}
|
||||
|
@ -192,7 +192,15 @@ export const generateFormFields = (fields: FieldProp[]) => {
|
||||
export const transformErrors: ErrorTransformer = (errors) => {
|
||||
const errorRet = errors.map((error) => {
|
||||
const { property } = error;
|
||||
const id = 'root' + property?.replaceAll('.', '/');
|
||||
|
||||
/**
|
||||
* For nested fields we have to check if it's property start with "."
|
||||
* else we will just prepend the root to property
|
||||
*/
|
||||
const id = property?.startsWith('.')
|
||||
? 'root' + property?.replaceAll('.', '/')
|
||||
: `root/${property}`;
|
||||
|
||||
// If element is not present in DOM, ignore error
|
||||
if (document.getElementById(id)) {
|
||||
const fieldName = error.params?.missingProperty;
|
||||
|
Loading…
x
Reference in New Issue
Block a user