Commit 7f55da68 authored by tom's avatar tom

logs tab

parent de5dcd73
...@@ -120,7 +120,7 @@ export const recipe = defineSlotRecipe({ ...@@ -120,7 +120,7 @@ export const recipe = defineSlotRecipe({
}, },
valueText: { valueText: {
lineClamp: '1', lineClamp: '1',
maxW: '80%', maxW: '100%',
}, },
}, },
......
...@@ -66,7 +66,7 @@ const TransactionPageContent = () => { ...@@ -66,7 +66,7 @@ const TransactionPageContent = () => {
// config.features.dataAvailability.isEnabled && txQuery.data?.blob_versioned_hashes?.length ? // config.features.dataAvailability.isEnabled && txQuery.data?.blob_versioned_hashes?.length ?
// { id: 'blobs', title: 'Blobs', component: <TxBlobs txQuery={ txQuery }/> } : // { id: 'blobs', title: 'Blobs', component: <TxBlobs txQuery={ txQuery }/> } :
// undefined, // undefined,
// { id: 'logs', title: 'Logs', component: <TxLogs txQuery={ txQuery }/> }, { id: 'logs', title: 'Logs', component: <TxLogs txQuery={ txQuery }/> },
// { id: 'state', title: 'State', component: <TxState txQuery={ txQuery }/> }, // { id: 'state', title: 'State', component: <TxState txQuery={ txQuery }/> },
// { id: 'raw_trace', title: 'Raw trace', component: <TxRawTrace txQuery={ txQuery }/> }, // { id: 'raw_trace', title: 'Raw trace', component: <TxRawTrace txQuery={ txQuery }/> },
].filter(Boolean); ].filter(Boolean);
......
import type { HTMLChakraProps } from '@chakra-ui/react';
import { Center } from '@chakra-ui/react';
import React from 'react';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { Tooltip } from 'toolkit/chakra/tooltip';
interface Props extends HTMLChakraProps<'div'> {
isLoading?: boolean;
}
const LogIndex = ({ children, isLoading, ...props }: Props) => {
return (
<Tooltip content="Log index">
<Skeleton loading={ isLoading } asChild>
<Center
color={{ _light: 'blue.600', _dark: 'gray.50' }}
bgColor={{ _light: 'blue.50', _dark: 'gray.600' }}
borderRadius="base"
{ ...props }
>
{ children }
</Center>
</Skeleton>
</Tooltip>
);
};
export default React.memo(LogIndex);
import { Grid, GridItem, Tooltip, Button, useColorModeValue, Alert, Link } from '@chakra-ui/react'; import { Grid, GridItem } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { Log } from 'types/api/log'; import type { Log } from 'types/api/log';
...@@ -7,7 +7,9 @@ import { route } from 'nextjs-routes'; ...@@ -7,7 +7,9 @@ import { route } from 'nextjs-routes';
// import searchIcon from 'icons/search.svg'; // import searchIcon from 'icons/search.svg';
import { space } from 'lib/html-entities'; import { space } from 'lib/html-entities';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Alert } from 'toolkit/chakra/alert';
import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import LogDecodedInputData from 'ui/shared/logs/LogDecodedInputData'; import LogDecodedInputData from 'ui/shared/logs/LogDecodedInputData';
...@@ -15,6 +17,8 @@ import LogTopic from 'ui/shared/logs/LogTopic'; ...@@ -15,6 +17,8 @@ import LogTopic from 'ui/shared/logs/LogTopic';
import type { DataType } from 'ui/shared/RawInputData'; import type { DataType } from 'ui/shared/RawInputData';
import RawInputData from 'ui/shared/RawInputData'; import RawInputData from 'ui/shared/RawInputData';
import LogIndex from './LogIndex';
type Props = Log & { type Props = Log & {
type: 'address' | 'transaction'; type: 'address' | 'transaction';
isLoading?: boolean; isLoading?: boolean;
...@@ -23,15 +27,12 @@ type Props = Log & { ...@@ -23,15 +27,12 @@ type Props = Log & {
const RowHeader = ({ children, isLoading }: { children: React.ReactNode; isLoading?: boolean }) => ( const RowHeader = ({ children, isLoading }: { children: React.ReactNode; isLoading?: boolean }) => (
<GridItem _notFirst={{ my: { base: 4, lg: 0 } }}> <GridItem _notFirst={{ my: { base: 4, lg: 0 } }}>
<Skeleton fontWeight={ 500 } isLoaded={ !isLoading } display="inline-block">{ children }</Skeleton> <Skeleton fontWeight={ 500 } loading={ isLoading } display="inline-block">{ children }</Skeleton>
</GridItem> </GridItem>
); );
const LogItem = ({ address, index, topics, data, decoded, type, transaction_hash: txHash, isLoading, defaultDataType }: Props) => { const LogItem = ({ address, index, topics, data, decoded, type, transaction_hash: txHash, isLoading, defaultDataType }: Props) => {
const borderColor = useColorModeValue('blackAlpha.200', 'whiteAlpha.200');
const dataBgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
const hasTxInfo = type === 'address' && txHash; const hasTxInfo = type === 'address' && txHash;
return ( return (
...@@ -41,7 +42,7 @@ const LogItem = ({ address, index, topics, data, decoded, type, transaction_hash ...@@ -41,7 +42,7 @@ const LogItem = ({ address, index, topics, data, decoded, type, transaction_hash
py={ 8 } py={ 8 }
_notFirst={{ _notFirst={{
borderTopWidth: '1px', borderTopWidth: '1px',
borderTopColor: borderColor, borderTopColor: { _light: 'blackAlpha.200', _dark: 'whiteAlpha.200' },
}} }}
_first={{ _first={{
pt: 0, pt: 0,
...@@ -76,13 +77,15 @@ const LogItem = ({ address, index, topics, data, decoded, type, transaction_hash ...@@ -76,13 +77,15 @@ const LogItem = ({ address, index, topics, data, decoded, type, transaction_hash
<Icon as={ searchIcon } boxSize={ 5 }/> <Icon as={ searchIcon } boxSize={ 5 }/>
</Link> </Link>
</Tooltip> */ } </Tooltip> */ }
<Skeleton isLoaded={ !isLoading } ml="auto" borderRadius="base"> <LogIndex
<Tooltip label="Log index"> isLoading={ isLoading }
<Button variant="outline" colorScheme="gray" data-selected="true" size="sm" fontWeight={ 400 }> textStyle="sm"
ml="auto"
minW={ 8 }
height={ 8 }
>
{ index } { index }
</Button> </LogIndex>
</Tooltip>
</Skeleton>
</GridItem> </GridItem>
{ decoded && ( { decoded && (
<> <>
...@@ -107,7 +110,13 @@ const LogItem = ({ address, index, topics, data, decoded, type, transaction_hash ...@@ -107,7 +110,13 @@ const LogItem = ({ address, index, topics, data, decoded, type, transaction_hash
{ defaultDataType ? ( { defaultDataType ? (
<RawInputData hex={ data } isLoading={ isLoading } defaultDataType={ defaultDataType } minHeight="53px"/> <RawInputData hex={ data } isLoading={ isLoading } defaultDataType={ defaultDataType } minHeight="53px"/>
) : ( ) : (
<Skeleton isLoaded={ !isLoading } p={ 4 } fontSize="sm" borderRadius="md" bgColor={ isLoading ? undefined : dataBgColor }> <Skeleton
loading={ isLoading }
p={ 4 }
fontSize="sm"
borderRadius="md"
bgColor={ isLoading ? undefined : { _light: 'blackAlpha.50', _dark: 'whiteAlpha.50' } }
>
{ data } { data }
</Skeleton> </Skeleton>
) } ) }
......
import { Flex, Button, Select } from '@chakra-ui/react'; import { createListCollection, Flex } from '@chakra-ui/react';
import capitalize from 'lodash/capitalize'; import { capitalize } from 'es-toolkit';
import React from 'react'; import React from 'react';
import hexToAddress from 'lib/hexToAddress'; import hexToAddress from 'lib/hexToAddress';
import hexToUtf8 from 'lib/hexToUtf8'; import hexToUtf8 from 'lib/hexToUtf8';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { SelectContent, SelectControl, SelectItem, SelectRoot, SelectValueText } from 'toolkit/chakra/select';
import { Skeleton } from 'toolkit/chakra/skeleton';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LogIndex from './LogIndex';
interface Props { interface Props {
hex: string; hex: string;
index: number; index: number;
...@@ -25,11 +28,18 @@ const VALUE_CONVERTERS: Record<DataType, (hex: string) => string> = { ...@@ -25,11 +28,18 @@ const VALUE_CONVERTERS: Record<DataType, (hex: string) => string> = {
}; };
const OPTIONS: Array<DataType> = [ 'hex', 'address', 'text', 'number' ]; const OPTIONS: Array<DataType> = [ 'hex', 'address', 'text', 'number' ];
const collection = createListCollection({
items: OPTIONS.map((option) => ({
value: option,
label: capitalize(option),
})),
});
const LogTopic = ({ hex, index, isLoading }: Props) => { const LogTopic = ({ hex, index, isLoading }: Props) => {
const [ selectedDataType, setSelectedDataType ] = React.useState<DataType>('hex'); const [ selectedDataType, setSelectedDataType ] = React.useState<DataType>('hex');
const handleSelectChange = React.useCallback((event: React.ChangeEvent<HTMLSelectElement>) => { const handleSelectChange = React.useCallback((details: { value: Array<string> }) => {
setSelectedDataType(event.target.value as DataType); setSelectedDataType(details.value[0] as DataType);
}, []); }, []);
const value = VALUE_CONVERTERS[selectedDataType.toLowerCase() as Lowercase<DataType>](hex); const value = VALUE_CONVERTERS[selectedDataType.toLowerCase() as Lowercase<DataType>](hex);
...@@ -41,7 +51,7 @@ const LogTopic = ({ hex, index, isLoading }: Props) => { ...@@ -41,7 +51,7 @@ const LogTopic = ({ hex, index, isLoading }: Props) => {
case 'text': { case 'text': {
return ( return (
<> <>
<Skeleton isLoaded={ !isLoading } overflow="hidden" whiteSpace="nowrap"> <Skeleton loading={ isLoading } overflow="hidden" whiteSpace="nowrap">
<HashStringShortenDynamic hash={ value }/> <HashStringShortenDynamic hash={ value }/>
</Skeleton> </Skeleton>
<CopyToClipboard text={ value } isLoading={ isLoading }/> <CopyToClipboard text={ value } isLoading={ isLoading }/>
...@@ -62,24 +72,36 @@ const LogTopic = ({ hex, index, isLoading }: Props) => { ...@@ -62,24 +72,36 @@ const LogTopic = ({ hex, index, isLoading }: Props) => {
return ( return (
<Flex alignItems="center" px={{ base: 0, lg: 3 }} _notFirst={{ mt: 3 }} overflow="hidden" maxW="100%"> <Flex alignItems="center" px={{ base: 0, lg: 3 }} _notFirst={{ mt: 3 }} overflow="hidden" maxW="100%">
<Skeleton isLoaded={ !isLoading } mr={ 3 } borderRadius="base"> <LogIndex
<Button variant="outline" colorScheme="gray" data-selected size="xs" fontWeight={ 400 } w={ 6 }> isLoading={ isLoading }
textStyle="xs"
mr={ 3 }
minW={ 6 }
height={ 6 }
>
{ index } { index }
</Button> </LogIndex>
</Skeleton>
{ index !== 0 && ( { index !== 0 && (
<Skeleton isLoaded={ !isLoading } mr={ 3 } flexShrink={ 0 } borderRadius="base"> <SelectRoot
<Select collection={ collection }
size="xs" variant="outline"
borderRadius="base" value={ [ selectedDataType ] }
value={ selectedDataType } onValueChange={ handleSelectChange }
onChange={ handleSelectChange } mr={ 3 }
w="auto" flexShrink={ 0 }
aria-label="Data type" width="fit-content"
> >
{ OPTIONS.map((option) => <option key={ option } value={ option }>{ capitalize(option) }</option>) } <SelectControl w="105px" loading={ isLoading }>
</Select> <SelectValueText placeholder="Data type"/>
</Skeleton> </SelectControl>
<SelectContent>
{ collection.items.map((item) => (
<SelectItem item={ item } key={ item.value }>
{ item.label }
</SelectItem>
)) }
</SelectContent>
</SelectRoot>
) } ) }
{ content } { content }
</Flex> </Flex>
......
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