Miscellaneous (#737)
* fix: sorted assets by value * tidy: refactored AssetsSelectTable * fix: fixed the multipleVaultWithdraw Modal
This commit is contained in:
parent
fd924c885e
commit
000aa71e06
@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useMemo, useState } from 'react'
|
import { useCallback, useMemo, useState } from 'react'
|
||||||
|
|
||||||
import AssetSelectTable from 'components/Modals/AssetsSelect/AssetSelectTable'
|
import AssetsSelect from 'components/Modals/AssetsSelect'
|
||||||
import SearchBar from 'components/common/SearchBar'
|
import SearchBar from 'components/common/SearchBar'
|
||||||
import Text from 'components/common/Text'
|
import Text from 'components/common/Text'
|
||||||
import useMarketBorrowings from 'hooks/markets/useMarketBorrowings'
|
import useMarketBorrowings from 'hooks/markets/useMarketBorrowings'
|
||||||
@ -89,11 +89,11 @@ export default function AddVaultAssetsModalContent(props: Props) {
|
|||||||
Leverage will be set at 50% for both assets by default
|
Leverage will be set at 50% for both assets by default
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
<AssetSelectTable
|
<AssetsSelect
|
||||||
isBorrow={true}
|
|
||||||
assets={poolAssets}
|
assets={poolAssets}
|
||||||
onChangeSelected={onChangePoolDenoms}
|
onChangeSelected={onChangePoolDenoms}
|
||||||
selectedDenoms={selectedPoolDenoms}
|
selectedDenoms={selectedPoolDenoms}
|
||||||
|
isBorrow
|
||||||
/>
|
/>
|
||||||
<div className='p-4'>
|
<div className='p-4'>
|
||||||
<Text>Assets not in the liquidity pool</Text>
|
<Text>Assets not in the liquidity pool</Text>
|
||||||
@ -102,11 +102,11 @@ export default function AddVaultAssetsModalContent(props: Props) {
|
|||||||
these assets below.
|
these assets below.
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
<AssetSelectTable
|
<AssetsSelect
|
||||||
isBorrow={true}
|
|
||||||
assets={stableAssets}
|
assets={stableAssets}
|
||||||
onChangeSelected={onChangeOtherDenoms}
|
onChangeSelected={onChangeOtherDenoms}
|
||||||
selectedDenoms={selectedOtherDenoms}
|
selectedDenoms={selectedOtherDenoms}
|
||||||
|
isBorrow
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@ -1,154 +0,0 @@
|
|||||||
import {
|
|
||||||
flexRender,
|
|
||||||
getCoreRowModel,
|
|
||||||
getSortedRowModel,
|
|
||||||
RowSelectionState,
|
|
||||||
SortingState,
|
|
||||||
useReactTable,
|
|
||||||
} from '@tanstack/react-table'
|
|
||||||
import classNames from 'classnames'
|
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
|
||||||
|
|
||||||
import { SortAsc, SortDesc, SortNone } from 'components/common/Icons'
|
|
||||||
import useAssetTableColumns from 'components/Modals/AssetsSelect/useAssetTableColumns'
|
|
||||||
import Text from 'components/common/Text'
|
|
||||||
import useMarketAssets from 'hooks/markets/useMarketAssets'
|
|
||||||
import useStore from 'store'
|
|
||||||
import { byDenom } from 'utils/array'
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
assets: Asset[] | BorrowAsset[]
|
|
||||||
selectedDenoms: string[]
|
|
||||||
onChangeSelected: (denoms: string[]) => void
|
|
||||||
isBorrow: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function AssetSelectTable(props: Props) {
|
|
||||||
const { data: markets } = useMarketAssets()
|
|
||||||
const defaultSelected = useMemo(() => {
|
|
||||||
const assets = props.assets as BorrowAsset[]
|
|
||||||
return assets.reduce(
|
|
||||||
(acc, asset, index) => {
|
|
||||||
if (props.selectedDenoms?.includes(asset.denom)) {
|
|
||||||
acc[index] = true
|
|
||||||
}
|
|
||||||
return acc
|
|
||||||
},
|
|
||||||
{} as { [key: number]: boolean },
|
|
||||||
)
|
|
||||||
}, [props.selectedDenoms, props.assets])
|
|
||||||
const [sorting, setSorting] = useState<SortingState>([{ id: 'symbol', desc: false }])
|
|
||||||
const [selected, setSelected] = useState<RowSelectionState>(defaultSelected)
|
|
||||||
const balances = useStore((s) => s.balances)
|
|
||||||
const columns = useAssetTableColumns(props.isBorrow)
|
|
||||||
const tableData: AssetTableRow[] = useMemo(() => {
|
|
||||||
return props.assets.map((asset) => {
|
|
||||||
const balancesForAsset = balances.find(byDenom(asset.denom))
|
|
||||||
return {
|
|
||||||
asset,
|
|
||||||
balance: balancesForAsset?.amount ?? '0',
|
|
||||||
market: markets.find((market) => market.denom === asset.denom),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, [balances, props.assets, markets])
|
|
||||||
|
|
||||||
const table = useReactTable({
|
|
||||||
data: tableData,
|
|
||||||
columns,
|
|
||||||
state: {
|
|
||||||
sorting,
|
|
||||||
rowSelection: selected,
|
|
||||||
},
|
|
||||||
onRowSelectionChange: setSelected,
|
|
||||||
onSortingChange: setSorting,
|
|
||||||
getCoreRowModel: getCoreRowModel(),
|
|
||||||
getSortedRowModel: getSortedRowModel(),
|
|
||||||
})
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const newSelectedDenoms = props.assets
|
|
||||||
.filter((_, index) => selected[index])
|
|
||||||
.map((asset) => asset.denom)
|
|
||||||
|
|
||||||
if (
|
|
||||||
props.selectedDenoms.length === newSelectedDenoms.length &&
|
|
||||||
newSelectedDenoms.every((denom) => props.selectedDenoms.includes(denom))
|
|
||||||
)
|
|
||||||
return
|
|
||||||
props.onChangeSelected(newSelectedDenoms)
|
|
||||||
}, [selected, props])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<table className='w-full'>
|
|
||||||
<thead className='border-b border-white/10'>
|
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
|
||||||
<tr key={headerGroup.id}>
|
|
||||||
{headerGroup.headers.map((header) => {
|
|
||||||
return (
|
|
||||||
<th
|
|
||||||
key={header.id}
|
|
||||||
onClick={header.column.getToggleSortingHandler()}
|
|
||||||
className={classNames(
|
|
||||||
'p-2',
|
|
||||||
header.column.getCanSort() && 'hover:cursor-pointer',
|
|
||||||
header.id === 'symbol' ? 'text-left' : 'text-right',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
'flex',
|
|
||||||
header.id === 'symbol' ? 'justify-start' : 'justify-end',
|
|
||||||
'align-center',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<span className='w-6 h-6 text-white'>
|
|
||||||
{header.column.getCanSort()
|
|
||||||
? {
|
|
||||||
asc: <SortAsc />,
|
|
||||||
desc: <SortDesc />,
|
|
||||||
false: <SortNone />,
|
|
||||||
}[header.column.getIsSorted() as string] ?? null
|
|
||||||
: null}
|
|
||||||
</span>
|
|
||||||
<Text
|
|
||||||
tag='span'
|
|
||||||
size='sm'
|
|
||||||
className='flex items-center font-normal text-white/40'
|
|
||||||
>
|
|
||||||
{flexRender(header.column.columnDef.header, header.getContext())}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{table.getRowModel().rows.map((row) => {
|
|
||||||
return (
|
|
||||||
<tr
|
|
||||||
key={row.id}
|
|
||||||
className='hover:cursor-pointer text-white/60'
|
|
||||||
onClick={() => row.toggleSelected()}
|
|
||||||
>
|
|
||||||
{row.getVisibleCells().map((cell) => {
|
|
||||||
return (
|
|
||||||
<td
|
|
||||||
key={cell.id}
|
|
||||||
className={classNames(
|
|
||||||
cell.column.id === 'select' ? `` : 'text-right',
|
|
||||||
'px-4 py-3',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
||||||
</td>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
)
|
|
||||||
}
|
|
55
src/components/Modals/AssetsSelect/Columns/Asset.tsx
Normal file
55
src/components/Modals/AssetsSelect/Columns/Asset.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { Row } from '@tanstack/react-table'
|
||||||
|
|
||||||
|
import Checkbox from 'components/common/Checkbox'
|
||||||
|
import Text from 'components/common/Text'
|
||||||
|
import AssetImage from 'components/common/assets/AssetImage'
|
||||||
|
import AssetRate from 'components/common/assets/AssetRate'
|
||||||
|
|
||||||
|
export const ASSET_META = { id: 'name', header: 'Asset', accessorKey: 'asset.symbol' }
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
row: Row<AssetTableRow>
|
||||||
|
}
|
||||||
|
|
||||||
|
function isBorrowAsset(object?: any): object is BorrowAsset {
|
||||||
|
if (!object) return false
|
||||||
|
return 'borrowRate' in object
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Asset(props: Props) {
|
||||||
|
const { row } = props
|
||||||
|
const asset = row.original.asset
|
||||||
|
const market = row.original.market
|
||||||
|
const isBorrow = isBorrowAsset(asset)
|
||||||
|
const showRate = !isBorrow && market?.borrowEnabled
|
||||||
|
const apy = isBorrow ? market?.apy.borrow : market?.apy.deposit
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex items-center'>
|
||||||
|
<Checkbox
|
||||||
|
name={`asset-${asset.id.toLowerCase()}`}
|
||||||
|
checked={row.getIsSelected()}
|
||||||
|
onChange={row.getToggleSelectedHandler()}
|
||||||
|
noMouseEvents
|
||||||
|
/>
|
||||||
|
<AssetImage asset={asset} size={24} className='ml-4' />
|
||||||
|
<div className='ml-2 text-left'>
|
||||||
|
<Text size='sm' className='mb-0.5 text-white'>
|
||||||
|
{asset.symbol}
|
||||||
|
</Text>
|
||||||
|
{showRate && market ? (
|
||||||
|
<AssetRate
|
||||||
|
rate={apy ?? 0}
|
||||||
|
isEnabled={market.borrowEnabled}
|
||||||
|
className='text-xs'
|
||||||
|
type='apy'
|
||||||
|
orientation='rtl'
|
||||||
|
suffix
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text size='xs'>{asset.name}</Text>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
38
src/components/Modals/AssetsSelect/Columns/Balance.tsx
Normal file
38
src/components/Modals/AssetsSelect/Columns/Balance.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { Row } from '@tanstack/react-table'
|
||||||
|
|
||||||
|
import DisplayCurrency from 'components/common/DisplayCurrency'
|
||||||
|
import { FormattedNumber } from 'components/common/FormattedNumber'
|
||||||
|
import { BN_ZERO } from 'constants/math'
|
||||||
|
import { BNCoin } from 'types/classes/BNCoin'
|
||||||
|
import { demagnify } from 'utils/formatters'
|
||||||
|
import { BN } from 'utils/helpers'
|
||||||
|
|
||||||
|
export const BALANCE_META = { id: 'value', header: 'Balance', accessorKey: 'value' }
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
row: Row<AssetTableRow>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const valueSortingFn = (a: Row<AssetTableRow>, b: Row<AssetTableRow>): number => {
|
||||||
|
const valueA = a.original.value ?? BN_ZERO
|
||||||
|
const valueB = b.original.value ?? BN_ZERO
|
||||||
|
return valueA.minus(valueB).toNumber()
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Balance(props: Props) {
|
||||||
|
const { row } = props
|
||||||
|
const asset = row.original.asset
|
||||||
|
const balance = BN(row.original.balance ?? '0')
|
||||||
|
const coin = BNCoin.fromDenomAndBigNumber(asset.denom, balance)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex flex-wrap items-center'>
|
||||||
|
<DisplayCurrency coin={coin} className='mb-0.5 w-full text-white' />
|
||||||
|
<FormattedNumber
|
||||||
|
className='w-full text-xs'
|
||||||
|
options={{ minDecimals: 2, maxDecimals: asset.decimals }}
|
||||||
|
amount={demagnify(balance, asset)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
25
src/components/Modals/AssetsSelect/Columns/BorrowRate.tsx
Normal file
25
src/components/Modals/AssetsSelect/Columns/BorrowRate.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Row } from '@tanstack/react-table'
|
||||||
|
|
||||||
|
import Text from 'components/common/Text'
|
||||||
|
import { formatPercent } from 'utils/formatters'
|
||||||
|
|
||||||
|
export const BORROW_RATE_META = {
|
||||||
|
id: 'asset.borrowRate',
|
||||||
|
header: 'BorrowRate',
|
||||||
|
accessorKey: 'asset.borrowRate',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
row: Row<AssetTableRow>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function BorrowRate(props: Props) {
|
||||||
|
const { row } = props
|
||||||
|
const asset = row.original.asset as BorrowAsset
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Text size='sm' className='mb-0.5 text-white'>
|
||||||
|
{formatPercent(asset.borrowRate ?? 0)}
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
import { ColumnDef } from '@tanstack/react-table'
|
||||||
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
|
import Asset, { ASSET_META } from 'components/Modals/AssetsSelect/Columns/Asset'
|
||||||
|
import Balance, {
|
||||||
|
BALANCE_META,
|
||||||
|
valueSortingFn,
|
||||||
|
} from 'components/Modals/AssetsSelect/Columns/Balance'
|
||||||
|
import BorrowRate, { BORROW_RATE_META } from 'components/Modals/AssetsSelect/Columns/BorrowRate'
|
||||||
|
|
||||||
|
export default function useAssetSelectColumns(isBorrow?: boolean) {
|
||||||
|
return useMemo<ColumnDef<AssetTableRow>[]>(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
...ASSET_META,
|
||||||
|
cell: ({ row }) => <Asset row={row} />,
|
||||||
|
},
|
||||||
|
isBorrow
|
||||||
|
? {
|
||||||
|
...BORROW_RATE_META,
|
||||||
|
cell: ({ row }) => <BorrowRate row={row} />,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
...BALANCE_META,
|
||||||
|
cell: ({ row }) => <Balance row={row} />,
|
||||||
|
sortingFn: valueSortingFn,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}, [isBorrow])
|
||||||
|
}
|
81
src/components/Modals/AssetsSelect/index.tsx
Normal file
81
src/components/Modals/AssetsSelect/index.tsx
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import { RowSelectionState } from '@tanstack/react-table'
|
||||||
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
|
import useAssetSelectColumns from 'components/Modals/AssetsSelect/Columns/useAssetSelectColumns'
|
||||||
|
import Table from 'components/common/Table'
|
||||||
|
import useGetCoinValue from 'hooks/assets/useGetCoinValue'
|
||||||
|
import useMarketAssets from 'hooks/markets/useMarketAssets'
|
||||||
|
import useStore from 'store'
|
||||||
|
import { BNCoin } from 'types/classes/BNCoin'
|
||||||
|
import { byDenom } from 'utils/array'
|
||||||
|
import { BN } from 'utils/helpers'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
assets: Asset[]
|
||||||
|
onChangeSelected: (selected: string[]) => void
|
||||||
|
selectedDenoms: string[]
|
||||||
|
isBorrow?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AssetsSelect(props: Props) {
|
||||||
|
const { assets, onChangeSelected, selectedDenoms, isBorrow } = props
|
||||||
|
const columns = useAssetSelectColumns(isBorrow)
|
||||||
|
const { data: markets } = useMarketAssets()
|
||||||
|
const getCoinValue = useGetCoinValue()
|
||||||
|
|
||||||
|
const defaultSelected = useMemo(() => {
|
||||||
|
const selectableAssets = assets
|
||||||
|
return selectableAssets.reduce(
|
||||||
|
(acc, asset, index) => {
|
||||||
|
if (selectedDenoms?.includes(asset.denom)) {
|
||||||
|
acc[index] = true
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{} as { [key: number]: boolean },
|
||||||
|
)
|
||||||
|
}, [selectedDenoms, assets])
|
||||||
|
|
||||||
|
const [selected, setSelected] = useState<RowSelectionState>(defaultSelected)
|
||||||
|
|
||||||
|
const balances = useStore((s) => s.balances)
|
||||||
|
const tableData: AssetTableRow[] = useMemo(() => {
|
||||||
|
return assets.map((asset) => {
|
||||||
|
const balancesForAsset = balances.find(byDenom(asset.denom))
|
||||||
|
const coin = BNCoin.fromDenomAndBigNumber(asset.denom, BN(balancesForAsset?.amount ?? '0'))
|
||||||
|
const value = getCoinValue(coin)
|
||||||
|
return {
|
||||||
|
asset,
|
||||||
|
balance: balancesForAsset?.amount ?? '0',
|
||||||
|
value,
|
||||||
|
market: markets.find((market) => market.denom === asset.denom),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [balances, assets, markets, getCoinValue])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const selectedAssets = assets.filter((_, index) => selected[index])
|
||||||
|
|
||||||
|
const newSelectedDenoms = selectedAssets
|
||||||
|
.sort((a, b) => a.symbol.localeCompare(b.symbol))
|
||||||
|
.map((asset) => asset.denom)
|
||||||
|
if (
|
||||||
|
selectedDenoms.length === newSelectedDenoms.length &&
|
||||||
|
newSelectedDenoms.every((denom) => selectedDenoms.includes(denom))
|
||||||
|
)
|
||||||
|
return
|
||||||
|
onChangeSelected(newSelectedDenoms)
|
||||||
|
}, [selected, props, assets, selectedDenoms, onChangeSelected])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
title='Assets'
|
||||||
|
hideCard={true}
|
||||||
|
columns={columns}
|
||||||
|
data={tableData}
|
||||||
|
initialSorting={[{ id: isBorrow ? 'asset.borrowRate' : 'value', desc: !isBorrow }]}
|
||||||
|
setRowSelection={setSelected}
|
||||||
|
selectedRows={selected}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
@ -1,94 +0,0 @@
|
|||||||
import { ColumnDef } from '@tanstack/react-table'
|
|
||||||
import React from 'react'
|
|
||||||
|
|
||||||
import AssetImage from 'components/common/assets/AssetImage'
|
|
||||||
import AssetRate from 'components/common/assets/AssetRate'
|
|
||||||
import Checkbox from 'components/common/Checkbox'
|
|
||||||
import DisplayCurrency from 'components/common/DisplayCurrency'
|
|
||||||
import { FormattedNumber } from 'components/common/FormattedNumber'
|
|
||||||
import Text from 'components/common/Text'
|
|
||||||
import { BNCoin } from 'types/classes/BNCoin'
|
|
||||||
import { demagnify, formatPercent } from 'utils/formatters'
|
|
||||||
|
|
||||||
function showBorrowRate(data: AssetTableRow[]) {
|
|
||||||
const assetData = data.length && (data[0].asset as BorrowAsset)
|
|
||||||
return !!(assetData && assetData?.borrowRate)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function useAssetTableColumns(isBorrow: boolean) {
|
|
||||||
return React.useMemo<ColumnDef<AssetTableRow>[]>(
|
|
||||||
() => [
|
|
||||||
{
|
|
||||||
header: 'Asset',
|
|
||||||
accessorKey: 'symbol',
|
|
||||||
id: 'symbol',
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const market = row.original.market
|
|
||||||
const borrowAsset = row.original.asset as BorrowAsset
|
|
||||||
const showRate = !borrowAsset?.borrowRate
|
|
||||||
const apy = isBorrow ? market?.apy.borrow : market?.apy.deposit
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='flex items-center'>
|
|
||||||
<Checkbox
|
|
||||||
name={`asset-${borrowAsset.id.toLowerCase()}`}
|
|
||||||
checked={row.getIsSelected()}
|
|
||||||
onChange={row.getToggleSelectedHandler()}
|
|
||||||
noMouseEvents
|
|
||||||
/>
|
|
||||||
<AssetImage asset={borrowAsset} size={24} className='ml-4' />
|
|
||||||
<div className='ml-2 text-left'>
|
|
||||||
<Text size='sm' className='mb-0.5 text-white'>
|
|
||||||
{borrowAsset.symbol}
|
|
||||||
</Text>
|
|
||||||
{showRate && market ? (
|
|
||||||
<AssetRate
|
|
||||||
rate={apy ?? 0}
|
|
||||||
isEnabled={market.borrowEnabled}
|
|
||||||
className='text-xs'
|
|
||||||
type='apy'
|
|
||||||
orientation='rtl'
|
|
||||||
suffix
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Text size='xs'>{borrowAsset.name}</Text>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'details',
|
|
||||||
header: (data) => {
|
|
||||||
const tableData = data.table.options.data as AssetTableRow[]
|
|
||||||
if (showBorrowRate(tableData)) return 'Borrow Rate'
|
|
||||||
return 'Balance'
|
|
||||||
},
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const asset = row.original.asset as BorrowAsset
|
|
||||||
const balance = row.original.balance
|
|
||||||
if (asset?.borrowRate)
|
|
||||||
return (
|
|
||||||
<Text size='sm' className='mb-0.5 text-white'>
|
|
||||||
{formatPercent(asset.borrowRate ?? 0)}
|
|
||||||
</Text>
|
|
||||||
)
|
|
||||||
if (!balance) return null
|
|
||||||
const coin = new BNCoin({ denom: row.original.asset.denom, amount: balance })
|
|
||||||
return (
|
|
||||||
<div className='flex flex-wrap items-center'>
|
|
||||||
<DisplayCurrency coin={coin} className='mb-0.5 w-full text-white' />
|
|
||||||
<FormattedNumber
|
|
||||||
className='w-full text-xs'
|
|
||||||
options={{ minDecimals: 2, maxDecimals: asset.decimals }}
|
|
||||||
amount={demagnify(balance, asset)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[isBorrow],
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useMemo, useState } from 'react'
|
import { useCallback, useMemo, useState } from 'react'
|
||||||
|
|
||||||
import AssetSelectTable from 'components/Modals/AssetsSelect/AssetSelectTable'
|
import AssetsSelect from 'components/Modals/AssetsSelect'
|
||||||
import SearchBar from 'components/common/SearchBar'
|
import SearchBar from 'components/common/SearchBar'
|
||||||
import useAllAssets from 'hooks/assets/useAllAssets'
|
import useAllAssets from 'hooks/assets/useAllAssets'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
@ -59,8 +59,7 @@ export default function WalletAssetsModalContent(props: Props) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='max-h-[446px] overflow-y-scroll scrollbar-hide'>
|
<div className='max-h-[446px] overflow-y-scroll scrollbar-hide'>
|
||||||
<AssetSelectTable
|
<AssetsSelect
|
||||||
isBorrow={isBorrow}
|
|
||||||
assets={filteredAssets}
|
assets={filteredAssets}
|
||||||
onChangeSelected={onChangeSelect}
|
onChangeSelected={onChangeSelect}
|
||||||
selectedDenoms={selectedDenoms}
|
selectedDenoms={selectedDenoms}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
|
import Modal from 'components/Modals/Modal'
|
||||||
import Button from 'components/common/Button'
|
import Button from 'components/common/Button'
|
||||||
import { CircularProgress } from 'components/common/CircularProgress'
|
import { CircularProgress } from 'components/common/CircularProgress'
|
||||||
import DisplayCurrency from 'components/common/DisplayCurrency'
|
import DisplayCurrency from 'components/common/DisplayCurrency'
|
||||||
import DoubleLogo from 'components/common/DoubleLogo'
|
import DoubleLogo from 'components/common/DoubleLogo'
|
||||||
import { FormattedNumber } from 'components/common/FormattedNumber'
|
import { FormattedNumber } from 'components/common/FormattedNumber'
|
||||||
import Modal from 'components/Modals/Modal'
|
|
||||||
import Text from 'components/common/Text'
|
import Text from 'components/common/Text'
|
||||||
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
|
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
|
||||||
import { LocalStorageKeys } from 'constants/localStorageKeys'
|
import { LocalStorageKeys } from 'constants/localStorageKeys'
|
||||||
@ -73,17 +73,19 @@ export default function WithdrawFromVaultsModal() {
|
|||||||
primaryDenom={vault.denoms.primary}
|
primaryDenom={vault.denoms.primary}
|
||||||
secondaryDenom={vault.denoms.secondary}
|
secondaryDenom={vault.denoms.secondary}
|
||||||
/>
|
/>
|
||||||
<div className='flex flex-wrap flex-1'>
|
<div className='flex flex-wrap flex-grow'>
|
||||||
<Text className='w-full'>{vault.name}</Text>
|
<Text size='sm' className='w-full'>
|
||||||
<Text size='sm' className='w-full text-white/50'>
|
{vault.name}
|
||||||
|
</Text>
|
||||||
|
<Text size='xs' className='w-full text-white/50'>
|
||||||
Unlocked
|
Unlocked
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-wrap'>
|
<div className='flex flex-wrap flex-shrink max-w-1/2'>
|
||||||
<DisplayCurrency coin={coin} className='w-full text-right' />
|
<DisplayCurrency coin={coin} className='w-full text-sm text-right' />
|
||||||
<FormattedNumber
|
<FormattedNumber
|
||||||
amount={Number(primaryAssetAmount.toPrecision(4))}
|
amount={Number(primaryAssetAmount.toPrecision(4))}
|
||||||
className='w-full text-sm text-right text-white/50'
|
className='w-full text-xs text-right text-white/50'
|
||||||
options={{
|
options={{
|
||||||
suffix: ` ${vault.symbols.primary}`,
|
suffix: ` ${vault.symbols.primary}`,
|
||||||
maxDecimals: primaryAsset.decimals,
|
maxDecimals: primaryAsset.decimals,
|
||||||
@ -92,7 +94,7 @@ export default function WithdrawFromVaultsModal() {
|
|||||||
/>
|
/>
|
||||||
<FormattedNumber
|
<FormattedNumber
|
||||||
amount={Number(secondaryAssetAmount.toPrecision(4))}
|
amount={Number(secondaryAssetAmount.toPrecision(4))}
|
||||||
className='w-full text-sm text-right text-white/50'
|
className='w-full text-xs text-right text-white/50'
|
||||||
options={{
|
options={{
|
||||||
suffix: ` ${vault.symbols.secondary}`,
|
suffix: ` ${vault.symbols.secondary}`,
|
||||||
maxDecimals: secondaryAsset.decimals,
|
maxDecimals: secondaryAsset.decimals,
|
||||||
|
@ -41,7 +41,6 @@ export default function useAccountBalancesColumns(
|
|||||||
type={row.original.type}
|
type={row.original.type}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
|
||||||
sortingFn: valueSortingFn,
|
sortingFn: valueSortingFn,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -165,7 +165,7 @@ export default function AccountFundContent(props: Props) {
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
className='w-full mt-4'
|
className='w-full mt-4'
|
||||||
text='Select assets'
|
text='Select Assets'
|
||||||
color='tertiary'
|
color='tertiary'
|
||||||
rightIcon={<Plus />}
|
rightIcon={<Plus />}
|
||||||
iconClassName='w-3'
|
iconClassName='w-3'
|
||||||
|
@ -38,7 +38,6 @@ interface AmountMessageProps {
|
|||||||
function AmountMessage(props: AmountMessageProps) {
|
function AmountMessage(props: AmountMessageProps) {
|
||||||
const asset = useAsset(props.coin.denom)
|
const asset = useAsset(props.coin.denom)
|
||||||
if (!asset) return null
|
if (!asset) return null
|
||||||
console.log(props.coin.amount.toNumber())
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={props.coin.denom} className='flex gap-1'>
|
<div key={props.coin.denom} className='flex gap-1'>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import AssetImage from 'components/common/assets/AssetImage'
|
import AssetImage from 'components/common/assets/AssetImage'
|
||||||
import useAsset from 'hooks/assets/useAsset'
|
import useAsset from 'hooks/assets/useAsset'
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ export default function DoubleLogo(props: Props) {
|
|||||||
<AssetImage asset={primaryAsset} size={24} />
|
<AssetImage asset={primaryAsset} size={24} />
|
||||||
</div>
|
</div>
|
||||||
<div className='absolute'>
|
<div className='absolute'>
|
||||||
<AssetImage asset={secondaryAsset} size={16} className='ml-5 mt-5' />
|
<AssetImage asset={secondaryAsset} size={16} className='mt-5 ml-5' />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -6,10 +6,10 @@ interface Props<T> {
|
|||||||
table: TanstackTable<T>
|
table: TanstackTable<T>
|
||||||
renderExpanded?: (row: TanstackRow<T>, table: TanstackTable<T>) => JSX.Element
|
renderExpanded?: (row: TanstackRow<T>, table: TanstackTable<T>) => JSX.Element
|
||||||
rowClassName?: string
|
rowClassName?: string
|
||||||
rowClickHandler?: () => void
|
|
||||||
spacingClassName?: string
|
spacingClassName?: string
|
||||||
isBalancesTable?: boolean
|
isBalancesTable?: boolean
|
||||||
className?: string
|
className?: string
|
||||||
|
isSelectable?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBorderColor(row: AccountBalanceRow) {
|
function getBorderColor(row: AccountBalanceRow) {
|
||||||
@ -24,14 +24,19 @@ export default function Row<T>(props: Props<T>) {
|
|||||||
key={`${props.row.id}-row`}
|
key={`${props.row.id}-row`}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'group/row transition-bg',
|
'group/row transition-bg',
|
||||||
props.renderExpanded && 'hover:cursor-pointer',
|
(props.renderExpanded || props.isSelectable) && 'hover:cursor-pointer',
|
||||||
canExpand && props.row.getIsExpanded() ? 'is-expanded bg-black/20' : 'hover:bg-white/5',
|
canExpand && props.row.getIsExpanded() ? 'is-expanded bg-black/20' : 'hover:bg-white/5',
|
||||||
)}
|
)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const isExpanded = props.row.getIsExpanded()
|
if (props.isSelectable) {
|
||||||
props.table.resetExpanded()
|
props.row.toggleSelected()
|
||||||
!isExpanded && props.row.toggleExpanded()
|
}
|
||||||
|
if (canExpand) {
|
||||||
|
const isExpanded = props.row.getIsExpanded()
|
||||||
|
props.table.resetExpanded()
|
||||||
|
!isExpanded && props.row.toggleExpanded()
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{props.row.getVisibleCells().map((cell) => {
|
{props.row.getVisibleCells().map((cell) => {
|
||||||
|
@ -3,6 +3,8 @@ import {
|
|||||||
flexRender,
|
flexRender,
|
||||||
getCoreRowModel,
|
getCoreRowModel,
|
||||||
getSortedRowModel,
|
getSortedRowModel,
|
||||||
|
OnChangeFn,
|
||||||
|
RowSelectionState,
|
||||||
SortingState,
|
SortingState,
|
||||||
Row as TanstackRow,
|
Row as TanstackRow,
|
||||||
Table as TanstackTable,
|
Table as TanstackTable,
|
||||||
@ -27,6 +29,8 @@ interface Props<T> {
|
|||||||
spacingClassName?: string
|
spacingClassName?: string
|
||||||
isBalancesTable?: boolean
|
isBalancesTable?: boolean
|
||||||
hideCard?: boolean
|
hideCard?: boolean
|
||||||
|
setRowSelection?: OnChangeFn<RowSelectionState>
|
||||||
|
selectedRows?: RowSelectionState
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Table<T>(props: Props<T>) {
|
export default function Table<T>(props: Props<T>) {
|
||||||
@ -37,7 +41,10 @@ export default function Table<T>(props: Props<T>) {
|
|||||||
columns: props.columns,
|
columns: props.columns,
|
||||||
state: {
|
state: {
|
||||||
sorting,
|
sorting,
|
||||||
|
rowSelection: props.selectedRows,
|
||||||
},
|
},
|
||||||
|
enableRowSelection: true,
|
||||||
|
onRowSelectionChange: props.setRowSelection,
|
||||||
onSortingChange: setSorting,
|
onSortingChange: setSorting,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
getSortedRowModel: getSortedRowModel(),
|
getSortedRowModel: getSortedRowModel(),
|
||||||
@ -80,7 +87,7 @@ export default function Table<T>(props: Props<T>) {
|
|||||||
'align-center',
|
'align-center',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span className='w-5 h-5 text-white my-auto'>
|
<span className='w-5 h-5 my-auto text-white'>
|
||||||
{header.column.getCanSort()
|
{header.column.getCanSort()
|
||||||
? {
|
? {
|
||||||
asc: <SortAsc size={16} />,
|
asc: <SortAsc size={16} />,
|
||||||
@ -112,6 +119,7 @@ export default function Table<T>(props: Props<T>) {
|
|||||||
renderExpanded={props.renderExpanded}
|
renderExpanded={props.renderExpanded}
|
||||||
spacingClassName={props.spacingClassName}
|
spacingClassName={props.spacingClassName}
|
||||||
isBalancesTable={props.isBalancesTable}
|
isBalancesTable={props.isBalancesTable}
|
||||||
|
isSelectable={!!props.setRowSelection}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -2,4 +2,5 @@ interface AssetTableRow {
|
|||||||
balance?: string
|
balance?: string
|
||||||
asset: BorrowAsset | Asset
|
asset: BorrowAsset | Asset
|
||||||
market?: Market
|
market?: Market
|
||||||
|
value?: BigNumber
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user