From 60c8313e4d2c63876ce96db36dbe3a5ce8572a10 Mon Sep 17 00:00:00 2001 From: Katty Barroso <51223655+kattylucy@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:32:29 +0200 Subject: [PATCH] Update to filters and table (#2512) * Adjust filters with new design * Add formatted date * Add changes to data reports table * Make column sticky --- centrifuge-app/src/components/DataTable.tsx | 27 +- .../src/components/Report/AssetList.tsx | 25 +- .../components/Report/AssetTransactions.tsx | 13 +- .../src/components/Report/DataFilter.tsx | 368 +++++++++--------- .../src/components/Report/FeeTransactions.tsx | 2 +- .../src/components/Report/InvestorList.tsx | 8 +- .../Report/InvestorTransactions.tsx | 12 +- .../src/components/Report/TokenPrice.tsx | 2 +- centrifuge-app/src/components/TextLink.tsx | 3 - 9 files changed, 236 insertions(+), 224 deletions(-) diff --git a/centrifuge-app/src/components/DataTable.tsx b/centrifuge-app/src/components/DataTable.tsx index 73fc0ac58..bf28c0b8a 100644 --- a/centrifuge-app/src/components/DataTable.tsx +++ b/centrifuge-app/src/components/DataTable.tsx @@ -129,7 +129,7 @@ export const DataTable = >({ {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 +142,7 @@ export const DataTable = >({ ))} )} + {pinnedData?.map((row, i) => ( ` borderBottomStyle: 'solid', borderBottomWidth: '1px', borderBottomColor: 'borderPrimary', + borderLeftStyle: 'solid', + borderLeftWidth: '1px', + borderLeftColor: 'borderPrimary', + borderRightStyle: 'solid', + borderRightWidth: '1px', + borderRightColor: 'borderPrimary', backgroundColor: 'transparent', // using a&:hover caused the background sometimes not to update when switching themes '&:hover': @@ -275,6 +282,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 +310,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/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..e85fdf5d4 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,195 @@ 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) && ( +