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

hostd paginate transactions, refactor entitylist states #425

Merged
merged 1 commit into from
Nov 29, 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/lucky-walls-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'hostd': minor
---

Wallet transactions are now paginated.
5 changes: 5 additions & 0 deletions .changeset/twelve-glasses-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@siafoundation/design-system': minor
---

EntityList props refactored.
4 changes: 2 additions & 2 deletions apps/explorer/components/Address/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ export function Address({ id, address }: Props) {
<TabsTrigger value="utxos">Unspent outputs</TabsTrigger>
</TabsList>
<TabsContent value="transactions">
<EntityList entities={transactions} />
<EntityList dataset={transactions} />
</TabsContent>
<TabsContent value="utxos">
<EntityList entities={utxos} />
<EntityList dataset={utxos} />
</TabsContent>
</Tabs>
</ContentLayout>
Expand Down
4 changes: 2 additions & 2 deletions apps/explorer/components/AddressSkeleton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ export function AddressSkeleton() {
<TabsTrigger value="utxos">Unspent outputs</TabsTrigger>
</TabsList>
<TabsContent value="transactions">
<EntityList />
<EntityList isLoading />
</TabsContent>
<TabsContent value="utxos">
<EntityList />
<EntityList isLoading />
</TabsContent>
</Tabs>
</ContentLayout>
Expand Down
2 changes: 1 addition & 1 deletion apps/explorer/components/Block/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function Block({ block }: Props) {
>
<EntityList
title={`Transactions (${block.transactions?.length || 0})`}
entities={block.transactions?.map((tx) => ({
dataset={block.transactions?.map((tx) => ({
hash: tx.id,
label: 'transaction',
initials: 'T',
Expand Down
2 changes: 1 addition & 1 deletion apps/explorer/components/BlockSkeleton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function BlockSkeleton() {
</div>
}
>
<EntityList title="Transactions" entities={undefined} />
<EntityList title="Transactions" isLoading />
</ContentLayout>
)
}
34 changes: 17 additions & 17 deletions apps/explorer/components/Contract/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ export function Contract({ contract, rates, renewedFrom, renewedTo }: Props) {
value:
contract.negotiation_timestamp !== '0001-01-01T00:00:00Z'
? humanDate(contract.negotiation_timestamp, {
dateStyle: 'medium',
timeStyle: 'short',
})
dateStyle: 'medium',
timeStyle: 'short',
})
: '-',
},
{
Expand All @@ -81,9 +81,9 @@ export function Contract({ contract, rates, renewedFrom, renewedTo }: Props) {
value:
contract.expiration_timestamp !== '0001-01-01T00:00:00Z'
? humanDate(contract.expiration_timestamp, {
dateStyle: 'medium',
timeStyle: 'short',
})
dateStyle: 'medium',
timeStyle: 'short',
})
: '-',
},
{
Expand All @@ -99,9 +99,9 @@ export function Contract({ contract, rates, renewedFrom, renewedTo }: Props) {
value:
contract.proof_timestamp !== '0001-01-01T00:00:00Z'
? humanDate(contract.proof_timestamp, {
dateStyle: 'medium',
timeStyle: 'short',
})
dateStyle: 'medium',
timeStyle: 'short',
})
: '-',
},
{
Expand All @@ -115,9 +115,9 @@ export function Contract({ contract, rates, renewedFrom, renewedTo }: Props) {
value:
contract.proof_deadline_timestamp !== '0001-01-01T00:00:00Z'
? humanDate(contract.proof_deadline_timestamp, {
dateStyle: 'medium',
timeStyle: 'short',
})
dateStyle: 'medium',
timeStyle: 'short',
})
: '-',
},
{
Expand All @@ -131,9 +131,9 @@ export function Contract({ contract, rates, renewedFrom, renewedTo }: Props) {
value:
contract.payout_timestamp !== '0001-01-01T00:00:00Z'
? humanDate(contract.payout_timestamp, {
dateStyle: 'medium',
timeStyle: 'short',
})
dateStyle: 'medium',
timeStyle: 'short',
})
: '-',
},
{
Expand Down Expand Up @@ -202,13 +202,13 @@ export function Contract({ contract, rates, renewedFrom, renewedTo }: Props) {
<div>
<EntityList
title={`Missed proof outputs (${missedProofOutputs.length})`}
entities={missedProofOutputs}
dataset={missedProofOutputs}
/>
</div>
<div>
<EntityList
title={`Valid proof outputs (${validProofOutputs.length})`}
entities={validProofOutputs}
dataset={validProofOutputs}
/>
</div>
</div>
Expand Down
8 changes: 2 additions & 6 deletions apps/explorer/components/ContractSkeleton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,12 @@ export function ContractSkeleton() {
<div>
<EntityList
title="Missed proof outputs"
entities={undefined}
isLoading
skeletonCount={2}
/>
</div>
<div>
<EntityList
title="Valid proof outputs"
entities={undefined}
skeletonCount={2}
/>
<EntityList title="Valid proof outputs" isLoading skeletonCount={2} />
</div>
</div>
</ContentLayout>
Expand Down
2 changes: 1 addition & 1 deletion apps/explorer/components/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export function Home({
<div>
<BlockList
title="Latest blocks"
blocks={reverse(sortBy(blocks, 'timestamp')).map((block) => ({
dataset={reverse(sortBy(blocks, 'timestamp')).map((block) => ({
height: block.height,
timestamp: block.timestamp,
href: routes.block.view.replace(':id', String(block.height)),
Expand Down
4 changes: 2 additions & 2 deletions apps/explorer/components/HomeSkeleton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export function HomeSkeleton() {
}
>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-x-5 gap-y-5">
<BlockList title="Latest blocks" skeletonCount={5} />
<EntityList title="Top hosts" skeletonCount={5} />
<BlockList title="Latest blocks" isLoading skeletonCount={5} />
<EntityList title="Top hosts" isLoading skeletonCount={5} />
</div>
</ContentLayout>
)
Expand Down
9 changes: 3 additions & 6 deletions apps/explorer/components/Transaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,14 @@ export function Transaction({ title, transaction }: Props) {
<div className="flex flex-col gap-5">
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-5 gap-y-5">
<div>
<EntityList title={`Inputs (${inputs.length})`} entities={inputs}>
<EntityList title={`Inputs (${inputs.length})`} dataset={inputs}>
{inputs?.map((i) => (
<OutputListItem key={i.outputId} {...i} />
))}
</EntityList>
</div>
<div>
<EntityList
title={`Outputs (${outputs.length})`}
entities={outputs}
>
<EntityList title={`Outputs (${outputs.length})`} dataset={outputs}>
{outputs?.map((o) => (
<OutputListItem key={o.outputId} {...o} />
))}
Expand All @@ -150,7 +147,7 @@ export function Transaction({ title, transaction }: Props) {
{!!operations?.length && (
<EntityList
title={`Related operations (${operations.length})`}
entities={operations}
dataset={operations}
/>
)}
</div>
Expand Down
10 changes: 3 additions & 7 deletions apps/explorer/components/TransactionSkeleton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,15 @@ export function TransactionSkeleton() {
<div className="grid grid-cols-1 gap-5">
<div className="grid grid-cols-2 gap-5">
<div>
<EntityList title="Inputs" entities={undefined} skeletonCount={4} />
<EntityList title="Inputs" isLoading skeletonCount={4} />
</div>
<div>
<EntityList
title="Outputs"
entities={undefined}
skeletonCount={4}
/>
<EntityList title="Outputs" isLoading skeletonCount={4} />
</div>
</div>
{/* <EntityList
title="Related operations"
entities={undefined}
isLoading
skeletonCount={4}
/> */}
</div>
Expand Down
1 change: 1 addition & 0 deletions apps/hostd/components/Node/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function Node() {
</div>
<PeerList
peers={peerList}
isLoading={peers.isValidating}
connectPeer={() => openDialog('connectPeer')}
/>
</div>
Expand Down
18 changes: 18 additions & 0 deletions apps/hostd/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>
)
}
103 changes: 18 additions & 85 deletions apps/hostd/components/Wallet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,98 +1,29 @@
import {
EntityList,
EntityListItemProps,
WalletLayoutActions,
getTransactionType,
BalanceEvolution,
daysInMilliseconds,
WalletSyncWarning,
PaginatorUnknownTotal,
} from '@siafoundation/design-system'
import {
useMetricsPeriod,
useWallet,
useWalletPending,
useWalletTransactions,
} from '@siafoundation/react-hostd'
import { useMemo } from 'react'
import { useWallet } from '@siafoundation/react-hostd'
import { useDialog } from '../../contexts/dialog'
import { routes } from '../../config/routes'
import BigNumber from 'bignumber.js'
import { HostdSidenav } from '../HostdSidenav'
import { HostdAuthedLayout } from '../HostdAuthedLayout'
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: {
limit: 50,
offset: 0,
},
})
const pending = useWalletPending()

const { openDialog } = useDialog()

const wallet = useWallet()

const entities: EntityListItemProps[] = useMemo(
() => [
...(pending.data || []).map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t.transaction, t.source),
hash: t.ID,
timestamp: new Date(t.timestamp).getTime(),
sc: new BigNumber(t.inflow).minus(t.outflow),
unconfirmed: true,
}
}),
...(transactions.data || [])
.map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t.transaction, t.source),
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, transactions, openDialog]
)

const dayPeriods = 30
const start = useMemo(() => {
const today = new Date().getTime()
const periodsInMs = daysInMilliseconds(dayPeriods)
const periodsAgo = today - periodsInMs
return new Date(periodsAgo).toISOString()
}, [])

const metrics = useMetricsPeriod({
params: {
interval: 'daily',
start,
},
})
const balances = useMemo(
() =>
(metrics.data || [])
.map((t) => {
return {
sc: Number(t.balance),
timestamp: new Date(t.timestamp).getTime(),
}
})
.sort((a, b) => (a.timestamp >= b.timestamp ? 1 : -1)),
[metrics.data]
)

const { isSynced, isWalletSynced, syncPercent, walletScanPercent } =
useSyncStatus()

const { dataset, balances, metrics, offset, limit, dataState, pageCount } =
useTransactions()

return (
<HostdAuthedLayout
routes={routes}
Expand All @@ -118,14 +49,7 @@ 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.find((b) => b.sc) ? (
Expand All @@ -136,8 +60,17 @@ export function Wallet() {
) : null}
<EntityList
title="Transactions"
entities={entities.slice(0, 100)}
dataset={dataset}
isLoading={dataState === 'loading'}
emptyState={<EmptyState />}
actions={
<PaginatorUnknownTotal
offset={offset}
limit={limit}
pageTotal={pageCount}
isLoading={dataState === 'loading'}
/>
}
/>
</div>
</HostdAuthedLayout>
Expand Down
Loading