Skip to content

Commit

Permalink
feat: update export functionality (#96)
Browse files Browse the repository at this point in the history
* feat: update export functionality

* chore: format
  • Loading branch information
Jeroen Offerijns committed Jan 5, 2021
1 parent 9f94f35 commit 7b78aec
Show file tree
Hide file tree
Showing 15 changed files with 229 additions and 168 deletions.
2 changes: 1 addition & 1 deletion onboard-api/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Module } from '@nestjs/common'
import { ScheduleModule } from '@nestjs/schedule'
import { AppController } from './app.controller'
import { AddressController } from './controllers/address.controller'
import { AgreementController } from './controllers/agreement.controller'
Expand All @@ -13,7 +14,6 @@ import { DocusignService } from './services/docusign.service'
import { SecuritizeService } from './services/kyc/securitize.service'
import { PoolService } from './services/pool.service'
import { SessionService } from './services/session.service'
import { ScheduleModule } from '@nestjs/schedule'
import { SyncService } from './services/sync.service'

// TODO: separate into modules
Expand Down
2 changes: 1 addition & 1 deletion onboard-api/src/services/kyc/securitize.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable, Logger } from '@nestjs/common'
import { KycRepo } from '../../repos/kyc.repo'
import config from '../../config'
import { KycRepo } from '../../repos/kyc.repo'
const fetch = require('@vercel/fetch-retry')(require('node-fetch'))

export interface SecuritizeDigest {
Expand Down
2 changes: 1 addition & 1 deletion tinlake-ui/components/HelpMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Drop } from 'grommet'
import React from 'react'
import { preload } from '../../utils/images'
import { Wrapper, InnerMenu, Title, MenuItem, Name } from './styles'
import { InnerMenu, MenuItem, Name, Title, Wrapper } from './styles'

