Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new sdk to current app #2579

Draft
wants to merge 5 commits into
base: reports
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion centrifuge-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@centrifuge/centrifuge-js": "workspace:*",
"@centrifuge/centrifuge-react": "workspace:*",
"@centrifuge/fabric": "workspace:*",
"@centrifuge/sdk": "^0.0.0-alpha.0",
"@centrifuge/sdk": "^0.0.0-alpha.11",
"@makerdao/multicall": "^0.12.0",
"@polkadot/react-identicon": "~3.1.4",
"@styled-system/css": "^5.1.5",
Expand Down
26 changes: 14 additions & 12 deletions centrifuge-app/src/components/Charts/SimpleBarChart.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { CurrencyBalance, CurrencyMetadata } from '@centrifuge/centrifuge-js'
import { Shelf, Text } from '@centrifuge/fabric'
import { CurrencyMetadata } from '@centrifuge/centrifuge-js'
import { Box, Shelf, Text } from '@centrifuge/fabric'
import { Currency } from '@centrifuge/sdk'
import { Bar, BarChart, CartesianGrid, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'
import { useTheme } from 'styled-components'
import { formatDate } from '../../../src/utils/date'
import { formatBalance, formatBalanceAbbreviated } from '../../../src/utils/formatting'
import { formatDecimal, formatDecimalAbbreviated } from '../../../src/utils/formatting'
import { LoadBoundary } from '../LoadBoundary'
import { CustomTick } from './PoolPerformanceChart'
import { TooltipContainer, TooltipTitle } from './Tooltip'

type SimpleBarChartProps = {
currency?: CurrencyMetadata
data: { name: string; yAxis: number }[]
data: { name: string; yAxis: Currency }[]
groupBy?: string
}

Expand Down Expand Up @@ -62,10 +63,7 @@ export const SimpleBarChart = ({ currency, data, groupBy }: SimpleBarChartProps)
angle={45}
/>
<YAxis
tickFormatter={(tick: number) => {
const balance = new CurrencyBalance(tick, currency?.decimals || 0)
return formatBalanceAbbreviated(balance, '', 0)
}}
tickFormatter={(tick: any) => formatDecimalAbbreviated(tick, 0)}
tick={{ fontSize: 10, color: theme.colors.textPrimary }}
tickLine={false}
axisLine={false}
Expand All @@ -79,10 +77,14 @@ export const SimpleBarChart = ({ currency, data, groupBy }: SimpleBarChartProps)
if (payload && payload?.length > 0) {
return (
<TooltipContainer>
<TooltipTitle>{formatDate(payload[0].payload.name)}</TooltipTitle>
{payload.map((item) => (
<Text variant="body3">{formatBalance(item.value as number, currency)}</Text>
))}
{payload.map((item) => {
return (
<Box>
<TooltipTitle>{formatDate(item.payload.name)}</TooltipTitle>
<Text variant="body3">{formatDecimal(item.value, 2, currency?.displayName)}</Text>
</Box>
)
})}
</TooltipContainer>
)
}
Expand Down
98 changes: 58 additions & 40 deletions centrifuge-app/src/components/Report/AssetList.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { Pool } from '@centrifuge/centrifuge-js'
import { Box, Text } from '@centrifuge/fabric'
import { AssetListReport } from '@centrifuge/sdk/dist/types/reports'
import { useContext, useEffect, useMemo } from 'react'
import { useBasePath } from '../../../src/utils/useBasePath'
import { formatDate } from '../../utils/date'
import { formatBalance, formatPercentage } from '../../utils/formatting'
import { formatDecimal, formatPercentage } from '../../utils/formatting'
import { getCSVDownloadUrl } from '../../utils/getCSVDownloadUrl'
import { useAllPoolAssetSnapshots, usePoolMetadata } from '../../utils/usePools'
import { usePoolMetadata } from '../../utils/usePools'
import { DataTable, SortableTableHeader } from '../DataTable'
import { Spinner } from '../Spinner'
import { RouterTextLink } from '../TextLink'
import { ReportContext } from './ReportContext'
import { UserFeedback } from './UserFeedback'
import type { TableDataRow } from './index'
import { useReport } from './useReportsQuery'

const noop = (v: any) => v

Expand All @@ -21,7 +23,12 @@ const valuationLabels = {
oracle: 'Fungible asset - external pricing',
}

function getColumnConfig(isPrivate: boolean, symbol: string) {
type AssetSnapshot = AssetListReport & {
transactionType: 'ACTIVE' | string
name: string
}

function getColumnConfig(isPrivate: boolean, symbol: string, decimals: number) {
if (isPrivate) {
return [
{ header: 'Name', align: 'left', csvOnly: false, formatter: noop },
Expand All @@ -30,42 +37,42 @@ function getColumnConfig(isPrivate: boolean, symbol: string) {
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Principal outstanding',
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Interest outstanding',
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Principal repaid',
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Interest repaid',
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Additional repaid',
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Origination date',
Expand Down Expand Up @@ -98,25 +105,25 @@ function getColumnConfig(isPrivate: boolean, symbol: string) {
header: 'Collateral value',
align: 'left',
csvOnly: false,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Probability of default (PD)',
align: 'left',
csvOnly: false,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Loss given default (LGD)',
align: 'left',
csvOnly: false,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Discount rate',
align: 'left',
csvOnly: false,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
]
} else {
Expand All @@ -127,28 +134,28 @@ function getColumnConfig(isPrivate: boolean, symbol: string) {
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Face value',
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Quantity',
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, undefined, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, '') : '-'),
},
{
header: 'Market price',
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Maturity date',
Expand All @@ -162,28 +169,40 @@ function getColumnConfig(isPrivate: boolean, symbol: string) {
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
{
header: 'Realized profit',
align: 'left',
csvOnly: false,
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatDecimal(v, 2, symbol) : '-'),
},
]
}
}

export function AssetList({ pool }: { pool: Pool }) {
const basePath = useBasePath()
const { loanStatus, startDate, setCsvData } = useContext(ReportContext)
const { loanStatus, startDate, setCsvData, endDate } = useContext(ReportContext)
const { data: poolMetadata } = usePoolMetadata(pool)
const { symbol } = pool.currency
const { symbol, decimals } = pool.currency
const poolCreditType = poolMetadata?.pool?.asset.class || 'privateCredit'
const { data: snapshots } = useAllPoolAssetSnapshots(pool.id, startDate)
const isPrivate = poolCreditType === 'Private credit' || poolCreditType === 'privateCredit'
const columnConfig = getColumnConfig(isPrivate, symbol)
const columnConfig = getColumnConfig(isPrivate, symbol, decimals)

const { data: snapshots = [], isLoading } = useReport(
'assetList',
pool,
new Date(startDate),
new Date(endDate),
undefined,
{
...(loanStatus && { status: loanStatus }),
}
)

console.log(snapshots, isPrivate)

const columns = useMemo(
() =>
Expand Down Expand Up @@ -213,16 +232,14 @@ export function AssetList({ pool }: { pool: Pool }) {
const data = useMemo((): any[] => {
if (!snapshots) return []

return snapshots
return (snapshots as AssetSnapshot[])
.filter((snapshot) => snapshot?.valuationMethod?.toLowerCase() !== 'cash')
.filter((snapshot) => {
const isMaturityDatePassed = snapshot?.actualMaturityDate
? new Date() > new Date(snapshot.actualMaturityDate)
: false
const isDebtZero = snapshot?.outstandingDebt?.isZero()
const isMaturityDatePassed = snapshot?.maturityDate ? new Date() > new Date(snapshot.maturityDate) : false
const isDebtZero = 'outstandingQuantity' in snapshot ? snapshot.outstandingQuantity?.isZero() : false

if (loanStatus === 'ongoing') {
return snapshot.status === 'ACTIVE' && !isMaturityDatePassed && !isDebtZero
return snapshot.transactionType === 'ACTIVE' && !isMaturityDatePassed && !isDebtZero
} else if (loanStatus === 'repaid') {
return isMaturityDatePassed && isDebtZero
} else if (loanStatus === 'overdue') {
Expand All @@ -231,12 +248,13 @@ export function AssetList({ pool }: { pool: Pool }) {
})
.sort((a, b) => {
// Sort by actualMaturityDate in descending order
const dateA = new Date(a.actualMaturityDate || 0).getTime()
const dateB = new Date(b.actualMaturityDate || 0).getTime()
const dateA = new Date(a.maturityDate || 0).getTime()
const dateB = new Date(b.maturityDate || 0).getTime()
return dateB - dateA
})
.map((snapshot) => {
const valuationMethod = snapshot?.valuationMethod as keyof typeof valuationLabels
const valuationMethod =
'valuationMethod' in snapshot ? (snapshot.valuationMethod as keyof typeof valuationLabels) : ''
if (isPrivate) {
return {
name: '',
Expand All @@ -245,10 +263,10 @@ export function AssetList({ pool }: { pool: Pool }) {
snapshot?.presentValue,
snapshot?.outstandingPrincipal,
snapshot?.outstandingInterest,
snapshot?.totalRepaidPrincipal,
snapshot?.totalRepaidInterest,
snapshot?.totalRepaidUnscheduled,
snapshot?.actualOriginationDate,
snapshot?.repaidPrincipal,
snapshot?.repaidInterest,
snapshot?.repaidUnscheduled,
snapshot?.originationDate,
snapshot?.actualMaturityDate,
valuationMethod || snapshot?.valuationMethod,
snapshot?.advanceRate,
Expand All @@ -269,9 +287,9 @@ export function AssetList({ pool }: { pool: Pool }) {
snapshot?.faceValue,
snapshot?.outstandingQuantity,
snapshot?.currentPrice,
snapshot?.actualMaturityDate,
snapshot?.unrealizedProfitAtMarketPrice,
snapshot?.sumRealizedProfitFifo,
snapshot?.maturityDate,
snapshot?.unrealizedProfit,
snapshot?.realizedProfit,
],
heading: false,
id: snapshot?.assetId,
Expand Down Expand Up @@ -304,7 +322,7 @@ export function AssetList({ pool }: { pool: Pool }) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data])

if (!snapshots) {
if (isLoading) {
return <Spinner />
}

Expand Down
Loading
Loading