Commit ffc87f4d authored by tom's avatar tom

state, blobs and user ops tabs

parent 7f55da68
...@@ -14,6 +14,10 @@ interface Props extends LinkProps { ...@@ -14,6 +14,10 @@ interface Props extends LinkProps {
const ID = 'CutLink'; const ID = 'CutLink';
// TODO @tom2drum another variant of CutLink
// ui/tx/TxAllowedPeekers.tsx
// ui/tx/state/TxStateTokenIdList.tsx
const CutLink = (props: Props) => { const CutLink = (props: Props) => {
const { children, id = ID, onClick, isExpanded: isExpandedProp = false, ...rest } = props; const { children, id = ID, onClick, isExpanded: isExpandedProp = false, ...rest } = props;
......
...@@ -59,16 +59,16 @@ const TransactionPageContent = () => { ...@@ -59,16 +59,16 @@ const TransactionPageContent = () => {
// { id: 'wrapped', title: 'Regular tx details', component: <TxDetailsWrapped data={ data.wrapped }/> } : // { id: 'wrapped', title: 'Regular tx details', component: <TxDetailsWrapped data={ data.wrapped }/> } :
// undefined, // undefined,
{ id: 'token_transfers', title: 'Token transfers', component: <TxTokenTransfer txQuery={ txQuery }/> }, { id: 'token_transfers', title: 'Token transfers', component: <TxTokenTransfer txQuery={ txQuery }/> },
// config.features.userOps.isEnabled ? config.features.userOps.isEnabled ?
// { id: 'user_ops', title: 'User operations', component: <TxUserOps txQuery={ txQuery }/> } : { id: 'user_ops', title: 'User operations', component: <TxUserOps txQuery={ txQuery }/> } :
// undefined, undefined,
{ id: 'internal', title: 'Internal txns', component: <TxInternals txQuery={ txQuery }/> }, { id: 'internal', title: 'Internal txns', component: <TxInternals txQuery={ txQuery }/> },
// config.features.dataAvailability.isEnabled && txQuery.data?.blob_versioned_hashes?.length ? config.features.dataAvailability.isEnabled && txQuery.data?.blob_versioned_hashes?.length ?
// { id: 'blobs', title: 'Blobs', component: <TxBlobs txQuery={ txQuery }/> } : { id: 'blobs', title: 'Blobs', component: <TxBlobs txQuery={ txQuery }/> } :
// undefined, undefined,
{ id: 'logs', title: 'Logs', component: <TxLogs txQuery={ txQuery }/> }, { id: 'logs', title: 'Logs', component: <TxLogs txQuery={ txQuery }/> },
// { id: 'state', title: 'State', component: <TxState txQuery={ txQuery }/> }, { id: 'state', title: 'State', component: <TxState txQuery={ txQuery }/> },
// { id: 'raw_trace', title: 'Raw trace', component: <TxRawTrace txQuery={ txQuery }/> }, { id: 'raw_trace', title: 'Raw trace', component: <TxRawTrace txQuery={ txQuery }/> },
].filter(Boolean); ].filter(Boolean);
})(); })();
......
import { Flex, useColorModeValue } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import * as blobUtils from 'lib/blob'; import * as blobUtils from 'lib/blob';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import type { IconName } from 'ui/shared/IconSvg'; import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
interface Props { interface Props {
data: string; data: string;
isLoading?: boolean; isLoading?: boolean;
...@@ -18,8 +17,6 @@ const TYPES: Record<string, { iconName: IconName; label: string }> = { ...@@ -18,8 +17,6 @@ const TYPES: Record<string, { iconName: IconName; label: string }> = {
}; };
const BlobDataType = ({ data, isLoading }: Props) => { const BlobDataType = ({ data, isLoading }: Props) => {
const iconColor = useColorModeValue('gray.500', 'gray.400');
const guessedType = React.useMemo(() => { const guessedType = React.useMemo(() => {
if (isLoading) { if (isLoading) {
return; return;
...@@ -48,8 +45,8 @@ const BlobDataType = ({ data, isLoading }: Props) => { ...@@ -48,8 +45,8 @@ const BlobDataType = ({ data, isLoading }: Props) => {
return ( return (
<Flex alignItems="center" columnGap={ 2 }> <Flex alignItems="center" columnGap={ 2 }>
<IconSvg name={ iconName } boxSize={ 5 } color={ iconColor } isLoading={ isLoading }/> <IconSvg name={ iconName } boxSize={ 5 } color={{ _light: 'gray.500', _dark: 'gray.400' }} isLoading={ isLoading }/>
<Skeleton isLoaded={ !isLoading }>{ label }</Skeleton> <Skeleton loading={ isLoading }>{ label }</Skeleton>
</Flex> </Flex>
); );
}; };
......
import React from 'react'; import React from 'react';
import Skeleton from 'ui/shared/chakra/Skeleton';
import StatusTag from 'ui/shared/statusTag/StatusTag'; import StatusTag from 'ui/shared/statusTag/StatusTag';
type Props = { type Props = {
...@@ -14,9 +13,7 @@ const UserOpStatus = ({ status, isLoading }: Props) => { ...@@ -14,9 +13,7 @@ const UserOpStatus = ({ status, isLoading }: Props) => {
} }
return ( return (
<Skeleton isLoaded={ !isLoading } display="inline-block"> <StatusTag isLoading={ isLoading } type={ status === true ? 'ok' : 'error' } text={ status === true ? 'Success' : 'Failed' }/>
<StatusTag type={ status === true ? 'ok' : 'error' } text={ status === true ? 'Success' : 'Failed' }/>
</Skeleton>
); );
}; };
......
...@@ -11,7 +11,6 @@ interface Props { ...@@ -11,7 +11,6 @@ interface Props {
const CUT_LENGTH = 2; const CUT_LENGTH = 2;
// TODO @tom2drum another variant of CutLink
const TxAllowedPeekers = ({ items }: Props) => { const TxAllowedPeekers = ({ items }: Props) => {
const [ isExpanded, setIsExpanded ] = React.useState(false); const [ isExpanded, setIsExpanded ] = React.useState(false);
......
import { Hide, Show } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { TX_BLOB } from 'stubs/blobs'; import { TX_BLOB } from 'stubs/blobs';
...@@ -34,12 +34,12 @@ const TxBlobs = ({ txQuery }: Props) => { ...@@ -34,12 +34,12 @@ const TxBlobs = ({ txQuery }: Props) => {
const content = data ? ( const content = data ? (
<> <>
<Hide below="lg" ssr={ false }> <Box hideBelow="lg">
<TxBlobsTable data={ data.items } isLoading={ isPlaceholderData } top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }/> <TxBlobsTable data={ data.items } isLoading={ isPlaceholderData } top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }/>
</Hide> </Box>
<Show below="lg" ssr={ false }> <Box hideFrom="lg">
<TxBlobsList data={ data.items } isLoading={ isPlaceholderData }/> <TxBlobsList data={ data.items } isLoading={ isPlaceholderData }/>
</Show> </Box>
</> </>
) : null; ) : null;
...@@ -52,11 +52,12 @@ const TxBlobs = ({ txQuery }: Props) => { ...@@ -52,11 +52,12 @@ const TxBlobs = ({ txQuery }: Props) => {
return ( return (
<DataListDisplay <DataListDisplay
isError={ isError || txQuery.isError } isError={ isError || txQuery.isError }
items={ data?.items } itemsNum={ data?.items.length }
emptyText="There are no blobs for this transaction." emptyText="There are no blobs for this transaction."
content={ content }
actionBar={ actionBar } actionBar={ actionBar }
/> >
{ content }
</DataListDisplay>
); );
}; };
......
import { Hide, Show, Text } from '@chakra-ui/react'; import { Box, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { TX_STATE_CHANGES } from 'stubs/txStateChanges'; import { TX_STATE_CHANGES } from 'stubs/txStateChanges';
...@@ -39,12 +39,12 @@ const TxState = ({ txQuery }: Props) => { ...@@ -39,12 +39,12 @@ const TxState = ({ txQuery }: Props) => {
const content = data ? ( const content = data ? (
<> <>
<Hide below="lg" ssr={ false }> <Box hideBelow="lg">
<TxStateTable data={ data.items } isLoading={ isPlaceholderData } top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }/> <TxStateTable data={ data.items } isLoading={ isPlaceholderData } top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }/>
</Hide> </Box>
<Show below="lg" ssr={ false }> <Box hideFrom="lg">
<TxStateList data={ data.items } isLoading={ isPlaceholderData }/> <TxStateList data={ data.items } isLoading={ isPlaceholderData }/>
</Show> </Box>
</> </>
) : null; ) : null;
...@@ -64,11 +64,12 @@ const TxState = ({ txQuery }: Props) => { ...@@ -64,11 +64,12 @@ const TxState = ({ txQuery }: Props) => {
) } ) }
<DataListDisplay <DataListDisplay
isError={ isError || txQuery.isError } isError={ isError || txQuery.isError }
items={ data?.items } itemsNum={ data?.items.length }
emptyText="There are no state changes for this transaction." emptyText="There are no state changes for this transaction."
content={ content }
actionBar={ actionBar } actionBar={ actionBar }
/> >
{ content }
</DataListDisplay>
</> </>
); );
}; };
......
...@@ -2,8 +2,8 @@ import React from 'react'; ...@@ -2,8 +2,8 @@ import React from 'react';
import type { TxBlob } from 'types/api/blobs'; import type { TxBlob } from 'types/api/blobs';
import { Skeleton } from 'toolkit/chakra/skeleton';
import BlobDataType from 'ui/shared/blob/BlobDataType'; import BlobDataType from 'ui/shared/blob/BlobDataType';
import Skeleton from 'ui/shared/chakra/Skeleton';
import BlobEntity from 'ui/shared/entities/blob/BlobEntity'; import BlobEntity from 'ui/shared/entities/blob/BlobEntity';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
...@@ -29,7 +29,7 @@ const TxBlobListItem = ({ data, isLoading }: Props) => { ...@@ -29,7 +29,7 @@ const TxBlobListItem = ({ data, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Size, bytes</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Size, bytes</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading }> <Skeleton loading={ isLoading }>
{ size.toLocaleString() } { size.toLocaleString() }
</Skeleton> </Skeleton>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
......
import { Table, Tbody, Tr, Th } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TxBlob } from 'types/api/blobs'; import type { TxBlob } from 'types/api/blobs';
import { default as Thead } from 'ui/shared/TheadSticky'; import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import TxBlobsTableItem from './TxBlobsTableItem'; import TxBlobsTableItem from './TxBlobsTableItem';
...@@ -16,20 +15,20 @@ interface Props { ...@@ -16,20 +15,20 @@ interface Props {
const TxInternalsTable = ({ data, top, isLoading }: Props) => { const TxInternalsTable = ({ data, top, isLoading }: Props) => {
return ( return (
<Table> <TableRoot>
<Thead top={ top }> <TableHeaderSticky top={ top }>
<Tr> <TableRow>
<Th width="60%">Blob hash</Th> <TableColumnHeader width="60%">Blob hash</TableColumnHeader>
<Th width="20%">Data type</Th> <TableColumnHeader width="20%">Data type</TableColumnHeader>
<Th width="20%">Size, bytes</Th> <TableColumnHeader width="20%">Size, bytes</TableColumnHeader>
</Tr> </TableRow>
</Thead> </TableHeaderSticky>
<Tbody> <TableBody>
{ data.map((item, index) => ( { data.map((item, index) => (
<TxBlobsTableItem key={ item.hash + (isLoading ? index : '') } data={ item } isLoading={ isLoading }/> <TxBlobsTableItem key={ item.hash + (isLoading ? index : '') } data={ item } isLoading={ isLoading }/>
)) } )) }
</Tbody> </TableBody>
</Table> </TableRoot>
); );
}; };
......
import { Tr, Td } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TxBlob } from 'types/api/blobs'; import type { TxBlob } from 'types/api/blobs';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import BlobDataType from 'ui/shared/blob/BlobDataType'; import BlobDataType from 'ui/shared/blob/BlobDataType';
import Skeleton from 'ui/shared/chakra/Skeleton';
import BlobEntity from 'ui/shared/entities/blob/BlobEntity'; import BlobEntity from 'ui/shared/entities/blob/BlobEntity';
interface Props { interface Props {
...@@ -16,19 +16,19 @@ const TxBlobsTableItem = ({ data, isLoading }: Props) => { ...@@ -16,19 +16,19 @@ const TxBlobsTableItem = ({ data, isLoading }: Props) => {
const size = data.blob_data ? data.blob_data.replace('0x', '').length / 2 : '-'; const size = data.blob_data ? data.blob_data.replace('0x', '').length / 2 : '-';
return ( return (
<Tr alignItems="top"> <TableRow alignItems="top">
<Td> <TableCell>
<BlobEntity hash={ data.hash } noIcon isLoading={ isLoading }/> <BlobEntity hash={ data.hash } noIcon isLoading={ isLoading }/>
</Td> </TableCell>
<Td verticalAlign="middle"> <TableCell verticalAlign="middle">
{ data.blob_data ? <BlobDataType isLoading={ isLoading } data={ data.blob_data }/> : '-' } { data.blob_data ? <BlobDataType isLoading={ isLoading } data={ data.blob_data }/> : '-' }
</Td> </TableCell>
<Td verticalAlign="middle"> <TableCell verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } display="inline-block"> <Skeleton loading={ isLoading } display="inline-block">
{ size.toLocaleString() } { size.toLocaleString() }
</Skeleton> </Skeleton>
</Td> </TableCell>
</Tr> </TableRow>
); );
}; };
......
import {
Table,
Tbody,
Tr,
Th,
} from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TxStateChange } from 'types/api/txStateChanges'; import type { TxStateChange } from 'types/api/txStateChanges';
import { AddressHighlightProvider } from 'lib/contexts/addressHighlight'; import { AddressHighlightProvider } from 'lib/contexts/addressHighlight';
import { default as Thead } from 'ui/shared/TheadSticky'; import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import TxStateTableItem from 'ui/tx/state/TxStateTableItem'; import TxStateTableItem from 'ui/tx/state/TxStateTableItem';
interface Props { interface Props {
...@@ -21,21 +15,21 @@ interface Props { ...@@ -21,21 +15,21 @@ interface Props {
const TxStateTable = ({ data, isLoading, top }: Props) => { const TxStateTable = ({ data, isLoading, top }: Props) => {
return ( return (
<AddressHighlightProvider> <AddressHighlightProvider>
<Table minWidth="1000px" w="100%"> <TableRoot minWidth="1000px" w="100%">
<Thead top={ top }> <TableHeaderSticky top={ top }>
<Tr> <TableRow>
<Th width="140px">Type</Th> <TableColumnHeader width="140px">Type</TableColumnHeader>
<Th width="160px">Address</Th> <TableColumnHeader width="160px">Address</TableColumnHeader>
<Th width="33%" isNumeric>Before</Th> <TableColumnHeader width="33%" isNumeric>Before</TableColumnHeader>
<Th width="33%" isNumeric>After</Th> <TableColumnHeader width="33%" isNumeric>After</TableColumnHeader>
<Th width="33%" isNumeric>Change</Th> <TableColumnHeader width="33%" isNumeric>Change</TableColumnHeader>
<Th width="150px" minW="80px" maxW="150px">Token ID</Th> <TableColumnHeader width="150px" minW="80px" maxW="150px">Token ID</TableColumnHeader>
</Tr> </TableRow>
</Thead> </TableHeaderSticky>
<Tbody> <TableBody>
{ data.map((item, index) => <TxStateTableItem data={ item } key={ index } isLoading={ isLoading }/>) } { data.map((item, index) => <TxStateTableItem data={ item } key={ index } isLoading={ isLoading }/>) }
</Tbody> </TableBody>
</Table> </TableRoot>
</AddressHighlightProvider> </AddressHighlightProvider>
); );
}; };
......
import { Tr, Td, Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TxStateChange } from 'types/api/txStateChanges'; import type { TxStateChange } from 'types/api/txStateChanges';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import { getStateElements } from './utils'; import { getStateElements } from './utils';
...@@ -16,13 +17,13 @@ const TxStateTableItem = ({ data, isLoading }: Props) => { ...@@ -16,13 +17,13 @@ const TxStateTableItem = ({ data, isLoading }: Props) => {
const { before, after, change, tag, tokenId } = getStateElements(data, isLoading); const { before, after, change, tag, tokenId } = getStateElements(data, isLoading);
return ( return (
<Tr> <TableRow>
<Td> <TableCell>
<Box py="3px"> <Box py="3px">
{ tag } { tag }
</Box> </Box>
</Td> </TableCell>
<Td> <TableCell>
<AddressEntity <AddressEntity
address={ data.address } address={ data.address }
isLoading={ isLoading } isLoading={ isLoading }
...@@ -30,12 +31,12 @@ const TxStateTableItem = ({ data, isLoading }: Props) => { ...@@ -30,12 +31,12 @@ const TxStateTableItem = ({ data, isLoading }: Props) => {
my="7px" my="7px"
w="100%" w="100%"
/> />
</Td> </TableCell>
<Td isNumeric><Box py="7px">{ before }</Box></Td> <TableCell isNumeric><Box py="7px">{ before }</Box></TableCell>
<Td isNumeric><Box py="7px">{ after }</Box></Td> <TableCell isNumeric><Box py="7px">{ after }</Box></TableCell>
<Td isNumeric><Box py="7px">{ change }</Box></Td> <TableCell isNumeric><Box py="7px">{ change }</Box></TableCell>
<Td>{ tokenId }</Td> <TableCell>{ tokenId }</TableCell>
</Tr> </TableRow>
); );
}; };
......
import { Flex, Text, Link, useBoolean } from '@chakra-ui/react'; import { Flex, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Link } from 'toolkit/chakra/link';
import NftEntity from 'ui/shared/entities/nft/NftEntity'; import NftEntity from 'ui/shared/entities/nft/NftEntity';
interface Props { interface Props {
...@@ -10,7 +11,11 @@ interface Props { ...@@ -10,7 +11,11 @@ interface Props {
} }
const TxStateTokenIdList = ({ items, tokenAddress, isLoading }: Props) => { const TxStateTokenIdList = ({ items, tokenAddress, isLoading }: Props) => {
const [ isCut, setIsCut ] = useBoolean(true); const [ isCut, setIsCut ] = React.useState(true);
const handleToggle = React.useCallback(() => {
setIsCut((prev) => !prev);
}, []);
return ( return (
<Flex flexDir="column" rowGap={ 2 }> <Flex flexDir="column" rowGap={ 2 }>
...@@ -33,7 +38,7 @@ const TxStateTokenIdList = ({ items, tokenAddress, isLoading }: Props) => { ...@@ -33,7 +38,7 @@ const TxStateTokenIdList = ({ items, tokenAddress, isLoading }: Props) => {
fontWeight={ 400 } fontWeight={ 400 }
textDecoration="underline dashed" textDecoration="underline dashed"
_hover={{ textDecoration: 'underline dashed', color: 'link_hovered' }} _hover={{ textDecoration: 'underline dashed', color: 'link_hovered' }}
onClick={ setIsCut.toggle } onClick={ handleToggle }
pb={{ base: '5px', md: 0 }} pb={{ base: '5px', md: 0 }}
> >
View { isCut ? 'more' : 'less' } View { isCut ? 'more' : 'less' }
......
import { Flex, Tooltip } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
...@@ -9,8 +9,9 @@ import { ZERO_ADDRESS } from 'lib/consts'; ...@@ -9,8 +9,9 @@ import { ZERO_ADDRESS } from 'lib/consts';
import { nbsp, space } from 'lib/html-entities'; import { nbsp, space } from 'lib/html-entities';
import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Badge } from 'toolkit/chakra/badge';
import Tag from 'ui/shared/chakra/Tag'; import { Skeleton } from 'toolkit/chakra/skeleton';
import { Tooltip } from 'toolkit/chakra/tooltip';
import NftEntity from 'ui/shared/entities/nft/NftEntity'; import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity'; import TokenEntity from 'ui/shared/entities/token/TokenEntity';
...@@ -20,10 +21,10 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) { ...@@ -20,10 +21,10 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
const tag = (() => { const tag = (() => {
if (data.is_miner) { if (data.is_miner) {
return ( return (
<Tooltip label="A block producer who successfully included the block into the blockchain"> <Tooltip content="A block producer who successfully included the block into the blockchain">
<Tag textTransform="capitalize" colorScheme="yellow" isLoading={ isLoading }> <Badge textTransform="capitalize" colorPalette="yellow" loading={ isLoading }>
{ getNetworkValidatorTitle() } { getNetworkValidatorTitle() }
</Tag> </Badge>
</Tooltip> </Tooltip>
); );
} }
...@@ -40,8 +41,8 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) { ...@@ -40,8 +41,8 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
if (changeDirection) { if (changeDirection) {
const text = changeDirection === 'from' ? 'Mint' : 'Burn'; const text = changeDirection === 'from' ? 'Mint' : 'Burn';
return ( return (
<Tooltip label="Address used in tokens mintings and burnings"> <Tooltip content="Address used in tokens mintings and burnings">
<Tag textTransform="capitalize" colorScheme="yellow" isLoading={ isLoading }>{ text } address</Tag> <Badge textTransform="capitalize" colorPalette="yellow" loading={ isLoading }>{ text } address</Badge>
</Tooltip> </Tooltip>
); );
} }
...@@ -60,17 +61,17 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) { ...@@ -60,17 +61,17 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
return { return {
before: ( before: (
<Skeleton isLoaded={ !isLoading } wordBreak="break-all" display="inline-block"> <Skeleton loading={ isLoading } wordBreak="break-all" display="inline-block">
{ beforeBn.toFormat() } { currencyUnits.ether } { beforeBn.toFormat() } { currencyUnits.ether }
</Skeleton> </Skeleton>
), ),
after: ( after: (
<Skeleton isLoaded={ !isLoading } wordBreak="break-all" display="inline-block"> <Skeleton loading={ isLoading } wordBreak="break-all" display="inline-block">
{ afterBn.toFormat() } { currencyUnits.ether } { afterBn.toFormat() } { currencyUnits.ether }
</Skeleton> </Skeleton>
), ),
change: ( change: (
<Skeleton isLoaded={ !isLoading } display="inline-block" color={ changeColor }> <Skeleton loading={ isLoading } display="inline-block" color={ changeColor }>
<span>{ changeSign }{ nbsp }{ differenceBn.abs().toFormat() }</span> <span>{ changeSign }{ nbsp }{ differenceBn.abs().toFormat() }</span>
</Skeleton> </Skeleton>
), ),
...@@ -106,7 +107,7 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) { ...@@ -106,7 +107,7 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
const changeSign = differenceBn.isGreaterThanOrEqualTo(0) ? '+' : '-'; const changeSign = differenceBn.isGreaterThanOrEqualTo(0) ? '+' : '-';
return ( return (
<Skeleton isLoaded={ !isLoading } display="inline-block" color={ changeColor } wordBreak="break-all"> <Skeleton loading={ isLoading } display="inline-block" color={ changeColor } wordBreak="break-all">
<span>{ changeSign }{ nbsp }{ differenceBn.abs().toFormat() }</span> <span>{ changeSign }{ nbsp }{ differenceBn.abs().toFormat() }</span>
</Skeleton> </Skeleton>
); );
...@@ -133,14 +134,14 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) { ...@@ -133,14 +134,14 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
return { return {
before: data.balance_before ? ( before: data.balance_before ? (
<Flex whiteSpace="pre-wrap" justifyContent={{ base: 'flex-start', lg: 'flex-end' }} flexWrap="wrap"> <Flex whiteSpace="pre-wrap" justifyContent={{ base: 'flex-start', lg: 'flex-end' }} flexWrap="wrap">
<Skeleton isLoaded={ !isLoading } wordBreak="break-all">{ beforeBn.toFormat() }</Skeleton> <Skeleton loading={ isLoading } wordBreak="break-all">{ beforeBn.toFormat() }</Skeleton>
<span>{ space }</span> <span>{ space }</span>
{ tokenLink } { tokenLink }
</Flex> </Flex>
) : null, ) : null,
after: data.balance_after ? ( after: data.balance_after ? (
<Flex whiteSpace="pre-wrap" justifyContent={{ base: 'flex-start', lg: 'flex-end' }} flexWrap="wrap"> <Flex whiteSpace="pre-wrap" justifyContent={{ base: 'flex-start', lg: 'flex-end' }} flexWrap="wrap">
<Skeleton isLoaded={ !isLoading } wordBreak="break-all">{ afterBn.toFormat() }</Skeleton> <Skeleton loading={ isLoading } wordBreak="break-all">{ afterBn.toFormat() }</Skeleton>
<span>{ space }</span> <span>{ space }</span>
{ tokenLink } { tokenLink }
</Flex> </Flex>
......
import { Hide, Show } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar'; import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
...@@ -23,7 +23,7 @@ const UserOpsContent = ({ query, showTx = true, showSender = true }: Props) => { ...@@ -23,7 +23,7 @@ const UserOpsContent = ({ query, showTx = true, showSender = true }: Props) => {
const content = query.data?.items ? ( const content = query.data?.items ? (
<> <>
<Hide below="lg" ssr={ false }> <Box hideBelow="lg">
<UserOpsTable <UserOpsTable
items={ query.data.items } items={ query.data.items }
top={ query.pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 } top={ query.pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }
...@@ -31,8 +31,8 @@ const UserOpsContent = ({ query, showTx = true, showSender = true }: Props) => { ...@@ -31,8 +31,8 @@ const UserOpsContent = ({ query, showTx = true, showSender = true }: Props) => {
showTx={ showTx } showTx={ showTx }
showSender={ showSender } showSender={ showSender }
/> />
</Hide> </Box>
<Show below="lg" ssr={ false }> <Box hideFrom="lg">
{ query.data.items.map((item, index) => ( { query.data.items.map((item, index) => (
<UserOpsListItem <UserOpsListItem
key={ item.hash + (query.isPlaceholderData ? String(index) : '') } key={ item.hash + (query.isPlaceholderData ? String(index) : '') }
...@@ -42,7 +42,7 @@ const UserOpsContent = ({ query, showTx = true, showSender = true }: Props) => { ...@@ -42,7 +42,7 @@ const UserOpsContent = ({ query, showTx = true, showSender = true }: Props) => {
showSender={ showSender } showSender={ showSender }
/> />
)) } )) }
</Show> </Box>
</> </>
) : null; ) : null;
...@@ -55,11 +55,12 @@ const UserOpsContent = ({ query, showTx = true, showSender = true }: Props) => { ...@@ -55,11 +55,12 @@ const UserOpsContent = ({ query, showTx = true, showSender = true }: Props) => {
return ( return (
<DataListDisplay <DataListDisplay
isError={ query.isError } isError={ query.isError }
items={ query.data?.items } itemsNum={ query.data?.items?.length }
emptyText="There are no user operations." emptyText="There are no user operations."
content={ content }
actionBar={ actionBar } actionBar={ actionBar }
/> >
{ content }
</DataListDisplay>
); );
}; };
......
...@@ -3,7 +3,6 @@ import React from 'react'; ...@@ -3,7 +3,6 @@ import React from 'react';
import type { UserOpsItem } from 'types/api/userOps'; import type { UserOpsItem } from 'types/api/userOps';
import config from 'configs/app'; import config from 'configs/app';
import Skeleton from 'ui/shared/chakra/Skeleton';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam'; import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
...@@ -76,8 +75,7 @@ const UserOpsListItem = ({ item, isLoading, showTx, showSender }: Props) => { ...@@ -76,8 +75,7 @@ const UserOpsListItem = ({ item, isLoading, showTx, showSender }: Props) => {
<BlockEntity <BlockEntity
number={ Number(item.block_number) } number={ Number(item.block_number) }
isLoading={ isLoading } isLoading={ isLoading }
fontSize="sm" textStyle="sm"
lineHeight={ 5 }
noIcon noIcon
/> />
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
...@@ -86,9 +84,7 @@ const UserOpsListItem = ({ item, isLoading, showTx, showSender }: Props) => { ...@@ -86,9 +84,7 @@ const UserOpsListItem = ({ item, isLoading, showTx, showSender }: Props) => {
<> <>
<ListItemMobileGrid.Label isLoading={ isLoading }>Fee</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Fee</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading }> <CurrencyValue value={ item.fee } isLoading={ isLoading } accuracy={ 8 } currency={ config.chain.currency.symbol }/>
<CurrencyValue value={ item.fee } isLoading={ isLoading } accuracy={ 8 } currency={ config.chain.currency.symbol }/>
</Skeleton>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
</> </>
) } ) }
......
import { Table, Tbody, Th, Tr } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { UserOpsItem } from 'types/api/userOps'; import type { UserOpsItem } from 'types/api/userOps';
import config from 'configs/app'; import config from 'configs/app';
import { default as Thead } from 'ui/shared/TheadSticky'; import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import UserOpsTableItem from './UserOpsTableItem'; import UserOpsTableItem from './UserOpsTableItem';
...@@ -18,19 +17,19 @@ import UserOpsTableItem from './UserOpsTableItem'; ...@@ -18,19 +17,19 @@ import UserOpsTableItem from './UserOpsTableItem';
const UserOpsTable = ({ items, isLoading, top, showTx, showSender }: Props) => { const UserOpsTable = ({ items, isLoading, top, showTx, showSender }: Props) => {
return ( return (
<Table minW="1000px"> <TableRoot minW="1000px">
<Thead top={ top }> <TableHeaderSticky top={ top }>
<Tr> <TableRow>
<Th w="60%">User op hash</Th> <TableColumnHeader w="60%">User op hash</TableColumnHeader>
<Th w="110px">Age</Th> <TableColumnHeader w="110px">Age</TableColumnHeader>
<Th w="140px">Status</Th> <TableColumnHeader w="140px">Status</TableColumnHeader>
{ showSender && <Th w="160px">Sender</Th> } { showSender && <TableColumnHeader w="160px">Sender</TableColumnHeader> }
{ showTx && <Th w="160px">Tx hash</Th> } { showTx && <TableColumnHeader w="160px">Tx hash</TableColumnHeader> }
<Th w="40%">Block</Th> <TableColumnHeader w="40%">Block</TableColumnHeader>
{ !config.UI.views.tx.hiddenFields?.tx_fee && <Th w="120px" isNumeric>{ `Fee ${ config.chain.currency.symbol }` }</Th> } { !config.UI.views.tx.hiddenFields?.tx_fee && <TableColumnHeader w="120px" isNumeric>{ `Fee ${ config.chain.currency.symbol }` }</TableColumnHeader> }
</Tr> </TableRow>
</Thead> </TableHeaderSticky>
<Tbody> <TableBody>
{ items.map((item, index) => { { items.map((item, index) => {
return ( return (
<UserOpsTableItem <UserOpsTableItem
...@@ -42,8 +41,8 @@ const UserOpsTable = ({ items, isLoading, top, showTx, showSender }: Props) => { ...@@ -42,8 +41,8 @@ const UserOpsTable = ({ items, isLoading, top, showTx, showSender }: Props) => {
/> />
); );
}) } }) }
</Tbody> </TableBody>
</Table> </TableRoot>
); );
}; };
......
import { Td, Tr } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { UserOpsItem } from 'types/api/userOps'; import type { UserOpsItem } from 'types/api/userOps';
import config from 'configs/app'; import config from 'configs/app';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam'; import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
...@@ -21,55 +21,54 @@ import UserOpStatus from 'ui/shared/userOps/UserOpStatus'; ...@@ -21,55 +21,54 @@ import UserOpStatus from 'ui/shared/userOps/UserOpStatus';
const UserOpsTableItem = ({ item, isLoading, showTx, showSender }: Props) => { const UserOpsTableItem = ({ item, isLoading, showTx, showSender }: Props) => {
return ( return (
<Tr> <TableRow>
<Td verticalAlign="middle"> <TableCell verticalAlign="middle">
<UserOpEntity hash={ item.hash } isLoading={ isLoading } noIcon fontWeight={ 700 } truncation="constant_long"/> <UserOpEntity hash={ item.hash } isLoading={ isLoading } noIcon fontWeight={ 700 } truncation="constant_long"/>
</Td> </TableCell>
<Td verticalAlign="middle"> <TableCell verticalAlign="middle">
<TimeAgoWithTooltip <TimeAgoWithTooltip
timestamp={ item.timestamp } timestamp={ item.timestamp }
isLoading={ isLoading } isLoading={ isLoading }
color="text_secondary" color="text.secondary"
display="inline-block" display="inline-block"
/> />
</Td> </TableCell>
<Td verticalAlign="middle"> <TableCell verticalAlign="middle">
<UserOpStatus status={ item.status } isLoading={ isLoading }/> <UserOpStatus status={ item.status } isLoading={ isLoading }/>
</Td> </TableCell>
{ showSender && ( { showSender && (
<Td verticalAlign="middle"> <TableCell verticalAlign="middle">
<AddressStringOrParam <AddressStringOrParam
address={ item.address } address={ item.address }
isLoading={ isLoading } isLoading={ isLoading }
truncation="constant" truncation="constant"
/> />
</Td> </TableCell>
) } ) }
{ showTx && ( { showTx && (
<Td verticalAlign="middle"> <TableCell verticalAlign="middle">
<TxEntity <TxEntity
hash={ item.transaction_hash } hash={ item.transaction_hash }
isLoading={ isLoading } isLoading={ isLoading }
truncation="constant" truncation="constant"
noIcon noIcon
/> />
</Td> </TableCell>
) } ) }
<Td verticalAlign="middle"> <TableCell verticalAlign="middle">
<BlockEntity <BlockEntity
number={ Number(item.block_number) } number={ Number(item.block_number) }
isLoading={ isLoading } isLoading={ isLoading }
fontSize="sm" textStyle="sm"
lineHeight={ 5 }
noIcon noIcon
/> />
</Td> </TableCell>
{ !config.UI.views.tx.hiddenFields?.tx_fee && ( { !config.UI.views.tx.hiddenFields?.tx_fee && (
<Td verticalAlign="middle" isNumeric> <TableCell verticalAlign="middle" isNumeric>
<CurrencyValue value={ item.fee } isLoading={ isLoading } accuracy={ 8 }/> <CurrencyValue value={ item.fee } isLoading={ isLoading } accuracy={ 8 }/>
</Td> </TableCell>
) } ) }
</Tr> </TableRow>
); );
}; };
......
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