feat(orders): reduce number of columns in orders table (#4238)

This commit is contained in:
Bartłomiej Głownia 2023-07-06 17:57:29 +02:00 committed by GitHub
parent 0665ac85db
commit e89b818e4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 161 deletions

View File

@ -16,7 +16,7 @@ const orderStatus = 'status';
const orderRemaining = 'remaining';
const orderPrice = 'price';
const orderTimeInForce = 'timeInForce';
const orderCreatedAt = 'createdAt';
const orderUpdatedAt = 'updatedAt';
const cancelOrderBtn = 'cancel';
const cancelAllOrdersBtn = 'cancelAll';
const editOrderBtn = 'edit';
@ -46,6 +46,10 @@ describe('orders list', { tags: '@smoke', testIsolation: true }, () => {
cy.wrap($symbol).invoke('text').should('not.be.empty');
});
cy.get(`[col-id='${orderRemaining}']`).each(($remaining) => {
cy.wrap($remaining).invoke('text').should('not.be.empty');
});
cy.get(`[col-id='${orderSize}']`).each(($size) => {
cy.wrap($size).invoke('text').should('not.be.empty');
});
@ -58,10 +62,6 @@ describe('orders list', { tags: '@smoke', testIsolation: true }, () => {
cy.wrap($status).invoke('text').should('not.be.empty');
});
cy.get(`[col-id='${orderRemaining}']`).each(($remaining) => {
cy.wrap($remaining).invoke('text').should('not.be.empty');
});
cy.get(`[col-id='${orderPrice}']`).each(($price) => {
cy.wrap($price).invoke('text').should('not.be.empty');
});
@ -70,7 +70,7 @@ describe('orders list', { tags: '@smoke', testIsolation: true }, () => {
cy.wrap($timeInForce).invoke('text').should('not.be.empty');
});
cy.get(`[col-id='${orderCreatedAt}']`).each(($dateTime) => {
cy.get(`[col-id='${orderUpdatedAt}']`).each(($dateTime) => {
cy.wrap($dateTime).invoke('text').should('not.be.empty');
});
});
@ -96,7 +96,8 @@ describe('orders list', { tags: '@smoke', testIsolation: true }, () => {
'have.text',
'Partially Filled'
);
cy.get(`[col-id='${orderRemaining}']`).should('have.text', '7/10');
cy.get(`[col-id='${orderRemaining}']`).should('have.text', '7');
cy.get(`[col-id='${orderSize}']`).should('have.text', '-10');
cy.getByTestId(cancelOrderBtn).should('not.exist');
cy.getByTestId(editOrderBtn).should('not.exist');
});
@ -219,7 +220,7 @@ describe('subscribe orders', { tags: '@smoke' }, () => {
cy.getByTestId(`order-status-${orderId}`)
.parentsUntil(`.ag-row`)
.siblings(`[col-id=${orderRemaining}]`)
.should('have.text', '4/5');
.should('have.text', '4');
});
it('must see a filled order', () => {
@ -267,7 +268,7 @@ describe('subscribe orders', { tags: '@smoke' }, () => {
status: Schema.OrderStatus.STATUS_ACTIVE,
});
cy.get(`[row-id=${orderId}]`)
.find('[col-id="size"]')
.find(`[col-id="${orderSize}"]`)
.should('have.text', '-15');
});
@ -281,7 +282,7 @@ describe('subscribe orders', { tags: '@smoke' }, () => {
status: Schema.OrderStatus.STATUS_ACTIVE,
});
cy.get(`[row-id=${orderId}]`)
.find('[col-id="size"]')
.find(`[col-id="${orderSize}"]`)
.should('have.text', '+5');
});
@ -364,7 +365,7 @@ describe('subscribe orders', { tags: '@smoke' }, () => {
});
cy.get(`[row-id=${orderId}]`)
.find(`[col-id='${orderTimeInForce}']`)
.should('have.text', "Good 'til Cancelled (GTC)");
.should('have.text', 'GTC');
});
it('for Active order when is part of a liquidity or peg shape, must not see an option to amend the individual order ', () => {

View File

@ -76,54 +76,4 @@ describe('order data provider', () => {
)?.length
).toEqual(5);
});
it('add only data matching date range filter', () => {
const data = [
{
id: '1',
createdAt: new Date('2022-01-29').toISOString(),
},
{
id: '2',
createdAt: new Date('2022-01-30').toISOString(),
},
] as OrderFieldsFragment[];
const delta = [
// this one should be ignored because it does not match date range
{
id: '0',
createdAt: new Date('2022-02-02').toISOString(),
},
// this one should be updated
{
id: '2',
updatedAt: new Date('2022-01-31').toISOString(),
createdAt: new Date('2022-01-30').toISOString(),
},
// this should be added
{
id: '4',
createdAt: new Date('2022-01-31').toISOString(),
},
] as OrderUpdateFieldsFragment[];
const updatedData = update(
data,
filterOrderUpdates(delta),
{
partyId: '0x123',
filter: {
dateRange: { end: new Date('2022-02-01').toISOString() },
},
},
mapOrderUpdateToOrder
);
expect(updatedData?.findIndex((node) => node.id === delta[0].id)).toEqual(
-1
);
expect(updatedData && updatedData[0].id).toEqual(delta[2].id);
expect(updatedData && updatedData[0].updatedAt).toEqual(delta[2].updatedAt);
expect(updatedData && updatedData[2].id).toEqual(delta[1].id);
expect(updatedData && updatedData[2].updatedAt).toEqual(delta[1].updatedAt);
});
});

