Skip to content

Commit

Permalink
Add data table for orders
Browse files Browse the repository at this point in the history
  • Loading branch information
kattylucy committed Jan 14, 2025
1 parent 214ab90 commit a404c10
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 3 deletions.
9 changes: 7 additions & 2 deletions centrifuge-app/src/components/Report/DataFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export function DataFilter({ poolId }: ReportFilterProps) {
{ label: 'Token price', value: 'token-price' },
{ label: 'Asset list', value: 'asset-list' },
{ label: 'Investor list', value: 'investor-list' },
{ label: 'Orders', value: 'orders' },
]

return (
Expand Down Expand Up @@ -228,8 +229,12 @@ export function DataFilter({ poolId }: ReportFilterProps) {
/>
)}

<DateInput label="From" value={startDate} max={endDate} onChange={(e) => setStartDate(e.target.value)} />
<DateInput label="To" value={endDate} min={startDate} onChange={(e) => setEndDate(e.target.value)} />
{report !== 'orders' && (
<>
<DateInput label="From" value={startDate} max={endDate} onChange={(e) => setStartDate(e.target.value)} />
<DateInput label="To" value={endDate} min={startDate} onChange={(e) => setEndDate(e.target.value)} />
</>
)}
</Grid>
<Box display="flex" alignItems="center" justifyContent="space-between" margin={2}>
<Box display="flex" alignItems="center">
Expand Down
111 changes: 111 additions & 0 deletions centrifuge-app/src/components/Report/Orders.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { Pool } from '@centrifuge/centrifuge-js/dist/modules/pools'
import { Box, Text } from '@centrifuge/fabric'
import { useMemo } from 'react'
import { TableDataRow } from '.'
import { formatDateAndTime } from '../../../src/utils/date'
import { formatBalance } from '../../../src/utils/formatting'
import { usePoolOrdersByPoolId } from '../../../src/utils/usePools'
import { DataTable, SortableTableHeader } from '../DataTable'

const noop = (v: any) => v

const Orders = ({ pool }: { pool: Pool }) => {
const orders = usePoolOrdersByPoolId(pool.id)

const columnsConfig = [
{
align: 'left',
header: 'Epoch',
sortable: true,
formatter: noop,
},
{
align: 'left',
header: 'Date & Time',
sortable: true,
formatter: (v: any) => formatDateAndTime(v),
width: '200px',
},
{
align: 'left',
header: 'NAV',
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, undefined, pool.currency.decimals) : '-'),
},
{
align: 'left',
header: 'Nav per share',
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, undefined, pool.currency.decimals) : '-'),
},
{
align: 'left',
header: 'Investments locked',
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, pool.currency.symbol, 2) : '-'),
},
{
align: 'left',
header: 'Investments executed',
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, pool.currency.symbol, 2) : '-'),
},
{
align: 'left',
header: 'Redemptions locked',
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, pool.currency.symbol, 2) : '-'),
},
{
align: 'left',
header: 'Redemptions executed',
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, pool.currency.symbol, 2) : '-'),
},
{
align: 'left',
header: 'Paid fees',
sortable: true,
formatter: (v: any) => (v ? formatBalance(v, pool.currency.symbol, 2) : '-'),
},
]

const columns = columnsConfig.map((col, index) => ({
align: col.align,
header: col.sortable ? <SortableTableHeader label={col.header} /> : col.header,
cell: (row: TableDataRow) => {
return <Text variant="body3">{col.formatter((row.value as any)[index])}</Text>
},
sortKey: col.sortable ? `value[${index}]` : undefined,
width: col.width,
}))

const data = useMemo(() => {
if (!orders?.length) return []
else {
return orders.map((order) => ({
name: '',
value: [
order.epochId,
order.closedAt,
order.netAssetValue,
order.tokenPrice,
order.sumOutstandingInvestOrders,
order.sumFulfilledInvestOrders,
order.sumOutstandingRedeemOrders,
order.sumFulfilledRedeemOrders,
order.paidFees,
],
heading: false,
}))
}
}, [orders])

return (
<Box paddingX={2}>
<DataTable data={data} columns={columns} scrollable />
</Box>
)
}

