feat(#81): make market list table sortable and add filters (#1082)

This commit is contained in:
Bartłomiej Głownia 2022-08-30 15:28:58 +02:00 committed by GitHub
parent f250f1ce09
commit ebe3d36d3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 29 deletions

View File

@ -32,6 +32,8 @@ type MarketListTableValueFormatterParams = Omit<
data: MarketList_markets; data: MarketList_markets;
}; };
export const getRowId = ({ data }: { data: { id: string } }) => data.id;
export const MarketListTable = forwardRef<AgGridReact, Props>((props, ref) => { export const MarketListTable = forwardRef<AgGridReact, Props>((props, ref) => {
const { setAssetDetailsDialogOpen, setAssetDetailsDialogSymbol } = const { setAssetDetailsDialogOpen, setAssetDetailsDialogSymbol } =
useAssetDetailsDialogStore(); useAssetDetailsDialogStore();
@ -39,11 +41,13 @@ export const MarketListTable = forwardRef<AgGridReact, Props>((props, ref) => {
<AgGrid <AgGrid
style={{ width: '100%', height: '100%' }} style={{ width: '100%', height: '100%' }}
overlayNoRowsTemplate={t('No markets')} overlayNoRowsTemplate={t('No markets')}
getRowId={({ data }) => data?.id} getRowId={getRowId}
ref={ref} ref={ref}
defaultColDef={{ defaultColDef={{
flex: 1, flex: 1,
resizable: true, resizable: true,
sortable: true,
filter: true,
}} }}
suppressCellFocus={true} suppressCellFocus={true}
components={{ PriceFlashCell }} components={{ PriceFlashCell }}

View File

@ -1,21 +1,23 @@
import { useRef, useCallback, useMemo } from 'react'; import { useRef, useCallback, useMemo } from 'react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit'; 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 { useDataProvider } from '@vegaprotocol/react-helpers';
import type { AgGridReact } from 'ag-grid-react'; 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 { import type {
MarketList_markets, MarketList_markets,
MarketList_markets_data, MarketList_markets_data,
} from '../../__generated__/MarketList'; MarketDataSub_marketData,
} from '../../__generated__';
import { marketsDataProvider as dataProvider } from '../../markets-data-provider'; import { marketsDataProvider as dataProvider } from '../../markets-data-provider';
import { Interval, MarketState } from '@vegaprotocol/types'; import { Interval, MarketState } from '@vegaprotocol/types';
export const MarketsContainer = () => { export const MarketsContainer = () => {
const { push } = useRouter(); const { push } = useRouter();
const gridRef = useRef<AgGridReact | null>(null); const gridRef = useRef<AgGridReact | null>(null);
const dataRef = useRef<MarketList_markets[] | null>(null);
const yTimestamp = useMemo(() => { const yTimestamp = useMemo(() => {
const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600; const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
@ -26,37 +28,53 @@ export const MarketsContainer = () => {
[yTimestamp] [yTimestamp]
); );
const update = useCallback(({ data }: { data: MarketList_markets[] }) => { const update = useCallback(
({ delta }: { delta: MarketDataSub_marketData }) => {
const update: MarketList_markets[] = [];
const add: MarketList_markets[] = [];
const remove: MarketList_markets[] = [];
if (!gridRef.current?.api) { if (!gridRef.current?.api) {
return false; return false;
} }
dataRef.current = data; const rowNode = gridRef.current.api.getRowNode(
gridRef.current.api.refreshInfiniteCache(); getRowId({ data: delta.market })
);
if (rowNode) {
const updatedData = produce<MarketList_markets>(
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; return true;
}, []); },
[gridRef]
);
const { data, error, loading } = useDataProvider< const { data, error, loading } = useDataProvider<
MarketList_markets[], MarketList_markets[],
MarketList_markets_data MarketList_markets_data
>({ dataProvider, update, variables }); >({ 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 ( return (
<AsyncRenderer loading={loading} error={error} data={data}> <AsyncRenderer loading={loading} error={error} data={data}>
<MarketListTable <MarketListTable
rowModelType="infinite" rowData={
datasource={{ getRows }} data &&
data.filter(
(m) => m.data?.market.state !== MarketState.STATE_REJECTED
)
}
ref={gridRef} ref={gridRef}
onRowClicked={(rowEvent: RowClickedEvent) => { onRowClicked={(rowEvent: RowClickedEvent) => {
const { data, event } = rowEvent; const { data, event } = rowEvent;