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

renterd paginate transactions #424

Merged
merged 1 commit into from
Nov 28, 2023
Merged
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
5 changes: 5 additions & 0 deletions .changeset/grumpy-bags-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': minor
---

Wallet transactions are now paginated.
18 changes: 18 additions & 0 deletions apps/renterd/components/Wallet/WalletFilterBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { WalletSyncWarning } from '@siafoundation/design-system'
import { useSyncStatus } from '../../hooks/useSyncStatus'

export function WalletFilterBar() {
const { isSynced, syncPercent, isWalletSynced, walletScanPercent } =
useSyncStatus()
return (
<div className="flex gap-2 w-full">
<WalletSyncWarning
isSynced={isSynced}
isWalletSynced={isWalletSynced}
syncPercent={syncPercent}
walletScanPercent={walletScanPercent}
/>
<div className="flex-1" />
</div>
)
}
113 changes: 17 additions & 96 deletions apps/renterd/components/Wallet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,103 +1,23 @@
import {
EntityList,
EntityListItemProps,
PaginatorUnknownTotal,
WalletLayoutActions,
getTransactionType,
BalanceEvolution,
WalletSyncWarning,
} from '@siafoundation/design-system'
import {
useWallet,
useWalletPending,
useWalletTransactions,
} from '@siafoundation/react-renterd'
import { useMemo } from 'react'
import { useWallet } from '@siafoundation/react-renterd'
import { useDialog } from '../../contexts/dialog'
import { routes } from '../../config/routes'
import BigNumber from 'bignumber.js'
import { RenterdSidenav } from '../RenterdSidenav'
import { RenterdAuthedLayout } from '../RenterdAuthedLayout'
import { useSyncStatus } from '../../hooks/useSyncStatus'
import { EmptyState } from './EmptyState'
import { useTransactions } from '../../contexts/transactions'
import { WalletFilterBar } from './WalletFilterBar'

export function Wallet() {
const transactions = useWalletTransactions({
params: {
// Endpoint currently returns wrong end of txn list
// max: 50,
},
config: {
swr: {
refreshInterval: 60_000,
revalidateOnFocus: false,
},
},
})

const pending = useWalletPending()

const { openDialog } = useDialog()

const entities: EntityListItemProps[] | null = useMemo(() => {
if (!pending.data || !transactions.data) {
return null
}
return [
...(pending.data || []).map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t),
// hash: t.ID,
// timestamp: new Date(t.Timestamp).getTime(),
// onClick: () => openDialog('transactionDetails', t.ID),
// sc: totals.sc,
unconfirmed: true,
}
}),
...(transactions.data || [])
.map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t.raw),
hash: t.id,
timestamp: new Date(t.timestamp).getTime(),
onClick: () => openDialog('transactionDetails', t.id),
sc: new BigNumber(t.inflow).minus(t.outflow),
}
})
.sort((a, b) => (a.timestamp < b.timestamp ? 1 : -1)),
]
}, [pending.data, transactions.data, openDialog])

// This now works but the visx chart has an issue where the tooltip does not
// find the correct nearest datum when the data is not at a consistent
// interval due to axis scale issues. renterd needs to return clean data
// like hostd or we need to wait for this issue to be fixed:
// https://github.com/airbnb/visx/issues/1533
// until then renterd will use a line graph which does not have the issue.
const balances = useMemo(
() =>
transactions.data
?.sort((a, b) => (a.timestamp > b.timestamp ? 1 : -1))
.reduce((acc, t, i) => {
if (i === 0) {
return acc.concat({
sc: new BigNumber(t.inflow).minus(t.outflow).toNumber(),
timestamp: new Date(t.timestamp).getTime(),
})
}
return acc.concat({
sc: new BigNumber(acc[i - 1].sc)
.plus(t.inflow)
.minus(t.outflow)
.toNumber(),
timestamp: new Date(t.timestamp).getTime(),
})
}, []),
[transactions.data]
)

const wallet = useWallet()
const { dataset, offset, limit, pageCount, dataState } = useTransactions()
const { isSynced, syncPercent, isWalletSynced, walletScanPercent } =
useSyncStatus()

