mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 11:54:10 +00:00 
			
		
		
		
	fix: content manager error management
This commit is contained in:
		
							parent
							
								
									6529e2bd50
								
							
						
					
					
						commit
						068381c9c9
					
				@ -670,45 +670,16 @@ const useField = <TValue = any,>(path: string): FieldValue<TValue | undefined> =
 | 
			
		||||
 | 
			
		||||
  const handleChange = useForm('useField', (state) => state.onChange);
 | 
			
		||||
 | 
			
		||||
  const formatNestedErrorMessages = (stateErrors: FormErrors<FormValues>) => {
 | 
			
		||||
    const nestedErrors: Record<string, any> = {};
 | 
			
		||||
  const error = useForm('useField', (state) => {
 | 
			
		||||
    const error = getIn(state.errors, path);
 | 
			
		||||
 | 
			
		||||
    Object.entries(stateErrors).forEach(([key, value]) => {
 | 
			
		||||
      let current = nestedErrors;
 | 
			
		||||
    if (isErrorMessageDescriptor(error)) {
 | 
			
		||||
      const { values, ...message } = error;
 | 
			
		||||
      return formatMessage(message, values);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      const pathParts = key.split('.');
 | 
			
		||||
      pathParts.forEach((part, index) => {
 | 
			
		||||
        const isLastPart = index === pathParts.length - 1;
 | 
			
		||||
 | 
			
		||||
        if (isLastPart) {
 | 
			
		||||
          if (typeof value === 'string') {
 | 
			
		||||
            // If the value is a translation message object or a string, it should be nested as is
 | 
			
		||||
            current[part] = value;
 | 
			
		||||
          } else if (isErrorMessageDescriptor(value)) {
 | 
			
		||||
            // If the value is a plain object, it should be converted to a string message
 | 
			
		||||
            current[part] = formatMessage(value);
 | 
			
		||||
          } else {
 | 
			
		||||
            // If the value is not an object, it may be an array or a message
 | 
			
		||||
            setIn(current, part, value);
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          // Ensure nested structure exists
 | 
			
		||||
          if (!current[part]) {
 | 
			
		||||
            const isArray = !isNaN(Number(pathParts[index + 1]));
 | 
			
		||||
            current[part] = isArray ? [] : {};
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          current = current[part];
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return nestedErrors;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const error = useForm('useField', (state) =>
 | 
			
		||||
    getIn(formatNestedErrorMessages(state.errors), path)
 | 
			
		||||
  );
 | 
			
		||||
    return error;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    initialValue,
 | 
			
		||||
 | 
			
		||||
@ -46,11 +46,6 @@ const Initializer = ({ disabled, name, onClick }: InitializerProps) => {
 | 
			
		||||
          </Flex>
 | 
			
		||||
        </Flex>
 | 
			
		||||
      </Box>
 | 
			
		||||
      {field.error && (
 | 
			
		||||
        <Typography textColor="danger600" variant="pi">
 | 
			
		||||
          {field.error}
 | 
			
		||||
        </Typography>
 | 
			
		||||
      )}
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,3 @@
 | 
			
		||||
import { useState } from 'react';
 | 
			
		||||
 | 
			
		||||
import { Box, Checkbox, Field, Flex, NumberInput, TextInput } from '@strapi/design-system';
 | 
			
		||||
import { useIntl } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
@ -23,7 +21,6 @@ export const CheckboxWithNumberField = ({
 | 
			
		||||
  value = null,
 | 
			
		||||
}: CheckboxWithNumberFieldProps) => {
 | 
			
		||||
  const { formatMessage } = useIntl();
 | 
			
		||||
  const [showInput, setShowInput] = useState(!!value || value === 0);
 | 
			
		||||
  const label = intlLabel.id
 | 
			
		||||
    ? formatMessage(
 | 
			
		||||
        { id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
 | 
			
		||||
@ -46,13 +43,12 @@ export const CheckboxWithNumberField = ({
 | 
			
		||||
          const nextValue = value ? initValue : null;
 | 
			
		||||
 | 
			
		||||
          onChange({ target: { name, value: nextValue } });
 | 
			
		||||
          setShowInput((prev) => !prev);
 | 
			
		||||
        }}
 | 
			
		||||
        checked={showInput}
 | 
			
		||||
        checked={value !== null}
 | 
			
		||||
      >
 | 
			
		||||
        {label}
 | 
			
		||||
      </Checkbox>
 | 
			
		||||
      {showInput && (
 | 
			
		||||
      {value !== null && (
 | 
			
		||||
        <Box paddingLeft={6} style={{ maxWidth: '200px' }}>
 | 
			
		||||
          {type === 'text' ? (
 | 
			
		||||
            <Field.Root error={errorMessage} name={name}>
 | 
			
		||||
@ -70,7 +66,7 @@ export const CheckboxWithNumberField = ({
 | 
			
		||||
                aria-label={label}
 | 
			
		||||
                disabled={disabled}
 | 
			
		||||
                onValueChange={(value: any) => {
 | 
			
		||||
                  onChange({ target: { name, value, type } });
 | 
			
		||||
                  onChange({ target: { name, value: value ?? 0, type } });
 | 
			
		||||
                }}
 | 
			
		||||
                value={value || 0}
 | 
			
		||||
              />
 | 
			
		||||
 | 
			
		||||
@ -81,7 +81,7 @@ const validators = {
 | 
			
		||||
    yup
 | 
			
		||||
      .number()
 | 
			
		||||
      .integer()
 | 
			
		||||
      .min(0)
 | 
			
		||||
      .min(1)
 | 
			
		||||
      .when('maxLength', (maxLength, schema) => {
 | 
			
		||||
        if (maxLength) {
 | 
			
		||||
          return schema.max(maxLength, getTrad('error.validation.minSupMax'));
 | 
			
		||||
@ -118,7 +118,11 @@ const createTextShape = (usedAttributeNames: Array<string>, reservedNames: Array
 | 
			
		||||
        name: 'isValidRegExpPattern',
 | 
			
		||||
        message: getTrad('error.validation.regex'),
 | 
			
		||||
        test(value) {
 | 
			
		||||
          return new RegExp(value || '') !== null;
 | 
			
		||||
          try {
 | 
			
		||||
            return new RegExp(value || '') !== null;
 | 
			
		||||
          } catch (e) {
 | 
			
		||||
            return false;
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
      .nullable(),
 | 
			
		||||
 | 
			
		||||
@ -42,6 +42,7 @@ export const TabForm = ({
 | 
			
		||||
            <Grid.Root gap={4}>
 | 
			
		||||
              {section.items.map((input: any, i: number) => {
 | 
			
		||||
                const key = `${sectionIndex}.${i}`;
 | 
			
		||||
 | 
			
		||||
                /**
 | 
			
		||||
                 * Use undefined as the default value because not every input wants a string e.g. Date pickers
 | 
			
		||||
                 */
 | 
			
		||||
 | 
			
		||||
@ -64,7 +64,7 @@
 | 
			
		||||
  "error.validation.enum-duplicate": "Duplicate values are not allowed (only alphanumeric characters are taken into account).",
 | 
			
		||||
  "error.validation.enum-empty-string": "Empty strings are not allowed",
 | 
			
		||||
  "error.validation.enum-regex": "At least one value is invalid. Values should have at least one alphabetical character preceding the first occurence of a number.",
 | 
			
		||||
  "error.validation.minSupMax": "Can't be superior",
 | 
			
		||||
  "error.validation.minSupMax": "min can't be superior to max",
 | 
			
		||||
  "error.validation.positive": "Must be a positive number",
 | 
			
		||||
  "error.validation.regex": "Regex pattern is invalid",
 | 
			
		||||
  "error.validation.relation.targetAttribute-taken": "This name exists in the target",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user