Commit 3d60e745 authored by tom's avatar tom

blocks and block txs

parent 66197cb7
...@@ -7,7 +7,7 @@ import type { ApiResource } from './resources'; ...@@ -7,7 +7,7 @@ import type { ApiResource } from './resources';
export default function buildUrl( export default function buildUrl(
resource: ApiResource, resource: ApiResource,
pathParams?: Record<string, string>, pathParams?: Record<string, string>,
queryParams?: Record<string, string | undefined>, queryParams?: Record<string, string | number | undefined>,
) { ) {
// FIXME // FIXME
// 1. I was not able to figure out how to send CORS with credentials from localhost // 1. I was not able to figure out how to send CORS with credentials from localhost
...@@ -28,7 +28,7 @@ export default function buildUrl( ...@@ -28,7 +28,7 @@ export default function buildUrl(
const url = new URL(compile(path)(pathParams), baseUrl); const url = new URL(compile(path)(pathParams), baseUrl);
queryParams && Object.entries(queryParams).forEach(([ key, value ]) => { queryParams && Object.entries(queryParams).forEach(([ key, value ]) => {
value && url.searchParams.append(key, value); value && url.searchParams.append(key, String(value));
}); });
return url.toString(); return url.toString();
......
import type ArrayElement from 'types/utils/ArrayElement';
import appConfig from 'configs/app/config'; import appConfig from 'configs/app/config';
export interface ApiResource { export interface ApiResource {
...@@ -7,7 +9,7 @@ export interface ApiResource { ...@@ -7,7 +9,7 @@ export interface ApiResource {
} }
export const RESOURCES = { export const RESOURCES = {
// account // ACCOUNT
user_info: { user_info: {
path: '/api/account/v1/user/info', path: '/api/account/v1/user/info',
}, },
...@@ -42,12 +44,34 @@ export const RESOURCES = { ...@@ -42,12 +44,34 @@ export const RESOURCES = {
basePath: appConfig.statsApi.basePath, basePath: appConfig.statsApi.basePath,
}, },
// BLOCKS, TXS
blocks: {
path: '/api/v2/blocks',
paginationFields: [ 'block_number' as const, 'items_count' as const ],
filterFields: [ 'type' as const ],
},
block_txs: {
path: '/api/v2/blocks/:id/transactions',
paginationFields: [ 'block_number' as const, 'items_count' as const, 'index' as const ],
filterFields: [],
},
// DEPRECATED // DEPRECATED
old_api: { old_api: {
path: '/api', path: '/api',
}, },
}; };
export type ResourceName = keyof typeof RESOURCES;
export type ResourceFiltersKey<R extends ResourceName> = typeof RESOURCES[R] extends {filterFields: Array<unknown>} ?
ArrayElement<typeof RESOURCES[R]['filterFields']> :
never;
export type ResourcePaginationKey<R extends ResourceName> = typeof RESOURCES[R] extends {paginationFields: Array<unknown>} ?
ArrayElement<typeof RESOURCES[R]['paginationFields']> :
never;
export const resourceKey = (x: keyof typeof RESOURCES) => x; export const resourceKey = (x: keyof typeof RESOURCES) => x;
export interface ResourceError<T = unknown> { export interface ResourceError<T = unknown> {
......
...@@ -10,7 +10,7 @@ import type { ResourceError, ApiResource } from './resources'; ...@@ -10,7 +10,7 @@ import type { ResourceError, ApiResource } from './resources';
export interface Params { export interface Params {
pathParams?: Record<string, string>; pathParams?: Record<string, string>;
queryParams?: Record<string, string | undefined>; queryParams?: Record<string, string | number | undefined>;
fetchParams?: Pick<FetchParams, 'body' | 'method'>; fetchParams?: Pick<FetchParams, 'body' | 'method'>;
} }
......
...@@ -2,24 +2,33 @@ import type { UseQueryOptions } from '@tanstack/react-query'; ...@@ -2,24 +2,33 @@ import type { UseQueryOptions } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import type { UserInfo, CustomAbis, PublicTags, AddressTags, TransactionTags, ApiKeys, WatchlistAddress } from 'types/api/account'; import type { UserInfo, CustomAbis, PublicTags, AddressTags, TransactionTags, ApiKeys, WatchlistAddress } from 'types/api/account';
import type { BlocksResponse, BlockTransactionsResponse } from 'types/api/block';
import type { Stats, Charts } from 'types/api/stats'; import type { Stats, Charts } from 'types/api/stats';
import type { RESOURCES, ResourceError } from './resources'; import type { RESOURCES, ResourceError, ResourceName } from './resources';
import type { Params as ApiFetchParams } from './useApiFetch'; import type { Params as ApiFetchParams } from './useApiFetch';
import useApiFetch from './useApiFetch'; import useApiFetch from './useApiFetch';
interface Params<R extends keyof typeof RESOURCES> extends ApiFetchParams { export interface Params<R extends ResourceName> extends ApiFetchParams {
queryOptions?: Omit<UseQueryOptions<unknown, ResourceError, ResourcePayload<R>>, 'queryKey' | 'queryFn'>; queryOptions?: Omit<UseQueryOptions<unknown, ResourceError, ResourcePayload<R>>, 'queryKey' | 'queryFn'>;
} }
export default function useApiQuery<R extends keyof typeof RESOURCES>( export function getResourceKey<R extends ResourceName>(resource: R, { pathParams, queryParams }: Params<R> = {}) {
if (pathParams || queryParams) {
return [ resource, { ...pathParams, ...queryParams } ];
}
return [ resource ];
}
export default function useApiQuery<R extends ResourceName>(
resource: R, resource: R,
{ queryOptions, pathParams, queryParams, fetchParams }: Params<R> = {}, { queryOptions, pathParams, queryParams, fetchParams }: Params<R> = {},
) { ) {
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
return useQuery<unknown, ResourceError, ResourcePayload<R>>( return useQuery<unknown, ResourceError, ResourcePayload<R>>(
pathParams || queryParams ? [ resource, { ...pathParams, ...queryParams } ] : [ resource ], getResourceKey(resource, { pathParams, queryParams }),
async() => { async() => {
return apiFetch<R, ResourcePayload<R>, ResourceError>(resource, { pathParams, queryParams, fetchParams }); return apiFetch<R, ResourcePayload<R>, ResourceError>(resource, { pathParams, queryParams, fetchParams });
}, queryOptions); }, queryOptions);
...@@ -35,4 +44,6 @@ export type ResourcePayload<Q extends keyof typeof RESOURCES> = ...@@ -35,4 +44,6 @@ export type ResourcePayload<Q extends keyof typeof RESOURCES> =
Q extends 'watchlist' ? Array<WatchlistAddress> : Q extends 'watchlist' ? Array<WatchlistAddress> :
Q extends 'stats_counters' ? Stats : Q extends 'stats_counters' ? Stats :
Q extends 'stats_charts' ? Charts : Q extends 'stats_charts' ? Charts :
never; Q extends 'blocks' ? BlocksResponse :
Q extends 'block_txs' ? BlockTransactionsResponse :
never;
import type { UseQueryOptions } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { useQuery, useQueryClient } from '@tanstack/react-query'; import mapValues from 'lodash/mapValues';
import { pick, omit } from 'lodash'; import omit from 'lodash/omit';
import pick from 'lodash/pick';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { animateScroll, scroller } from 'react-scroll'; import { animateScroll, scroller } from 'react-scroll';
import { PAGINATION_FIELDS, PAGINATION_FILTERS_FIELDS } from 'types/api/pagination'; import type { PaginatedResponseX, PaginatedResources, PaginationFiltersX } from 'types/api/pagination';
import type { PaginationParams, PaginatedResponse, PaginatedQueryKeys, PaginationFilters } from 'types/api/pagination';
import useFetch from 'lib/hooks/useFetch'; import { RESOURCES } from 'lib/api/resources';
import type { Params as UseApiQueryParams } from 'lib/api/useApiQuery';
import useApiQuery from 'lib/api/useApiQuery';
interface Params<QueryName extends PaginatedQueryKeys> { interface Params<Resource extends PaginatedResources> {
apiPath: string; resourceName: Resource;
queryName: QueryName; options?: UseApiQueryParams<Resource>['queryOptions'];
queryIds?: Array<string>; pathParams?: Record<string, string>;
filters?: PaginationFilters<QueryName>; filters?: PaginationFiltersX<Resource>;
options?: Omit<UseQueryOptions<unknown, unknown, PaginatedResponse<QueryName>>, 'queryKey' | 'queryFn'>;
scroll?: { elem: string; offset: number }; scroll?: { elem: string; offset: number };
} }
export default function useQueryWithPages<QueryName extends PaginatedQueryKeys>({ export default function useQueryWithPages<Resource extends PaginatedResources>({
queryName, resourceName,
filters, filters,
options, options,
apiPath, pathParams,
queryIds,
scroll, scroll,
}: Params<QueryName>) { }: Params<Resource>) {
const paginationFields = PAGINATION_FIELDS[queryName]; const resource = RESOURCES[resourceName];
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const router = useRouter(); const router = useRouter();
type NextPageParams = {
[K in keyof PaginatedResponseX<Resource>['next_page_params']]: string;
}
const currPageParams = mapValues(pick(router.query, resource.paginationFields), (value) => value?.toString()) as NextPageParams;
const [ page, setPage ] = React.useState<number>(router.query.page && !Array.isArray(router.query.page) ? Number(router.query.page) : 1); const [ page, setPage ] = React.useState<number>(router.query.page && !Array.isArray(router.query.page) ? Number(router.query.page) : 1);
const currPageParams = pick(router.query, paginationFields); const [ pageParams, setPageParams ] = React.useState<Record<number, NextPageParams>>({
const [ pageParams, setPageParams ] = React.useState<Array<PaginationParams<QueryName>>>([ ]); [page]: currPageParams,
const fetch = useFetch(); });
const isMounted = React.useRef(false);
const canGoBackwards = React.useRef(!router.query.page);
const [ hasPagination, setHasPagination ] = React.useState(page > 1); const [ hasPagination, setHasPagination ] = React.useState(page > 1);
const queryKey = [ queryName, ...(queryIds || []), { page, filters } ]; const isMounted = React.useRef(false);
const canGoBackwards = React.useRef(!router.query.page);
const queryParams = { ...filters, ...pageParams[page] };
const scrollToTop = useCallback(() => { const scrollToTop = useCallback(() => {
scroll ? scroller.scrollTo(scroll.elem, { offset: scroll.offset }) : animateScroll.scrollToTop({ duration: 0 }); scroll ? scroller.scrollTo(scroll.elem, { offset: scroll.offset }) : animateScroll.scrollToTop({ duration: 0 });
}, [ scroll ]); }, [ scroll ]);
const queryResult = useQuery<unknown, unknown, PaginatedResponse<QueryName>>( const queryResult = useApiQuery(resourceName, {
queryKey, pathParams,
async() => { queryParams,
const params: Array<string> = []; queryOptions: {
staleTime: page === 1 ? 0 : Infinity,
Object.entries({ ...filters, ...currPageParams }).forEach(([ key, val ]) => { ...options,
if (Array.isArray(val)) {
val.length && params.push(`${ key }=${ val.join(',') }`);
} else if (val) {
params.push(`${ key }=${ val }`);
}
});
return fetch(`${ apiPath }${ params.length ? '?' + params.join('&') : '' }`);
}, },
{ staleTime: page === 1 ? 0 : Infinity, ...options }, });
);
const { data } = queryResult; const { data } = queryResult;
const onNextPageClick = useCallback(() => { const onNextPageClick = useCallback(() => {
...@@ -69,9 +66,13 @@ export default function useQueryWithPages<QueryName extends PaginatedQueryKeys>( ...@@ -69,9 +66,13 @@ export default function useQueryWithPages<QueryName extends PaginatedQueryKeys>(
return; return;
} }
const nextPageParams = data.next_page_params; const nextPageParams = data.next_page_params;
if (page >= pageParams.length && data?.next_page_params) {
setPageParams(prev => [ ...prev, nextPageParams ]); setPageParams((prev) => ({
} ...prev,
[page + 1]: mapValues(nextPageParams, (value) => value?.toString()) as NextPageParams,
}));
setPage(prev => prev + 1);
const nextPageQuery = { ...router.query }; const nextPageQuery = { ...router.query };
Object.entries(nextPageParams).forEach(([ key, val ]) => nextPageQuery[key] = val.toString()); Object.entries(nextPageParams).forEach(([ key, val ]) => nextPageQuery[key] = val.toString());
nextPageQuery.page = String(page + 1); nextPageQuery.page = String(page + 1);
...@@ -80,53 +81,52 @@ export default function useQueryWithPages<QueryName extends PaginatedQueryKeys>( ...@@ -80,53 +81,52 @@ export default function useQueryWithPages<QueryName extends PaginatedQueryKeys>(
router.push({ pathname: router.pathname, query: nextPageQuery }, undefined, { shallow: true }) router.push({ pathname: router.pathname, query: nextPageQuery }, undefined, { shallow: true })
.then(() => { .then(() => {
scrollToTop(); scrollToTop();
setPage(prev => prev + 1);
}); });
}, [ data?.next_page_params, page, pageParams.length, router, scrollToTop ]); }, [ data?.next_page_params, page, router, scrollToTop ]);
const onPrevPageClick = useCallback(() => { const onPrevPageClick = useCallback(() => {
// returning to the first page // returning to the first page
// we dont have pagination params for the first page // we dont have pagination params for the first page
let nextPageQuery: typeof router.query = { ...router.query }; let nextPageQuery: typeof router.query = { ...router.query };
if (page === 2) { if (page === 2) {
nextPageQuery = omit(router.query, paginationFields, 'page'); nextPageQuery = omit(router.query, resource.paginationFields, 'page');
canGoBackwards.current = true; canGoBackwards.current = true;
} else { } else {
const nextPageParams = { ...pageParams[page - 2] }; const nextPageParams = pageParams[page - 1];
nextPageParams && Object.entries(nextPageParams).forEach(([ key, val ]) => nextPageQuery[key] = val.toString()); nextPageParams && Object.entries(nextPageParams).forEach(([ key, val ]) => nextPageQuery[key] = String(val));
nextPageQuery.page = String(page - 1); nextPageQuery.page = String(page - 1);
} }
router.query = nextPageQuery;
router.push({ pathname: router.pathname, query: nextPageQuery }, undefined, { shallow: true }) router.push({ pathname: router.pathname, query: nextPageQuery }, undefined, { shallow: true })
.then(() => { .then(() => {
scrollToTop(); scrollToTop();
setPage(prev => prev - 1); setPage(prev => prev - 1);
page === 2 && queryClient.removeQueries({ queryKey: [ queryName ] }); page === 2 && queryClient.removeQueries({ queryKey: [ resourceName ] });
}); });
setHasPagination(true); setHasPagination(true);
}, [ router, page, paginationFields, pageParams, queryClient, scrollToTop, queryName ]); }, [ router, page, resource.paginationFields, pageParams, scrollToTop, queryClient, resourceName ]);
const resetPage = useCallback(() => { const resetPage = useCallback(() => {
queryClient.removeQueries({ queryKey: [ queryName ] }); queryClient.removeQueries({ queryKey: [ resourceName ] });
router.push({ pathname: router.pathname, query: omit(router.query, paginationFields, 'page') }, undefined, { shallow: true }).then(() => { router.push({ pathname: router.pathname, query: omit(router.query, resource.paginationFields, 'page') }, undefined, { shallow: true }).then(() => {
queryClient.removeQueries({ queryKey: [ queryName ] }); queryClient.removeQueries({ queryKey: [ resourceName ] });
scrollToTop(); scrollToTop();
setPage(1); setPage(1);
setPageParams([ ]); setPageParams({});
canGoBackwards.current = true; canGoBackwards.current = true;
window.setTimeout(() => { window.setTimeout(() => {
// FIXME after router is updated we still have inactive queries for previously visited page (e.g third), where we came from // FIXME after router is updated we still have inactive queries for previously visited page (e.g third), where we came from
// so have to remove it but with some delay :) // so have to remove it but with some delay :)
queryClient.removeQueries({ queryKey: [ queryName ], type: 'inactive' }); queryClient.removeQueries({ queryKey: [ resourceName ], type: 'inactive' });
}, 100); }, 100);
}); });
setHasPagination(true); setHasPagination(true);
}, [ queryClient, queryName, router, paginationFields, scrollToTop ]); }, [ queryClient, resourceName, router, resource.paginationFields, scrollToTop ]);
const onFilterChange = useCallback((newFilters: PaginationFilters<QueryName> | undefined) => { const onFilterChange = useCallback((newFilters: PaginationFiltersX<Resource> | undefined) => {
const newQuery = omit(router.query, PAGINATION_FIELDS[queryName], 'page', PAGINATION_FILTERS_FIELDS[queryName]); const newQuery = omit(router.query, resource.paginationFields, 'page', resource.filterFields);
if (newFilters) { if (newFilters) {
Object.entries(newFilters).forEach(([ key, value ]) => { Object.entries(newFilters).forEach(([ key, value ]) => {
if (value && value.length) { if (value && value.length) {
...@@ -143,12 +143,12 @@ export default function useQueryWithPages<QueryName extends PaginatedQueryKeys>( ...@@ -143,12 +143,12 @@ export default function useQueryWithPages<QueryName extends PaginatedQueryKeys>(
{ shallow: true }, { shallow: true },
).then(() => { ).then(() => {
setPage(1); setPage(1);
setPageParams([ ]); setPageParams({});
scrollToTop(); scrollToTop();
}); });
}, [ queryName, router, scrollToTop, setPageParams, setPage ]); }, [ router, resource.paginationFields, resource.filterFields, scrollToTop ]);
const hasPaginationParams = Object.keys(currPageParams).length > 0; const hasPaginationParams = Object.keys(currPageParams || {}).length > 0;
const nextPageParams = data?.next_page_params; const nextPageParams = data?.next_page_params;
const pagination = { const pagination = {
...@@ -165,12 +165,12 @@ export default function useQueryWithPages<QueryName extends PaginatedQueryKeys>( ...@@ -165,12 +165,12 @@ export default function useQueryWithPages<QueryName extends PaginatedQueryKeys>(
React.useEffect(() => { React.useEffect(() => {
if (page !== 1 && isMounted.current) { if (page !== 1 && isMounted.current) {
queryClient.cancelQueries({ queryKey }); queryClient.cancelQueries({ queryKey: [ resourceName ] });
setPage(1); setPage(1);
} }
// hook should run only when queryName has changed // hook should run only when queryName has changed
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [ queryName ]); }, [ resourceName ]);
React.useEffect(() => { React.useEffect(() => {
window.setTimeout(() => { window.setTimeout(() => {
......
...@@ -32,6 +32,17 @@ export type PaginatedQueryKeys = ...@@ -32,6 +32,17 @@ export type PaginatedQueryKeys =
QueryKeys.addressCoinBalanceHistory | QueryKeys.addressCoinBalanceHistory |
QueryKeys.addressBlocksValidated; QueryKeys.addressBlocksValidated;
export type PaginatedResources = 'blocks' | 'block_txs';
export type PaginatedResponseX<Q extends PaginatedResources> =
Q extends 'blocks' ? BlocksResponse :
Q extends 'block_txs' ? BlockTransactionsResponse :
never;
export type PaginationFiltersX<Q extends PaginatedResources> =
Q extends 'blocks' ? BlockFilters :
never;
export type PaginatedResponse<Q extends PaginatedQueryKeys> = export type PaginatedResponse<Q extends PaginatedQueryKeys> =
Q extends QueryKeys.addressInternalTxs ? AddressInternalTxsResponse : Q extends QueryKeys.addressInternalTxs ? AddressInternalTxsResponse :
Q extends QueryKeys.addressTxs ? AddressTransactionsResponse : Q extends QueryKeys.addressTxs ? AddressTransactionsResponse :
......
...@@ -21,6 +21,7 @@ import SkeletonTable from 'ui/shared/skeletons/SkeletonTable'; ...@@ -21,6 +21,7 @@ import SkeletonTable from 'ui/shared/skeletons/SkeletonTable';
type QueryResult = UseQueryResult<BlocksResponse> & { type QueryResult = UseQueryResult<BlocksResponse> & {
pagination: PaginationProps; pagination: PaginationProps;
isPaginationVisible: boolean;
}; };
interface Props { interface Props {
...@@ -110,11 +111,9 @@ const BlocksContent = ({ type, query }: Props) => { ...@@ -110,11 +111,9 @@ const BlocksContent = ({ type, query }: Props) => {
})(); })();
const isPaginatorHidden = !query.isLoading && !query.isError && query.pagination.page === 1 && !query.pagination.hasNextPage;
return ( return (
<> <>
{ isMobile && !isPaginatorHidden && ( { isMobile && query.isPaginationVisible && (
<ActionBar mt={ -6 }> <ActionBar mt={ -6 }>
<Pagination ml="auto" { ...query.pagination }/> <Pagination ml="auto" { ...query.pagination }/>
</ActionBar> </ActionBar>
......
...@@ -2,7 +2,6 @@ import { Flex, Icon, Link, Tooltip } from '@chakra-ui/react'; ...@@ -2,7 +2,6 @@ import { Flex, Icon, Link, Tooltip } from '@chakra-ui/react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import { QueryKeys } from 'types/client/queries';
import type { RoutedTab } from 'ui/shared/RoutedTabs/types'; import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import eastArrowIcon from 'icons/arrows/east.svg'; import eastArrowIcon from 'icons/arrows/east.svg';
...@@ -30,8 +29,7 @@ const BlockPageContent = () => { ...@@ -30,8 +29,7 @@ const BlockPageContent = () => {
const appProps = useAppContext(); const appProps = useAppContext();
const blockTxsQuery = useQueryWithPages({ const blockTxsQuery = useQueryWithPages({
apiPath: `/node-api/blocks/${ router.query.id }/transactions`, resourceName: 'block_txs',
queryName: QueryKeys.blockTxs,
options: { options: {
enabled: Boolean(router.query.id && router.query.tab === 'txs'), enabled: Boolean(router.query.id && router.query.tab === 'txs'),
}, },
......
...@@ -2,7 +2,6 @@ import { useRouter } from 'next/router'; ...@@ -2,7 +2,6 @@ import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { BlockType } from 'types/api/block'; import type { BlockType } from 'types/api/block';
import { QueryKeys } from 'types/client/queries';
import type { RoutedTab } from 'ui/shared/RoutedTabs/types'; import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
...@@ -19,12 +18,6 @@ const TAB_TO_TYPE: Record<string, BlockType> = { ...@@ -19,12 +18,6 @@ const TAB_TO_TYPE: Record<string, BlockType> = {
uncles: 'uncle', uncles: 'uncle',
}; };
const TAB_TO_QUERY: Record<string, QueryKeys.blocks | QueryKeys.blocksReorgs | QueryKeys.blocksUncles> = {
blocks: QueryKeys.blocks,
reorgs: QueryKeys.blocksReorgs,
uncles: QueryKeys.blocksUncles,
};
const TAB_LIST_PROPS = { const TAB_LIST_PROPS = {
marginBottom: 0, marginBottom: 0,
py: 5, py: 5,
...@@ -35,11 +28,9 @@ const BlocksPageContent = () => { ...@@ -35,11 +28,9 @@ const BlocksPageContent = () => {
const router = useRouter(); const router = useRouter();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const type = router.query.tab && !Array.isArray(router.query.tab) ? TAB_TO_TYPE[router.query.tab] : 'block'; const type = router.query.tab && !Array.isArray(router.query.tab) ? TAB_TO_TYPE[router.query.tab] : 'block';
const queryName = router.query.tab && !Array.isArray(router.query.tab) ? TAB_TO_QUERY[router.query.tab] : QueryKeys.blocks;
const blocksQuery = useQueryWithPages({ const blocksQuery = useQueryWithPages({
apiPath: '/node-api/blocks', resourceName: 'blocks',
queryName,
filters: { type }, filters: { type },
}); });
......
...@@ -18,6 +18,7 @@ import useTxsSort from './useTxsSort'; ...@@ -18,6 +18,7 @@ import useTxsSort from './useTxsSort';
type QueryResult = UseQueryResult<TxsResponse> & { type QueryResult = UseQueryResult<TxsResponse> & {
pagination: PaginationProps; pagination: PaginationProps;
isPaginationVisible: boolean;
}; };
type Props = { type Props = {
...@@ -31,7 +32,6 @@ type Props = { ...@@ -31,7 +32,6 @@ type Props = {
const TxsContent = ({ filter, query, showBlockInfo = true, showSocketInfo = true, currentAddress, enableTimeIncrement }: Props) => { const TxsContent = ({ filter, query, showBlockInfo = true, showSocketInfo = true, currentAddress, enableTimeIncrement }: Props) => {
const { data, isLoading, isError, setSortByField, setSortByValue, sorting } = useTxsSort(query); const { data, isLoading, isError, setSortByField, setSortByValue, sorting } = useTxsSort(query);
const isPaginatorHidden = !isLoading && !isError && query.pagination.page === 1 && !query.pagination.hasNextPage;
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const content = (() => { const content = (() => {
...@@ -86,7 +86,7 @@ const TxsContent = ({ filter, query, showBlockInfo = true, showSocketInfo = true ...@@ -86,7 +86,7 @@ const TxsContent = ({ filter, query, showBlockInfo = true, showSocketInfo = true
sorting={ sorting } sorting={ sorting }
showBlockInfo={ showBlockInfo } showBlockInfo={ showBlockInfo }
showSocketInfo={ showSocketInfo } showSocketInfo={ showSocketInfo }
top={ isPaginatorHidden ? 0 : 80 } top={ query.isPaginationVisible ? 80 : 0 }
currentAddress={ currentAddress } currentAddress={ currentAddress }
enableTimeIncrement={ enableTimeIncrement } enableTimeIncrement={ enableTimeIncrement }
/> />
...@@ -103,7 +103,7 @@ const TxsContent = ({ filter, query, showBlockInfo = true, showSocketInfo = true ...@@ -103,7 +103,7 @@ const TxsContent = ({ filter, query, showBlockInfo = true, showSocketInfo = true
sorting={ sorting } sorting={ sorting }
setSorting={ setSortByValue } setSorting={ setSortByValue }
paginationProps={ query.pagination } paginationProps={ query.pagination }
showPagination={ !isPaginatorHidden } showPagination={ query.isPaginationVisible }
filterComponent={ filter } filterComponent={ filter }
/> />
) } ) }
......
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