fix: Required custom field consider blank space as valid input (#29635)

pull/29620/head^2
Aleksander Nicacio da Silva 3 years ago committed by GitHub
parent ee75fc2e82
commit baaa38f7f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .changeset/olive-pears-sell.md
  2. 46
      packages/ui-client/src/components/CustomFieldsForm.tsx

@ -0,0 +1,5 @@
---
'@rocket.chat/ui-client': patch
---
Fixed required custom fields considering blank spaces as valid.

@ -3,8 +3,9 @@ import type { SelectOption } from '@rocket.chat/fuselage';
import { Field, Select, TextInput } from '@rocket.chat/fuselage';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
import { useTranslation } from '@rocket.chat/ui-contexts';
import { useCallback, useMemo } from 'react';
import type { Control, FieldValues } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import { Controller, useFormState, get } from 'react-hook-form';
type CustomFieldFormProps<T extends FieldValues> = {
metadata: CustomFieldMetadata[];
@ -33,32 +34,41 @@ const CustomField = <T extends FieldValues>({
...props
}: CustomFieldProps<T>) => {
const t = useTranslation();
const { getFieldState } = control;
const { errors } = useFormState({ control });
const Component = FIELD_TYPES[type] ?? null;
const selectOptions =
options.length > 0 && options[0] instanceof Array ? options : options.map((option) => [option, option, defaultValue === option]);
const selectOptions = useMemo(
() =>
options.length > 0 && options[0] instanceof Array ? options : options.map((option) => [option, option, defaultValue === option]),
[defaultValue, options],
);
const validateRequired = useCallback((value) => (required ? typeof value === 'string' && !!value.trim() : true), [required]);
const getErrorMessage = (error: any) => {
switch (error?.type) {
case 'required':
return t('The_field_is_required', label || name);
case 'minLength':
return t('Min_length_is', props?.minLength);
case 'maxLength':
return t('Max_length_is', props?.maxLength);
}
};
const getErrorMessage = useCallback(
(error: any) => {
switch (error?.type) {
case 'required':
return t('The_field_is_required', label || name);
case 'minLength':
return t('Min_length_is', props?.minLength);
case 'maxLength':
return t('Max_length_is', props?.maxLength);
}
},
[label, name, props?.maxLength, props?.minLength, t],
);
const error = getErrorMessage(getFieldState(name as any).error);
const error = get(errors, name);
const errorMessage = useMemo(() => getErrorMessage(error), [error, getErrorMessage]);
return (
<Controller<T, any>
name={name}
control={control}
defaultValue={defaultValue ?? ''}
rules={{ required, minLength: props.minLength, maxLength: props.maxLength }}
rules={{ minLength: props.minLength, maxLength: props.maxLength, validate: { required: validateRequired } }}
render={({ field }) => (
<Field rcx-field-group__item>
<Field.Label>
@ -66,9 +76,9 @@ const CustomField = <T extends FieldValues>({
{required && '*'}
</Field.Label>
<Field.Row>
<Component {...props} {...field} error={error} options={selectOptions as SelectOption[]} flexGrow={1} />
<Component {...props} {...field} error={errorMessage} options={selectOptions as SelectOption[]} flexGrow={1} />
</Field.Row>
<Field.Error>{error}</Field.Error>
<Field.Error>{errorMessage}</Field.Error>
</Field>
)}
/>

Loading…
Cancel
Save