From e41aff88b16a110d4b365129dd68976751b53e96 Mon Sep 17 00:00:00 2001 From: Matthew Russell Date: Sun, 3 Sep 2023 11:15:41 -0700 Subject: [PATCH] chore(trading): make top traded default sort for market selector (#4637) --- .../market-selector/market-selector.spec.tsx | 4 +- .../market-selector/market-selector.tsx | 13 ++-- .../market-selector/sort-dropdown.tsx | 46 ++++++------- .../use-market-selector-list.spec.tsx | 68 ++++++++++++------- .../use-market-selector-list.ts | 22 +----- 5 files changed, 70 insertions(+), 83 deletions(-) diff --git a/apps/trading/components/market-selector/market-selector.spec.tsx b/apps/trading/components/market-selector/market-selector.spec.tsx index faf20a8ff..f4cfadda6 100644 --- a/apps/trading/components/market-selector/market-selector.spec.tsx +++ b/apps/trading/components/market-selector/market-selector.spec.tsx @@ -262,9 +262,7 @@ describe('MarketSelector', () => { await userEvent.click(screen.getByTestId('sort-trigger')); const options = screen.getAllByTestId(/sort-item/); expect(options.map((o) => o.textContent?.trim())).toEqual( - Object.entries(Sort) - .filter(([key]) => key !== Sort.None) - .map(([key]) => SortTypeMapping[key as SortType]) + Object.entries(Sort).map(([key]) => SortTypeMapping[key as SortType]) ); await userEvent.click(screen.getByTestId('sort-item-Gained')); expect( diff --git a/apps/trading/components/market-selector/market-selector.tsx b/apps/trading/components/market-selector/market-selector.tsx index 7750ea33d..673eb43e1 100644 --- a/apps/trading/components/market-selector/market-selector.tsx +++ b/apps/trading/components/market-selector/market-selector.tsx @@ -40,7 +40,7 @@ export const MarketSelector = ({ const [filter, setFilter] = useState({ searchTerm: '', product: Product.All, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); const allProducts = filter.product === Product.All; @@ -53,7 +53,7 @@ export const MarketSelector = ({ return (
-
+
{ @@ -106,9 +106,6 @@ export const MarketSelector = ({ currentSort={filter.sort} onSelect={(sort) => { setFilter((curr) => { - if (curr.sort === sort) { - return { ...curr, sort: Sort.None }; - } return { ...curr, sort, @@ -294,9 +291,9 @@ const List = ({ const Skeleton = () => { return ( -
-
-
+
+
+
diff --git a/apps/trading/components/market-selector/sort-dropdown.tsx b/apps/trading/components/market-selector/sort-dropdown.tsx index 82e6382ea..285d6d566 100644 --- a/apps/trading/components/market-selector/sort-dropdown.tsx +++ b/apps/trading/components/market-selector/sort-dropdown.tsx @@ -1,4 +1,3 @@ -import { t } from '@vegaprotocol/i18n'; import { DropdownMenu, DropdownMenuContent, @@ -11,7 +10,6 @@ import { } from '@vegaprotocol/ui-toolkit'; export const Sort = { - None: 'None', Gained: 'Gained', Lost: 'Lost', New: 'New', @@ -23,17 +21,15 @@ export type SortType = keyof typeof Sort; export const SortTypeMapping: { [key in SortType]: string; } = { - [Sort.None]: 'None', + [Sort.TopTraded]: 'Top traded', [Sort.Gained]: 'Top gaining', [Sort.Lost]: 'Top losing', [Sort.New]: 'New markets', - [Sort.TopTraded]: 'Top traded', }; const SortIconMapping: { [key in SortType]: VegaIconNames; } = { - [Sort.None]: null as unknown as VegaIconNames, // not shown in list [Sort.Gained]: VegaIconNames.TREND_UP, [Sort.Lost]: VegaIconNames.TREND_DOWN, [Sort.New]: VegaIconNames.STAR, @@ -51,10 +47,8 @@ export const SortDropdown = ({ - - {currentSort === SortTypeMapping.None - ? t('Sort') - : SortTypeMapping[currentSort]}{' '} + + {SortTypeMapping[currentSort]} @@ -65,24 +59,22 @@ export const SortDropdown = ({ value={currentSort} onValueChange={(value) => onSelect(value as SortType)} > - {Object.keys(Sort) - .filter((s) => s !== Sort.None) - .map((key) => { - return ( - - - {' '} - {SortTypeMapping[key as SortType]} - - - - ); - })} + {Object.keys(Sort).map((key) => { + return ( + + + {' '} + {SortTypeMapping[key as SortType]} + + + + ); + })} diff --git a/apps/trading/components/market-selector/use-market-selector-list.spec.tsx b/apps/trading/components/market-selector/use-market-selector-list.spec.tsx index 0741aa889..5297dafc4 100644 --- a/apps/trading/components/market-selector/use-market-selector-list.spec.tsx +++ b/apps/trading/components/market-selector/use-market-selector-list.spec.tsx @@ -12,7 +12,10 @@ import { useMarketList } from '@vegaprotocol/markets'; import type { Filter } from '../../components/market-selector'; import { subDays } from 'date-fns'; -jest.mock('@vegaprotocol/markets'); +jest.mock('@vegaprotocol/markets', () => ({ + ...jest.requireActual('@vegaprotocol/markets'), + useMarketList: jest.fn(), +})); const mockUseMarketList = useMarketList as jest.Mock; describe('useMarketSelectorList', () => { @@ -20,7 +23,7 @@ describe('useMarketSelectorList', () => { const defaultArgs: Filter = { searchTerm: '', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }; return renderHook((args) => useMarketSelectorList(args), { @@ -109,21 +112,21 @@ describe('useMarketSelectorList', () => { rerender({ searchTerm: '', product: Product.Spot as 'Future', - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); expect(result.current.markets).toEqual([markets[1]]); rerender({ searchTerm: '', product: Product.Perpetual as 'Future', - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); expect(result.current.markets).toEqual([markets[2]]); rerender({ searchTerm: '', product: Product.All, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); expect(result.current.markets).toEqual(markets); @@ -189,7 +192,7 @@ describe('useMarketSelectorList', () => { const { result, rerender } = setup({ searchTerm: '', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: ['asset-0'], }); expect(result.current.markets).toEqual([markets[0], markets[1]]); @@ -197,7 +200,7 @@ describe('useMarketSelectorList', () => { rerender({ searchTerm: '', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: ['asset-0', 'asset-1'], }); @@ -210,7 +213,7 @@ describe('useMarketSelectorList', () => { rerender({ searchTerm: '', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: ['asset-0', 'asset-1', 'asset-2'], }); @@ -220,7 +223,7 @@ describe('useMarketSelectorList', () => { rerender({ searchTerm: '', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: ['asset-invalid'], }); @@ -275,28 +278,28 @@ describe('useMarketSelectorList', () => { const { result, rerender } = setup({ searchTerm: 'abc', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); expect(result.current.markets).toEqual([markets[0]]); rerender({ searchTerm: 'def', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); expect(result.current.markets).toEqual([markets[1], markets[2]]); rerender({ searchTerm: 'defg', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); expect(result.current.markets).toEqual([markets[2]]); rerender({ searchTerm: 'zzz', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); expect(result.current.markets).toEqual([]); @@ -305,14 +308,14 @@ describe('useMarketSelectorList', () => { rerender({ searchTerm: 'aaa', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); expect(result.current.markets).toEqual([markets[0]]); rerender({ searchTerm: 'ggg', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); expect(result.current.markets).toEqual([ @@ -322,11 +325,15 @@ describe('useMarketSelectorList', () => { ]); }); - it('sorts by state and volume by default', () => { + it('sorts by top traded by default', () => { const markets = [ createMarketFragment({ id: 'market-0', - state: MarketState.STATE_PENDING, + state: MarketState.STATE_ACTIVE, + // @ts-ignore data not on fragment + data: { + markPrice: '1', + }, // @ts-ignore candles not on fragment candles: [ { @@ -337,30 +344,42 @@ describe('useMarketSelectorList', () => { createMarketFragment({ id: 'market-1', state: MarketState.STATE_ACTIVE, + // @ts-ignore data not on fragment + data: { + markPrice: '1', + }, // @ts-ignore candles not on fragment candles: [ { - volume: '200', + volume: '100', }, ], }), createMarketFragment({ id: 'market-2', state: MarketState.STATE_ACTIVE, + // @ts-ignore data not on fragment + data: { + markPrice: '1', + }, // @ts-ignore candles not on fragment candles: [ { - volume: '100', + volume: '300', }, ], }), createMarketFragment({ - state: MarketState.STATE_PENDING, id: 'market-3', + state: MarketState.STATE_ACTIVE, + // @ts-ignore data not on fragment + data: { + markPrice: '1', + }, // @ts-ignore candles not on fragment candles: [ { - volume: '100', + volume: '400', }, ], }), @@ -375,14 +394,15 @@ describe('useMarketSelectorList', () => { const { result } = setup({ searchTerm: '', product: Product.Future, - sort: Sort.None, + sort: Sort.TopTraded, assets: [], }); + expect(result.current.markets).toEqual([ - markets[1], + markets[3], markets[2], markets[0], - markets[3], + markets[1], ]); }); diff --git a/apps/trading/components/market-selector/use-market-selector-list.ts b/apps/trading/components/market-selector/use-market-selector-list.ts index 72bef8f54..47f68e4c8 100644 --- a/apps/trading/components/market-selector/use-market-selector-list.ts +++ b/apps/trading/components/market-selector/use-market-selector-list.ts @@ -1,11 +1,7 @@ import { useMemo } from 'react'; import orderBy from 'lodash/orderBy'; import { MarketState } from '@vegaprotocol/types'; -import { - calcCandleVolume, - calcTradedFactor, - useMarketList, -} from '@vegaprotocol/markets'; +import { calcTradedFactor, useMarketList } from '@vegaprotocol/markets'; import { priceChangePercentage } from '@vegaprotocol/utils'; import type { Filter } from '../../components/market-selector/market-selector'; import { Sort } from './sort-dropdown'; @@ -60,22 +56,6 @@ export const useMarketSelectorList = ({ return false; }); - if (sort === Sort.None) { - // Sort by market state primarily and AtoZ secondarily - return orderBy( - markets, - [ - (m) => MARKET_TEMPLATE.indexOf(m.state), - (m) => { - if (!m.candles?.length) return 0; - const vol = calcCandleVolume(m.candles); - return Number(vol || 0); - }, - ], - ['asc', 'desc'] - ); - } - if (sort === Sort.Gained || sort === Sort.Lost) { const dir = sort === Sort.Gained ? 'desc' : 'asc'; return orderBy(