chore(orders): use columnDefs in orders list, fix sorting by size and filled (#4170)

This commit is contained in:
Bartłomiej Głownia 2023-06-24 00:33:25 +02:00 committed by GitHub
parent 2c2bc391e8
commit 005455c870
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,14 +2,13 @@ import {
addDecimalsFormatNumber, addDecimalsFormatNumber,
getDateTimeFormat, getDateTimeFormat,
isNumeric, isNumeric,
toBigNum,
} from '@vegaprotocol/utils'; } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n'; import { t } from '@vegaprotocol/i18n';
import * as Schema from '@vegaprotocol/types'; import * as Schema from '@vegaprotocol/types';
import { ButtonLink } from '@vegaprotocol/ui-toolkit'; import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import { AgGridColumn } from 'ag-grid-react';
import BigNumber from 'bignumber.js';
import type { ForwardedRef } from 'react'; import type { ForwardedRef } from 'react';
import { memo, forwardRef } from 'react'; import { memo, forwardRef, useMemo } from 'react';
import { import {
AgGridLazy as AgGrid, AgGridLazy as AgGrid,
SetFilter, SetFilter,
@ -24,11 +23,13 @@ import type {
TypedDataAgGrid, TypedDataAgGrid,
VegaICellRendererParams, VegaICellRendererParams,
VegaValueFormatterParams, VegaValueFormatterParams,
VegaValueGetterParams,
} from '@vegaprotocol/datagrid'; } from '@vegaprotocol/datagrid';
import type { AgGridReact } from 'ag-grid-react'; import type { AgGridReact } from 'ag-grid-react';
import type { Order } from '../order-data-provider'; import type { Order } from '../order-data-provider';
import { OrderActionsDropdown } from '../order-actions-dropdown'; import { OrderActionsDropdown } from '../order-actions-dropdown';
import { Filter } from '../order-list-manager'; import { Filter } from '../order-list-manager';
import type { ColDef } from 'ag-grid-community';
export type OrderListTableProps = TypedDataAgGrid<Order> & { export type OrderListTableProps = TypedDataAgGrid<Order> & {
marketId?: string; marketId?: string;
@ -54,49 +55,40 @@ export const OrderListTable = memo<
: filter === undefined || filter === Filter.Open : filter === undefined || filter === Filter.Open
? true ? true
: false; : false;
const columnDefs: ColDef[] = useMemo(
return ( () => [
<AgGrid {
ref={ref} headerName: t('Market'),
defaultColDef={{ field: 'market.tradableInstrument.instrument.code',
resizable: true, cellRenderer: 'MarketNameCell',
sortable: true, cellRendererParams: { idPath: 'market.id', onMarketClick },
filterParams: { buttons: ['reset'] }, minWidth: 150,
}} },
style={{ {
width: '100%', headerName: t('Size'),
height: '100%', field: 'size',
}} cellClass: 'font-mono text-right',
getRowId={({ data }) => data.id} type: 'rightAligned',
components={{ MarketNameCell, OrderTypeCell }} cellClassRules: {
{...props}
>
<AgGridColumn
headerName={t('Market')}
field="market.tradableInstrument.instrument.code"
cellRenderer="MarketNameCell"
cellRendererParams={{ idPath: 'market.id', onMarketClick }}
minWidth={150}
/>
<AgGridColumn
headerName={t('Size')}
field="size"
cellClass="font-mono text-right"
type="rightAligned"
cellClassRules={{
[positiveClassNames]: ({ data }: { data: Order }) => [positiveClassNames]: ({ data }: { data: Order }) =>
data?.side === Schema.Side.SIDE_BUY, data?.side === Schema.Side.SIDE_BUY,
[negativeClassNames]: ({ data }: { data: Order }) => [negativeClassNames]: ({ data }: { data: Order }) =>
data?.side === Schema.Side.SIDE_SELL, data?.side === Schema.Side.SIDE_SELL,
}} },
valueFormatter={({ valueGetter: ({ data }: VegaValueGetterParams<Order>) => {
value, return data?.size && data.market
? toBigNum(data.size, data.market.positionDecimalPlaces ?? 0)
.multipliedBy(data.side === Schema.Side.SIDE_SELL ? -1 : 1)
.toNumber()
: undefined;
},
valueFormatter: ({
data, data,
}: VegaValueFormatterParams<Order, 'size'>) => { }: VegaValueFormatterParams<Order, 'size'>) => {
if (!data) { if (!data) {
return undefined; return '';
} }
if (!data?.market || !isNumeric(value)) { if (!data?.market || !isNumeric(data.size)) {
return '-'; return '-';
} }
const prefix = data const prefix = data
@ -107,33 +99,33 @@ export const OrderListTable = memo<
return ( return (
prefix + prefix +
addDecimalsFormatNumber( addDecimalsFormatNumber(
value, data.size,
data.market.positionDecimalPlaces data.market.positionDecimalPlaces
) )
); );
}} },
minWidth={80} minWidth: 80,
/> },
<AgGridColumn {
field="type" field: 'type',
filter={SetFilter} filter: SetFilter,
filterParams={{ filterParams: {
set: Schema.OrderTypeMapping, set: Schema.OrderTypeMapping,
}} },
cellRenderer="OrderTypeCell" cellRenderer: 'OrderTypeCell',
cellRendererParams={{ cellRendererParams: {
onClick: onOrderTypeClick, onClick: onOrderTypeClick,
}} },
minWidth={80} minWidth: 80,
/> },
<AgGridColumn {
field="status" field: 'status',
filter={SetFilter} filter: SetFilter,
filterParams={{ filterParams: {
set: Schema.OrderStatusMapping, set: Schema.OrderStatusMapping,
readonly: filter !== undefined, readonly: filter !== undefined,
}} },
valueFormatter={({ valueFormatter: ({
value, value,
data, data,
}: VegaValueFormatterParams<Order, 'status'>) => { }: VegaValueFormatterParams<Order, 'status'>) => {
@ -145,8 +137,8 @@ export const OrderListTable = memo<
}`; }`;
} }
return value ? Schema.OrderStatusMapping[value] : ''; return value ? Schema.OrderStatusMapping[value] : '';
}} },
cellRenderer={({ cellRenderer: ({
valueFormatted, valueFormatted,
data, data,
}: { }: {
@ -156,45 +148,51 @@ export const OrderListTable = memo<
<span data-testid={`order-status-${data?.id}`}> <span data-testid={`order-status-${data?.id}`}>
{valueFormatted} {valueFormatted}
</span> </span>
)} ),
minWidth={100} minWidth: 100,
/> },
<AgGridColumn {
headerName={t('Filled')} headerName: t('Filled'),
field="remaining" field: 'remaining',
cellClass="font-mono text-right" cellClass: 'font-mono text-right',
type="rightAligned" type: 'rightAligned',
valueFormatter={({ valueGetter: ({ data }: VegaValueGetterParams<Order>) => {
return data?.size && data.market
? toBigNum(
(BigInt(data.size) - BigInt(data.remaining)).toString(),
data.market.positionDecimalPlaces ?? 0
).toNumber()
: undefined;
},
valueFormatter: ({
data, data,
value, value,
}: VegaValueFormatterParams<Order, 'remaining'>) => { }: VegaValueFormatterParams<Order, 'remaining'>): string => {
if (!data) { if (!data) {
return undefined; return '';
} }
if (!data?.market || !isNumeric(value) || !isNumeric(data.size)) { if (!data?.market || !isNumeric(value) || !isNumeric(data.size)) {
return '-'; return '-';
} }
const dps = data.market.positionDecimalPlaces; const { positionDecimalPlaces } = data.market;
const size = new BigNumber(data.size); const filled = BigInt(data.size) - BigInt(data.remaining);
const remaining = new BigNumber(value);
const fills = size.minus(remaining);
return `${addDecimalsFormatNumber( return `${addDecimalsFormatNumber(
fills.toString(), filled.toString(),
dps positionDecimalPlaces
)}/${addDecimalsFormatNumber(size.toString(), dps)}`; )}/${addDecimalsFormatNumber(data.size, positionDecimalPlaces)}`;
}} },
minWidth={100} minWidth: 100,
/> },
<AgGridColumn {
field="price" field: 'price',
type="rightAligned" type: 'rightAligned',
cellClass="font-mono text-right" cellClass: 'font-mono text-right',
valueFormatter={({ valueFormatter: ({
value, value,
data, data,
}: VegaValueFormatterParams<Order, 'price'>) => { }: VegaValueFormatterParams<Order, 'price'>) => {
if (!data) { if (!data) {
return undefined; return '';
} }
if ( if (
!data?.market || !data?.market ||
@ -204,16 +202,16 @@ export const OrderListTable = memo<
return '-'; return '-';
} }
return addDecimalsFormatNumber(value, data.market.decimalPlaces); return addDecimalsFormatNumber(value, data.market.decimalPlaces);
}} },
minWidth={100} minWidth: 100,
/> },
<AgGridColumn {
field="timeInForce" field: 'timeInForce',
filter={SetFilter} filter: SetFilter,
filterParams={{ filterParams: {
set: Schema.OrderTimeInForceMapping, set: Schema.OrderTimeInForceMapping,
}} },
valueFormatter={({ valueFormatter: ({
value, value,
data, data,
}: VegaValueFormatterParams<Order, 'timeInForce'>) => { }: VegaValueFormatterParams<Order, 'timeInForce'>) => {
@ -235,13 +233,13 @@ export const OrderListTable = memo<
}${data?.reduceOnly ? t('. Reduce only') : ''}`; }${data?.reduceOnly ? t('. Reduce only') : ''}`;
return label; return label;
}} },
minWidth={150} minWidth: 150,
/> },
<AgGridColumn {
field="createdAt" field: 'createdAt',
filter={DateRangeFilter} filter: DateRangeFilter,
cellRenderer={({ cellRenderer: ({
value, value,
}: VegaICellRendererParams<Order, 'createdAt'>) => { }: VegaICellRendererParams<Order, 'createdAt'>) => {
return ( return (
@ -249,12 +247,12 @@ export const OrderListTable = memo<
{value ? getDateTimeFormat().format(new Date(value)) : value} {value ? getDateTimeFormat().format(new Date(value)) : value}
</span> </span>
); );
}} },
minWidth={150} minWidth: 150,
/> },
<AgGridColumn {
field="updatedAt" field: 'updatedAt',
cellRenderer={({ cellRenderer: ({
data, data,
value, value,
}: VegaICellRendererParams<Order, 'updatedAt'>) => { }: VegaICellRendererParams<Order, 'updatedAt'>) => {
@ -266,15 +264,15 @@ export const OrderListTable = memo<
{value ? getDateTimeFormat().format(new Date(value)) : '-'} {value ? getDateTimeFormat().format(new Date(value)) : '-'}
</span> </span>
); );
}} },
minWidth={150} minWidth: 150,
/> },
<AgGridColumn {
colId="amend" colId: 'amend',
{...COL_DEFS.actions} ...COL_DEFS.actions,
minWidth={showAllActions ? 120 : COL_DEFS.actions.minWidth} minWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth,
maxWidth={showAllActions ? 120 : COL_DEFS.actions.minWidth} maxWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth,
cellRenderer={({ data }: { data?: Order }) => { cellRenderer: ({ data }: { data?: Order }) => {
if (!data) return null; if (!data) return null;
return ( return (
@ -298,9 +296,37 @@ export const OrderListTable = memo<
<OrderActionsDropdown id={data?.id} /> <OrderActionsDropdown id={data?.id} />
</div> </div>
); );
}} },
/> },
</AgGrid> ],
[
filter,
onCancel,
onEdit,
onMarketClick,
onOrderTypeClick,
props.isReadOnly,
showAllActions,
]
);
return (
<AgGrid
ref={ref}
defaultColDef={{
resizable: true,
sortable: true,
filterParams: { buttons: ['reset'] },
}}
columnDefs={columnDefs}
style={{
width: '100%',
height: '100%',
}}
getRowId={({ data }) => data.id}
components={{ MarketNameCell, OrderTypeCell }}
{...props}
/>
); );
} }
) )