Commit d2368c18 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #564 from blockscout/internal-link

Internal link navigation with SPA
parents 43f96e1b 88f06cb3
......@@ -25,13 +25,13 @@ export default function useNavItems() {
return React.useMemo(() => {
const mainNavItems = [
{ text: 'Blocks', url: link('blocks'), icon: blocksIcon, isActive: currentRoute.startsWith('block'), isNewUi: false },
{ text: 'Transactions', url: link('txs'), icon: transactionsIcon, isActive: currentRoute.startsWith('tx'), isNewUi: false },
{ text: 'Tokens', url: link('tokens'), icon: tokensIcon, isActive: currentRoute === 'tokens', isNewUi: false },
{ text: 'Accounts', url: link('accounts'), icon: walletIcon, isActive: currentRoute === 'accounts', isNewUi: false },
{ text: 'Blocks', url: link('blocks'), icon: blocksIcon, isActive: currentRoute.startsWith('block'), isNewUi: true },
{ text: 'Transactions', url: link('txs'), icon: transactionsIcon, isActive: currentRoute.startsWith('tx'), isNewUi: true },
{ text: 'Tokens', url: link('tokens'), icon: tokensIcon, isActive: currentRoute.startsWith('token'), isNewUi: true },
{ text: 'Accounts', url: link('accounts'), icon: walletIcon, isActive: currentRoute === 'accounts', isNewUi: true },
isMarketplaceFilled ?
{ text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute === 'apps', isNewUi: true } : null,
{ text: 'Charts & stats', url: link('stats'), icon: statsIcon, isActive: currentRoute === 'stats', isNewUi: false },
{ text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute.startsWith('app'), isNewUi: true } : null,
{ text: 'Charts & stats', url: link('stats'), icon: statsIcon, isActive: currentRoute === 'stats', isNewUi: true },
// there should be custom site sections like Stats, Faucet, More, etc but never an 'other'
// examples https://explorer-edgenet.polygon.technology/ and https://explorer.celo.org/
// at this stage custom menu items is under development, we will implement it later
......
import type { ServerResponse } from 'http';
export function appendValue(res: ServerResponse | undefined, name: string, value: number) {
const currentValue = res?.getHeader('Server-Timing') || '';
const nextValue = [
currentValue,
`${ name };dur=${ value }`,
].filter(Boolean).join(',');
res?.setHeader('Server-Timing', nextValue);
}
......@@ -10,6 +10,7 @@ const cspPolicy = getCspPolicy();
export function middleware(req: NextRequest) {
const isPageRequest = req.headers.get('accept')?.includes('text/html');
const start = Date.now();
if (!isPageRequest) {
return;
......@@ -25,8 +26,11 @@ export function middleware(req: NextRequest) {
return NextResponse.redirect(authUrl);
}
const end = Date.now();
const res = NextResponse.next();
res.headers.append('Content-Security-Policy-Report-Only', cspPolicy);
res.headers.append('Server-Timing', `middleware;dur=${ end - start }`);
return res;
}
......
......@@ -21,7 +21,7 @@ export const baseResponse: AddressCoinBalanceHistoryResponse = {
block_number: 30367234,
block_timestamp: '2022-10-01T17:55:20Z',
delta: '1933020674364000',
transaction_hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193',
transaction_hash: null,
value: '10143933697708939226',
},
{
......
import { ColorModeScript } from '@chakra-ui/react';
import type { DocumentContext } from 'next/document';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import React from 'react';
import * as serverTiming from 'lib/next/serverTiming';
import theme from 'theme';
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const originalRenderPage = ctx.renderPage;
ctx.renderPage = async() => {
const start = Date.now();
const result = await originalRenderPage();
const end = Date.now();
serverTiming.appendValue(ctx.res, 'renderPage', end - start);
return result;
};
const initialProps = await Document.getInitialProps(ctx);
return initialProps;
}
render() {
return (
<Html lang="en">
......
......@@ -10,6 +10,7 @@ import link from 'lib/link/link';
import getNetworkTitle from 'lib/networks/getNetworkTitle';
import type { Props } from 'lib/next/getServerSideProps';
import { getServerSideProps as getServerSidePropsBase } from 'lib/next/getServerSideProps';
import * as serverTiming from 'lib/next/serverTiming';
import SearchResults from 'ui/pages/SearchResults';
const SearchResultsPage: NextPage = () => {
......@@ -27,6 +28,8 @@ const SearchResultsPage: NextPage = () => {
export default SearchResultsPage;
export const getServerSideProps: GetServerSideProps<Props> = async({ req, res, resolvedUrl, query }) => {
const start = Date.now();
try {
const q = String(query.q);
const url = buildUrlNode('search_check_redirect', undefined, { q });
......@@ -63,5 +66,9 @@ export const getServerSideProps: GetServerSideProps<Props> = async({ req, res, r
};
} catch (error) {}
const end = Date.now();
serverTiming.appendValue(res, 'query.search.check-redirect', end - start);
return getServerSidePropsBase({ req, res, resolvedUrl, query });
};
......@@ -18,11 +18,13 @@ const AddressCoinBalance = () => {
const [ socketAlert, setSocketAlert ] = React.useState(false);
const queryClient = useQueryClient();
const router = useRouter();
const scrollRef = React.useRef<HTMLDivElement>(null);
const addressHash = String(router.query?.id);
const coinBalanceQuery = useQueryWithPages({
resourceName: 'address_coin_balance',
pathParams: { id: addressHash },
scrollRef,
});
const handleSocketError = React.useCallback(() => {
......@@ -65,6 +67,7 @@ const AddressCoinBalance = () => {
<>
{ socketAlert && <SocketAlert mb={ 6 }/> }
<AddressCoinBalanceChart addressHash={ addressHash }/>
<div ref={ scrollRef }></div>
<AddressCoinBalanceHistory query={ coinBalanceQuery }/>
</>
);
......
import { Box, Flex, Text, Icon, Grid, Link } from '@chakra-ui/react';
import { Box, Flex, Text, Icon, Grid } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import React from 'react';
......@@ -17,9 +17,10 @@ import AddressLink from 'ui/shared/address/AddressLink';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import ExternalLink from 'ui/shared/ExternalLink';
import HashStringShorten from 'ui/shared/HashStringShorten';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkExternal from 'ui/shared/LinkExternal';
import LinkInternal from 'ui/shared/LinkInternal';
import AddressAddToMetaMask from './details/AddressAddToMetaMask';
import AddressBalance from './details/AddressBalance';
......@@ -107,8 +108,8 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
<Flex mt={ 8 } columnGap={ 4 } flexWrap="wrap">
<Text fontSize="sm">Verify with other explorers</Text>
{ explorers.map((explorer) => {
const url = new URL(explorer.paths.tx + '/' + router.query.id, explorer.baseUrl);
return <ExternalLink key={ explorer.baseUrl } title={ explorer.title } href={ url.toString() }/>;
const url = new URL(explorer.paths.address + '/' + router.query.id, explorer.baseUrl);
return <LinkExternal key={ explorer.baseUrl } title={ explorer.title } href={ url.toString() }/>;
}) }
</Flex>
) }
......@@ -135,7 +136,9 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
hint="Implementation address of the proxy contract."
columnGap={ 1 }
>
<Link href={ link('address_index', { id: data.implementation_address }) }>{ data.implementation_name }</Link>
<LinkInternal href={ link('address_index', { id: data.implementation_address }) }>
{ data.implementation_name }
</LinkInternal>
<Text variant="secondary" overflow="hidden">
<HashStringShortenDynamic hash={ `(${ data.implementation_address })` }/>
</Text>
......@@ -195,14 +198,14 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
alignSelf="center"
py={{ base: '2px', lg: 1 }}
>
<Link
<LinkInternal
href={ link('block', { id: String(data.block_number_balance_updated_at) }) }
display="flex"
alignItems="center"
>
<Icon as={ blockIcon } boxSize={ 6 } mr={ 2 }/>
{ data.block_number_balance_updated_at }
</Link>
</LinkInternal>
</DetailsInfoItem>
) }
</Grid>
......
import { Link, Text, Flex } from '@chakra-ui/react';
import { Text, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -8,6 +8,7 @@ import appConfig from 'configs/app/config';
import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile';
import Utilization from 'ui/shared/Utilization/Utilization';
......@@ -23,7 +24,7 @@ const AddressBlocksValidatedListItem = (props: Props) => {
return (
<ListItemMobile rowGap={ 2 } isAnimated>
<Flex justifyContent="space-between" w="100%">
<Link href={ blockUrl } fontWeight="700">{ props.height }</Link>
<LinkInternal href={ blockUrl } fontWeight="700">{ props.height }</LinkInternal>
<Text variant="secondary">{ timeAgo }</Text>
</Flex>
<Flex columnGap={ 2 } w="100%">
......
import { Link, Td, Tr, Text, Box, Flex } from '@chakra-ui/react';
import { Td, Tr, Text, Box, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -7,6 +7,7 @@ import type { Block } from 'types/api/block';
import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
import Utilization from 'ui/shared/Utilization/Utilization';
type Props = Block & {
......@@ -21,7 +22,7 @@ const AddressBlocksValidatedTableItem = (props: Props) => {
return (
<Tr>
<Td>
<Link href={ blockUrl } fontWeight="700">{ props.height }</Link>
<LinkInternal href={ blockUrl } fontWeight="700">{ props.height }</LinkInternal>
</Td>
<Td>
<Text variant="secondary">{ timeAgo }</Text>
......
import { Link, Text, Stat, StatHelpText, StatArrow, Flex } from '@chakra-ui/react';
import { Text, Stat, StatHelpText, StatArrow, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -10,6 +10,7 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link';
import Address from 'ui/shared/address/Address';
import AddressLink from 'ui/shared/address/AddressLink';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile';
type Props = AddressCoinBalanceHistoryItem & {
......@@ -25,19 +26,19 @@ const AddressCoinBalanceListItem = (props: Props) => {
return (
<ListItemMobile rowGap={ 2 } isAnimated>
<Flex justifyContent="space-between" w="100%">
<Text fontWeight={ 600 }>{ BigNumber(props.value).div(WEI).toFixed(8) } { appConfig.network.currency.symbol }</Text>
<Text fontWeight={ 600 }>{ BigNumber(props.value).div(WEI).dp(8).toFormat() } { appConfig.network.currency.symbol }</Text>
<Stat flexGrow="0">
<StatHelpText display="flex" mb={ 0 } alignItems="center">
<StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' }/>
<Text as="span" color={ isPositiveDelta ? 'green.500' : 'red.500' } fontWeight={ 600 }>
{ deltaBn.toFormat() }
{ deltaBn.dp(8).toFormat() }
</Text>
</StatHelpText>
</Stat>
</Flex>
<Flex columnGap={ 2 } w="100%">
<Text fontWeight={ 500 } flexShrink={ 0 }>Block</Text>
<Link href={ blockUrl } fontWeight="700">{ props.block_number }</Link>
<LinkInternal href={ blockUrl } fontWeight="700">{ props.block_number }</LinkInternal>
</Flex>
{ props.transaction_hash && (
<Flex columnGap={ 2 } w="100%">
......
import { Link, Td, Tr, Text, Stat, StatHelpText, StatArrow } from '@chakra-ui/react';
import { Td, Tr, Text, Stat, StatHelpText, StatArrow } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -9,6 +9,7 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link';
import Address from 'ui/shared/address/Address';
import AddressLink from 'ui/shared/address/AddressLink';
import LinkInternal from 'ui/shared/LinkInternal';
type Props = AddressCoinBalanceHistoryItem & {
page: number;
......@@ -23,12 +24,12 @@ const AddressCoinBalanceTableItem = (props: Props) => {
return (
<Tr>
<Td>
<Link href={ blockUrl } fontWeight="700">{ props.block_number }</Link>
<LinkInternal href={ blockUrl } fontWeight="700">{ props.block_number }</LinkInternal>
</Td>
<Td>
{ props.transaction_hash ?
(
<Address maxW="150px" fontWeight="700">
<Address w="150px" fontWeight="700">
<AddressLink hash={ props.transaction_hash } type="transaction"/>
</Address>
) :
......@@ -39,14 +40,14 @@ const AddressCoinBalanceTableItem = (props: Props) => {
<Text variant="secondary">{ timeAgo }</Text>
</Td>
<Td isNumeric pr={ 1 }>
<Text>{ BigNumber(props.value).div(WEI).toFixed(8) }</Text>
<Text>{ BigNumber(props.value).div(WEI).dp(8).toFormat() }</Text>
</Td>
<Td isNumeric display="flex" justifyContent="end">
<Stat flexGrow="0">
<StatHelpText display="flex" mb={ 0 } alignItems="center">
<StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' }/>
<Text as="span" color={ isPositiveDelta ? 'green.500' : 'red.500' } fontWeight={ 600 }>
{ deltaBn.toFormat() }
{ deltaBn.dp(8).toFormat() }
</Text>
</StatHelpText>
</Stat>
......
......@@ -8,7 +8,8 @@ import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import ExternalLink from 'ui/shared/ExternalLink';
import LinkExternal from 'ui/shared/LinkExternal';
import LinkInternal from 'ui/shared/LinkInternal';
import RawDataSnippet from 'ui/shared/RawDataSnippet';
import ContractSourceCode from './ContractSourceCode';
......@@ -72,7 +73,9 @@ const ContractCode = () => {
const decoded = data.decoded_constructor_args
.map(([ value, { name, type } ], index) => {
const valueEl = type === 'address' ? <Link href={ link('address_index', { id: value }) }>{ value }</Link> : <span>{ value }</span>;
const valueEl = type === 'address' ?
<LinkInternal href={ link('address_index', { id: value }) }>{ value }</LinkInternal> :
<span>{ value }</span>;
return (
<Box key={ index }>
<span>Arg [{ index }] { name || '' } ({ type }): </span>
......@@ -98,7 +101,7 @@ const ContractCode = () => {
return data.external_libraries.map((item) => (
<Box key={ item.address_hash }>
<chakra.span fontWeight={ 500 }>{ item.name }: </chakra.span>
<Link href={ link('address_index', { id: item.address_hash }, { tab: 'contract' }) }>{ item.address_hash }</Link>
<LinkInternal href={ link('address_index', { id: item.address_hash }, { tab: 'contract' }) }>{ item.address_hash }</LinkInternal>
</Box>
));
})();
......@@ -110,7 +113,7 @@ const ContractCode = () => {
{ data.is_verified_via_sourcify && (
<Alert status="warning" whiteSpace="pre-wrap" flexWrap="wrap">
<span>This contract has been { data.is_partially_verified ? 'partially ' : '' }verified via Sourcify. </span>
{ data.sourcify_repo_url && <ExternalLink href={ data.sourcify_repo_url } title="View contract in Sourcify repository" fontSize="md"/> }
{ data.sourcify_repo_url && <LinkExternal href={ data.sourcify_repo_url } title="View contract in Sourcify repository" fontSize="md"/> }
</Alert>
) }
{ data.is_changed_bytecode && (
......@@ -126,7 +129,7 @@ const ContractCode = () => {
<AddressLink type="address" hash={ data.verified_twin_address_hash } truncation="constant" ml={ 2 }/>
</Address>
<chakra.span mt={ 1 }>All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with </chakra.span>
<Link href={ link('address_contract_verification', { id: data.verified_twin_address_hash }) }>Verify & Publish</Link>
<LinkInternal href={ link('address_contract_verification', { id: data.verified_twin_address_hash }) }>Verify & Publish</LinkInternal>
<span> page</span>
</Alert>
) }
......
import { Box, chakra, Link, Spinner } from '@chakra-ui/react';
import { Box, chakra, Spinner } from '@chakra-ui/react';
import React from 'react';
import type { ContractMethodWriteResult } from './types';
import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
interface Props {
result: ContractMethodWriteResult;
......@@ -30,7 +31,7 @@ const ContractWriteResultDumb = ({ result, onSettle, txInfo }: Props) => {
const isErrorResult = 'message' in result;
const txLink = (
<Link href={ link('tx', { id: txHash }) }>View transaction details</Link>
<LinkInternal href={ link('tx', { id: txHash }) }>View transaction details</LinkInternal>
);
const content = (() => {
......
import { Link, Skeleton } from '@chakra-ui/react';
import { Skeleton } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query';
import BigNumber from 'bignumber.js';
import NextLink from 'next/link';
import React from 'react';
import type { AddressCounters } from 'types/api/address';
import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
interface Props {
prop: keyof AddressCounters;
......@@ -42,11 +42,9 @@ const AddressCounterItem = ({ prop, query, address, onClick }: Props) => {
return <span>0</span>;
}
return (
<NextLink href={ link('address_index', { id: address }, { tab: PROP_TO_TAB[prop] }) } passHref>
<Link onClick={ onClick }>
<LinkInternal href={ link('address_index', { id: address }, { tab: PROP_TO_TAB[prop] }) } onClick={ onClick }>
{ Number(data).toLocaleString() }
</Link>
</NextLink>
</LinkInternal>
);
}
}
......
import { Link } from '@chakra-ui/react';
import React from 'react';
import type { Address } from 'types/api/address';
import link from 'lib/link/link';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import LinkInternal from 'ui/shared/LinkInternal';
interface Props {
data: Pick<Address, 'name' | 'token' | 'is_contract'>;
......@@ -17,9 +17,9 @@ const AddressNameInfo = ({ data }: Props) => {
title="Token name"
hint="Token name and symbol"
>
<Link href={ link('token_index', { hash: data.token.address }) }>
<LinkInternal href={ link('token_index', { hash: data.token.address }) }>
{ data.token.name } ({ data.token.symbol })
</Link>
</LinkInternal>
</DetailsInfoItem>
);
}
......
import { Flex, Tag, Icon, Box, HStack, Text, Link } from '@chakra-ui/react';
import { Flex, Tag, Icon, Box, HStack, Text } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -12,6 +12,7 @@ import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import InOutTag from 'ui/shared/InOutTag';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile';
import TxStatus from 'ui/shared/TxStatus';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
......@@ -49,7 +50,7 @@ const TxInternalsListItem = ({
</Flex>
<HStack spacing={ 1 }>
<Text fontSize="sm" fontWeight={ 500 }>Block</Text>
<Link href={ link('block', { id: block.toString() }) }>{ block }</Link>
<LinkInternal href={ link('block', { id: block.toString() }) }>{ block }</LinkInternal>
</HStack>
<Box w="100%" display="flex" columnGap={ 3 }>
<Address width="calc((100% - 48px) / 2)">
......
import { Tr, Td, Tag, Icon, Box, Flex, Text, Link } from '@chakra-ui/react';
import { Tr, Td, Tag, Icon, Box, Flex, Text } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -12,6 +12,7 @@ import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import InOutTag from 'ui/shared/InOutTag';
import LinkInternal from 'ui/shared/LinkInternal';
import TxStatus from 'ui/shared/TxStatus';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
......@@ -57,7 +58,7 @@ const AddressIntTxsTableItem = ({
</Flex>
</Td>
<Td verticalAlign="middle">
<Link href={ link('block', { id: block.toString() }) }>{ block }</Link>
<LinkInternal href={ link('block', { id: block.toString() }) }>{ block }</LinkInternal>
</Td>
<Td verticalAlign="middle">
<Address display="inline-flex" maxW="100%">
......
import { Grid, GridItem, Text, Icon, Link, Box, Tooltip } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import capitalize from 'lodash/capitalize';
import NextLink from 'next/link';
import { useRouter } from 'next/router';
import React from 'react';
import { scroller, Element } from 'react-scroll';
......@@ -23,6 +22,7 @@ import DataFetchAlert from 'ui/shared/DataFetchAlert';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal';
import PrevNext from 'ui/shared/PrevNext';
import TextSeparator from 'ui/shared/TextSeparator';
import Utilization from 'ui/shared/Utilization/Utilization';
......@@ -116,11 +116,9 @@ const BlockDetails = () => {
title="Transactions"
hint="The number of transactions in the block."
>
<NextLink href={ link('block', { id: router.query.id }, { tab: 'txs' }) } passHref>
<Link>
<LinkInternal href={ link('block', { id: router.query.id }, { tab: 'txs' }) }>
{ data.tx_count } transactions
</Link>
</NextLink>
</LinkInternal>
</DetailsInfoItem>
<DetailsInfoItem
title={ appConfig.network.verificationType === 'validation' ? 'Validated by' : 'Mined by' }
......
import { Flex, Link, Spinner, Text, Box, Icon } from '@chakra-ui/react';
import { Flex, Spinner, Text, Box, Icon } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import capitalize from 'lodash/capitalize';
import React from 'react';
......@@ -14,6 +14,7 @@ import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressLink from 'ui/shared/address/AddressLink';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile';
import Utilization from 'ui/shared/Utilization/Utilization';
......@@ -33,12 +34,12 @@ const BlocksListItem = ({ data, isPending, enableTimeIncrement }: Props) => {
<Flex justifyContent="space-between" w="100%">
<Flex columnGap={ 2 } alignItems="center">
{ isPending && <Spinner size="sm"/> }
<Link
<LinkInternal
fontWeight={ 600 }
href={ link('block', { id: String(data.height) }) }
>
{ data.height }
</Link>
</LinkInternal>
</Flex>
<BlockTimestamp ts={ data.timestamp } isEnabled={ enableTimeIncrement }/>
</Flex>
......
import { Tr, Td, Link, Flex, Box, Icon, Tooltip, Spinner, useColorModeValue } from '@chakra-ui/react';
import { Tr, Td, Flex, Box, Icon, Tooltip, Spinner, useColorModeValue } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { motion } from 'framer-motion';
import React from 'react';
......@@ -12,6 +12,7 @@ import link from 'lib/link/link';
import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressLink from 'ui/shared/address/AddressLink';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import LinkInternal from 'ui/shared/LinkInternal';
import Utilization from 'ui/shared/Utilization/Utilization';
interface Props {
......@@ -38,12 +39,12 @@ const BlocksTableItem = ({ data, isPending, enableTimeIncrement }: Props) => {
<Flex columnGap={ 2 } alignItems="center" mb={ 2 }>
{ isPending && <Spinner size="sm" flexShrink={ 0 }/> }
<Tooltip isDisabled={ data.type !== 'reorg' } label="Chain reorganizations">
<Link
<LinkInternal
fontWeight={ 600 }
href={ link('block', { id: String(data.height) }) }
>
{ data.height }
</Link>
</LinkInternal>
</Tooltip>
</Flex>
<BlockTimestamp ts={ data.timestamp } isEnabled={ enableTimeIncrement }/>
......
import { Box, Heading, Flex, Link, Text, VStack, Skeleton } from '@chakra-ui/react';
import { Box, Heading, Flex, Text, VStack, Skeleton } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query';
import { AnimatePresence } from 'framer-motion';
import React from 'react';
......@@ -12,6 +12,7 @@ import { nbsp } from 'lib/html-entities';
import link from 'lib/link/link';
import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage';
import LinkInternal from 'ui/shared/LinkInternal';
import LatestBlocksItem from './LatestBlocksItem';
import LatestBlocksItemSkeleton from './LatestBlocksItemSkeleton';
......@@ -97,7 +98,7 @@ const LatestBlocks = () => {
</AnimatePresence>
</VStack>
<Flex justifyContent="center">
<Link fontSize="sm" href={ link('blocks') }>View all blocks</Link>
<LinkInternal fontSize="sm" href={ link('blocks') }>View all blocks</LinkInternal>
</Flex>
</>
);
......
......@@ -5,7 +5,6 @@ import {
GridItem,
HStack,
Icon,
Link,
Text,
} from '@chakra-ui/react';
import { motion } from 'framer-motion';
......@@ -18,6 +17,7 @@ import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import link from 'lib/link/link';
import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressLink from 'ui/shared/address/AddressLink';
import LinkInternal from 'ui/shared/LinkInternal';
type Props = {
block: Block;
......@@ -43,13 +43,13 @@ const LatestBlocksItem = ({ block, h }: Props) => {
<Flex justifyContent="space-between" alignItems="center" mb={ 3 }>
<HStack spacing={ 2 }>
<Icon as={ blockIcon } boxSize="30px" color="link"/>
<Link
<LinkInternal
href={ link('block', { id: String(block.height) }) }
fontSize="xl"
fontWeight="500"
>
{ block.height }
</Link>
</LinkInternal>
</HStack>
<BlockTimestamp ts={ block.timestamp } isEnabled fontSize="sm"/>
</Flex>
......
import { Box, Heading, Flex, Link, Text, Skeleton } from '@chakra-ui/react';
import { Box, Heading, Flex, Text, Skeleton } from '@chakra-ui/react';
import React from 'react';
import useApiQuery from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
import useNewTxsSocket from 'lib/hooks/useNewTxsSocket';
import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
import SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import LatestTxsItem from './LatestTxsItem';
......@@ -36,12 +37,12 @@ const LatestTransactions = () => {
const txsUrl = link('txs');
content = (
<>
<SocketNewItemsNotice borderBottomRadius={ 0 } url={ link('txs') } num={ num } alert={ socketAlert }/>
<SocketNewItemsNotice borderBottomRadius={ 0 } url={ txsUrl } num={ num } alert={ socketAlert }/>
<Box mb={{ base: 3, lg: 4 }}>
{ data.slice(0, txsCount).map((tx => <LatestTxsItem key={ tx.hash } tx={ tx }/>)) }
</Box>
<Flex justifyContent="center">
<Link fontSize="sm" href={ txsUrl }>View all transactions</Link>
<LinkInternal fontSize="sm" href={ txsUrl }>View all transactions</LinkInternal>
</Flex>
</>
);
......
......@@ -8,7 +8,6 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import iconSuccess from 'icons/status/success.svg';
import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext';
import isBrowser from 'lib/isBrowser';
import notEmpty from 'lib/notEmpty';
import AddressBlocksValidated from 'ui/address/AddressBlocksValidated';
import AddressCoinBalance from 'ui/address/AddressCoinBalance';
......@@ -41,11 +40,8 @@ const AddressPageContent = () => {
const router = useRouter();
const appProps = useAppContext();
const isInBrowser = isBrowser();
const referrer = isInBrowser ? window.document.referrer : appProps.referrer;
const hasGoBackLink = referrer && referrer.includes('/accounts');
const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/accounts');
const tabsScrollRef = React.useRef<HTMLDivElement>(null);
......@@ -134,7 +130,7 @@ const AddressPageContent = () => {
<PageTitle
text={ `${ addressQuery.data?.is_contract ? 'Contract' : 'Address' } details` }
additionalsRight={ tagsNode }
backLinkUrl={ hasGoBackLink ? referrer : undefined }
backLinkUrl={ hasGoBackLink ? appProps.referrer : undefined }
backLinkLabel="Back to top accounts list"
/>
) }
......
......@@ -6,7 +6,6 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import { useAppContext } from 'lib/appContext';
import useIsMobile from 'lib/hooks/useIsMobile';
import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import isBrowser from 'lib/isBrowser';
import BlockDetails from 'ui/block/BlockDetails';
import TextAd from 'ui/shared/ad/TextAd';
import Page from 'ui/shared/Page/Page';
......@@ -24,7 +23,6 @@ const TAB_LIST_PROPS = {
const BlockPageContent = () => {
const router = useRouter();
const isMobile = useIsMobile();
const isInBrowser = isBrowser();
const appProps = useAppContext();
const blockTxsQuery = useQueryWithPages({
......@@ -46,15 +44,14 @@ const BlockPageContent = () => {
const hasPagination = !isMobile && router.query.tab === 'txs' && blockTxsQuery.isPaginationVisible;
const referrer = isInBrowser ? window.document.referrer : appProps.referrer;
const hasGoBackLink = referrer && referrer.includes('/blocks');
const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/blocks');
return (
<Page>
<TextAd mb={ 6 }/>
<PageTitle
text={ `Block #${ router.query.id }` }
backLinkUrl={ hasGoBackLink ? referrer : undefined }
backLinkUrl={ hasGoBackLink ? appProps.referrer : undefined }
backLinkLabel="Back to blocks list"
/>
<RoutedTabs
......
......@@ -8,7 +8,6 @@ import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext';
import useIsMobile from 'lib/hooks/useIsMobile';
import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import isBrowser from 'lib/isBrowser';
import AdBanner from 'ui/shared/ad/AdBanner';
import TextAd from 'ui/shared/ad/TextAd';
import Page from 'ui/shared/Page/Page';
......@@ -29,11 +28,8 @@ const TokenPageContent = () => {
const isMobile = useIsMobile();
const appProps = useAppContext();
const isInBrowser = isBrowser();
const referrer = isInBrowser ? window.document.referrer : appProps.referrer;
const hasGoBackLink = referrer && referrer.includes('/tokens');
const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/tokens');
const scrollRef = React.useRef<HTMLDivElement>(null);
......@@ -104,7 +100,7 @@ const TokenPageContent = () => {
<TextAd mb={ 6 }/>
<PageTitle
text={ `${ tokenQuery.data?.name } (${ tokenQuery.data?.symbol }) token` }
backLinkUrl={ hasGoBackLink ? referrer : undefined }
backLinkUrl={ hasGoBackLink ? appProps.referrer : undefined }
backLinkLabel="Back to tokens list"
additionalsLeft={ (
<TokenLogo hash={ tokenQuery.data?.address } name={ tokenQuery.data?.name } boxSize={ 6 }/>
......
......@@ -6,10 +6,9 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext';
import isBrowser from 'lib/isBrowser';
import networkExplorers from 'lib/networks/networkExplorers';
import TextAd from 'ui/shared/ad/TextAd';
import ExternalLink from 'ui/shared/ExternalLink';
import LinkExternal from 'ui/shared/LinkExternal';
import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs';
......@@ -33,11 +32,8 @@ const TABS: Array<RoutedTab> = [
const TransactionPageContent = () => {
const router = useRouter();
const appProps = useAppContext();
const isInBrowser = isBrowser();
const referrer = isInBrowser ? window.document.referrer : appProps.referrer;
const hasGoBackLink = referrer && referrer.includes('/txs');
const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/txs');
const { data } = useApiQuery('tx', {
pathParams: { id: router.query.id?.toString() },
......@@ -48,7 +44,7 @@ const TransactionPageContent = () => {
.filter((explorer) => explorer.paths.tx)
.map((explorer) => {
const url = new URL(explorer.paths.tx + '/' + router.query.id, explorer.baseUrl);
return <ExternalLink key={ explorer.baseUrl } title={ `Open in ${ explorer.title }` } href={ url.toString() }/>;
return <LinkExternal key={ explorer.baseUrl } title={ `Open in ${ explorer.title }` } href={ url.toString() }/>;
});
const additionals = (
......@@ -74,7 +70,7 @@ const TransactionPageContent = () => {
<PageTitle
text="Transaction details"
additionalsRight={ additionals }
backLinkUrl={ hasGoBackLink ? referrer : undefined }
backLinkUrl={ hasGoBackLink ? appProps.referrer : undefined }
backLinkLabel="Back to transactions list"
/>
<RoutedTabs tabs={ TABS }/>
......
import { Text, Link, Flex, Icon, Box, chakra } from '@chakra-ui/react';
import { Text, Flex, Icon, Box, chakra } from '@chakra-ui/react';
import React from 'react';
import type { SearchResultItem } from 'types/api/search';
......@@ -11,6 +11,7 @@ import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile';
import TokenLogo from 'ui/shared/TokenLogo';
......@@ -29,9 +30,9 @@ const SearchResultListItem = ({ data, searchTerm }: Props) => {
return (
<Flex alignItems="flex-start">
<TokenLogo boxSize={ 6 } hash={ data.address } name={ data.name } flexShrink={ 0 }/>
<Link ml={ 2 } href={ link('token_index', { hash: data.address }) } fontWeight={ 700 } wordBreak="break-all">
<LinkInternal ml={ 2 } href={ link('token_index', { hash: data.address }) } fontWeight={ 700 } wordBreak="break-all">
<chakra.span dangerouslySetInnerHTML={{ __html: highlightText(name, searchTerm) }}/>
</Link>
</LinkInternal>
</Flex>
);
}
......@@ -54,9 +55,9 @@ const SearchResultListItem = ({ data, searchTerm }: Props) => {
return (
<Flex alignItems="center">
<Icon as={ blockIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/>
<Link fontWeight={ 700 } href={ link('block', { id: String(data.block_number) }) }>
<LinkInternal fontWeight={ 700 } href={ link('block', { id: String(data.block_number) }) }>
<Box as={ shouldHighlightHash ? 'span' : 'mark' }>{ data.block_number }</Box>
</Link>
</LinkInternal>
</Flex>
);
}
......
import { Tr, Td, Text, Link, Flex, Icon, Box } from '@chakra-ui/react';
import { Tr, Td, Text, Flex, Icon, Box } from '@chakra-ui/react';
import React from 'react';
import type { SearchResultItem } from 'types/api/search';
......@@ -11,6 +11,7 @@ import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal';
import TokenLogo from 'ui/shared/TokenLogo';
interface Props {
......@@ -29,9 +30,9 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => {
<Td fontSize="sm">
<Flex alignItems="center">
<TokenLogo boxSize={ 6 } hash={ data.address } name={ data.name } flexShrink={ 0 }/>
<Link ml={ 2 } href={ link('token_index', { hash: data.address }) } fontWeight={ 700 } wordBreak="break-all">
<LinkInternal ml={ 2 } href={ link('token_index', { hash: data.address }) } fontWeight={ 700 } wordBreak="break-all">
<span dangerouslySetInnerHTML={{ __html: highlightText(name, searchTerm) }}/>
</Link>
</LinkInternal>
</Flex>
</Td>
<Td fontSize="sm" verticalAlign="middle">
......@@ -52,11 +53,11 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => {
<Td fontSize="sm">
<Flex alignItems="center" overflow="hidden">
<AddressIcon address={{ hash: data.address, is_contract: data.type === 'contract', implementation_name: null }} mr={ 2 } flexShrink={ 0 }/>
<Link href={ link('address_index', { id: data.address }) } fontWeight={ 700 } overflow="hidden" whiteSpace="nowrap">
<LinkInternal href={ link('address_index', { id: data.address }) } fontWeight={ 700 } overflow="hidden" whiteSpace="nowrap">
<Box as={ shouldHighlightHash ? 'mark' : 'span' } display="block">
<HashStringShortenDynamic hash={ data.address }/>
</Box>
</Link>
</LinkInternal>
</Flex>
</Td>
<Td fontSize="sm" verticalAlign="middle">
......@@ -86,9 +87,9 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => {
<Td fontSize="sm">
<Flex alignItems="center">
<Icon as={ blockIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/>
<Link fontWeight={ 700 } href={ link('block', { id: String(data.block_number) }) }>
<LinkInternal fontWeight={ 700 } href={ link('block', { id: String(data.block_number) }) }>
<Box as={ shouldHighlightHash ? 'span' : 'mark' }>{ data.block_number }</Box>
</Link>
</LinkInternal>
</Flex>
</Td>
<Td fontSize="sm" verticalAlign="middle">
......
......@@ -9,7 +9,7 @@ interface Props {
className?: string;
}
const ExternalLink = ({ href, title, className }: Props) => {
const LinkExternal = ({ href, title, className }: Props) => {
return (
<Link className={ className } fontSize="sm" display="inline-flex" alignItems="center" target="_blank" href={ href }>
{ title }
......@@ -18,4 +18,4 @@ const ExternalLink = ({ href, title, className }: Props) => {
);
};
export default React.memo(chakra(ExternalLink));
export default React.memo(chakra(LinkExternal));
import type { LinkProps } from '@chakra-ui/react';
import { Link } from '@chakra-ui/react';
import NextLink from 'next/link';
import type { LegacyRef } from 'react';
import React from 'react';
// NOTE! use this component only for links to pages that are completely implemented in new UI
const LinkInternal = (props: LinkProps, ref: LegacyRef<HTMLAnchorElement>) => {
if (!props.href) {
return <Link { ...props } ref={ ref }/>;
}
return (
<NextLink href={ props.href } passHref target={ props.target }>
<Link { ...props } ref={ ref }/>
</NextLink>
);
};
export default React.memo(React.forwardRef(LinkInternal));
import { Heading, Flex, Grid, Tooltip, Link, Icon, chakra } from '@chakra-ui/react';
import { Heading, Flex, Grid, Tooltip, Icon, chakra } from '@chakra-ui/react';
import React from 'react';
import eastArrowIcon from 'icons/arrows/east.svg';
import TextAd from 'ui/shared/ad/TextAd';
import LinkInternal from 'ui/shared/LinkInternal';
type Props = {
text: string;
......@@ -42,9 +43,9 @@ const PageTitle = ({ text, additionalsLeft, additionalsRight, withTextAd, backLi
>
{ backLinkUrl && (
<Tooltip label={ backLinkLabel }>
<Link display="inline-flex" href={ backLinkUrl } h="40px">
<LinkInternal display="inline-flex" href={ backLinkUrl } h="40px">
<Icon as={ eastArrowIcon } boxSize={ 6 } transform="rotate(180deg)" margin="auto"/>
</Link>
</LinkInternal>
</Tooltip>
) }
{ additionalsLeft !== undefined && (
......
import { Link, chakra, shouldForwardProp, Tooltip, Box } from '@chakra-ui/react';
import { chakra, shouldForwardProp, Tooltip, Box } from '@chakra-ui/react';
import type { HTMLAttributeAnchorTarget } from 'react';
import React from 'react';
......@@ -6,6 +6,7 @@ import useIsMobile from 'lib/hooks/useIsMobile';
import link from 'lib/link/link';
import HashStringShorten from 'ui/shared/HashStringShorten';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal';
import TruncatedTextTooltip from '../TruncatedTextTooltip';
......@@ -93,7 +94,7 @@ const AddressLink = (props: Props) => {
}
return (
<Link
<LinkInternal
className={ className }
href={ url }
target={ target }
......@@ -101,7 +102,7 @@ const AddressLink = (props: Props) => {
whiteSpace="nowrap"
>
{ content }
</Link>
</LinkInternal>
);
};
......
......@@ -58,7 +58,7 @@ const LogItem = ({ address, index, topics, data, decoded, type, tx_hash: txHash
<AddressLink
hash={ hasTxInfo ? txHash : address.hash }
alias={ hasTxInfo ? undefined : address.name }
type={ type }
type={ type === 'address' ? 'transaction' : 'address' }
/>
</Address>
{ /* api doesn't have find topic feature yet */ }
......
import { Icon, Link, GridItem, Show, Flex } from '@chakra-ui/react';
import NextLink from 'next/link';
import { Icon, GridItem, Show, Flex } from '@chakra-ui/react';
import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer';
......@@ -7,6 +6,7 @@ import type { TokenTransfer } from 'types/api/tokenTransfer';
import tokenIcon from 'icons/token.svg';
import link from 'lib/link/link';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import LinkInternal from 'ui/shared/LinkInternal';
import { flattenTotal } from 'ui/shared/TokenTransfer/helpers';
import TxDetailsTokenTransfer from './TxDetailsTokenTransfer';
......@@ -64,9 +64,9 @@ const TxDetailsTokenTransfers = ({ data, txHash }: Props) => {
<Show above="lg" ssr={ false }><GridItem></GridItem></Show>
<GridItem fontSize="sm" alignItems="center" display="inline-flex" pl={{ base: '28px', lg: 0 }}>
<Icon as={ tokenIcon } boxSize={ 6 }/>
<NextLink href={ viewAllUrl } passHref>
<Link>View all</Link>
</NextLink>
<LinkInternal href={ viewAllUrl }>
View all
</LinkInternal>
</GridItem>
</>
) }
......
import { Box, Heading, Text, Flex, Link } from '@chakra-ui/react';
import { Box, Heading, Text, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -8,6 +8,7 @@ import appConfig from 'configs/app/config';
import getValueWithUnit from 'lib/getValueWithUnit';
import link from 'lib/link/link';
import CurrencyValue from 'ui/shared/CurrencyValue';
import LinkInternal from 'ui/shared/LinkInternal';
import TextSeparator from 'ui/shared/TextSeparator';
import Utilization from 'ui/shared/Utilization/Utilization';
......@@ -89,7 +90,7 @@ const TxAdditionalInfoContent = ({ tx }: { tx: Transaction }) => {
<Text fontWeight="600" as="span">{ tx.position }</Text>
</Box>
</Box>
<Link fontSize="sm" href={ link('tx', { id: tx.hash }) }>More details</Link>
<LinkInternal fontSize="sm" href={ link('tx', { id: tx.hash }) }>More details</LinkInternal>
</>
);
};
......
......@@ -3,7 +3,6 @@ import {
Box,
Flex,
Icon,
Link,
Text,
} from '@chakra-ui/react';
import React from 'react';
......@@ -20,6 +19,7 @@ import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import InOutTag from 'ui/shared/InOutTag';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile';
import TxStatus from 'ui/shared/TxStatus';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
......@@ -88,7 +88,7 @@ const TxsListItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement }:
{ showBlockInfo && tx.block !== null && (
<Box mt={ 2 }>
<Text as="span">Block </Text>
<Link href={ link('block', { id: tx.block.toString() }) }>{ tx.block }</Link>
<LinkInternal href={ link('block', { id: tx.block.toString() }) }>{ tx.block }</LinkInternal>
</Box>
) }
<Flex alignItems="center" height={ 6 } mt={ 6 }>
......
......@@ -3,7 +3,6 @@ import {
Tr,
Td,
Tag,
Link,
Icon,
VStack,
Text,
......@@ -23,6 +22,7 @@ import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import CurrencyValue from 'ui/shared/CurrencyValue';
import InOutTag from 'ui/shared/InOutTag';
import LinkInternal from 'ui/shared/LinkInternal';
import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
import TxStatus from 'ui/shared/TxStatus';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
......@@ -99,7 +99,7 @@ const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement }
</Td>
{ showBlockInfo && (
<Td>
{ tx.block && <Link href={ link('block', { id: tx.block.toString() }) }>{ tx.block }</Link> }
{ tx.block && <LinkInternal href={ link('block', { id: tx.block.toString() }) }>{ tx.block }</LinkInternal> }
</Td>
) }
<Show above="xl" ssr={ 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