Commit de5dcd73 authored by tom's avatar tom

internal txs tab

parent 81bf03c8
......@@ -8,7 +8,7 @@ import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
import { Skeleton } from './skeleton';
export interface BadgeProps extends ChakraBadgeProps {
export interface BadgeProps extends Omit<ChakraBadgeProps, 'colorScheme'> {
loading?: boolean;
iconStart?: IconName;
truncated?: boolean;
......
......@@ -42,7 +42,6 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
className="group"
target="_blank"
rel="noopener noreferrer"
cursor={ href ? 'pointer' : 'default' }
{ ...rest }
>
{ children }
......@@ -54,7 +53,7 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
return (
<Skeleton loading={ loading } asChild>
<ChakraLink asChild ref={ ref } cursor={ href ? 'pointer' : 'default' } { ...rest }>
<ChakraLink asChild ref={ ref } { ...rest }>
{ href ? <NextLink href={ href as NextLinkProps['href'] } scroll={ scroll }>{ children }</NextLink> : <span>{ children }</span> }
</ChakraLink>
</Skeleton>
......
......@@ -62,7 +62,7 @@ const TransactionPageContent = () => {
// config.features.userOps.isEnabled ?
// { id: 'user_ops', title: 'User operations', component: <TxUserOps txQuery={ txQuery }/> } :
// 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 ?
// { id: 'blobs', title: 'Blobs', component: <TxBlobs txQuery={ txQuery }/> } :
// undefined,
......
......@@ -76,7 +76,13 @@ const EntityTag = ({ data, isLoading, noLink, ...rest }: Props) => {
return (
<EntityTagTooltip data={ data }>
<Link external={ linkParams?.type === 'external' } href={ linkParams?.href } onClick={ handleLinkClick } noIcon>
<Link
external={ linkParams?.type === 'external' }
href={ linkParams?.href }
onClick={ handleLinkClick }
noIcon
cursor={ hasLink ? 'pointer' : 'default' }
>
<Tag
bg={ data.meta?.bgColor }
color={ data.meta?.textColor }
......
......@@ -5,6 +5,7 @@ import { Alert } from 'toolkit/chakra/alert';
import { Link } from 'toolkit/chakra/link';
import { TableBody, TableColumnHeader, TableHeader, TableRoot, TableRow } from 'toolkit/chakra/table';
import * as SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import TxPendingAlert from 'ui/tx/TxPendingAlert';
import { Section, Container, SectionHeader, SamplesStack, Sample, SectionSubHeader } from './parts';
......@@ -35,7 +36,7 @@ const AlertsShowcase = () => {
<SectionHeader>Variant</SectionHeader>
<SamplesStack>
<Sample label="variant: subtle">
<Alert status="info" title="Info"> Alert content </Alert>
<Alert status="info" title="Info" showIcon> Alert content </Alert>
</Sample>
</SamplesStack>
</Section>
......@@ -102,7 +103,7 @@ const AlertsShowcase = () => {
<SectionSubHeader>Multiple lines</SectionSubHeader>
<SamplesStack>
<Sample label="multiple lines, with title, inline=false">
<Alert status="warning" title="Warning" inline={ false } maxWidth="500px">
<Alert status="warning" title="Warning" inline={ false } maxWidth="500px" showIcon>
<Box>
Participated in our recent Blockscout activities? Check your eligibility and claim your NFT Scout badges. More exciting things are coming soon!
</Box>
......@@ -115,6 +116,9 @@ const AlertsShowcase = () => {
</Box>
</Alert>
</Sample>
<Sample label="with spinner">
<TxPendingAlert/>
</Sample>
</SamplesStack>
</Section>
</Container>
......
import { Show, Hide } from '@chakra-ui/react';
import { Box } from '@chakra-ui/react';
import React from 'react';
import type { InternalTransaction } from 'types/api/internalTransaction';
......@@ -22,14 +22,14 @@ import TxSocketAlert from 'ui/tx/TxSocketAlert';
import type { TxQuery } from './useTxQuery';
const SORT_SEQUENCE: Record<SortField, Array<Sort | undefined>> = {
value: [ 'value-desc', 'value-asc', undefined ],
'gas-limit': [ 'gas-limit-desc', 'gas-limit-asc', undefined ],
const SORT_SEQUENCE: Record<SortField, Array<Sort>> = {
value: [ 'value-desc', 'value-asc', 'default' ],
'gas-limit': [ 'gas-limit-desc', 'gas-limit-asc', 'default' ],
};
const getNextSortValue = (getNextSortValueShared<SortField, Sort>).bind(undefined, SORT_SEQUENCE);
const sortFn = (sort: Sort | undefined) => (a: InternalTransaction, b: InternalTransaction) => {
const sortFn = (sort: Sort) => (a: InternalTransaction, b: InternalTransaction) => {
switch (sort) {
case 'value-desc': {
return compareBns(b.value, a.value);
......@@ -68,7 +68,7 @@ const TxInternals = ({ txQuery }: Props) => {
// filters are not implemented yet in api
// const [ filters, setFilters ] = React.useState<Array<TxInternalsType>>([]);
// const [ searchTerm, setSearchTerm ] = React.useState<string>('');
const [ sort, setSort ] = React.useState<Sort>();
const [ sort, setSort ] = React.useState<Sort>('default');
const { data, isPlaceholderData, isError, pagination } = useQueryWithPages({
resourceName: 'tx_internal_txs',
pathParams: { hash: txQuery.data?.hash },
......@@ -103,8 +103,8 @@ const TxInternals = ({ txQuery }: Props) => {
const content = filteredData ? (
<>
<Show below="lg" ssr={ false }><TxInternalsList data={ filteredData } isLoading={ isPlaceholderData }/></Show>
<Hide below="lg" ssr={ false }>
<Box hideFrom="lg"><TxInternalsList data={ filteredData } isLoading={ isPlaceholderData }/></Box>
<Box hideBelow="lg">
<TxInternalsTable
data={ filteredData }
sort={ sort }
......@@ -112,7 +112,7 @@ const TxInternals = ({ txQuery }: Props) => {
top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }
isLoading={ isPlaceholderData }
/>
</Hide>
</Box>
</>
) : null;
......@@ -127,15 +127,16 @@ const TxInternals = ({ txQuery }: Props) => {
return (
<DataListDisplay
isError={ isError || txQuery.isError }
items={ data?.items }
itemsNum={ data?.items.length }
emptyText="There are no internal transactions for this transaction."
// filterProps={{
// emptyFilteredText: `Couldn${ apos }t find any transaction that matches your query.`.
// hasActiveFilters: Boolean(filters.length || searchTerm),
// }}
content={ content }
actionBar={ actionBar }
/>
>
{ content }
</DataListDisplay>
);
};
......
import { Alert, Spinner } from '@chakra-ui/react';
import { Spinner } from '@chakra-ui/react';
import React from 'react';
import { Alert } from 'toolkit/chakra/alert';
const TxPendingAlert = () => {
return (
<Alert>
<Spinner size="sm" mr={ 2 }/>
<Alert startElement={ <Spinner size="sm" my={ 1 }/> }>
This transaction is pending confirmation.
</Alert>
);
......
......@@ -6,9 +6,9 @@ import type { InternalTransaction } from 'types/api/internalTransaction';
import config from 'configs/app';
import { currencyUnits } from 'lib/units';
import { Badge } from 'toolkit/chakra/badge';
import { Skeleton } from 'toolkit/chakra/skeleton';
import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Skeleton from 'ui/shared/chakra/Skeleton';
import Tag from 'ui/shared/chakra/Tag';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TxStatus from 'ui/shared/statusTag/TxStatus';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
......@@ -22,7 +22,7 @@ const TxInternalsListItem = ({ type, from, to, value, success, error, gas_limit:
return (
<ListItemMobile rowGap={ 3 }>
<Flex columnGap={ 2 }>
{ typeTitle && <Tag colorScheme="cyan" isLoading={ isLoading }>{ typeTitle }</Tag> }
{ typeTitle && <Badge colorPalette="cyan" loading={ isLoading }>{ typeTitle }</Badge> }
<TxStatus status={ success ? 'ok' : 'error' } errorText={ error } isLoading={ isLoading }/>
</Flex>
<AddressFromTo
......@@ -32,15 +32,15 @@ const TxInternalsListItem = ({ type, from, to, value, success, error, gas_limit:
w="100%"
fontWeight="500"
/>
<HStack spacing={ 3 }>
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 }>Value { currencyUnits.ether }</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary">
<HStack gap={ 3 }>
<Skeleton loading={ isLoading } fontSize="sm" fontWeight={ 500 }>Value { currencyUnits.ether }</Skeleton>
<Skeleton loading={ isLoading } fontSize="sm" color="text_secondary">
{ BigNumber(value).div(BigNumber(10 ** config.chain.currency.decimals)).toFormat() }
</Skeleton>
</HStack>
<HStack spacing={ 3 }>
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 }>Gas limit</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary">{ BigNumber(gasLimit).toFormat() }</Skeleton>
<HStack gap={ 3 }>
<Skeleton loading={ isLoading } fontSize="sm" fontWeight={ 500 }>Gas limit</Skeleton>
<Skeleton loading={ isLoading } fontSize="sm" color="text_secondary">{ BigNumber(gasLimit).toFormat() }</Skeleton>
</HStack>
</ListItemMobile>
);
......
import { Table, Tbody, Tr, Th, Link } from '@chakra-ui/react';
import React from 'react';
import type { InternalTransaction } from 'types/api/internalTransaction';
import { AddressHighlightProvider } from 'lib/contexts/addressHighlight';
import { currencyUnits } from 'lib/units';
import { Link } from 'toolkit/chakra/link';
import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import IconSvg from 'ui/shared/IconSvg';
import { default as Thead } from 'ui/shared/TheadSticky';
import TxInternalsTableItem from 'ui/tx/internals/TxInternalsTableItem';
import type { Sort, SortField } from 'ui/tx/internals/utils';
......@@ -23,31 +23,31 @@ const TxInternalsTable = ({ data, sort, onSortToggle, top, isLoading }: Props) =
return (
<AddressHighlightProvider>
<Table>
<Thead top={ top }>
<Tr>
<Th width="28%">Type</Th>
<Th width="40%">From/To</Th>
<Th width="16%" isNumeric>
<TableRoot>
<TableHeaderSticky top={ top }>
<TableRow>
<TableColumnHeader width="28%">Type</TableColumnHeader>
<TableColumnHeader width="40%">From/To</TableColumnHeader>
<TableColumnHeader width="16%" isNumeric>
<Link display="flex" alignItems="center" justifyContent="flex-end" onClick={ onSortToggle('value') } columnGap={ 1 }>
{ sort?.includes('value') && <IconSvg name="arrows/east" boxSize={ 4 } transform={ sortIconTransform }/> }
Value { currencyUnits.ether }
</Link>
</Th>
<Th width="16%" isNumeric>
</TableColumnHeader>
<TableColumnHeader width="16%" isNumeric>
<Link display="flex" alignItems="center" justifyContent="flex-end" onClick={ onSortToggle('gas-limit') } columnGap={ 1 }>
{ sort?.includes('gas-limit') && <IconSvg name="arrows/east" boxSize={ 4 } transform={ sortIconTransform }/> }
Gas limit { currencyUnits.ether }
</Link>
</Th>
</Tr>
</Thead>
<Tbody>
</TableColumnHeader>
</TableRow>
</TableHeaderSticky>
<TableBody>
{ data.map((item, index) => (
<TxInternalsTableItem key={ item.index.toString() + (isLoading ? index : '') } { ...item } isLoading={ isLoading }/>
)) }
</Tbody>
</Table>
</TableBody>
</TableRoot>
</AddressHighlightProvider>
);
};
......
import { Tr, Td, Box, Flex } from '@chakra-ui/react';
import { Box, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
import type { InternalTransaction } from 'types/api/internalTransaction';
import config from 'configs/app';
import { Badge } from 'toolkit/chakra/badge';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Skeleton from 'ui/shared/chakra/Skeleton';
import Tag from 'ui/shared/chakra/Tag';
import TxStatus from 'ui/shared/statusTag/TxStatus';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
......@@ -20,35 +21,35 @@ const TxInternalTableItem = ({ type, from, to, value, success, error, gas_limit:
const toData = to ? to : createdContract;
return (
<Tr alignItems="top">
<Td>
<TableRow alignItems="top">
<TableCell>
<Flex rowGap={ 2 } flexWrap="wrap">
{ typeTitle && (
<Box w="126px" display="inline-block">
<Tag colorScheme="cyan" mr={ 5 } isLoading={ isLoading }>{ typeTitle }</Tag>
<Badge colorPalette="cyan" mr={ 5 } loading={ isLoading }>{ typeTitle }</Badge>
</Box>
) }
<TxStatus status={ success ? 'ok' : 'error' } errorText={ error } isLoading={ isLoading }/>
</Flex>
</Td>
<Td verticalAlign="middle">
</TableCell>
<TableCell verticalAlign="middle">
<AddressFromTo
from={ from }
to={ toData }
isLoading={ isLoading }
/>
</Td>
<Td isNumeric verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } display="inline-block">
</TableCell>
<TableCell isNumeric verticalAlign="middle">
<Skeleton loading={ isLoading } display="inline-block">
{ BigNumber(value).div(BigNumber(10 ** config.chain.currency.decimals)).toFormat() }
</Skeleton>
</Td>
<Td isNumeric verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } display="inline-block">
</TableCell>
<TableCell isNumeric verticalAlign="middle">
<Skeleton loading={ isLoading } display="inline-block">
{ BigNumber(gasLimit).toFormat() }
</Skeleton>
</Td>
</Tr>
</TableCell>
</TableRow>
);
};
......
import type { TxInternalsType } from 'types/api/internalTransaction';
export type Sort = 'value-asc' | 'value-desc' | 'gas-limit-asc' | 'gas-limit-desc';
export type Sort = 'value-asc' | 'value-desc' | 'gas-limit-asc' | 'gas-limit-desc' | 'default';
export type SortField = 'value' | 'gas-limit';
interface TxInternalsTypeItem {
......
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