Commit 45f6a946 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #116 from blockscout/disable-form-button

Disable form button
parents adf7a48c 66b007f7
......@@ -32,7 +32,7 @@ type Inputs = {
const NAME_MAX_LENGTH = 255;
const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
const { control, handleSubmit, formState: { errors }, setError } = useForm<Inputs>({
const { control, handleSubmit, formState: { errors, isValid }, setError } = useForm<Inputs>({
mode: 'all',
defaultValues: {
token: data?.api_key || '',
......@@ -143,7 +143,7 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
size="lg"
variant="primary"
onClick={ handleSubmit(onSubmit) }
disabled={ Object.keys(errors).length > 0 }
disabled={ !isValid }
isLoading={ mutation.isLoading }
>
{ data ? 'Save' : 'Generate API key' }
......
......@@ -36,7 +36,7 @@ type Inputs = {
const NAME_MAX_LENGTH = 255;
const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
const { control, formState: { errors }, handleSubmit, setError } = useForm<Inputs>({
const { control, formState: { errors, isValid }, handleSubmit, setError } = useForm<Inputs>({
defaultValues: {
contract_address_hash: data?.contract_address_hash || '',
name: data?.name || '',
......@@ -102,7 +102,7 @@ const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
return (
<AddressInput<Inputs, 'contract_address_hash'>
field={ field }
error={ errors.contract_address_hash?.message }
error={ errors.contract_address_hash }
backgroundColor={ formBackgroundColor }
placeholder="Smart contract address (0x...)"
/>
......@@ -164,7 +164,7 @@ const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
size="lg"
variant="primary"
onClick={ handleSubmit(onSubmit) }
disabled={ Object.keys(errors).length > 0 }
disabled={ !isValid }
isLoading={ mutation.isLoading }
>
{ data ? 'Save' : 'Create custom ABI' }
......
......@@ -32,7 +32,7 @@ type Inputs = {
const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
const [ pending, setPending ] = useState(false);
const { control, handleSubmit, formState: { errors }, setError } = useForm<Inputs>({
const { control, handleSubmit, formState: { errors, isValid }, setError } = useForm<Inputs>({
mode: 'all',
defaultValues: {
address: data?.address_hash || '',
......@@ -83,11 +83,11 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
};
const renderAddressInput = useCallback(({ field }: {field: ControllerRenderProps<Inputs, 'address'>}) => {
return <AddressInput<Inputs, 'address'> field={ field } error={ errors.address?.message } backgroundColor={ formBackgroundColor }/>;
return <AddressInput<Inputs, 'address'> field={ field } error={ errors.address } backgroundColor={ formBackgroundColor }/>;
}, [ errors, formBackgroundColor ]);
const renderTagInput = useCallback(({ field }: {field: ControllerRenderProps<Inputs, 'tag'>}) => {
return <TagInput<Inputs, 'tag'> field={ field } error={ errors.tag?.message } backgroundColor={ formBackgroundColor }/>;
return <TagInput<Inputs, 'tag'> field={ field } error={ errors.tag } backgroundColor={ formBackgroundColor }/>;
}, [ errors, formBackgroundColor ]);
return (
......@@ -117,7 +117,7 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
size="lg"
variant="primary"
onClick={ handleSubmit(onSubmit) }
disabled={ Object.keys(errors).length > 0 }
disabled={ !isValid }
isLoading={ pending }
>
{ data ? 'Save changes' : 'Add tag' }
......
......@@ -34,7 +34,7 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
const [ pending, setPending ] = useState(false);
const formBackgroundColor = useColorModeValue('white', 'gray.900');
const { control, handleSubmit, formState: { errors }, setError } = useForm<Inputs>({
const { control, handleSubmit, formState: { errors, isValid }, setError } = useForm<Inputs>({
mode: 'all',
defaultValues: {
transaction: data?.transaction_hash || '',
......@@ -82,11 +82,11 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
};
const renderTransactionInput = useCallback(({ field }: {field: ControllerRenderProps<Inputs, 'transaction'>}) => {
return <TransactionInput field={ field } error={ errors.transaction?.message } backgroundColor={ formBackgroundColor }/>;
return <TransactionInput field={ field } error={ errors.transaction } backgroundColor={ formBackgroundColor }/>;
}, [ errors, formBackgroundColor ]);
const renderTagInput = useCallback(({ field }: {field: ControllerRenderProps<Inputs, 'tag'>}) => {
return <TagInput<Inputs, 'tag'> field={ field } error={ errors.tag?.message } backgroundColor={ formBackgroundColor }/>;
return <TagInput<Inputs, 'tag'> field={ field } error={ errors.tag } backgroundColor={ formBackgroundColor }/>;
}, [ errors, formBackgroundColor ]);
return (
......@@ -116,7 +116,7 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
size="lg"
variant="primary"
onClick={ handleSubmit(onSubmit) }
disabled={ Object.keys(errors).length > 0 }
disabled={ !isValid }
isLoading={ pending }
>
{ data ? 'Save changes' : 'Add tag' }
......
import { IconButton, Icon } from '@chakra-ui/react';
import React, { useCallback } from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import type { ControllerRenderProps, Control, FieldError } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import MinusIcon from 'icons/minus.svg';
......@@ -14,7 +14,7 @@ interface Props {
control: Control<Inputs>;
index: number;
fieldsLength: number;
error?: string;
error?: FieldError;
onAddFieldClick: (e: React.SyntheticEvent) => void;
onRemoveFieldClick: (index: number) => (e: React.SyntheticEvent) => void;
}
......
import { FormControl, FormLabel, Textarea } from '@chakra-ui/react';
import React, { useCallback } from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import type { ControllerRenderProps, Control, FieldError } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import getPlaceholderWithError from 'lib/getPlaceholderWithError';
......@@ -11,7 +11,7 @@ const TEXT_INPUT_MAX_LENGTH = 255;
interface Props {
control: Control<Inputs>;
error?: string;
error?: FieldError;
}
export default function PublicTagFormComment({ control, error }: Props) {
......@@ -24,7 +24,7 @@ export default function PublicTagFormComment({ control, error }: Props) {
size="lg"
/>
<FormLabel>
{ getPlaceholderWithError('Specify the reason for adding tags and color preference(s)', error) }
{ getPlaceholderWithError('Specify the reason for adding tags and color preference(s)', error?.message) }
</FormLabel>
</FormControl>
);
......
......@@ -8,7 +8,7 @@ import {
} from '@chakra-ui/react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import React, { useCallback, useState } from 'react';
import type { Path, SubmitHandler } from 'react-hook-form';
import type { FieldError, Path, SubmitHandler } from 'react-hook-form';
import { useForm, useFieldArray } from 'react-hook-form';
import type { PublicTags, PublicTag, PublicTagNew, PublicTagErrors } from 'types/api/account';
......@@ -57,7 +57,7 @@ const ADDRESS_INPUT_BUTTONS_WIDTH = 170;
const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
const queryClient = useQueryClient();
const { control, handleSubmit, formState: { errors }, setError } = useForm<Inputs>({
const { control, handleSubmit, formState: { errors, isValid }, setError } = useForm<Inputs>({
defaultValues: {
fullName: data?.full_name || '',
email: data?.email || '',
......@@ -158,7 +158,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
fieldName="fullName"
control={ control }
label={ placeholders.fullName }
error={ errors.fullName?.message }
error={ errors.fullName }
required
/>
</GridItem>
......@@ -167,7 +167,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
fieldName="companyName"
control={ control }
label={ placeholders.companyName }
error={ errors.companyName?.message }
error={ errors.companyName }
/>
</GridItem>
<GridItem>
......@@ -176,7 +176,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
control={ control }
label={ placeholders.email }
pattern={ EMAIL_REGEXP }
error={ errors.email?.message }
error={ errors.email }
required
/>
</GridItem>
......@@ -185,7 +185,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
fieldName="companyUrl"
control={ control }
label={ placeholders.companyUrl }
error={ errors?.companyUrl?.message }
error={ errors?.companyUrl }
/>
</GridItem>
</Grid>
......@@ -198,7 +198,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
fieldName="tags"
control={ control }
label={ placeholders.tags }
error={ errors.tags?.message }
error={ errors.tags }
required/>
</Box>
{ fields.map((field, index) => {
......@@ -206,7 +206,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
<Box position="relative" key={ field.id } marginBottom={ 4 }>
<PublicTagFormAddressInput
control={ control }
error={ errors?.addresses?.[index]?.message }
error={ errors?.addresses?.[index] as FieldError }
index={ index }
fieldsLength={ fields.length }
onAddFieldClick={ onAddFieldClick }
......@@ -216,14 +216,14 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
);
}) }
<Box marginBottom={ 8 }>
<PublicTagFormComment control={ control } error={ errors.comment?.message }/>
<PublicTagFormComment control={ control } error={ errors.comment }/>
</Box>
<HStack spacing={ 6 }>
<Button
size="lg"
variant="primary"
onClick={ handleSubmit(onSubmit) }
disabled={ Object.keys(errors).length > 0 }
disabled={ !isValid }
isLoading={ mutation.isLoading }
>
Send request
......
import { FormControl, FormLabel, Input } from '@chakra-ui/react';
import React, { useCallback } from 'react';
import type { ControllerRenderProps, FieldValues, Path, Control } from 'react-hook-form';
import type { ControllerRenderProps, FieldError, FieldValues, Path, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import getPlaceholderWithError from 'lib/getPlaceholderWithError';
......@@ -13,7 +13,7 @@ interface Props<TInputs extends FieldValues> {
required?: boolean;
control: Control<TInputs, object>;
pattern?: RegExp;
error?: string;
error?: FieldError;
}
export default function PublicTagsFormInput<Inputs extends FieldValues>({
......@@ -34,7 +34,7 @@ export default function PublicTagsFormInput<Inputs extends FieldValues>({
isInvalid={ Boolean(error) }
maxLength={ TEXT_INPUT_MAX_LENGTH }
/>
<FormLabel>{ getPlaceholderWithError(label, error) }</FormLabel>
<FormLabel>{ getPlaceholderWithError(label, error?.message) }</FormLabel>
</FormControl>
);
}, [ label, required, error ]);
......
......@@ -4,7 +4,7 @@ import {
FormLabel,
} from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, FieldValues, Path } from 'react-hook-form';
import type { ControllerRenderProps, FieldError, FieldValues, Path } from 'react-hook-form';
import getPlaceholderWithError from 'lib/getPlaceholderWithError';
import { ADDRESS_LENGTH } from 'lib/validations/address';
......@@ -14,7 +14,7 @@ type Props<TInputs extends FieldValues, TInputName extends Path<TInputs>> = {
size?: string;
placeholder?: string;
backgroundColor?: string;
error?: string;
error?: FieldError;
}
export default function AddressInput<Inputs extends FieldValues, Name extends Path<Inputs>>(
......@@ -33,7 +33,7 @@ export default function AddressInput<Inputs extends FieldValues, Name extends Pa
maxLength={ ADDRESS_LENGTH }
size={ size }
/>
<FormLabel>{ getPlaceholderWithError(placeholder, error) }</FormLabel>
<FormLabel>{ getPlaceholderWithError(placeholder, error?.message) }</FormLabel>
</FormControl>
);
}
......@@ -4,7 +4,7 @@ import {
FormLabel,
} from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, FieldValues, Path } from 'react-hook-form';
import type { ControllerRenderProps, FieldError, FieldValues, Path } from 'react-hook-form';
import getPlaceholderWithError from 'lib/getPlaceholderWithError';
......@@ -12,7 +12,7 @@ const TAG_MAX_LENGTH = 35;
type Props<TInputs extends FieldValues, TInputName extends Path<TInputs>> = {
field: ControllerRenderProps<TInputs, TInputName>;
error?: string;
error?: FieldError;
backgroundColor?: string;
}
......@@ -24,7 +24,7 @@ function TagInput<Inputs extends FieldValues, Name extends Path<Inputs>>({ field
isInvalid={ Boolean(error) }
maxLength={ TAG_MAX_LENGTH }
/>
<FormLabel>{ getPlaceholderWithError(`Private tag (max 35 characters)`, error) }</FormLabel>
<FormLabel>{ getPlaceholderWithError(`Private tag (max 35 characters)`, error?.message) }</FormLabel>
</FormControl>
);
}
......
......@@ -4,14 +4,14 @@ import {
FormLabel,
} from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, FieldValues } from 'react-hook-form';
import type { ControllerRenderProps, FieldError, FieldValues } from 'react-hook-form';
import getPlaceholderWithError from 'lib/getPlaceholderWithError';
import { TRANSACTION_HASH_LENGTH } from 'lib/validations/transaction';
type Props<Field> = {
field: Field;
error?: string;
error?: FieldError;
backgroundColor?: string;
}
......@@ -23,7 +23,7 @@ function TransactionInput<Field extends Partial<ControllerRenderProps<FieldValue
isInvalid={ Boolean(error) }
maxLength={ TRANSACTION_HASH_LENGTH }
/>
<FormLabel>{ getPlaceholderWithError('Transaction hash (0x...)', error) }</FormLabel>
<FormLabel>{ getPlaceholderWithError('Transaction hash (0x...)', error?.message) }</FormLabel>
</FormControl>
);
}
......
......@@ -72,7 +72,7 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
notificationsDefault = data.notification_settings;
}
const { control, handleSubmit, formState: { errors }, setError } = useForm<Inputs>({
const { control, handleSubmit, formState: { errors, isValid }, setError } = useForm<Inputs>({
defaultValues: {
address: data?.address_hash || '',
tag: data?.name || '',
......@@ -134,13 +134,13 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
<AddressInput<Inputs, 'address'>
field={ field }
backgroundColor={ formBackgroundColor }
error={ errors.address?.message }
error={ errors.address }
/>
);
}, [ errors, formBackgroundColor ]);
const renderTagInput = useCallback(({ field }: {field: ControllerRenderProps<Inputs, 'tag'>}) => {
return <TagInput<Inputs, 'tag'> field={ field } error={ errors.tag?.message } backgroundColor={ formBackgroundColor }/>;
return <TagInput<Inputs, 'tag'> field={ field } error={ errors.tag } backgroundColor={ formBackgroundColor }/>;
}, [ errors, formBackgroundColor ]);
// eslint-disable-next-line react/display-name
......@@ -156,6 +156,7 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
control={ control }
rules={{
pattern: ADDRESS_REGEXP,
required: true,
}}
render={ renderAddressInput }
/>
......@@ -166,6 +167,7 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
control={ control }
rules={{
maxLength: TAG_MAX_LENGTH,
required: true,
}}
render={ renderTagInput }
/>
......@@ -188,7 +190,7 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
variant="primary"
onClick={ handleSubmit(onSubmit) }
isLoading={ pending }
disabled={ Object.keys(errors).length > 0 }
disabled={ !isValid }
>
{ data ? 'Save changes' : 'Add address' }
</Button>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment