From b7ebc7ce12af0bebcbd35150b2345d06df96e728 Mon Sep 17 00:00:00 2001 From: Edd Date: Wed, 14 Jun 2023 15:24:38 +0100 Subject: [PATCH] chore: make filter its own component --- .../src/app/components/txs/tx-filter.tsx | 181 ++++++++++++++++++ .../components/txs/txs-infinite-list.spec.tsx | 6 - .../app/components/txs/txs-infinite-list.tsx | 8 +- .../src/app/routes/parties/id/index.tsx | 1 - .../src/app/routes/txs/home/index.tsx | 165 +--------------- 5 files changed, 187 insertions(+), 174 deletions(-) create mode 100644 apps/explorer/src/app/components/txs/tx-filter.tsx diff --git a/apps/explorer/src/app/components/txs/tx-filter.tsx b/apps/explorer/src/app/components/txs/tx-filter.tsx new file mode 100644 index 000000000..f9c12d932 --- /dev/null +++ b/apps/explorer/src/app/components/txs/tx-filter.tsx @@ -0,0 +1,181 @@ +import { t } from '@vegaprotocol/i18n'; +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuItemIndicator, + DropdownMenuSeparator, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuTrigger, + Icon, + DropdownMenuSubContent, +} from '@vegaprotocol/ui-toolkit'; +import classNames from 'classnames'; +import type { Dispatch, SetStateAction } from 'react'; + +// All possible transaction types. Should be generated. +export type FilterOption = + | 'Amend LiquidityProvision Order' + | 'Amend Order' + | 'Batch Market Instructions' + | 'Cancel LiquidityProvision Order' + | 'Cancel Order' + | 'Cancel Transfer Funds' + | 'Chain Event' + | 'Delegate' + | 'Ethereum Key Rotate Submission' + | 'Issue Signatures' + | 'Key Rotate Submission' + | 'Liquidity Provision Order' + | 'Node Signature' + | 'Node Vote' + | 'Proposal' + | 'Protocol Upgrade' + | 'Register new Node' + | 'State Variable Proposal' + | 'Submit Oracle Data' + | 'Submit Order' + | 'Transfer Funds' + | 'Undelegate' + | 'Validator Heartbeat' + | 'Vote on Proposal' + | 'Withdraw'; + +// Alphabetised list of transaction types to appear at the top level +export const PrimaryFilterOptions: FilterOption[] = [ + 'Amend LiquidityProvision Order', + 'Amend Order', + 'Batch Market Instructions', + 'Cancel LiquidityProvision Order', + 'Cancel Order', + 'Cancel Transfer Funds', + 'Delegate', + 'Liquidity Provision Order', + 'Proposal', + 'Submit Oracle Data', + 'Submit Order', + 'Transfer Funds', + 'Undelegate', + 'Vote on Proposal', + 'Withdraw', +]; + +// Alphabetised list of transaction types to nest under a 'More...' submenu +export const SecondaryFilterOptions: FilterOption[] = [ + 'Chain Event', + 'Ethereum Key Rotate Submission', + 'Issue Signatures', + 'Key Rotate Submission', + 'Node Signature', + 'Node Vote', + 'Protocol Upgrade', + 'Register new Node', + 'State Variable Proposal', + 'Validator Heartbeat', +]; + +export const AllFilterOptions: FilterOption[] = [ + ...PrimaryFilterOptions, + ...SecondaryFilterOptions, +]; + +export function getFilterLabel(filters: Set) { + if (!filters || filters.size !== 1) { + return {t('Filter')}; + } + + return ( + + {t('Filters')}: {Array.from(filters)[0]} + + ); +} + +// Effectively a copy & paste of the Vega DropdownMenuItem styles +const itemClass = classNames( + 'relative flex gap-2 items-center rounded-sm p-2 text-sm', + 'cursor-default', + 'hover:bg-white dark:hover:bg-vega-dark-200', + 'focus:bg-white dark:focus:bg-vega-dark-200', + 'select-none', + 'whitespace-nowrap' +); + +export interface TxFilterProps { + filters: Set; + setFilters: Dispatch>>; +} + +/** + * Renders a structured dropdown menu of all of the available transaction + * types. It allows a user to select one transaction type to view. Later + * it will support multiple selection, but until the API supports that it is + * one or all. + * @param filters null or Set of tranaction types + * @param setFilters A function to update the filters prop + * @returns + */ +export const TxsFilter = ({ filters, setFilters }: TxFilterProps) => { + return ( + {getFilterLabel(filters)} + } + > + + {filters.size > 1 ? null : ( + <> + setFilters(new Set(AllFilterOptions))} + > + {t('Clear filters')} + + + + )} + {PrimaryFilterOptions.map((f) => ( + { + // NOTE: These act like radio buttons until the API supports multiple filters + setFilters(new Set([f])); + }} + id={`radio-${f}`} + > + {f} + + + + + ))} + + + {t('More Types')} + + + + {SecondaryFilterOptions.map((f) => ( + { + // NOTE: These act like radio buttons until the API supports multiple filters + setFilters(new Set([f])); + }} + id={`radio-${f}`} + > + {f} + + + + + ))} + + + + + ); +}; diff --git a/apps/explorer/src/app/components/txs/txs-infinite-list.spec.tsx b/apps/explorer/src/app/components/txs/txs-infinite-list.spec.tsx index cea2a9c76..c02b1a413 100644 --- a/apps/explorer/src/app/components/txs/txs-infinite-list.spec.tsx +++ b/apps/explorer/src/app/components/txs/txs-infinite-list.spec.tsx @@ -40,7 +40,6 @@ describe('Txs infinite list', () => { it('should display a "no items" message when no items provided', () => { render( { const txs = generateTxs(1); render( { render( { render( { render( { render( { }; export const TxsInfiniteList = ({ - filters, hasMoreTxs, areTxsLoading, txs, @@ -75,15 +73,13 @@ export const TxsInfiniteList = ({ const hasMountedRef = useRef(false); useEffect(() => { - // We only need to reset cached items when "sortOrder" changes. - // This effect will run on mount too; there's no need to reset in that case. if (hasMountedRef.current) { if (infiniteLoaderRef.current) { infiniteLoaderRef.current.resetloadMoreItemsCache(true); } } hasMountedRef.current = true; - }, [filters]); + }, [loadMoreTxs]); if (!txs) { if (!areTxsLoading) { @@ -98,8 +94,6 @@ export const TxsInfiniteList = ({ } } - console.dir(txs); - // If there are more items to be loaded then add an extra row to hold a loading indicator. const itemCount = hasMoreTxs ? txs.length + 1 : txs.length; diff --git a/apps/explorer/src/app/routes/parties/id/index.tsx b/apps/explorer/src/app/routes/parties/id/index.tsx index cf2015119..9f2b1e638 100644 --- a/apps/explorer/src/app/routes/parties/id/index.tsx +++ b/apps/explorer/src/app/routes/parties/id/index.tsx @@ -83,7 +83,6 @@ const Party = () => { {t('Transactions')} {!error && txsData ? ( ) { - if (!filters || filters.size !== 1) { - return Filter; - } - - return ( - - Filters: {Array.from(filters)[0]} - - ); -} - export const TxsList = () => { useDocumentTitle(['Transactions']); @@ -123,6 +28,7 @@ export const TxsListFiltered = () => { filters && filters.size === 1 ? `filters[cmd.type]=${Array.from(filters)[0]}` : ''; + const { hasMoreTxs, loadTxs, error, txsData, refreshTxs, loading } = useTxsData({ limit: BE_TXS_PER_REQUEST, @@ -133,71 +39,10 @@ export const TxsListFiltered = () => { <> - - {getFilterLabel(filters)} - } - > - - {filters.size > 1 ? null : ( - <> - - setFilters(new Set(AllFilterOptions)) - } - > - Clear filters - - - - )} - {PrimaryFilterOptions.map((f) => ( - { - // NOTE: These act like radio buttons until the API supports multiple filters - setFilters(new Set([f])); - }} - id={`radio-${f}`} - > - {f} - - - - - ))} - - - More Types - - - - {SecondaryFilterOptions.map((f) => ( - { - // NOTE: These act like radio buttons until the API supports multiple filters - setFilters(new Set([f])); - }} - id={`radio-${f}`} - > - {f} - - - - - ))} - - - - + +