* feat(#1552): order edit dialog supports size editing * feat(#1552): calculate size delta correctly * feat(#1552): be able to edit order size * feat(#1552): make sizeediting optional
This commit is contained in:
parent
7ab1778830
commit
2eae066ea7
@ -4,6 +4,7 @@ import {
|
|||||||
toDecimal,
|
toDecimal,
|
||||||
Size,
|
Size,
|
||||||
getDateTimeFormat,
|
getDateTimeFormat,
|
||||||
|
addDecimal,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import { Schema } from '@vegaprotocol/types';
|
import { Schema } from '@vegaprotocol/types';
|
||||||
import {
|
import {
|
||||||
@ -26,6 +27,7 @@ interface OrderEditDialogProps {
|
|||||||
|
|
||||||
interface FormFields {
|
interface FormFields {
|
||||||
limitPrice: string;
|
limitPrice: string;
|
||||||
|
size: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OrderEditDialog = ({
|
export const OrderEditDialog = ({
|
||||||
@ -41,15 +43,13 @@ export const OrderEditDialog = ({
|
|||||||
handleSubmit,
|
handleSubmit,
|
||||||
} = useForm<FormFields>({
|
} = useForm<FormFields>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
limitPrice: addDecimalsFormatNumber(
|
limitPrice: addDecimal(order.price, order.market?.decimalPlaces ?? 0),
|
||||||
order.price,
|
size: addDecimal(order.size, order.market?.positionDecimalPlaces ?? 0),
|
||||||
order.market?.decimalPlaces ?? 0
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const step = toDecimal(order.market?.decimalPlaces ?? 0);
|
const step = toDecimal(order.market?.decimalPlaces ?? 0);
|
||||||
|
const stepSize = toDecimal(order.market?.positionDecimalPlaces ?? 0);
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
@ -96,9 +96,10 @@ export const OrderEditDialog = ({
|
|||||||
<form
|
<form
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
data-testid="edit-order"
|
data-testid="edit-order"
|
||||||
className="w-1/2 mt-4"
|
className="w-full mt-4"
|
||||||
>
|
>
|
||||||
<FormGroup label={t('Price')} labelFor="limitPrice">
|
<div className="flex flex-col md:flex-row gap-4">
|
||||||
|
<FormGroup label={t('Price')} labelFor="limitPrice" className="grow">
|
||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
step={step}
|
step={step}
|
||||||
@ -106,15 +107,37 @@ export const OrderEditDialog = ({
|
|||||||
required: t('You need to provide a price'),
|
required: t('You need to provide a price'),
|
||||||
validate: {
|
validate: {
|
||||||
min: (value) =>
|
min: (value) =>
|
||||||
Number(value) > 0 ? true : t('The price cannot be negative'),
|
Number(value) > 0
|
||||||
|
? true
|
||||||
|
: t('The price cannot be negative'),
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
id="limitPrice"
|
id="limitPrice"
|
||||||
/>
|
/>
|
||||||
{errors.limitPrice?.message && (
|
{errors.limitPrice?.message && (
|
||||||
<InputError intent="danger">{errors.limitPrice.message}</InputError>
|
<InputError intent="danger">
|
||||||
|
{errors.limitPrice.message}
|
||||||
|
</InputError>
|
||||||
)}
|
)}
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
<FormGroup label={t('Size')} labelFor="size" className="grow">
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
step={stepSize}
|
||||||
|
{...register('size', {
|
||||||
|
required: t('You need to provide a size'),
|
||||||
|
validate: {
|
||||||
|
min: (value) =>
|
||||||
|
Number(value) > 0 ? true : t('The size cannot be negative'),
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
id="size"
|
||||||
|
/>
|
||||||
|
{errors.size?.message && (
|
||||||
|
<InputError intent="danger">{errors.size.message}</InputError>
|
||||||
|
)}
|
||||||
|
</FormGroup>
|
||||||
|
</div>
|
||||||
<Button variant="primary" size="md" type="submit">
|
<Button variant="primary" size="md" type="submit">
|
||||||
{t('Update')}
|
{t('Update')}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -136,7 +136,7 @@ export const OrderList = forwardRef<AgGridReact, OrderListProps>(
|
|||||||
order={editOrder}
|
order={editOrder}
|
||||||
onSubmit={(fields) => {
|
onSubmit={(fields) => {
|
||||||
setEditOrder(null);
|
setEditOrder(null);
|
||||||
orderEdit.edit({ price: fields.limitPrice });
|
orderEdit.edit({ price: fields.limitPrice, size: fields.size });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -356,6 +356,7 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
|||||||
colId="amend"
|
colId="amend"
|
||||||
headerName=""
|
headerName=""
|
||||||
field="status"
|
field="status"
|
||||||
|
minWidth={150}
|
||||||
cellRenderer={({ data, node }: VegaICellRendererParams<Order>) => {
|
cellRenderer={({ data, node }: VegaICellRendererParams<Order>) => {
|
||||||
if (node?.rowPinned) {
|
if (node?.rowPinned) {
|
||||||
return (
|
return (
|
||||||
|
@ -124,7 +124,7 @@ function setup(order: Order, context?: Partial<VegaWalletContextShape>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('useOrderEdit', () => {
|
describe('useOrderEdit', () => {
|
||||||
it('should edit a correctly formatted order', async () => {
|
it('should edit a correctly formatted order if there is no size', async () => {
|
||||||
const mockSendTx = jest.fn().mockReturnValue(Promise.resolve({}));
|
const mockSendTx = jest.fn().mockReturnValue(Promise.resolve({}));
|
||||||
const pubKeyObj = { publicKey: '0x123', name: 'test key 1' };
|
const pubKeyObj = { publicKey: '0x123', name: 'test key 1' };
|
||||||
const order = generateOrder({
|
const order = generateOrder({
|
||||||
@ -154,6 +154,36 @@ describe('useOrderEdit', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should edit a correctly formatted order', async () => {
|
||||||
|
const mockSendTx = jest.fn().mockReturnValue(Promise.resolve({}));
|
||||||
|
const pubKeyObj = { publicKey: '0x123', name: 'test key 1' };
|
||||||
|
const order = generateOrder({
|
||||||
|
price: '123456789',
|
||||||
|
market: { decimalPlaces: 2 },
|
||||||
|
});
|
||||||
|
const { result } = setup(order, {
|
||||||
|
sendTx: mockSendTx,
|
||||||
|
pubKeys: [pubKeyObj],
|
||||||
|
pubKey: pubKeyObj.publicKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.edit({ price: '1234567.89', size: '20' });
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockSendTx).toHaveBeenCalledWith(pubKeyObj.publicKey, {
|
||||||
|
orderAmendment: {
|
||||||
|
orderId: order.id,
|
||||||
|
// eslint-disable-next-line
|
||||||
|
marketId: order.market!.id,
|
||||||
|
timeInForce: order.timeInForce,
|
||||||
|
price: '123456789', // Decimal removed
|
||||||
|
sizeDelta: 1990,
|
||||||
|
expiresAt: undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('has the correct default state', () => {
|
it('has the correct default state', () => {
|
||||||
const order = generateOrder();
|
const order = generateOrder();
|
||||||
const { result } = setup(order);
|
const { result } = setup(order);
|
||||||
|
@ -5,10 +5,11 @@ import type { OrderEventFieldsFragment } from './';
|
|||||||
import * as Sentry from '@sentry/react';
|
import * as Sentry from '@sentry/react';
|
||||||
import type { Order } from '../components';
|
import type { Order } from '../components';
|
||||||
import { useOrderEvent } from './use-order-event';
|
import { useOrderEvent } from './use-order-event';
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
// Can only edit price for now
|
|
||||||
export interface EditOrderArgs {
|
export interface EditOrderArgs {
|
||||||
price: string;
|
price: string;
|
||||||
|
size?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useOrderEdit = (order: Order | null) => {
|
export const useOrderEdit = (order: Order | null) => {
|
||||||
@ -47,7 +48,13 @@ export const useOrderEdit = (order: Order | null) => {
|
|||||||
marketId: order.market.id,
|
marketId: order.market.id,
|
||||||
price: removeDecimal(args.price, order.market.decimalPlaces),
|
price: removeDecimal(args.price, order.market.decimalPlaces),
|
||||||
timeInForce: order.timeInForce,
|
timeInForce: order.timeInForce,
|
||||||
sizeDelta: 0,
|
sizeDelta: args.size
|
||||||
|
? new BigNumber(
|
||||||
|
removeDecimal(args.size, order.market.positionDecimalPlaces)
|
||||||
|
)
|
||||||
|
.minus(order.size)
|
||||||
|
.toNumber()
|
||||||
|
: 0,
|
||||||
expiresAt: order.expiresAt
|
expiresAt: order.expiresAt
|
||||||
? toNanoSeconds(order.expiresAt) // Wallet expects timestamp in nanoseconds
|
? toNanoSeconds(order.expiresAt) // Wallet expects timestamp in nanoseconds
|
||||||
: undefined,
|
: undefined,
|
||||||
|
Loading…
Reference in New Issue
Block a user