export default Orders
1 change: 1 addition & 0 deletions centrifuge-app/src/components/Report/ReportContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type Report =
| 'balance-sheet'
| 'cash-flow-statement'
| 'profit-and-loss'
| 'orders'

export type ReportContextType = {
csvData?: CsvDataProps
Expand Down
2 changes: 2 additions & 0 deletions centrifuge-app/src/components/Report/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { FeeTransactions } from './FeeTransactions'
import { InvestorList } from './InvestorList'
import { InvestorTransactions } from './InvestorTransactions'
import { OracleTransactions } from './OracleTransactions'
import Orders from './Orders'
import { PoolBalance } from './PoolBalance'
import { ProfitAndLoss } from './ProfitAndLoss'
import { ReportContext } from './ReportContext'
Expand Down Expand Up @@ -38,6 +39,7 @@ export function ReportComponent({ pool }: { pool: Pool }) {
{report === 'cash-flow-statement' && <CashflowStatement pool={pool} />}
{report === 'oracle-tx' && <OracleTransactions pool={pool} />}
{report === 'profit-and-loss' && <ProfitAndLoss pool={pool} />}
{report === 'orders' && <Orders pool={pool} />}
</Box>
</Box>
)
Expand Down
13 changes: 13 additions & 0 deletions centrifuge-app/src/utils/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ export function formatDate(timestamp: number | string | Date, options?: Intl.Dat
})
}

export function formatDateAndTime(timestamp: number | string | Date, options?: Intl.DateTimeFormatOptions) {
return new Date(timestamp).toLocaleString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZone: 'UTC',
...options,
})
}

export function formatDateTechnical(timestamp: number | string) {
return new Date(timestamp).toLocaleDateString('en-US')
}
Expand Down
5 changes: 5 additions & 0 deletions centrifuge-app/src/utils/usePools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ export function usePoolOrders(poolId: string) {
return result
}

export function usePoolOrdersByPoolId(poolId: string) {
const [result] = useCentrifugeQuery(['poolOrdersByPoolId', poolId], (cent) => cent.pools.getPoolOrdersById([poolId]))
return result
}