const HelpMenu: React.FC<{}> = () => {
const ref = React.useRef<HTMLDivElement>(null)
Expand Down
18 changes: 8 additions & 10 deletions tinlake-ui/components/Loan/Data/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import { DisplayField } from '@centrifuge/axis-display-field'
import { baseToDisplay, feeToInterestRate, ITinlake, Loan } from '@centrifuge/tinlake-js'
import { Box, Table, TableBody, TableCell, TableRow } from 'grommet'
import * as React from 'react'
import { Box, Table, TableBody, TableRow, TableCell } from 'grommet'
import { baseToDisplay, feeToInterestRate } from '@centrifuge/tinlake-js'
import { Loan } from '@centrifuge/tinlake-js'
import { addThousandsSeparators } from '../../../utils/addThousandsSeparators'
import { toPrecision } from '../../../utils/toPrecision'
import styled from 'styled-components'
import { AuthState } from '../../../ducks/auth'
import { ITinlake } from '@centrifuge/tinlake-js'
import { addThousandsSeparators } from '../../../utils/addThousandsSeparators'
import { dateToYMD } from '../../../utils/date'
import LoanLabel from '../Label'
import { DisplayField } from '@centrifuge/axis-display-field'
import { getAddressLink } from '../../../utils/etherscanLinkGenerator'
import { toPrecision } from '../../../utils/toPrecision'
import { LoadingValue } from '../../LoadingValue'
import LoanLabel from '../Label'

interface Props {
loan: Loan
tinlake: ITinlake
auth?: AuthState
}

import styled from 'styled-components'
import { LoadingValue } from '../../LoadingValue'
const DisplayFieldWrapper = styled.div`
width: 100%;
max-width: 200px;
Expand Down
227 changes: 123 additions & 104 deletions tinlake-ui/components/Loan/List/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { DisplayField } from '@centrifuge/axis-display-field'
import { baseToDisplay, bnToHex, feeToInterestRate } from '@centrifuge/tinlake-js'
import { Box, Button, DataTable, Text } from 'grommet'
import BN from 'bn.js'
import { Box, DataTable, Text } from 'grommet'
import { useRouter } from 'next/router'
import * as React from 'react'
import styled from 'styled-components'
import NumberDisplay from '../../../components/NumberDisplay'
import { SortableLoan } from '../../../ducks/loans'
import { dateToYMD } from '../../../utils/date'
import { hexToInt } from '../../../utils/etherscanLinkGenerator'
import { saveAsCSV } from '../../../utils/export'
import ChevronRight from '../../ChevronRight'
import { dateToYMD } from '../../../utils/date'
import BN from 'bn.js'
import LoanLabel from '../Label'
import { saveAsCSV } from '../../../utils/export'

interface Props {
loans: SortableLoan[]
Expand All @@ -31,109 +32,113 @@ const LoanList: React.FC<Props> = (props: Props) => {
}

return (
<Box
width="100%"
elevation="small"
round="xsmall"
pad={{ top: 'xsmall' }}
margin={{ bottom: 'medium' }}
background="white"
>
<div style={{ display: 'none' }}>
<Button label="Export" primary onClick={() => saveAsCSV(props.loans)} />
</div>

{props.loans.length > 0 && (
<DataTable
style={{ tableLayout: 'auto' }}
data={props.loans}
sort={{ direction: 'desc', property: 'loanId' }}
pad="xsmall"
sortable
onClickRow={clickRow as any}
columns={[
{
header: 'Asset ID',
property: 'loanId',
align: 'center',
size: '140px',
},
{
header: 'NFT ID',
primary: true,
property: 'tokenId',
align: 'start',
size: '260px',
render: (l: SortableLoan) => (
<Box style={{ maxWidth: '200px' }}>
<DisplayField as={'span'} value={hexToInt(bnToHex(l.tokenId).toString())} />
</Box>
),
},
{
header: 'Financing Date',
property: 'financingDate',
align: 'end',
render: (l: SortableLoan) => (l.financingDate && l.financingDate > 0 ? dateToYMD(l.financingDate) : '-'),
},
{
header: 'Maturity Date',
property: 'maturityDate',
align: 'end',
render: (l: SortableLoan) => (l.maturityDate && l.maturityDate > 0 ? dateToYMD(l.maturityDate) : '-'),
},
{
header: 'Amount (DAI)',
property: 'amountNum',
align: 'end',
render: (l: SortableLoan) => (
<NumberDisplay
suffix=""
precision={0}
value={baseToDisplay(
l.status === 'closed'
? l.repaysAggregatedAmount || new BN(0)
: l.debt.isZero()
? l.principal
: l.debt,
18
)}
/>
),
},
{
header: <HeaderCell text={'Financing Fee'}></HeaderCell>,
property: 'interestRateNum',
align: 'end',
render: (l: SortableLoan) =>
l.status === 'Repaid' ? (
'-'
) : (
<NumberDisplay suffix=" %" precision={2} value={feeToInterestRate(l.interestRate)} />
<>
<Box
width="100%"
elevation="small"
round="xsmall"
pad={{ top: 'xsmall' }}
margin={{ bottom: 'medium' }}
background="white"
>
{props.loans.length > 0 && (
<DataTable
style={{ tableLayout: 'auto' }}
data={props.loans}
sort={{ direction: 'desc', property: 'loanId' }}
pad="xsmall"
sortable
onClickRow={clickRow as any}
columns={[
{
header: 'Asset ID',
property: 'loanId',
align: 'center',
size: '140px',
},
{
header: 'NFT ID',
primary: true,
property: 'tokenId',
align: 'start',
size: '260px',
render: (l: SortableLoan) => (
<Box style={{ maxWidth: '200px' }}>
<DisplayField as={'span'} value={hexToInt(bnToHex(l.tokenId).toString())} />
</Box>
),
},
{
header: 'Financing Date',
property: 'financingDate',
align: 'end',
render: (l: SortableLoan) =>
l.financingDate && l.financingDate > 0 ? dateToYMD(l.financingDate) : '-',
},
{
header: 'Maturity Date',
property: 'maturityDate',
align: 'end',
render: (l: SortableLoan) => (l.maturityDate && l.maturityDate > 0 ? dateToYMD(l.maturityDate) : '-'),
},
{
header: 'Amount (DAI)',
property: 'amountNum',
align: 'end',
render: (l: SortableLoan) => (
<NumberDisplay
suffix=""
precision={0}
value={baseToDisplay(
l.status === 'closed'
? l.repaysAggregatedAmount || new BN(0)
: l.debt.isZero()
? l.principal
: l.debt,
18
)}
/>
),
},
{
header: 'Status',
property: 'status',
align: 'start',
size: '130px',
render: (l: SortableLoan) => <LoanLabel loan={l} />,
},
{
header: '',
property: 'id',
align: 'center',
sortable: false,
size: '36px',
render: (_l: SortableLoan) => {
return <ChevronRight />
},
},
]}
/>
{
header: <HeaderCell text={'Financing Fee'}></HeaderCell>,
property: 'interestRateNum',
align: 'end',
render: (l: SortableLoan) =>
l.status === 'Repaid' ? (
'-'
) : (
<NumberDisplay suffix=" %" precision={2} value={feeToInterestRate(l.interestRate)} />
),
},
{
header: 'Status',
property: 'status',
align: 'start',
size: '130px',
render: (l: SortableLoan) => <LoanLabel loan={l} />,
},
{
header: '',
property: 'id',
align: 'center',
sortable: false,
size: '36px',
render: (_l: SortableLoan) => {
return <ChevronRight />
},
},
]}
/>
)}
{props.loans.length === 0 && <Text margin="medium">No assets have been originated.</Text>}
</Box>
{'export' in router.query && (
<Box justify="end">
<ExportLink onClick={() => saveAsCSV(props.loans)}>Export asset list as CSV</ExportLink>
</Box>
)}
{props.loans.length === 0 && <Text margin="medium">No assets have been originated.</Text>}
</Box>
</>
)
}

Expand All @@ -143,4 +148,18 @@ const HeaderCell = (props: { text: string }) => (
</Box>
)

const ExportLink = styled.a`
color: #333;
text-decoration: underline;
margin: 0 16px 12px 0;
font-size: 13px;
cursor: pointer;
text-align: right;
&:hover,
&:focus {
color: #000;
}
`

export default LoanList
6 changes: 3 additions & 3 deletions tinlake-ui/components/PoolsMetrics/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { baseToDisplay } from '@centrifuge/tinlake-js'
import { Box } from 'grommet'
import { useRouter } from 'next/router'
import * as React from 'react'
import { useSelector } from 'react-redux'
import { Area, AreaChart, ResponsiveContainer, Tooltip } from 'recharts'
import { PoolsDailyData, PoolsData } from '../../ducks/pools'
import { dateToYMD } from '../../utils/date'
import NumberDisplay from '../NumberDisplay'
import { Cont, Label, TokenLogo, Unit, Value } from './styles'
import { AreaChart, Area, Tooltip, ResponsiveContainer } from 'recharts'
import { useSelector } from 'react-redux'
import { dateToYMD } from '../../utils/date'

interface Props {
pools: PoolsData
Expand Down
Loading

0 comments on commit 7b78aec

Please sign in to comment.