Commit 7a8a5c0b authored by tom's avatar tom

private tags resources

parent 2f4c6b6d
...@@ -15,6 +15,12 @@ export const RESOURCES = { ...@@ -15,6 +15,12 @@ export const RESOURCES = {
public_tags: { public_tags: {
path: '/api/account/v1/user/public_tags/:id?', path: '/api/account/v1/user/public_tags/:id?',
}, },
private_tags_address: {
path: '/api/account/v1/user/tags/address/:id?',
},
private_tags_tx: {
path: '/api/account/v1/user/tags/transaction/:id?',
},
// DEPRECATED // DEPRECATED
old_api: { old_api: {
......
import type { UseQueryOptions } from '@tanstack/react-query'; import type { UseQueryOptions } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import type { UserInfo, CustomAbis, PublicTags } from 'types/api/account'; import type { UserInfo, CustomAbis, PublicTags, AddressTags, TransactionTags } from 'types/api/account';
import type { CsrfData } from 'types/client/account'; import type { CsrfData } from 'types/client/account';
import type { RESOURCES, ResourceError } from './resources'; import type { RESOURCES, ResourceError } from './resources';
...@@ -28,4 +28,6 @@ export type ResourcePayload<Q extends keyof typeof RESOURCES> = ...@@ -28,4 +28,6 @@ export type ResourcePayload<Q extends keyof typeof RESOURCES> =
Q extends 'csrf' ? CsrfData : Q extends 'csrf' ? CsrfData :
Q extends 'custom_abi' ? CustomAbis : Q extends 'custom_abi' ? CustomAbis :
Q extends 'public_tags' ? PublicTags : Q extends 'public_tags' ? PublicTags :
never; Q extends 'private_tags_address' ? AddressTags :
Q extends 'private_tags_tx' ? TransactionTags :
never;
...@@ -9,11 +9,11 @@ import type { SubmitHandler, ControllerRenderProps } from 'react-hook-form'; ...@@ -9,11 +9,11 @@ import type { SubmitHandler, ControllerRenderProps } from 'react-hook-form';
import { useForm, Controller } from 'react-hook-form'; import { useForm, Controller } from 'react-hook-form';
import type { AddressTag, AddressTagErrors } from 'types/api/account'; import type { AddressTag, AddressTagErrors } from 'types/api/account';
import { QueryKeys } from 'types/client/accountQueries';
import type { ResourceErrorAccount } from 'lib/api/resources';
import { resourceKey } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch';
import getErrorMessage from 'lib/getErrorMessage'; import getErrorMessage from 'lib/getErrorMessage';
import type { ErrorType } from 'lib/hooks/useFetch';
import useFetch from 'lib/hooks/useFetch';
import { ADDRESS_REGEXP } from 'lib/validations/address'; import { ADDRESS_REGEXP } from 'lib/validations/address';
import AddressInput from 'ui/shared/AddressInput'; import AddressInput from 'ui/shared/AddressInput';
import TagInput from 'ui/shared/TagInput'; import TagInput from 'ui/shared/TagInput';
...@@ -32,7 +32,7 @@ type Inputs = { ...@@ -32,7 +32,7 @@ type Inputs = {
} }
const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => { const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
const fetch = useFetch(); const apiFetch = useApiFetch();
const [ pending, setPending ] = useState(false); const [ pending, setPending ] = useState(false);
const { control, handleSubmit, formState: { errors, isValid, isDirty }, setError } = useForm<Inputs>({ const { control, handleSubmit, formState: { errors, isValid, isDirty }, setError } = useForm<Inputs>({
mode: 'onTouched', mode: 'onTouched',
...@@ -54,24 +54,28 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => { ...@@ -54,24 +54,28 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
const isEdit = data?.id; const isEdit = data?.id;
if (isEdit) { if (isEdit) {
return fetch(`/node-api/account/private-tags/address/${ data.id }`, { method: 'PUT', body }); return apiFetch('private_tags_address', {
pathParams: { id: data.id },
fetchParams: { method: 'PUT', body },
});
} }
return fetch('/node-api/account/private-tags/address', { method: 'POST', body }); return apiFetch('private_tags_address', { fetchParams: { method: 'POST', body } });
}, { }, {
onError: (e: ErrorType<AddressTagErrors>) => { onError: (error: ResourceErrorAccount<AddressTagErrors>) => {
setPending(false); setPending(false);
if (e?.error?.address_hash || e?.error?.name) { const errorMap = error.payload?.errors;
e?.error?.address_hash && setError('address', { type: 'custom', message: getErrorMessage(e.error, 'address_hash') }); if (errorMap?.address_hash || errorMap?.name) {
e?.error?.name && setError('tag', { type: 'custom', message: getErrorMessage(e.error, 'name') }); errorMap?.address_hash && setError('address', { type: 'custom', message: getErrorMessage(errorMap, 'address_hash') });
} else if (e?.error?.identity_id) { errorMap?.name && setError('tag', { type: 'custom', message: getErrorMessage(errorMap, 'name') });
setError('address', { type: 'custom', message: getErrorMessage(e.error, 'identity_id') }); } else if (errorMap?.identity_id) {
setError('address', { type: 'custom', message: getErrorMessage(errorMap, 'identity_id') });
} else { } else {
setAlertVisible(true); setAlertVisible(true);
} }
}, },
onSuccess: () => { onSuccess: () => {
queryClient.refetchQueries([ QueryKeys.addressTags ]).then(() => { queryClient.refetchQueries([ resourceKey('private_tags_address') ]).then(() => {
onClose(); onClose();
setPending(false); setPending(false);
}); });
......
...@@ -3,9 +3,9 @@ import { useQueryClient } from '@tanstack/react-query'; ...@@ -3,9 +3,9 @@ import { useQueryClient } from '@tanstack/react-query';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import type { AddressTag, TransactionTag, AddressTags, TransactionTags } from 'types/api/account'; import type { AddressTag, TransactionTag, AddressTags, TransactionTags } from 'types/api/account';
import { QueryKeys } from 'types/client/accountQueries';
import useFetch from 'lib/hooks/useFetch'; import { resourceKey } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch';
import DeleteModal from 'ui/shared/DeleteModal'; import DeleteModal from 'ui/shared/DeleteModal';
type Props = { type Props = {
...@@ -20,19 +20,23 @@ const DeletePrivateTagModal: React.FC<Props> = ({ isOpen, onClose, data, type }) ...@@ -20,19 +20,23 @@ const DeletePrivateTagModal: React.FC<Props> = ({ isOpen, onClose, data, type })
const id = data.id; const id = data.id;
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const fetch = useFetch(); const apiFetch = useApiFetch();
const mutationFn = useCallback(() => { const mutationFn = useCallback(() => {
return fetch(`/node-api/account/private-tags/${ type }/${ id }`, { method: 'DELETE' }); const resourceName = type === 'address' ? 'private_tags_address' : 'private_tags_tx';
}, [ fetch, type, id ]); return apiFetch(resourceName, {
pathParams: { id: data.id },
fetchParams: { method: 'DELETE' },
});
}, [ type, apiFetch, data.id ]);
const onSuccess = useCallback(async() => { const onSuccess = useCallback(async() => {
if (type === 'address') { if (type === 'address') {
queryClient.setQueryData([ QueryKeys.addressTags ], (prevData: AddressTags | undefined) => { queryClient.setQueryData([ resourceKey('private_tags_address') ], (prevData: AddressTags | undefined) => {
return prevData?.filter((item: AddressTag) => item.id !== id); return prevData?.filter((item: AddressTag) => item.id !== id);
}); });
} else { } else {
queryClient.setQueryData([ QueryKeys.transactionTags ], (prevData: TransactionTags | undefined) => { queryClient.setQueryData([ resourceKey('private_tags_tx') ], (prevData: TransactionTags | undefined) => {
return prevData?.filter((item: TransactionTag) => item.id !== id); return prevData?.filter((item: TransactionTag) => item.id !== id);
}); });
} }
......
import { Box, Button, Skeleton, useDisclosure } from '@chakra-ui/react'; import { Box, Button, Skeleton, useDisclosure } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React, { useCallback, useState } from 'react'; import React, { useCallback, useState } from 'react';
import type { AddressTags, AddressTag } from 'types/api/account'; import type { AddressTag } from 'types/api/account';
import { QueryKeys } from 'types/client/accountQueries';
import useFetch from 'lib/hooks/useFetch'; import useApiQuery from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import AccountPageDescription from 'ui/shared/AccountPageDescription'; import AccountPageDescription from 'ui/shared/AccountPageDescription';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
...@@ -18,13 +16,11 @@ import AddressTagTable from './AddressTagTable/AddressTagTable'; ...@@ -18,13 +16,11 @@ import AddressTagTable from './AddressTagTable/AddressTagTable';
import DeletePrivateTagModal from './DeletePrivateTagModal'; import DeletePrivateTagModal from './DeletePrivateTagModal';
const PrivateAddressTags = () => { const PrivateAddressTags = () => {
const { data: addressTagsData, isLoading, isError } = const { data: addressTagsData, isLoading, isError } = useApiQuery('private_tags_address', { queryOptions: { refetchOnMount: false } });
useQuery<unknown, unknown, AddressTags>([ QueryKeys.addressTags ], async() => fetch('/node-api/account/private-tags/address'), { refetchOnMount: false });
const addressModalProps = useDisclosure(); const addressModalProps = useDisclosure();
const deleteModalProps = useDisclosure(); const deleteModalProps = useDisclosure();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const fetch = useFetch();
const [ addressModalData, setAddressModalData ] = useState<AddressTag>(); const [ addressModalData, setAddressModalData ] = useState<AddressTag>();
const [ deleteModalData, setDeleteModalData ] = useState<AddressTag>(); const [ deleteModalData, setDeleteModalData ] = useState<AddressTag>();
......
import { Box, Button, Skeleton, useDisclosure } from '@chakra-ui/react'; import { Box, Button, Skeleton, useDisclosure } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React, { useCallback, useState } from 'react'; import React, { useCallback, useState } from 'react';
import type { TransactionTags, TransactionTag } from 'types/api/account'; import type { TransactionTag } from 'types/api/account';
import { QueryKeys } from 'types/client/accountQueries';
import useFetch from 'lib/hooks/useFetch'; import useApiQuery from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import AccountPageDescription from 'ui/shared/AccountPageDescription'; import AccountPageDescription from 'ui/shared/AccountPageDescription';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
...@@ -18,16 +16,11 @@ import TransactionTagListItem from './TransactionTagTable/TransactionTagListItem ...@@ -18,16 +16,11 @@ import TransactionTagListItem from './TransactionTagTable/TransactionTagListItem
import TransactionTagTable from './TransactionTagTable/TransactionTagTable'; import TransactionTagTable from './TransactionTagTable/TransactionTagTable';
const PrivateTransactionTags = () => { const PrivateTransactionTags = () => {
const { data: transactionTagsData, isLoading, isError } = const { data: transactionTagsData, isLoading, isError } = useApiQuery('private_tags_tx', { queryOptions: { refetchOnMount: false } });
useQuery<unknown, unknown, TransactionTags>(
[ QueryKeys.transactionTags ],
async() => fetch('/node-api/account/private-tags/transaction'), { refetchOnMount: false },
);
const transactionModalProps = useDisclosure(); const transactionModalProps = useDisclosure();
const deleteModalProps = useDisclosure(); const deleteModalProps = useDisclosure();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const fetch = useFetch();
const [ transactionModalData, setTransactionModalData ] = useState<TransactionTag>(); const [ transactionModalData, setTransactionModalData ] = useState<TransactionTag>();
const [ deleteModalData, setDeleteModalData ] = useState<TransactionTag>(); const [ deleteModalData, setDeleteModalData ] = useState<TransactionTag>();
......
...@@ -9,11 +9,11 @@ import type { SubmitHandler, ControllerRenderProps } from 'react-hook-form'; ...@@ -9,11 +9,11 @@ import type { SubmitHandler, ControllerRenderProps } from 'react-hook-form';
import { useForm, Controller } from 'react-hook-form'; import { useForm, Controller } from 'react-hook-form';
import type { TransactionTag, TransactionTagErrors } from 'types/api/account'; import type { TransactionTag, TransactionTagErrors } from 'types/api/account';
import { QueryKeys } from 'types/client/accountQueries';
import type { ResourceErrorAccount } from 'lib/api/resources';
import { resourceKey } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch';
import getErrorMessage from 'lib/getErrorMessage'; import getErrorMessage from 'lib/getErrorMessage';
import type { ErrorType } from 'lib/hooks/useFetch';
import useFetch from 'lib/hooks/useFetch';
import { TRANSACTION_HASH_REGEXP } from 'lib/validations/transaction'; import { TRANSACTION_HASH_REGEXP } from 'lib/validations/transaction';
import TagInput from 'ui/shared/TagInput'; import TagInput from 'ui/shared/TagInput';
import TransactionInput from 'ui/shared/TransactionInput'; import TransactionInput from 'ui/shared/TransactionInput';
...@@ -44,7 +44,7 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => ...@@ -44,7 +44,7 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
}); });
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const fetch = useFetch(); const apiFetch = useApiFetch();
const { mutate } = useMutation((formData: Inputs) => { const { mutate } = useMutation((formData: Inputs) => {
const body = { const body = {
...@@ -54,24 +54,28 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => ...@@ -54,24 +54,28 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
const isEdit = data?.id; const isEdit = data?.id;
if (isEdit) { if (isEdit) {
return fetch(`/node-api/account/private-tags/transaction/${ data.id }`, { method: 'PUT', body }); return apiFetch('private_tags_tx', {
pathParams: { id: data.id },
fetchParams: { method: 'PUT', body },
});
} }
return fetch('/node-api/account/private-tags/transaction', { method: 'POST', body }); return apiFetch('private_tags_tx', { fetchParams: { method: 'POST', body } });
}, { }, {
onError: (e: ErrorType<TransactionTagErrors>) => { onError: (error: ResourceErrorAccount<TransactionTagErrors>) => {
setPending(false); setPending(false);
if (e?.error?.tx_hash || e?.error?.name) { const errorMap = error.payload?.errors;
e?.error?.tx_hash && setError('transaction', { type: 'custom', message: getErrorMessage(e.error, 'tx_hash') }); if (errorMap?.tx_hash || errorMap?.name) {
e?.error?.name && setError('tag', { type: 'custom', message: getErrorMessage(e.error, 'name') }); errorMap?.tx_hash && setError('transaction', { type: 'custom', message: getErrorMessage(errorMap, 'tx_hash') });
} else if (e?.error?.identity_id) { errorMap?.name && setError('tag', { type: 'custom', message: getErrorMessage(errorMap, 'name') });
setError('transaction', { type: 'custom', message: getErrorMessage(e.error, 'identity_id') }); } else if (errorMap?.identity_id) {
setError('transaction', { type: 'custom', message: getErrorMessage(errorMap, 'identity_id') });
} else { } else {
setAlertVisible(true); setAlertVisible(true);
} }
}, },
onSuccess: () => { onSuccess: () => {
queryClient.refetchQueries([ QueryKeys.transactionTags ]).then(() => { queryClient.refetchQueries([ resourceKey('private_tags_tx') ]).then(() => {
onClose(); onClose();
setPending(false); setPending(false);
}); });
......
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