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 { 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 { RawTracesResponse } from 'types/api/rawTrace';
import type { TokenTransferResponse, TokenTransferFilters } from 'types/api/tokenTransfer';
......@@ -94,6 +94,7 @@ export const GENERAL_API_TX_RESOURCES = {
internal_txs: {
path: '/api/v2/internal-transactions',
paginated: true,
filterFields: [ 'transaction_hash' as const ],
},
} satisfies Record<string, ApiResource>;
......@@ -125,5 +126,6 @@ export type GeneralApiTxPaginationFilters<R extends GeneralApiTxResourceName> =
R extends 'general:txs_validated' | 'general:txs_pending' ? TTxsFilters :
R extends 'general:txs_with_blobs' ? TTxsWithBlobsFilters :
R extends 'general:tx_token_transfers' ? TokenTransferFilters :
R extends 'general:internal_txs' ? InternalTransactionFilters :
never;
/* eslint-enable @stylistic/indent */
......@@ -34,3 +34,7 @@ export interface InternalTransactionsResponse {
transaction_index: number;
} | null;
}
export interface InternalTransactionFilters {
transaction_hash: string;
}
import { Box } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
import useDebounce from 'lib/hooks/useDebounce';
import useIsMobile from 'lib/hooks/useIsMobile';
import getQueryParamString from 'lib/router/getQueryParamString';
import { INTERNAL_TX } from 'stubs/internalTx';
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 InternalTxsTable from 'ui/internalTxs/InternalTxsTable';
import ActionBar from 'ui/shared/ActionBar';
......@@ -13,10 +18,15 @@ import Pagination from 'ui/shared/pagination/Pagination';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
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 { isError, isPlaceholderData, data, pagination } = useQueryWithPages({
const { isError, isPlaceholderData, data, pagination, onFilterChange } = useQueryWithPages({
resourceName: 'general:internal_txs',
filters: { transaction_hash: debouncedSearchTerm },
options: {
placeholderData: generateListStub<'general:internal_txs'>(
INTERNAL_TX,
......@@ -34,11 +44,36 @@ const InternalTxs = () => {
},
});
const actionBar = (!isMobile || pagination.isVisible) ? (
<ActionBar mt={ -6 }>
<Pagination ml="auto" { ...pagination }/>
</ActionBar>
) : null;
const handleSearchTermChange = React.useCallback((value: string) => {
onFilterChange({ transaction_hash: value });
setSearchTerm(value);
}, [ onFilterChange ]);
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 ? (
<>
......@@ -61,6 +96,10 @@ const InternalTxs = () => {
isError={ isError }
itemsNum={ data?.items.length }
emptyText="There are no internal transactions."
filterProps={{
emptyFilteredText: `Couldn${ apos }t find any internal transaction that matches your query.`,
hasActiveFilters: Boolean(searchTerm),
}}
actionBar={ actionBar }
>
{ 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