export function useOrder(poolId: string, trancheId: string, address?: string) {
const [result] = useCentrifugeQuery(
['order', trancheId, address],
Expand Down
89 changes: 88 additions & 1 deletion centrifuge-js/src/modules/pools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
SubqueryPoolAssetSnapshot,
SubqueryPoolFeeSnapshot,
SubqueryPoolFeeTransaction,
SubqueryPoolOrdersById,
SubqueryPoolSnapshot,
SubqueryTrancheBalances,
SubqueryTrancheSnapshot,
Expand Down Expand Up @@ -2443,6 +2444,11 @@ export function getPoolsModule(inst: Centrifuge) {
tranche {
poolId
trancheId
pool {
currency{
decimals
}
}
}
timestamp
tokenSupply
Expand Down Expand Up @@ -2501,13 +2507,14 @@ export function getPoolsModule(inst: Centrifuge) {
map(({ trancheSnapshots }) => {
const trancheStates: Record<
string,
{ timestamp: string; tokenPrice: Price; yield30DaysAnnualized: Perquintill }[]
{ timestamp: string; tokenPrice: Price; yield30DaysAnnualized: Perquintill; tokenSupply: TokenBalance }[]
> = {}
trancheSnapshots?.forEach((state) => {
const tid = state.tranche.trancheId
const entry = {
timestamp: state.timestamp,
tokenPrice: new Price(state.tokenPrice),
tokenSupply: new TokenBalance(state.tokenSupply, state.tranche.pool.currency.decimals),
pool: state.tranche.poolId,
yield30DaysAnnualized: state.yield30DaysAnnualized
? new Perquintill(state.yield30DaysAnnualized)
Expand Down Expand Up @@ -3941,6 +3948,85 @@ export function getPoolsModule(inst: Centrifuge) {
)
}

function getPoolOrdersById(args: [poolId: string]) {
const [poolId] = args

const $query = inst.getSubqueryObservable<{
epoches: { nodes: SubqueryPoolOrdersById[] }
}>(
`query($poolId: String!) {
epoches(
filter: {
poolId: { equalTo: $poolId }
}
) {
nodes {
poolId
id
sumPoolFeesPaidAmount
closedAt
epochStates{
nodes{
tokenPrice
sumOutstandingInvestOrders
sumFulfilledInvestOrders
sumOutstandingRedeemOrders
sumFulfilledRedeemOrders
}
}
poolSnapshots{
nodes{
netAssetValue
}
}
}
}
}
`,
{
poolId,
},
false
)

return $query.pipe(
combineLatestWith(getPoolCurrency([poolId])),
map(([data, poolCurrency]) => {
return data?.epoches?.nodes.map((order) => {
const index = order.epochStates.nodes.length - 1
return {
epochId: order.id,
closedAt: order.closedAt,
paidFees: order.sumPoolFeesPaidAmount
? new CurrencyBalance(order.sumPoolFeesPaidAmount, poolCurrency.decimals)
: null,
tokenPrice: order.epochStates.nodes[index].tokenPrice
? new CurrencyBalance(order.epochStates.nodes[index].tokenPrice, poolCurrency.decimals)
: null,
sumOutstandingInvestOrders: order.epochStates.nodes[index].sumOutstandingInvestOrders
? new CurrencyBalance(order.epochStates.nodes[index].sumOutstandingInvestOrders, poolCurrency.decimals)
: null,
sumFulfilledInvestOrders: order.epochStates.nodes[index].sumFulfilledInvestOrders
? new CurrencyBalance(order.epochStates.nodes[index].sumFulfilledInvestOrders, poolCurrency.decimals)
: null,
sumOutstandingRedeemOrders: order.epochStates.nodes[index].sumOutstandingRedeemOrders
? new CurrencyBalance(order.epochStates.nodes[index].sumOutstandingRedeemOrders, poolCurrency.decimals)
: null,
sumFulfilledRedeemOrders: order.epochStates.nodes[index].sumFulfilledRedeemOrders
? new CurrencyBalance(order.epochStates.nodes[index].sumFulfilledRedeemOrders, poolCurrency.decimals)
: null,
netAssetValue: order.poolSnapshots.nodes.length
? new CurrencyBalance(
order.poolSnapshots.nodes[order.poolSnapshots.nodes.length - 1].netAssetValue,
poolCurrency.decimals
)
: null,
}
})
})
)
}

function getLoans(args: [poolId: string]) {
const [poolId] = args
const $api = inst.getApi()
Expand Down Expand Up @@ -4631,6 +4717,7 @@ export function getPoolsModule(inst: Centrifuge) {
getBalances,
getOrder,
getPoolOrders,
getPoolOrdersById,
getPoolAccountOrders,
getPortfolio,
getLoans,
Expand Down
26 changes: 26 additions & 0 deletions centrifuge-js/src/types/subquery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export type SubqueryTrancheSnapshot = {
tranche: {
poolId: string
trancheId: string
pool: {
currency: {
decimals: number
}
}
}
tokenSupply: string
sumOutstandingInvestOrdersByPeriod: string
Expand Down Expand Up @@ -192,6 +197,27 @@ export type SubqueryPoolAssetSnapshot = {
totalRepaidUnscheduled: string | undefined
}

export type SubqueryPoolOrdersById = {
__typename?: 'Epoches'
id: string
sumPoolFeesPaidAmount: string
closedAt: string
epochStates: {
nodes: {
tokenPrice: string
sumOutstandingInvestOrders: string
sumFulfilledInvestOrders: string
sumOutstandingRedeemOrders: string
sumFulfilledRedeemOrders: string
}[]
}
poolSnapshots: {
nodes: {
netAssetValue: string
}[]
}
}

export type PoolFeeTransactionType = 'PROPOSED' | 'ADDED' | 'REMOVED' | 'CHARGED' | 'UNCHARGED' | 'PAID' | 'ACCRUED'

export type SubqueryPoolFeeTransaction = {
Expand Down

0 comments on commit a404c10

Please sign in to comment.