From d9e3cf88344352bd084046b7ac3b9205894e3e3c Mon Sep 17 00:00:00 2001 From: sophian Date: Thu, 28 Sep 2023 18:49:30 -0400 Subject: [PATCH] Addsort buttons to table and view all button --- .../Portfolio/TransactionTypeChip.tsx | 8 +- .../src/components/Portfolio/Transactions.tsx | 136 ++++++++++++++---- centrifuge-app/src/pages/Portfolio/index.tsx | 2 +- centrifuge-js/src/modules/pools.ts | 33 ++--- 4 files changed, 132 insertions(+), 47 deletions(-) diff --git a/centrifuge-app/src/components/Portfolio/TransactionTypeChip.tsx b/centrifuge-app/src/components/Portfolio/TransactionTypeChip.tsx index 07ddb6b5da..4efe785dc3 100644 --- a/centrifuge-app/src/components/Portfolio/TransactionTypeChip.tsx +++ b/centrifuge-app/src/components/Portfolio/TransactionTypeChip.tsx @@ -13,11 +13,11 @@ const states: { } } = { INVEST_ORDER_UPDATE: { - label: 'Pending invest', + label: 'Invest order placed', status: 'default', }, REDEEM_ORDER_UPDATE: { - label: 'Pending redemption', + label: 'Redeem order placed', status: 'default', }, INVEST_ORDER_CANCEL: { @@ -29,11 +29,11 @@ const states: { status: 'default', }, INVEST_EXECUTION: { - label: 'Invest', + label: 'Invest executed', status: 'ok', }, REDEEM_EXECUTION: { - label: 'Redeem', + label: 'Redeem executed', status: 'info', }, TRANSFER_IN: { diff --git a/centrifuge-app/src/components/Portfolio/Transactions.tsx b/centrifuge-app/src/components/Portfolio/Transactions.tsx index 84f7d1e09a..27e436520a 100644 --- a/centrifuge-app/src/components/Portfolio/Transactions.tsx +++ b/centrifuge-app/src/components/Portfolio/Transactions.tsx @@ -1,10 +1,28 @@ -import { BorrowerTransactionType, CurrencyBalance, InvestorTransactionType, Pool } from '@centrifuge/centrifuge-js' +import { + BorrowerTransactionType, + CurrencyBalance, + InvestorTransactionType, + Pool, + TokenBalance, +} from '@centrifuge/centrifuge-js' import { useCentrifugeUtils } from '@centrifuge/centrifuge-react' -import { Box, Grid, IconExternalLink, Stack, Text } from '@centrifuge/fabric' +import { + AnchorButton, + Box, + Grid, + IconChevronDown, + IconChevronUp, + IconExternalLink, + IconEye, + Shelf, + Stack, + Text, +} from '@centrifuge/fabric' import * as React from 'react' -import { Link, useRouteMatch } from 'react-router-dom' +import { useRouteMatch } from 'react-router-dom' +import styled from 'styled-components' import { formatDate } from '../../utils/date' -import { formatBalanceAbbreviated } from '../../utils/formatting' +import { formatBalance } from '../../utils/formatting' import { useAddress } from '../../utils/useAddress' import { usePool, usePoolMetadata, useTransactionsByAddress } from '../../utils/usePools' import { TransactionTypeChip } from './TransactionTypeChip' @@ -22,20 +40,34 @@ export function Transactions({ count, txTypes }: AddressTransactionsProps) { const address = useAddress() const transactions = useTransactionsByAddress(formatAddress(address || '')) const match = useRouteMatch('/portfolio/transactions') - - const investorTransactions = - transactions?.investorTransactions - .filter((tx) => (txTypes ? txTypes?.includes(tx.type) : tx)) - .map((tx) => { - return { - date: new Date(tx.timestamp).getTime(), - type: tx.type, - amount: tx.tokenAmount, - poolId: tx.poolId, - hash: tx.hash, - trancheId: tx.trancheId, - } - }) || [] + const [sortKey, setSortKey] = React.useState<'date' | 'amount'>('date') + const [sortOrder, setSortOrder] = React.useState<'asc' | 'desc'>('desc') + + const investorTransactions = React.useMemo(() => { + const txs = + transactions?.investorTransactions + .filter((tx) => (txTypes ? txTypes?.includes(tx.type) : tx)) + .map((tx) => { + return { + date: new Date(tx.timestamp).getTime(), + type: tx.type, + poolId: tx.poolId, + hash: tx.hash, + trancheId: tx.trancheId, + amount: tx.currencyAmount, + } + }) + .sort((a, b) => { + if (sortKey === 'date') { + return new Date(b.date).getTime() - new Date(a.date).getTime() + } else if (sortKey === 'amount') { + return b.amount.toDecimal().minus(a.amount.toDecimal()).toNumber() + } else { + return 1 + } + }) || [] + return sortOrder === 'asc' ? txs : txs.reverse() + }, [sortKey, transactions, sortOrder]) return !!investorTransactions.slice(0, count ?? investorTransactions.length) ? ( @@ -46,14 +78,52 @@ export function Transactions({ count, txTypes }: AddressTransactionsProps) { Action - - Transaction date + { + setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc') + setSortKey('date') + }} + gap={1} + > + Transaction date + + + + + Token - + { + setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc') + setSortKey('amount') + }} + gap={1} + justifyContent="flex-end" + > Amount - + + + + + @@ -64,7 +134,13 @@ export function Transactions({ count, txTypes }: AddressTransactionsProps) { ))} - {match ? null : View all} + + {match ? null : ( + + View all + + )} + ) : null } @@ -72,12 +148,20 @@ export function Transactions({ count, txTypes }: AddressTransactionsProps) { export type TransactionCardProps = { date: number type: InvestorTransactionType | BorrowerTransactionType - amount: CurrencyBalance + amount: CurrencyBalance | TokenBalance poolId: string hash: string trancheId?: string } +const SortButton = styled(Shelf)` + background: initial; + border: none; + cursor: pointer; + display: inline-flex; + align-items: flex-start; +` + export function TransactionListItem({ date, type, amount, poolId, hash, trancheId }: TransactionCardProps) { const pool = usePool(poolId) as Pool const { data } = usePoolMetadata(pool) @@ -112,7 +196,7 @@ export function TransactionListItem({ date, type, amount, poolId, hash, trancheI - {!!token ? token.currency?.name.split(data.pool?.name || '') : data.pool?.name} + {!!token ? token?.currency?.name.split(`${data?.pool?.name} ` || '').at(-1) : data.pool?.name} {!!token && ( @@ -123,7 +207,7 @@ export function TransactionListItem({ date, type, amount, poolId, hash, trancheI - {formatBalanceAbbreviated(amount, pool.currency.symbol)} + {formatBalance(amount.toDecimal(), pool.currency.symbol)} diff --git a/centrifuge-app/src/pages/Portfolio/index.tsx b/centrifuge-app/src/pages/Portfolio/index.tsx index 5eab454d08..4f7a5f2f10 100644 --- a/centrifuge-app/src/pages/Portfolio/index.tsx +++ b/centrifuge-app/src/pages/Portfolio/index.tsx @@ -19,7 +19,7 @@ export function PortfolioPage() { } function Portfolio() { - const address = useAddress() + const address = useAddress('substrate') const theme = useTheme() if (!address) { diff --git a/centrifuge-js/src/modules/pools.ts b/centrifuge-js/src/modules/pools.ts index 39d826d398..625eea78f2 100644 --- a/centrifuge-js/src/modules/pools.ts +++ b/centrifuge-js/src/modules/pools.ts @@ -2047,25 +2047,26 @@ export function getPoolsModule(inst: Centrifuge) { return $query.pipe( switchMap((data) => { - const $investorTransactions = from(data?.investorTransactions.nodes || []) - // .pipe(distinct(({ hash }) => hash)) - .pipe( - mergeMap((entry) => { - return getPoolCurrency([entry.poolId]).pipe( - map((poolCurrency) => ({ - ...entry, - tokenAmount: new CurrencyBalance(entry.tokenAmount || 0, poolCurrency.decimals), - tokenPrice: new Price(entry.tokenPrice || 0), - currencyAmount: new CurrencyBalance(entry.currencyAmount || 0, poolCurrency.decimals), - trancheId: entry.trancheId.split('-')[1], - })) - ) - }), - toArray() - ) + const $investorTransactions = from(data?.investorTransactions.nodes || []).pipe( + mergeMap((entry) => { + return getPoolCurrency([entry.poolId]).pipe( + map((poolCurrency) => ({ + ...entry, + tokenAmount: new TokenBalance(entry.tokenAmount || 0, poolCurrency.decimals), + tokenPrice: new Price(entry.tokenPrice || 0), + currencyAmount: new CurrencyBalance(entry.currencyAmount || 0, poolCurrency.decimals), + trancheId: entry.trancheId.split('-')[1], + })) + ) + }), + toArray() + ) return forkJoin([$investorTransactions]).pipe( map(([investorTransactions]) => { + investorTransactions.sort((a, b) => { + return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime() + }) return { investorTransactions, }