Commit 741e498f authored by tom's avatar tom

pagination and tx info hide

parent 78a95507
import type { UseQueryOptions } from '@tanstack/react-query';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { pick, omit } from 'lodash';
import { useRouter } from 'next/router';
......@@ -17,11 +18,15 @@ interface ResponseWithPagination {
next_page_params: PaginationParams | null;
}
export default function useQueryWithPages<Response extends ResponseWithPagination>(
apiPath: string,
queryName: QueryKeys,
filters?: TTxsFilters | BlockFilters,
) {
interface Params<Response> {
apiPath: string;
queryName: QueryKeys;
queryIds?: Array<string>;
filters?: TTxsFilters | BlockFilters;
options?: Omit<UseQueryOptions<unknown, unknown, Response>, 'queryKey' | 'queryFn'>;
}
export default function useQueryWithPages<Response extends ResponseWithPagination>({ queryName, filters, options, apiPath, queryIds }: Params<Response>) {
const queryClient = useQueryClient();
const router = useRouter();
const [ page, setPage ] = React.useState(1);
......@@ -30,7 +35,7 @@ export default function useQueryWithPages<Response extends ResponseWithPaginatio
const fetch = useFetch();
const queryResult = useQuery<unknown, unknown, Response>(
[ queryName, { page, filters } ],
[ queryName, ...(queryIds || []), { page, filters } ],
async() => {
const params: Array<string> = [];
......@@ -44,7 +49,7 @@ export default function useQueryWithPages<Response extends ResponseWithPaginatio
return fetch(`${ apiPath }${ params.length ? '?' + params.join('&') : '' }`);
},
{ staleTime: Infinity },
{ staleTime: Infinity, ...options },
);
const { data } = queryResult;
......
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/transactions/${ req.query.id }/token-transfers`;
const searchParamsStr = getSearchParams(req);
return `/v2/transactions/${ req.query.id }/token-transfers${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
......
......@@ -25,7 +25,11 @@ const BlocksContent = ({ type }: Props) => {
const queryClient = useQueryClient();
const [ socketAlert, setSocketAlert ] = React.useState('');
const { data, isLoading, isError, pagination } = useQueryWithPages<BlocksResponse>('/node-api/blocks', QueryKeys.blocks, { type });
const { data, isLoading, isError, pagination } = useQueryWithPages<BlocksResponse>({
apiPath: '/node-api/blocks',
queryName: QueryKeys.blocks,
filters: { type },
});
const handleNewBlockMessage: SocketMessage.NewBlock['handler'] = React.useCallback((payload) => {
queryClient.setQueryData([ QueryKeys.blocks, { page: pagination.page, filters: { type } } ], (prevData: BlocksResponse | undefined) => {
......
import { Alert, Hide, Show } from '@chakra-ui/react';
import type { QueryKey } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
import { Hide, Show, Text } from '@chakra-ui/react';
import React from 'react';
import type { TokenTransferResponse } from 'types/api/tokenTransfer';
import type { QueryKeys } from 'types/client/queries';
import useFetch from 'lib/hooks/useFetch';
import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import ActionBar from 'ui/shared/ActionBar';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import Pagination from 'ui/shared/Pagination';
import SkeletonTable from 'ui/shared/SkeletonTable';
import { flattenTotal } from 'ui/shared/TokenTransfer/helpers';
import TokenTransferList from 'ui/shared/TokenTransfer/TokenTransferList';
......@@ -17,28 +18,32 @@ interface Props {
isLoading?: boolean;
isDisabled?: boolean;
path: string;
queryKey: QueryKey;
queryName: QueryKeys;
queryIds?: Array<string>;
baseAddress?: string;
showTxInfo?: boolean;
}
const TokenTransfer = ({ isLoading: isLoadingProp, isDisabled, queryKey, path, baseAddress }: Props) => {
const fetch = useFetch();
const { isError, isLoading, data } = useQuery<unknown, unknown, TokenTransferResponse>(
queryKey,
async() => await fetch(path),
{
enabled: !isDisabled,
},
);
const TokenTransfer = ({ isLoading: isLoadingProp, isDisabled, queryName, queryIds, path, baseAddress, showTxInfo = true }: Props) => {
const { isError, isLoading, data, pagination } = useQueryWithPages<TokenTransferResponse>({
apiPath: path,
queryName,
queryIds,
options: { enabled: !isDisabled },
});
const content = (() => {
if (isLoading || isLoadingProp) {
return (
<>
<Hide below="lg">
<SkeletonTable columns={ [ '44px', '185px', '160px', '25%', '25%', '25%', '25%' ] }/>
<SkeletonTable columns={ showTxInfo ?
[ '44px', '185px', '160px', '25%', '25%', '25%', '25%' ] :
[ '185px', '25%', '25%', '25%', '25%' ] }
/>
</Hide>
<Show below="lg">
<TokenTransferSkeletonMobile/>
<TokenTransferSkeletonMobile showTxInfo={ showTxInfo }/>
</Show>
</>
);
......@@ -49,21 +54,30 @@ const TokenTransfer = ({ isLoading: isLoadingProp, isDisabled, queryKey, path, b
}
if (!data.items?.length) {
return <Alert>There are no token transfers</Alert>;
return <Text as="span">There are no token transfers</Text>;
}
const items = data.items.reduce(flattenTotal, []);
return (
<>
<Hide below="lg">
<TokenTransferTable data={ items } baseAddress={ baseAddress }/>
<TokenTransferTable data={ items } baseAddress={ baseAddress } showTxInfo={ showTxInfo }/>
</Hide>
<Show below="lg">
<TokenTransferList data={ items } baseAddress={ baseAddress }/>
<TokenTransferList data={ items } baseAddress={ baseAddress } showTxInfo={ showTxInfo }/>
</Show>
</>
);
})();
return (
<>
<ActionBar>
<Pagination ml="auto" { ...pagination }/>
</ActionBar>
{ content }
</>
);
};
export default React.memo(TokenTransfer);
......@@ -8,12 +8,13 @@ import TokenTransferListItem from 'ui/shared/TokenTransfer/TokenTransferListItem
interface Props {
data: Array<TokenTransfer>;
baseAddress?: string;
showTxInfo?: boolean;
}
const TokenTransferList = ({ data, baseAddress }: Props) => {
const TokenTransferList = ({ data, baseAddress, showTxInfo }: Props) => {
return (
<Box>
{ data.map((item, index) => <TokenTransferListItem key={ index } { ...item } baseAddress={ baseAddress }/>) }
{ data.map((item, index) => <TokenTransferListItem key={ index } { ...item } baseAddress={ baseAddress } showTxInfo={ showTxInfo }/>) }
</Box>
);
};
......
......@@ -16,9 +16,10 @@ import TokenSnippet from 'ui/shared/TokenSnippet';
type Props = TokenTransfer & {
baseAddress?: string;
showTxInfo?: boolean;
}
const TokenTransferListItem = ({ token, total, tx_hash: txHash, from, to, baseAddress }: Props) => {
const TokenTransferListItem = ({ token, total, tx_hash: txHash, from, to, baseAddress, showTxInfo }: Props) => {
const value = (() => {
if (!('value' in total)) {
return null;
......@@ -33,7 +34,7 @@ const TokenTransferListItem = ({ token, total, tx_hash: txHash, from, to, baseAd
<Flex w="100%">
<TokenSnippet hash={ token.address } w="auto" maxW="calc(100% - 140px)" name={ token.name || 'Unnamed token' }/>
<Tag flexShrink={ 0 } ml={ 2 } mr="auto">{ token.type }</Tag>
<AdditionalInfoButton/>
{ showTxInfo && <AdditionalInfoButton/> }
</Flex>
{ 'token_id' in total && (
<Flex alignItems="center">
......@@ -42,12 +43,14 @@ const TokenTransferListItem = ({ token, total, tx_hash: txHash, from, to, baseAd
<AddressLink hash={ token.address } id={ total.token_id } type="token_instance_item"/>
</Flex>
) }
{ showTxInfo && (
<Flex columnGap={ 2 } w="100%">
<Text fontWeight={ 500 } flexShrink={ 0 }>Txn hash</Text>
<Address display="inline-flex" maxW="100%">
<AddressLink type="transaction" hash={ txHash }/>
</Address>
</Flex>
) }
<Flex w="100%" columnGap={ 3 }>
<Address width={ addressWidth }>
<AddressIcon hash={ from.hash }/>
......
import { Skeleton, SkeletonCircle, Flex, Box, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
const TokenTransferSkeletonMobile = () => {
const TokenTransferSkeletonMobile = ({ showTxInfo }: { showTxInfo?: boolean }) => {
const borderColor = useColorModeValue('blackAlpha.200', 'whiteAlpha.200');
return (
......@@ -22,17 +22,19 @@ const TokenTransferSkeletonMobile = () => {
<SkeletonCircle size="6" mr={ 2 } flexShrink={ 0 }/>
<Skeleton w="100px" mr={ 2 }/>
<Skeleton w="50px"/>
<Skeleton w="24px" ml="auto"/>
{ showTxInfo && <Skeleton w="24px" ml="auto"/> }
</Flex>
<Flex h={ 6 } columnGap={ 2 }>
<Skeleton w="70px"/>
<Skeleton w="24px"/>
<Skeleton w="90px"/>
</Flex>
{ showTxInfo && (
<Flex h={ 6 } columnGap={ 2 }>
<Skeleton w="70px" flexShrink={ 0 }/>
<Skeleton w="100%"/>
</Flex>
) }
<Flex h={ 6 }>
<SkeletonCircle size="6" mr={ 2 } flexShrink={ 0 }/>
<Skeleton flexGrow={ 1 } mr={ 3 }/>
......
......@@ -9,27 +9,28 @@ import TokenTransferTableItem from 'ui/shared/TokenTransfer/TokenTransferTableIt
interface Props {
data: Array<TokenTransfer>;
baseAddress?: string;
showTxInfo?: boolean;
}
const TxInternalsTable = ({ data, baseAddress }: Props) => {
const TxInternalsTable = ({ data, baseAddress, showTxInfo }: Props) => {
return (
<Table variant="simple" size="sm" mt={ 6 }>
<Thead top={ 0 }>
<Table variant="simple" size="sm">
<Thead top={ 80 }>
<Tr>
<Th width="44px"></Th>
{ showTxInfo && <Th width="44px"></Th> }
<Th width="185px">Token</Th>
<Th width="160px">Token ID</Th>
<Th width="25%">Txn hash</Th>
{ showTxInfo && <Th width="25%">Txn hash</Th> }
<Th width="25%">From</Th>
{ baseAddress && <Th width="50px" px={ 0 }/> }
<Th width="25%">To</Th>
<Th width="25%">Value</Th>
<Th width="25%" isNumeric>Value</Th>
</Tr>
</Thead>
<Tbody>
{ data.map((item, index) => (
<TokenTransferTableItem key={ index } { ...item } baseAddress={ baseAddress }/>
<TokenTransferTableItem key={ index } { ...item } baseAddress={ baseAddress } showTxInfo={ showTxInfo }/>
)) }
</Tbody>
</Table>
......
......@@ -14,9 +14,10 @@ import TokenSnippet from 'ui/shared/TokenSnippet';
type Props = TokenTransfer & {
baseAddress?: string;
showTxInfo?: boolean;
}
const TxInternalTableItem = ({ token, total, tx_hash: txHash, from, to, baseAddress }: Props) => {
const TxInternalTableItem = ({ token, total, tx_hash: txHash, from, to, baseAddress, showTxInfo }: Props) => {
const value = (() => {
if (!('value' in total)) {
return '-';
......@@ -27,9 +28,11 @@ const TxInternalTableItem = ({ token, total, tx_hash: txHash, from, to, baseAddr
return (
<Tr alignItems="top">
{ showTxInfo && (
<Td>
<AdditionalInfoButton/>
</Td>
) }
<Td>
<Flex flexDir="column" alignItems="flex-start">
<TokenSnippet hash={ token.address } name={ token.name || 'Unnamed token' } lineHeight="30px"/>
......@@ -44,11 +47,13 @@ const TxInternalTableItem = ({ token, total, tx_hash: txHash, from, to, baseAddr
</Flex>
) : '-' }
</Td>
{ showTxInfo && (
<Td>
<Address display="inline-flex" maxW="100%" fontWeight={ 600 } lineHeight="30px">
<AddressLink type="transaction" hash={ txHash }/>
</Address>
</Td>
) }
<Td>
<Address display="inline-flex" maxW="100%" lineHeight="30px">
<AddressIcon hash={ from.hash }/>
......
import { Text } from '@chakra-ui/react';
import React from 'react';
import { QueryKeys } from 'types/client/queries';
......@@ -20,17 +21,20 @@ const TxTokenTransfer = () => {
return <DataFetchAlert/>;
}
const queryKey = [ QueryKeys.txTokenTransfers, data?.hash ];
const path = `/node-api/transactions/${ data?.hash }/token-transfers`;
return (
<>
<Text>Token transfers for transaction { data?.hash }</Text>
<TokenTransfer
isLoading={ isLoading }
isDisabled={ !data?.status || !data?.hash }
path={ path }
queryKey={ queryKey }
// todo_tom delete me
baseAddress="0xd789a607CEac2f0E14867de4EB15b15C9FFB5859"/>
queryName={ QueryKeys.txTokenTransfers }
queryIds={ data?.hash ? [ data.hash ] : undefined }
showTxInfo={ false }
/>
</>
);
};
......
......@@ -62,7 +62,11 @@ const TxsContent = ({
isLoading,
isError,
pagination,
} = useQueryWithPages<TransactionsResponse>(apiPath, queryName, stateFilter && { filter: stateFilter });
} = useQueryWithPages<TransactionsResponse>({
apiPath,
queryName,
filters: stateFilter ? { filter: stateFilter } : undefined,
});
// } = useQueryWithPages({ ...filters, filter: stateFilter, apiPath });
const content = (() => {
......
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