chore: update account, fills and orders subscriptions in data providers

This commit is contained in:
Bartłomiej Głownia 2022-09-13 20:37:10 +02:00
parent 7cbca79146
commit ab20c2314f
10 changed files with 136 additions and 166 deletions

View File

@ -14,6 +14,10 @@ export const generateOrder = (
const order: Orders_party_ordersConnection_edges_node = {
__typename: 'Order',
id: 'order-id2',
market: {
__typename: 'Market',
id: 'market-id',
},
size: '10',
type: OrderType.TYPE_MARKET,
status: OrderStatus.STATUS_ACTIVE,
@ -49,6 +53,10 @@ export const generateMockOrders =
return [
generateOrder({
id: '066468C06549101DAF7BC51099E1412A0067DC08C246B7D8013C9D0CBF1E8EE7',
market: {
__typename: 'Market',
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
},
size: '10',
type: OrderType.TYPE_LIMIT,
status: OrderStatus.STATUS_FILLED,
@ -60,6 +68,10 @@ export const generateMockOrders =
}),
generateOrder({
id: '48DB6767E4E4E0F649C5A13ABFADE39F8451C27DA828DAF14B7A1E8E5EBDAD99',
market: {
__typename: 'Market',
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
},
size: '1',
type: OrderType.TYPE_LIMIT,
status: OrderStatus.STATUS_FILLED,
@ -71,6 +83,10 @@ export const generateMockOrders =
}),
generateOrder({
id: '4e93702990712c41f6995fcbbd94f60bb372ad12d64dfa7d96d205c49f790336',
market: {
__typename: 'Market',
id: 'c6f4337b31ed57a961969c3ba10297b369d01b9e75a4cbb96db4fc62886444e6',
},
size: '1',
type: OrderType.TYPE_LIMIT,
status: OrderStatus.STATUS_FILLED,

View File

@ -1,126 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
import { OrderType, Side, OrderStatus, OrderRejectionReason, OrderTimeInForce } from "@vegaprotocol/types";
// ====================================================
// GraphQL fragment: OrderFields
// ====================================================
export interface OrderFields_market_tradableInstrument_instrument {
__typename: "Instrument";
/**
* Uniquely identify an instrument across all instruments available on Vega (string)
*/
id: string;
/**
* A short non necessarily unique code used to easily describe the instrument (e.g: FX:BTCUSD/DEC18) (string)
*/
code: string;
/**
* Full and fairly descriptive name for the instrument
*/
name: string;
}
export interface OrderFields_market_tradableInstrument {
__typename: "TradableInstrument";
/**
* An instance of, or reference to, a fully specified instrument.
*/
instrument: OrderFields_market_tradableInstrument_instrument;
}
export interface OrderFields_market {
__typename: "Market";
/**
* Market ID
*/
id: string;
/**
* decimalPlaces indicates the number of decimal places that an integer must be shifted by in order to get a correct
* number denominated in the currency of the market. (uint64)
*
* Examples:
* Currency Balance decimalPlaces Real Balance
* GBP 100 0 GBP 100
* GBP 100 2 GBP 1.00
* GBP 100 4 GBP 0.01
* GBP 1 4 GBP 0.0001 ( 0.01p )
*
* GBX (pence) 100 0 GBP 1.00 (100p )
* GBX (pence) 100 2 GBP 0.01 ( 1p )
* GBX (pence) 100 4 GBP 0.0001 ( 0.01p )
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/
decimalPlaces: number;
/**
* positionDecimalPlaces indicates the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
* This sets how big the smallest order / position on the market can be.
*/
positionDecimalPlaces: number;
/**
* An instance of, or reference to, a tradable instrument.
*/
tradableInstrument: OrderFields_market_tradableInstrument;
}
export interface OrderFields {
__typename: "Order";
/**
* Hash of the order data
*/
id: string;
/**
* The market the order is trading on (probably stored internally as a hash of the market details)
*/
market: OrderFields_market;
/**
* Type the order type (defaults to PARTY)
*/
type: OrderType | null;
/**
* Whether the order is to buy or sell
*/
side: Side;
/**
* Total number of contracts that may be bought or sold (immutable) (uint64)
*/
size: string;
/**
* The status of an order, for example 'Active'
*/
status: OrderStatus;
/**
* Reason for the order to be rejected
*/
rejectionReason: OrderRejectionReason | null;
/**
* The worst price the order will trade at (e.g. buy for price or less, sell for price or more) (uint64)
*/
price: string;
/**
* The timeInForce of order (determines how and if it executes, and whether it persists on the book)
*/
timeInForce: OrderTimeInForce;
/**
* Number of contracts remaining of the total that have not yet been bought or sold (uint64)
*/
remaining: string;
/**
* Expiration time of this order (ISO-8601 RFC3339+Nano formatted date)
*/
expiresAt: string | null;
/**
* RFC3339Nano formatted date and time for when the order was created (timestamp)
*/
createdAt: string;
/**
* RFC3339Nano time the order was altered
*/
updatedAt: string | null;
}

View File

@ -9,12 +9,24 @@ import { Pagination, OrderType, Side, OrderStatus, OrderRejectionReason, OrderTi
// GraphQL query operation: Orders
// ====================================================
export interface Orders_party_ordersConnection_edges_node_market {
__typename: "Market";
/**
* Market ID
*/
id: string;
}
export interface Orders_party_ordersConnection_edges_node {
__typename: "Order";
/**
* Hash of the order data
*/
id: string;
id: string;
/**
* The market the order is trading on (probably stored internally as a hash of the market details)
*/
market: Orders_party_ordersConnection_edges_node_market;
/**
* The order type
*/

View File

@ -1,4 +1,3 @@
export * from './__generated__/OrderFields';
export * from './__generated__/OrderSub';
export * from './__generated__/Orders';
export * from './order-data-provider';

View File

@ -22,6 +22,9 @@ export const ORDERS_QUERY = gql`
edges {
node {
id
market {
id
}
type
side
size
@ -91,9 +94,14 @@ export const update = (
draft.unshift(...draft.splice(index, 1));
}
} else if (newer) {
const { marketId, ...order } = node;
draft.unshift({
node: {
...node,
...order,
market: {
__typename: 'Market',
id: marketId,
},
__typename: 'Order',
},
cursor: '',

View File

@ -7,8 +7,9 @@ import { useCallback, useMemo, useRef } from 'react';
import type { BodyScrollEvent, BodyScrollEndEvent } from 'ag-grid-community';
import type { AgGridReact } from 'ag-grid-react';
import { marketsProvider } from '@vegaprotocol/market-list';
import { OrderList, ordersDataProvider as dataProvider } from '../';
import type { OrderFields, Orders_party_ordersConnection_edges } from '../';
import type { Orders_party_ordersConnection_edges, OrderSub_orders } from '../';
interface OrderListManagerProps {
partyId: string;
@ -44,7 +45,7 @@ export const OrderListManager = ({ partyId }: OrderListManagerProps) => {
delta,
}: {
data: (Orders_party_ordersConnection_edges | null)[];
delta: OrderFields[];
delta: OrderSub_orders[];
}) => {
if (!gridRef.current?.api) {
return false;
@ -79,6 +80,14 @@ export const OrderListManager = ({ partyId }: OrderListManagerProps) => {
[]
);
const {
data: markets,
error: marketsError,
loading: marketsLoading,
} = useDataProvider({
dataProvider: marketsProvider,
});
const { data, error, loading, load, totalCount } = useDataProvider({
dataProvider,
update,
@ -107,14 +116,21 @@ export const OrderListManager = ({ partyId }: OrderListManagerProps) => {
};
return (
<AsyncRenderer loading={loading} error={error} data={data}>
<OrderList
ref={gridRef}
rowModelType="infinite"
datasource={{ getRows }}
onBodyScrollEnd={onBodyScrollEnd}
onBodyScroll={onBodyScroll}
/>
<AsyncRenderer
loading={loading || marketsLoading}
error={error || marketsError}
data={data && markets}
>
{markets && (
<OrderList
ref={gridRef}
markets={markets}
rowModelType="infinite"
datasource={{ getRows }}
onBodyScrollEnd={onBodyScrollEnd}
onBodyScroll={onBodyScroll}
/>
)}
</AsyncRenderer>
);
};

View File

@ -14,15 +14,17 @@ import {
Dialog,
Icon,
} from '@vegaprotocol/ui-toolkit';
import type { Market } from '@vegaprotocol/market-list';
import { OrderTimeInForce } from '@vegaprotocol/types';
import { useForm } from 'react-hook-form';
import type { OrderFields } from '../order-data-provider';
import type { Orders_party_ordersConnection_edges_node } from '../order-data-provider';
interface OrderEditDialogProps {
isOpen: boolean;
onChange: (isOpen: boolean) => void;
order: OrderFields;
order: Orders_party_ordersConnection_edges_node;
onSubmit: (fields: FormFields) => void;
market: Market;
}
interface FormFields {
@ -34,6 +36,7 @@ export const OrderEditDialog = ({
onChange,
order,
onSubmit,
market,
}: OrderEditDialogProps) => {
const headerClassName = 'text-lg font-bold text-black dark:text-white';
const {
@ -42,7 +45,7 @@ export const OrderEditDialog = ({
handleSubmit,
} = useForm<FormFields>();
const step = toDecimal(order.market?.decimalPlaces ?? 0);
const step = toDecimal(market.decimalPlaces);
return (
<Dialog
@ -55,15 +58,13 @@ export const OrderEditDialog = ({
{order.market && (
<div>
<p className={headerClassName}>{t(`Market`)}</p>
<p>{t(`${order.market.tradableInstrument.instrument.name}`)}</p>
<p>{t(`${market.tradableInstrument.instrument.name}`)}</p>
</div>
)}
{order.type === OrderType.TYPE_LIMIT && order.market && (
<div>
<p className={headerClassName}>{t(`Current price`)}</p>
<p>
{addDecimalsFormatNumber(order.price, order.market.decimalPlaces)}
</p>
<p>{addDecimalsFormatNumber(order.price, market.decimalPlaces)}</p>
</div>
)}
<div>
@ -73,7 +74,7 @@ export const OrderEditDialog = ({
<Size
value={order.size}
side={order.side}
positionDecimalPlaces={order.market.positionDecimalPlaces}
positionDecimalPlaces={market.positionDecimalPlaces}
/>
}
</p>

View File

@ -3,21 +3,37 @@ import { OrderList, OrderListTable } from './order-list';
import { useState } from 'react';
import type { VegaTxState } from '@vegaprotocol/wallet';
import { VegaTransactionDialog, VegaTxStatus } from '@vegaprotocol/wallet';
import type { Market } from '@vegaprotocol/market-list';
import { generateOrdersArray } from '../mocks';
import { OrderEditDialog } from './order-edit-dialog';
import type { OrderFields } from '../order-data-provider';
import type { Orders_party_ordersConnection_edges_node } from '../order-data-provider';
export default {
component: OrderList,
title: 'OrderList',
} as Meta;
const generateMatchingMarkets = (
orders: Orders_party_ordersConnection_edges_node[]
) =>
orders.map(
(order) =>
({
id: order.market.id,
decimalPlaces: 5,
positionDecimalPlaces: 0,
} as Market)
);
const Template: Story = (args) => {
const cancel = () => Promise.resolve();
return (
<div style={{ height: 1000 }}>
<OrderListTable
rowData={args.data}
markets={generateMatchingMarkets(
args.data as Orders_party_ordersConnection_edges_node[]
)}
cancel={cancel}
setEditOrder={() => {
return;
@ -29,7 +45,8 @@ const Template: Story = (args) => {
const Template2: Story = (args) => {
const [open, setOpen] = useState(false);
const [editOrder, setEditOrder] = useState<OrderFields>();
const [editOrder, setEditOrder] =
useState<Orders_party_ordersConnection_edges_node>();
const cancel = () => {
setOpen(!open);
return Promise.resolve();
@ -46,6 +63,9 @@ const Template2: Story = (args) => {
<div style={{ height: 1000 }}>
<OrderListTable
rowData={args.data}
markets={generateMatchingMarkets(
args.data as Orders_party_ordersConnection_edges_node[]
)}
cancel={cancel}
setEditOrder={(order) => {
setEditOrder(order);
@ -59,6 +79,7 @@ const Template2: Story = (args) => {
/>
{editOrder && (
<OrderEditDialog
market={generateMatchingMarkets([editOrder])[0]}
isOpen={Boolean(editOrder)}
onChange={(isOpen) => {
if (!isOpen) setEditOrder(undefined);

View File

@ -29,6 +29,7 @@ import type {
AgGridReactProps,
AgReactUiProps,
} from 'ag-grid-react';
import type { Market } from '@vegaprotocol/market-list';
import { AgGridColumn } from 'ag-grid-react';
import { forwardRef, useState } from 'react';
import type { Orders_party_ordersConnection_edges_node } from '../';
@ -37,16 +38,22 @@ import BigNumber from 'bignumber.js';
import { useOrderCancel } from '../../order-hooks/use-order-cancel';
import { useOrderEdit } from '../../order-hooks/use-order-edit';
import { OrderEditDialog } from './order-edit-dialog';
import type { OrderFields } from '../';
import { OrderFeedback } from '../order-feedback';
type OrderListProps = AgGridReactProps | AgReactUiProps;
type OrderListProps = (AgGridReactProps | AgReactUiProps) & {
markets: Market[];
};
export const OrderList = forwardRef<AgGridReact, OrderListProps>(
(props, ref) => {
const [editOrder, setEditOrder] = useState<OrderFields | null>(null);
const [editOrder, setEditOrder] =
useState<Orders_party_ordersConnection_edges_node | null>(null);
const orderCancel = useOrderCancel();
const orderEdit = useOrderEdit(editOrder);
const market: Market | null =
(editOrder &&
props.markets.find((market) => market.id === editOrder.market.id)) ||
null;
const orderEdit = useOrderEdit(editOrder, market);
return (
<>
@ -79,8 +86,9 @@ export const OrderList = forwardRef<AgGridReact, OrderListProps>(
order={orderEdit.updatedOrder}
/>
</orderEdit.Dialog>
{editOrder && (
{editOrder && market && (
<OrderEditDialog
market={market}
isOpen={Boolean(editOrder)}
onChange={(isOpen) => {
if (!isOpen) setEditOrder(null);
@ -104,13 +112,13 @@ type OrderListTableValueFormatterParams = Omit<
data: Orders_party_ordersConnection_edges_node | null;
};
type OrderListTableProps = (AgGridReactProps | AgReactUiProps) & {
cancel: (order: OrderFields) => void;
setEditOrder: (order: OrderFields) => void;
type OrderListTableProps = OrderListProps & {
cancel: (order: Orders_party_ordersConnection_edges_node) => void;
setEditOrder: (order: Orders_party_ordersConnection_edges_node) => void;
};
export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
({ cancel, setEditOrder, ...props }, ref) => {
({ cancel, setEditOrder, markets, ...props }, ref) => {
return (
<AgGrid
ref={ref}
@ -157,7 +165,12 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
: '-'
: '';
return (
prefix + addDecimal(value, data.market.positionDecimalPlaces)
prefix +
addDecimal(
value,
markets.find((market) => market.id === data.market.id)
?.positionDecimalPlaces ?? 0
)
);
}}
/>
@ -203,7 +216,9 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
if (value === undefined || !data || !data.market) {
return undefined;
}
const dps = data.market.positionDecimalPlaces;
const dps =
markets.find((market) => market.id === data.market.id)
?.positionDecimalPlaces ?? 0;
const size = new BigNumber(data.size);
const remaining = new BigNumber(value);
const fills = size.minus(remaining);
@ -231,7 +246,11 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
) {
return '-';
}
return addDecimal(value, data.market.decimalPlaces);
return addDecimal(
value,
markets.find((market) => market.id === data.market.id)
?.decimalPlaces ?? 0
);
}}
/>
<AgGridColumn

View File

@ -1,9 +1,10 @@
import { removeDecimal, toNanoSeconds } from '@vegaprotocol/react-helpers';
import { useState, useCallback } from 'react';
import { useVegaTransaction, useVegaWallet } from '@vegaprotocol/wallet';
import type { Market } from '@vegaprotocol/market-list';
import type { OrderEvent_busEvents_event_Order } from './';
import * as Sentry from '@sentry/react';
import type { OrderFields } from '../components';
import type { Orders_party_ordersConnection_edges_node } from '../components';
import { useOrderEvent } from './use-order-event';
// Can only edit price for now
@ -11,7 +12,10 @@ export interface EditOrderArgs {
price: string;
}
export const useOrderEdit = (order: OrderFields | null) => {
export const useOrderEdit = (
order: Orders_party_ordersConnection_edges_node | null,
market: Market | null
) => {
const { keypair } = useVegaWallet();
const [updatedOrder, setUpdatedOrder] =
@ -34,7 +38,7 @@ export const useOrderEdit = (order: OrderFields | null) => {
const edit = useCallback(
async (args: EditOrderArgs) => {
if (!keypair || !order || !order.market) {
if (!keypair || !order || !market) {
return;
}
@ -47,7 +51,7 @@ export const useOrderEdit = (order: OrderFields | null) => {
orderAmendment: {
orderId: order.id,
marketId: order.market.id,
price: removeDecimal(args.price, order.market.decimalPlaces),
price: removeDecimal(args.price, market.decimalPlaces),
timeInForce: order.timeInForce,
sizeDelta: 0,
expiresAt: order.expiresAt
@ -65,7 +69,7 @@ export const useOrderEdit = (order: OrderFields | null) => {
return;
}
},
[keypair, send, order, setComplete, waitForOrderEvent]
[keypair, send, order, market, setComplete, waitForOrderEvent]
);
return {