From 8b2ec489d827cd89aefbbf58c62319c1b8b44431 Mon Sep 17 00:00:00 2001
From: Matthew Russell
Date: Tue, 19 Jul 2022 01:37:07 +0100
Subject: [PATCH] feat: improve types for order transactions and dialogs
---
.../src/components/deal-ticket-amount.tsx | 4 +-
.../src/components/deal-ticket-manager.tsx | 151 ++++++--
.../src/components/deal-ticket.tsx | 10 +-
.../order-list/order-edit-dialog.tsx | 24 +-
.../order-list/order-list.stories.tsx | 26 +-
.../lib/components/order-list/order-list.tsx | 153 +++++----
libs/orders/src/lib/index.ts | 1 -
libs/orders/src/lib/market.ts | 13 -
.../src/lib/order-hooks/use-order-cancel.tsx | 37 +-
.../src/lib/order-hooks/use-order-edit.tsx | 30 +-
.../src/lib/order-hooks/use-order-submit.ts | 56 +--
.../lib/order-hooks/use-order-validation.tsx | 17 +-
.../orders/src/lib/utils/get-default-order.ts | 33 +-
libs/wallet/src/use-vega-transaction.ts | 9 +-
.../vega-transaction-dialog.tsx | 321 ++++++------------
libs/wallet/src/wallet-types.ts | 13 -
libs/withdraws/src/lib/withdraw-dialog.tsx | 6 +
17 files changed, 438 insertions(+), 466 deletions(-)
delete mode 100644 libs/orders/src/lib/market.ts
diff --git a/libs/deal-ticket/src/components/deal-ticket-amount.tsx b/libs/deal-ticket/src/components/deal-ticket-amount.tsx
index 000153aea..b86bb3a96 100644
--- a/libs/deal-ticket/src/components/deal-ticket-amount.tsx
+++ b/libs/deal-ticket/src/components/deal-ticket-amount.tsx
@@ -1,13 +1,13 @@
import type { UseFormRegister } from 'react-hook-form';
import { VegaWalletOrderType } from '@vegaprotocol/wallet';
-import type { Order } from '@vegaprotocol/orders';
import { DealTicketMarketAmount } from './deal-ticket-market-amount';
import { DealTicketLimitAmount } from './deal-ticket-limit-amount';
+import type { OrderSubmitInput } from '@vegaprotocol/orders';
export interface DealTicketAmountProps {
orderType: VegaWalletOrderType;
step: number;
- register: UseFormRegister;
+ register: UseFormRegister;
quoteName: string;
price?: string;
}
diff --git a/libs/deal-ticket/src/components/deal-ticket-manager.tsx b/libs/deal-ticket/src/components/deal-ticket-manager.tsx
index b202f6c6f..8497ce4d5 100644
--- a/libs/deal-ticket/src/components/deal-ticket-manager.tsx
+++ b/libs/deal-ticket/src/components/deal-ticket-manager.tsx
@@ -1,10 +1,16 @@
import type { ReactNode } from 'react';
+import { useEffect } from 'react';
import { useState } from 'react';
+import type { VegaTxState } from '@vegaprotocol/wallet';
import { VegaTransactionDialog, VegaTxStatus } from '@vegaprotocol/wallet';
import { DealTicket } from './deal-ticket';
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
+import type { OrderEvent_busEvents_event_Order } from '@vegaprotocol/orders';
import { useOrderSubmit } from '@vegaprotocol/orders';
-import { OrderStatus } from '@vegaprotocol/types';
+import { OrderStatus, OrderType } from '@vegaprotocol/types';
+import { Icon, Intent } from '@vegaprotocol/ui-toolkit';
+import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
+import { useEnvironment } from '@vegaprotocol/environment';
export interface DealTicketManagerProps {
market: DealTicketQuery_market;
@@ -17,26 +23,41 @@ export const DealTicketManager = ({
}: DealTicketManagerProps) => {
const [orderDialogOpen, setOrderDialogOpen] = useState(false);
const { submit, transaction, finalizedOrder, reset } = useOrderSubmit(market);
- const getDialogTitle = (status?: string) => {
- switch (status) {
- case OrderStatus.Active:
- return 'Order submitted';
- case OrderStatus.Filled:
- return 'Order filled';
- case OrderStatus.PartiallyFilled:
- return 'Order partially filled';
- case OrderStatus.Parked:
- return 'Order parked';
- default:
- return 'Submission failed';
+
+ let title;
+ let intent;
+ let icon;
+ let dialogContent;
+
+ if (finalizedOrder) {
+ title = getDialogTitle(finalizedOrder);
+
+ if (finalizedOrder.status === OrderStatus.Rejected) {
+ icon = ;
+ intent = Intent.Danger;
+ dialogContent = (
+
+ {t(`Reason: ${finalizedOrder.rejectionReason}`)}
+
+ );
}
- };
+
+ icon = ;
+ intent = Intent.Success;
+ dialogContent = (
+
+ );
+ }
+
return (
<>
{children || (
{
+ setOrderDialogOpen(true);
+ submit(order);
+ }}
transactionStatus={
transaction.status === VegaTxStatus.Requested ||
transaction.status === VegaTxStatus.Pending
@@ -45,15 +66,101 @@ export const DealTicketManager = ({
}
/>
)}
+
{
+ setOrderDialogOpen(isOpen);
+ if (!isOpen) {
+ reset();
+ }
+ }}
transaction={transaction}
- reset={reset}
- title={getDialogTitle(finalizedOrder?.status)}
- />
+ intent={intent}
+ title={title}
+ icon={icon}
+ >
+ {dialogContent}
+
+ >
+ );
+};
+
+const getDialogTitle = (finalizedOrder: OrderEvent_busEvents_event_Order) => {
+ switch (finalizedOrder.status) {
+ case OrderStatus.Active:
+ return 'Order submitted';
+ case OrderStatus.Filled:
+ return 'Order filled';
+ case OrderStatus.PartiallyFilled:
+ return 'Order partially filled';
+ case OrderStatus.Parked:
+ return 'Order parked';
+ default:
+ return undefined;
+ }
+};
+
+interface OrderSuccessContentProps {
+ order: OrderEvent_busEvents_event_Order;
+ transaction: VegaTxState;
+}
+
+const OrderSuccessContent = ({
+ order,
+ transaction,
+}: OrderSuccessContentProps) => {
+ const headerClassName = 'text-h5 font-bold text-black dark:text-white';
+ const { VEGA_EXPLORER_URL } = useEnvironment();
+ return (
+ <>
+
+ {order.market && (
+
+
{t(`Market`)}
+
{t(`${order.market.name}`)}
+
+ )}
+
+
{t(`Status`)}
+
{t(`${order.status}`)}
+
+ {order.type === OrderType.Limit && order.market && (
+
+
{t(`Price`)}
+
+ {addDecimalsFormatNumber(order.price, order.market.decimalPlaces)}
+
+
+ )}
+
+
{t(`Amount`)}
+
+ {`${order.side === 'Buy' ? '+' : '-'} ${order.size}
+ `}
+
+
+
+
+ {transaction.txHash && (
+
+ )}
+
>
);
};
diff --git a/libs/deal-ticket/src/components/deal-ticket.tsx b/libs/deal-ticket/src/components/deal-ticket.tsx
index 4e3d3d4ee..b3324b509 100644
--- a/libs/deal-ticket/src/components/deal-ticket.tsx
+++ b/libs/deal-ticket/src/components/deal-ticket.tsx
@@ -16,16 +16,16 @@ import { DealTicketAmount } from './deal-ticket-amount';
import { TimeInForceSelector } from './time-in-force-selector';
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
import { ExpirySelector } from './expiry-selector';
-import type { Order } from '@vegaprotocol/orders';
+import type { OrderSubmitInput } from '@vegaprotocol/orders';
import { getDefaultOrder, useOrderValidation } from '@vegaprotocol/orders';
export type TransactionStatus = 'default' | 'pending';
export interface DealTicketProps {
market: DealTicketQuery_market;
- submit: (order: Order) => void;
+ submit: (order: OrderSubmitInput) => void;
transactionStatus: TransactionStatus;
- defaultOrder?: Order;
+ defaultOrder?: OrderSubmitInput;
}
export const DealTicket = ({
@@ -39,7 +39,7 @@ export const DealTicket = ({
handleSubmit,
watch,
formState: { errors },
- } = useForm({
+ } = useForm({
mode: 'onChange',
defaultValues: getDefaultOrder(market),
});
@@ -57,7 +57,7 @@ export const DealTicket = ({
const isDisabled = transactionStatus === 'pending' || disabled;
const onSubmit = useCallback(
- (order: Order) => {
+ (order: OrderSubmitInput) => {
if (!isDisabled) {
submit(order);
}
diff --git a/libs/orders/src/lib/components/order-list/order-edit-dialog.tsx b/libs/orders/src/lib/components/order-list/order-edit-dialog.tsx
index 94bf5fd76..0a7c1d6a2 100644
--- a/libs/orders/src/lib/components/order-list/order-edit-dialog.tsx
+++ b/libs/orders/src/lib/components/order-list/order-edit-dialog.tsx
@@ -6,25 +6,18 @@ import {
import { OrderType } from '@vegaprotocol/types';
import { FormGroup, Input, InputError, Button } from '@vegaprotocol/ui-toolkit';
import { useForm } from 'react-hook-form';
-import Icon from 'react-syntax-highlighter';
-import { OrderDialogWrapper } from '@vegaprotocol/wallet';
-import type { Order } from '@vegaprotocol/wallet';
+import type { Orders_party_orders } from '../__generated__';
interface OrderEditDialogProps {
- title: string;
- order: Order | null;
- edit: (body: Order) => Promise;
+ order: Orders_party_orders;
+ onSubmit: (order: Orders_party_orders) => void;
}
interface FormFields {
entryPrice: string;
}
-export const OrderEditDialog = ({
- order,
- title,
- edit,
-}: OrderEditDialogProps) => {
+export const OrderEditDialog = ({ order, onSubmit }: OrderEditDialogProps) => {
const headerClassName = 'text-h5 font-bold text-black dark:text-white';
const {
register,
@@ -39,7 +32,7 @@ export const OrderEditDialog = ({
});
if (!order) return null;
return (
- }>
+
{order.market && (
@@ -69,11 +62,10 @@ export const OrderEditDialog = ({
-
-
+
);
};
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 8fbc6ad10..0cd9cecaa 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
@@ -1,8 +1,7 @@
import type { Story, Meta } from '@storybook/react';
-import { OrderType, OrderStatus, OrderTimeInForce } from '@vegaprotocol/types';
import { OrderList, OrderListTable } from './order-list';
import { useState } from 'react';
-import type { Order, VegaTxState } from '@vegaprotocol/wallet';
+import type { VegaTxState } from '@vegaprotocol/wallet';
import { VegaTransactionDialog, VegaTxStatus } from '@vegaprotocol/wallet';
import { generateOrdersArray } from '../mocks';
@@ -18,9 +17,6 @@ const Template: Story = (args) => {
{
- return;
- }}
setEditOrder={() => {
return;
}}
@@ -41,36 +37,22 @@ const Template2: Story = (args) => {
txHash: null,
signature: null,
};
- const finalizedOrder: Order = {
- status: OrderStatus.Cancelled,
- rejectionReason: null,
- size: '10',
- price: '1000',
- market: { name: 'ETH/DAI (30 Jun 2022)', decimalPlaces: 5 },
- type: OrderType.Limit,
- timeInForce: OrderTimeInForce.GTC,
- };
- const reset = () => null;
+
return (
<>
{
- return;
- }}
setEditOrder={() => {
return;
}}
/>
>
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 2593872ec..e8fd87be6 100644
--- a/libs/orders/src/lib/components/order-list/order-list.tsx
+++ b/libs/orders/src/lib/components/order-list/order-list.tsx
@@ -5,99 +5,98 @@ import {
getDateTimeFormat,
t,
} from '@vegaprotocol/react-helpers';
-import { AgGridDynamic as AgGrid, Button } from '@vegaprotocol/ui-toolkit';
+import {
+ AgGridDynamic as AgGrid,
+ Button,
+ Dialog,
+} from '@vegaprotocol/ui-toolkit';
import type {
ICellRendererParams,
ValueFormatterParams,
} from 'ag-grid-community';
-import type {
- AgGridReact,
- AgGridReactProps,
- AgReactUiProps,
-} from 'ag-grid-react';
+import type { AgGridReact } 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 type { OrderCancelInput } from '../../order-hooks/use-order-cancel';
import { useOrderCancel } from '../../order-hooks/use-order-cancel';
import { VegaTransactionDialog } from '@vegaprotocol/wallet';
import { useOrderEdit } from '../../order-hooks/use-order-edit';
import { OrderEditDialog } from './order-edit-dialog';
-type OrderListProps = AgGridReactProps | AgReactUiProps;
+interface OrderListProps {
+ data: Orders_party_ordersConnection_edges_node[] | null;
+}
export const OrderList = forwardRef(
- (props, ref) => {
+ ({ data }, ref) => {
+ // Cancel transaction dialog
const [cancelOrderDialogOpen, setCancelOrderDialogOpen] = useState(false);
+ // Edit order transaction dialog
const [editOrderDialogOpen, setEditOrderDialogOpen] = useState(false);
+ // Order for edit order dialog
const [editOrder, setEditOrder] =
useState(null);
-
- const { transaction, updatedOrder, reset, cancel } = useOrderCancel();
+ const { transaction, reset, cancel } = useOrderCancel();
const {
transaction: editTransaction,
- updatedOrder: editedOrder,
reset: resetEdit,
edit,
} = useOrderEdit();
- const getCancelDialogTitle = (status?: string) => {
- switch (status) {
- case OrderStatus.Cancelled:
- return 'Order cancelled';
- case OrderStatus.Rejected:
- return 'Order rejected';
- case OrderStatus.Expired:
- return 'Order expired';
- default:
- return 'Cancellation failed';
- }
- };
- const getEditDialogTitle = () =>
- editedOrder
- ? t(
- `Order ${
- editOrder?.market?.tradableInstrument.instrument.code ?? ''
- } updated`
- )
- : t(
- `Edit ${
- editOrder?.market?.tradableInstrument.instrument.code ?? ''
- } order`
- );
+ // const getEditDialogTitle = () =>
+ // editedOrder
+ // ? t(
+ // `Order ${
+ // editOrder?.market?.tradableInstrument.instrument.code ?? ''
+ // } updated`
+ // )
+ // : t(
+ // `Edit ${
+ // editOrder?.market?.tradableInstrument.instrument.code ?? ''
+ // } order`
+ // );
return (
<>
{
+ setCancelOrderDialogOpen(true);
+ cancel(order);
+ }}
ref={ref}
- setEditOrderDialogOpen={setEditOrderDialogOpen}
setEditOrder={setEditOrder}
/>
{
+ setCancelOrderDialogOpen(isOpen);
+ if (!isOpen) {
+ reset();
+ }
+ }}
transaction={transaction}
- reset={reset}
- title={getCancelDialogTitle(updatedOrder?.status)}
- finalizedOrder={updatedOrder}
/>
{
+ setEditOrderDialogOpen(isOpen);
+ if (!isOpen) {
+ resetEdit();
+ }
+ }}
transaction={editTransaction}
- reset={resetEdit}
- title={getEditDialogTitle()}
- finalizedOrder={editedOrder}
- >
-
-
+ />
+ {
+ setEditOrder(null);
+ setEditOrderDialogOpen(true);
+ // @ts-ignore fix me, market is null
+ edit(order);
+ }}
+ />
>
);
}
@@ -109,17 +108,16 @@ type OrderListTableValueFormatterParams = Omit<
> & {
data: Orders_party_ordersConnection_edges_node | null;
};
-
-type OrderListTableProps = (AgGridReactProps | AgReactUiProps) & {
- cancel: (body?: unknown) => Promise;
- setEditOrderDialogOpen: (value: boolean) => void;
+interface OrderListTableProps {
+ data: Orders_party_ordersConnection_edges_node[] | null;
+ cancel: (order: OrderCancelInput) => void;
setEditOrder: (
order: Orders_party_ordersConnection_edges_node | null
) => void;
-};
+}
export const OrderListTable = forwardRef(
- ({ cancel, setEditOrderDialogOpen, setEditOrder, ...props }, ref) => {
+ ({ data, cancel, setEditOrder }, ref) => {
return (
(
style={{ width: '100%', height: '100%' }}
getRowId={({ data }) => data.id}
rowHeight={40}
- {...props}
>
(
data-testid="edit"
variant="secondary"
onClick={() => {
- setEditOrderDialogOpen(true);
setEditOrder(data);
}}
>
@@ -301,7 +297,10 @@ export const OrderListTable = forwardRef(
+ ),
+ };
+ default:
+ return {
+ title: '',
+ icon: null,
+ intent: undefined,
+ content: null,
+ };
+ }
};
diff --git a/libs/wallet/src/wallet-types.ts b/libs/wallet/src/wallet-types.ts
index 480e1eb4b..42d9e85ab 100644
--- a/libs/wallet/src/wallet-types.ts
+++ b/libs/wallet/src/wallet-types.ts
@@ -44,16 +44,3 @@ export interface Market {
decimalPlaces: number;
id?: string;
}
-
-export interface Order {
- id?: string;
- status?: string;
- rejectionReason?: string | null;
- size: string;
- price: string;
- market: Market | null;
- type: string | null;
- side?: string;
- timeInForce: OrderTimeInForce;
- expiresAt?: Date | string | null;
-}
diff --git a/libs/withdraws/src/lib/withdraw-dialog.tsx b/libs/withdraws/src/lib/withdraw-dialog.tsx
index 4f3f5b16a..108eac341 100644
--- a/libs/withdraws/src/lib/withdraw-dialog.tsx
+++ b/libs/withdraws/src/lib/withdraw-dialog.tsx
@@ -117,6 +117,12 @@ const getProps = (
intent: Intent.None,
children: Awaiting transaction,
},
+ [VegaTxStatus.Complete]: {
+ title: t('Withdrawal successful'),
+ icon: 'tick',
+ intent: Intent.Success,
+ children: Withdrawal has completed,
+ },
};
const ethTxPropsMap: Record = {