diff --git a/centrifuge-app/src/components/Charts/PoolPerformanceChart.tsx b/centrifuge-app/src/components/Charts/PoolPerformanceChart.tsx index 6d6e0f133..b4a7b07ab 100644 --- a/centrifuge-app/src/components/Charts/PoolPerformanceChart.tsx +++ b/centrifuge-app/src/components/Charts/PoolPerformanceChart.tsx @@ -276,11 +276,7 @@ function PoolPerformanceChart() { tickFormatter={(tick: number) => formatBalanceAbbreviated(tick, '', 2)} yAxisId="right" orientation="right" - domain={ - selectedTabIndex === 0 - ? ['auto', 'auto'] - : [(dataMin: number) => [Math.round(dataMin)], (dataMax: number) => [Math.round(dataMax)]] - } + domain={selectedTabIndex === 0 ? ['auto', 'auto'] : ['dataMin', 'dataMax']} /> {formatDate(payload[0].payload.day)} {payload.map(({ name, value }, index) => { + const hasSeniorTranche = payload.length >= 3 + const labelMap: Record = { nav: 'NAV', - juniorTokenPrice: 'Junior Token Price', + juniorTokenPrice: hasSeniorTranche ? 'Junior Token Price' : 'Token Price', seniorTokenPrice: 'Senior Token Price', - juniorAPY: 'Junior APY', + juniorAPY: hasSeniorTranche ? 'Junior APY' : 'APY', seniorAPY: 'Senior APY', default: 'Cash', } diff --git a/centrifuge-app/src/components/DataTable.tsx b/centrifuge-app/src/components/DataTable.tsx index 73fc0ac58..37c927dbe 100644 --- a/centrifuge-app/src/components/DataTable.tsx +++ b/centrifuge-app/src/components/DataTable.tsx @@ -51,6 +51,7 @@ export type DataTableProps = { pageSize?: number page?: number headerStyles?: React.CSSProperties + hideBorder?: boolean } & GroupedProps export type OrderBy = 'asc' | 'desc' @@ -101,11 +102,22 @@ export const DataTable = >({ page = 1, headerStyles, scrollable = false, + hideBorder, }: DataTableProps) => { + const tableRef = React.useRef(null) + const [offsetTop, setOffsetTop] = React.useState(0) const [orderBy, setOrderBy] = React.useState>( defaultSortKey ? { [defaultSortKey]: defaultSortOrder } : {} ) + React.useEffect(() => { + if (tableRef.current) { + const rect = tableRef.current.getBoundingClientRect() + const offsetFromTopOfScreen = rect.top + window.scrollY + setOffsetTop(offsetFromTopOfScreen) + } + }, []) + const [currentSortKey, setCurrentSortKey] = React.useState(defaultSortKey || '') const updateSortOrder = (sortKey: Column['sortKey']) => { @@ -125,11 +137,19 @@ export const DataTable = >({ const templateColumns = `[start] ${columns.map((col) => col.width ?? 'minmax(min-content, 1fr)').join(' ')} [end]` return ( - + {showHeader && ( - + {columns.map((col, i) => ( - + {col?.header && typeof col.header !== 'string' && col?.sortKey && React.isValidElement(col.header) ? React.cloneElement(col.header as React.ReactElement, { @@ -142,6 +162,7 @@ export const DataTable = >({ ))} )} + {pinnedData?.map((row, i) => ( >({ to={onRowClicked ? onRowClicked(row) : undefined} key={keyField ? row[keyField] : i} tabIndex={onRowClicked ? 0 : undefined} + hideBorder={hideBorder} > {columns.map((col, index) => ( @@ -167,6 +189,7 @@ export const DataTable = >({ to={onRowClicked ? onRowClicked(row) : undefined} key={keyField ? row[keyField] : i} tabIndex={onRowClicked ? 0 : undefined} + hideBorder={hideBorder} > {columns.map((col, index) => ( >({ })} {/* summary row is not included in sorting */} {summary && ( - + {columns.map((col, i) => ( {col.cell(summary, i)} @@ -202,11 +225,12 @@ export const DataTable = >({ ) } -const TableGrid = styled(Grid)<{ scrollable?: boolean }>` - ${({ scrollable }) => +const TableGrid = styled(Grid)<{ scrollable?: boolean; offsetTop?: number }>` + ${({ scrollable, offsetTop }) => scrollable && css({ - maxHeight: 'calc(100vh - 180px)', + maxHeight: `calc(100vh - ${offsetTop}px)`, + paddingBottom: 20, overflowY: 'auto', overflowX: 'auto', })} @@ -216,31 +240,37 @@ const Row = styled('div')` display: grid; grid-template-columns: subgrid; grid-column: start / end; - box-shadow: ${({ theme }) => `-1px 0 0 0 ${theme.colors.borderPrimary}, 1px 0 0 0 ${theme.colors.borderPrimary}`}; ` -const HeaderRow = styled(Row)<{ styles?: any; scrollable?: boolean }>(({ styles, scrollable }) => - css({ - backgroundColor: 'backgroundSecondary', - borderStyle: 'solid', - borderWidth: '1px 0', - borderColor: 'borderPrimary', - position: scrollable ? 'sticky' : 'static', - top: scrollable ? 0 : 'auto', - zIndex: scrollable ? 10 : 'auto', - borderTopLeftRadius: '8px', - borderTopRightRadius: '8px', - ...styles, - }) +const HeaderRow = styled(Row)<{ styles?: any; scrollable?: boolean; hideBorder?: boolean }>( + ({ styles, scrollable, hideBorder }) => + css({ + backgroundColor: 'backgroundSecondary', + borderStyle: 'solid', + borderWidth: hideBorder ? 0 : 1, + borderColor: hideBorder ? 'transparent' : 'borderPrimary', + position: scrollable ? 'sticky' : 'static', + top: scrollable ? 0 : 'auto', + zIndex: scrollable ? 10 : 'auto', + borderTopLeftRadius: hideBorder ? 0 : '8px', + borderTopRightRadius: hideBorder ? 0 : '8px', + ...styles, + }) ) export const DataRow = styled(Row)` - ${({ hoverable, as: comp }) => + ${({ hoverable, as: comp, hideBorder }) => css({ width: '100%', borderBottomStyle: 'solid', - borderBottomWidth: '1px', - borderBottomColor: 'borderPrimary', + borderBottomWidth: hideBorder ? 0 : '1px', + borderBottomColor: hideBorder ? 'transparent' : 'borderPrimary', + borderLeftStyle: 'solid', + borderLeftWidth: hideBorder ? 0 : '1px', + borderLeftColor: hideBorder ? 'transparent' : 'borderPrimary', + borderRightStyle: 'solid', + borderRightWidth: hideBorder ? 0 : '1px', + borderRightColor: hideBorder ? 'transparent' : 'borderPrimary', backgroundColor: 'transparent', // using a&:hover caused the background sometimes not to update when switching themes '&:hover': @@ -275,6 +305,13 @@ export const DataCol = styled(Text)<{ align: Column['align']; isLabel?: boolean min-width: 0; overflow: hidden; white-space: nowrap; + ${({ isLabel }) => + isLabel && + css({ + position: 'sticky', + left: 0, + zIndex: 1, + })} ${({ align }) => { switch (align) { @@ -296,10 +333,19 @@ export const DataCol = styled(Text)<{ align: Column['align']; isLabel?: boolean }} ` -const HeaderCol = styled(DataCol)` +const HeaderCol = styled(DataCol)<{ isLabel?: boolean }>` height: 32px; align-items: center; + ${({ isLabel }) => + isLabel && + css({ + position: 'sticky', + left: 0, + zIndex: 2, + backgroundColor: 'backgroundSecondary', + })} + &:has(:focus-visible) { box-shadow: inset 0 0 0 3px var(--fabric-focus); } diff --git a/centrifuge-app/src/components/IssuerSection.tsx b/centrifuge-app/src/components/IssuerSection.tsx index 0af8d87db..edf56bc06 100644 --- a/centrifuge-app/src/components/IssuerSection.tsx +++ b/centrifuge-app/src/components/IssuerSection.tsx @@ -3,6 +3,7 @@ import { useCentrifuge } from '@centrifuge/centrifuge-react' import { AnchorButton, Box, + Grid, IconBalanceSheet, IconCashflow, IconChevronRight, @@ -27,6 +28,10 @@ type IssuerSectionProps = { metadata: Partial | undefined } +const ButtonSections = styled(RouterTextLink)` + text-decoration: unset; +` + const StyledBox = styled(Box)` padding: 24px; &:hover { @@ -35,7 +40,10 @@ const StyledBox = styled(Box)` } ` -const HoverBox = styled(StyledBox)` +const StyledRouterTextLink = styled(RouterTextLink)` + color: white; + text-decoration: unset; + font-size: 14px; padding: 8px 22px; background-color: ${SUBTLE_GRAY}; border: 3px solid transparent; @@ -44,12 +52,6 @@ const HoverBox = styled(StyledBox)` border-radius: 4px; border-color: #91969b1a; } -` - -const StyledRouterTextLink = styled(RouterTextLink)` - color: white; - text-decoration: unset; - font-size: 14px; :active { color: white; } @@ -97,14 +99,12 @@ export function ReportDetails({ metadata }: IssuerSectionProps) { Reports - - View all - + View all {reportLinks.map((link, i) => ( - + - + ))} @@ -174,15 +174,15 @@ export function IssuerDetails({ metadata }: IssuerSectionProps) { )} - - + + {metadata?.pool?.issuer.name} {metadata?.pool?.issuer.description} {metadata?.pool?.issuer?.categories?.length ? ( - + {metadata?.pool?.issuer?.categories.map((category) => ( @@ -195,7 +195,7 @@ export function IssuerDetails({ metadata }: IssuerSectionProps) { ))} ) : null} - + - + + + ) diff --git a/centrifuge-app/src/components/LayoutBase/styles.tsx b/centrifuge-app/src/components/LayoutBase/styles.tsx index dcaec9cab..9faef617e 100644 --- a/centrifuge-app/src/components/LayoutBase/styles.tsx +++ b/centrifuge-app/src/components/LayoutBase/styles.tsx @@ -147,7 +147,7 @@ export const WalletInner = styled(Stack)` @media (min-width: ${({ theme }) => theme.breakpoints[BREAK_POINT_COLUMNS]}) { justify-content: flex-end; height: 50px; - margin-right: 30px; + margin-right: 20px; margin-top: 15px; } ` diff --git a/centrifuge-app/src/components/PoolCard/index.tsx b/centrifuge-app/src/components/PoolCard/index.tsx index 22b91605a..7959a1247 100644 --- a/centrifuge-app/src/components/PoolCard/index.tsx +++ b/centrifuge-app/src/components/PoolCard/index.tsx @@ -1,31 +1,16 @@ -import { CurrencyBalance, Rate, Token } from '@centrifuge/centrifuge-js' -import { Box, Card, Divider, Stack, Text, Thumbnail } from '@centrifuge/fabric' +import { CurrencyBalance, PoolMetadata, Rate, Token } from '@centrifuge/centrifuge-js' +import { Box, Card, Divider, Shelf, Stack, Text, Thumbnail } from '@centrifuge/fabric' import Decimal from 'decimal.js-light' import { useMemo } from 'react' import styled, { useTheme } from 'styled-components' import { daysBetween } from '../../utils/date' import { formatBalance, formatBalanceAbbreviated, formatPercentage } from '../../utils/formatting' import { CardHeader } from '../ListItemCardStyles' +import { RatingPill } from '../PoolOverview/KeyMetrics' import { RouterTextLink } from '../TextLink' import { Tooltips } from '../Tooltips' import { PoolStatus, PoolStatusKey } from './PoolStatus' -export type InnerMetadata = { - minInitialInvestment?: CurrencyBalance -} - -export type MetaData = { - tranches: { - [key: string]: InnerMetadata - } - pool: { - issuer: { - shortDescription?: string - } - investorType?: string - } -} - type TrancheWithCurrency = Pick const StyledRouterTextLink = styled(RouterTextLink)` @@ -36,24 +21,14 @@ const StyledRouterTextLink = styled(RouterTextLink)` const StyledCard = styled(Card)` width: 100%; max-width: 100%; - height: 320px; - margin-right: 12px; - margin-bottom: 12px; padding: 12px; - border: 1px solid rgba(207, 207, 207, 0.5); + border: 1px solid ${({ theme }) => theme.colors.borderPrimary}; + height: 350px; &:hover { border: 1px solid ${({ theme }) => theme.colors.textPrimary}; box-shadow: 0px 20px 24px -4px rgba(16, 24, 40, 0.08), 0px 8px 8px -4px rgba(16, 24, 40, 0.03); } - - @media (min-width: ${({ theme }) => theme.breakpoints['M']}) { - width: auto; - } - - @media (min-width: ${({ theme }) => theme.breakpoints['XL']}) { - width: auto; - } ` const StyledText = styled(Text)` @@ -127,8 +102,9 @@ export type PoolCardProps = { apr?: Rate | null | undefined status?: PoolStatusKey iconUri?: string + isArchive?: boolean tranches?: TrancheWithCurrency[] - metaData?: MetaData + metaData?: PoolMetadata createdAt?: string } @@ -143,16 +119,19 @@ export function PoolCard({ tranches, metaData, createdAt, + isArchive, }: PoolCardProps) { const theme = useTheme() const isOneTranche = tranches && tranches?.length === 1 const isTinlakePool = poolId?.startsWith('0x') + const ratings = metaData?.pool?.poolRatings ?? [] const tinlakeKey = (Object.keys(tinlakeTranches).find( (key) => tinlakeTranches[key as TinlakeTranchesKey].name === name ) || 'none') as TinlakeTranchesKey const renderText = (text: string, isApr?: boolean, seniority?: number) => { + if (isArchive) return if ( (isApr && poolId === NS3_POOL_ID) || (isApr && poolId === DYF_POOL_ID) || @@ -306,6 +285,18 @@ export function PoolCard({ {isTinlakePool ? tinlakeTranches[tinlakeKey].investorType : metaData?.pool?.investorType ?? '-'} + {ratings.length ? ( + + + Rating + + + {ratings.map((rating) => { + return + })} + + + ) : null} ) diff --git a/centrifuge-app/src/components/PoolList.tsx b/centrifuge-app/src/components/PoolList.tsx index 5113ecced..0aac5b5e6 100644 --- a/centrifuge-app/src/components/PoolList.tsx +++ b/centrifuge-app/src/components/PoolList.tsx @@ -1,6 +1,6 @@ import Centrifuge, { Pool, PoolMetadata } from '@centrifuge/centrifuge-js' import { useCentrifuge } from '@centrifuge/centrifuge-react' -import { Box, IconChevronRight, Shelf, Stack, Text } from '@centrifuge/fabric' +import { Box, Grid, IconChevronRight, Shelf, Stack, Text } from '@centrifuge/fabric' import * as React from 'react' import { useLocation } from 'react-router' import styled from 'styled-components' @@ -9,7 +9,7 @@ import { TinlakePool } from '../utils/tinlake/useTinlakePools' import { useIsAboveBreakpoint } from '../utils/useIsAboveBreakpoint' import { useListedPools } from '../utils/useListedPools' import { useMetadataMulti } from '../utils/useMetadata' -import { MetaData, PoolCard, PoolCardProps } from './PoolCard' +import { PoolCard, PoolCardProps } from './PoolCard' import { PoolStatusKey } from './PoolCard/PoolStatus' import { filterPools } from './PoolFilter/utils' @@ -44,7 +44,6 @@ export function PoolList() { const [listedPools, , metadataIsLoading] = useListedPools() const isLarge = useIsAboveBreakpoint('L') const isMedium = useIsAboveBreakpoint('M') - const isExtraLarge = useIsAboveBreakpoint('XL') const centPools = listedPools.filter(({ id }) => !id.startsWith('0x')) as Pool[] const centPoolsMetaData: PoolMetaDataPartial[] = useMetadataMulti( @@ -82,31 +81,26 @@ export function PoolList() { - + {metadataIsLoading ? Array(6) .fill(true) .map((_, index) => ( - + )) : filteredPools.map((pool) => ( - + ))} - + {!metadataIsLoading && archivedPools.length > 0 && ( <> - + - + {pools.map((pool) => ( - - + + ))} - + ) } @@ -162,7 +148,7 @@ export function poolsToPoolCardProps( status: getPoolStatus(pool), iconUri: metaData?.pool?.icon?.uri ? cent.metadata.parseMetadataUrl(metaData?.pool?.icon?.uri) : undefined, tranches: pool.tranches, - metaData: metaData as MetaData, + metaData: metaData as PoolMetadata, createdAt: pool.createdAt ?? '', } }) diff --git a/centrifuge-app/src/components/PoolOverview/KeyMetrics.tsx b/centrifuge-app/src/components/PoolOverview/KeyMetrics.tsx index 631449df1..e9a037601 100644 --- a/centrifuge-app/src/components/PoolOverview/KeyMetrics.tsx +++ b/centrifuge-app/src/components/PoolOverview/KeyMetrics.tsx @@ -1,4 +1,4 @@ -import { CurrencyBalance, DailyTrancheState, Price } from '@centrifuge/centrifuge-js' +import { CurrencyBalance, DailyTrancheState, PoolMetadata, Price } from '@centrifuge/centrifuge-js' import { NetworkIcon, formatBalanceAbbreviated, useCentrifuge } from '@centrifuge/centrifuge-react' import { Box, @@ -46,6 +46,8 @@ type Tranche = Pick & { type TinlakeDataKey = keyof typeof tinlakeData +type RatingProps = Partial[number]> + const ratingIcons: { [key: string]: JSX.Element } = { "Moody's": , Particula: , @@ -90,8 +92,6 @@ export const KeyMetrics = ({ poolId }: Props) => { const poolFees = usePoolFees(poolId) const tranchesIds = pool.tranches.map((tranche) => tranche.id) const dailyTranches = useDailyTranchesStates(tranchesIds) - const theme = useTheme() - const cent = useCentrifuge() const averageMaturity = useAverageMaturity(poolId) const expenseRatio = useMemo(() => { @@ -190,39 +190,8 @@ export const KeyMetrics = ({ poolId }: Props) => { metric: 'Rating', value: ( - {metadata?.pool?.poolRatings.map((rating) => ( - - } - > - - {rating.agency && ratingIcons[rating.agency] ? ratingIcons[rating.agency] : } - {rating.value} - - + {metadata.pool.poolRatings.map((rating) => ( + ))} ), @@ -248,7 +217,7 @@ export const KeyMetrics = ({ poolId }: Props) => { {metrics.map(({ metric, value }, index) => { return ( - + {metric} @@ -275,6 +244,10 @@ const TooltipBody = ({ url?: string links?: { text: string; url: string }[] }) => { + const handleLinkClick = (e: React.MouseEvent) => { + e.stopPropagation() + } + return ( @@ -283,8 +256,8 @@ const TooltipBody = ({ {links ? ( links.map((link, index) => ( - - + + {link.text} @@ -294,7 +267,7 @@ const TooltipBody = ({ )) ) : ( - + {subtitle} @@ -313,7 +286,7 @@ const AvailableNetworks = ({ poolId }: { poolId: string }) => { const renderTooltipBody = (networkName: string, tranches: Tranche[], baseUrl: string) => { const links = tranches.map((tranche) => ({ - text: `View ${tranche.currency.name.split(' ').at(-1)}`, + text: `View Transactions`, url: `${baseUrl}/token/${tranche.id}`, })) @@ -353,3 +326,47 @@ const AvailableNetworks = ({ poolId }: { poolId: string }) => { ) } + +export const RatingPill = ({ agency, reportUrl, reportFile, value }: RatingProps) => { + const theme = useTheme() + const cent = useCentrifuge() + return ( + + + } + > + + {agency && ratingIcons[agency] ? ratingIcons[agency] : } + + {value} + + + + + ) +} diff --git a/centrifuge-app/src/components/PoolOverview/PoolPerfomance.tsx b/centrifuge-app/src/components/PoolOverview/PoolPerfomance.tsx index 4d51641f8..47191b355 100644 --- a/centrifuge-app/src/components/PoolOverview/PoolPerfomance.tsx +++ b/centrifuge-app/src/components/PoolOverview/PoolPerfomance.tsx @@ -4,8 +4,8 @@ import PoolPerformanceChart from '../Charts/PoolPerformanceChart' import { Spinner } from '../Spinner' export const PoolPerformance = () => ( - }> - + }> + diff --git a/centrifuge-app/src/components/PoolOverview/TrancheTokenCards.tsx b/centrifuge-app/src/components/PoolOverview/TrancheTokenCards.tsx index 146a009e4..a0cc7aeef 100644 --- a/centrifuge-app/src/components/PoolOverview/TrancheTokenCards.tsx +++ b/centrifuge-app/src/components/PoolOverview/TrancheTokenCards.tsx @@ -150,7 +150,13 @@ export const TrancheTokenCards = ({ return ( - + diff --git a/centrifuge-app/src/components/Report/AssetList.tsx b/centrifuge-app/src/components/Report/AssetList.tsx index 0166310ce..6db290375 100644 --- a/centrifuge-app/src/components/Report/AssetList.tsx +++ b/centrifuge-app/src/components/Report/AssetList.tsx @@ -27,42 +27,42 @@ function getColumnConfig(isPrivate: boolean, symbol: string) { { header: 'Name', align: 'left', csvOnly: false, formatter: noop }, { header: 'Value', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), }, { header: 'Principal outstanding', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), }, { header: 'Interest outstanding', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), }, { header: 'Principal repaid', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), }, { header: 'Interest repaid', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), }, { header: 'Additional repaid', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), @@ -124,28 +124,28 @@ function getColumnConfig(isPrivate: boolean, symbol: string) { { header: 'Name', align: 'left', csvOnly: false, formatter: noop }, { header: 'Market value', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), }, { header: 'Face value', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), }, { header: 'Quantity', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, undefined, 2) : '-'), }, { header: 'Market price', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), @@ -159,14 +159,14 @@ function getColumnConfig(isPrivate: boolean, symbol: string) { }, { header: 'Unrealized profit', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), }, { header: 'Realized profit', - align: 'right', + align: 'left', csvOnly: false, sortable: true, formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'), @@ -192,6 +192,7 @@ export function AssetList({ pool }: { pool: Pool }) { align: col.align, header: col.sortable ? : col.header, sortKey: col.sortable ? `value[${index}]` : undefined, + width: '177px', cell: (row: TableDataRow & { id: string }) => { const assetId = row?.id?.split('-')[1] return col.header === 'Name' ? ( diff --git a/centrifuge-app/src/components/Report/AssetTransactions.tsx b/centrifuge-app/src/components/Report/AssetTransactions.tsx index 633f5f139..86209f59e 100644 --- a/centrifuge-app/src/components/Report/AssetTransactions.tsx +++ b/centrifuge-app/src/components/Report/AssetTransactions.tsx @@ -22,9 +22,10 @@ export function AssetTransactions({ pool }: { pool: Pool }) { const columnConfig = [ { header: 'Asset ID', - align: 'left', + align: 'center', csvOnly: false, formatter: noop, + width: '80px', }, { header: 'Asset name', @@ -34,7 +35,7 @@ export function AssetTransactions({ pool }: { pool: Pool }) { }, { header: 'Epoch', - align: 'right', + align: 'center', csvOnly: false, formatter: noop, }, @@ -46,7 +47,7 @@ export function AssetTransactions({ pool }: { pool: Pool }) { }, { header: 'Transaction type', - align: 'right', + align: 'left', csvOnly: false, formatter: noop, }, @@ -58,14 +59,15 @@ export function AssetTransactions({ pool }: { pool: Pool }) { }, { header: 'Currency', - align: 'right', + align: 'left', csvOnly: true, formatter: noop, }, { header: 'Transaction', - align: 'right', + align: 'center', csvOnly: false, + width: '80px', formatter: (v: any) => ( {col.formatter((row.value as any)[index])}, csvOnly: col.csvOnly, + width: col.width ?? '252px', })) .filter((col) => !col.csvOnly) diff --git a/centrifuge-app/src/components/Report/DataFilter.tsx b/centrifuge-app/src/components/Report/DataFilter.tsx index 6b146626b..44b97527d 100644 --- a/centrifuge-app/src/components/Report/DataFilter.tsx +++ b/centrifuge-app/src/components/Report/DataFilter.tsx @@ -1,9 +1,9 @@ import { Loan, Pool } from '@centrifuge/centrifuge-js' import { useGetNetworkName } from '@centrifuge/centrifuge-react' -import { AnchorButton, Box, DateInput, IconDownload, SearchInput, Select, Shelf } from '@centrifuge/fabric' +import { AnchorButton, Box, DateInput, Grid, IconDownload, SearchInput, Select, Stack, Text } from '@centrifuge/fabric' import * as React from 'react' import { useNavigate } from 'react-router' -import { useIsAboveBreakpoint } from '../../../src/utils/useIsAboveBreakpoint' +import { formatDate } from '../../../src/utils/date' import { usePool } from '../../../src/utils/usePools' import { nftMetadataSchema } from '../../schemas' import { useBasePath } from '../../utils/useBasePath' @@ -45,7 +45,6 @@ export function DataFilter({ poolId }: ReportFilterProps) { const navigate = useNavigate() const basePath = useBasePath() const pool = usePool(poolId) as Pool - const isMedium = useIsAboveBreakpoint('M') const { data: domains } = useActiveDomains(pool.id) const getNetworkName = useGetNetworkName() @@ -64,208 +63,196 @@ export function DataFilter({ poolId }: ReportFilterProps) { ] return ( - - - - - ) => { + const { value } = event.target + if (value) { + navigate(`${basePath}/${pool.id}/data/${value}`) + } + }} + /> - {['pool-balance', 'token-price'].includes(report) && ( - - setLoanStatus(event.target.value)} - /> - - )} + {['pool-balance', 'token-price'].includes(report) && ( + ({ - label: token.currency.name, - value: token.id, - })), - ]} - value={activeTranche} - onChange={(event) => { - if (event.target.value) { - setActiveTranche(event.target.value) - } - }} - /> - - )} + {report === 'asset-list' && ( + setLoan(event.target.value)} - value={loan} - options={[ - { label: 'All', value: 'all' }, - ...(loans?.map((l) => ({ - value: l.id, - label: , - })) ?? []), - ]} - /> - - )} + {(report === 'investor-list' || report === 'investor-tx') && ( + { - if (event.target.value) { - setTxType(event.target.value) - } - }} - /> - - )} + {report === 'asset-tx' && ( + ({ - label: getNetworkName(domain.chainId), - value: String(domain.chainId), - })), - ]} - value={network} - onChange={(e) => { - const { value } = e.target - if (value) { - setNetwork(isNaN(Number(value)) ? value : Number(value)) - } - }} - /> - - - )} - - - - - setStartDate(e.target.value)} /> - - setEndDate(e.target.value)} /> - - } - small - variant="inverted" - style={{ marginLeft: '12px', marginTop: '22px' }} - > - Download - - - + { label: 'Submitted orders', value: 'orders' }, + { label: 'Executed orders', value: 'executions' }, + { label: 'Transfers', value: 'transfers' }, + ] + : report === 'asset-tx' + ? [ + { label: 'All', value: 'all' }, + { label: 'Created', value: 'Created' }, + { label: 'Financed', value: 'Financed' }, + { label: 'Repaid', value: 'Repaid' }, + { label: 'Priced', value: 'Priced' }, + { label: 'Closed', value: 'Closed' }, + ] + : [ + { label: 'All', value: 'all' }, + { label: formatPoolFeeTransactionType('CHARGED'), value: 'CHARGED' }, + { label: formatPoolFeeTransactionType('UNCHARGED'), value: 'UNCHARGED' }, + { label: formatPoolFeeTransactionType('ACCRUED'), value: 'ACCRUED' }, + { label: formatPoolFeeTransactionType('PAID'), value: 'PAID' }, + ] + } + value={txType} + onChange={(event) => { + if (event.target.value) { + setTxType(event.target.value) + } + }} + /> + )} - {['investor-tx', 'investor-list'].includes(report) && ( - + {['investor-tx', 'investor-list'].includes(report) && ( +