Commit d36d5675 authored by tom's avatar tom

scroll to top on form validation error

parent 618d235d
...@@ -120,8 +120,8 @@ export const RESOURCES = { ...@@ -120,8 +120,8 @@ export const RESOURCES = {
}, },
token_info_applications: { token_info_applications: {
path: '/api/v1/chains/:chainId/token-info-submissions', path: '/api/v1/chains/:chainId/token-info-submissions/:id?',
pathParams: [ 'chainId' as const ], pathParams: [ 'chainId' as const, 'id' as const ],
endpoint: appConfig.adminServiceApi.endpoint, endpoint: appConfig.adminServiceApi.endpoint,
basePath: appConfig.adminServiceApi.basePath, basePath: appConfig.adminServiceApi.basePath,
}, },
......
...@@ -28,7 +28,7 @@ const VerifiedAddresses = () => { ...@@ -28,7 +28,7 @@ const VerifiedAddresses = () => {
pathParams: { chainId: appConfig.network.id }, pathParams: { chainId: appConfig.network.id },
}); });
const applicationsQuery = useApiQuery('token_info_applications', { const applicationsQuery = useApiQuery('token_info_applications', {
pathParams: { chainId: appConfig.network.id }, pathParams: { chainId: appConfig.network.id, id: undefined },
}); });
const queryClient = useQueryClient(); const queryClient = useQueryClient();
...@@ -58,8 +58,9 @@ const VerifiedAddresses = () => { ...@@ -58,8 +58,9 @@ const VerifiedAddresses = () => {
}, [ queryClient ]); }, [ queryClient ]);
const handleApplicationSubmit = React.useCallback((newItem: TokenInfoApplication) => { const handleApplicationSubmit = React.useCallback((newItem: TokenInfoApplication) => {
setSelectedAddress(undefined);
queryClient.setQueryData( queryClient.setQueryData(
getResourceKey('token_info_applications', { pathParams: { chainId: appConfig.network.id } }), getResourceKey('token_info_applications', { pathParams: { chainId: appConfig.network.id, id: undefined } }),
(prevData: TokenInfoApplications | undefined) => { (prevData: TokenInfoApplications | undefined) => {
if (!prevData) { if (!prevData) {
return { submissions: [ newItem ] }; return { submissions: [ newItem ] };
......
...@@ -10,6 +10,7 @@ import appConfig from 'configs/app/config'; ...@@ -10,6 +10,7 @@ import appConfig from 'configs/app/config';
import useApiFetch from 'lib/api/useApiFetch'; import useApiFetch from 'lib/api/useApiFetch';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import useToast from 'lib/hooks/useToast'; import useToast from 'lib/hooks/useToast';
import useUpdateEffect from 'lib/hooks/useUpdateEffect';
import ContentLoader from 'ui/shared/ContentLoader'; import ContentLoader from 'ui/shared/ContentLoader';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
...@@ -37,6 +38,8 @@ interface Props { ...@@ -37,6 +38,8 @@ interface Props {
const TokenInfoForm = ({ address, application, onSubmit }: Props) => { const TokenInfoForm = ({ address, application, onSubmit }: Props) => {
const containerRef = React.useRef<HTMLFormElement>(null);
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
const toast = useToast(); const toast = useToast();
...@@ -54,9 +57,9 @@ const TokenInfoForm = ({ address, application, onSubmit }: Props) => { ...@@ -54,9 +57,9 @@ const TokenInfoForm = ({ address, application, onSubmit }: Props) => {
try { try {
const submission = prepareRequestBody(data); const submission = prepareRequestBody(data);
const result = await apiFetch<'token_info_applications', TokenInfoApplication, { message: string }>('token_info_applications', { const result = await apiFetch<'token_info_applications', TokenInfoApplication, { message: string }>('token_info_applications', {
pathParams: { chainId: appConfig.network.id }, pathParams: { chainId: appConfig.network.id, id: application?.id },
fetchParams: { fetchParams: {
method: 'POST', method: application?.id ? 'PUT' : 'POST',
body: { submission }, body: { submission },
}, },
}); });
...@@ -76,7 +79,13 @@ const TokenInfoForm = ({ address, application, onSubmit }: Props) => { ...@@ -76,7 +79,13 @@ const TokenInfoForm = ({ address, application, onSubmit }: Props) => {
isClosable: true, isClosable: true,
}); });
} }
}, [ apiFetch, onSubmit, toast ]); }, [ apiFetch, application?.id, onSubmit, toast ]);
useUpdateEffect(() => {
if (formState.submitCount > 0 && !formState.isValid) {
containerRef.current?.scrollIntoView({ behavior: 'smooth' });
}
}, [ formState.isValid, formState.submitCount ]);
if (configQuery.isError) { if (configQuery.isError) {
return <DataFetchAlert/>; return <DataFetchAlert/>;
...@@ -89,7 +98,7 @@ const TokenInfoForm = ({ address, application, onSubmit }: Props) => { ...@@ -89,7 +98,7 @@ const TokenInfoForm = ({ address, application, onSubmit }: Props) => {
const fieldProps = { control, isReadOnly: application?.status === 'IN_PROCESS' }; const fieldProps = { control, isReadOnly: application?.status === 'IN_PROCESS' };
return ( return (
<form noValidate onSubmit={ handleSubmit(onFormSubmit) } autoComplete="off"> <form noValidate onSubmit={ handleSubmit(onFormSubmit) } autoComplete="off" ref={ containerRef }>
<div>Requests are sent to a moderator for review and approval. This process can take several days.</div> <div>Requests are sent to a moderator for review and approval. This process can take several days.</div>
{ application?.status === 'IN_PROCESS' && { application?.status === 'IN_PROCESS' &&
<Alert status="warning" mt={ 6 }>Request in progress. Once an admin approves your request you can edit token info.</Alert> } <Alert status="warning" mt={ 6 }>Request in progress. Once an admin approves your request you can edit token info.</Alert> }
......
...@@ -50,7 +50,7 @@ const VerifiedAddressesTableItem = ({ item, application, onAdd, onEdit }: Props) ...@@ -50,7 +50,7 @@ const VerifiedAddressesTableItem = ({ item, application, onAdd, onEdit }: Props)
<Td> <Td>
<AddressSnippet address={{ hash: item.contractAddress, is_contract: true, implementation_name: null }}/> <AddressSnippet address={{ hash: item.contractAddress, is_contract: true, implementation_name: null }}/>
</Td> </Td>
<Td> <Td fontSize="sm">
{ application ? ( { application ? (
<Flex alignItems="center" columnGap={ 2 } w="100%"> <Flex alignItems="center" columnGap={ 2 } w="100%">
<Image <Image
...@@ -84,8 +84,8 @@ const VerifiedAddressesTableItem = ({ item, application, onAdd, onEdit }: Props) ...@@ -84,8 +84,8 @@ const VerifiedAddressesTableItem = ({ item, application, onAdd, onEdit }: Props)
<Link onClick={ handleAddClick }>Add details</Link> <Link onClick={ handleAddClick }>Add details</Link>
) } ) }
</Td> </Td>
<Td>{ status }</Td> <Td fontSize="sm">{ status }</Td>
<Td></Td> <Td fontSize="sm"></Td>
</Tr> </Tr>
); );
}; };
......
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