Commit 7faddf76 authored by tom's avatar tom

refactor txs sort

parent 3de29111
import type { TransactionsResponse } from 'types/api/transaction'; import type { Transaction } from 'types/api/transaction';
import type { Sort } from 'types/client/txs-sort'; import type { Sort } from 'types/client/txs-sort';
import compareBns from 'lib/bigint/compareBns'; import compareBns from 'lib/bigint/compareBns';
export default function sortTxs(txs: TransactionsResponse['items'], sorting?: Sort) { const sortTxs = (sorting?: Sort) => (tx1: Transaction, tx2: Transaction) => {
let sortedTxs;
switch (sorting) { switch (sorting) {
case 'val-desc': case 'val-desc':
sortedTxs = [ ...txs ].sort((tx1, tx2) => compareBns(tx1.value, tx2.value)); return compareBns(tx1.value, tx2.value);
break;
case 'val-asc': case 'val-asc':
sortedTxs = [ ...txs ].sort((tx1, tx2) => compareBns(tx2.value, tx1.value)); return compareBns(tx2.value, tx1.value);
break;
case 'fee-desc': case 'fee-desc':
sortedTxs = [ ...txs ].sort((tx1, tx2) => compareBns(tx1.fee.value, tx2.fee.value)); return compareBns(tx1.fee.value, tx2.fee.value);
break;
case 'fee-asc': case 'fee-asc':
sortedTxs = [ ...txs ].sort((tx1, tx2) => compareBns(tx2.fee.value, tx1.fee.value)); return compareBns(tx2.fee.value, tx1.fee.value);
break;
default: default:
sortedTxs = txs; return 0;
} }
};
return sortedTxs; export default sortTxs;
}
import { Text, Box, Show, Hide } from '@chakra-ui/react'; import { Text, Box, Show, Hide } from '@chakra-ui/react';
import React, { useState, useCallback } from 'react'; import React from 'react';
import type { TTxsFilters } from 'types/api/txsFilters'; import type { TTxsFilters } from 'types/api/txsFilters';
import type { QueryKeys } from 'types/client/queries'; import type { QueryKeys } from 'types/client/queries';
import type { Sort } from 'types/client/txs-sort';
import * as cookies from 'lib/cookies';
import useQueryWithPages from 'lib/hooks/useQueryWithPages'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import TxsHeader from './TxsHeader'; import TxsHeader from './TxsHeader';
import TxsListItem from './TxsListItem';
import TxsSkeletonDesktop from './TxsSkeletonDesktop'; import TxsSkeletonDesktop from './TxsSkeletonDesktop';
import TxsSkeletonMobile from './TxsSkeletonMobile'; import TxsSkeletonMobile from './TxsSkeletonMobile';
import TxsWithSort from './TxsWithSort'; import TxsTable from './TxsTable';
import useTxsSort from './useTxsSort';
type Props = { type Props = {
queryName: QueryKeys.txsPending | QueryKeys.txsValidate | QueryKeys.blockTxs; queryName: QueryKeys.txsPending | QueryKeys.txsValidate | QueryKeys.blockTxs;
...@@ -27,66 +27,41 @@ const TxsContent = ({ ...@@ -27,66 +27,41 @@ const TxsContent = ({
stateFilter, stateFilter,
apiPath, apiPath,
}: Props) => { }: Props) => {
const [ sorting, setSorting ] = useState<Sort>(cookies.get(cookies.NAMES.TXS_SORT) as Sort || '');
// const [ filters, setFilters ] = useState<Partial<TTxsFilters>>({ type: [], method: [] });
const sort = useCallback((field: 'val' | 'fee') => () => {
setSorting((prevVal) => {
let newVal: Sort = '';
if (field === 'val') {
if (prevVal === 'val-asc') {
newVal = '';
} else if (prevVal === 'val-desc') {
newVal = 'val-asc';
} else {
newVal = 'val-desc';
}
}
if (field === 'fee') {
if (prevVal === 'fee-asc') {
newVal = '';
} else if (prevVal === 'fee-desc') {
newVal = 'fee-asc';
} else {
newVal = 'fee-desc';
}
}
cookies.set(cookies.NAMES.TXS_SORT, newVal);
return newVal;
});
}, [ ]);
const { const {
data,
isLoading,
isError,
pagination, pagination,
...queryResult
} = useQueryWithPages({ } = useQueryWithPages({
apiPath, apiPath,
queryName, queryName,
filters: stateFilter ? { filter: stateFilter } : undefined, filters: stateFilter ? { filter: stateFilter } : undefined,
}); });
// } = useQueryWithPages({ ...filters, filter: stateFilter, apiPath }); // } = useQueryWithPages({ ...filters, filter: stateFilter, apiPath });
const { data, isLoading, isError, setSortByField, setSortByValue, sorting } = useTxsSort(queryResult);
const content = (() => { const content = (() => {
if (isError) { if (isError) {
return <DataFetchAlert/>; return <DataFetchAlert/>;
} }
const txs = data?.items; if (isLoading) {
return (
if (!isLoading && !txs?.length) { <>
return <Text as="span">There are no transactions.</Text>; <Show below="lg" ssr={ false }><TxsSkeletonMobile/></Show>
<Hide below="lg" ssr={ false }><TxsSkeletonDesktop/></Hide>
</>
);
} }
if (!isLoading && txs) { const txs = data.items;
return <TxsWithSort txs={ txs } sorting={ sorting } sort={ sort }/>;
if (!txs.length) {
return <Text as="span">There are no transactions.</Text>;
} }
return ( return (
<> <>
<Show below="lg" ssr={ false }><TxsSkeletonMobile/></Show> <Show below="lg" ssr={ false }><Box>{ txs.map(tx => <TxsListItem tx={ tx } key={ tx.hash }/>) }</Box></Show>
<Hide below="lg" ssr={ false }><TxsSkeletonDesktop/></Hide> <Hide below="lg" ssr={ false }><TxsTable txs={ txs } sort={ setSortByField } sorting={ sorting }/></Hide>
</> </>
); );
})(); })();
...@@ -94,7 +69,7 @@ const TxsContent = ({ ...@@ -94,7 +69,7 @@ const TxsContent = ({
return ( return (
<> <>
{ showDescription && <Box mb={{ base: 6, lg: 12 }}>Only the first 10,000 elements are displayed</Box> } { showDescription && <Box mb={{ base: 6, lg: 12 }}>Only the first 10,000 elements are displayed</Box> }
<TxsHeader mt={ -6 } sorting={ sorting } setSorting={ setSorting } paginationProps={ pagination }/> <TxsHeader mt={ -6 } sorting={ sorting } setSorting={ setSortByValue } paginationProps={ pagination }/>
{ content } { content }
</> </>
); );
......
...@@ -14,7 +14,7 @@ import TxsSorting from 'ui/txs/TxsSorting'; ...@@ -14,7 +14,7 @@ import TxsSorting from 'ui/txs/TxsSorting';
type Props = { type Props = {
sorting: Sort; sorting: Sort;
setSorting: (val: Sort | ((val: Sort) => Sort)) => void; setSorting: (val: Sort) => void;
paginationProps: PaginationProps; paginationProps: PaginationProps;
className?: string; className?: string;
} }
......
...@@ -11,13 +11,12 @@ import React from 'react'; ...@@ -11,13 +11,12 @@ import React from 'react';
import type { Sort } from 'types/client/txs-sort'; import type { Sort } from 'types/client/txs-sort';
import * as cookies from 'lib/cookies';
import SortButton from 'ui/shared/SortButton'; import SortButton from 'ui/shared/SortButton';
interface Props { interface Props {
isActive: boolean; isActive: boolean;
sorting: Sort; sorting: Sort;
setSorting: (val: Sort | ((val: Sort) => Sort)) => void; setSorting: (val: Sort) => void;
} }
const SORT_OPTIONS = [ const SORT_OPTIONS = [
...@@ -32,14 +31,8 @@ const TxsSorting = ({ isActive, sorting, setSorting }: Props) => { ...@@ -32,14 +31,8 @@ const TxsSorting = ({ isActive, sorting, setSorting }: Props) => {
const { isOpen, onToggle } = useDisclosure(); const { isOpen, onToggle } = useDisclosure();
const setSortingFromMenu = React.useCallback((val: string | Array<string>) => { const setSortingFromMenu = React.useCallback((val: string | Array<string>) => {
setSorting((prevVal: Sort) => { const value = val as Sort | Array<Sort>;
let newVal: Sort = ''; setSorting(Array.isArray(value) ? value[0] : value);
if (val !== prevVal) {
newVal = val as Sort;
}
cookies.set(cookies.NAMES.TXS_SORT, newVal);
return newVal;
});
}, [ setSorting ]); }, [ setSorting ]);
return ( return (
......
import { Box, Show, Hide } from '@chakra-ui/react';
import React, { useEffect, useState } from 'react';
import type { TransactionsResponse } from 'types/api/transaction';
import type { Sort } from 'types/client/txs-sort';
import sortTxs from 'lib/tx/sortTxs';
import TxsListItem from './TxsListItem';
import TxsTable from './TxsTable';
type Props = {
txs: TransactionsResponse['items'];
sorting?: Sort;
sort: (field: 'val' | 'fee') => () => void;
}
const TxsWithSort = ({
txs,
sorting,
sort,
}: Props) => {
const [ sortedTxs, setSortedTxs ] = useState<TransactionsResponse['items']>(sortTxs(txs, sorting));
useEffect(() => {
setSortedTxs(sortTxs(txs, sorting));
}, [ sorting, txs ]);
return (
<>
<Show below="lg" ssr={ false }><Box>{ sortedTxs.map(tx => <TxsListItem tx={ tx } key={ tx.hash }/>) }</Box></Show>
<Hide below="lg" ssr={ false }><TxsTable txs={ sortedTxs } sort={ sort } sorting={ sorting }/></Hide>
</>
);
};
export default TxsWithSort;
import type { UseQueryResult } from '@tanstack/react-query';
import React from 'react';
import type { BlockTransactionsResponse } from 'types/api/block';
import type { TransactionsResponsePending, TransactionsResponseValidated } from 'types/api/transaction';
import type { Sort } from 'types/client/txs-sort';
import * as cookies from 'lib/cookies';
import sortTxs from 'lib/tx/sortTxs';
type TxsResponse = TransactionsResponseValidated | TransactionsResponsePending | BlockTransactionsResponse;
type HookResult = UseQueryResult<TxsResponse> & {
sorting: Sort;
setSortByField: (field: 'val' | 'fee') => () => void;
setSortByValue: (value: Sort) => void;
}
export default function useTxsSort(
queryResult: UseQueryResult<TxsResponse>,
): HookResult {
const [ sorting, setSorting ] = React.useState<Sort>(cookies.get(cookies.NAMES.TXS_SORT) as Sort);
const setSortByField = React.useCallback((field: 'val' | 'fee') => () => {
setSorting((prevVal) => {
let newVal: Sort = '';
if (field === 'val') {
if (prevVal === 'val-asc') {
newVal = '';
} else if (prevVal === 'val-desc') {
newVal = 'val-asc';
} else {
newVal = 'val-desc';
}
}
if (field === 'fee') {
if (prevVal === 'fee-asc') {
newVal = '';
} else if (prevVal === 'fee-desc') {
newVal = 'fee-asc';
} else {
newVal = 'fee-desc';
}
}
cookies.set(cookies.NAMES.TXS_SORT, newVal);
return newVal;
});
}, [ ]);
const setSortByValue = React.useCallback((value: Sort) => {
setSorting((prevVal: Sort) => {
let newVal: Sort = '';
if (value !== prevVal) {
newVal = value as Sort;
}
cookies.set(cookies.NAMES.TXS_SORT, newVal);
return newVal;
});
}, []);
return React.useMemo(() => {
if (queryResult.isError || queryResult.isLoading) {
return { ...queryResult, setSortByField, setSortByValue, sorting };
}
return {
...queryResult,
data: { ...queryResult.data, items: queryResult.data.items.slice().sort(sortTxs(sorting)) },
setSortByField,
setSortByValue,
sorting,
};
}, [ queryResult, setSortByField, setSortByValue, sorting ]);
}
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