mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 15:44:59 +00:00
Merge pull request #11514 from strapi/fix-field-validations
[v4] CTB: Fix field validations
This commit is contained in:
commit
369e22d8f7
@ -15,7 +15,7 @@ import { TextInput } from '@strapi/design-system/TextInput';
|
||||
|
||||
const CheckboxWithNumberField = ({ error, intlLabel, modifiedData, name, onChange, value }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const [showInput, setShowInput] = useState(!!value);
|
||||
const [showInput, setShowInput] = useState(!!value || value === 0);
|
||||
const label = intlLabel.id
|
||||
? formatMessage(
|
||||
{ id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
|
||||
@ -34,10 +34,13 @@ const CheckboxWithNumberField = ({ error, intlLabel, modifiedData, name, onChang
|
||||
id={name}
|
||||
name={name}
|
||||
onValueChange={value => {
|
||||
onChange({ target: { name, value: value ? 1 : null } });
|
||||
const initValue = type === 'text' ? '0' : 0;
|
||||
const nextValue = value ? initValue : null;
|
||||
|
||||
onChange({ target: { name, value: nextValue } });
|
||||
setShowInput(prev => !prev);
|
||||
}}
|
||||
value={Boolean(value)}
|
||||
value={showInput}
|
||||
>
|
||||
{label}
|
||||
</Checkbox>
|
||||
@ -51,7 +54,7 @@ const CheckboxWithNumberField = ({ error, intlLabel, modifiedData, name, onChang
|
||||
id={name}
|
||||
name={name}
|
||||
onChange={onChange}
|
||||
value={typeof value === 'boolean' ? '1' : value}
|
||||
value={value === null ? '' : value}
|
||||
/>
|
||||
) : (
|
||||
<NumberInput
|
||||
@ -63,7 +66,7 @@ const CheckboxWithNumberField = ({ error, intlLabel, modifiedData, name, onChang
|
||||
onValueChange={value => {
|
||||
onChange({ target: { name, value, type } });
|
||||
}}
|
||||
value={typeof value === 'boolean' ? 0 : value}
|
||||
value={value || 0}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@ -224,7 +224,7 @@ const baseForm = {
|
||||
defaultMessage: 'Number format',
|
||||
},
|
||||
name: 'type',
|
||||
type: 'select',
|
||||
type: 'select-number',
|
||||
options: [
|
||||
{
|
||||
key: '__null_reset_value__',
|
||||
|
||||
@ -51,18 +51,18 @@ const types = {
|
||||
default: yup
|
||||
.string()
|
||||
.nullable()
|
||||
.matches(/^\d*$/),
|
||||
.matches(/^-?\d*$/),
|
||||
unique: validators.unique(),
|
||||
required: validators.required(),
|
||||
max: yup
|
||||
.string()
|
||||
.nullable()
|
||||
.matches(/^\d*$/, errorsTrads.regex),
|
||||
.matches(/^-?\d*$/, errorsTrads.regex),
|
||||
min: yup
|
||||
.string()
|
||||
.nullable()
|
||||
.test(isMinSuperiorThanMax)
|
||||
.matches(/^\d*$/, errorsTrads.regex),
|
||||
.matches(/^-?\d*$/, errorsTrads.regex),
|
||||
};
|
||||
|
||||
return yup.object(shape);
|
||||
|
||||
@ -68,11 +68,13 @@ const validators = {
|
||||
yup
|
||||
.number()
|
||||
.integer()
|
||||
.positive(getTrad('error.validation.positive'))
|
||||
.nullable(),
|
||||
minLength: () =>
|
||||
yup
|
||||
.number()
|
||||
.integer()
|
||||
.min(0)
|
||||
.when('maxLength', (maxLength, schema) => {
|
||||
if (maxLength) {
|
||||
return schema.max(maxLength, getTrad('error.validation.minSupMax'));
|
||||
|
||||
@ -68,6 +68,7 @@ import {
|
||||
RESET_PROPS_AND_SAVE_CURRENT_DATA,
|
||||
RESET_PROPS,
|
||||
} from './constants';
|
||||
import SelectNumber from '../SelectNumber';
|
||||
|
||||
/* eslint-disable indent */
|
||||
/* eslint-disable react/no-array-index-key */
|
||||
@ -832,6 +833,7 @@ const FormModal = () => {
|
||||
'select-component': SelectComponent,
|
||||
'select-components': SelectComponents,
|
||||
'select-default-boolean': BooleanDefaultValueSelect,
|
||||
'select-number': SelectNumber,
|
||||
'toggle-draft-publish': DraftAndPublishToggle,
|
||||
'text-plural': PluralName,
|
||||
'text-singular': SingularName,
|
||||
@ -883,6 +885,8 @@ const FormModal = () => {
|
||||
|
||||
const schemaKind = get(contentTypes, [targetUid, 'schema', 'kind']);
|
||||
|
||||
console.log({ formModal: modifiedData });
|
||||
|
||||
return (
|
||||
<>
|
||||
<ModalLayout onClose={handleClosed} labelledBy="title">
|
||||
|
||||
@ -0,0 +1,105 @@
|
||||
/**
|
||||
*
|
||||
* SelectNumber
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Select, Option } from '@strapi/design-system/Select';
|
||||
|
||||
const SelectNumber = ({ intlLabel, error, modifiedData, name, onChange, options, value }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const label = formatMessage(intlLabel);
|
||||
const errorMessage = error ? formatMessage({ id: error, defaultMessage: error }) : '';
|
||||
|
||||
const handleChange = nextValue => {
|
||||
onChange({ target: { name, value: nextValue, type: 'select' } });
|
||||
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextValue === 'biginteger' && value !== 'biginteger') {
|
||||
if (modifiedData.default !== undefined && modifiedData.default !== null) {
|
||||
onChange({ target: { name: 'default', value: null } });
|
||||
}
|
||||
|
||||
if (modifiedData.max !== undefined && modifiedData.max !== null) {
|
||||
onChange({ target: { name: 'max', value: null } });
|
||||
}
|
||||
|
||||
if (modifiedData.min !== undefined && modifiedData.min !== null) {
|
||||
onChange({ target: { name: 'min', value: null } });
|
||||
}
|
||||
}
|
||||
|
||||
if (['decimal', 'float', 'integer'].includes(nextValue) && value === 'biginteger') {
|
||||
if (modifiedData.default !== undefined && modifiedData.default !== null) {
|
||||
onChange({ target: { name: 'default', value: null } });
|
||||
}
|
||||
|
||||
if (modifiedData.max !== undefined && modifiedData.max !== null) {
|
||||
onChange({ target: { name: 'max', value: null } });
|
||||
}
|
||||
|
||||
if (modifiedData.min !== undefined && modifiedData.min !== null) {
|
||||
onChange({ target: { name: 'min', value: null } });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Select
|
||||
error={errorMessage}
|
||||
label={label}
|
||||
id={name}
|
||||
name={name}
|
||||
onChange={handleChange}
|
||||
value={value || ''}
|
||||
>
|
||||
{options.map(({ metadatas: { intlLabel, disabled, hidden }, key, value }) => {
|
||||
return (
|
||||
<Option key={key} value={value} disabled={disabled} hidden={hidden}>
|
||||
{formatMessage(intlLabel)}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
|
||||
SelectNumber.defaultProps = {
|
||||
error: undefined,
|
||||
value: '',
|
||||
};
|
||||
|
||||
SelectNumber.propTypes = {
|
||||
error: PropTypes.string,
|
||||
intlLabel: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
defaultMessage: PropTypes.string.isRequired,
|
||||
values: PropTypes.object,
|
||||
}).isRequired,
|
||||
modifiedData: PropTypes.object.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
options: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
metadatas: PropTypes.shape({
|
||||
intlLabel: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
defaultMessage: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
hidden: PropTypes.bool,
|
||||
}).isRequired,
|
||||
key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
}).isRequired
|
||||
).isRequired,
|
||||
value: PropTypes.string,
|
||||
};
|
||||
|
||||
export default SelectNumber;
|
||||
@ -62,6 +62,7 @@
|
||||
"error.validation.enum-empty-string": "Empty strings are not allowed",
|
||||
"error.validation.minSupMax": "Can't be superior",
|
||||
"error.validation.regex": "Regex pattern is invalid",
|
||||
"error.validation.positive": "Must be a positive number",
|
||||
"error.validation.relation.targetAttribute-taken": "This name exists in the target",
|
||||
"form.attribute.component.option.add": "Add a component",
|
||||
"form.attribute.component.option.create": "Create a new component",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user