Commit 98dcb80b authored by tom's avatar tom

skeletons for token transfers

parent 172791f3
import type { TokenCounters, TokenHolder, TokenHolders, TokenInfo, TokenInstance, TokenInventoryResponse, TokenType } from 'types/api/token';
import type { TokenTransfer, TokenTransferResponse } from 'types/api/tokenTransfer';
import type { TokenTransfer, TokenTransferPagination, TokenTransferResponse } from 'types/api/tokenTransfer';
import { ADDRESS_PARAMS, ADDRESS_HASH } from './addressParams';
import { BLOCK_HASH } from './block';
......@@ -72,14 +72,14 @@ export const TOKEN_TRANSFER_ERC_1155: TokenTransfer = {
token: TOKEN_INFO_ERC_1155,
};
export const getTokenTransfersStub = (type?: TokenType): TokenTransferResponse => {
export const getTokenTransfersStub = (type?: TokenType, pagination: TokenTransferPagination | null = null): TokenTransferResponse => {
switch (type) {
case 'ERC-721':
return { items: Array(50).fill(TOKEN_TRANSFER_ERC_721), next_page_params: null };
return { items: Array(50).fill(TOKEN_TRANSFER_ERC_721), next_page_params: pagination };
case 'ERC-1155':
return { items: Array(50).fill(TOKEN_TRANSFER_ERC_1155), next_page_params: null };
return { items: Array(50).fill(TOKEN_TRANSFER_ERC_1155), next_page_params: pagination };
default:
return { items: Array(50).fill(TOKEN_TRANSFER_ERC_20), next_page_params: null };
return { items: Array(50).fill(TOKEN_TRANSFER_ERC_20), next_page_params: pagination };
}
};
......
......@@ -20,11 +20,12 @@ import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage';
import TOKEN_TYPE from 'lib/token/tokenTypes';
import { getTokenTransfersStub } from 'stubs/token';
import ActionBar from 'ui/shared/ActionBar';
import DataListDisplay from 'ui/shared/DataListDisplay';
import HashStringShorten from 'ui/shared/HashStringShorten';
import Pagination from 'ui/shared/Pagination';
import SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import * as SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import TokenLogo from 'ui/shared/TokenLogo';
import TokenTransferFilter from 'ui/shared/TokenTransfer/TokenTransferFilter';
import TokenTransferList from 'ui/shared/TokenTransfer/TokenTransferList';
......@@ -81,11 +82,18 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
},
);
const { isError, isLoading, data, pagination, onFilterChange, isPaginationVisible } = useQueryWithPages({
const { isError, isPlaceholderData, data, pagination, onFilterChange, isPaginationVisible } = useQueryWithPages({
resourceName: 'address_token_transfers',
pathParams: { hash: currentAddress },
filters: tokenFilter ? { token: tokenFilter } : filters,
scrollRef,
options: {
placeholderData: getTokenTransfersStub(undefined, {
block_number: 7793535,
index: 46,
items_count: 50,
}),
},
});
const handleTypeFilterChange = React.useCallback((nextValue: Array<TokenType>) => {
......@@ -172,16 +180,17 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
showSocketInfo={ pagination.page === 1 && !tokenFilter }
socketInfoAlert={ socketAlert }
socketInfoNum={ newItemsCount }
isLoading={ isPlaceholderData }
/>
</Hide>
<Show below="lg" ssr={ false }>
{ pagination.page === 1 && !tokenFilter && (
<SocketNewItemsNotice
<SocketNewItemsNotice.Mobile
url={ window.location.href }
num={ newItemsCount }
alert={ socketAlert }
type="token_transfer"
borderBottomRadius={ 0 }
isLoading={ isPlaceholderData }
/>
) }
<TokenTransferList
......@@ -189,6 +198,7 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
baseAddress={ currentAddress }
showTxInfo
enableTimeIncrement
isLoading={ isPlaceholderData }
/>
</Show>
</>
......@@ -221,7 +231,7 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
<>
{ isMobile && tokenFilterComponent }
{ !isActionBarHidden && (
<ActionBar mt={ -6 } showShadow={ isLoading }>
<ActionBar mt={ -6 }>
{ !isMobile && tokenFilterComponent }
{ !tokenFilter && (
<TokenTransferFilter
......@@ -231,9 +241,17 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
withAddressFilter
onAddressFilterChange={ handleAddressFilterChange }
defaultAddressFilter={ filters.filter }
isLoading={ isPlaceholderData }
/>
) }
{ currentAddress && (
<AddressCsvExportLink
address={ currentAddress }
type="token-transfers"
ml={{ base: 2, lg: 'auto' }}
isLoading={ isPlaceholderData }
/>
) }
{ currentAddress && <AddressCsvExportLink address={ currentAddress } type="token-transfers" ml={{ base: 2, lg: 'auto' }}/> }
{ isPaginationVisible && <Pagination ml={{ base: 'auto', lg: 8 }} { ...pagination }/> }
</ActionBar>
) }
......@@ -243,7 +261,7 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
return (
<DataListDisplay
isError={ isError }
isLoading={ isLoading }
isLoading={ false }
items={ data?.items }
skeletonProps={{
isLongSkeleton: true,
......
......@@ -21,7 +21,7 @@ const AdditionalInfoButton = ({ isOpen, onClick, className, isLoading }: Props,
const infoBgColor = useColorModeValue('blue.50', 'gray.600');
if (isLoading) {
return <Skeleton boxSize={ 6 } borderRadius="sm"/>;
return <Skeleton boxSize={ 6 } borderRadius="sm" flexShrink={ 0 }/>;
}
return (
......
......@@ -33,7 +33,7 @@ interface Props {
const TokenLogo = ({ hash, name, className, isLoading }: Props) => {
if (isLoading) {
return <Skeleton className={ className } borderRadius="base"/>;
return <Skeleton className={ className } borderRadius="base" flexShrink={ 0 }/>;
}
const logoSrc = appConfig.network.assetsPathname && hash ? [
......
......@@ -11,13 +11,14 @@ interface Props {
className?: string;
logoSize?: number;
isDisabled?: boolean;
isLoading?: boolean;
}
const TokenSnippet = ({ symbol, hash, name, className, logoSize = 6, isDisabled }: Props) => {
const TokenSnippet = ({ symbol, hash, name, className, logoSize = 6, isDisabled, isLoading }: Props) => {
return (
<Flex className={ className } alignItems="center" columnGap={ 2 } w="100%">
<TokenLogo boxSize={ logoSize } hash={ hash } name={ name }/>
<AddressLink hash={ hash } alias={ name } type="token" isDisabled={ isDisabled }/>
<TokenLogo boxSize={ logoSize } hash={ hash } name={ name } isLoading={ isLoading }/>
<AddressLink hash={ hash } alias={ name } type="token" isDisabled={ isDisabled } isLoading={ isLoading }/>
{ symbol && <Text variant="secondary">({ symbol })</Text> }
</Flex>
);
......
......@@ -19,6 +19,7 @@ interface Props {
withAddressFilter?: boolean;
onAddressFilterChange?: (nextValue: string) => void;
defaultAddressFilter?: AddressFromToFilter;
isLoading?: boolean;
}
const TokenTransferFilter = ({
......@@ -28,10 +29,11 @@ const TokenTransferFilter = ({
withAddressFilter,
onAddressFilterChange,
defaultAddressFilter,
isLoading,
}: Props) => {
return (
<PopoverFilter appliedFiltersNum={ appliedFiltersNum } contentProps={{ w: '200px' }}>
<PopoverFilter appliedFiltersNum={ appliedFiltersNum } contentProps={{ w: '200px' }} isLoading={ isLoading }>
{ withAddressFilter && (
<>
<Text variant="secondary" fontWeight={ 600 }>Address</Text>
......
......@@ -10,18 +10,20 @@ interface Props {
baseAddress?: string;
showTxInfo?: boolean;
enableTimeIncrement?: boolean;
isLoading?: boolean;
}
const TokenTransferList = ({ data, baseAddress, showTxInfo, enableTimeIncrement }: Props) => {
const TokenTransferList = ({ data, baseAddress, showTxInfo, enableTimeIncrement, isLoading }: Props) => {
return (
<Box>
{ data.map((item) => (
{ data.map((item, index) => (
<TokenTransferListItem
key={ item.tx_hash + item.block_hash + item.log_index }
key={ item.tx_hash + item.block_hash + item.log_index + (isLoading ? index : '') }
{ ...item }
baseAddress={ baseAddress }
showTxInfo={ showTxInfo }
enableTimeIncrement={ enableTimeIncrement }
isLoading={ isLoading }
/>
)) }
</Box>
......
import { Text, Flex, Tag, Icon } from '@chakra-ui/react';
import { Flex, Icon, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -10,6 +10,8 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import Tag from 'ui/shared/chakra/Tag';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import InOutTag from 'ui/shared/InOutTag';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TokenSnippet from 'ui/shared/TokenSnippet/TokenSnippet';
......@@ -17,12 +19,11 @@ import { getTokenTransferTypeText } from 'ui/shared/TokenTransfer/helpers';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
import CopyToClipboard from '../CopyToClipboard';
type Props = TokenTransfer & {
baseAddress?: string;
showTxInfo?: boolean;
enableTimeIncrement?: boolean;
isLoading?: boolean;
}
const TokenTransferListItem = ({
......@@ -36,6 +37,7 @@ const TokenTransferListItem = ({
type,
timestamp,
enableTimeIncrement,
isLoading,
}: Props) => {
const value = (() => {
if (!('value' in total)) {
......@@ -51,57 +53,63 @@ const TokenTransferListItem = ({
return (
<ListItemMobile rowGap={ 3 } isAnimated>
<Flex w="100%" justifyContent="space-between">
<Flex flexWrap="wrap" rowGap={ 1 } mr={ showTxInfo && txHash ? 2 : 0 }>
<TokenSnippet hash={ token.address } w="auto" maxW="calc(100% - 140px)" name={ token.name || 'Unnamed token' }/>
<Tag flexShrink={ 0 } ml={ 2 } mr={ 2 }>{ token.type }</Tag>
<Tag colorScheme="orange">{ getTokenTransferTypeText(type) }</Tag>
<Flex flexWrap="wrap" rowGap={ 1 } mr={ showTxInfo && txHash ? 2 : 0 } columnGap={ 2 }>
<TokenSnippet hash={ token.address } w="auto" maxW="calc(100% - 140px)" name={ token.name || 'Unnamed token' } isLoading={ isLoading }/>
<Tag flexShrink={ 0 } isLoading={ isLoading }>{ token.type }</Tag>
<Tag colorScheme="orange" isLoading={ isLoading }>{ getTokenTransferTypeText(type) }</Tag>
</Flex>
{ showTxInfo && txHash && (
<TxAdditionalInfo hash={ txHash } isMobile/>
<TxAdditionalInfo hash={ txHash } isMobile isLoading={ isLoading }/>
) }
</Flex>
{ 'token_id' in total && <TokenTransferNft hash={ token.address } id={ total.token_id }/> }
{ 'token_id' in total && <TokenTransferNft hash={ token.address } id={ total.token_id } isLoading={ isLoading }/> }
{ showTxInfo && txHash && (
<Flex justifyContent="space-between" alignItems="center" lineHeight="24px" width="100%">
<Flex>
<Icon
as={ transactionIcon }
boxSize="30px"
mr={ 2 }
color="link"
/>
<Skeleton isLoaded={ !isLoading } boxSize="30px" mr={ 2 } borderRadius="base">
<Icon
as={ transactionIcon }
boxSize="30px"
color="link"
/>
</Skeleton>
<Address width="100%">
<AddressLink
hash={ txHash }
type="transaction"
fontWeight="700"
truncation="constant"
isLoading={ isLoading }
/>
</Address>
</Flex>
{ timestamp && <Text variant="secondary" fontWeight="400" fontSize="sm">{ timeAgo }</Text> }
{ timestamp && (
<Skeleton isLoaded={ !isLoading } color="text_secondary" fontWeight="400" fontSize="sm">
<span>{ timeAgo }</span>
</Skeleton>
) }
</Flex>
) }
<Flex w="100%" columnGap={ 3 }>
<Address width={ addressWidth }>
<AddressIcon address={ from }/>
<AddressLink type="address" ml={ 2 } fontWeight="500" hash={ from.hash } isDisabled={ baseAddress === from.hash }/>
{ baseAddress !== from.hash && <CopyToClipboard text={ from.hash }/> }
<AddressIcon address={ from } isLoading={ isLoading }/>
<AddressLink type="address" ml={ 2 } fontWeight="500" hash={ from.hash } isDisabled={ baseAddress === from.hash } isLoading={ isLoading }/>
{ baseAddress !== from.hash && <CopyToClipboard text={ from.hash } isLoading={ isLoading }/> }
</Address>
{ baseAddress ?
<InOutTag isIn={ baseAddress === to.hash } isOut={ baseAddress === from.hash } w="50px" textAlign="center"/> :
<Icon as={ eastArrowIcon } boxSize={ 6 } color="gray.500"/>
<InOutTag isIn={ baseAddress === to.hash } isOut={ baseAddress === from.hash } w="50px" textAlign="center" isLoading={ isLoading }/> :
<Skeleton isLoaded={ !isLoading } boxSize={ 6 }><Icon as={ eastArrowIcon } boxSize={ 6 } color="gray.500"/></Skeleton>
}
<Address width={ addressWidth }>
<AddressIcon address={ to }/>
<AddressLink type="address" ml={ 2 } fontWeight="500" hash={ to.hash } isDisabled={ baseAddress === to.hash }/>
{ baseAddress !== to.hash && <CopyToClipboard text={ to.hash }/> }
<AddressIcon address={ to } isLoading={ isLoading }/>
<AddressLink type="address" ml={ 2 } fontWeight="500" hash={ to.hash } isDisabled={ baseAddress === to.hash } isLoading={ isLoading }/>
{ baseAddress !== to.hash && <CopyToClipboard text={ to.hash } isLoading={ isLoading }/> }
</Address>
</Flex>
{ value && (
<Flex columnGap={ 2 } w="100%">
<Text fontWeight={ 500 } flexShrink={ 0 }>Value</Text>
<Text variant="secondary">{ value }</Text>
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 } flexShrink={ 0 }>Value</Skeleton>
<Skeleton isLoaded={ !isLoading } color="text_secondary"><span>{ value }</span></Skeleton>
</Flex>
) }
</ListItemMobile>
......
import { Table, Tbody, Tr, Th, Td } from '@chakra-ui/react';
import { Table, Tbody, Tr, Th } from '@chakra-ui/react';
import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer';
import SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import * as SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import { default as Thead } from 'ui/shared/TheadSticky';
import TokenTransferTableItem from 'ui/shared/TokenTransfer/TokenTransferTableItem';
......@@ -16,6 +16,7 @@ interface Props {
showSocketInfo?: boolean;
socketInfoAlert?: string;
socketInfoNum?: number;
isLoading?: boolean;
}
const TokenTransferTable = ({
......@@ -27,6 +28,7 @@ const TokenTransferTable = ({
showSocketInfo,
socketInfoAlert,
socketInfoNum,
isLoading,
}: Props) => {
return (
......@@ -45,26 +47,22 @@ const TokenTransferTable = ({
</Thead>
<Tbody>
{ showSocketInfo && (
<Tr>
<Td colSpan={ 10 } p={ 0 }>
<SocketNewItemsNotice
borderRadius={ 0 }
pl="10px"
url={ window.location.href }
alert={ socketInfoAlert }
num={ socketInfoNum }
type="token_transfer"
/>
</Td>
</Tr>
<SocketNewItemsNotice.Desktop
url={ window.location.href }
alert={ socketInfoAlert }
num={ socketInfoNum }
type="token_transfer"
isLoading={ isLoading }
/>
) }
{ data.map((item) => (
{ data.map((item, index) => (
<TokenTransferTableItem
key={ item.tx_hash + item.block_hash + item.log_index }
key={ item.tx_hash + item.block_hash + item.log_index + (isLoading ? index : '') }
{ ...item }
baseAddress={ baseAddress }
showTxInfo={ showTxInfo }
enableTimeIncrement={ enableTimeIncrement }
isLoading={ isLoading }
/>
)) }
</Tbody>
......
import { Tr, Td, Tag, Flex, Text } from '@chakra-ui/react';
import { Tr, Td, Flex, Skeleton, Box } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -8,18 +8,19 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import Tag from 'ui/shared/chakra/Tag';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import InOutTag from 'ui/shared/InOutTag';
import TokenSnippet from 'ui/shared/TokenSnippet/TokenSnippet';
import { getTokenTransferTypeText } from 'ui/shared/TokenTransfer/helpers';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
import CopyToClipboard from '../CopyToClipboard';
type Props = TokenTransfer & {
baseAddress?: string;
showTxInfo?: boolean;
enableTimeIncrement?: boolean;
isLoading?: boolean;
}
const TokenTransferTableItem = ({
......@@ -33,6 +34,7 @@ const TokenTransferTableItem = ({
type,
timestamp,
enableTimeIncrement,
isLoading,
}: Props) => {
const timeAgo = useTimeAgoIncrement(timestamp, enableTimeIncrement);
......@@ -40,48 +42,81 @@ const TokenTransferTableItem = ({
<Tr alignItems="top">
{ showTxInfo && txHash && (
<Td>
<TxAdditionalInfo hash={ txHash }/>
<Box my="3px">
<TxAdditionalInfo hash={ txHash } isLoading={ isLoading }/>
</Box>
</Td>
) }
<Td>
<Flex flexDir="column" alignItems="flex-start">
<TokenSnippet hash={ token.address } name={ token.name || 'Unnamed token' } lineHeight="30px"/>
<Tag mt={ 1 }>{ token.type }</Tag>
<Tag colorScheme="orange" mt={ 2 }>{ getTokenTransferTypeText(type) }</Tag>
<Flex flexDir="column" alignItems="flex-start" my="3px" rowGap={ 2 }>
<TokenSnippet hash={ token.address } name={ token.name || 'Unnamed token' } isLoading={ isLoading }/>
<Tag isLoading={ isLoading }>{ token.type }</Tag>
<Tag colorScheme="orange" isLoading={ isLoading }>{ getTokenTransferTypeText(type) }</Tag>
</Flex>
</Td>
<Td lineHeight="30px">
{ 'token_id' in total && <TokenTransferNft hash={ token.address } id={ total.token_id }/> }
<Td>
{ 'token_id' in total && <TokenTransferNft hash={ token.address } id={ total.token_id } isLoading={ isLoading }/> }
</Td>
{ showTxInfo && txHash && (
<Td>
<Address display="inline-flex" maxW="100%" fontWeight={ 600 } lineHeight="30px">
<AddressLink type="transaction" hash={ txHash }/>
<Address display="inline-flex" maxW="100%" fontWeight={ 600 } mt="7px">
<AddressLink type="transaction" hash={ txHash } isLoading={ isLoading }/>
</Address>
{ timestamp && <Text color="gray.500" fontWeight="400" mt="10px">{ timeAgo }</Text> }
{ timestamp && (
<Skeleton isLoaded={ !isLoading } color="text_secondary" fontWeight="400" mt="10px" display="inline-block">
<span>{ timeAgo }</span>
</Skeleton>
) }
</Td>
) }
<Td>
<Address display="inline-flex" maxW="100%" lineHeight="30px">
<AddressIcon address={ from }/>
<AddressLink type="address" ml={ 2 } fontWeight="500" hash={ from.hash } alias={ from.name } flexGrow={ 1 } isDisabled={ baseAddress === from.hash }/>
{ baseAddress !== from.hash && <CopyToClipboard text={ from.hash }/> }
<Address display="inline-flex" maxW="100%" my="3px">
<AddressIcon address={ from } isLoading={ isLoading }/>
<AddressLink
type="address" ml={ 2 }
fontWeight="500"
hash={ from.hash }
alias={ from.name }
flexGrow={ 1 }
isDisabled={ baseAddress === from.hash }
isLoading={ isLoading }
/>
{ baseAddress !== from.hash && <CopyToClipboard text={ from.hash } isLoading={ isLoading }/> }
</Address>
</Td>
{ baseAddress && (
<Td px={ 0 }>
<InOutTag isIn={ baseAddress === to.hash } isOut={ baseAddress === from.hash } w="50px" textAlign="center" mt="3px"/>
<Box mt="3px">
<InOutTag
isIn={ baseAddress === to.hash }
isOut={ baseAddress === from.hash }
w="50px"
textAlign="center"
isLoading={ isLoading }
/>
</Box>
</Td>
) }
<Td>
<Address display="inline-flex" maxW="100%" lineHeight="30px">
<AddressIcon address={ to }/>
<AddressLink type="address" ml={ 2 } fontWeight="500" hash={ to.hash } alias={ to.name } flexGrow={ 1 } isDisabled={ baseAddress === to.hash }/>
{ baseAddress !== to.hash && <CopyToClipboard text={ to.hash }/> }
<Address display="inline-flex" maxW="100%" my="3px">
<AddressIcon address={ to } isLoading={ isLoading }/>
<AddressLink
type="address"
ml={ 2 }
fontWeight="500"
hash={ to.hash }
alias={ to.name }
flexGrow={ 1 }
isDisabled={ baseAddress === to.hash }
isLoading={ isLoading }
/>
{ baseAddress !== to.hash && <CopyToClipboard text={ to.hash } isLoading={ isLoading }/> }
</Address>
</Td>
<Td isNumeric verticalAlign="top" lineHeight="30px">
{ 'value' in total && BigNumber(total.value).div(BigNumber(10 ** Number(total.decimals))).dp(8).toFormat() }
<Td isNumeric verticalAlign="top">
<Skeleton isLoaded={ !isLoading } display="inline-block" my="7px">
{ 'value' in total && BigNumber(total.value).div(BigNumber(10 ** Number(total.decimals))).dp(8).toFormat() }
</Skeleton>
</Td>
</Tr>
);
......
......@@ -15,9 +15,10 @@ interface Props {
isActive?: boolean;
children: React.ReactNode;
contentProps?: PopoverContentProps;
isLoading?: boolean;
}
const PopoverFilter = ({ appliedFiltersNum, children, contentProps, isActive }: Props) => {
const PopoverFilter = ({ appliedFiltersNum, children, contentProps, isActive, isLoading }: Props) => {
const { isOpen, onToggle, onClose } = useDisclosure();
return (
......@@ -27,6 +28,7 @@ const PopoverFilter = ({ appliedFiltersNum, children, contentProps, isActive }:
isActive={ isOpen || isActive || Number(appliedFiltersNum) > 0 }
onClick={ onToggle }
appliedFiltersNum={ appliedFiltersNum }
isLoading={ isLoading }
/>
</PopoverTrigger>
<PopoverContent { ...contentProps }>
......
......@@ -9,6 +9,7 @@ import getFilterValuesFromQuery from 'lib/getFilterValuesFromQuery';
import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import { apos } from 'lib/html-entities';
import TOKEN_TYPE from 'lib/token/tokenTypes';
import { getTokenTransfersStub } from 'stubs/token';
import ActionBar from 'ui/shared/ActionBar';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import DataListDisplay from 'ui/shared/DataListDisplay';
......@@ -34,7 +35,10 @@ const TxTokenTransfer = () => {
const tokenTransferQuery = useQueryWithPages({
resourceName: 'tx_token_transfers',
pathParams: { hash: txsInfo.data?.hash.toString() },
options: { enabled: Boolean(txsInfo.data?.status && txsInfo.data?.hash) },
options: {
enabled: !txsInfo.isPlaceholderData && Boolean(txsInfo.data?.status && txsInfo.data?.hash),
placeholderData: getTokenTransfersStub(),
},
filters: { type: typeFilter },
});
......@@ -43,7 +47,7 @@ const TxTokenTransfer = () => {
setTypeFilter(nextValue);
}, [ tokenTransferQuery ]);
if (!txsInfo.isLoading && !txsInfo.isError && !txsInfo.data.status) {
if (!txsInfo.isLoading && !txsInfo.isPlaceholderData && !txsInfo.isError && !txsInfo.data.status) {
return txsInfo.socketStatus ? <TxSocketAlert status={ txsInfo.socketStatus }/> : <TxPendingAlert/>;
}
......@@ -57,10 +61,10 @@ const TxTokenTransfer = () => {
const content = tokenTransferQuery.data?.items ? (
<>
<Hide below="lg" ssr={ false }>
<TokenTransferTable data={ tokenTransferQuery.data?.items } top={ isActionBarHidden ? 0 : 80 }/>
<TokenTransferTable data={ tokenTransferQuery.data?.items } top={ isActionBarHidden ? 0 : 80 } isLoading={ tokenTransferQuery.isPlaceholderData }/>
</Hide>
<Show below="lg" ssr={ false }>
<TokenTransferList data={ tokenTransferQuery.data?.items }/>
<TokenTransferList data={ tokenTransferQuery.data?.items } isLoading={ tokenTransferQuery.isPlaceholderData }/>
</Show>
</>
) : null;
......@@ -71,6 +75,7 @@ const TxTokenTransfer = () => {
defaultTypeFilters={ typeFilter }
onTypeFilterChange={ handleTypeFilterChange }
appliedFiltersNum={ numActiveFilters }
isLoading={ tokenTransferQuery.isPlaceholderData }
/>
{ tokenTransferQuery.isPaginationVisible && <Pagination ml="auto" { ...tokenTransferQuery.pagination }/> }
</ActionBar>
......@@ -79,7 +84,7 @@ const TxTokenTransfer = () => {
return (
<DataListDisplay
isError={ txsInfo.isError || tokenTransferQuery.isError }
isLoading={ txsInfo.isLoading || tokenTransferQuery.isLoading }
isLoading={ false }
items={ tokenTransferQuery.data?.items }
skeletonProps={{
isLongSkeleton: true,
......
......@@ -15,7 +15,7 @@ import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TxStatus from 'ui/shared/TxStatus';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
type Props = InternalTransaction & { isLoading: boolean };
type Props = InternalTransaction & { isLoading?: boolean };
const TxInternalsListItem = ({ type, from, to, value, success, error, gas_limit: gasLimit, created_contract: createdContract, isLoading }: Props) => {
const typeTitle = TX_INTERNALS_ITEMS.find(({ id }) => id === type)?.title;
......
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