From ef075361599172576ce3a4c9169cefb640960319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20G=C5=82ownia?= Date: Fri, 28 Oct 2022 17:15:21 +0200 Subject: [PATCH] feat(958): add cancel all orders button (#1861) --- .../components/portfolio/orders/orders.tsx | 4 +- .../orders/use-column-definitions.tsx | 9 +- .../src/integration/trading-orders.cy.ts | 66 +++---- .../components/order-list/order-list.spec.tsx | 9 +- .../order-list/order-list.stories.tsx | 2 + .../lib/components/order-list/order-list.tsx | 161 ++++++++++++++---- .../src/lib/order-hooks/use-order-cancel.tsx | 50 ++++-- libs/wallet/src/connectors/vega-connector.ts | 4 +- 8 files changed, 208 insertions(+), 97 deletions(-) diff --git a/apps/console-lite/src/app/components/portfolio/orders/orders.tsx b/apps/console-lite/src/app/components/portfolio/orders/orders.tsx index 416515020..b0f32adc5 100644 --- a/apps/console-lite/src/app/components/portfolio/orders/orders.tsx +++ b/apps/console-lite/src/app/components/portfolio/orders/orders.tsx @@ -65,8 +65,8 @@ const OrdersManager = () => { defaultColDef={defaultColDef} /> void; orderCancel: { - cancel: (args: CancelOrderArgs) => void; + cancel: (args: OrderCancellationBody['orderCancellation']) => void; [key: string]: unknown; }; } diff --git a/apps/trading-e2e/src/integration/trading-orders.cy.ts b/apps/trading-e2e/src/integration/trading-orders.cy.ts index 6dfdc314f..d3d8de0d5 100644 --- a/apps/trading-e2e/src/integration/trading-orders.cy.ts +++ b/apps/trading-e2e/src/integration/trading-orders.cy.ts @@ -14,6 +14,7 @@ const orderPrice = 'price'; const orderTimeInForce = 'timeInForce'; const orderCreatedAt = 'createdAt'; const cancelOrderBtn = 'cancel'; +const cancelAllOrdersBtn = 'cancelAll'; const editOrderBtn = 'edit'; describe('orders list', { tags: '@smoke' }, () => { @@ -29,50 +30,49 @@ describe('orders list', { tags: '@smoke' }, () => { cy.wait('@Orders').then(() => { expect(subscriptionMocks.OrdersUpdate).to.be.calledOnce; }); + cy.wait('@Markets'); }); it('renders orders', () => { cy.getByTestId('tab-orders').should('be.visible'); - + cy.getByTestId(cancelAllOrdersBtn).should('be.visible'); + cy.getByTestId(cancelOrderBtn).should('have.length.at.least', 1); + cy.getByTestId(editOrderBtn).should('have.length.at.least', 1); cy.getByTestId('tab-orders').within(() => { - cy.get(`[col-id='${orderSymbol}']`).each(($symbol) => { - cy.wrap($symbol).invoke('text').should('not.be.empty'); - }); + cy.get(`[role='rowgroup']`) + .first() + .within(() => { + cy.get(`[col-id='${orderSymbol}']`).each(($symbol) => { + cy.wrap($symbol).invoke('text').should('not.be.empty'); + }); - cy.get(`[col-id='${orderSize}']`).each(($size) => { - cy.wrap($size).invoke('text').should('not.be.empty'); - }); + cy.get(`[col-id='${orderSize}']`).each(($size) => { + cy.wrap($size).invoke('text').should('not.be.empty'); + }); - cy.get(`[col-id='${orderType}']`).each(($type) => { - cy.wrap($type).invoke('text').should('not.be.empty'); - }); + cy.get(`[col-id='${orderType}']`).each(($type) => { + cy.wrap($type).invoke('text').should('not.be.empty'); + }); - cy.get(`[col-id='${orderStatus}']`).each(($status) => { - cy.wrap($status).invoke('text').should('not.be.empty'); - }); + cy.get(`[col-id='${orderStatus}']`).each(($status) => { + 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='${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'); - }); + cy.get(`[col-id='${orderPrice}']`).each(($price) => { + cy.wrap($price).invoke('text').should('not.be.empty'); + }); - cy.get(`[col-id='${orderTimeInForce}']`).each(($timeInForce) => { - cy.wrap($timeInForce).invoke('text').should('not.be.empty'); - }); + cy.get(`[col-id='${orderTimeInForce}']`).each(($timeInForce) => { + cy.wrap($timeInForce).invoke('text').should('not.be.empty'); + }); - cy.get(`[col-id='${orderCreatedAt}']`).each(($dateTime) => { - cy.wrap($dateTime).invoke('text').should('not.be.empty'); - }); - - cy.getByTestId(cancelOrderBtn) - .should('be.visible') - .and('have.length.at.least', 1); - - cy.getByTestId(editOrderBtn) - .should('be.visible') - .and('have.length.at.least', 1); + cy.get(`[col-id='${orderCreatedAt}']`).each(($dateTime) => { + cy.wrap($dateTime).invoke('text').should('not.be.empty'); + }); + }); }); }); diff --git a/libs/orders/src/lib/components/order-list/order-list.spec.tsx b/libs/orders/src/lib/components/order-list/order-list.spec.tsx index 82b90d949..227780334 100644 --- a/libs/orders/src/lib/components/order-list/order-list.spec.tsx +++ b/libs/orders/src/lib/components/order-list/order-list.spec.tsx @@ -25,6 +25,7 @@ const defaultProps: OrderListTableProps = { rowData: [], setEditOrder: jest.fn(), cancel: jest.fn(), + cancelAll: jest.fn(), }; const generateJsx = ( @@ -87,8 +88,8 @@ describe('OrderListTable', () => { '-', 'Edit', ]; - cells.forEach((cell, i) => - expect(cell).toHaveTextContent(expectedValues[i]) + expectedValues.forEach((expectedValue, i) => + expect(cells[i]).toHaveTextContent(expectedValue) ); }); @@ -112,8 +113,8 @@ describe('OrderListTable', () => { '-', 'Edit', ]; - cells.forEach((cell, i) => - expect(cell).toHaveTextContent(expectedValues[i]) + expectedValues.forEach((expectedValue, i) => + expect(cells[i]).toHaveTextContent(expectedValue) ); }); diff --git a/libs/orders/src/lib/components/order-list/order-list.stories.tsx b/libs/orders/src/lib/components/order-list/order-list.stories.tsx index d87053932..f12f9a9b0 100644 --- a/libs/orders/src/lib/components/order-list/order-list.stories.tsx +++ b/libs/orders/src/lib/components/order-list/order-list.stories.tsx @@ -19,6 +19,7 @@ const Template: Story = (args) => { { return; }} @@ -47,6 +48,7 @@ const Template2: Story = (args) => { diff --git a/libs/orders/src/lib/components/order-list/order-list.tsx b/libs/orders/src/lib/components/order-list/order-list.tsx index 8265e7b04..306c319e3 100644 --- a/libs/orders/src/lib/components/order-list/order-list.tsx +++ b/libs/orders/src/lib/components/order-list/order-list.tsx @@ -1,3 +1,4 @@ +import { useEnvironment } from '@vegaprotocol/environment'; import { addDecimalsFormatNumber, getDateTimeFormat, @@ -5,6 +6,7 @@ import { negativeClassNames, positiveClassNames, t, + truncateByChars, } from '@vegaprotocol/react-helpers'; import { OrderRejectionReasonMapping, @@ -19,10 +21,12 @@ import { Intent, Link, } from '@vegaprotocol/ui-toolkit'; +import type { TransactionResult } from '@vegaprotocol/wallet'; +import type { VegaTxState } from '@vegaprotocol/wallet'; import { AgGridColumn } from 'ag-grid-react'; import BigNumber from 'bignumber.js'; import { forwardRef, useState } from 'react'; - +import type { TypedDataAgGrid } from '@vegaprotocol/ui-toolkit'; import { useOrderCancel } from '../../order-hooks/use-order-cancel'; import { useOrderEdit } from '../../order-hooks/use-order-edit'; import { OrderFeedback } from '../order-feedback'; @@ -32,9 +36,46 @@ import type { VegaICellRendererParams, VegaValueFormatterParams, } from '@vegaprotocol/ui-toolkit'; -import type { AgGridReact, AgGridReactProps } from 'ag-grid-react'; -import type { Order } from '../'; -type OrderListProps = AgGridReactProps; +import type { AgGridReact } from 'ag-grid-react'; +import type { Order } from '../order-data-provider'; +import type { OrderEventFieldsFragment } from '../../order-hooks'; + +type OrderListProps = TypedDataAgGrid; + +export const TransactionComplete = ({ + transaction, + transactionResult, +}: { + transaction: VegaTxState; + transactionResult?: TransactionResult; +}) => { + const { VEGA_EXPLORER_URL } = useEnvironment(); + if (!transactionResult) return null; + return ( + <> + {transactionResult.status ? ( +

{t('Transaction successful')}

+ ) : ( +

+ {t('Transaction failed')}: {transactionResult.error} +

+ )} + {transaction.txHash && ( + <> +

{t('Transaction')}

+

+ + {truncateByChars(transaction.txHash)} + +

+ + )} + + ); +}; export const OrderList = forwardRef( (props, ref) => { @@ -46,7 +87,10 @@ export const OrderList = forwardRef( <> { + cancelAll={() => { + orderCancel.cancel({}); + }} + cancel={(order: Order) => { if (!order.market) return; orderCancel.cancel({ orderId: order.id, @@ -57,14 +101,16 @@ export const OrderList = forwardRef( setEditOrder={setEditOrder} /> + ) : ( + ), }} /> @@ -97,13 +143,14 @@ export const OrderList = forwardRef( } ); -export type OrderListTableProps = AgGridReactProps & { +export type OrderListTableProps = OrderListProps & { cancel: (order: Order) => void; + cancelAll: () => void; setEditOrder: (order: Order) => void; }; export const OrderListTable = forwardRef( - ({ cancel, setEditOrder, ...props }, ref) => { + ({ cancel, cancelAll, setEditOrder, ...props }, ref) => { return ( ( style={{ width: '100%', height: '100%' }} getRowId={({ data }) => data.id} rowHeight={34} + pinnedBottomRowData={[{}]} {...props} > ( valueFormatter={({ value, data, + node, }: VegaValueFormatterParams) => { + if (node?.rowPinned) { + return ''; + } if (!data?.market || !isNumeric(value)) { return '-'; } @@ -167,7 +219,11 @@ export const OrderListTable = forwardRef( valueFormatter={({ data: order, value, + node, }: VegaValueFormatterParams) => { + if (node?.rowPinned) { + return ''; + } if (!value) return '-'; if (order?.peggedOrder) return t('Pegged'); if (order?.liquidityProvision) return t('Liquidity provision'); @@ -197,7 +253,11 @@ export const OrderListTable = forwardRef( valueFormatter={({ data, value, + node, }: VegaValueFormatterParams) => { + if (node?.rowPinned) { + return ''; + } if (!data?.market || !isNumeric(value) || !isNumeric(data.size)) { return '-'; } @@ -218,7 +278,11 @@ export const OrderListTable = forwardRef( valueFormatter={({ value, data, + node, }: VegaValueFormatterParams) => { + if (node?.rowPinned) { + return ''; + } if ( !data?.market || data.type === Schema.OrderType.TYPE_MARKET || @@ -260,7 +324,11 @@ export const OrderListTable = forwardRef( field="updatedAt" valueFormatter={({ value, + node, }: VegaValueFormatterParams) => { + if (node?.rowPinned) { + return ''; + } return value ? getDateTimeFormat().format(new Date(value)) : '-'; }} /> @@ -268,10 +336,23 @@ export const OrderListTable = forwardRef( colId="amend" headerName="" field="status" - cellRenderer={({ data }: VegaICellRendererParams) => { + cellRenderer={({ data, node }: VegaICellRendererParams) => { + if (node?.rowPinned) { + return ( +
+ +
+ ); + } if (isOrderAmendable(data)) { return data ? ( -
+