Commit 341acb38 authored by tom's avatar tom

user ops

parent d13f87b4
...@@ -5,12 +5,12 @@ import React from 'react'; ...@@ -5,12 +5,12 @@ import React from 'react';
import type { Props } from 'nextjs/getServerSideProps'; import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs'; import PageNextJs from 'nextjs/PageNextJs';
// const UserOp = dynamic(() => import('ui/pages/UserOp'), { ssr: false }); const UserOp = dynamic(() => import('ui/pages/UserOp'), { ssr: false });
const Page: NextPage<Props> = (props: Props) => { const Page: NextPage<Props> = (props: Props) => {
return ( return (
<PageNextJs pathname="/op/[hash]" query={ props.query }> <PageNextJs pathname="/op/[hash]" query={ props.query }>
{ /* <UserOp/> */ } <UserOp/>
</PageNextJs> </PageNextJs>
); );
}; };
......
...@@ -4,12 +4,12 @@ import React from 'react'; ...@@ -4,12 +4,12 @@ import React from 'react';
import PageNextJs from 'nextjs/PageNextJs'; import PageNextJs from 'nextjs/PageNextJs';
// const UserOps = dynamic(() => import('ui/pages/UserOps'), { ssr: false }); const UserOps = dynamic(() => import('ui/pages/UserOps'), { ssr: false });
const Page: NextPage = () => { const Page: NextPage = () => {
return ( return (
<PageNextJs pathname="/ops"> <PageNextJs pathname="/ops">
{ /* <UserOps/> */ } <UserOps/>
</PageNextJs> </PageNextJs>
); );
}; };
......
...@@ -3,6 +3,7 @@ import * as React from 'react'; ...@@ -3,6 +3,7 @@ import * as React from 'react';
export interface SwitchProps extends ChakraSwitch.RootProps { export interface SwitchProps extends ChakraSwitch.RootProps {
inputProps?: React.InputHTMLAttributes<HTMLInputElement>; inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
labelProps?: ChakraSwitch.LabelProps;
rootRef?: React.Ref<HTMLLabelElement>; rootRef?: React.Ref<HTMLLabelElement>;
trackLabel?: { on: React.ReactNode; off: React.ReactNode }; trackLabel?: { on: React.ReactNode; off: React.ReactNode };
thumbLabel?: { on: React.ReactNode; off: React.ReactNode }; thumbLabel?: { on: React.ReactNode; off: React.ReactNode };
...@@ -10,7 +11,7 @@ export interface SwitchProps extends ChakraSwitch.RootProps { ...@@ -10,7 +11,7 @@ export interface SwitchProps extends ChakraSwitch.RootProps {
export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>( export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
function Switch(props, ref) { function Switch(props, ref) {
const { inputProps, children, rootRef, trackLabel, thumbLabel, ...rest } = const { inputProps, children, rootRef, trackLabel, thumbLabel, labelProps, ...rest } =
props; props;
return ( return (
...@@ -31,7 +32,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>( ...@@ -31,7 +32,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
) } ) }
</ChakraSwitch.Control > </ChakraSwitch.Control >
{ children != null && ( { children != null && (
<ChakraSwitch.Label>{ children }</ChakraSwitch.Label> <ChakraSwitch.Label { ...labelProps }>{ children }</ChakraSwitch.Label>
) } ) }
</ChakraSwitch.Root> </ChakraSwitch.Root>
); );
......
...@@ -2,9 +2,9 @@ import { inRange } from 'es-toolkit'; ...@@ -2,9 +2,9 @@ import { inRange } from 'es-toolkit';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { TabItemRegular } from 'toolkit/components/AdaptiveTabs/types';
import type { Log } from 'types/api/log'; import type { Log } from 'types/api/log';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import type { RoutedTab } from 'ui/shared/Tabs/types';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/contexts/app'; import { useAppContext } from 'lib/contexts/app';
...@@ -12,11 +12,11 @@ import throwOnAbsentParamError from 'lib/errors/throwOnAbsentParamError'; ...@@ -12,11 +12,11 @@ import throwOnAbsentParamError from 'lib/errors/throwOnAbsentParamError';
import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError'; import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import { USER_OP } from 'stubs/userOps'; import { USER_OP } from 'stubs/userOps';
import RoutedTabs from 'toolkit/components/RoutedTabs/RoutedTabs';
import RoutedTabsSkeleton from 'toolkit/components/RoutedTabs/RoutedTabsSkeleton';
import useActiveTabFromQuery from 'toolkit/components/RoutedTabs/useActiveTabFromQuery';
import TextAd from 'ui/shared/ad/TextAd'; import TextAd from 'ui/shared/ad/TextAd';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/Tabs/RoutedTabs';
import TabsSkeleton from 'ui/shared/Tabs/TabsSkeleton';
import useTabIndexFromQuery from 'ui/shared/Tabs/useTabIndexFromQuery';
import TxLogs from 'ui/tx/TxLogs'; import TxLogs from 'ui/tx/TxLogs';
import TxTokenTransfer from 'ui/tx/TxTokenTransfer'; import TxTokenTransfer from 'ui/tx/TxTokenTransfer';
import useTxQuery from 'ui/tx/useTxQuery'; import useTxQuery from 'ui/tx/useTxQuery';
...@@ -65,7 +65,7 @@ const UserOp = () => { ...@@ -65,7 +65,7 @@ const UserOp = () => {
} }
}, [ userOpQuery.data ]); }, [ userOpQuery.data ]);
const tabs: Array<RoutedTab> = React.useMemo(() => ([ const tabs: Array<TabItemRegular> = React.useMemo(() => ([
{ id: 'index', title: 'Details', component: <UserOpDetails query={ userOpQuery }/> }, { id: 'index', title: 'Details', component: <UserOpDetails query={ userOpQuery }/> },
{ {
id: 'token_transfers', id: 'token_transfers',
...@@ -76,7 +76,7 @@ const UserOp = () => { ...@@ -76,7 +76,7 @@ const UserOp = () => {
{ id: 'raw', title: 'Raw', component: <UserOpRaw rawData={ userOpQuery.data?.raw } isLoading={ userOpQuery.isPlaceholderData }/> }, { id: 'raw', title: 'Raw', component: <UserOpRaw rawData={ userOpQuery.data?.raw } isLoading={ userOpQuery.isPlaceholderData }/> },
]), [ userOpQuery, txQuery, filterTokenTransfersByLogIndex, filterLogsByLogIndex ]); ]), [ userOpQuery, txQuery, filterTokenTransfersByLogIndex, filterLogsByLogIndex ]);
const tabIndex = useTabIndexFromQuery(tabs); const activeTab = useActiveTabFromQuery(tabs);
const backLink = React.useMemo(() => { const backLink = React.useMemo(() => {
const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/ops'); const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/ops');
...@@ -106,8 +106,8 @@ const UserOp = () => { ...@@ -106,8 +106,8 @@ const UserOp = () => {
/> />
{ userOpQuery.isPlaceholderData ? ( { userOpQuery.isPlaceholderData ? (
<> <>
<TabsSkeleton tabs={ tabs } mt={ 6 }/> <RoutedTabsSkeleton tabs={ tabs } mt={ 6 }/>
{ tabs[tabIndex]?.component } { activeTab?.component }
</> </>
) : ) :
<RoutedTabs tabs={ tabs }/> } <RoutedTabs tabs={ tabs }/> }
......
import type { FlexProps } from '@chakra-ui/react'; import type { FlexProps } from '@chakra-ui/react';
import { Flex, chakra } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
export interface Props extends FlexProps { export interface Props extends FlexProps {
...@@ -44,4 +44,4 @@ const ContainerWithScrollY = ({ gradientHeight, children, onScrollVisibilityChan ...@@ -44,4 +44,4 @@ const ContainerWithScrollY = ({ gradientHeight, children, onScrollVisibilityChan
); );
}; };
export default chakra(ContainerWithScrollY); export default ContainerWithScrollY;
...@@ -73,11 +73,11 @@ export const ItemValue = ({ children, ...rest }: ItemValueProps) => { ...@@ -73,11 +73,11 @@ export const ItemValue = ({ children, ...rest }: ItemValueProps) => {
); );
}; };
export const ItemValueWithScroll = ({ children, gradientHeight, onScrollVisibilityChange, className }: ContainerWithScrollY.Props) => { export const ItemValueWithScroll = ({ children, gradientHeight, onScrollVisibilityChange, ...rest }: ContainerWithScrollY.Props) => {
return ( return (
<ItemValue position="relative"> <ItemValue position="relative" >
<ContainerWithScrollY.default <ContainerWithScrollY.default
className={ className } { ...rest }
gradientHeight={ gradientHeight } gradientHeight={ gradientHeight }
onScrollVisibilityChange={ onScrollVisibilityChange } onScrollVisibilityChange={ onScrollVisibilityChange }
> >
......
...@@ -63,13 +63,12 @@ export interface EntityProps extends EntityBase.EntityBaseProps { ...@@ -63,13 +63,12 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
const UserOpEntity = (props: EntityProps) => { const UserOpEntity = (props: EntityProps) => {
const partsProps = distributeEntityProps(props); const partsProps = distributeEntityProps(props);
const content = <Content { ...partsProps.content }/>;
return ( return (
<Container { ...partsProps.container }> <Container { ...partsProps.container }>
<Icon { ...partsProps.icon }/> <Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }> { props.noLink ? content : <Link { ...partsProps.link }>{ content }</Link> }
<Content { ...partsProps.content }/>
</Link>
<Copy { ...partsProps.copy }/> <Copy { ...partsProps.copy }/>
</Container> </Container>
); );
......
...@@ -125,7 +125,7 @@ const TxInterpretationElementByType = ( ...@@ -125,7 +125,7 @@ const TxInterpretationElementByType = (
case 'method': { case 'method': {
return ( return (
<Badge <Badge
colorScheme={ value === 'Multicall' ? 'teal' : 'gray' } colorPalette={ value === 'Multicall' ? 'teal' : 'gray' }
truncated truncated
ml={ 1 } ml={ 1 }
mr={ 2 } mr={ 2 }
......
import { Tag } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { UserOpSponsorType as TUserOpSponsorType } from 'types/api/userOps'; import type { UserOpSponsorType as TUserOpSponsorType } from 'types/api/userOps';
import { Badge } from 'toolkit/chakra/badge';
type Props = { type Props = {
sponsorType: TUserOpSponsorType; sponsorType: TUserOpSponsorType;
}; };
...@@ -22,7 +23,7 @@ const UserOpSponsorType = ({ sponsorType }: Props) => { ...@@ -22,7 +23,7 @@ const UserOpSponsorType = ({ sponsorType }: Props) => {
case 'wallet_deposit': case 'wallet_deposit':
text = 'Wallet deposit'; text = 'Wallet deposit';
} }
return <Tag>{ text }</Tag>; return <Badge>{ text }</Badge>;
}; };
export default UserOpSponsorType; export default UserOpSponsorType;
import { chakra, FormLabel, FormControl, Switch } from '@chakra-ui/react'; import { chakra, Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Switch } from 'toolkit/chakra/switch';
import Hint from 'ui/shared/Hint'; import Hint from 'ui/shared/Hint';
interface Props { interface Props {
...@@ -22,13 +23,23 @@ const UserOpCallDataSwitch = ({ className, initialValue, isDisabled, onChange }: ...@@ -22,13 +23,23 @@ const UserOpCallDataSwitch = ({ className, initialValue, isDisabled, onChange }:
}, [ onChange ]); }, [ onChange ]);
return ( return (
<FormControl className={ className } display="flex" columnGap={ 2 } ml="auto" w="fit-content"> <Flex ml="auto" alignItems="center" gap={ 2 }>
<FormLabel htmlFor="isExternal" fontSize="sm" lineHeight={ 5 } fontWeight={ 600 } m={ 0 }> <Switch
Show external call data className={ className }
</FormLabel> id="call-data-switch"
<Switch id="isExternal" isChecked={ isChecked } isDisabled={ isDisabled } onChange={ handleChange }/> checked={ isChecked }
disabled={ isDisabled }
onCheckedChange={ handleChange }
flexDirection="row-reverse"
size="md"
gap={ 2 }
labelProps={{ fontWeight: '600', fontSize: 'sm' }}
>
<chakra.span hideBelow="lg">Show external call data</chakra.span>
<chakra.span hideFrom="lg">External call data</chakra.span>
</Switch>
<Hint label="Inner call data is a predicted decoded call from this user operation"/> <Hint label="Inner call data is a predicted decoded call from this user operation"/>
</FormControl> </Flex>
); );
}; };
......
This diff is collapsed.
...@@ -2,7 +2,7 @@ import React from 'react'; ...@@ -2,7 +2,7 @@ import React from 'react';
import type { UserOp } from 'types/api/userOps'; import type { UserOp } from 'types/api/userOps';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import RawDataSnippet from 'ui/shared/RawDataSnippet'; import RawDataSnippet from 'ui/shared/RawDataSnippet';
// order is taken from the ERC-4337 standard // order is taken from the ERC-4337 standard
...@@ -27,7 +27,7 @@ const UserOpRaw = ({ rawData, isLoading }: Props) => { ...@@ -27,7 +27,7 @@ const UserOpRaw = ({ rawData, isLoading }: Props) => {
return res; return res;
}, {} as UserOp['raw']), undefined, 4); }, {} as UserOp['raw']), undefined, 4);
return <Skeleton isLoaded={ !isLoading }><RawDataSnippet data={ text }/></Skeleton>; return <Skeleton loading={ isLoading }><RawDataSnippet data={ text }/></Skeleton>;
}; };
export default UserOpRaw; export default UserOpRaw;
import { Flex, Link } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
// import type { UseQueryResult } from '@tanstack/react-query'; // import type { UseQueryResult } from '@tanstack/react-query';
import React from 'react'; import React from 'react';
...@@ -8,6 +8,7 @@ import config from 'configs/app'; ...@@ -8,6 +8,7 @@ import config from 'configs/app';
// import type { ResourceError } from 'lib/api/resources'; // import type { ResourceError } from 'lib/api/resources';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import { TX_INTERPRETATION } from 'stubs/txInterpretation'; import { TX_INTERPRETATION } from 'stubs/txInterpretation';
import { Link } from 'toolkit/chakra/link';
import { TX_ACTIONS_BLOCK_ID } from 'ui/shared/DetailedInfo/DetailedInfoActionsWrapper'; import { TX_ACTIONS_BLOCK_ID } from 'ui/shared/DetailedInfo/DetailedInfoActionsWrapper';
import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity'; import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity';
import TxInterpretation from 'ui/shared/tx/interpretation/TxInterpretation'; import TxInterpretation from 'ui/shared/tx/interpretation/TxInterpretation';
......
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