fix: required constraint becomes invalid after setting validation rules on form fields (#4977)
Some checks are pending
auto-merge / push-commit (push) Waiting to run
Build Docker Image / build-and-push (push) Waiting to run
Build Pro Image / build-and-push (push) Waiting to run
deploy client docs / Build (push) Waiting to run
E2E / Build (push) Waiting to run
E2E / Core and plugins (push) Blocked by required conditions
E2E / plugin-workflow (push) Blocked by required conditions
E2E / plugin-workflow-approval (push) Blocked by required conditions
E2E / plugin-data-source-main (push) Blocked by required conditions
E2E / Comment on PR (push) Blocked by required conditions
NocoBase FrontEnd Test / frontend-test (18) (push) Waiting to run

* fix: required constraint becomes invalid after setting validation rules on form fields

* fix: bug
This commit is contained in:
Katherine 2024-08-02 10:14:07 +08:00 committed by GitHub
parent b081790f81
commit 7b31c92023
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 13 additions and 130 deletions

View File

@ -319,7 +319,7 @@ export const fieldSettingsFormItem = new SchemaSettings({
const { getField } = useCollection_deprecated();
const collectionField =
getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
const customPredicate = (value) => value !== null && value !== undefined && !Number.isNaN(value);
return {
title: t('Set validation rules'),
components: { ArrayCollapse, FormLayout },
@ -408,7 +408,7 @@ export const fieldSettingsFormItem = new SchemaSettings({
onSubmit(v) {
const rules = [];
for (const rule of v.rules) {
rules.push(_.pickBy(rule, _.identity));
rules.push(_.pickBy(rule, customPredicate));
}
const schema = {
['x-uid']: fieldSchema['x-uid'],
@ -426,6 +426,7 @@ export const fieldSettingsFormItem = new SchemaSettings({
}
const concatValidator = _.concat([], collectionField?.uiSchema?.['x-validator'] || [], rules);
field.validator = concatValidator;
field.required = fieldSchema.required as any;
fieldSchema['x-validator'] = rules;
schema['x-validator'] = rules;
dn.emit('patch', {

View File

@ -202,6 +202,7 @@ export const filterFormItemFieldSettings = new SchemaSettings({
const { getField } = useCollection_deprecated();
const collectionField =
getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
const customPredicate = (value) => value !== null && value !== undefined && !Number.isNaN(value);
return {
title: t('Set validation rules'),
@ -291,7 +292,7 @@ export const filterFormItemFieldSettings = new SchemaSettings({
onSubmit(v) {
const rules = [];
for (const rule of v.rules) {
rules.push(_.pickBy(rule, _.identity));
rules.push(_.pickBy(rule, customPredicate));
}
const schema = {
['x-uid']: fieldSchema['x-uid'],
@ -309,6 +310,7 @@ export const filterFormItemFieldSettings = new SchemaSettings({
}
const concatValidator = _.concat([], collectionField?.uiSchema?.['x-validator'] || [], rules);
field.validator = concatValidator;
field.required = fieldSchema.required as any;
fieldSchema['x-validator'] = rules;
schema['x-validator'] = rules;
dn.emit('patch', {

View File

@ -268,8 +268,9 @@ AssociationSelect.Designer = function Designer() {
}
onSubmit={(v) => {
const rules = [];
const customPredicate = (value) => value !== null && value !== undefined && !Number.isNaN(value);
for (const rule of v.rules) {
rules.push(_.pickBy(rule, _.identity));
rules.push(_.pickBy(rule, customPredicate));
}
const schema = {
['x-uid']: fieldSchema['x-uid'],

View File

@ -188,6 +188,7 @@ export const EditValidationRules = () => {
const collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
const interfaceConfig = getInterface(collectionField?.interface);
const validateSchema = interfaceConfig?.['validateSchema']?.(fieldSchema);
const customPredicate = (value) => value !== null && value !== undefined && !Number.isNaN(value);
return form && !form?.readPretty && validateSchema ? (
<SchemaSettingsModalItem
@ -280,7 +281,7 @@ export const EditValidationRules = () => {
onSubmit={(v) => {
const rules = [];
for (const rule of v.rules) {
rules.push(_.pickBy(rule, _.identity));
rules.push(_.pickBy(rule, customPredicate));
}
const schema = {
['x-uid']: fieldSchema['x-uid'],
@ -302,6 +303,7 @@ export const EditValidationRules = () => {
}
const concatValidator = _.concat([], collectionField?.uiSchema?.['x-validator'] || [], rules);
field.validator = concatValidator;
field.required = fieldSchema.required as any;
fieldSchema['x-validator'] = rules;
schema['x-validator'] = rules;
dn.emit('patch', {

View File

@ -20,6 +20,7 @@ import {
useFormBlockContext,
useIsFormReadPretty,
useValidateSchema,
EditValidationRules,
} from '@nocobase/client';
import _ from 'lodash';
import { useTranslation } from 'react-i18next';
@ -192,131 +193,7 @@ export const bulkEditFormItemSettings = new SchemaSettings({
{
name: 'setValidationRules',
type: 'modal',
useComponentProps() {
const { t } = useTranslation();
const field = useField<Field>();
const fieldSchema = useFieldSchema();
const { dn, refresh } = useDesignable();
const validateSchema = useValidateSchema();
const { getCollectionJoinField } = useCollectionManager_deprecated();
const { dataSource } = useCollection_deprecated();
const collectionField = getCollectionJoinField(fieldSchema['x-collection-field'], dataSource);
return {
title: t('Set validation rules'),
components: { ArrayCollapse, FormLayout },
schema: {
type: 'object',
title: t('Set validation rules'),
properties: {
rules: {
type: 'array',
default: fieldSchema?.['x-validator'],
'x-component': 'ArrayCollapse',
'x-decorator': 'FormItem',
'x-component-props': {
accordion: true,
},
maxItems: 3,
items: {
type: 'object',
'x-component': 'ArrayCollapse.CollapsePanel',
'x-component-props': {
header: '{{ t("Validation rule") }}',
},
properties: {
index: {
type: 'void',
'x-component': 'ArrayCollapse.Index',
},
layout: {
type: 'void',
'x-component': 'FormLayout',
'x-component-props': {
labelStyle: {
marginTop: '6px',
},
labelCol: 8,
wrapperCol: 16,
},
properties: {
...validateSchema,
message: {
type: 'string',
title: '{{ t("Error message") }}',
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
'x-component-props': {
autoSize: {
minRows: 2,
maxRows: 2,
},
},
},
},
},
remove: {
type: 'void',
'x-component': 'ArrayCollapse.Remove',
},
moveUp: {
type: 'void',
'x-component': 'ArrayCollapse.MoveUp',
},
moveDown: {
type: 'void',
'x-component': 'ArrayCollapse.MoveDown',
},
},
},
properties: {
add: {
type: 'void',
title: '{{ t("Add validation rule") }}',
'x-component': 'ArrayCollapse.Addition',
'x-reactions': {
dependencies: ['rules'],
fulfill: {
state: {
disabled: '{{$deps[0].length >= 3}}',
},
},
},
},
},
},
},
},
onSubmit(v) {
const rules = [];
for (const rule of v.rules) {
rules.push(_.pickBy(rule, _.identity));
}
const schema = {
['x-uid']: fieldSchema['x-uid'],
};
if (['percent'].includes(collectionField?.interface)) {
for (const rule of rules) {
if (!!rule.maxValue || !!rule.minValue) {
rule['percentMode'] = true;
}
if (rule.percentFormat) {
rule['percentFormats'] = true;
}
}
}
const concatValidator = _.concat([], collectionField?.uiSchema?.['x-validator'] || [], rules);
field.validator = concatValidator;
fieldSchema['x-validator'] = rules;
schema['x-validator'] = rules;
dn.emit('patch', {
schema,
});
refresh();
},
};
},
Component: EditValidationRules,
useVisible() {
const { form } = useFormBlockContext();
const isFormReadPretty = useIsFormReadPretty();