View File

@ -39,13 +39,6 @@ const orderMatchFilters = (
return true;
}
if (
variables?.filter?.status &&
!(order.status && variables.filter.status.includes(order.status))
) {
return false;
}
if (
variables?.filter?.liveOnly &&
!(order.status && liveOnlyOrderStatuses.includes(order.status))
@ -53,34 +46,6 @@ const orderMatchFilters = (
return false;
}
if (
variables?.filter?.types &&
!(order.type && variables.filter.types.includes(order.type))
) {
return false;
}
if (
variables?.filter?.timeInForce &&
!variables.filter.timeInForce.includes(order.timeInForce)
) {
return false;
}
if (variables?.filter?.excludeLiquidity && order.liquidityProvisionId) {
return false;
}
if (
variables?.filter?.dateRange?.start &&
!(order.createdAt && variables.filter.dateRange.start < order.createdAt)
) {
return false;
}
if (
variables?.filter?.dateRange?.end &&
!(order.createdAt && variables.filter.dateRange.end > order.createdAt)
) {
return false;
}
return true;
};

View File

@ -50,13 +50,12 @@ describe('OrderListTable', () => {
});
const expectedHeaders = [
'Market',
'Filled',
'Size',
'Type',
'Status',
'Filled',
'Price',
'Time In Force',
'Created At',
'Updated At',
'', // no cell header for edit/cancel
];
@ -73,14 +72,13 @@ describe('OrderListTable', () => {
const cells = screen.getAllByRole('gridcell');
const expectedValues: string[] = [
marketOrder.market?.tradableInstrument.instrument.code || '',
'+0.10',
'0.05',
'0.10',
Schema.OrderTypeMapping[marketOrder.type as Schema.OrderType] || '',
Schema.OrderStatusMapping[marketOrder.status],
'5',
'-',
Schema.OrderTimeInForceMapping[marketOrder.timeInForce],
Schema.OrderTimeInForceCode[marketOrder.timeInForce],
getDateTimeFormat().format(new Date(marketOrder.createdAt)),
'-',
'Edit',
];
expectedValues.forEach((expectedValue, i) =>
@ -96,16 +94,15 @@ describe('OrderListTable', () => {
const expectedValues: string[] = [
limitOrder.market?.tradableInstrument.instrument.code || '',
'+0.10',
'0.05',
'0.10',
Schema.OrderTypeMapping[limitOrder.type || Schema.OrderType.TYPE_LIMIT],
Schema.OrderStatusMapping[limitOrder.status],
'5',
'-',
`${
Schema.OrderTimeInForceMapping[limitOrder.timeInForce]
Schema.OrderTimeInForceCode[limitOrder.timeInForce]
}: ${getDateTimeFormat().format(new Date(limitOrder.expiresAt ?? ''))}`,
getDateTimeFormat().format(new Date(limitOrder.createdAt)),
'-',
'Edit',
];
expectedValues.forEach((expectedValue, i) =>
@ -124,7 +121,7 @@ describe('OrderListTable', () => {
render(generateJsx({ rowData: [rejectedOrder] }));
});
const cells = screen.getAllByRole('gridcell');
expect(cells[3]).toHaveTextContent(
expect(cells[4]).toHaveTextContent(
`${Schema.OrderStatusMapping[rejectedOrder.status]}: ${
Schema.OrderRejectionReasonMapping[rejectedOrder.rejectionReason]
}`
@ -193,7 +190,7 @@ describe('OrderListTable', () => {
});
const amendCell = getAmendCell();
const typeCell = screen.getAllByRole('gridcell')[2];
const typeCell = screen.getAllByRole('gridcell')[3];
expect(typeCell).toHaveTextContent('Liquidity provision');
expect(amendCell.queryByTestId('edit')).not.toBeInTheDocument();
expect(amendCell.queryByTestId('cancel')).not.toBeInTheDocument();
@ -215,7 +212,7 @@ describe('OrderListTable', () => {
});
const amendCell = getAmendCell();
const typeCell = screen.getAllByRole('gridcell')[2];
const typeCell = screen.getAllByRole('gridcell')[3];
expect(typeCell).toHaveTextContent('Mid - 10.0 Peg limit');
expect(amendCell.queryByTestId('edit')).toBeInTheDocument();
expect(amendCell.queryByTestId('cancel')).toBeInTheDocument();

View File

@ -63,6 +63,38 @@ export const OrderListTable = memo<
cellRendererParams: { idPath: 'market.id', onMarketClick },
minWidth: 150,
},
{
headerName: t('Filled'),
field: 'remaining',
cellClass: 'font-mono text-right',
type: 'rightAligned',
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,
value,
}: VegaValueFormatterParams<Order, 'remaining'>): string => {
if (!data) {
return '';
}
if (!data?.market || !isNumeric(value) || !isNumeric(data.size)) {
return '-';
}
return addDecimalsFormatNumber(
(BigInt(data.size) - BigInt(data.remaining)).toString(),
data.market.positionDecimalPlaces
);
},
minWidth: 50,
width: 90,
flex: 0,
},
{
headerName: t('Size'),
field: 'size',
@ -103,7 +135,9 @@ export const OrderListTable = memo<
)
);
},
minWidth: 80,
minWidth: 50,
width: 80,
flex: 0,
},
{
field: 'type',
@ -150,38 +184,6 @@ export const OrderListTable = memo<
),
minWidth: 100,
},
{
headerName: t('Filled'),
field: 'remaining',
cellClass: 'font-mono text-right',
type: 'rightAligned',
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,
value,
}: VegaValueFormatterParams<Order, 'remaining'>): string => {
if (!data) {
return '';
}
if (!data?.market || !isNumeric(value) || !isNumeric(data.size)) {
return '-';
}
const { positionDecimalPlaces } = data.market;
const filled = BigInt(data.size) - BigInt(data.remaining);
return `${addDecimalsFormatNumber(
filled.toString(),
positionDecimalPlaces
)}/${addDecimalsFormatNumber(data.size, positionDecimalPlaces)}`;
},
minWidth: 100,
},
{
field: 'price',
type: 'rightAligned',
@ -221,12 +223,10 @@ export const OrderListTable = memo<
const expiry = getDateTimeFormat().format(
new Date(data.expiresAt)
);
return `${Schema.OrderTimeInForceMapping[value]}: ${expiry}`;
return `${Schema.OrderTimeInForceCode[value]}: ${expiry}`;
}
const tifLabel = value
? Schema.OrderTimeInForceMapping[value]
: '';
const tifLabel = value ? Schema.OrderTimeInForceCode[value] : '';
const label = `${tifLabel}${
data?.postOnly ? t('. Post Only') : ''
}${data?.reduceOnly ? t('. Reduce only') : ''}`;
@ -235,29 +235,18 @@ export const OrderListTable = memo<
},
minWidth: 150,
},
{
field: 'createdAt',
filter: DateRangeFilter,
cellRenderer: ({
value,
}: VegaICellRendererParams<Order, 'createdAt'>) => {
return (
<span data-value={value}>
{value ? getDateTimeFormat().format(new Date(value)) : value}
</span>
);
},
minWidth: 150,
},
{
field: 'updatedAt',
filter: DateRangeFilter,
valueGetter: ({ data }: VegaValueGetterParams<Order>) =>
data?.updatedAt || data?.createdAt,
cellRenderer: ({
data,
value,
}: VegaICellRendererParams<Order, 'updatedAt'>) => {
if (!data) {
return undefined;
}
const value = data.updatedAt || data.createdAt;
return (
<span data-value={value}>
{value ? getDateTimeFormat().format(new Date(value)) : '-'}