hide perp positions table if none open
This commit is contained in:
parent
267639dec5
commit
d35304e84f
|
@ -35,10 +35,21 @@ const PositionsTable = () => {
|
||||||
[mangoGroup]
|
[mangoGroup]
|
||||||
)
|
)
|
||||||
const perpAccounts = mangoAccount
|
const perpAccounts = mangoAccount
|
||||||
? groupConfig.perpMarkets.map(
|
? groupConfig.perpMarkets.map((m) => {
|
||||||
(m) => mangoAccount.perpAccounts[m.marketIndex]
|
return {
|
||||||
)
|
perpAccount: mangoAccount.perpAccounts[m.marketIndex],
|
||||||
|
marketIndex: m.marketIndex,
|
||||||
|
}
|
||||||
|
})
|
||||||
: []
|
: []
|
||||||
|
const filteredPerpAccounts = perpAccounts.filter(
|
||||||
|
({ perpAccount }) =>
|
||||||
|
!(
|
||||||
|
perpAccount.quotePosition.eq(ZERO_I80F48) &&
|
||||||
|
perpAccount.basePosition.eq(new BN(0))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
console.log('perp acc length', filteredPerpAccounts.length)
|
||||||
|
|
||||||
const handleSettlePnl = async (
|
const handleSettlePnl = async (
|
||||||
perpMarket: PerpMarket,
|
perpMarket: PerpMarket,
|
||||||
|
@ -81,7 +92,7 @@ const PositionsTable = () => {
|
||||||
<div className="flex flex-col py-4">
|
<div className="flex flex-col py-4">
|
||||||
<div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
<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">
|
<div className="align-middle inline-block min-w-full sm:px-6 lg:px-8">
|
||||||
{perpAccounts.length ? (
|
{filteredPerpAccounts.length ? (
|
||||||
<div className="overflow-hidden border-b border-th-bkg-2 sm:rounded-m">
|
<div className="overflow-hidden border-b border-th-bkg-2 sm:rounded-m">
|
||||||
<Table className="min-w-full divide-y divide-th-bkg-2">
|
<Table className="min-w-full divide-y divide-th-bkg-2">
|
||||||
<Thead>
|
<Thead>
|
||||||
|
@ -110,94 +121,90 @@ const PositionsTable = () => {
|
||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
<Tbody>
|
<Tbody>
|
||||||
{perpAccounts.map((perpAcc, index) => {
|
{filteredPerpAccounts.map(
|
||||||
const perpMarketInfo = perpMarkets[index]
|
({ perpAccount, marketIndex }, index) => {
|
||||||
const marketConfig = getMarketByPublicKey(
|
const perpMarketInfo = perpMarkets[marketIndex]
|
||||||
groupConfig,
|
const marketConfig = getMarketByPublicKey(
|
||||||
perpMarketInfo.perpMarket
|
groupConfig,
|
||||||
)
|
perpMarketInfo.perpMarket
|
||||||
|
)
|
||||||
|
|
||||||
const marketCache =
|
const marketCache =
|
||||||
mangoCache.perpMarketCache[marketConfig.marketIndex]
|
mangoCache.perpMarketCache[marketIndex]
|
||||||
const price =
|
const price = mangoCache.priceCache[marketIndex].price
|
||||||
mangoCache.priceCache[marketConfig.marketIndex].price
|
const perpMarket = allMarkets[
|
||||||
const perpMarket = allMarkets[
|
marketConfig.publicKey.toString()
|
||||||
marketConfig.publicKey.toString()
|
] as PerpMarket
|
||||||
] as PerpMarket
|
|
||||||
|
|
||||||
if (
|
return (
|
||||||
perpAcc.quotePosition.eq(ZERO_I80F48) &&
|
<Tr
|
||||||
perpAcc.basePosition.eq(new BN(0))
|
key={`${marketIndex}`}
|
||||||
) {
|
className={`border-b border-th-bkg-3
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tr
|
|
||||||
key={`${index}`}
|
|
||||||
className={`border-b border-th-bkg-3
|
|
||||||
${index % 2 === 0 ? `bg-th-bkg-2` : `bg-th-bkg-3`}
|
${index % 2 === 0 ? `bg-th-bkg-2` : `bg-th-bkg-3`}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<Td className="px-6 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
<Td className="px-6 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
||||||
{marketConfig.name}
|
{marketConfig.name}
|
||||||
</Td>
|
</Td>
|
||||||
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
||||||
<SideBadge
|
<SideBadge
|
||||||
side={
|
side={
|
||||||
perpAcc.basePosition.gt(new BN(0))
|
perpAccount.basePosition.gt(new BN(0))
|
||||||
? 'long'
|
? 'long'
|
||||||
: 'short'
|
: 'short'
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Td>
|
|
||||||
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
|
||||||
{perpMarket.baseLotsToNumber(perpAcc.basePosition)}
|
|
||||||
</Td>
|
|
||||||
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
|
||||||
{nativeI80F48ToUi(
|
|
||||||
perpAcc.quotePosition,
|
|
||||||
marketConfig.quoteDecimals
|
|
||||||
).toFixed()}
|
|
||||||
</Td>
|
|
||||||
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
|
||||||
$
|
|
||||||
{nativeI80F48ToUi(
|
|
||||||
perpAcc.getPnl(perpMarketInfo, price),
|
|
||||||
marketConfig.quoteDecimals
|
|
||||||
).toFixed()}
|
|
||||||
</Td>
|
|
||||||
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
|
||||||
{perpAcc
|
|
||||||
.getHealth(
|
|
||||||
perpMarketInfo,
|
|
||||||
price,
|
|
||||||
perpMarketInfo.maintAssetWeight,
|
|
||||||
perpMarketInfo.maintLiabWeight,
|
|
||||||
marketCache.longFunding,
|
|
||||||
marketCache.shortFunding
|
|
||||||
)
|
|
||||||
.toFixed(3)}
|
|
||||||
</Td>
|
|
||||||
<Td className="px-6 whitespace-nowrap text-sm text-th-fgd-1">
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button
|
|
||||||
onClick={() =>
|
|
||||||
handleSettlePnl(perpMarket, perpAcc)
|
|
||||||
}
|
}
|
||||||
className="ml-3 text-xs pt-0 pb-0 h-8 pl-3 pr-3"
|
/>
|
||||||
>
|
</Td>
|
||||||
{settlingPerpAcc == perpAcc ? (
|
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
||||||
<Loading />
|
{perpMarket.baseLotsToNumber(
|
||||||
) : (
|
perpAccount.basePosition
|
||||||
<span>Settle PNL</span>
|
)}
|
||||||
)}
|
</Td>
|
||||||
</Button>
|
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
||||||
</div>
|
{nativeI80F48ToUi(
|
||||||
</Td>
|
perpAccount.quotePosition,
|
||||||
</Tr>
|
marketConfig.quoteDecimals
|
||||||
)
|
).toFixed()}
|
||||||
})}
|
</Td>
|
||||||
|
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
||||||
|
$
|
||||||
|
{nativeI80F48ToUi(
|
||||||
|
perpAccount.getPnl(perpMarketInfo, price),
|
||||||
|
marketConfig.quoteDecimals
|
||||||
|
).toFixed()}
|
||||||
|
</Td>
|
||||||
|
<Td className="px-2 py-2.5 whitespace-nowrap text-sm text-th-fgd-1">
|
||||||
|
{perpAccount
|
||||||
|
.getHealth(
|
||||||
|
perpMarketInfo,
|
||||||
|
price,
|
||||||
|
perpMarketInfo.maintAssetWeight,
|
||||||
|
perpMarketInfo.maintLiabWeight,
|
||||||
|
marketCache.longFunding,
|
||||||
|
marketCache.shortFunding
|
||||||
|
)
|
||||||
|
.toFixed(3)}
|
||||||
|
</Td>
|
||||||
|
<Td className="px-6 whitespace-nowrap text-sm text-th-fgd-1">
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<Button
|
||||||
|
onClick={() =>
|
||||||
|
handleSettlePnl(perpMarket, perpAccount)
|
||||||
|
}
|
||||||
|
className="ml-3 text-xs pt-0 pb-0 h-8 pl-3 pr-3"
|
||||||
|
>
|
||||||
|
{settlingPerpAcc == perpAccount ? (
|
||||||
|
<Loading />
|
||||||
|
) : (
|
||||||
|
<span>Settle PNL</span>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
</Tr>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)}
|
||||||
</Tbody>
|
</Tbody>
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,15 +7,11 @@ import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table'
|
||||||
import SideBadge from './SideBadge'
|
import SideBadge from './SideBadge'
|
||||||
import { LinkButton } from './Button'
|
import { LinkButton } from './Button'
|
||||||
import { useSortableData } from '../hooks/useSortableData'
|
import { useSortableData } from '../hooks/useSortableData'
|
||||||
import useMangoStore from '../stores/useMangoStore'
|
|
||||||
|
|
||||||
const TradeHistoryTable = () => {
|
const TradeHistoryTable = () => {
|
||||||
const { asPath } = useRouter()
|
const { asPath } = useRouter()
|
||||||
const tradeHistory = useTradeHistory()
|
const tradeHistory = useTradeHistory()
|
||||||
const { items, requestSort, sortConfig } = useSortableData(tradeHistory)
|
const { items, requestSort, sortConfig } = useSortableData(tradeHistory)
|
||||||
console.log('trade history items: ', items)
|
|
||||||
|
|
||||||
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
|
|
||||||
|
|
||||||
const renderTradeDateTime = (timestamp: BN | string) => {
|
const renderTradeDateTime = (timestamp: BN | string) => {
|
||||||
let date
|
let date
|
||||||
|
@ -276,7 +272,7 @@ const TradeHistoryTable = () => {
|
||||||
<div
|
<div
|
||||||
className={`w-full text-center py-6 bg-th-bkg-1 text-th-fgd-3 rounded-md`}
|
className={`w-full text-center py-6 bg-th-bkg-1 text-th-fgd-3 rounded-md`}
|
||||||
>
|
>
|
||||||
No {marketConfig.name} trade history.
|
No trade history.
|
||||||
{asPath === '/account' ? (
|
{asPath === '/account' ? (
|
||||||
<Link href={'/'}>
|
<Link href={'/'}>
|
||||||
<a
|
<a
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect } from 'react'
|
import { useCallback, useEffect } from 'react'
|
||||||
import { AccountInfo } from '@solana/web3.js'
|
import { AccountInfo } from '@solana/web3.js'
|
||||||
import useMangoStore, {
|
import useMangoStore, {
|
||||||
DEFAULT_CONNECTION,
|
DEFAULT_CONNECTION,
|
||||||
|
@ -78,28 +78,30 @@ const useHydrateStore = () => {
|
||||||
}, [selectedMarket])
|
}, [selectedMarket])
|
||||||
|
|
||||||
// fetch filled trades for selected market
|
// fetch filled trades for selected market
|
||||||
useInterval(() => {
|
const fetchFills = useCallback(async () => {
|
||||||
async function fetchFills() {
|
if (!selectedMarket) {
|
||||||
const market = useMangoStore.getState().selectedMarket.current
|
return null
|
||||||
|
|
||||||
if (!market) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const loadedFills = await selectedMarket.loadFills(
|
|
||||||
DEFAULT_CONNECTION,
|
|
||||||
10000
|
|
||||||
)
|
|
||||||
setMangoStore((state) => {
|
|
||||||
state.selectedMarket.fills = loadedFills
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
console.log('Error fetching fills:', err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
const loadedFills = await selectedMarket.loadFills(
|
||||||
|
DEFAULT_CONNECTION,
|
||||||
|
10000
|
||||||
|
)
|
||||||
|
setMangoStore((state) => {
|
||||||
|
state.selectedMarket.fills = loadedFills
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Error fetching fills:', err)
|
||||||
|
}
|
||||||
|
}, [selectedMarket, setMangoStore])
|
||||||
|
|
||||||
|
useInterval(() => {
|
||||||
fetchFills()
|
fetchFills()
|
||||||
}, _SLOW_REFRESH_INTERVAL)
|
}, _SLOW_REFRESH_INTERVAL)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchFills()
|
||||||
|
}, [fetchFills])
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useHydrateStore
|
export default useHydrateStore
|
||||||
|
|
Loading…
Reference in New Issue