mango-ui-v3/components/OpenOrdersTable.tsx

236 lines
9.1 KiB
TypeScript
Raw Normal View History

2021-04-12 20:39:08 -07:00
import { useState } from 'react'
import Link from 'next/link'
import { ArrowSmDownIcon } from '@heroicons/react/solid'
import { useRouter } from 'next/router'
import { useOpenOrders } from '../hooks/useOpenOrders'
import Button, { LinkButton } from './Button'
2021-04-12 20:39:08 -07:00
import Loading from './Loading'
import useMangoStore, { mangoClient } from '../stores/useMangoStore'
2021-04-12 20:39:08 -07:00
import { notify } from '../utils/notifications'
import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table'
import SideBadge from './SideBadge'
import { useSortableData } from '../hooks/useSortableData'
2021-06-18 20:07:57 -07:00
import { Order, Market } from '@project-serum/serum/lib/market'
import { PerpOrder, PerpMarket } from '@blockworks-foundation/mango-client'
import { formatUsdValue, sleep } from '../utils'
2021-04-05 14:38:59 -07:00
const OpenOrdersTable = () => {
const { asPath } = useRouter()
const openOrders = useOpenOrders()
const { items, requestSort, sortConfig } = useSortableData(openOrders)
2021-04-12 20:39:08 -07:00
const [cancelId, setCancelId] = useState(null)
2021-04-15 15:45:26 -07:00
const actions = useMangoStore((s) => s.actions)
2021-04-12 20:39:08 -07:00
2021-06-23 08:32:33 -07:00
const handleCancelOrder = async (
order: Order | PerpOrder,
market: Market | PerpMarket
) => {
const wallet = useMangoStore.getState().wallet.current
const selectedMangoGroup =
useMangoStore.getState().selectedMangoGroup.current
2021-06-23 08:32:33 -07:00
const selectedMangoAccount =
useMangoStore.getState().selectedMangoAccount.current
2021-06-18 20:07:57 -07:00
setCancelId(order.orderId)
let txid
2021-04-12 20:39:08 -07:00
try {
2021-06-23 08:32:33 -07:00
if (!selectedMangoGroup || !selectedMangoAccount) return
2021-06-18 20:07:57 -07:00
if (market instanceof Market) {
txid = await mangoClient.cancelSpotOrder(
selectedMangoGroup,
2021-06-23 08:32:33 -07:00
selectedMangoAccount,
wallet,
market,
order as Order
)
2021-06-18 20:07:57 -07:00
} else if (market instanceof PerpMarket) {
txid = await mangoClient.cancelPerpOrder(
selectedMangoGroup,
2021-06-23 08:32:33 -07:00
selectedMangoAccount,
wallet,
market,
order as PerpOrder
)
2021-06-18 20:07:57 -07:00
}
notify({ title: 'Successfully cancelled order', txid })
2021-04-12 20:39:08 -07:00
} catch (e) {
notify({
title: 'Error cancelling order',
2021-04-12 20:39:08 -07:00
description: e.message,
txid: e.txid,
2021-04-12 20:39:08 -07:00
type: 'error',
})
console.log('error', `${e}`)
2021-04-12 20:39:08 -07:00
} finally {
sleep(500).then(() => {
actions.fetchMangoAccounts()
actions.updateOpenOrders()
})
2021-04-12 20:39:08 -07:00
setCancelId(null)
}
}
2021-04-05 14:38:59 -07:00
return (
<div className={`flex flex-col py-4`}>
<div className={`-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8`}>
<div className={`align-middle inline-block min-w-full sm:px-6 lg:px-8`}>
2021-04-11 21:17:23 -07:00
{openOrders && openOrders.length > 0 ? (
<div className={`shadow overflow-hidden border-b border-th-bkg-2`}>
<Table className={`min-w-full divide-y divide-th-bkg-2`}>
<Thead>
<Tr className="text-th-fgd-3 text-xs">
2021-07-29 06:19:32 -07:00
<Th scope="col" className={`px-6 py-2`}>
<LinkButton
2021-07-29 06:19:32 -07:00
className="flex items-center no-underline font-normal"
onClick={() => requestSort('marketName')}
>
Market
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'marketName'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
2021-07-29 06:19:32 -07:00
<Th scope="col" className={`px-6 py-2`}>
<LinkButton
2021-07-29 06:19:32 -07:00
className="flex items-center no-underline font-normal"
onClick={() => requestSort('side')}
>
Side
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'side'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
2021-07-29 06:19:32 -07:00
<Th scope="col" className={`px-6 py-2`}>
<LinkButton
2021-07-29 06:19:32 -07:00
className="flex items-center no-underline font-normal"
onClick={() => requestSort('size')}
>
Size
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'size'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
2021-07-29 06:19:32 -07:00
<Th scope="col" className={`px-6 py-2`}>
<LinkButton
2021-07-29 06:19:32 -07:00
className="flex items-center no-underline font-normal"
onClick={() => requestSort('price')}
>
Price
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'price'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
2021-07-19 13:24:49 -07:00
<Th scope="col" className={`relative px-6 py-2.5`}>
<span className={`sr-only`}>Edit</span>
</Th>
</Tr>
</Thead>
<Tbody>
2021-06-23 08:32:33 -07:00
{items.map(({ order, market }, index) => (
<Tr
key={`${order.orderId}${order.side}`}
className={`border-b border-th-bkg-3
${index % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-2`}
`}
2021-04-05 14:38:59 -07:00
>
<Td
2021-07-29 06:19:32 -07:00
className={`px-6 py-2 whitespace-nowrap text-th-fgd-1`}
2021-04-05 14:38:59 -07:00
>
<div className="flex items-center">
<img
alt=""
width="20"
height="20"
2021-06-23 08:32:33 -07:00
src={`/assets/icons/${market.config.baseSymbol.toLowerCase()}.svg`}
className={`mr-2.5`}
/>
2021-06-18 20:07:57 -07:00
<div>{market.config.name}</div>
</div>
</Td>
<Td
2021-07-29 06:19:32 -07:00
className={`px-6 py-2 whitespace-nowrap text-th-fgd-1`}
>
<SideBadge side={order.side} />
</Td>
<Td
2021-07-29 06:19:32 -07:00
className={`px-6 py-2 whitespace-nowrap text-th-fgd-1`}
>
{order.size}
</Td>
<Td
2021-07-29 06:19:32 -07:00
className={`px-6 py-2 whitespace-nowrap text-th-fgd-1`}
>
2021-08-20 04:51:29 -07:00
{formatUsdValue(order.price)}
</Td>
2021-07-29 06:19:32 -07:00
<Td className={`px-6 py-2 whitespace-nowrap`}>
<div className={`flex justify-end`}>
<Button
2021-06-23 08:32:33 -07:00
onClick={() =>
handleCancelOrder(order, market.account)
}
2021-07-24 11:12:52 -07:00
className="ml-3 text-xs pt-0 pb-0 h-8 pl-3 pr-3"
>
2021-06-18 20:07:57 -07:00
{cancelId + '' === order.orderId + '' ? (
<Loading />
) : (
<span>Cancel</span>
)}
</Button>
</div>
</Td>
</Tr>
))}
</Tbody>
</Table>
</div>
) : (
<div
2021-04-19 06:45:59 -07:00
className={`w-full text-center py-6 bg-th-bkg-1 text-th-fgd-3 rounded-md`}
>
2021-08-15 06:31:59 -07:00
No open orders
{asPath === '/account' ? (
<Link href={'/'}>
<a
className={`inline-flex ml-2 py-0
`}
>
Make a trade
</a>
</Link>
) : null}
</div>
)}
2021-04-05 14:38:59 -07:00
</div>
</div>
</div>
)
}
export default OpenOrdersTable