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

Address and Contact pages: move tabs up (#2626)

Fixes #2593
parent 02db9002
...@@ -25,12 +25,11 @@ import AccountHistoryFilter from './AddressAccountHistoryFilter'; ...@@ -25,12 +25,11 @@ import AccountHistoryFilter from './AddressAccountHistoryFilter';
const getFilterValue = (getFilterValueFromQuery<NovesHistoryFilterValue>).bind(null, NovesHistoryFilterValues); const getFilterValue = (getFilterValueFromQuery<NovesHistoryFilterValue>).bind(null, NovesHistoryFilterValues);
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
shouldRender?: boolean; shouldRender?: boolean;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
}; };
const AddressAccountHistory = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: Props) => { const AddressAccountHistory = ({ shouldRender = true, isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const isMounted = useIsMounted(); const isMounted = useIsMounted();
...@@ -41,7 +40,6 @@ const AddressAccountHistory = ({ scrollRef, shouldRender = true, isQueryEnabled ...@@ -41,7 +40,6 @@ const AddressAccountHistory = ({ scrollRef, shouldRender = true, isQueryEnabled
const { data, isError, pagination, isPlaceholderData } = useQueryWithPages({ const { data, isError, pagination, isPlaceholderData } = useQueryWithPages({
resourceName: 'noves_address_history', resourceName: 'noves_address_history',
pathParams: { address: currentAddress }, pathParams: { address: currentAddress },
scrollRef,
options: { options: {
enabled: isQueryEnabled, enabled: isQueryEnabled,
placeholderData: generateListStub<'noves_address_history'>(NOVES_TRANSLATE, 10, { hasNextPage: false, pageNumber: 1, pageSize: 10 }), placeholderData: generateListStub<'noves_address_history'>(NOVES_TRANSLATE, 10, { hasNextPage: false, pageNumber: 1, pageSize: 10 }),
......
...@@ -27,12 +27,11 @@ import AddressBlocksValidatedTableItem from './blocksValidated/AddressBlocksVali ...@@ -27,12 +27,11 @@ import AddressBlocksValidatedTableItem from './blocksValidated/AddressBlocksVali
const OVERLOAD_COUNT = 75; const OVERLOAD_COUNT = 75;
interface Props { interface Props {
scrollRef?: React.RefObject<HTMLDivElement>;
shouldRender?: boolean; shouldRender?: boolean;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
} }
const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: Props) => { const AddressBlocksValidated = ({ shouldRender = true, isQueryEnabled = true }: Props) => {
const [ socketAlert, setSocketAlert ] = React.useState(''); const [ socketAlert, setSocketAlert ] = React.useState('');
const [ newItemsCount, setNewItemsCount ] = React.useState(0); const [ newItemsCount, setNewItemsCount ] = React.useState(0);
...@@ -44,7 +43,6 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled ...@@ -44,7 +43,6 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled
const query = useQueryWithPages({ const query = useQueryWithPages({
resourceName: 'address_blocks_validated', resourceName: 'address_blocks_validated',
pathParams: { hash: addressHash }, pathParams: { hash: addressHash },
scrollRef,
options: { options: {
enabled: isQueryEnabled, enabled: isQueryEnabled,
placeholderData: generateListStub<'address_blocks_validated'>( placeholderData: generateListStub<'address_blocks_validated'>(
......
...@@ -31,10 +31,9 @@ import type { AddressQuery } from './utils/useAddressQuery'; ...@@ -31,10 +31,9 @@ import type { AddressQuery } from './utils/useAddressQuery';
interface Props { interface Props {
addressQuery: AddressQuery; addressQuery: AddressQuery;
scrollRef?: React.RefObject<HTMLDivElement>;
} }
const AddressDetails = ({ addressQuery, scrollRef }: Props) => { const AddressDetails = ({ addressQuery }: Props) => {
const router = useRouter(); const router = useRouter();
const addressHash = getQueryParamString(router.query.hash); const addressHash = getQueryParamString(router.query.hash);
...@@ -44,13 +43,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -44,13 +43,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
addressQuery, addressQuery,
}); });
const handleCounterItemClick = React.useCallback(() => {
window.setTimeout(() => {
// cannot do scroll instantly, have to wait a little
scrollRef?.current?.scrollIntoView({ behavior: 'smooth' });
}, 500);
}, [ scrollRef ]);
const error404Data = React.useMemo(() => ({ const error404Data = React.useMemo(() => ({
hash: addressHash || '', hash: addressHash || '',
is_contract: false, is_contract: false,
...@@ -184,7 +176,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -184,7 +176,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
Tokens Tokens
</DetailsInfoItem.Label> </DetailsInfoItem.Label>
<DetailsInfoItem.Value py={ addressQuery.data ? 0 : undefined }> <DetailsInfoItem.Value py={ addressQuery.data ? 0 : undefined }>
{ addressQuery.data ? <TokenSelect onClick={ handleCounterItemClick }/> : <Box>0</Box> } { addressQuery.data ? <TokenSelect/> : <Box>0</Box> }
</DetailsInfoItem.Value> </DetailsInfoItem.Value>
</> </>
) } ) }
...@@ -215,7 +207,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -215,7 +207,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
prop="transactions_count" prop="transactions_count"
query={ countersQuery } query={ countersQuery }
address={ data.hash } address={ data.hash }
onClick={ handleCounterItemClick }
isAddressQueryLoading={ addressQuery.isPlaceholderData } isAddressQueryLoading={ addressQuery.isPlaceholderData }
isDegradedData={ addressQuery.isDegradedData } isDegradedData={ addressQuery.isDegradedData }
/> />
...@@ -237,7 +228,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -237,7 +228,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
prop="token_transfers_count" prop="token_transfers_count"
query={ countersQuery } query={ countersQuery }
address={ data.hash } address={ data.hash }
onClick={ handleCounterItemClick }
isAddressQueryLoading={ addressQuery.isPlaceholderData } isAddressQueryLoading={ addressQuery.isPlaceholderData }
isDegradedData={ addressQuery.isDegradedData } isDegradedData={ addressQuery.isDegradedData }
/> />
...@@ -261,7 +251,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -261,7 +251,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
prop="gas_usage_count" prop="gas_usage_count"
query={ countersQuery } query={ countersQuery }
address={ data.hash } address={ data.hash }
onClick={ handleCounterItemClick }
isAddressQueryLoading={ addressQuery.isPlaceholderData } isAddressQueryLoading={ addressQuery.isPlaceholderData }
isDegradedData={ addressQuery.isDegradedData } isDegradedData={ addressQuery.isDegradedData }
/> />
...@@ -291,7 +280,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -291,7 +280,6 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
prop="validations_count" prop="validations_count"
query={ countersQuery } query={ countersQuery }
address={ data.hash } address={ data.hash }
onClick={ handleCounterItemClick }
isAddressQueryLoading={ addressQuery.isPlaceholderData } isAddressQueryLoading={ addressQuery.isPlaceholderData }
isDegradedData={ addressQuery.isDegradedData } isDegradedData={ addressQuery.isDegradedData }
/> />
......
...@@ -16,12 +16,11 @@ import AddressCsvExportLink from './AddressCsvExportLink'; ...@@ -16,12 +16,11 @@ import AddressCsvExportLink from './AddressCsvExportLink';
import AddressEpochRewardsListItem from './epochRewards/AddressEpochRewardsListItem'; import AddressEpochRewardsListItem from './epochRewards/AddressEpochRewardsListItem';
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
shouldRender?: boolean; shouldRender?: boolean;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
}; };
const AddressEpochRewards = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: Props) => { const AddressEpochRewards = ({ shouldRender = true, isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const isMounted = useIsMounted(); const isMounted = useIsMounted();
...@@ -32,7 +31,6 @@ const AddressEpochRewards = ({ scrollRef, shouldRender = true, isQueryEnabled = ...@@ -32,7 +31,6 @@ const AddressEpochRewards = ({ scrollRef, shouldRender = true, isQueryEnabled =
pathParams: { pathParams: {
hash, hash,
}, },
scrollRef,
options: { options: {
enabled: isQueryEnabled && Boolean(hash), enabled: isQueryEnabled && Boolean(hash),
placeholderData: generateListStub<'address_epoch_rewards'>(EPOCH_REWARD_ITEM, 50, { next_page_params: { placeholderData: generateListStub<'address_epoch_rewards'>(EPOCH_REWARD_ITEM, 50, { next_page_params: {
......
...@@ -24,11 +24,10 @@ import AddressTxsFilter from './AddressTxsFilter'; ...@@ -24,11 +24,10 @@ import AddressTxsFilter from './AddressTxsFilter';
const getFilterValue = (getFilterValueFromQuery<AddressFromToFilter>).bind(null, AddressFromToFilterValues); const getFilterValue = (getFilterValueFromQuery<AddressFromToFilter>).bind(null, AddressFromToFilterValues);
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
shouldRender?: boolean; shouldRender?: boolean;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
}; };
const AddressInternalTxs = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: Props) => { const AddressInternalTxs = ({ shouldRender = true, isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const isMounted = useIsMounted(); const isMounted = useIsMounted();
...@@ -40,7 +39,6 @@ const AddressInternalTxs = ({ scrollRef, shouldRender = true, isQueryEnabled = t ...@@ -40,7 +39,6 @@ const AddressInternalTxs = ({ scrollRef, shouldRender = true, isQueryEnabled = t
resourceName: 'address_internal_txs', resourceName: 'address_internal_txs',
pathParams: { hash }, pathParams: { hash },
filters: { filter: filterValue }, filters: { filter: filterValue },
scrollRef,
options: { options: {
enabled: isQueryEnabled, enabled: isQueryEnabled,
placeholderData: generateListStub<'address_internal_txs'>( placeholderData: generateListStub<'address_internal_txs'>(
......
...@@ -15,12 +15,11 @@ import AddressCsvExportLink from './AddressCsvExportLink'; ...@@ -15,12 +15,11 @@ import AddressCsvExportLink from './AddressCsvExportLink';
import useAddressQuery from './utils/useAddressQuery'; import useAddressQuery from './utils/useAddressQuery';
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
shouldRender?: boolean; shouldRender?: boolean;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
}; };
const AddressLogs = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: Props) => { const AddressLogs = ({ shouldRender = true, isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const isMounted = useIsMounted(); const isMounted = useIsMounted();
...@@ -28,7 +27,6 @@ const AddressLogs = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: ...@@ -28,7 +27,6 @@ const AddressLogs = ({ scrollRef, shouldRender = true, isQueryEnabled = true }:
const { data, isPlaceholderData, isError, pagination } = useQueryWithPages({ const { data, isPlaceholderData, isError, pagination } = useQueryWithPages({
resourceName: 'address_logs', resourceName: 'address_logs',
pathParams: { hash }, pathParams: { hash },
scrollRef,
options: { options: {
enabled: isQueryEnabled, enabled: isQueryEnabled,
placeholderData: generateListStub<'address_logs'>(LOG, 3, { next_page_params: { placeholderData: generateListStub<'address_logs'>(LOG, 3, { next_page_params: {
......
...@@ -8,12 +8,11 @@ import AddressMudTable from './mud/AddressMudTable'; ...@@ -8,12 +8,11 @@ import AddressMudTable from './mud/AddressMudTable';
import AddressMudTables from './mud/AddressMudTables'; import AddressMudTables from './mud/AddressMudTables';
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
shouldRender?: boolean; shouldRender?: boolean;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
}; };
const AddressMud = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: Props) => { const AddressMud = ({ shouldRender = true, isQueryEnabled = true }: Props) => {
const isMounted = useIsMounted(); const isMounted = useIsMounted();
const router = useRouter(); const router = useRouter();
const tableId = router.query.table_id?.toString(); const tableId = router.query.table_id?.toString();
...@@ -24,14 +23,14 @@ const AddressMud = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: P ...@@ -24,14 +23,14 @@ const AddressMud = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: P
} }
if (tableId && recordId) { if (tableId && recordId) {
return <AddressMudRecord tableId={ tableId } recordId={ recordId } isQueryEnabled={ isQueryEnabled } scrollRef={ scrollRef }/>; return <AddressMudRecord tableId={ tableId } recordId={ recordId } isQueryEnabled={ isQueryEnabled }/>;
} }
if (tableId) { if (tableId) {
return <AddressMudTable tableId={ tableId } scrollRef={ scrollRef } isQueryEnabled={ isQueryEnabled }/>; return <AddressMudTable tableId={ tableId } isQueryEnabled={ isQueryEnabled }/>;
} }
return <AddressMudTables scrollRef={ scrollRef } isQueryEnabled={ isQueryEnabled }/>; return <AddressMudTables isQueryEnabled={ isQueryEnabled }/>;
}; };
export default AddressMud; export default AddressMud;
...@@ -63,14 +63,13 @@ const matchFilters = (filters: Filters, tokenTransfer: TokenTransfer, address?: ...@@ -63,14 +63,13 @@ const matchFilters = (filters: Filters, tokenTransfer: TokenTransfer, address?:
}; };
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
shouldRender?: boolean; shouldRender?: boolean;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
// for tests only // for tests only
overloadCount?: number; overloadCount?: number;
}; };
const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shouldRender = true, isQueryEnabled = true }: Props) => { const AddressTokenTransfers = ({ overloadCount = OVERLOAD_COUNT, shouldRender = true, isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
...@@ -94,7 +93,6 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shou ...@@ -94,7 +93,6 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shou
resourceName: 'address_token_transfers', resourceName: 'address_token_transfers',
pathParams: { hash: currentAddress }, pathParams: { hash: currentAddress },
filters: tokenFilter ? { token: tokenFilter } : filters, filters: tokenFilter ? { token: tokenFilter } : filters,
scrollRef,
options: { options: {
enabled: isQueryEnabled, enabled: isQueryEnabled,
placeholderData: getTokenTransfersStub(undefined, { placeholderData: getTokenTransfersStub(undefined, {
......
...@@ -47,14 +47,13 @@ const matchFilter = (filterValue: AddressFromToFilter, transaction: Transaction, ...@@ -47,14 +47,13 @@ const matchFilter = (filterValue: AddressFromToFilter, transaction: Transaction,
}; };
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
shouldRender?: boolean; shouldRender?: boolean;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
// for tests only // for tests only
overloadCount?: number; overloadCount?: number;
}; };
const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shouldRender = true, isQueryEnabled = true }: Props) => { const AddressTxs = ({ overloadCount = OVERLOAD_COUNT, shouldRender = true, isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const isMounted = useIsMounted(); const isMounted = useIsMounted();
...@@ -73,7 +72,6 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shouldRender = ...@@ -73,7 +72,6 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shouldRender =
pathParams: { hash: currentAddress }, pathParams: { hash: currentAddress },
filters: { filter: filterValue }, filters: { filter: filterValue },
sorting: getSortParamsFromValue<TransactionsSortingValue, TransactionsSortingField, TransactionsSorting['order']>(sort), sorting: getSortParamsFromValue<TransactionsSortingValue, TransactionsSortingField, TransactionsSorting['order']>(sort),
scrollRef,
options: { options: {
enabled: isQueryEnabled, enabled: isQueryEnabled,
placeholderData: generateListStub<'address_txs'>(TX, 50, { next_page_params: { placeholderData: generateListStub<'address_txs'>(TX, 50, { next_page_params: {
...@@ -185,7 +183,7 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shouldRender = ...@@ -185,7 +183,7 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shouldRender =
return ( return (
<> <>
{ !isMobile && ( { !isMobile && addressTxsQuery.pagination.isVisible && (
<ActionBar mt={ -6 }> <ActionBar mt={ -6 }>
{ filter } { filter }
{ currentAddress && csvExportLink } { currentAddress && csvExportLink }
......
...@@ -14,11 +14,10 @@ import BeaconChainWithdrawalsListItem from 'ui/withdrawals/beaconChain/BeaconCha ...@@ -14,11 +14,10 @@ import BeaconChainWithdrawalsListItem from 'ui/withdrawals/beaconChain/BeaconCha
import BeaconChainWithdrawalsTable from 'ui/withdrawals/beaconChain/BeaconChainWithdrawalsTable'; import BeaconChainWithdrawalsTable from 'ui/withdrawals/beaconChain/BeaconChainWithdrawalsTable';
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
shouldRender?: boolean; shouldRender?: boolean;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
}; };
const AddressWithdrawals = ({ scrollRef, shouldRender = true, isQueryEnabled = true }: Props) => { const AddressWithdrawals = ({ shouldRender = true, isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const isMounted = useIsMounted(); const isMounted = useIsMounted();
...@@ -27,7 +26,6 @@ const AddressWithdrawals = ({ scrollRef, shouldRender = true, isQueryEnabled = t ...@@ -27,7 +26,6 @@ const AddressWithdrawals = ({ scrollRef, shouldRender = true, isQueryEnabled = t
const { data, isPlaceholderData, isError, pagination } = useQueryWithPages({ const { data, isPlaceholderData, isError, pagination } = useQueryWithPages({
resourceName: 'address_withdrawals', resourceName: 'address_withdrawals',
pathParams: { hash }, pathParams: { hash },
scrollRef,
options: { options: {
enabled: isQueryEnabled, enabled: isQueryEnabled,
placeholderData: generateListStub<'address_withdrawals'>(WITHDRAWAL, 50, { next_page_params: { placeholderData: generateListStub<'address_withdrawals'>(WITHDRAWAL, 50, { next_page_params: {
......
...@@ -14,7 +14,6 @@ interface Props { ...@@ -14,7 +14,6 @@ interface Props {
prop: keyof AddressCounters; prop: keyof AddressCounters;
query: UseQueryResult<AddressCounters, ResourceError<unknown>>; query: UseQueryResult<AddressCounters, ResourceError<unknown>>;
address: string; address: string;
onClick: () => void;
isAddressQueryLoading: boolean; isAddressQueryLoading: boolean;
isDegradedData: boolean; isDegradedData: boolean;
} }
...@@ -25,7 +24,12 @@ const PROP_TO_TAB = { ...@@ -25,7 +24,12 @@ const PROP_TO_TAB = {
validations_count: 'blocks_validated', validations_count: 'blocks_validated',
}; };
const AddressCounterItem = ({ prop, query, address, onClick, isAddressQueryLoading, isDegradedData }: Props) => { const AddressCounterItem = ({ prop, query, address, isAddressQueryLoading, isDegradedData }: Props) => {
const handleClick = React.useCallback(() => {
window.scrollTo({ top: 0, behavior: 'smooth' });
}, []);
if (query.isPlaceholderData || isAddressQueryLoading) { if (query.isPlaceholderData || isAddressQueryLoading) {
return <Skeleton h={ 5 } w="80px" borderRadius="full"/>; return <Skeleton h={ 5 } w="80px" borderRadius="full"/>;
} }
...@@ -53,8 +57,8 @@ const AddressCounterItem = ({ prop, query, address, onClick, isAddressQueryLoadi ...@@ -53,8 +57,8 @@ const AddressCounterItem = ({ prop, query, address, onClick, isAddressQueryLoadi
return ( return (
<LinkInternal <LinkInternal
href={ route({ pathname: '/address/[hash]', query: { hash: address, tab: PROP_TO_TAB[prop] } }) } href={ route({ pathname: '/address/[hash]', query: { hash: address, tab: PROP_TO_TAB[prop] } }) }
onClick={ onClick }
scroll={ false } scroll={ false }
onClick={ handleClick }
> >
{ Number(data).toLocaleString() } { Number(data).toLocaleString() }
</LinkInternal> </LinkInternal>
......
...@@ -12,7 +12,6 @@ import LinkInternal from 'ui/shared/links/LinkInternal'; ...@@ -12,7 +12,6 @@ import LinkInternal from 'ui/shared/links/LinkInternal';
import useAddressQuery from '../utils/useAddressQuery'; import useAddressQuery from '../utils/useAddressQuery';
type TableViewProps = { type TableViewProps = {
scrollRef?: React.RefObject<HTMLDivElement>;
className?: string; className?: string;
hash: string; hash: string;
tableId: string; tableId: string;
...@@ -25,23 +24,19 @@ type RecordViewProps = TableViewProps & { ...@@ -25,23 +24,19 @@ type RecordViewProps = TableViewProps & {
}; };
type BreadcrumbItemProps = { type BreadcrumbItemProps = {
scrollRef?: React.RefObject<HTMLDivElement>;
text: string; text: string;
href: string; href: string;
isLast?: boolean; isLast?: boolean;
}; };
const BreadcrumbItem = ({ text, href, isLast, scrollRef }: BreadcrumbItemProps) => { const BreadcrumbItem = ({ text, href, isLast }: BreadcrumbItemProps) => {
const iconColor = useColorModeValue('gray.300', 'gray.600'); const iconColor = useColorModeValue('gray.300', 'gray.600');
const currentUrl = isBrowser() ? window.location.href : ''; const currentUrl = isBrowser() ? window.location.href : '';
const onLinkClick = React.useCallback(() => { const onLinkClick = React.useCallback(() => {
window.setTimeout(() => { window.scrollTo({ top: 0, behavior: 'smooth' });
// cannot do scroll instantly, have to wait a little }, []);
scrollRef?.current?.scrollIntoView({ behavior: 'smooth' });
}, 500);
}, [ scrollRef ]);
if (isLast) { if (isLast) {
return ( return (
...@@ -95,20 +90,17 @@ const AddressMudBreadcrumbs = (props: TableViewProps | RecordViewProps) => { ...@@ -95,20 +90,17 @@ const AddressMudBreadcrumbs = (props: TableViewProps | RecordViewProps) => {
<BreadcrumbItem <BreadcrumbItem
text="MUD World" text="MUD World"
href={ route({ pathname: '/address/[hash]', query: queryParams }) } href={ route({ pathname: '/address/[hash]', query: queryParams }) }
scrollRef={ props.scrollRef }
/> />
<BreadcrumbItem <BreadcrumbItem
text={ props.tableName } text={ props.tableName }
href={ route({ pathname: '/address/[hash]', query: { ...queryParams, table_id: props.tableId } }) } href={ route({ pathname: '/address/[hash]', query: { ...queryParams, table_id: props.tableId } }) }
isLast={ !('recordId' in props) } isLast={ !('recordId' in props) }
scrollRef={ props.scrollRef }
/> />
{ ('recordId' in props) && ( { ('recordId' in props) && (
<BreadcrumbItem <BreadcrumbItem
text={ props.recordName } text={ props.recordName }
href={ route({ pathname: '/address/[hash]', query: { ...queryParams, table_id: props.tableId, record_id: props.recordId } }) } href={ route({ pathname: '/address/[hash]', query: { ...queryParams, table_id: props.tableId, record_id: props.recordId } }) }
isLast isLast
scrollRef={ props.scrollRef }
/> />
) } ) }
......
...@@ -14,13 +14,12 @@ import AddressMudRecordValues from './AddressMudRecordValues'; ...@@ -14,13 +14,12 @@ import AddressMudRecordValues from './AddressMudRecordValues';
import { getValueString } from './utils'; import { getValueString } from './utils';
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
tableId: string; tableId: string;
recordId: string; recordId: string;
}; };
const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true, scrollRef }: Props) => { const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const hash = getQueryParamString(router.query.hash); const hash = getQueryParamString(router.query.hash);
...@@ -50,7 +49,6 @@ const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true, scrollRef ...@@ -50,7 +49,6 @@ const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true, scrollRef
recordId={ recordId } recordId={ recordId }
recordName={ data.record.id } recordName={ data.record.id }
mb={ 6 } mb={ 6 }
scrollRef={ scrollRef }
/> />
) } ) }
<Show above="lg" ssr={ false }> <Show above="lg" ssr={ false }>
......
...@@ -23,14 +23,13 @@ const BREADCRUMBS_HEIGHT = 60; ...@@ -23,14 +23,13 @@ const BREADCRUMBS_HEIGHT = 60;
const FILTERS_HEIGHT = 44; const FILTERS_HEIGHT = 44;
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
tableId: string; tableId: string;
}; };
type FilterKeys = keyof AddressMudRecordsFilter; type FilterKeys = keyof AddressMudRecordsFilter;
const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) => { const AddressMudTable = ({ tableId, isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const [ sorting, setSorting ] = const [ sorting, setSorting ] =
React.useState<AddressMudRecordsSorting | undefined>(getSortParamsFromQuery<AddressMudRecordsSorting>(router.query, SORT_SEQUENCE)); React.useState<AddressMudRecordsSorting | undefined>(getSortParamsFromQuery<AddressMudRecordsSorting>(router.query, SORT_SEQUENCE));
...@@ -45,7 +44,6 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) = ...@@ -45,7 +44,6 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
pathParams: { hash, table_id: tableId }, pathParams: { hash, table_id: tableId },
filters, filters,
sorting, sorting,
scrollRef,
options: { options: {
// no placeholder data because the structure of a table is unpredictable // no placeholder data because the structure of a table is unpredictable
enabled: isQueryEnabled, enabled: isQueryEnabled,
...@@ -103,7 +101,6 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) = ...@@ -103,7 +101,6 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
hash={ hash } hash={ hash }
tableId={ tableId } tableId={ tableId }
tableName={ data?.table.table_full_name } tableName={ data?.table.table_full_name }
scrollRef={ scrollRef }
mb={ hasActiveFilters ? 4 : 0 } mb={ hasActiveFilters ? 4 : 0 }
/> />
) : null; ) : null;
...@@ -127,7 +124,6 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) = ...@@ -127,7 +124,6 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
setFilters={ setFilters } setFilters={ setFilters }
filters={ filters } filters={ filters }
toggleTableHasHorizontalScroll={ setTableHasHorizontalScroll.toggle } toggleTableHasHorizontalScroll={ setTableHasHorizontalScroll.toggle }
scrollRef={ scrollRef }
hash={ hash } hash={ hash }
/> />
) : null; ) : null;
......
...@@ -18,11 +18,10 @@ import AddressMudTablesListItem from './AddressMudTablesListItem'; ...@@ -18,11 +18,10 @@ import AddressMudTablesListItem from './AddressMudTablesListItem';
import AddressMudTablesTable from './AddressMudTablesTable'; import AddressMudTablesTable from './AddressMudTablesTable';
type Props = { type Props = {
scrollRef?: React.RefObject<HTMLDivElement>;
isQueryEnabled?: boolean; isQueryEnabled?: boolean;
}; };
const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => { const AddressMudTables = ({ isQueryEnabled = true }: Props) => {
const router = useRouter(); const router = useRouter();
const hash = getQueryParamString(router.query.hash); const hash = getQueryParamString(router.query.hash);
...@@ -34,7 +33,6 @@ const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => { ...@@ -34,7 +33,6 @@ const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => {
resourceName: 'address_mud_tables', resourceName: 'address_mud_tables',
pathParams: { hash }, pathParams: { hash },
filters: { q: debouncedSearchTerm }, filters: { q: debouncedSearchTerm },
scrollRef,
options: { options: {
enabled: isQueryEnabled, enabled: isQueryEnabled,
placeholderData: generateListStub<'address_mud_tables'>(ADDRESS_MUD_TABLE_ITEM, 3, { next_page_params: { placeholderData: generateListStub<'address_mud_tables'>(ADDRESS_MUD_TABLE_ITEM, 3, { next_page_params: {
...@@ -72,7 +70,6 @@ const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => { ...@@ -72,7 +70,6 @@ const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => {
items={ data.items } items={ data.items }
isLoading={ isPlaceholderData } isLoading={ isPlaceholderData }
top={ ACTION_BAR_HEIGHT_DESKTOP } top={ ACTION_BAR_HEIGHT_DESKTOP }
scrollRef={ scrollRef }
hash={ hash } hash={ hash }
/> />
</Hide> </Hide>
......
...@@ -11,12 +11,11 @@ type Props = { ...@@ -11,12 +11,11 @@ type Props = {
items: AddressMudTables['items']; items: AddressMudTables['items'];
isLoading: boolean; isLoading: boolean;
top: number; top: number;
scrollRef?: React.RefObject<HTMLDivElement>;
hash: string; hash: string;
}; };
//sorry for the naming //sorry for the naming
const AddressMudTablesTable = ({ items, isLoading, top, scrollRef, hash }: Props) => { const AddressMudTablesTable = ({ items, isLoading, top, hash }: Props) => {
return ( return (
<Table style={{ tableLayout: 'auto' }}> <Table style={{ tableLayout: 'auto' }}>
<Thead top={ top }> <Thead top={ top }>
...@@ -33,7 +32,6 @@ const AddressMudTablesTable = ({ items, isLoading, top, scrollRef, hash }: Props ...@@ -33,7 +32,6 @@ const AddressMudTablesTable = ({ items, isLoading, top, scrollRef, hash }: Props
key={ item.table.table_id + (isLoading ? String(index) : '') } key={ item.table.table_id + (isLoading ? String(index) : '') }
item={ item } item={ item }
isLoading={ isLoading } isLoading={ isLoading }
scrollRef={ scrollRef }
hash={ hash } hash={ hash }
/> />
)) } )) }
......
...@@ -10,15 +10,13 @@ import Skeleton from 'ui/shared/chakra/Skeleton'; ...@@ -10,15 +10,13 @@ import Skeleton from 'ui/shared/chakra/Skeleton';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
type Props = { type Props = {
item: AddressMudTableItem; item: AddressMudTableItem;
isLoading: boolean; isLoading: boolean;
scrollRef?: React.RefObject<HTMLDivElement>;
hash: string; hash: string;
}; };
const AddressMudTablesTableItem = ({ item, isLoading, scrollRef, hash }: Props) => { const AddressMudTablesTableItem = ({ item, isLoading, hash }: Props) => {
const [ isOpened, setIsOpened ] = useBoolean(false); const [ isOpened, setIsOpened ] = useBoolean(false);
const router = useRouter(); const router = useRouter();
...@@ -39,8 +37,9 @@ const AddressMudTablesTableItem = ({ item, isLoading, scrollRef, hash }: Props) ...@@ -39,8 +37,9 @@ const AddressMudTablesTableItem = ({ item, isLoading, scrollRef, hash }: Props)
{ shallow: true }, { shallow: true },
); );
} }
scrollRef?.current?.scrollIntoView();
}, [ router, scrollRef, hash ]); window.scrollTo({ top: 0, behavior: 'smooth' });
}, [ router, hash ]);
return ( return (
<> <>
......
...@@ -18,11 +18,7 @@ import useFetchTokens from '../utils/useFetchTokens'; ...@@ -18,11 +18,7 @@ import useFetchTokens from '../utils/useFetchTokens';
import TokenSelectDesktop from './TokenSelectDesktop'; import TokenSelectDesktop from './TokenSelectDesktop';
import TokenSelectMobile from './TokenSelectMobile'; import TokenSelectMobile from './TokenSelectMobile';
interface Props { const TokenSelect = () => {
onClick?: () => void;
}
const TokenSelect = ({ onClick }: Props) => {
const router = useRouter(); const router = useRouter();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
...@@ -38,8 +34,8 @@ const TokenSelect = ({ onClick }: Props) => { ...@@ -38,8 +34,8 @@ const TokenSelect = ({ onClick }: Props) => {
const handleIconButtonClick = React.useCallback(() => { const handleIconButtonClick = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Tokens show all (icon)' }); mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Tokens show all (icon)' });
onClick?.(); window.scrollTo({ top: 0, behavior: 'smooth' });
}, [ onClick ]); }, [ ]);
if (isPending) { if (isPending) {
return ( return (
......
...@@ -67,7 +67,6 @@ const AddressPageContent = () => { ...@@ -67,7 +67,6 @@ const AddressPageContent = () => {
const router = useRouter(); const router = useRouter();
const appProps = useAppContext(); const appProps = useAppContext();
const tabsScrollRef = React.useRef<HTMLDivElement>(null);
const hash = getQueryParamString(router.query.hash); const hash = getQueryParamString(router.query.hash);
const checkDomainName = useCheckDomainNameParam(hash); const checkDomainName = useCheckDomainNameParam(hash);
...@@ -154,23 +153,53 @@ const AddressPageContent = () => { ...@@ -154,23 +153,53 @@ const AddressPageContent = () => {
const tabs: Array<RoutedTab> = React.useMemo(() => { const tabs: Array<RoutedTab> = React.useMemo(() => {
return [ return [
{
id: 'index',
title: 'Details',
component: <AddressDetails addressQuery={ addressQuery }/>,
},
addressQuery.data?.is_contract ? {
id: 'contract',
title: () => {
const tabName = addressQuery.data.proxy_type === 'eip7702' ? 'Code' : 'Contract';
if (addressQuery.data.is_verified) {
return (
<>
<span>{ tabName }</span>
<IconSvg name="status/success" boxSize="14px" color="green.500" ml={ 1 }/>
</>
);
}
return tabName;
},
component: (
<AddressContract
tabs={ contractTabs.tabs }
shouldRender={ !isTabsLoading }
isLoading={ contractTabs.isLoading }
/>
),
subTabs: CONTRACT_TAB_IDS,
} : undefined,
config.features.mudFramework.isEnabled && mudTablesCountQuery.data && mudTablesCountQuery.data > 0 && { config.features.mudFramework.isEnabled && mudTablesCountQuery.data && mudTablesCountQuery.data > 0 && {
id: 'mud', id: 'mud',
title: 'MUD', title: 'MUD',
count: mudTablesCountQuery.data, count: mudTablesCountQuery.data,
component: <AddressMud scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>, component: <AddressMud shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
}, },
{ {
id: 'txs', id: 'txs',
title: 'Transactions', title: 'Transactions',
count: addressTabsCountersQuery.data?.transactions_count, count: addressTabsCountersQuery.data?.transactions_count,
component: <AddressTxs scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>, component: <AddressTxs shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
}, },
txInterpretation.isEnabled && txInterpretation.provider === 'noves' ? txInterpretation.isEnabled && txInterpretation.provider === 'noves' ?
{ {
id: 'account_history', id: 'account_history',
title: 'Account history', title: 'Account history',
component: <AddressAccountHistory scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>, component: <AddressAccountHistory shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
} : } :
undefined, undefined,
config.features.userOps.isEnabled && Boolean(userOpsAccountQuery.data?.total_ops) ? config.features.userOps.isEnabled && Boolean(userOpsAccountQuery.data?.total_ops) ?
...@@ -186,14 +215,14 @@ const AddressPageContent = () => { ...@@ -186,14 +215,14 @@ const AddressPageContent = () => {
id: 'withdrawals', id: 'withdrawals',
title: 'Withdrawals', title: 'Withdrawals',
count: addressTabsCountersQuery.data?.withdrawals_count, count: addressTabsCountersQuery.data?.withdrawals_count,
component: <AddressWithdrawals scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>, component: <AddressWithdrawals shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
} : } :
undefined, undefined,
{ {
id: 'token_transfers', id: 'token_transfers',
title: 'Token transfers', title: 'Token transfers',
count: addressTabsCountersQuery.data?.token_transfers_count, count: addressTabsCountersQuery.data?.token_transfers_count,
component: <AddressTokenTransfers scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>, component: <AddressTokenTransfers shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
}, },
{ {
id: 'tokens', id: 'tokens',
...@@ -206,13 +235,13 @@ const AddressPageContent = () => { ...@@ -206,13 +235,13 @@ const AddressPageContent = () => {
id: 'internal_txns', id: 'internal_txns',
title: 'Internal txns', title: 'Internal txns',
count: addressTabsCountersQuery.data?.internal_transactions_count, count: addressTabsCountersQuery.data?.internal_transactions_count,
component: <AddressInternalTxs scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>, component: <AddressInternalTxs shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
}, },
addressTabsCountersQuery.data?.celo_election_rewards_count ? { addressTabsCountersQuery.data?.celo_election_rewards_count ? {
id: 'epoch_rewards', id: 'epoch_rewards',
title: 'Epoch rewards', title: 'Epoch rewards',
count: addressTabsCountersQuery.data?.celo_election_rewards_count, count: addressTabsCountersQuery.data?.celo_election_rewards_count,
component: <AddressEpochRewards scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>, component: <AddressEpochRewards shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
} : undefined, } : undefined,
{ {
id: 'coin_balance_history', id: 'coin_balance_history',
...@@ -224,7 +253,7 @@ const AddressPageContent = () => { ...@@ -224,7 +253,7 @@ const AddressPageContent = () => {
id: 'blocks_validated', id: 'blocks_validated',
title: `Blocks ${ getNetworkValidationActionText() }`, title: `Blocks ${ getNetworkValidationActionText() }`,
count: addressTabsCountersQuery.data?.validations_count, count: addressTabsCountersQuery.data?.validations_count,
component: <AddressBlocksValidated scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>, component: <AddressBlocksValidated shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
} : } :
undefined, undefined,
addressTabsCountersQuery.data?.logs_count ? addressTabsCountersQuery.data?.logs_count ?
...@@ -232,38 +261,12 @@ const AddressPageContent = () => { ...@@ -232,38 +261,12 @@ const AddressPageContent = () => {
id: 'logs', id: 'logs',
title: 'Logs', title: 'Logs',
count: addressTabsCountersQuery.data?.logs_count, count: addressTabsCountersQuery.data?.logs_count,
component: <AddressLogs scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>, component: <AddressLogs shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
} : } :
undefined, undefined,
addressQuery.data?.is_contract ? {
id: 'contract',
title: () => {
const tabName = addressQuery.data.proxy_type === 'eip7702' ? 'Code' : 'Contract';
if (addressQuery.data.is_verified) {
return (
<>
<span>{ tabName }</span>
<IconSvg name="status/success" boxSize="14px" color="green.500" ml={ 1 }/>
</>
);
}
return tabName;
},
component: (
<AddressContract
tabs={ contractTabs.tabs }
shouldRender={ !isTabsLoading }
isLoading={ contractTabs.isLoading }
/>
),
subTabs: CONTRACT_TAB_IDS,
} : undefined,
].filter(Boolean); ].filter(Boolean);
}, [ }, [
addressQuery.data, addressQuery,
contractTabs, contractTabs,
addressTabsCountersQuery.data, addressTabsCountersQuery.data,
userOpsAccountQuery.data, userOpsAccountQuery.data,
...@@ -348,10 +351,6 @@ const AddressPageContent = () => { ...@@ -348,10 +351,6 @@ const AddressPageContent = () => {
/> />
); );
const content = (addressQuery.isError || addressQuery.isDegradedData) ?
null :
<RoutedTabs tabs={ tabs } tabListProps={{ mt: 6 }} isLoading={ isTabsLoading }/>;
const backLink = React.useMemo(() => { const backLink = React.useMemo(() => {
if (appProps.referrer && appProps.referrer.includes('/accounts')) { if (appProps.referrer && appProps.referrer.includes('/accounts')) {
return { return {
...@@ -433,10 +432,7 @@ const AddressPageContent = () => { ...@@ -433,10 +432,7 @@ const AddressPageContent = () => {
{ !addressMetadataQuery.isPending && { !addressMetadataQuery.isPending &&
<AddressMetadataAlert tags={ addressMetadataQuery.data?.addresses?.[hash.toLowerCase()]?.tags } mt="-4px" mb={ 6 }/> } <AddressMetadataAlert tags={ addressMetadataQuery.data?.addresses?.[hash.toLowerCase()]?.tags } mt="-4px" mb={ 6 }/> }
{ config.features.metasuites.isEnabled && <Box display="none" id="meta-suites__address" data-ready={ !isLoading }/> } { config.features.metasuites.isEnabled && <Box display="none" id="meta-suites__address" data-ready={ !isLoading }/> }
<AddressDetails addressQuery={ addressQuery } scrollRef={ tabsScrollRef }/> <RoutedTabs tabs={ tabs } tabListProps={{ mt: 6 }} isLoading={ isTabsLoading }/>
{ /* should stay before tabs to scroll up with pagination */ }
<Box ref={ tabsScrollRef }></Box>
{ content }
</> </>
); );
}; };
......
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