Feat/1500 cancel and edit buttons conditional rendering (#1528)
* feat: allow second type arg to be generic as you dont always need the value * feat: update order data provider to include fields required to determine if editable or cancellable * feat: use ag grid type helpers and add rendering logic to cancel and amend buttons * feat: combine cancel/edit buttons into single cell for better spacing * feat: add test cases for dispaly of amend/cancel buttons * chore: add missing fields to mock generate function * chore: remove unnecessary wait for in fills test that was sporadically failing * fix: add missing fields to generate order function * fix: add missing fields to generate order function for console-lite
This commit is contained in:
parent
7a7c4ad452
commit
032805b5b9
@ -31,6 +31,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
@ -50,6 +52,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
@ -69,6 +73,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
@ -88,6 +94,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
@ -106,6 +114,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
createdAt: new Date(2020, 1, 27).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
rejectionReason: null,
|
||||
},
|
||||
];
|
||||
|
@ -31,6 +31,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
@ -50,6 +52,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
@ -69,6 +73,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
@ -88,6 +94,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
{
|
||||
__typename: 'Order',
|
||||
@ -107,6 +115,8 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -51,20 +51,18 @@ describe('FillsTable', () => {
|
||||
await waitForGridToBeInTheDOM();
|
||||
await waitForDataToHaveLoaded();
|
||||
|
||||
await waitFor(async () => {
|
||||
await screen.findByText('Market');
|
||||
const headers = screen.getAllByRole('columnheader');
|
||||
expect(headers).toHaveLength(7);
|
||||
expect(headers.map((h) => h.textContent?.trim())).toEqual([
|
||||
'Market',
|
||||
'Size',
|
||||
'Value',
|
||||
'Filled value',
|
||||
'Role',
|
||||
'Fee',
|
||||
'Date',
|
||||
]);
|
||||
});
|
||||
await screen.findByText('Market');
|
||||
const headers = screen.getAllByRole('columnheader');
|
||||
expect(headers).toHaveLength(7);
|
||||
expect(headers.map((h) => h.textContent?.trim())).toEqual([
|
||||
'Market',
|
||||
'Size',
|
||||
'Value',
|
||||
'Filled value',
|
||||
'Role',
|
||||
'Fee',
|
||||
'Date',
|
||||
]);
|
||||
});
|
||||
|
||||
it('formats cells correctly for buyer fill', async () => {
|
||||
@ -83,6 +81,7 @@ describe('FillsTable', () => {
|
||||
});
|
||||
|
||||
render(<FillsTable partyId={partyId} rowData={[buyerFill]} />);
|
||||
|
||||
await waitForGridToBeInTheDOM();
|
||||
await waitForDataToHaveLoaded();
|
||||
|
||||
|
@ -69,6 +69,8 @@ export const generateOrder = (partialOrder?: PartialDeep<OrderWithMarket>) => {
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
rejectionReason: null,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
};
|
||||
return merge(order, partialOrder);
|
||||
};
|
||||
|
@ -9,6 +9,10 @@ import { OrderType, Side, OrderStatus, OrderRejectionReason, OrderTimeInForce }
|
||||
// GraphQL subscription operation: OrderSub
|
||||
// ====================================================
|
||||
|
||||
export interface OrderSub_orders_peggedOrder {
|
||||
__typename: "PeggedOrder";
|
||||
}
|
||||
|
||||
export interface OrderSub_orders {
|
||||
__typename: "OrderUpdate";
|
||||
/**
|
||||
@ -63,6 +67,14 @@ export interface OrderSub_orders {
|
||||
* RFC3339Nano time the order was altered
|
||||
*/
|
||||
updatedAt: string | null;
|
||||
/**
|
||||
* The liquidity provision this order was created from
|
||||
*/
|
||||
liquidityProvisionId: string | null;
|
||||
/**
|
||||
* PeggedOrder contains the details about a pegged order
|
||||
*/
|
||||
peggedOrder: OrderSub_orders_peggedOrder | null;
|
||||
}
|
||||
|
||||
export interface OrderSub {
|
||||
|
@ -17,6 +17,14 @@ export interface Orders_party_ordersConnection_edges_node_market {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface Orders_party_ordersConnection_edges_node_liquidityProvision {
|
||||
__typename: "LiquidityProvision";
|
||||
}
|
||||
|
||||
export interface Orders_party_ordersConnection_edges_node_peggedOrder {
|
||||
__typename: "PeggedOrder";
|
||||
}
|
||||
|
||||
export interface Orders_party_ordersConnection_edges_node {
|
||||
__typename: "Order";
|
||||
/**
|
||||
@ -71,6 +79,14 @@ export interface Orders_party_ordersConnection_edges_node {
|
||||
* RFC3339Nano time the order was altered
|
||||
*/
|
||||
updatedAt: string | null;
|
||||
/**
|
||||
* The liquidity provision this order was created from
|
||||
*/
|
||||
liquidityProvision: Orders_party_ordersConnection_edges_node_liquidityProvision | null;
|
||||
/**
|
||||
* PeggedOrder contains the details about a pegged order
|
||||
*/
|
||||
peggedOrder: Orders_party_ordersConnection_edges_node_peggedOrder | null;
|
||||
}
|
||||
|
||||
export interface Orders_party_ordersConnection_edges {
|
||||
|
@ -14,6 +14,7 @@ import type {
|
||||
Orders,
|
||||
Orders_party_ordersConnection_edges,
|
||||
Orders_party_ordersConnection_edges_node,
|
||||
Orders_party_ordersConnection_edges_node_liquidityProvision,
|
||||
OrderSub,
|
||||
OrderSub_orders,
|
||||
} from '../';
|
||||
@ -40,6 +41,12 @@ export const ORDERS_QUERY = gql`
|
||||
expiresAt
|
||||
createdAt
|
||||
updatedAt
|
||||
liquidityProvision {
|
||||
__typename
|
||||
}
|
||||
peggedOrder {
|
||||
__typename
|
||||
}
|
||||
}
|
||||
cursor
|
||||
}
|
||||
@ -70,6 +77,10 @@ export const ORDERS_SUB = gql`
|
||||
expiresAt
|
||||
createdAt
|
||||
updatedAt
|
||||
liquidityProvisionId
|
||||
peggedOrder {
|
||||
__typename
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -98,10 +109,20 @@ export const update = (
|
||||
draft.unshift(...draft.splice(index, 1));
|
||||
}
|
||||
} else if (newer) {
|
||||
const { marketId, ...order } = node;
|
||||
const { marketId, liquidityProvisionId, ...order } = node;
|
||||
|
||||
// If there is a liquidity provision id add the object to the resulting order
|
||||
const liquidityProvision: Orders_party_ordersConnection_edges_node_liquidityProvision | null =
|
||||
liquidityProvisionId
|
||||
? {
|
||||
__typename: 'LiquidityProvision',
|
||||
}
|
||||
: null;
|
||||
|
||||
draft.unshift({
|
||||
node: {
|
||||
...order,
|
||||
liquidityProvision: liquidityProvision,
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: marketId,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { act, render, screen } from '@testing-library/react';
|
||||
import { act, render, screen, within } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { addDecimal, getDateTimeFormat } from '@vegaprotocol/react-helpers';
|
||||
import { OrderType } from '@vegaprotocol/types';
|
||||
import { OrderTimeInForce, OrderType } from '@vegaprotocol/types';
|
||||
import {
|
||||
OrderRejectionReasonMapping,
|
||||
OrderTimeInForceMapping,
|
||||
@ -16,22 +17,28 @@ import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
||||
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
|
||||
import type { OrderListTableProps } from '../';
|
||||
import { OrderListTable } from '../';
|
||||
import type { OrderWithMarket } from '../';
|
||||
import { limitOrder, marketOrder } from '../mocks/generate-orders';
|
||||
import {
|
||||
generateOrder,
|
||||
limitOrder,
|
||||
marketOrder,
|
||||
} from '../mocks/generate-orders';
|
||||
|
||||
const defaultProps: OrderListTableProps = {
|
||||
rowData: [],
|
||||
setEditOrder: jest.fn(),
|
||||
cancel: jest.fn(),
|
||||
};
|
||||
|
||||
const generateJsx = (
|
||||
orders: OrderWithMarket[] | null,
|
||||
props: Partial<OrderListTableProps> = defaultProps,
|
||||
context: PartialDeep<VegaWalletContextShape> = { keypair: { pub: '0x123' } }
|
||||
) => {
|
||||
return (
|
||||
<MockedProvider>
|
||||
<VegaWalletContext.Provider value={context as VegaWalletContextShape}>
|
||||
<OrderListTable
|
||||
rowData={orders}
|
||||
cancel={jest.fn()}
|
||||
setEditOrder={jest.fn()}
|
||||
/>
|
||||
<OrderListTable {...defaultProps} {...props} />
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
);
|
||||
@ -40,19 +47,16 @@ const generateJsx = (
|
||||
describe('OrderListTable', () => {
|
||||
it('should show no orders message', async () => {
|
||||
await act(async () => {
|
||||
render(generateJsx([]));
|
||||
render(generateJsx({ rowData: [] }));
|
||||
});
|
||||
expect(screen.getByText('No orders')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render correct columns', async () => {
|
||||
await act(async () => {
|
||||
render(generateJsx([marketOrder, limitOrder]));
|
||||
render(generateJsx({ rowData: [marketOrder, limitOrder] }));
|
||||
});
|
||||
|
||||
const headers = screen.getAllByRole('columnheader');
|
||||
expect(headers).toHaveLength(11);
|
||||
expect(headers.map((h) => h.textContent?.trim())).toEqual([
|
||||
const expectedHeaders = [
|
||||
'Market',
|
||||
'Size',
|
||||
'Type',
|
||||
@ -62,14 +66,16 @@ describe('OrderListTable', () => {
|
||||
'Time In Force',
|
||||
'Created At',
|
||||
'Updated At',
|
||||
'Edit',
|
||||
'Cancel',
|
||||
]);
|
||||
'', // no cell header for edit/cancel
|
||||
];
|
||||
const headers = screen.getAllByRole('columnheader');
|
||||
expect(headers).toHaveLength(expectedHeaders.length);
|
||||
expect(headers.map((h) => h.textContent?.trim())).toEqual(expectedHeaders);
|
||||
});
|
||||
|
||||
it('should apply correct formatting for market order', async () => {
|
||||
await act(async () => {
|
||||
render(generateJsx([marketOrder]));
|
||||
render(generateJsx({ rowData: [marketOrder] }));
|
||||
});
|
||||
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
@ -84,7 +90,6 @@ describe('OrderListTable', () => {
|
||||
getDateTimeFormat().format(new Date(marketOrder.createdAt)),
|
||||
'-',
|
||||
'Edit',
|
||||
'Cancel',
|
||||
];
|
||||
cells.forEach((cell, i) =>
|
||||
expect(cell).toHaveTextContent(expectedValues[i])
|
||||
@ -93,7 +98,7 @@ describe('OrderListTable', () => {
|
||||
|
||||
it('should apply correct formatting applied for GTT limit order', async () => {
|
||||
await act(async () => {
|
||||
render(generateJsx([limitOrder]));
|
||||
render(generateJsx({ rowData: [limitOrder] }));
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
|
||||
@ -110,7 +115,6 @@ describe('OrderListTable', () => {
|
||||
getDateTimeFormat().format(new Date(limitOrder.createdAt)),
|
||||
'-',
|
||||
'Edit',
|
||||
'Cancel',
|
||||
];
|
||||
cells.forEach((cell, i) =>
|
||||
expect(cell).toHaveTextContent(expectedValues[i])
|
||||
@ -125,7 +129,7 @@ describe('OrderListTable', () => {
|
||||
OrderRejectionReason.ORDER_ERROR_INSUFFICIENT_ASSET_BALANCE,
|
||||
};
|
||||
await act(async () => {
|
||||
render(generateJsx([rejectedOrder]));
|
||||
render(generateJsx({ rowData: [rejectedOrder] }));
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
expect(cells[3]).toHaveTextContent(
|
||||
@ -134,4 +138,108 @@ describe('OrderListTable', () => {
|
||||
}`
|
||||
);
|
||||
});
|
||||
|
||||
describe('amend cell', () => {
|
||||
it('allows cancelling and editing for permitted orders', async () => {
|
||||
const mockEdit = jest.fn();
|
||||
const mockCancel = jest.fn();
|
||||
const order = generateOrder({
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
});
|
||||
await act(async () => {
|
||||
render(
|
||||
generateJsx({
|
||||
rowData: [order],
|
||||
setEditOrder: mockEdit,
|
||||
cancel: mockCancel,
|
||||
})
|
||||
);
|
||||
});
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.getAllByRole('button')).toHaveLength(2);
|
||||
await userEvent.click(amendCell.getByTestId('edit'));
|
||||
expect(mockEdit).toHaveBeenCalledWith(order);
|
||||
await userEvent.click(amendCell.getByTestId('cancel'));
|
||||
expect(mockCancel).toHaveBeenCalledWith(order);
|
||||
});
|
||||
|
||||
it('doesnt show buttons for liquidity provision orders', async () => {
|
||||
const order = generateOrder({
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
liquidityProvision: { __typename: 'LiquidityProvision' },
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
render(generateJsx({ rowData: [order] }));
|
||||
});
|
||||
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.queryAllByRole('button')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('doesnt show buttons for pegged orders', async () => {
|
||||
const order = generateOrder({
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
peggedOrder: {
|
||||
__typename: 'PeggedOrder',
|
||||
},
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
render(generateJsx({ rowData: [order] }));
|
||||
});
|
||||
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.queryAllByRole('button')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it.each([OrderStatus.STATUS_ACTIVE, OrderStatus.STATUS_PARKED])(
|
||||
'shows buttons for %s orders',
|
||||
async (status) => {
|
||||
const order = generateOrder({
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
status,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
render(generateJsx({ rowData: [order] }));
|
||||
});
|
||||
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.getAllByRole('button')).toHaveLength(2);
|
||||
}
|
||||
);
|
||||
|
||||
it.each([
|
||||
OrderStatus.STATUS_CANCELLED,
|
||||
OrderStatus.STATUS_EXPIRED,
|
||||
OrderStatus.STATUS_FILLED,
|
||||
OrderStatus.STATUS_REJECTED,
|
||||
OrderStatus.STATUS_STOPPED,
|
||||
])('doesnt show buttons for %s orders', async (status) => {
|
||||
const order = generateOrder({
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
status,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
render(generateJsx({ rowData: [order] }));
|
||||
});
|
||||
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.queryAllByRole('button')).toHaveLength(0);
|
||||
});
|
||||
|
||||
const getAmendCell = () => {
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
return within(
|
||||
cells.find((c) => c.getAttribute('col-id') === 'amend') as HTMLElement
|
||||
);
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -15,19 +15,18 @@ import {
|
||||
positiveClassNames,
|
||||
negativeClassNames,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
VegaICellRendererParams,
|
||||
VegaValueFormatterParams,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
AgGridDynamic as AgGrid,
|
||||
Button,
|
||||
Intent,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import type {
|
||||
ICellRendererParams,
|
||||
ValueFormatterParams,
|
||||
} from 'ag-grid-community';
|
||||
import type { AgGridReact, AgGridReactProps } from 'ag-grid-react';
|
||||
import { AgGridColumn } from 'ag-grid-react';
|
||||
import { forwardRef, useState } from 'react';
|
||||
import type { Orders_party_ordersConnection_edges_node } from '../';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import { useOrderCancel } from '../../order-hooks/use-order-cancel';
|
||||
@ -93,14 +92,7 @@ export const OrderList = forwardRef<AgGridReact, OrderListProps>(
|
||||
}
|
||||
);
|
||||
|
||||
type OrderListTableValueFormatterParams = Omit<
|
||||
ValueFormatterParams,
|
||||
'data' | 'value'
|
||||
> & {
|
||||
data: OrderWithMarket | null;
|
||||
};
|
||||
|
||||
type OrderListTableProps = AgGridReactProps & {
|
||||
export type OrderListTableProps = AgGridReactProps & {
|
||||
cancel: (order: OrderWithMarket) => void;
|
||||
setEditOrder: (order: OrderWithMarket) => void;
|
||||
};
|
||||
@ -135,11 +127,9 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
valueFormatter={({
|
||||
value,
|
||||
data,
|
||||
}: OrderListTableValueFormatterParams & {
|
||||
value?: OrderWithMarket['size'];
|
||||
}) => {
|
||||
if (value === undefined || !data || !data.market) {
|
||||
return undefined;
|
||||
}: VegaValueFormatterParams<OrderWithMarket, 'size'>) => {
|
||||
if (!data.market) {
|
||||
return '-';
|
||||
}
|
||||
const prefix = data
|
||||
? data.side === Side.SIDE_BUY
|
||||
@ -155,21 +145,17 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
field="type"
|
||||
valueFormatter={({
|
||||
value,
|
||||
}: ValueFormatterParams & {
|
||||
value?: Orders_party_ordersConnection_edges_node['type'];
|
||||
}) => OrderTypeMapping[value as OrderType]}
|
||||
}: VegaValueFormatterParams<OrderWithMarket, 'type'>) => {
|
||||
if (!value) return '-';
|
||||
return OrderTypeMapping[value];
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
field="status"
|
||||
valueFormatter={({
|
||||
value,
|
||||
data,
|
||||
}: OrderListTableValueFormatterParams & {
|
||||
value?: Orders_party_ordersConnection_edges_node['status'];
|
||||
}) => {
|
||||
if (value === undefined || !data || !data.market) {
|
||||
return undefined;
|
||||
}
|
||||
}: VegaValueFormatterParams<OrderWithMarket, 'status'>) => {
|
||||
if (value === OrderStatus.STATUS_REJECTED) {
|
||||
return `${OrderStatusMapping[value]}: ${
|
||||
data.rejectionReason &&
|
||||
@ -187,11 +173,9 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
valueFormatter={({
|
||||
data,
|
||||
value,
|
||||
}: OrderListTableValueFormatterParams & {
|
||||
value?: Orders_party_ordersConnection_edges_node['remaining'];
|
||||
}) => {
|
||||
if (value === undefined || !data || !data.market) {
|
||||
return undefined;
|
||||
}: VegaValueFormatterParams<OrderWithMarket, 'remaining'>) => {
|
||||
if (!data.market) {
|
||||
return '-';
|
||||
}
|
||||
const dps = data.market.positionDecimalPlaces;
|
||||
const size = new BigNumber(data.size);
|
||||
@ -210,15 +194,8 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
valueFormatter={({
|
||||
value,
|
||||
data,
|
||||
}: OrderListTableValueFormatterParams & {
|
||||
value?: Orders_party_ordersConnection_edges_node['price'];
|
||||
}) => {
|
||||
if (
|
||||
value === undefined ||
|
||||
!data ||
|
||||
!data.market ||
|
||||
data.type === OrderType.TYPE_MARKET
|
||||
) {
|
||||
}: VegaValueFormatterParams<OrderWithMarket, 'price'>) => {
|
||||
if (!data.market || data.type === OrderType.TYPE_MARKET) {
|
||||
return '-';
|
||||
}
|
||||
return addDecimal(value, data.market.decimalPlaces);
|
||||
@ -229,12 +206,7 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
valueFormatter={({
|
||||
value,
|
||||
data,
|
||||
}: OrderListTableValueFormatterParams & {
|
||||
value?: Orders_party_ordersConnection_edges_node['timeInForce'];
|
||||
}) => {
|
||||
if (value === undefined || !data || !data.market) {
|
||||
return undefined;
|
||||
}
|
||||
}: VegaValueFormatterParams<OrderWithMarket, 'timeInForce'>) => {
|
||||
if (
|
||||
value === OrderTimeInForce.TIME_IN_FORCE_GTT &&
|
||||
data.expiresAt
|
||||
@ -252,9 +224,7 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
field="createdAt"
|
||||
valueFormatter={({
|
||||
value,
|
||||
}: OrderListTableValueFormatterParams & {
|
||||
value?: Orders_party_ordersConnection_edges_node['createdAt'];
|
||||
}) => {
|
||||
}: VegaValueFormatterParams<OrderWithMarket, 'createdAt'>) => {
|
||||
return value ? getDateTimeFormat().format(new Date(value)) : value;
|
||||
}}
|
||||
/>
|
||||
@ -262,46 +232,35 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
field="updatedAt"
|
||||
valueFormatter={({
|
||||
value,
|
||||
}: OrderListTableValueFormatterParams & {
|
||||
value?: Orders_party_ordersConnection_edges_node['updatedAt'];
|
||||
}) => {
|
||||
}: VegaValueFormatterParams<OrderWithMarket, 'updatedAt'>) => {
|
||||
return value ? getDateTimeFormat().format(new Date(value)) : '-';
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
field="edit"
|
||||
cellRenderer={({ data }: ICellRendererParams) => {
|
||||
if (!data) return null;
|
||||
if (isOrderActive(data.status)) {
|
||||
colId="amend"
|
||||
headerName=""
|
||||
field="status"
|
||||
cellRenderer={({
|
||||
data,
|
||||
}: VegaICellRendererParams<OrderWithMarket>) => {
|
||||
if (isOrderAmendable(data)) {
|
||||
return (
|
||||
<Button
|
||||
data-testid="edit"
|
||||
onClick={() => {
|
||||
setEditOrder(data);
|
||||
}}
|
||||
size="xs"
|
||||
>
|
||||
{t('Edit')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
field="cancel"
|
||||
cellRenderer={({ data }: ICellRendererParams) => {
|
||||
if (!data) return null;
|
||||
if (isOrderActive(data.status)) {
|
||||
return (
|
||||
<Button
|
||||
size="xs"
|
||||
data-testid="cancel"
|
||||
onClick={() => cancel(data)}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
data-testid="edit"
|
||||
onClick={() => setEditOrder(data)}
|
||||
size="xs"
|
||||
>
|
||||
{t('Edit')}
|
||||
</Button>
|
||||
<Button
|
||||
size="xs"
|
||||
data-testid="cancel"
|
||||
onClick={() => cancel(data)}
|
||||
>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -327,6 +286,18 @@ export const isOrderActive = (status: OrderStatus) => {
|
||||
].includes(status);
|
||||
};
|
||||
|
||||
export const isOrderAmendable = (order: OrderWithMarket | undefined) => {
|
||||
if (!order || order.peggedOrder || order.liquidityProvision) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isOrderActive(order.status)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const getEditDialogTitle = (
|
||||
status?: OrderStatus
|
||||
): string | undefined => {
|
||||
|
20
libs/types/src/__generated__/types.ts
generated
20
libs/types/src/__generated__/types.ts
generated
@ -3161,6 +3161,8 @@ export type Query = {
|
||||
assetsConnection?: Maybe<AssetsConnection>;
|
||||
/** Find a deposit using its ID */
|
||||
deposit?: Maybe<Deposit>;
|
||||
/** Fetch all deposits */
|
||||
deposits?: Maybe<DepositsConnection>;
|
||||
/** Get data for a specific epoch, if ID omitted it gets the current epoch. If the string is 'next', fetch the next epoch */
|
||||
epoch: Epoch;
|
||||
/** Get the signatures bundle to allowlist an ERC20 token in the collateral bridge */
|
||||
@ -3321,6 +3323,8 @@ export type Query = {
|
||||
updateMarketProposals?: Maybe<Array<Proposal>>;
|
||||
/** Find a withdrawal using its ID */
|
||||
withdrawal?: Maybe<Withdrawal>;
|
||||
/** Fetch all withdrawals */
|
||||
withdrawals?: Maybe<WithdrawalsConnection>;
|
||||
};
|
||||
|
||||
|
||||
@ -3343,6 +3347,13 @@ export type QuerydepositArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** Queries allow a caller to read data and filter data via GraphQL. */
|
||||
export type QuerydepositsArgs = {
|
||||
dateRange?: InputMaybe<DateRange>;
|
||||
pagination?: InputMaybe<Pagination>;
|
||||
};
|
||||
|
||||
|
||||
/** Queries allow a caller to read data and filter data via GraphQL. */
|
||||
export type QueryepochArgs = {
|
||||
id?: InputMaybe<Scalars['ID']>;
|
||||
@ -3667,6 +3678,13 @@ export type QuerywithdrawalArgs = {
|
||||
id: Scalars['ID'];
|
||||
};
|
||||
|
||||
|
||||
/** Queries allow a caller to read data and filter data via GraphQL. */
|
||||
export type QuerywithdrawalsArgs = {
|
||||
dateRange?: InputMaybe<DateRange>;
|
||||
pagination?: InputMaybe<Pagination>;
|
||||
};
|
||||
|
||||
export type RankingScore = {
|
||||
__typename?: 'RankingScore';
|
||||
/** The performance score of the validator */
|
||||
@ -4406,6 +4424,8 @@ export enum TransferStatus {
|
||||
/** A proposal to update an asset's details */
|
||||
export type UpdateAsset = {
|
||||
__typename?: 'UpdateAsset';
|
||||
/** The asset to update */
|
||||
assetId: Scalars['ID'];
|
||||
/** The minimum economically meaningful amount of this specific asset */
|
||||
quantum: Scalars['String'];
|
||||
/** The source of the updated asset */
|
||||
|
@ -17,14 +17,12 @@ type RowHelper<TObj, TRow, TField extends Field> = Omit<
|
||||
value: Get<TRow, TField>;
|
||||
};
|
||||
|
||||
export type VegaValueFormatterParams<TRow, TField extends Field> = RowHelper<
|
||||
ValueFormatterParams,
|
||||
export type VegaValueFormatterParams<
|
||||
TRow,
|
||||
TField
|
||||
>;
|
||||
TField extends Field = string
|
||||
> = RowHelper<ValueFormatterParams, TRow, TField>;
|
||||
|
||||
export type VegaICellRendererParams<TRow, TField extends Field> = RowHelper<
|
||||
ICellRendererParams,
|
||||
export type VegaICellRendererParams<
|
||||
TRow,
|
||||
TField
|
||||
>;
|
||||
TField extends Field = string
|
||||
> = RowHelper<ICellRendererParams, TRow, TField>;
|
||||
|
Loading…
Reference in New Issue
Block a user