mango-ui-v3/components/OpenOrdersTable.tsx

247 lines
7.9 KiB
TypeScript
Raw Normal View History

2021-04-12 20:39:08 -07:00
import { useState } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useOpenOrders } from '../hooks/useOpenOrders'
import Button from './Button'
2021-04-12 20:39:08 -07:00
import Loading from './Loading'
2021-09-13 14:14:59 -07:00
import useMangoStore from '../stores/useMangoStore'
2021-04-12 20:39:08 -07:00
import { notify } from '../utils/notifications'
import SideBadge from './SideBadge'
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, getDecimalCount, usdFormatter } from '../utils'
import { Table, Td, Th, TrBody, TrHead } from './TableElements'
import { useViewport } from '../hooks/useViewport'
import { breakpoints } from './TradePageGrid'
import { Row } from './TableElements'
import { PerpTriggerOrder } from '../@types/types'
import { useTranslation } from 'next-i18next'
2021-04-05 14:38:59 -07:00
const DesktopTable = ({ openOrders, cancelledOrderId, handleCancelOrder }) => {
const { t } = useTranslation('common')
return (
<Table>
<thead>
<TrHead>
<Th>{t('market')}</Th>
<Th>{t('size')}</Th>
<Th>{t('size')}</Th>
<Th>{t('price')}</Th>
<Th>{t('value')}</Th>
<Th>{t('condition')}</Th>
<Th>
<span className={`sr-only`}>{t('edit')}</span>
</Th>
</TrHead>
</thead>
<tbody>
{openOrders.map(({ order, market }, index) => {
const decimals = getDecimalCount(market.account.tickSize)
return (
<TrBody index={index} key={`${order.orderId}${order.side}`}>
<Td>
<div className="flex items-center">
<img
alt=""
width="20"
height="20"
src={`/assets/icons/${market.config.baseSymbol.toLowerCase()}.svg`}
className={`mr-2.5`}
/>
<div>{market.config.name}</div>
</div>
</Td>
<Td>
<SideBadge side={order.side} />
</Td>
<Td>{order.size}</Td>
<Td>{usdFormatter(order.price, decimals)}</Td>
<Td>{formatUsdValue(order.price * order.size)}</Td>
<Td>
{order.perpTrigger &&
`${order.orderType} ${
order.triggerCondition
} ${order.triggerPrice.toFixed(2)}`}
</Td>
<Td>
<div className={`flex justify-end`}>
<Button
onClick={() => handleCancelOrder(order, market.account)}
className="ml-3 text-xs pt-0 pb-0 h-8 pl-3 pr-3"
>
{cancelledOrderId + '' === order.orderId + '' ? (
<Loading />
) : (
<span>{t('cancel')}</span>
)}
</Button>
</div>
</Td>
</TrBody>
)
})}
</tbody>
</Table>
)
}
const MobileTable = ({ openOrders, cancelledOrderId, handleCancelOrder }) => {
const { t } = useTranslation('common')
return (
<>
{openOrders.map(({ market, order }, index) => (
<Row key={`${order.orderId}${order.side}`} index={index}>
<div className="col-span-12 flex items-center justify-between text-fgd-1 text-left">
<div className="flex items-center">
<img
alt=""
width="20"
height="20"
src={`/assets/icons/${market.config.baseSymbol.toLowerCase()}.svg`}
className={`mr-2.5`}
/>
<div>
<div className="mb-0.5">{market.config.name}</div>
<div className="text-th-fgd-3 text-xs">
<span
className={`mr-1
${
order.side === 'buy'
? 'text-th-green'
: 'text-th-red'
}
`}
>
{order.side.toUpperCase()}
</span>
2021-09-29 12:09:51 -07:00
{order.perpTrigger
? `${order.size} ${order.triggerCondition} ${order.triggerPrice}`
: `${order.size} at ${formatUsdValue(order.price)}`}
</div>
</div>
</div>
<Button
onClick={() => handleCancelOrder(order, market.account)}
className="ml-3 text-xs pt-0 pb-0 h-8 pl-3 pr-3"
>
{cancelledOrderId + '' === order.orderId + '' ? (
<Loading />
) : (
<span>{t('cancel')}</span>
)}
</Button>
</div>
</Row>
))}
</>
)
}
2021-04-05 14:38:59 -07:00
const OpenOrdersTable = () => {
const { t } = useTranslation('common')
const { asPath } = useRouter()
const openOrders = useOpenOrders()
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)
const { width } = useViewport()
const isMobile = width ? width < breakpoints.md : false
2021-04-12 20:39:08 -07:00
2021-06-23 08:32:33 -07:00
const handleCancelOrder = async (
order: Order | PerpOrder | PerpTriggerOrder,
2021-06-23 08:32:33 -07:00
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-09-13 14:14:59 -07:00
const mangoClient = useMangoStore.getState().connection.client
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,
2021-09-07 12:27:54 -07:00
order as Order
)
2021-06-18 20:07:57 -07:00
} else if (market instanceof PerpMarket) {
// TODO: this is not ideal
if (order['triggerCondition']) {
txid = await mangoClient.removeAdvancedOrder(
selectedMangoGroup,
selectedMangoAccount,
wallet,
(order as PerpTriggerOrder).orderId
)
} else {
txid = await mangoClient.cancelPerpOrder(
selectedMangoGroup,
selectedMangoAccount,
wallet,
market,
order as PerpOrder,
false
)
}
2021-06-18 20:07:57 -07:00
}
notify({ title: t('cancel-success'), txid })
2021-04-12 20:39:08 -07:00
} catch (e) {
notify({
title: t('cancel-error'),
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 {
// await sleep(600)
2021-09-07 16:27:14 -07:00
actions.reloadMangoAccount()
2021-04-12 20:39:08 -07:00
setCancelId(null)
}
}
2021-04-05 14:38:59 -07:00
const tableProps = {
openOrders,
cancelledOrderId: cancelId,
handleCancelOrder,
}
2021-04-05 14:38:59 -07:00
return (
<div className={`flex flex-col py-2 sm:pb-4 sm:pt-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 ? (
!isMobile ? (
<DesktopTable {...tableProps} />
) : (
<MobileTable {...tableProps} />
)
) : (
<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`}
>
{t('no-orders')}
{asPath === '/account' ? (
<Link href={'/'}>
<a
className={`inline-flex ml-2 py-0
`}
>
{t('make-trade')}
</a>
</Link>
) : null}
</div>
)}
2021-04-05 14:38:59 -07:00
</div>
</div>
</div>
)
}
export default OpenOrdersTable