Skip to content

Commit

Permalink
Merge branch 'main' into fix-close-epoch
Browse files Browse the repository at this point in the history
  • Loading branch information
onnovisser authored May 7, 2024
2 parents 0297c26 + 78ae30d commit 75e5f60
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 76 deletions.
2 changes: 1 addition & 1 deletion centrifuge-app/.env-config/.env.demo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
REACT_APP_COLLATOR_WSS_URL=wss://fullnode.demo.k-f.dev
REACT_APP_COLLATOR_WSS_URL=wss://fullnode-apps.demo.k-f.dev
REACT_APP_DEFAULT_NODE_URL=https://pod-demo.k-f.dev
REACT_APP_DEFAULT_UNLIST_POOLS=true
REACT_APP_FAUCET_URL=https://europe-central2-peak-vista-185616.cloudfunctions.net/faucet-api-demo
Expand Down
8 changes: 5 additions & 3 deletions centrifuge-app/src/components/Charts/PriceChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ export const PriceChart = ({ data, currency, filter, setFilter }: PriceChartProp
{ label: 'YTD', value: 'YTD' },
]}
onChange={(option) => setFilter(option.target.value as FilterOptions)}
defaultValue={filter}
/>
</Box>
)}
</Shelf>
<ResponsiveContainer width="100%" height="100%" minHeight="200px">
<AreaChart data={data || []} margin={{ top: 18, left: -30 }}>
<AreaChart data={data || []} margin={{ top: 18, left: -10 }}>
<defs>
<linearGradient id="colorPrice" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={'#626262'} stopOpacity={0.4} />
Expand Down Expand Up @@ -86,12 +87,13 @@ export const PriceChart = ({ data, currency, filter, setFilter }: PriceChartProp
tickLine={false}
style={{ fontSize: '10px', fill: theme.colors.textSecondary, letterSpacing: '-0.5px' }}
tickFormatter={(tick: number) => {
return tick.toFixed(2)
return tick.toFixed(6)
}}
domain={['dataMin - 0.001', 'dataMax + 0.001']}
interval={'preserveStartEnd'}
/>
<CartesianGrid stroke={theme.colors.borderPrimary} />
<Tooltip content={<CustomizedTooltip currency={currency} precision={4} />} />
<Tooltip content={<CustomizedTooltip currency={currency} precision={6} />} />
<Area
type="monotone"
dataKey="price"
Expand Down
2 changes: 1 addition & 1 deletion centrifuge-app/src/components/InvestRedeem/Claim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function Claim({ type, onDismiss }: { type: 'invest' | 'redeem'; onDismis
body={
<Stack gap={1}>
<div>
Invested
Invested{' '}
<Text fontWeight="bold">
{formatBalance(state.order.payoutTokenAmount.mul(state.tokenPrice), state.poolCurrency?.displayName)}
</Text>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Drawer } from '@centrifuge/fabric'
import { Box, Drawer, Stack, Text } from '@centrifuge/fabric'
import * as React from 'react'
import { useDailyPoolStates, usePool } from '../../utils/usePools'
import { FilterOptions, PriceChart } from '../Charts/PriceChart'
import { LoadBoundary } from '../LoadBoundary'
import { InvestRedeem } from './InvestRedeem'

Expand All @@ -21,6 +23,79 @@ export function InvestRedeemDrawer({
<LoadBoundary>
<InvestRedeem poolId={poolId} trancheId={trancheId} defaultView={defaultView} />
</LoadBoundary>
<LoadBoundary>
<Stack gap={12}>
<Text variant="heading6" color="textPrimary" fontWeight={600}>
Price
</Text>
<Box borderColor="rgba(0,0,0,0.08)" borderWidth="1px" borderStyle="solid" borderRadius="2px" p="6px">
<TokenPriceChart poolId={poolId} trancheId={trancheId} />
</Box>
</Stack>
</LoadBoundary>
</Drawer>
)
}

const TokenPriceChart = React.memo(function TokenPriceChart({
poolId,
trancheId,
}: {
poolId: string
trancheId: string
}) {
const [filter, setFilter] = React.useState<FilterOptions>('30days')
const pool = usePool(poolId)

const dateFrom = React.useMemo(() => {
if (filter === 'YTD') {
const currentYear = new Date().getFullYear()
const januaryFirst = new Date(currentYear, 0, 1)
return januaryFirst
}
if (filter === '30days') {
const thirtyDaysAgo = new Date()
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30)
thirtyDaysAgo.setHours(0, 0, 0, 0) // set to midnight
return thirtyDaysAgo
}
if (filter === '90days') {
const ninetyDaysAgo = new Date()
ninetyDaysAgo.setDate(ninetyDaysAgo.getDate() - 90)
ninetyDaysAgo.setHours(0, 0, 0, 0)
return ninetyDaysAgo
}
const today = new Date()
today.setHours(0, 0, 0, 0)
return today
}, [filter])

const { poolStates: dailyPoolStates } = useDailyPoolStates(poolId, new Date(dateFrom)) || {}

const data = React.useMemo(() => {
const tokenData =
dailyPoolStates?.map((state) => {
return { price: state.tranches[trancheId].price?.toFloat() || 0, day: new Date(state.timestamp) }
}) || []
if (tokenData.length > 0) {
tokenData.push({
day: new Date(),
price:
pool?.tranches
.find((tranche) => tranche.id === trancheId)
?.tokenPrice?.toDecimal()
.toNumber() || 1,
})
}
return tokenData
}, [dailyPoolStates, filter, trancheId])

Check warning on line 91 in centrifuge-app/src/components/InvestRedeem/InvestRedeemDrawer.tsx

View workflow job for this annotation

GitHub Actions / ff-prod / build-app

React Hook React.useMemo has a missing dependency: 'pool?.tranches'. Either include it or remove the dependency array

Check warning on line 91 in centrifuge-app/src/components/InvestRedeem/InvestRedeemDrawer.tsx

View workflow job for this annotation

GitHub Actions / build-app

React Hook React.useMemo has a missing dependency: 'pool?.tranches'. Either include it or remove the dependency array

return (
<PriceChart
data={data}
currency={pool.tranches.find((tranche) => tranche.id === trancheId)?.currency.displayName || ''}
filter={filter}
setFilter={setFilter}
/>
)
})
18 changes: 10 additions & 8 deletions centrifuge-app/src/pages/Loan/HoldingsValues.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AssetTransaction, CurrencyBalance, External#Info, Pool } from '@centrifuge/centrifuge-js'
import Decimal from 'decimal.js-light'
import React from 'react'
import { LabelValueStack } from '../../components/LabelValueStack'
import { Dec } from '../../utils/Decimal'
import { formatBalance } from '../../utils/formatting'
Expand All @@ -25,7 +26,7 @@ export function HoldingsValues({ pool, transactions, currentFace, # }: Pro
return sum
}, Dec(0)) || Dec(0)

const getAverageSettlePrice = () => {
const averageSettlePrice = React.useMemo(() => {
if (!transactions?.length) return Dec(0)

const weightedSum = transactions.reduce((sum, trx) => {
Expand All @@ -39,12 +40,17 @@ export function HoldingsValues({ pool, transactions, currentFace, # }: Pro
}, Dec(0))

const sumOfAmounts = transactions.reduce(
(sum, trx) => sum.add(trx.amount ? new CurrencyBalance(trx.amount, pool.currency.decimals).toDecimal() : Dec(0)),
(sum, trx) =>
sum.add(
trx.settlementPrice && trx.amount
? new CurrencyBalance(trx.amount, pool.currency.decimals).toDecimal()
: Dec(0)
),
Dec(0)
)

return weightedSum.div(sumOfAmounts)
}
}, [transactions])

return (
<>
Expand All @@ -55,11 +61,7 @@ export function HoldingsValues({ pool, transactions, currentFace, # }: Pro
<LabelValueStack label="Net spent" value={`${formatBalance(netSpent, pool.currency.symbol, 2, 2)}`} />
<LabelValueStack
label="Average settle price"
value={
getAverageSettlePrice().isZero()
? '-'
: `${formatBalance(getAverageSettlePrice(), pool.currency.symbol, 2, 2)}`
}
value={averageSettlePrice.isZero() ? '-' : `${formatBalance(averageSettlePrice, pool.currency.symbol, 2, 2)}`}
/>
<LabelValueStack label="Notional" value={`${formatBalance(#.notional, pool.currency.symbol, 2, 2)}`} />
<LabelValueStack label="Quantity" value={`${formatBalance(#.outstandingQuantity, undefined, 2, 0)}`} />
Expand Down
125 changes: 63 additions & 62 deletions centrifuge-app/src/pages/Loan/TransactionTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,74 +104,75 @@ export const TransactionTable = ({ transactions, currency, loanType, decimals, p
return `${type[0]}${type.slice(1).toLowerCase()}`
}

let columns: Column[] = [
{
align: 'left',
header: 'Type',
cell: (row: Row) => <StatusChip status={getStatusChipType(row.type)}>{getStatusText(row.type)}</StatusChip>,
},
{
align: 'left',
header: 'Transaction date',
cell: (row: Row) => (
<Tooltip
title="Transaction date"
body={formatDate(row.transactionDate, { hour: 'numeric', minute: 'numeric', second: 'numeric' })}
>
{formatDate(row.transactionDate)}
</Tooltip>
),
},
]

if (poolType === 'publicCredit') {
columns = [
...columns,
const columns = useMemo(() => {
return [
{
align: 'left',
header: `Face flow (${currency})`,
cell: (row: Row) =>
row.faceFlow ? `${row.type === 'REPAID' ? '-' : ''}${formatBalance(row.faceFlow, undefined, 2, 2)}` : '-',
header: 'Type',
cell: (row: Row) => <StatusChip status={getStatusChipType(row.type)}>{getStatusText(row.type)}</StatusChip>,
},
{
align: 'left',
header: 'Quantity',
cell: (row: Row) => (row.quantity ? formatBalance(row.quantity, undefined, 2, 0) : '-'),
header: 'Transaction date',
cell: (row: Row) => (
<Tooltip
title="Transaction date"
body={formatDate(row.transactionDate, { hour: 'numeric', minute: 'numeric', second: 'numeric' })}
>
{formatDate(row.transactionDate)}
</Tooltip>
),
},
{
align: 'left',
header: `Settle price (${currency})`,
cell: (row: Row) => (row.settlePrice ? formatBalance(row.settlePrice, undefined, 6, 2) : '-'),
},
{
align: 'left',
header: `Net cash flow (${currency})`,
cell: (row: Row) =>
row.amount ? `${row.type === 'BORROWED' ? '-' : ''}${formatBalance(row.amount, undefined, 2, 2)}` : '-',
},
{
align: 'left',
header: `Position (${currency})`,
cell: (row: Row) => (row.type === 'CREATED' ? '-' : formatBalance(row.position, undefined, 2, 2)),
},
]
} else {
columns = [
...columns,
{
align: 'left',
header: `Amount (${currency})`,
cell: (row: Row) =>
row.amount ? `${row.type === 'REPAID' ? '-' : ''}${formatBalance(row.amount, undefined, 2, 2)}` : '-',
},
{
align: 'left',
header: `Principal (${currency})`,
cell: (row: Row) =>
row.position ? `${row.type === 'REPAID' ? '-' : ''}${formatBalance(row.position, undefined, 2, 2)}` : '-',
},
]
}
...(poolType === 'publicCredit'
? [
{
align: 'left',
header: `Face flow (${currency})`,
cell: (row: Row) =>
row.faceFlow
? `${row.type === 'REPAID' ? '-' : ''}${formatBalance(row.faceFlow, undefined, 2, 2)}`
: '-',
},
{
align: 'left',
header: 'Quantity',
cell: (row: Row) => (row.quantity ? formatBalance(row.quantity, undefined, 2, 0) : '-'),
},
{
align: 'left',
header: `Settle price (${currency})`,
cell: (row: Row) => (row.settlePrice ? formatBalance(row.settlePrice, undefined, 6, 2) : '-'),
},
{
align: 'left',
header: `Net cash flow (${currency})`,
cell: (row: Row) =>
row.amount ? `${row.type === 'BORROWED' ? '-' : ''}${formatBalance(row.amount, undefined, 2, 2)}` : '-',
},
{
align: 'left',
header: `Position (${currency})`,
cell: (row: Row) => (row.type === 'CREATED' ? '-' : formatBalance(row.position, undefined, 2, 2)),
},
]
: [
{
align: 'left',
header: `Amount (${currency})`,
cell: (row: Row) =>
row.amount ? `${row.type === 'REPAID' ? '-' : ''}${formatBalance(row.amount, undefined, 2, 2)}` : '-',
},
{
align: 'left',
header: `Principal (${currency})`,
cell: (row: Row) =>
row.position
? `${row.type === 'REPAID' ? '-' : ''}${formatBalance(row.position, undefined, 2, 2)}`
: '-',
},
]),
] as Column[]
}, [])

return <DataTable data={assetTransactions.reverse()} columns={columns} />
}

0 comments on commit 75e5f60

Please # to comment.