Commit 3e24ed76 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Tx interpretation: change margins between elements (#2241)

Paddings: icons + amount/text in interpretation

Fixes #1997
parent 9657e427
......@@ -391,3 +391,8 @@ export const withRecipientNameTag = {
...withRecipientEns,
to: addressMock.withNameTag,
};
export const withRecipientContract = {
...withRecipientEns,
to: addressMock.contract,
};
......@@ -2,7 +2,7 @@ import type { AddressMetadataTagApi } from './addressMetadata';
export interface AddressImplementation {
address: string;
name: string | null;
name?: string | null;
}
export interface AddressTag {
......
......@@ -42,7 +42,7 @@ const DomainsGrid = ({ data }: { data: Array<bens.Domain> }) => {
rowGap={ 4 }
mt={ 2 }
>
{ data.slice(0, 9).map((domain) => <EnsEntity key={ domain.id } name={ domain.name } protocol={ domain.protocol } noCopy/>) }
{ data.slice(0, 9).map((domain) => <EnsEntity key={ domain.id } domain={ domain.name } protocol={ domain.protocol } noCopy/>) }
</Grid>
);
};
......@@ -126,7 +126,7 @@ const AddressEnsDomains = ({ query, addressHash, mainDomainName }: Props) => {
<Box w="100%">
<chakra.span color="text_secondary" fontSize="xs">Primary*</chakra.span>
<Flex alignItems="center" fontSize="md" mt={ 2 }>
<EnsEntity name={ mainDomain.name } protocol={ mainDomain.protocol } fontWeight={ 600 } noCopy/>
<EnsEntity domain={ mainDomain.name } protocol={ mainDomain.protocol } fontWeight={ 600 } noCopy/>
{ mainDomain.expiry_date &&
<chakra.span color="text_secondary" whiteSpace="pre"> (expires { dayjs(mainDomain.expiry_date).fromNow() })</chakra.span> }
</Flex>
......
......@@ -25,7 +25,7 @@ const NameDomainsListItem = ({
<ListItemMobileGrid.Container>
<ListItemMobileGrid.Label isLoading={ isLoading }>Domain</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value>
<EnsEntity name={ name } protocol={ protocol } isLoading={ isLoading } fontWeight={ 500 }/>
<EnsEntity domain={ name } protocol={ protocol } isLoading={ isLoading } fontWeight={ 500 }/>
</ListItemMobileGrid.Value>
{ resolvedAddress && (
......
......@@ -24,7 +24,7 @@ const NameDomainsTableItem = ({
return (
<Tr>
<Td verticalAlign="middle">
<EnsEntity name={ name } protocol={ protocol } isLoading={ isLoading } fontWeight={ 600 }/>
<EnsEntity domain={ name } protocol={ protocol } isLoading={ isLoading } fontWeight={ 600 }/>
</Td>
<Td verticalAlign="middle">
{ resolvedAddress && <AddressEntity address={ resolvedAddress } isLoading={ isLoading } fontWeight={ 500 }/> }
......
......@@ -272,7 +272,11 @@ const AddressPageContent = () => {
const titleContentAfter = (
<EntityTags
tags={ tags }
isLoading={ isLoading || (config.features.addressMetadata.isEnabled && addressMetadataQuery.isPending) }
isLoading={
isLoading ||
(config.features.userOps.isEnabled && userOpsAccountQuery.isPlaceholderData) ||
(config.features.addressMetadata.isEnabled && addressMetadataQuery.isPending)
}
/>
);
......@@ -302,7 +306,7 @@ const AddressPageContent = () => {
<Flex alignItems="center" w="100%" columnGap={ 2 } rowGap={ 2 } flexWrap={{ base: 'wrap', lg: 'nowrap' }}>
{ addressQuery.data?.ens_domain_name && (
<EnsEntity
name={ addressQuery.data?.ens_domain_name }
domain={ addressQuery.data?.ens_domain_name }
protocol={ !addressEnsDomainsQuery.isPending ? addressMainDomain?.protocol : null }
fontFamily="heading"
fontSize="lg"
......@@ -319,7 +323,7 @@ const AddressPageContent = () => {
fontWeight={ 500 }
noLink
isSafeAddress={ isSafeAddress }
iconColor={ isSafeAddress ? safeIconColor : undefined }
icon={{ color: isSafeAddress ? safeIconColor : undefined }}
mr={ 4 }
/>
{ !isLoading && addressQuery.data?.is_contract && addressQuery.data.token &&
......
......@@ -167,7 +167,7 @@ const BlockPageContent = () => {
})();
const titleSecondRow = (
<>
{ !config.UI.views.block.hiddenFields?.miner && (
{ !config.UI.views.block.hiddenFields?.miner && blockQuery.data?.miner && (
<Skeleton
isLoaded={ !blockQuery.isPlaceholderData }
fontFamily="heading"
......@@ -179,7 +179,7 @@ const BlockPageContent = () => {
<chakra.span flexShrink={ 0 }>
{ `${ capitalize(getNetworkValidationActionText()) } by` }
</chakra.span>
<AddressEntity address={ blockQuery.data?.miner }/>
<AddressEntity address={ blockQuery.data.miner }/>
</Skeleton>
) }
<NetworkExplorers type="block" pathParam={ heightOrHash } ml={{ base: config.UI.views.block.hiddenFields?.miner ? 0 : 3, lg: 'auto' }}/>
......
......@@ -155,7 +155,7 @@ const CsvExport = () => {
const limit = (configQuery.data?.limit || 10_000).toLocaleString(undefined, { maximumFractionDigits: 3, notation: 'compact' });
if (exportTypeParam === 'holders') {
if (exportTypeParam === 'holders' && tokenQuery.data) {
return (
<Flex mb={ 10 } whiteSpace="pre-wrap" flexWrap="wrap">
<span>Export { exportType.text } for token </span>
......@@ -173,6 +173,10 @@ const CsvExport = () => {
);
}
if (!addressQuery.data) {
return null;
}
return (
<Flex mb={ 10 } whiteSpace="pre-wrap" flexWrap="wrap">
<span>Export { exportType.text } for address </span>
......
......@@ -57,7 +57,7 @@ const NameDomain = () => {
flexWrap={{ base: 'wrap', lg: 'nowrap' }}
>
<EnsEntity
name={ domainName }
domain={ domainName }
protocol={ infoQuery.data?.protocol }
isLoading={ isLoading }
noLink
......
......@@ -60,7 +60,7 @@ const DefaultView = () => {
beforeTitle={ (
<TokenEntity.Icon
token={ tokenData }
iconSize="lg"
size="lg"
/>
) }
backLink={ backLink }
......
......@@ -52,7 +52,7 @@ const LongNameAndManyTags = () => {
beforeTitle={ (
<TokenEntity.Icon
token={ tokenData }
iconSize="lg"
size="lg"
/>
) }
contentAfter={ contentAfter }
......
......@@ -29,7 +29,7 @@ const NftTokenTransferSnippet = ({ value, token, tokenId }: Props) => {
hash={ token.address }
id={ tokenId }
fontWeight={ 600 }
iconSize="md"
icon={{ size: 'md' }}
maxW={{ base: '100%', lg: '150px' }}
w="auto"
flexShrink={ 0 }
......
......@@ -9,7 +9,7 @@ import { test, expect } from 'playwright/lib';
import AddressEntity from './AddressEntity';
const iconSizes = [ 'md', 'lg' ];
const iconSizes = [ 'md', 'lg' ] as const;
test.use({ viewport: { width: 180, height: 140 } });
......@@ -19,7 +19,7 @@ test.describe('icon size', () => {
const component = await render(
<AddressEntity
address={ addressMock.withoutName }
iconSize={ size }
icon={{ size }}
/>,
);
......@@ -69,7 +69,7 @@ test.describe('proxy contract', () => {
test('without implementation name', async({ render, page }) => {
const component = await render(
<AddressEntity
address={{ ...addressMock.contract, implementations: [ { address: addressMock.contract.implementations?.[0].address } ] }}
address={{ ...addressMock.contract, implementations: [ { address: addressMock.contract.implementations?.[0].address as string } ] }}
/>,
);
......@@ -81,7 +81,7 @@ test.describe('proxy contract', () => {
test('without any name', async({ render, page }) => {
const component = await render(
<AddressEntity
address={{ ...addressMock.contract, name: undefined, implementations: [ { address: addressMock.contract.implementations?.[0].address } ] }}
address={{ ...addressMock.contract, name: undefined, implementations: [ { address: addressMock.contract.implementations?.[0].address as string } ] }}
/>,
);
......
import type { As } from '@chakra-ui/react';
import { Box, Flex, Skeleton, Tooltip, chakra, VStack } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import type { AddressParam } from 'types/api/addressParams';
......@@ -10,7 +9,7 @@ import { route } from 'nextjs-routes';
import { useAddressHighlightContext } from 'lib/contexts/addressHighlight';
import * as EntityBase from 'ui/shared/entities/base/components';
import { getIconProps } from '../base/utils';
import { distributeEntityProps, getIconProps } from '../base/utils';
import AddressEntityContentProxy from './AddressEntityContentProxy';
import AddressIdenticon from './AddressIdenticon';
......@@ -29,10 +28,7 @@ const Link = chakra((props: LinkProps) => {
);
});
type IconProps = Omit<EntityBase.IconBaseProps, 'name'> & Pick<EntityProps, 'address' | 'isSafeAddress'> & {
asProp?: As;
name?: EntityBase.IconBaseProps['name'];
};
type IconProps = Pick<EntityProps, 'address' | 'isSafeAddress'> & EntityBase.IconBaseProps;
const Icon = (props: IconProps) => {
if (props.noIcon) {
......@@ -40,8 +36,8 @@ const Icon = (props: IconProps) => {
}
const styles = {
...getIconProps(props.iconSize),
marginRight: 2,
...getIconProps(props.size),
marginRight: props.marginRight ?? 2,
};
if (props.isLoading) {
......@@ -80,7 +76,7 @@ const Icon = (props: IconProps) => {
return (
<Flex marginRight={ styles.marginRight }>
<AddressIdenticon
size={ props.iconSize === 'lg' ? 30 : 20 }
size={ props.size === 'lg' ? 30 : 20 }
hash={ props.address.hash }
/>
</Flex>
......@@ -137,18 +133,18 @@ const Copy = (props: CopyProps) => {
const Container = EntityBase.Container;
interface AddressProp extends Partial<AddressParam> {
hash: string;
}
export interface EntityProps extends EntityBase.EntityBaseProps {
address: Pick<AddressParam,
'hash' | 'name' | 'is_contract' | 'is_verified' | 'implementations' | 'ens_domain_name' | 'metadata'
>;
address: AddressProp;
isSafeAddress?: boolean;
noHighlight?: boolean;
}
const AddressEntry = (props: EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const partsProps = distributeEntityProps(props);
const context = useAddressHighlightContext(props.noHighlight);
return (
......@@ -162,16 +158,16 @@ const AddressEntry = (props: EntityProps) => {
position="relative"
zIndex={ 0 }
>
<Icon { ...partsProps } color={ props.iconColor }/>
<Link { ...linkProps }>
<Content { ...partsProps }/>
<Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }>
<Content { ...partsProps.content }/>
</Link>
<Copy { ...partsProps }/>
<Copy { ...partsProps.copy }/>
</Container>
);
};
export default React.memo(chakra(AddressEntry));
export default React.memo(chakra<As, EntityProps>(AddressEntry));
export {
Container,
......
......@@ -18,9 +18,7 @@ export type Truncation = 'constant' | 'constant_long' | 'dynamic' | 'tail' | 'no
export interface EntityBaseProps {
className?: string;
href?: string;
iconName?: IconName;
iconSize?: IconSize;
iconColor?: IconProps['color'];
icon?: EntityIconProps;
isExternal?: boolean;
isLoading?: boolean;
noCopy?: boolean;
......@@ -81,28 +79,30 @@ const Link = chakra(({ isLoading, children, isExternal, onClick, href, noLink }:
);
});
export interface IconBaseProps extends Pick<EntityBaseProps, 'isLoading' | 'iconSize' | 'noIcon'> {
name: IconName;
color?: IconProps['color'];
borderRadius?: IconProps['borderRadius'];
interface EntityIconProps extends Pick<IconProps, 'color' | 'borderRadius' | 'marginRight' | 'boxSize'> {
name?: IconName;
size?: IconSize;
}
const Icon = ({ isLoading, iconSize, noIcon, name, color, borderRadius }: IconBaseProps) => {
export interface IconBaseProps extends Pick<EntityBaseProps, 'isLoading' | 'noIcon'>, EntityIconProps {
}
const Icon = ({ isLoading, noIcon, size, name, color, borderRadius, marginRight, boxSize }: IconBaseProps) => {
const defaultColor = useColorModeValue('gray.500', 'gray.400');
if (noIcon) {
if (noIcon || !name) {
return null;
}
const styles = getIconProps(iconSize);
const styles = getIconProps(size);
return (
<IconSvg
name={ name }
boxSize={ styles.boxSize }
boxSize={ boxSize ?? styles.boxSize }
isLoading={ isLoading }
borderRadius={ borderRadius ?? 'base' }
display="block"
mr={ 2 }
mr={ marginRight ?? 2 }
color={ color ?? defaultColor }
minW={ 0 }
flexShrink={ 0 }
......
import type { EntityBaseProps } from './components';
export type IconSize = 'md' | 'lg';
export function getIconProps(size: IconSize = 'md') {
......@@ -14,3 +16,16 @@ export function getIconProps(size: IconSize = 'md') {
}
}
}
export function distributeEntityProps<Props extends EntityBaseProps>(props: Props) {
const { className, onClick, icon, ...restProps } = props;
return {
container: { className },
icon: { ...restProps, ...icon },
link: { ...restProps, onClick },
content: restProps,
symbol: restProps,
copy: restProps,
};
}
import type { As } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
import * as EntityBase from 'ui/shared/entities/base/components';
import { distributeEntityProps } from '../base/utils';
type LinkProps = EntityBase.LinkBaseProps & Pick<EntityProps, 'hash'>;
const Link = chakra((props: LinkProps) => {
......@@ -21,11 +23,7 @@ const Link = chakra((props: LinkProps) => {
);
});
type IconProps = Omit<EntityBase.IconBaseProps, 'name'> & {
name?: EntityBase.IconBaseProps['name'];
};
const Icon = (props: IconProps) => {
const Icon = (props: EntityBase.IconBaseProps) => {
return (
<EntityBase.Icon
{ ...props }
......@@ -65,21 +63,20 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
}
const BlobEntity = (props: EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const partsProps = distributeEntityProps(props);
return (
<Container className={ props.className }>
<Icon { ...partsProps }/>
<Link { ...linkProps }>
<Content { ...partsProps }/>
<Container { ...partsProps.container }>
<Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }>
<Content { ...partsProps.content }/>
</Link>
<Copy { ...partsProps }/>
<Copy { ...partsProps.copy }/>
</Container>
);
};
export default React.memo(chakra(BlobEntity));
export default React.memo(chakra<As, EntityProps>(BlobEntity));
export {
Container,
......
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
......@@ -11,25 +10,17 @@ import * as BlobEntity from './BlobEntity';
const rollupFeature = config.features.rollup;
const BlobEntityL1 = (props: BlobEntity.EntityProps) => {
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const linkProps = _omit(props, [ 'className' ]);
if (!rollupFeature.isEnabled) {
return null;
}
const defaultHref = rollupFeature.L1BaseUrl + route({
pathname: '/blobs/[hash]',
query: { hash: props.hash },
});
return (
<BlobEntity.Container className={ props.className }>
<BlobEntity.Icon { ...partsProps }/>
<BlobEntity.Link
{ ...linkProps }
isExternal
href={ rollupFeature.L1BaseUrl + route({ pathname: '/blobs/[hash]', query: { hash: props.hash } }) }
>
<BlobEntity.Content { ...partsProps }/>
</BlobEntity.Link>
<BlobEntity.Copy { ...partsProps }/>
</BlobEntity.Container>
<BlobEntity.default { ...props } href={ props.href ?? defaultHref } isExternal/>
);
};
......
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
......@@ -11,23 +10,18 @@ import * as BlockEntity from './BlockEntity';
const rollupFeature = config.features.rollup;
const BatchEntityL2 = (props: BlockEntity.EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
if (!rollupFeature.isEnabled) {
return null;
}
const defaultHref = route({ pathname: '/batches/[number]', query: { number: props.number.toString() } });
return (
<BlockEntity.Container className={ props.className }>
<BlockEntity.Icon { ...partsProps } name="txn_batches_slim"/>
<BlockEntity.Link
{ ...linkProps }
href={ route({ pathname: '/batches/[number]', query: { number: props.number.toString() } }) }
>
<BlockEntity.Content { ...partsProps }/>
</BlockEntity.Link>
</BlockEntity.Container>
<BlockEntity.default
{ ...props }
href={ props.href ?? defaultHref }
icon={{ name: 'txn_batches_slim' }}
/>
);
};
......
......@@ -4,7 +4,7 @@ import { test, expect } from 'playwright/lib';
import BlockEntity from './BlockEntity';
const iconSizes = [ 'md', 'lg' ];
const iconSizes = [ 'md', 'lg' ] as const;
test.use({ viewport: { width: 180, height: 30 } });
......@@ -14,7 +14,7 @@ test.describe('icon sizes', () => {
const component = await render(
<BlockEntity
number={ 17943507 }
iconSize={ size }
icon={{ size }}
/>,
);
......
import type { As } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
import * as EntityBase from 'ui/shared/entities/base/components';
import { distributeEntityProps } from '../base/utils';
type LinkProps = EntityBase.LinkBaseProps & Partial<Pick<EntityProps, 'hash' | 'number'>>;
const Link = chakra((props: LinkProps) => {
......@@ -22,11 +24,7 @@ const Link = chakra((props: LinkProps) => {
);
});
type IconProps = Omit<EntityBase.IconBaseProps, 'name'> & {
name?: EntityBase.IconBaseProps['name'];
};
const Icon = (props: IconProps) => {
const Icon = (props: EntityBase.IconBaseProps) => {
return (
<EntityBase.Icon
{ ...props }
......@@ -55,20 +53,19 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
}
const BlockEntity = (props: EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const partsProps = distributeEntityProps(props);
return (
<Container className={ props.className }>
<Icon { ...partsProps }/>
<Link { ...linkProps }>
<Content { ...partsProps }/>
<Container { ...partsProps.container }>
<Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }>
<Content { ...partsProps.content }/>
</Link>
</Container>
);
};
export default React.memo(chakra(BlockEntity));
export default React.memo(chakra<As, EntityProps>(BlockEntity));
export {
Container,
......
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
......@@ -11,25 +10,16 @@ import * as BlockEntity from './BlockEntity';
const rollupFeature = config.features.rollup;
const BlockEntityL1 = (props: BlockEntity.EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
if (!rollupFeature.isEnabled) {
return null;
}
return (
<BlockEntity.Container className={ props.className }>
<BlockEntity.Icon { ...partsProps }/>
<BlockEntity.Link
{ ...linkProps }
isExternal
href={ rollupFeature.L1BaseUrl + route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: props.hash ?? String(props.number) } }) }
>
<BlockEntity.Content { ...partsProps }/>
</BlockEntity.Link>
</BlockEntity.Container>
);
const defaultHref = rollupFeature.L1BaseUrl + route({
pathname: '/block/[height_or_hash]',
query: { height_or_hash: props.hash ?? String(props.number) },
});
return <BlockEntity.default { ...props } href={ props.href ?? defaultHref } isExternal/>;
};
export default chakra(BlockEntityL1);
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import config from 'configs/app';
......@@ -9,21 +8,11 @@ import * as BlockEntity from './BlockEntity';
const rollupFeature = config.features.rollup;
const BlockEntityL2 = (props: BlockEntity.EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
if (!rollupFeature.isEnabled) {
return null;
}
return (
<BlockEntity.Container className={ props.className }>
<BlockEntity.Icon { ...partsProps } name="txn_batches_slim"/>
<BlockEntity.Link { ...linkProps }>
<BlockEntity.Content { ...partsProps }/>
</BlockEntity.Link>
</BlockEntity.Container>
);
return <BlockEntity.default { ...props } icon={{ name: 'txn_batches_slim' }}/>;
};
export default chakra(BlockEntityL2);
......@@ -6,7 +6,7 @@ import { test, expect } from 'playwright/lib';
import EnsEntity from './EnsEntity';
const name = 'cat.eth';
const iconSizes = [ 'md', 'lg' ];
const iconSizes = [ 'md', 'lg' ] as const;
test.use({ viewport: { width: 180, height: 30 } });
......@@ -15,8 +15,8 @@ test.describe('icon size', () => {
test(size, async({ render }) => {
const component = await render(
<EnsEntity
name={ name }
iconSize={ size }
domain={ name }
icon={{ size }}
/>,
);
......@@ -28,7 +28,7 @@ test.describe('icon size', () => {
test('loading', async({ render }) => {
const component = await render(
<EnsEntity
name={ name }
domain={ name }
isLoading
/>,
);
......@@ -39,7 +39,7 @@ test('loading', async({ render }) => {
test('with long name', async({ render }) => {
const component = await render(
<EnsEntity
name="kitty.kitty.kitty.cat.eth"
domain="kitty.kitty.kitty.cat.eth"
/>,
);
......@@ -51,7 +51,7 @@ test('with long name', async({ render }) => {
test('customization', async({ render }) => {
const component = await render(
<EnsEntity
name={ name }
domain={ name }
p={ 3 }
borderWidth="1px"
borderColor="blue.700"
......@@ -68,7 +68,7 @@ test.describe('', () => {
const component = await render(
<EnsEntity
name={ name }
domain={ name }
protocol={ domainMock.protocolA }
/>,
);
......
import type { As } from '@chakra-ui/react';
import { Box, chakra, Flex, Image, PopoverBody, PopoverContent, PopoverTrigger, Portal, Skeleton, Text } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import type * as bens from '@blockscout/bens-types';
......@@ -12,12 +12,12 @@ import IconSvg from 'ui/shared/IconSvg';
import LinkExternal from 'ui/shared/links/LinkExternal';
import TruncatedValue from 'ui/shared/TruncatedValue';
import { getIconProps } from '../base/utils';
import { distributeEntityProps, getIconProps } from '../base/utils';
type LinkProps = EntityBase.LinkBaseProps & Pick<EntityProps, 'name'>;
type LinkProps = EntityBase.LinkBaseProps & Pick<EntityProps, 'domain'>;
const Link = chakra((props: LinkProps) => {
const defaultHref = route({ pathname: '/name-domains/[name]', query: { name: props.name } });
const defaultHref = route({ pathname: '/name-domains/[name]', query: { name: props.domain } });
return (
<EntityBase.Link
......@@ -29,15 +29,13 @@ const Link = chakra((props: LinkProps) => {
);
});
type IconProps = Omit<EntityBase.IconBaseProps, 'name'> & Pick<EntityProps, 'protocol'> & {
iconName?: EntityBase.IconBaseProps['name'];
};
type IconProps = Pick<EntityProps, 'protocol'> & EntityBase.IconBaseProps;
const Icon = (props: IconProps) => {
const icon = <EntityBase.Icon { ...props } name={ props.iconName ?? 'ENS_slim' }/>;
const icon = <EntityBase.Icon { ...props } name={ props.name ?? 'ENS_slim' }/>;
if (props.protocol) {
const styles = getIconProps(props.iconSize);
const styles = getIconProps(props.size);
if (props.isLoading) {
return <Skeleton boxSize={ styles.boxSize } borderRadius="sm" mr={ 2 }/>;
......@@ -98,24 +96,24 @@ const Icon = (props: IconProps) => {
return icon;
};
type ContentProps = Omit<EntityBase.ContentBaseProps, 'text'> & Pick<EntityProps, 'name'>;
type ContentProps = Omit<EntityBase.ContentBaseProps, 'text'> & Pick<EntityProps, 'domain'>;
const Content = chakra((props: ContentProps) => {
return (
<TruncatedValue
isLoading={ props.isLoading }
value={ props.name }
value={ props.domain }
/>
);
});
type CopyProps = Omit<EntityBase.CopyBaseProps, 'text'> & Pick<EntityProps, 'name'>;
type CopyProps = Omit<EntityBase.CopyBaseProps, 'text'> & Pick<EntityProps, 'domain'>;
const Copy = (props: CopyProps) => {
return (
<EntityBase.Copy
{ ...props }
text={ props.name }
text={ props.domain }
/>
);
};
......@@ -123,26 +121,25 @@ const Copy = (props: CopyProps) => {
const Container = EntityBase.Container;
export interface EntityProps extends EntityBase.EntityBaseProps {
name: string;
domain: string;
protocol?: bens.ProtocolInfo | null;
}
const EnsEntity = (props: EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const partsProps = distributeEntityProps(props);
return (
<Container className={ props.className }>
<Icon { ...partsProps }/>
<Link { ...linkProps }>
<Content { ...partsProps }/>
<Container { ...partsProps.container }>
<Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }>
<Content { ...partsProps.content }/>
</Link>
<Copy { ...partsProps }/>
<Copy { ...partsProps.copy }/>
</Container>
);
};
export default React.memo(chakra(EnsEntity));
export default React.memo(chakra<As, EntityProps>(EnsEntity));
export {
Container,
......
......@@ -4,7 +4,7 @@ import { test, expect } from 'playwright/lib';
import NftEntity from './NftEntity';
const iconSizes = [ 'md', 'lg' ];
const iconSizes = [ 'md', 'lg' ] as const;
const hash = '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859';
test.use({ viewport: { width: 180, height: 30 } });
......@@ -15,8 +15,8 @@ test.describe('icon sizes', () => {
const component = await render(
<NftEntity
hash={ hash }
id={ 1042 }
iconSize={ size }
id="1042"
icon={{ size }}
/>,
);
......@@ -29,7 +29,7 @@ test('loading', async({ render }) => {
const component = await render(
<NftEntity
hash={ hash }
id={ 1042 }
id="1042"
isLoading
/>,
);
......@@ -41,7 +41,7 @@ test('long id', async({ render }) => {
const component = await render(
<NftEntity
hash={ hash }
id={ 1794350723452223 }
id="1794350723452223"
/>,
);
......@@ -52,7 +52,7 @@ test('customization', async({ render }) => {
const component = await render(
<NftEntity
hash={ hash }
id={ 1042 }
id="1042"
p={ 3 }
borderWidth="1px"
borderColor="blue.700"
......
import type { As } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
......@@ -7,13 +7,11 @@ import { route } from 'nextjs-routes';
import * as EntityBase from 'ui/shared/entities/base/components';
import TruncatedValue from 'ui/shared/TruncatedValue';
const Container = EntityBase.Container;
import { distributeEntityProps } from '../base/utils';
type IconProps = Pick<EntityProps, 'isLoading' | 'noIcon' | 'iconSize'> & {
name?: EntityBase.IconBaseProps['name'];
};
const Container = EntityBase.Container;
const Icon = (props: IconProps) => {
const Icon = (props: EntityBase.IconBaseProps) => {
if (props.noIcon) {
return null;
}
......@@ -21,7 +19,7 @@ const Icon = (props: IconProps) => {
return (
<EntityBase.Icon
{ ...props }
iconSize={ props.iconSize ?? 'lg' }
size={ props.size ?? 'lg' }
name={ props.name ?? 'nft_shield' }
/>
);
......@@ -59,20 +57,19 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
}
const NftEntity = (props: EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const partsProps = distributeEntityProps(props);
return (
<Container className={ props.className } w="100%">
<Icon { ...partsProps }/>
<Link { ...linkProps }>
<Content { ...partsProps }/>
<Container w="100%" { ...partsProps.container }>
<Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }>
<Content { ...partsProps.content }/>
</Link>
</Container>
);
};
export default React.memo(chakra(NftEntity));
export default React.memo(chakra<As, EntityProps>(NftEntity));
export {
Container,
......
......@@ -6,7 +6,7 @@ import { test, expect } from 'playwright/lib';
import TokenEntity from './TokenEntity';
const iconSizes = [ 'md', 'lg' ];
const iconSizes = [ 'md', 'lg' ] as const;
test.use({ viewport: { width: 300, height: 100 } });
......@@ -16,7 +16,7 @@ test.describe('icon size', () => {
const component = await render(
<TokenEntity
token={ tokenMock.tokenInfo }
iconSize={ size }
icon={{ size }}
/>,
);
......@@ -37,6 +37,7 @@ test('with logo, long name and symbol', async({ page, render }) => {
await render(
<TokenEntity
token={{
type: 'ERC-20',
name: 'This token is the best token ever',
symbol: 'DUCK DUCK DUCK',
address: tokenMock.tokenInfo.address,
......
import type { ChakraProps } from '@chakra-ui/react';
import type { As } from '@chakra-ui/react';
import { Image, Skeleton, chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import type { TokenInfo } from 'types/api/token';
......@@ -11,7 +10,7 @@ import * as EntityBase from 'ui/shared/entities/base/components';
import TokenLogoPlaceholder from 'ui/shared/TokenLogoPlaceholder';
import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
import { getIconProps } from '../base/utils';
import { distributeEntityProps, getIconProps } from '../base/utils';
type LinkProps = EntityBase.LinkBaseProps & Pick<EntityProps, 'token'>;
......@@ -28,10 +27,7 @@ const Link = chakra((props: LinkProps) => {
);
});
type IconProps = Pick<EntityProps, 'token' | 'isLoading' | 'iconSize' | 'noIcon' | 'className'> & {
marginRight?: ChakraProps['marginRight'];
boxSize?: ChakraProps['boxSize'];
};
type IconProps = Pick<EntityProps, 'token' | 'className'> & EntityBase.IconBaseProps;
const Icon = (props: IconProps) => {
if (props.noIcon) {
......@@ -40,7 +36,7 @@ const Icon = (props: IconProps) => {
const styles = {
marginRight: props.marginRight ?? 2,
boxSize: props.boxSize ?? getIconProps(props.iconSize).boxSize,
boxSize: props.boxSize ?? getIconProps(props.size).boxSize,
borderRadius: 'base',
flexShrink: 0,
};
......@@ -143,22 +139,21 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
}
const TokenEntity = (props: EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const partsProps = distributeEntityProps(props);
return (
<Container className={ props.className } w="100%">
<Icon { ...partsProps }/>
<Link { ...linkProps }>
<Content { ...partsProps }/>
<Container w="100%" { ...partsProps.container }>
<Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }>
<Content { ...partsProps.content }/>
</Link>
<Symbol { ...partsProps }/>
<Copy { ...partsProps }/>
<Symbol { ...partsProps.symbol }/>
<Copy { ...partsProps.copy }/>
</Container>
);
};
export default React.memo(chakra(TokenEntity));
export default React.memo(chakra<As, EntityProps>(TokenEntity));
export {
Container,
......
......@@ -5,7 +5,7 @@ import { test, expect } from 'playwright/lib';
import TxEntity from './TxEntity';
const hash = '0x376db52955d5bce114d0ccea2dcf22289b4eae1b86bcae5a59bb5fdbfef48899';
const iconSizes = [ 'md', 'lg' ];
const iconSizes = [ 'md', 'lg' ] as const;
test.use({ viewport: { width: 180, height: 30 } });
......@@ -15,7 +15,7 @@ test.describe('icon size', () => {
const component = await render(
<TxEntity
hash={ hash }
iconSize={ size }
icon={{ size }}
/>,
);
......
import type { As } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
import * as EntityBase from 'ui/shared/entities/base/components';
import { distributeEntityProps } from '../base/utils';
type LinkProps = EntityBase.LinkBaseProps & Pick<EntityProps, 'hash'>;
const Link = chakra((props: LinkProps) => {
......@@ -21,11 +23,7 @@ const Link = chakra((props: LinkProps) => {
);
});
type IconProps = Omit<EntityBase.IconBaseProps, 'name'> & {
name?: EntityBase.IconBaseProps['name'];
};
const Icon = (props: IconProps) => {
const Icon = (props: EntityBase.IconBaseProps) => {
return (
<EntityBase.Icon
{ ...props }
......@@ -66,21 +64,20 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
}
const TxEntity = (props: EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const partsProps = distributeEntityProps(props);
return (
<Container className={ props.className }>
<Icon { ...partsProps } name={ props.iconName } color={ props.iconColor }/>
<Link { ...linkProps }>
<Content { ...partsProps }/>
<Container { ...partsProps.container }>
<Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }>
<Content { ...partsProps.content }/>
</Link>
<Copy { ...partsProps }/>
<Copy { ...partsProps.copy }/>
</Container>
);
};
export default React.memo(chakra(TxEntity));
export default React.memo(chakra<As, EntityProps>(TxEntity));
export {
Container,
......
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
......@@ -11,26 +10,16 @@ import * as TxEntity from './TxEntity';
const rollupFeature = config.features.rollup;
const TxEntityL1 = (props: TxEntity.EntityProps) => {
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const linkProps = _omit(props, [ 'className' ]);
if (!rollupFeature.isEnabled) {
return null;
}
return (
<TxEntity.Container className={ props.className }>
<TxEntity.Icon { ...partsProps }/>
<TxEntity.Link
{ ...linkProps }
isExternal
href={ rollupFeature.L1BaseUrl + route({ pathname: '/tx/[hash]', query: { hash: props.hash } }) }
>
<TxEntity.Content { ...partsProps }/>
</TxEntity.Link>
<TxEntity.Copy { ...partsProps }/>
</TxEntity.Container>
);
const defaultHref = rollupFeature.L1BaseUrl + route({
pathname: '/tx/[hash]',
query: { hash: props.hash },
});
return <TxEntity.default { ...props } href={ props.href ?? defaultHref } isExternal/>;
};
export default chakra(TxEntityL1);
......@@ -5,7 +5,7 @@ import { test, expect } from 'playwright/lib';
import UserOpEntity from './UserOpEntity';
const hash = '0x376db52955d5bce114d0ccea2dcf22289b4eae1b86bcae5a59bb5fdbfef48899';
const iconSizes = [ 'md', 'lg' ];
const iconSizes = [ 'md', 'lg' ] as const;
test.use({ viewport: { width: 180, height: 30 } });
......@@ -15,7 +15,7 @@ test.describe('icon size', () => {
const component = await render(
<UserOpEntity
hash={ hash }
iconSize={ size }
icon={{ size }}
/>,
);
......
import type { As } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
import * as EntityBase from 'ui/shared/entities/base/components';
import { distributeEntityProps } from '../base/utils';
type LinkProps = EntityBase.LinkBaseProps & Pick<EntityProps, 'hash'>;
const Link = chakra((props: LinkProps) => {
......@@ -21,11 +23,7 @@ const Link = chakra((props: LinkProps) => {
);
});
type IconProps = Omit<EntityBase.IconBaseProps, 'name'> & {
name?: EntityBase.IconBaseProps['name'];
};
const Icon = (props: IconProps) => {
const Icon = (props: EntityBase.IconBaseProps) => {
return (
<EntityBase.Icon
{ ...props }
......@@ -65,21 +63,20 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
}
const UserOpEntity = (props: EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
const partsProps = distributeEntityProps(props);
return (
<Container className={ props.className }>
<Icon { ...partsProps }/>
<Link { ...linkProps }>
<Content { ...partsProps }/>
<Container { ...partsProps.container }>
<Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }>
<Content { ...partsProps.content }/>
</Link>
<Copy { ...partsProps }/>
<Copy { ...partsProps.copy }/>
</Container>
);
};
export default React.memo(chakra(UserOpEntity));
export default React.memo(chakra<As, EntityProps>(UserOpEntity));
export {
Container,
......
......@@ -33,7 +33,7 @@ const Row = ({ name, type, indexed, value, isLoading }: ArrayElement<DecodedInpu
if (type === 'address' && typeof value === 'string') {
return (
<AddressEntity
address={{ hash: value, name: '', implementation_name: null, is_contract: false, is_verified: false }}
address={{ hash: value, name: '' }}
isLoading={ isLoading }
/>
);
......
......@@ -53,7 +53,7 @@ const LogItem = ({ address, index, topics, data, decoded, type, tx_hash: txHash,
) }
{ hasTxInfo ? <RowHeader isLoading={ isLoading }>Transaction</RowHeader> : <RowHeader isLoading={ isLoading }>Address</RowHeader> }
<GridItem display="flex" alignItems="center">
{ type === 'address' ? (
{ type === 'address' && txHash ? (
<TxEntity
hash={ txHash }
isLoading={ isLoading }
......
......@@ -51,7 +51,7 @@ const LogTopic = ({ hex, index, isLoading }: Props) => {
case 'address': {
return (
<AddressEntity
address={{ hash: value, name: '', implementation_name: null, is_contract: false, is_verified: false }}
address={{ hash: value, name: '' }}
isLoading={ isLoading }
/>
);
......
......@@ -56,6 +56,7 @@ const TxInterpretationElementByType = (
<chakra.span display="inline-block" verticalAlign="top" _notFirst={{ marginLeft: 1 }}>
<AddressEntity
address={ addressDataMap?.[value.hash] || value }
icon={{ marginRight: 1 }}
truncation="constant"
onClick={ onAddressClick }
whiteSpace="initial"
......@@ -68,6 +69,7 @@ const TxInterpretationElementByType = (
<chakra.span display="inline-block" verticalAlign="top" _notFirst={{ marginLeft: 1 }}>
<TokenEntity
token={ value }
icon={{ marginRight: 1 }}
onlySymbol
noCopy
width="fit-content"
......@@ -83,7 +85,8 @@ const TxInterpretationElementByType = (
return (
<chakra.span display="inline-block" verticalAlign="top" _notFirst={{ marginLeft: 1 }}>
<EnsEntity
name={ value }
domain={ value }
icon={{ marginRight: 1 }}
width="fit-content"
_notFirst={{ marginLeft: 1 }}
whiteSpace="initial"
......@@ -146,7 +149,7 @@ const TxInterpretation = ({ summary, isLoading, addressDataMap, className }: Pro
return (
<Skeleton isLoaded={ !isLoading } className={ className } fontWeight={ 500 } whiteSpace="pre-wrap" >
<Tooltip label="Transaction summary">
<IconSvg name="lightning" boxSize={ 5 } color="text_secondary" mr={ 2 } verticalAlign="text-top"/>
<IconSvg name="lightning" boxSize={ 5 } color="text_secondary" mr={ 1 } verticalAlign="text-top"/>
</Tooltip>
{ chunks.map((chunk, index) => {
return (
......
......@@ -68,28 +68,30 @@ const WalletMenuContent = ({ address, ensDomainName, disconnect, isAutoConnectDi
>
Your wallet is used to interact with apps and contracts in the explorer.
</Text>
<Flex alignItems="center" mb={ 6 }>
<AddressEntity
address={{ hash: address, ens_domain_name: ensDomainName }}
noTooltip
truncation="dynamic"
fontSize="sm"
fontWeight={ 700 }
color="text"
onClick={ onAddressClick }
flex={ 1 }
/>
<IconButton
aria-label="open wallet"
icon={ <IconSvg name="gear_slim" boxSize={ 5 }/> }
variant="simple"
h="20px"
w="20px"
ml={ 1 }
onClick={ handleOpenWeb3Modal }
isLoading={ isModalOpening }
/>
</Flex>
{ address && (
<Flex alignItems="center" mb={ 6 }>
<AddressEntity
address={{ hash: address, ens_domain_name: ensDomainName }}
noTooltip
truncation="dynamic"
fontSize="sm"
fontWeight={ 700 }
color="text"
onClick={ onAddressClick }
flex={ 1 }
/>
<IconButton
aria-label="open wallet"
icon={ <IconSvg name="gear_slim" boxSize={ 5 }/> }
variant="simple"
h="20px"
w="20px"
ml={ 1 }
onClick={ handleOpenWeb3Modal }
isLoading={ isModalOpening }
/>
</Flex>
) }
<Button size="sm" width="full" variant="outline" onClick={ disconnect }>
Disconnect
</Button>
......
......@@ -113,13 +113,15 @@ const TokenPageTitle = ({ tokenQuery, addressQuery, hash }: Props) => {
const secondRow = (
<Flex alignItems="center" w="100%" minW={ 0 } columnGap={ 2 } rowGap={ 2 } flexWrap={{ base: 'wrap', lg: 'nowrap' }}>
<AddressEntity
address={{ ...addressQuery.data, name: '' }}
isLoading={ isLoading }
fontFamily="heading"
fontSize="lg"
fontWeight={ 500 }
/>
{ addressQuery.data && (
<AddressEntity
address={{ ...addressQuery.data, name: '' }}
isLoading={ isLoading }
fontFamily="heading"
fontSize="lg"
fontWeight={ 500 }
/>
) }
{ !isLoading && tokenQuery.data && <AddressAddToWallet token={ tokenQuery.data } variant="button"/> }
<AddressQrCode address={ addressQuery.data } isLoading={ isLoading }/>
<AccountActionsMenu isLoading={ isLoading }/>
......@@ -139,7 +141,7 @@ const TokenPageTitle = ({ tokenQuery, addressQuery, hash }: Props) => {
<TokenEntity.Icon
token={ tokenQuery.data }
isLoading={ tokenQuery.isPlaceholderData }
iconSize="lg"
size="lg"
/>
) : null }
contentAfter={ contentAfter }
......
......@@ -89,18 +89,20 @@ const TokenInstancePageTitle = ({ isLoading, token, instance, hash }: Props) =>
const titleSecondRow = (
<Flex alignItems="center" w="100%" minW={ 0 } columnGap={ 2 } rowGap={ 2 } flexWrap={{ base: 'wrap', lg: 'nowrap' }}>
<TokenEntity
token={ token }
isLoading={ isLoading }
noSymbol
noCopy
jointSymbol
fontFamily="heading"
fontSize="lg"
fontWeight={ 500 }
w="auto"
maxW="700px"
/>
{ token && (
<TokenEntity
token={ token }
isLoading={ isLoading }
noSymbol
noCopy
jointSymbol
fontFamily="heading"
fontSize="lg"
fontWeight={ 500 }
w="auto"
maxW="700px"
/>
) }
{ !isLoading && <AddressAddToWallet token={ token } variant="button"/> }
<AddressQrCode address={ address } isLoading={ isLoading }/>
<AccountActionsMenu isLoading={ isLoading } showUpdateMetadataItem={ Boolean(instance?.metadata) }/>
......
......@@ -47,16 +47,20 @@ const TxDetailsWrapped = ({ data }: Props) => {
<DetailsInfoItemDivider/>
<DetailsInfoItem.Label
hint="Address (external or contract) receiving the transaction"
>
{ data.to?.is_contract ? 'Interacted with contract' : 'To' }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
<Flex flexWrap="nowrap" alignItems="center" maxW="100%">
<AddressEntity address={ data.to }/>
</Flex>
</DetailsInfoItem.Value>
{ data.to && (
<>
<DetailsInfoItem.Label
hint="Address (external or contract) receiving the transaction"
>
{ data.to.is_contract ? 'Interacted with contract' : 'To' }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
<Flex flexWrap="nowrap" alignItems="center" maxW="100%">
<AddressEntity address={ data.to }/>
</Flex>
</DetailsInfoItem.Value>
</>
) }
<DetailsInfoItemDivider/>
......
......@@ -113,11 +113,12 @@ test.describe('blockscout provider', () => {
test('no interpretation, has method called', async({ render, mockApiResponse }) => {
// the action button should not render if there is no interpretation
const newTxQuery = { ...txQuery, data: txMock.withRecipientContract } as TxQuery;
const metadataResponse = generateAddressMetadataResponse(protocolTagWithMeta);
await mockApiResponse('address_metadata_info', metadataResponse, { queryParams: addressMetadataQueryParams });
await mockApiResponse('tx_interpretation', { data: { summaries: [] } }, { pathParams: { hash } });
const component = await render(<TxSubHeading hash={ hash } hasTag={ false } txQuery={ txQuery }/>);
const component = await render(<TxSubHeading hash={ hash } hasTag={ false } txQuery={ newTxQuery }/>);
await expect(component).toHaveScreenshot();
});
......
......@@ -19,7 +19,7 @@ import { createNovesSummaryObject } from './assetFlows/utils/createNovesSummaryO
import type { TxQuery } from './useTxQuery';
type Props = {
hash?: string;
hash: string;
hasTag: boolean;
txQuery: TxQuery;
}
......
......@@ -25,9 +25,11 @@ const NovesActionSnippet: FC<Props> = ({ item, isLoaded }) => {
const symbol = action.nft?.symbol || action.token?.symbol;
const token = {
name: name,
symbol: symbol?.toLowerCase() === name?.toLowerCase() ? undefined : symbol,
address: action.nft?.address || action.token?.address,
name: name || '',
symbol: (symbol?.toLowerCase() === name?.toLowerCase() ? undefined : symbol) || '',
address: action.nft?.address || action.token?.address || '',
icon_url: '',
type: action.nft ? 'ERC-721' as const : 'ERC-20' as const,
};
return token;
......
......@@ -41,14 +41,14 @@ const TxDetailsAction = ({ action }: Props) => {
const token0 = {
address: data.symbol0 === 'Ether' ? '' : data.address0,
name: data.symbol0 === 'Ether' ? config.chain.currency.symbol || null : data.symbol0,
type: 'ERC-20',
type: 'ERC-20' as const,
symbol: null,
icon_url: null,
};
const token1 = {
address: data.symbol1 === 'Ether' ? '' : data.address1,
name: data.symbol1 === 'Ether' ? config.chain.currency.symbol || null : data.symbol1,
type: 'ERC-20',
type: 'ERC-20' as const,
symbol: null,
icon_url: null,
};
......@@ -99,7 +99,7 @@ const TxDetailsAction = ({ action }: Props) => {
const token = {
address: data.address,
name: data.name,
type: 'ERC-20',
type: 'ERC-20' as const,
symbol: null,
icon_url: null,
};
......@@ -133,7 +133,7 @@ const TxDetailsAction = ({ action }: Props) => {
<Flex key={ data.address + id } whiteSpace="pre-wrap" columnGap={ 2 }>
<chakra.span flexShrink={ 0 }>1</chakra.span>
<chakra.span color="text_secondary" flexShrink={ 0 }>of token ID</chakra.span>
<NftEntity hash={ data.address } id={ id } w="min-content" iconSize="md"/>
<NftEntity hash={ data.address } id={ id } w="min-content" icon={{ size: 'md' }}/>
</Flex>
);
})
......
......@@ -54,7 +54,9 @@ const TxsListItem = ({ tx, isLoading, showBlockInfo, currentAddress, enableTimeI
hash={ tx.hash }
truncation="constant_long"
fontWeight="700"
iconName={ tx.tx_types.includes('blob_transaction') ? 'blob' : undefined }
icon={{
name: tx.tx_types.includes('blob_transaction') ? 'blob' : undefined,
}}
/>
<TimeAgoWithTooltip
timestamp={ tx.timestamp }
......
......@@ -198,7 +198,7 @@ const UserOpDetails = ({ query }: Props) => {
Block
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
<BlockEntity number={ data.block_number } isLoading={ isPlaceholderData }/>
<BlockEntity number={ Number(data.block_number) } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
<DetailsInfoItem.Label
......
......@@ -13,7 +13,7 @@ import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity';
import TxInterpretation from 'ui/shared/tx/interpretation/TxInterpretation';
type Props = {
hash?: string;
hash: string;
// userOpQuery: UseQueryResult<UserOp, ResourceError<unknown>>;
}
......
......@@ -74,7 +74,7 @@ const UserOpsListItem = ({ item, isLoading, showTx, showSender }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Block</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value>
<BlockEntity
number={ item.block_number }
number={ Number(item.block_number) }
isLoading={ isLoading }
fontSize="sm"
lineHeight={ 5 }
......
......@@ -57,7 +57,7 @@ const UserOpsTableItem = ({ item, isLoading, showTx, showSender }: Props) => {
) }
<Td verticalAlign="middle">
<BlockEntity
number={ item.block_number }
number={ Number(item.block_number) }
isLoading={ isLoading }
fontSize="sm"
lineHeight={ 5 }
......
......@@ -48,6 +48,7 @@ const VerifiedAddressesListItem = ({ item, application, onAdd, onEdit, isLoading
}
const token = {
type: 'ERC-20' as const,
icon_url: application.iconUrl,
address: application.tokenAddress,
name: item.metadata.tokenName,
......
......@@ -48,6 +48,7 @@ const VerifiedAddressesTableItem = ({ item, application, onAdd, onEdit, isLoadin
}
const token = {
type: 'ERC-20' as const,
icon_url: application.iconUrl,
address: application.tokenAddress,
name: item.metadata.tokenName,
......
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