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

Internal transactions page: add search by hash (#2715)

Fixes #2623
parent 9f661cc6
import type { ApiResource } from '../../types'; import type { ApiResource } from '../../types';
import type { TxBlobs } from 'types/api/blobs'; import type { TxBlobs } from 'types/api/blobs';
import type { InternalTransactionsResponse } from 'types/api/internalTransaction'; import type { InternalTransactionFilters, InternalTransactionsResponse } from 'types/api/internalTransaction';
import type { LogsResponseTx } from 'types/api/log'; import type { LogsResponseTx } from 'types/api/log';
import type { RawTracesResponse } from 'types/api/rawTrace'; import type { RawTracesResponse } from 'types/api/rawTrace';
import type { TokenTransferResponse, TokenTransferFilters } from 'types/api/tokenTransfer'; import type { TokenTransferResponse, TokenTransferFilters } from 'types/api/tokenTransfer';
...@@ -94,6 +94,7 @@ export const GENERAL_API_TX_RESOURCES = { ...@@ -94,6 +94,7 @@ export const GENERAL_API_TX_RESOURCES = {
internal_txs: { internal_txs: {
path: '/api/v2/internal-transactions', path: '/api/v2/internal-transactions',
paginated: true, paginated: true,
filterFields: [ 'transaction_hash' as const ],
}, },
} satisfies Record<string, ApiResource>; } satisfies Record<string, ApiResource>;
...@@ -125,5 +126,6 @@ export type GeneralApiTxPaginationFilters<R extends GeneralApiTxResourceName> = ...@@ -125,5 +126,6 @@ export type GeneralApiTxPaginationFilters<R extends GeneralApiTxResourceName> =
R extends 'general:txs_validated' | 'general:txs_pending' ? TTxsFilters : R extends 'general:txs_validated' | 'general:txs_pending' ? TTxsFilters :
R extends 'general:txs_with_blobs' ? TTxsWithBlobsFilters : R extends 'general:txs_with_blobs' ? TTxsWithBlobsFilters :
R extends 'general:tx_token_transfers' ? TokenTransferFilters : R extends 'general:tx_token_transfers' ? TokenTransferFilters :
R extends 'general:internal_txs' ? InternalTransactionFilters :
never; never;
/* eslint-enable @stylistic/indent */ /* eslint-enable @stylistic/indent */
...@@ -34,3 +34,7 @@ export interface InternalTransactionsResponse { ...@@ -34,3 +34,7 @@ export interface InternalTransactionsResponse {
transaction_index: number; transaction_index: number;
} | null; } | null;
} }
export interface InternalTransactionFilters {
transaction_hash: string;
}
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import useDebounce from 'lib/hooks/useDebounce';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import getQueryParamString from 'lib/router/getQueryParamString';
import { INTERNAL_TX } from 'stubs/internalTx'; import { INTERNAL_TX } from 'stubs/internalTx';
import { generateListStub } from 'stubs/utils'; import { generateListStub } from 'stubs/utils';
import { FilterInput } from 'toolkit/components/filters/FilterInput';
import { apos } from 'toolkit/utils/htmlEntities';
import InternalTxsList from 'ui/internalTxs/InternalTxsList'; import InternalTxsList from 'ui/internalTxs/InternalTxsList';
import InternalTxsTable from 'ui/internalTxs/InternalTxsTable'; import InternalTxsTable from 'ui/internalTxs/InternalTxsTable';
import ActionBar from 'ui/shared/ActionBar'; import ActionBar from 'ui/shared/ActionBar';
...@@ -13,10 +18,15 @@ import Pagination from 'ui/shared/pagination/Pagination'; ...@@ -13,10 +18,15 @@ import Pagination from 'ui/shared/pagination/Pagination';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages'; import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
const InternalTxs = () => { const InternalTxs = () => {
const router = useRouter();
const [ searchTerm, setSearchTerm ] = React.useState(getQueryParamString(router.query.transaction_hash) || undefined);
const debouncedSearchTerm = useDebounce(searchTerm || '', 300);
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const { isError, isPlaceholderData, data, pagination } = useQueryWithPages({ const { isError, isPlaceholderData, data, pagination, onFilterChange } = useQueryWithPages({
resourceName: 'general:internal_txs', resourceName: 'general:internal_txs',
filters: { transaction_hash: debouncedSearchTerm },
options: { options: {
placeholderData: generateListStub<'general:internal_txs'>( placeholderData: generateListStub<'general:internal_txs'>(
INTERNAL_TX, INTERNAL_TX,
...@@ -34,11 +44,36 @@ const InternalTxs = () => { ...@@ -34,11 +44,36 @@ const InternalTxs = () => {
}, },
}); });
const actionBar = (!isMobile || pagination.isVisible) ? ( const handleSearchTermChange = React.useCallback((value: string) => {
<ActionBar mt={ -6 }> onFilterChange({ transaction_hash: value });
<Pagination ml="auto" { ...pagination }/> setSearchTerm(value);
</ActionBar> }, [ onFilterChange ]);
) : null;
const filterInput = (
<FilterInput
w={{ base: '100%', lg: '350px' }}
size="sm"
onChange={ handleSearchTermChange }
placeholder="Search by transaction hash"
initialValue={ searchTerm }
/>
);
const actionBar = (
<>
<Box mb={ 6 } display={{ base: 'flex', lg: 'none' }}>
{ filterInput }
</Box>
{ (!isMobile || pagination.isVisible) && (
<ActionBar mt={ -6 }>
<Box display={{ base: 'none', lg: 'flex' }}>
{ filterInput }
</Box>
<Pagination ml="auto" { ...pagination }/>
</ActionBar>
) }
</>
);
const content = data?.items ? ( const content = data?.items ? (
<> <>
...@@ -61,6 +96,10 @@ const InternalTxs = () => { ...@@ -61,6 +96,10 @@ const InternalTxs = () => {
isError={ isError } isError={ isError }
itemsNum={ data?.items.length } itemsNum={ data?.items.length }
emptyText="There are no internal transactions." emptyText="There are no internal transactions."
filterProps={{
emptyFilteredText: `Couldn${ apos }t find any internal transaction that matches your query.`,
hasActiveFilters: Boolean(searchTerm),
}}
actionBar={ actionBar } actionBar={ actionBar }
> >
{ content } { 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