From b04f244d3ea8816c5435f0be2f9cdbd963773132 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Mon, 18 Sep 2023 16:24:16 +0200 Subject: [PATCH] MP-3414: support unborrowable assets (#479) * MP-3414: support unborrowable assets * tidy: refactor * MP-3414: added Rate Tooltip to BalancesTable --- .../Account/AccountBalancesTable/index.tsx | 18 ++++--- .../{ => Asset}/AssetBalanceRow.tsx | 2 +- src/components/{ => Asset}/AssetImage.tsx | 0 src/components/Asset/AssetRate.tsx | 53 +++++++++++++++++++ src/components/Borrow/BorrowTable.tsx | 4 +- src/components/Earn/Farm/VaultLogo.tsx | 2 +- .../Earn/Lend/LendingMarketsTable.tsx | 19 +++---- src/components/Icons/InfoCircle.svg | 18 +++---- src/components/Modal.tsx | 2 + .../Modals/Account/AccountDeleteModal.tsx | 2 +- .../Modals/AssetAmountSelectActionModal.tsx | 2 +- .../Modals/AssetsSelect/AssetSelectTable.tsx | 7 ++- .../AssetsSelect/useAssetTableColumns.tsx | 28 ++++++++-- src/components/Modals/BorrowModal.tsx | 2 +- src/components/Modals/Settings/index.tsx | 2 +- src/components/Modals/WalletAssets/index.tsx | 1 + src/components/RewardsCenter.tsx | 8 +-- src/components/Select/Option.tsx | 2 +- src/components/TokenInput/index.tsx | 2 +- src/components/Tooltip/index.tsx | 5 +- .../TradeModule/AssetSelector/AssetButton.tsx | 2 +- .../TradeModule/AssetSelector/AssetItem.tsx | 2 +- .../components/Modals/AssetSelect.d.ts | 1 + 23 files changed, 132 insertions(+), 52 deletions(-) rename src/components/{ => Asset}/AssetBalanceRow.tsx (95%) rename src/components/{ => Asset}/AssetImage.tsx (100%) create mode 100644 src/components/Asset/AssetRate.tsx diff --git a/src/components/Account/AccountBalancesTable/index.tsx b/src/components/Account/AccountBalancesTable/index.tsx index 5649cb2b..03b26ef9 100644 --- a/src/components/Account/AccountBalancesTable/index.tsx +++ b/src/components/Account/AccountBalancesTable/index.tsx @@ -13,6 +13,7 @@ import { useLocation, useNavigate } from 'react-router-dom' import { getAmountChangeColor } from 'components/Account/AccountBalancesTable/functions' import useAccountBalanceData from 'components/Account/AccountBalancesTable/useAccountBalanceData' import AccountFundFullPage from 'components/Account/AccountFund/AccountFundFullPage' +import AssetRate from 'components/Asset/AssetRate' import ActionButton from 'components/Button/ActionButton' import DisplayCurrency from 'components/DisplayCurrency' import { FormattedNumber } from 'components/FormattedNumber' @@ -21,8 +22,10 @@ import Text from 'components/Text' import { ASSETS } from 'constants/assets' import { ORACLE_DENOM } from 'constants/oracle' import useCurrentAccount from 'hooks/useCurrentAccount' +import useMarketAssets from 'hooks/useMarketAssets' import useStore from 'store' import { BNCoin } from 'types/classes/BNCoin' +import { byDenom } from 'utils/array' import { getAssetByDenom } from 'utils/assets' import { demagnify, formatAmountToPrecision } from 'utils/formatters' import { getPage, getRoute } from 'utils/route' @@ -36,6 +39,7 @@ interface Props { export default function Index(props: Props) { const { account, lendingData, borrowingData, tableBodyClassName } = props + const { data: markets } = useMarketAssets() const currentAccount = useCurrentAccount() const navigate = useNavigate() const { pathname } = useLocation() @@ -126,18 +130,20 @@ export default function Index(props: Props) { cell: ({ row }) => { if (row.original.type === 'deposits') return + const isEnabled = markets.find(byDenom(row.original.denom))?.borrowEnabled ?? false return ( - ) }, }, ], - [baseCurrency.decimals], + [baseCurrency.decimals, markets], ) const table = useReactTable({ diff --git a/src/components/AssetBalanceRow.tsx b/src/components/Asset/AssetBalanceRow.tsx similarity index 95% rename from src/components/AssetBalanceRow.tsx rename to src/components/Asset/AssetBalanceRow.tsx index fe9c4beb..29a73b3e 100644 --- a/src/components/AssetBalanceRow.tsx +++ b/src/components/Asset/AssetBalanceRow.tsx @@ -1,4 +1,4 @@ -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' import DisplayCurrency from 'components/DisplayCurrency' import { FormattedNumber } from 'components/FormattedNumber' import Text from 'components/Text' diff --git a/src/components/AssetImage.tsx b/src/components/Asset/AssetImage.tsx similarity index 100% rename from src/components/AssetImage.tsx rename to src/components/Asset/AssetImage.tsx diff --git a/src/components/Asset/AssetRate.tsx b/src/components/Asset/AssetRate.tsx new file mode 100644 index 00000000..8f8f468f --- /dev/null +++ b/src/components/Asset/AssetRate.tsx @@ -0,0 +1,53 @@ +import classNames from 'classnames' + +import { FormattedNumber } from 'components/FormattedNumber' +import { InfoCircle } from 'components/Icons' +import Text from 'components/Text' +import { Tooltip } from 'components/Tooltip' + +interface Props { + rate: number + isEnabled: boolean + type: 'apy' | 'apr' + orientation: 'ltr' | 'rtl' + className?: string + suffix?: boolean +} + +interface TooltipProps { + orientation: Props['orientation'] +} + +function RateTooltip(props: TooltipProps) { + return ( + + + + ) +} + +export default function AssetRate(props: Props) { + const { rate, isEnabled, type, orientation, className } = props + const suffix = type === 'apy' ? 'APY' : 'APR' + + if (!isEnabled) + return ( + + {orientation === 'ltr' && }N/A + {orientation === 'rtl' && } + + ) + + return ( + + ) +} diff --git a/src/components/Borrow/BorrowTable.tsx b/src/components/Borrow/BorrowTable.tsx index 85a4434e..440693e3 100644 --- a/src/components/Borrow/BorrowTable.tsx +++ b/src/components/Borrow/BorrowTable.tsx @@ -2,7 +2,7 @@ import { ColumnDef, Row, Table } from '@tanstack/react-table' import { useCallback, useMemo } from 'react' import AmountAndValue from 'components/AmountAndValue' -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' import BorrowActionButtons from 'components/Borrow/BorrowActionButtons' import { FormattedNumber } from 'components/FormattedNumber' import { ChevronDown, ChevronUp } from 'components/Icons' @@ -11,8 +11,8 @@ import AssetListTable from 'components/MarketAssetTable' import MarketAssetTableRow from 'components/MarketAssetTable/MarketAssetTableRow' import MarketDetails from 'components/MarketAssetTable/MarketDetails' import TitleAndSubCell from 'components/TitleAndSubCell' -import { getEnabledMarketAssets } from 'utils/assets' import { BN_ZERO } from 'constants/math' +import { getEnabledMarketAssets } from 'utils/assets' interface Props { title: string diff --git a/src/components/Earn/Farm/VaultLogo.tsx b/src/components/Earn/Farm/VaultLogo.tsx index b11c9b66..6c662fc3 100644 --- a/src/components/Earn/Farm/VaultLogo.tsx +++ b/src/components/Earn/Farm/VaultLogo.tsx @@ -1,4 +1,4 @@ -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' import { getAssetByDenom } from 'utils/assets' interface Props { diff --git a/src/components/Earn/Lend/LendingMarketsTable.tsx b/src/components/Earn/Lend/LendingMarketsTable.tsx index 3bca4ed5..63ce1f8a 100644 --- a/src/components/Earn/Lend/LendingMarketsTable.tsx +++ b/src/components/Earn/Lend/LendingMarketsTable.tsx @@ -2,14 +2,14 @@ import { ColumnDef, Row, Table } from '@tanstack/react-table' import { useCallback, useMemo } from 'react' import AmountAndValue from 'components/AmountAndValue' -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' +import AssetRate from 'components/Asset/AssetRate' import LendingActionButtons from 'components/Earn/Lend/LendingActionButtons' import { FormattedNumber } from 'components/FormattedNumber' import { ChevronDown, ChevronUp } from 'components/Icons' import AssetListTable from 'components/MarketAssetTable' import MarketAssetTableRow from 'components/MarketAssetTable/MarketAssetTableRow' import MarketDetails from 'components/MarketAssetTable/MarketDetails' -import Text from 'components/Text' import TitleAndSubCell from 'components/TitleAndSubCell' import { BN_ZERO } from 'constants/math' import { convertLiquidityRateToAPR } from 'utils/formatters' @@ -83,16 +83,13 @@ export default function LendingMarketsTable(props: Props) { accessorKey: 'marketLiquidityRate', header: 'APR', cell: ({ row }) => { - if (!row.original.borrowEnabled) { - return - - } - return ( - ) }, diff --git a/src/components/Icons/InfoCircle.svg b/src/components/Icons/InfoCircle.svg index e2fa7a3e..12a60926 100644 --- a/src/components/Icons/InfoCircle.svg +++ b/src/components/Icons/InfoCircle.svg @@ -1,10 +1,8 @@ - - - - - - - - - - \ No newline at end of file + + + diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx index 5dfaa597..34950cfd 100644 --- a/src/components/Modal.tsx +++ b/src/components/Modal.tsx @@ -17,6 +17,7 @@ interface Props { modalClassName?: string onClose: () => void hideTxLoader?: boolean + dialogId?: string } export default function Modal(props: Props) { @@ -57,6 +58,7 @@ export default function Modal(props: Props) { 'backdrop:bg-black/50 backdrop:backdrop-blur-sm', modalClassName, )} + id={props.dialogId ? props.dialogId : 'modal'} > { const assets = props.assets as BorrowAsset[] return assets.reduce( @@ -44,9 +46,10 @@ export default function AssetSelectTable(props: Props) { return { asset, balance: balancesForAsset?.amount ?? '0', + market: markets.find((market) => market.denom === asset.denom), } }) - }, [balances, props.assets]) + }, [balances, props.assets, markets]) const table = useReactTable({ data: tableData, @@ -79,7 +82,7 @@ export default function AssetSelectTable(props: Props) { {table.getHeaderGroups().map((headerGroup) => ( - {headerGroup.headers.map((header, index) => { + {headerGroup.headers.map((header) => { return ( []>( @@ -19,6 +26,9 @@ export default function useAssetTableColumns() { id: 'symbol', cell: ({ row }) => { const asset = getAssetByDenom(row.original.asset.denom) as Asset + const market = row.original.market + const borrowAsset = row.original.asset as BorrowAsset + const showRate = !borrowAsset?.borrowRate return (
@@ -27,7 +37,18 @@ export default function useAssetTableColumns() { {asset.symbol} - {asset.name} + {showRate && market ? ( + + ) : ( + {asset.name} + )}
) @@ -37,8 +58,7 @@ export default function useAssetTableColumns() { id: 'details', header: (data) => { const tableData = data.table.options.data as AssetTableRow[] - const assetData = tableData.length && (tableData[0].asset as BorrowAsset) - if (assetData && assetData?.borrowRate) return 'Borrow Rate' + if (showBorrowRate(tableData)) return 'Borrow Rate' return 'Balance' }, cell: ({ row }) => { diff --git a/src/components/Modals/BorrowModal.tsx b/src/components/Modals/BorrowModal.tsx index d7aba172..0b2d1714 100644 --- a/src/components/Modals/BorrowModal.tsx +++ b/src/components/Modals/BorrowModal.tsx @@ -2,7 +2,7 @@ import BigNumber from 'bignumber.js' import { useCallback, useEffect, useMemo, useState } from 'react' import AccountSummary from 'components/Account/AccountSummary' -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' import Button from 'components/Button' import Card from 'components/Card' import DisplayCurrency from 'components/DisplayCurrency' diff --git a/src/components/Modals/Settings/index.tsx b/src/components/Modals/Settings/index.tsx index 5cc5670d..9210259a 100644 --- a/src/components/Modals/Settings/index.tsx +++ b/src/components/Modals/Settings/index.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames' import { useCallback, useMemo, useState } from 'react' -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' import Button from 'components/Button' import { ArrowCircle, Enter } from 'components/Icons' import Modal from 'components/Modal' diff --git a/src/components/Modals/WalletAssets/index.tsx b/src/components/Modals/WalletAssets/index.tsx index 07ed32d0..ec805db7 100644 --- a/src/components/Modals/WalletAssets/index.tsx +++ b/src/components/Modals/WalletAssets/index.tsx @@ -24,6 +24,7 @@ export default function WalletAssetsModal() { onClose={onClose} modalClassName='max-w-modal-xs' headerClassName='bg-white/10 border-b-white/5 border-b items-center p-4' + dialogId='wallet-assets-modal' >
diff --git a/src/components/RewardsCenter.tsx b/src/components/RewardsCenter.tsx index af2e3422..bb063a1b 100644 --- a/src/components/RewardsCenter.tsx +++ b/src/components/RewardsCenter.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useMemo, useState } from 'react' -import AssetBalanceRow from 'components/AssetBalanceRow' +import AssetBalanceRow from 'components/Asset/AssetBalanceRow' import Button from 'components/Button' import DisplayCurrency from 'components/DisplayCurrency' import Divider from 'components/Divider' @@ -10,6 +10,7 @@ import Text from 'components/Text' import { ASSETS } from 'constants/assets' import { DEFAULT_SETTINGS } from 'constants/defaultSettings' import { DISPLAY_CURRENCY_KEY } from 'constants/localStore' +import { ORACLE_DENOM } from 'constants/oracle' import useCurrentAccount from 'hooks/useCurrentAccount' import useLocalStorage from 'hooks/useLocalStorage' import usePrices from 'hooks/usePrices' @@ -20,7 +21,6 @@ import { BNCoin } from 'types/classes/BNCoin' import { byDenom } from 'utils/array' import { defaultFee } from 'utils/constants' import { formatAmountWithSymbol, getCoinValue } from 'utils/formatters' -import { ORACLE_DENOM } from 'constants/oracle' const renderIncentives = (unclaimedRewards: BNCoin[]) => { if (unclaimedRewards.length === 0) @@ -48,10 +48,6 @@ export default function RewardsCenter() { const [isConfirming, setIsConfirming] = useState(false) const [estimatedFee, setEstimatedFee] = useState(defaultFee) const [showRewardsCenter, setShowRewardsCenter] = useToggle() - const [displayCurrency] = useLocalStorage( - DISPLAY_CURRENCY_KEY, - DEFAULT_SETTINGS.displayCurrency, - ) const claimRewards = useStore((s) => s.claimRewards) const { data: prices } = usePrices() const { data: unclaimedRewards } = useUnclaimedRewards() diff --git a/src/components/Select/Option.tsx b/src/components/Select/Option.tsx index 1fde17c7..b70983c8 100644 --- a/src/components/Select/Option.tsx +++ b/src/components/Select/Option.tsx @@ -1,6 +1,6 @@ import classNames from 'classnames' -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' import DisplayCurrency from 'components/DisplayCurrency' import { ChevronDown, ChevronRight } from 'components/Icons' import Text from 'components/Text' diff --git a/src/components/TokenInput/index.tsx b/src/components/TokenInput/index.tsx index 27697718..4194b8b5 100644 --- a/src/components/TokenInput/index.tsx +++ b/src/components/TokenInput/index.tsx @@ -1,7 +1,7 @@ import BigNumber from 'bignumber.js' import classNames from 'classnames' -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' import Button from 'components/Button' import DisplayCurrency from 'components/DisplayCurrency' import { FormattedNumber } from 'components/FormattedNumber' diff --git a/src/components/Tooltip/index.tsx b/src/components/Tooltip/index.tsx index 1c27dc7b..38d2c552 100644 --- a/src/components/Tooltip/index.tsx +++ b/src/components/Tooltip/index.tsx @@ -23,9 +23,12 @@ export type TooltipType = 'info' | 'warning' | 'error' export const Tooltip = (props: Props) => { const [reduceMotion] = useLocalStorage(REDUCE_MOTION_KEY, DEFAULT_SETTINGS.reduceMotion) + const isInWalletAssetModal = document.getElementById('wallet-assets-modal') + const isInModal = document.getElementById('modal') + return ( document.querySelector('dialog[open]') ?? document.body} + appendTo={() => isInWalletAssetModal ?? isInModal ?? document.body} interactive={props.interactive} animation={false} delay={[props.delay ?? 0, 0]} diff --git a/src/components/Trade/TradeModule/AssetSelector/AssetButton.tsx b/src/components/Trade/TradeModule/AssetSelector/AssetButton.tsx index 355e5adc..9ed9adbf 100644 --- a/src/components/Trade/TradeModule/AssetSelector/AssetButton.tsx +++ b/src/components/Trade/TradeModule/AssetSelector/AssetButton.tsx @@ -1,4 +1,4 @@ -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' import Button from 'components/Button' interface Props { diff --git a/src/components/Trade/TradeModule/AssetSelector/AssetItem.tsx b/src/components/Trade/TradeModule/AssetSelector/AssetItem.tsx index 121538e1..2947bf29 100644 --- a/src/components/Trade/TradeModule/AssetSelector/AssetItem.tsx +++ b/src/components/Trade/TradeModule/AssetSelector/AssetItem.tsx @@ -1,4 +1,4 @@ -import AssetImage from 'components/AssetImage' +import AssetImage from 'components/Asset/AssetImage' import DisplayCurrency from 'components/DisplayCurrency' import { StarFilled, StarOutlined } from 'components/Icons' import Text from 'components/Text' diff --git a/src/types/interfaces/components/Modals/AssetSelect.d.ts b/src/types/interfaces/components/Modals/AssetSelect.d.ts index 3770c1db..e9715164 100644 --- a/src/types/interfaces/components/Modals/AssetSelect.d.ts +++ b/src/types/interfaces/components/Modals/AssetSelect.d.ts @@ -1,4 +1,5 @@ interface AssetTableRow { balance?: string asset: BorrowAsset | Asset + market?: Market }