Expand Down Expand Up @@ -126,28 +46,29 @@ export function Wallet() {
sendSiacoin={() => openDialog('sendSiacoin')}
/>
}
stats={
<WalletSyncWarning
isSynced={isSynced}
isWalletSynced={isWalletSynced}
syncPercent={syncPercent}
walletScanPercent={walletScanPercent}
/>
}
stats={<WalletFilterBar />}
>
<div className="p-6 flex flex-col gap-5">
{balances?.length ? (
{/* {balances?.length ? (
<BalanceEvolution
// see comment above
chartType="line"
balances={balances}
isLoading={transactions.isValidating}
/>
) : null}
) : null} */}
<EntityList
title="Transactions"
entities={entities?.slice(0, 100)}
entities={dataset?.slice(0, 100)}
emptyState={<EmptyState />}
actions={
<PaginatorUnknownTotal
offset={offset}
limit={limit}
pageTotal={pageCount}
isLoading={dataState === 'loading'}
/>
}
/>
</div>
</RenterdAuthedLayout>
Expand Down
25 changes: 14 additions & 11 deletions apps/renterd/config/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AppProvider } from '../contexts/app'
import { ConfigProvider } from '../contexts/config'
import { OnboardingBar } from '../components/OnboardingBar'
import { TransfersBar } from '../components/TransfersBar'
import { TransactionsProvider } from '../contexts/transactions'

type Props = {
children: React.ReactNode
Expand All @@ -17,18 +18,20 @@ export function Providers({ children }: Props) {
<AppProvider>
<ConfigProvider>
<DialogProvider>
<ContractsProvider>
<HostsProvider>
<FilesProvider>
{/* this is here so that dialogs can use all the other providers,
<TransactionsProvider>
<ContractsProvider>
<HostsProvider>
<FilesProvider>
{/* this is here so that dialogs can use all the other providers,
and the other providers can trigger dialogs */}
<OnboardingBar />
<TransfersBar />
<Dialogs />
{children}
</FilesProvider>
</HostsProvider>
</ContractsProvider>
<OnboardingBar />
<TransfersBar />
<Dialogs />
{children}
</FilesProvider>
</HostsProvider>
</ContractsProvider>
</TransactionsProvider>
</DialogProvider>
</ConfigProvider>
</AppProvider>
Expand Down
132 changes: 132 additions & 0 deletions apps/renterd/contexts/transactions/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import {
EntityListItemProps,
getTransactionType,
useDatasetEmptyState,
} from '@siafoundation/design-system'
import {
useWalletPending,
useWalletTransactions,
} from '@siafoundation/react-renterd'
import { createContext, useContext, useMemo } from 'react'
import { useDialog } from '../dialog'
import BigNumber from 'bignumber.js'
import { useRouter } from 'next/router'

const defaultLimit = 50
const filters = []

function useTransactionsMain() {
const router = useRouter()
const limit = Number(router.query.limit || defaultLimit)
const offset = Number(router.query.offset || 0)
const transactions = useWalletTransactions({
params: {
// Endpoint currently returns wrong end of txn list
limit,
offset,
},
config: {
swr: {
refreshInterval: 60_000,
revalidateOnFocus: false,
},
},
})

const pending = useWalletPending()

const { openDialog } = useDialog()

const dataset: EntityListItemProps[] | null = useMemo(() => {
if (!pending.data || !transactions.data) {
return null
}
return [
...(pending.data || []).map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t),
// hash: t.ID,
// timestamp: new Date(t.Timestamp).getTime(),
// onClick: () => openDialog('transactionDetails', t.ID),
// sc: totals.sc,
unconfirmed: true,
}
}),
...(transactions.data || [])
.map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t.raw),
hash: t.id,
timestamp: new Date(t.timestamp).getTime(),
onClick: () => openDialog('transactionDetails', t.id),
sc: new BigNumber(t.inflow).minus(t.outflow),
}
})
.sort((a, b) => (a.timestamp < b.timestamp ? 1 : -1)),
]
}, [pending.data, transactions.data, openDialog])

// // This now works but the visx chart has an issue where the tooltip does not
// // find the correct nearest datum when the data is not at a consistent
// // interval due to axis scale issues. renterd needs to return clean data
// // like hostd or we need to wait for this issue to be fixed:
// // https://github.com/airbnb/visx/issues/1533
// // until then renterd will use a line graph which does not have the issue.
// const balances = useMemo(
// () =>
// transactions.data
// ?.sort((a, b) => (a.timestamp > b.timestamp ? 1 : -1))
// .reduce((acc, t, i) => {
// if (i === 0) {
// return acc.concat({
// sc: new BigNumber(t.inflow).minus(t.outflow).toNumber(),
// timestamp: new Date(t.timestamp).getTime(),
// })
// }
// return acc.concat({
// sc: new BigNumber(acc[i - 1].sc)
// .plus(t.inflow)
// .minus(t.outflow)
// .toNumber(),
// timestamp: new Date(t.timestamp).getTime(),
// })
// }, []),
// [transactions.data]
// )
const error = transactions.error
const dataState = useDatasetEmptyState(
dataset,
transactions.isValidating,
error,
filters
)

return {
dataset,
error,
dataState,
offset,
limit,
pageCount: dataset?.length || 0,
}
}

type State = ReturnType<typeof useTransactionsMain>

const TransactionsContext = createContext({} as State)
export const useTransactions = () => useContext(TransactionsContext)

type Props = {
children: React.ReactNode
}

export function TransactionsProvider({ children }: Props) {
const state = useTransactionsMain()
return (
<TransactionsContext.Provider value={state}>
{children}
</TransactionsContext.Provider>
)
}
4 changes: 3 additions & 1 deletion libs/react-renterd/src/bus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ export function useWalletAddresses(args?: HookArgsSwr<void, string[]>) {

type WalletTransactionsParams = {
since?: number
max?: number
before?: number
offset?: number
limit?: number
}

export function useWalletTransactions(
Expand Down