From ebe3d36d3d1648a2efb68431f29a3f9ad31fc587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20G=C5=82ownia?= Date: Tue, 30 Aug 2022 15:28:58 +0200 Subject: [PATCH] feat(#81): make market list table sortable and add filters (#1082) --- .../markets-container/market-list-table.tsx | 6 +- .../markets-container/markets-container.tsx | 74 ++++++++++++------- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/libs/market-list/src/lib/components/markets-container/market-list-table.tsx b/libs/market-list/src/lib/components/markets-container/market-list-table.tsx index b5b03866a..4e5c0f5b6 100644 --- a/libs/market-list/src/lib/components/markets-container/market-list-table.tsx +++ b/libs/market-list/src/lib/components/markets-container/market-list-table.tsx @@ -32,6 +32,8 @@ type MarketListTableValueFormatterParams = Omit< data: MarketList_markets; }; +export const getRowId = ({ data }: { data: { id: string } }) => data.id; + export const MarketListTable = forwardRef((props, ref) => { const { setAssetDetailsDialogOpen, setAssetDetailsDialogSymbol } = useAssetDetailsDialogStore(); @@ -39,11 +41,13 @@ export const MarketListTable = forwardRef((props, ref) => { data?.id} + getRowId={getRowId} ref={ref} defaultColDef={{ flex: 1, resizable: true, + sortable: true, + filter: true, }} suppressCellFocus={true} components={{ PriceFlashCell }} diff --git a/libs/market-list/src/lib/components/markets-container/markets-container.tsx b/libs/market-list/src/lib/components/markets-container/markets-container.tsx index 1693bd957..173543131 100644 --- a/libs/market-list/src/lib/components/markets-container/markets-container.tsx +++ b/libs/market-list/src/lib/components/markets-container/markets-container.tsx @@ -1,21 +1,23 @@ import { useRef, useCallback, useMemo } from 'react'; import { useRouter } from 'next/router'; import { AsyncRenderer } from '@vegaprotocol/ui-toolkit'; -import { MarketListTable } from './market-list-table'; +import { MarketListTable, getRowId } from './market-list-table'; import { useDataProvider } from '@vegaprotocol/react-helpers'; import type { AgGridReact } from 'ag-grid-react'; -import type { IGetRowsParams, RowClickedEvent } from 'ag-grid-community'; +import type { RowClickedEvent } from 'ag-grid-community'; +import { produce } from 'immer'; +import merge from 'lodash/merge'; import type { MarketList_markets, MarketList_markets_data, -} from '../../__generated__/MarketList'; + MarketDataSub_marketData, +} from '../../__generated__'; import { marketsDataProvider as dataProvider } from '../../markets-data-provider'; import { Interval, MarketState } from '@vegaprotocol/types'; export const MarketsContainer = () => { const { push } = useRouter(); const gridRef = useRef(null); - const dataRef = useRef(null); const yTimestamp = useMemo(() => { const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600; @@ -26,37 +28,53 @@ export const MarketsContainer = () => { [yTimestamp] ); - const update = useCallback(({ data }: { data: MarketList_markets[] }) => { - if (!gridRef.current?.api) { - return false; - } - dataRef.current = data; - gridRef.current.api.refreshInfiniteCache(); - return true; - }, []); + const update = useCallback( + ({ delta }: { delta: MarketDataSub_marketData }) => { + const update: MarketList_markets[] = []; + const add: MarketList_markets[] = []; + const remove: MarketList_markets[] = []; + if (!gridRef.current?.api) { + return false; + } + const rowNode = gridRef.current.api.getRowNode( + getRowId({ data: delta.market }) + ); + if (rowNode) { + const updatedData = produce( + rowNode.data.data, + (draft: MarketList_markets) => merge(draft, delta) + ); + if (updatedData !== rowNode.data.data) { + update.push({ ...rowNode.data, data: updatedData }); + } + } + // @TODO - else add new market + if (update.length || add.length || remove.length) { + gridRef.current.api.applyTransactionAsync({ + update, + add, + addIndex: 0, + }); + } + return true; + }, + [gridRef] + ); + const { data, error, loading } = useDataProvider< MarketList_markets[], MarketList_markets_data >({ dataProvider, update, variables }); - dataRef.current = data; - const getRows = async ({ - successCallback, - startRow, - endRow, - }: IGetRowsParams) => { - const rowsThisBlock = dataRef.current - ? dataRef.current - .slice(startRow, endRow) - .filter((m) => m.data?.market.state !== MarketState.STATE_REJECTED) - : []; - const lastRow = dataRef.current?.length ?? -1; - successCallback(rowsThisBlock, lastRow); - }; + return ( m.data?.market.state !== MarketState.STATE_REJECTED + ) + } ref={gridRef} onRowClicked={(rowEvent: RowClickedEvent) => { const { data, event } = rowEvent;