@@ -1,9 +1,11 @@
|
||||
/* eslint-disable max-len */
|
||||
import type { AddressParam } from 'types/api/addressParams';
|
||||
import type { Transaction } from 'types/api/transaction';
|
||||
|
||||
import * as addressMock from 'mocks/address/address';
|
||||
import { publicTag, privateTag, watchlistName } from 'mocks/address/tag';
|
||||
import * as interopMock from 'mocks/interop/interop';
|
||||
import { protocolTag } from 'mocks/metadata/address';
|
||||
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
|
||||
import * as decodedInputDataMock from 'mocks/txs/decodedInputData';
|
||||
|
||||
@@ -88,8 +90,24 @@ export const withWatchListNames: Transaction = {
|
||||
} as Transaction['to'],
|
||||
};
|
||||
|
||||
export const withProtocolTag: Transaction = {
|
||||
...base,
|
||||
hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3194',
|
||||
to: {
|
||||
...(base.to as AddressParam),
|
||||
metadata: {
|
||||
tags: [ protocolTag ],
|
||||
reputation: null,
|
||||
},
|
||||
private_tags: [],
|
||||
watchlist_names: [],
|
||||
public_tags: [],
|
||||
},
|
||||
};
|
||||
|
||||
export const withPendingUpdate: Transaction = {
|
||||
...withWatchListNames,
|
||||
...withProtocolTag,
|
||||
hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3133',
|
||||
is_pending_update: true,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { AddressParam } from 'types/api/addressParams';
|
||||
|
||||
import * as txMock from 'mocks/txs/tx';
|
||||
import * as socketServer from 'playwright/fixtures/socketServer';
|
||||
import { test as base, expect, devices } from 'playwright/lib';
|
||||
import * as pwConfig from 'playwright/utils/config';
|
||||
|
||||
import LatestTxs from './LatestTxs';
|
||||
|
||||
@@ -37,6 +41,50 @@ test('default view +@dark-mode', async({ render, mockApiResponse }) => {
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test.describe('small desktop', () => {
|
||||
test.use({ viewport: pwConfig.viewport.md });
|
||||
test('one tag', async({ render, mockApiResponse }) => {
|
||||
await mockApiResponse('general:homepage_txs', [
|
||||
{
|
||||
...txMock.withProtocolTag,
|
||||
to: {
|
||||
...txMock.withProtocolTag.to,
|
||||
metadata: {
|
||||
tags: [ {
|
||||
slug: 'aerodrome',
|
||||
name: 'Very long protocol name that should be truncated',
|
||||
tagType: 'protocol',
|
||||
ordinal: 0,
|
||||
meta: null,
|
||||
} ],
|
||||
reputation: null,
|
||||
},
|
||||
} as AddressParam,
|
||||
},
|
||||
]);
|
||||
|
||||
const component = await render(
|
||||
<Box maxW="800px">
|
||||
<LatestTxs/>
|
||||
</Box>,
|
||||
);
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test('two or more tags', async({ render, mockApiResponse }) => {
|
||||
await mockApiResponse('general:homepage_txs', [
|
||||
txMock.withWatchListNames,
|
||||
]);
|
||||
|
||||
const component = await render(
|
||||
<Box maxW="800px">
|
||||
<LatestTxs/>
|
||||
</Box>,
|
||||
);
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('socket', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import config from 'configs/app';
|
||||
import { Skeleton } from 'toolkit/chakra/skeleton';
|
||||
import AddressFromTo from 'ui/shared/address/AddressFromTo';
|
||||
import TxEntity from 'ui/shared/entities/tx/TxEntity';
|
||||
import EntityTag from 'ui/shared/EntityTags/EntityTag';
|
||||
import TxStatus from 'ui/shared/statusTag/TxStatus';
|
||||
import TimeWithTooltip from 'ui/shared/time/TimeWithTooltip';
|
||||
import TxFee from 'ui/shared/tx/TxFee';
|
||||
@@ -30,15 +31,25 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => {
|
||||
const dataTo = tx.to ? tx.to : tx.created_contract;
|
||||
const columnNum = config.UI.views.tx.hiddenFields?.value && config.UI.views.tx.hiddenFields?.tx_fee ? 2 : 3;
|
||||
|
||||
const protocolTag = tx.to?.metadata?.tags?.find(tag => tag.tagType === 'protocol');
|
||||
|
||||
const tagsCount = [
|
||||
1, // tx type
|
||||
1, // tx status
|
||||
...(tx.from?.watchlist_names || []),
|
||||
...(tx.to?.watchlist_names || []),
|
||||
protocolTag,
|
||||
].filter(Boolean).length;
|
||||
|
||||
return (
|
||||
<Grid
|
||||
gridTemplateColumns={{
|
||||
lg: columnNum === 2 ? '3fr minmax(auto, 180px)' : '3fr minmax(auto, 180px) 170px',
|
||||
xl: columnNum === 2 ? '3fr minmax(auto, 250px)' : '3fr minmax(auto, 275px) 170px',
|
||||
lg: columnNum === 2 ? '3fr minmax(auto, 200px)' : '3fr minmax(auto, 200px) 170px',
|
||||
xl: columnNum === 2 ? '3fr minmax(auto, 270px)' : '3fr minmax(auto, 300px) 170px',
|
||||
}}
|
||||
gridGap={ 8 }
|
||||
gridGap={ 3 }
|
||||
width="100%"
|
||||
minW="700px"
|
||||
minW={ columnNum === 2 ? '700px' : '750px' }
|
||||
borderBottom="1px solid"
|
||||
borderColor="border.divider"
|
||||
p={ 4 }
|
||||
@@ -47,10 +58,11 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => {
|
||||
<Flex overflow="hidden" w="100%">
|
||||
<TxAdditionalInfo tx={ tx } isLoading={ isLoading } my="3px"/>
|
||||
<Box ml={ 3 } w="calc(100% - 40px)">
|
||||
<HStack flexWrap="wrap" my="3px">
|
||||
<HStack flexWrap={ tagsCount <= 3 ? 'nowrap' : 'wrap' } my="3px">
|
||||
<TxType types={ tx.transaction_types } isLoading={ isLoading }/>
|
||||
<TxStatus status={ tx.status } errorText={ tx.status === 'error' ? tx.result : undefined } isLoading={ isLoading }/>
|
||||
<TxWatchListTags tx={ tx } isLoading={ isLoading }/>
|
||||
{ protocolTag && <EntityTag data={ protocolTag } isLoading={ isLoading } minW="0"/> }
|
||||
</HStack>
|
||||
<Flex
|
||||
alignItems="center"
|
||||
|
||||
@@ -13,6 +13,7 @@ import config from 'configs/app';
|
||||
import { Skeleton } from 'toolkit/chakra/skeleton';
|
||||
import AddressFromTo from 'ui/shared/address/AddressFromTo';
|
||||
import TxEntity from 'ui/shared/entities/tx/TxEntity';
|
||||
import EntityTag from 'ui/shared/EntityTags/EntityTag';
|
||||
import TxStatus from 'ui/shared/statusTag/TxStatus';
|
||||
import TimeWithTooltip from 'ui/shared/time/TimeWithTooltip';
|
||||
import TxFee from 'ui/shared/tx/TxFee';
|
||||
@@ -29,6 +30,8 @@ type Props = {
|
||||
const LatestTxsItem = ({ tx, isLoading }: Props) => {
|
||||
const dataTo = tx.to ? tx.to : tx.created_contract;
|
||||
|
||||
const protocolTag = tx.to?.metadata?.tags?.find(tag => tag.tagType === 'protocol');
|
||||
|
||||
return (
|
||||
<Box
|
||||
width="100%"
|
||||
@@ -38,10 +41,11 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => {
|
||||
display={{ base: 'block', lg: 'none' }}
|
||||
>
|
||||
<Flex justifyContent="space-between">
|
||||
<HStack flexWrap="wrap">
|
||||
<HStack>
|
||||
<TxType types={ tx.transaction_types } isLoading={ isLoading }/>
|
||||
<TxStatus status={ tx.status } errorText={ tx.status === 'error' ? tx.result : undefined } isLoading={ isLoading }/>
|
||||
<TxWatchListTags tx={ tx } isLoading={ isLoading }/>
|
||||
{ protocolTag && <EntityTag data={ protocolTag } isLoading={ isLoading } minW="0"/> }
|
||||
</HStack>
|
||||
<TxAdditionalInfo tx={ tx } isMobile isLoading={ isLoading }/>
|
||||
</Flex>
|
||||
|
||||
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
@@ -27,7 +27,7 @@ const TxWatchListTags = ({ tx, isLoading }: Props) => {
|
||||
key={ tag.label }
|
||||
loading={ isLoading }
|
||||
truncated
|
||||
maxW={{ base: '115px', lg: 'initial' }}
|
||||
maxW={{ base: '115px', lg: '100%' }}
|
||||
colorPalette="gray"
|
||||
>
|
||||
{ tag.display_name }
|
||||
|
||||
@@ -13,6 +13,7 @@ import { Skeleton } from 'toolkit/chakra/skeleton';
|
||||
import AddressFromTo from 'ui/shared/address/AddressFromTo';
|
||||
import BlockEntity from 'ui/shared/entities/block/BlockEntity';
|
||||
import TxEntity from 'ui/shared/entities/tx/TxEntity';
|
||||
import EntityTag from 'ui/shared/EntityTags/EntityTag';
|
||||
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
|
||||
import TxStatus from 'ui/shared/statusTag/TxStatus';
|
||||
import TimeWithTooltip from 'ui/shared/time/TimeWithTooltip';
|
||||
@@ -49,6 +50,8 @@ const TxsListItem = ({
|
||||
}: Props) => {
|
||||
const dataTo = tx.to ? tx.to : tx.created_contract;
|
||||
|
||||
const protocolTag = tx.to?.metadata?.tags?.find(tag => tag.tagType === 'protocol');
|
||||
|
||||
return (
|
||||
<ListItemMobile display="block" width="100%" animation={ animation } key={ tx.hash }>
|
||||
<Flex justifyContent="space-between" alignItems="flex-start" mt={ 4 }>
|
||||
@@ -64,6 +67,7 @@ const TxsListItem = ({
|
||||
}
|
||||
<TxStatus status={ tx.status } errorText={ tx.status === 'error' ? tx.result : undefined } isLoading={ isLoading }/>
|
||||
<TxWatchListTags tx={ tx } isLoading={ isLoading }/>
|
||||
{ protocolTag && <EntityTag data={ protocolTag } isLoading={ isLoading }/> }
|
||||
</HStack>
|
||||
<TxAdditionalInfo tx={ tx } isMobile isLoading={ isLoading }/>
|
||||
</Flex>
|
||||
|
||||
@@ -12,6 +12,7 @@ import AddressFromTo from 'ui/shared/address/AddressFromTo';
|
||||
import BlockPendingUpdateHint from 'ui/shared/block/BlockPendingUpdateHint';
|
||||
import BlockEntity from 'ui/shared/entities/block/BlockEntity';
|
||||
import TxEntity from 'ui/shared/entities/tx/TxEntity';
|
||||
import EntityTag from 'ui/shared/EntityTags/EntityTag';
|
||||
import ChainIcon from 'ui/shared/externalChains/ChainIcon';
|
||||
import TxStatus from 'ui/shared/statusTag/TxStatus';
|
||||
import TimeWithTooltip from 'ui/shared/time/TimeWithTooltip';
|
||||
@@ -48,6 +49,8 @@ const TxsTableItem = ({
|
||||
}: Props) => {
|
||||
const dataTo = tx.to ? tx.to : tx.created_contract;
|
||||
|
||||
const protocolTag = tx.to?.metadata?.tags?.find(tag => tag.tagType === 'protocol');
|
||||
|
||||
return (
|
||||
<TableRow key={ tx.hash } animation={ animation }>
|
||||
<TableCell textAlign="center">
|
||||
@@ -77,7 +80,7 @@ const TxsTableItem = ({
|
||||
</VStack>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<VStack alignItems="start">
|
||||
<VStack alignItems="stretch">
|
||||
{ translationIsLoading || translationData ? (
|
||||
<TxTranslationType
|
||||
txTypes={ tx.transaction_types }
|
||||
@@ -92,11 +95,14 @@ const TxsTableItem = ({
|
||||
</VStack>
|
||||
</TableCell>
|
||||
<TableCell whiteSpace="nowrap">
|
||||
{ tx.method && (
|
||||
<Badge colorPalette={ tx.method === 'Multicall' ? 'teal' : 'gray' } loading={ isLoading } truncated>
|
||||
<span>{ tx.method }</span>
|
||||
</Badge>
|
||||
) }
|
||||
<VStack alignItems="stretch">
|
||||
{ tx.method && (
|
||||
<Badge colorPalette={ tx.method === 'Multicall' ? 'teal' : 'gray' } loading={ isLoading } truncated>
|
||||
<span>{ tx.method }</span>
|
||||
</Badge>
|
||||
) }
|
||||
{ protocolTag && <EntityTag data={ protocolTag } isLoading={ isLoading }/> }
|
||||
</VStack>
|
||||
</TableCell>
|
||||
{ showBlockInfo && (
|
||||
<TableCell>
|
||||
|
||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |