Add open orders page
This commit is contained in:
parent
b3501b26cc
commit
b48fe02510
|
@ -135,7 +135,8 @@ export default function TopBar() {
|
|||
}}
|
||||
>
|
||||
<Menu.Item key="/">TRADE</Menu.Item>
|
||||
<Menu.Item key="/balances">BALANCES</Menu.Item>
|
||||
{connected && <Menu.Item key="/balances">BALANCES</Menu.Item>}
|
||||
{connected && <Menu.Item key="/orders">ORDERS</Menu.Item>}
|
||||
<Menu.SubMenu title="LEARN" onTitleClick={() => window.open(EXTERNAL_LINKS['/learn'], '_blank')}>
|
||||
<Menu.Item key="/add-market">
|
||||
<a href={EXTERNAL_LINKS['/add-market']} target="_blank" rel="noopener noreferrer">
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, {useState} from 'react';
|
||||
import DataTable from '../layout/DataTable';
|
||||
|
||||
import styled from 'styled-components';
|
||||
import { Button, Row, Col, Tag } from 'antd';
|
||||
import { cancelOrder } from '../../utils/send';
|
||||
import { useWallet } from '../../utils/wallet';
|
||||
import { useSendConnection } from '../../utils/connection';
|
||||
import { notify } from '../../utils/notifications';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import {Button, Col, Row, Tag} from 'antd';
|
||||
import {cancelOrder} from '../../utils/send';
|
||||
import {useWallet} from '../../utils/wallet';
|
||||
import {useSendConnection} from '../../utils/connection';
|
||||
import {notify} from '../../utils/notifications';
|
||||
import {DeleteOutlined} from '@ant-design/icons';
|
||||
import {OrderWithMarketAndMarketName} from "../../utils/types";
|
||||
|
||||
const CancelButton = styled(Button)`
|
||||
color: #f23b69;
|
||||
border: 1px solid #f23b69;
|
||||
`;
|
||||
|
||||
export default function OpenOrderTable({ openOrders, onCancelSuccess }) {
|
||||
export default function OpenOrderTable({ openOrders, onCancelSuccess, pageSize, loading, marketFilter } : {
|
||||
openOrders: OrderWithMarketAndMarketName[] | null | undefined;
|
||||
onCancelSuccess?: () => void;
|
||||
pageSize?: number;
|
||||
loading?: boolean;
|
||||
marketFilter?: boolean;
|
||||
}) {
|
||||
let { wallet } = useWallet();
|
||||
let connection = useSendConnection();
|
||||
|
||||
|
@ -42,11 +49,17 @@ export default function OpenOrderTable({ openOrders, onCancelSuccess }) {
|
|||
onCancelSuccess && onCancelSuccess();
|
||||
}
|
||||
|
||||
const marketFilters = [
|
||||
...new Set((openOrders || []).map(orderInfos => orderInfos.marketName))
|
||||
].map(marketName => {return {text: marketName, value: marketName}});
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Market',
|
||||
dataIndex: 'marketName',
|
||||
key: 'marketName',
|
||||
filters: (marketFilter ? marketFilters : undefined),
|
||||
onFilter: (value, record) => record.marketName.indexOf(value) === 0,
|
||||
},
|
||||
{
|
||||
title: 'Side',
|
||||
|
@ -60,16 +73,27 @@ export default function OpenOrderTable({ openOrders, onCancelSuccess }) {
|
|||
{side.charAt(0).toUpperCase() + side.slice(1)}
|
||||
</Tag>
|
||||
),
|
||||
sorter: (a, b) => {
|
||||
if (a.side === b.side) {
|
||||
return 0.
|
||||
} else if (a.side === 'buy') {
|
||||
return 1.
|
||||
} else {
|
||||
return -1.
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Size',
|
||||
dataIndex: 'size',
|
||||
key: 'size',
|
||||
sorter: (a, b) => b.size - a.size,
|
||||
},
|
||||
{
|
||||
title: 'Price',
|
||||
dataIndex: 'price',
|
||||
key: 'price',
|
||||
sorter: (a, b) => b.price - a.price,
|
||||
},
|
||||
{
|
||||
key: 'orderId',
|
||||
|
@ -98,7 +122,8 @@ export default function OpenOrderTable({ openOrders, onCancelSuccess }) {
|
|||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
pagination={true}
|
||||
pageSize={5}
|
||||
pageSize={pageSize ? pageSize : 5}
|
||||
loading={loading !== undefined && loading}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
|
@ -1,10 +0,0 @@
|
|||
import React from 'react';
|
||||
import FloatingElement from '../components/layout/FloatingElement';
|
||||
|
||||
export default function OpenOrdersPage() {
|
||||
return (
|
||||
<FloatingElement style={{ flex: 1, paddingTop: 10 }}>
|
||||
{/*<OpenOrderTable openOrders={openOrders} />*/}
|
||||
</FloatingElement>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import React from 'react';
|
||||
import FloatingElement from '../components/layout/FloatingElement';
|
||||
import {getMarketInfos, useAllMarkets, useAllOpenOrders, useMarket} from "../utils/markets";
|
||||
import OpenOrderTable from "../components/UserInfoTable/OpenOrderTable";
|
||||
import {Button} from "antd";
|
||||
import {OrderWithMarketAndMarketName} from "../utils/types";
|
||||
|
||||
export default function OpenOrdersPage() {
|
||||
const {openOrders, loaded, refreshOpenOrders} = useAllOpenOrders();
|
||||
let {customMarkets} = useMarket();
|
||||
let marketInfos = getMarketInfos(customMarkets);
|
||||
let marketAddressesToNames = Object.fromEntries(marketInfos.map(info => [info.address.toBase58(), info.name]));
|
||||
let [allMarkets] = useAllMarkets(customMarkets);
|
||||
const marketsByAddress = Object.fromEntries((allMarkets || []).map(
|
||||
marketInfo => [marketInfo.market.address.toBase58(), marketInfo.market]
|
||||
));
|
||||
|
||||
const dataSource: OrderWithMarketAndMarketName[] = (openOrders || []).map((orderInfos) =>
|
||||
orderInfos.orders.map(order => {
|
||||
return {
|
||||
marketName: marketAddressesToNames[orderInfos.marketAddress],
|
||||
market: marketsByAddress[orderInfos.marketAddress],
|
||||
...order
|
||||
};
|
||||
})
|
||||
).flat();
|
||||
|
||||
return (
|
||||
<FloatingElement style={{ flex: 1, paddingTop: 10 }}>
|
||||
<Button
|
||||
onClick={refreshOpenOrders}
|
||||
loading={!loaded}
|
||||
>
|
||||
Refresh
|
||||
</Button>
|
||||
<OpenOrderTable
|
||||
openOrders={dataSource}
|
||||
pageSize={25}
|
||||
loading={!loaded}
|
||||
onCancelSuccess={refreshOpenOrders}
|
||||
marketFilter
|
||||
/>
|
||||
</FloatingElement>
|
||||
);
|
||||
}
|
|
@ -30,6 +30,7 @@ import {
|
|||
Trade,
|
||||
} from "./types";
|
||||
import {WRAPPED_SOL_MINT} from "@project-serum/serum/lib/token-instructions";
|
||||
import {Order} from "@project-serum/serum/lib/market";
|
||||
|
||||
// Used in debugging, should be false in production
|
||||
const _IGNORE_DEPRECATED = false;
|
||||
|
@ -607,65 +608,6 @@ export function useFillsForAllMarkets(limit = 100) {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: Update to use websocket
|
||||
export function useOpenOrdersForAllMarketsOld() {
|
||||
return [[], true]
|
||||
// const { connected, wallet } = useWallet();
|
||||
//
|
||||
// const connection = useConnection();
|
||||
// // todo: use custom markets
|
||||
// const allMarkets: {market: Market; marketName: string; programId: PublicKey;}[] = useAllMarkets([]);
|
||||
//
|
||||
// async function getOpenOrdersForAllMarkets() {
|
||||
// let orders: OrderWithMarket[] = [];
|
||||
// if (!connected) {
|
||||
// return orders;
|
||||
// }
|
||||
//
|
||||
// let marketData: {market: Market; marketName: string; programId: PublicKey;};
|
||||
// for (marketData of allMarkets) {
|
||||
// const { market, marketName } = marketData;
|
||||
// if (!market) {
|
||||
// return orders;
|
||||
// }
|
||||
// const openOrdersAccounts = await market.findOpenOrdersAccountsForOwner(
|
||||
// connection,
|
||||
// wallet.publicKey,
|
||||
// );
|
||||
// const openOrdersAccount = openOrdersAccounts && openOrdersAccounts[0];
|
||||
// if (!openOrdersAccount) {
|
||||
// return orders;
|
||||
// }
|
||||
// const [bids, asks] = await Promise.all([
|
||||
// market.loadBids(connection),
|
||||
// market.loadAsks(connection),
|
||||
// ]);
|
||||
// const ordersForMarket = [...bids, ...asks]
|
||||
// .filter((order) => {
|
||||
// return order.openOrdersAddress.equals(openOrdersAccount.publicKey);
|
||||
// })
|
||||
// .map((order) => {
|
||||
// return { ...order, marketName };
|
||||
// });
|
||||
// orders = orders.concat(ordersForMarket);
|
||||
// }
|
||||
//
|
||||
// return orders;
|
||||
// }
|
||||
//
|
||||
// return useAsyncData(
|
||||
// getOpenOrdersForAllMarkets,
|
||||
// tuple(
|
||||
// 'getOpenOrdersForAllMarkets',
|
||||
// connected,
|
||||
// connection,
|
||||
// wallet,
|
||||
// allMarkets,
|
||||
// ),
|
||||
// { refreshInterval: _SLOW_REFRESH_INTERVAL },
|
||||
// );
|
||||
}
|
||||
|
||||
export function useAllOpenOrdersAccounts() {
|
||||
const {wallet, connected} = useWallet();
|
||||
const connection = useConnection();
|
||||
|
@ -755,7 +697,11 @@ export function useAllOpenOrdersBalances() {
|
|||
return openOrdersBalances
|
||||
}
|
||||
|
||||
export function useAllOpenOrders() {
|
||||
export function useAllOpenOrders(): {
|
||||
openOrders: { orders: Order[]; marketAddress: string; }[] | null | undefined;
|
||||
loaded: boolean,
|
||||
refreshOpenOrders: () => void,
|
||||
} {
|
||||
const connection = useConnection();
|
||||
const { connected } = useWallet();
|
||||
const [openOrdersAccounts, openOrdersAccountsConnected] = useAllOpenOrdersAccounts();
|
||||
|
|
Loading…
Reference in New Issue