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

explorer outputs display and link to their associated address, hostd and renterd automatically refresh data tables #392

Merged
merged 3 commits into from
Oct 17, 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
6 changes: 6 additions & 0 deletions .changeset/metal-crews-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'hostd': minor
'renterd': minor
---

Data tables now refresh themselves without user interaction or refocusing the app, even more frequently if a long running operation is in progress.
5 changes: 5 additions & 0 deletions .changeset/quiet-ways-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'explorer': minor
---

Outputs on the transaction view now display and link to their associated address.
52 changes: 52 additions & 0 deletions apps/explorer/components/Transaction/OutputListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use client'

import {
EntityListItemLayout,
Link,
ValueCopyable,
ValueSc,
ValueSf,
} from '@siafoundation/design-system'
import BigNumber from 'bignumber.js'

type Props = {
label: string
address: string
addressHref: string
outputId: string
sc?: BigNumber
sf?: number
}

export function OutputListItem(props: Props) {
const { label, outputId, address, addressHref, sc, sf } = props
return (
<EntityListItemLayout label={label} href={addressHref}>
<div className="flex flex-col items-center gap-1 w-full">
<div className="flex gap-2 items-center w-full">
<Link href={addressHref} weight="medium" underline="hover" ellipsis>
{label}
</Link>
<div className="flex-1" />
{sc && <ValueSc variant="change" value={sc} />}
{sf && <ValueSf variant="change" value={sf} />}
</div>
<div className="flex gap-2 justify-between w-full @container">
<ValueCopyable
value={outputId}
type="output"
label={label}
color="subtle"
/>
<ValueCopyable
value={address}
type="address"
color="subtle"
href={addressHref}
className="hidden @sm:flex"
/>
</div>
</div>
</EntityListItemLayout>
)
}
42 changes: 34 additions & 8 deletions apps/explorer/components/Transaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,47 @@ import { EntityList, EntityListItemProps } from '@siafoundation/design-system'
import { routes } from '../../config/routes'
import { ContentLayout } from '../ContentLayout'
import { TransactionHeader } from './TransactionHeader'
import { OutputListItem } from './OutputListItem'

type Props = {
transaction: SiaCentralTransaction
title?: string
}

type OutputItem = {
label: string
addressHref: string
address: string
sc?: BigNumber
sf?: number
outputId: string
}

export function Transaction({ title, transaction }: Props) {
const inputs = useMemo(() => {
if (!transaction) {
return []
}
const list: EntityListItemProps[] = []
const list: OutputItem[] = []
transaction.siacoin_inputs?.forEach((o) => {
list.push({
label:
o.source === 'transaction'
? 'siacoin output'
: o.source.replace(/_/g, ' '),
addressHref: routes.address.view.replace(':id', o.unlock_hash),
address: o.unlock_hash,
sc: new BigNumber(o.value),
hash: o.output_id,
outputId: o.output_id,
})
})
transaction.siafund_inputs?.forEach((o) => {
list.push({
label: 'siafund output',
addressHref: routes.address.view.replace(':id', o.unlock_hash),
address: o.unlock_hash,
sc: new BigNumber(o.value),
hash: o.output_id,
outputId: o.output_id,
})
})
return list
Expand All @@ -43,22 +57,26 @@ export function Transaction({ title, transaction }: Props) {
if (!transaction) {
return []
}
const list: EntityListItemProps[] = []
const list: OutputItem[] = []
transaction.siacoin_outputs?.forEach((o) => {
list.push({
label:
o.source === 'transaction'
? 'siacoin output'
: o.source.replace(/_/g, ' '),
addressHref: routes.address.view.replace(':id', o.unlock_hash),
address: o.unlock_hash,
sc: new BigNumber(o.value),
hash: o.output_id,
outputId: o.output_id,
})
})
transaction.siafund_outputs?.forEach((o) => {
list.push({
label: 'siafund output',
addressHref: routes.address.view.replace(':id', o.unlock_hash),
address: o.unlock_hash,
sf: Number(o.value),
hash: o.output_id,
outputId: o.output_id,
})
})
return list
Expand Down Expand Up @@ -112,13 +130,21 @@ 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})`} entities={inputs}>
{inputs?.map((i) => (
<OutputListItem key={i.outputId} {...i} />
))}
</EntityList>
</div>
<div>
<EntityList
title={`Outputs (${outputs.length})`}
entities={outputs}
/>
>
{outputs?.map((o) => (
<OutputListItem key={o.outputId} {...o} />
))}
</EntityList>
</div>
</div>
{!!operations?.length && (
Expand Down
6 changes: 6 additions & 0 deletions apps/hostd/contexts/config/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
triggerSuccessToast,
triggerErrorToast,
useOnInvalid,
minutesInMilliseconds,
} from '@siafoundation/design-system'
import { useCallback, useEffect, useMemo, useState } from 'react'
import {
Expand All @@ -20,6 +21,11 @@ import useLocalStorageState from 'use-local-storage-state'
export function useConfigMain() {
const settings = useSettings({
standalone: 'configSettingsForm',
config: {
swr: {
refreshInterval: minutesInMilliseconds(1),
},
},
})
const settingsUpdate = useSettingsUpdate()
const dynDNSCheck = useSettingsDdns({
Expand Down
22 changes: 9 additions & 13 deletions apps/hostd/contexts/contracts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import {
useDatasetEmptyState,
useServerFilters,
getContractsTimeRangeBlockHeight,
secondsInMilliseconds,
} from '@siafoundation/design-system'
import { useRouter } from 'next/router'
import {
ContractStatus,
useContracts as useContractsData,
useEstimatedNetworkBlockHeight,
useStateConsensus,
} from '@siafoundation/react-hostd'
import { createContext, useContext, useMemo } from 'react'
import {
Expand All @@ -21,6 +20,7 @@ import {
} from './types'
import { columns } from './columns'
import { useDataset } from './dataset'
import { useSyncStatus } from '../../hooks/useSyncStatus'

const defaultLimit = 50

Expand Down Expand Up @@ -64,6 +64,11 @@ function useContractsMain() {
.filter((f) => f.id.startsWith('filterStatus'))
.map((f) => f.value) as ContractStatus[],
},
config: {
swr: {
refreshInterval: secondsInMilliseconds(60),
},
},
})

const dataset = useDataset({
Expand All @@ -79,17 +84,8 @@ function useContractsMain() {
const error = response.error
const dataState = useDatasetEmptyState(dataset, isValidating, error, filters)

const estimatedNetworkHeight = useEstimatedNetworkBlockHeight()
const state = useStateConsensus({
config: {
swr: {
refreshInterval: 60_000,
},
},
})
const currentHeight = state.data?.synced
? state.data.chainIndex.height
: estimatedNetworkHeight
const { estimatedBlockHeight, isSynced, nodeBlockHeight } = useSyncStatus()
const currentHeight = isSynced ? nodeBlockHeight : estimatedBlockHeight

const { range: contractsTimeRange } = useMemo(
() => getContractsTimeRangeBlockHeight(currentHeight, dataset || []),
Expand Down
2 changes: 2 additions & 0 deletions apps/hostd/contexts/metrics/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
getDataIntervalLabelFormatter,
getTimeRange,
MiBToBytes,
minutesInMilliseconds,
} from '@siafoundation/design-system'
import { humanBytes, humanNumber, humanSiacoin } from '@siafoundation/sia-js'
import { useCallback, useMemo } from 'react'
Expand Down Expand Up @@ -108,6 +109,7 @@ function useMetricsMain() {
config: {
swr: {
revalidateOnFocus: false,
refreshInterval: minutesInMilliseconds(5),
},
},
})
Expand Down
21 changes: 19 additions & 2 deletions apps/hostd/contexts/volumes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import {
useTableState,
useDatasetEmptyState,
secondsInMilliseconds,
} from '@siafoundation/design-system'
import { useVolumes as useVolumesData } from '@siafoundation/react-hostd'
import {
VolumeMeta,
useVolumes as useVolumesData,
} from '@siafoundation/react-hostd'
import { createContext, useContext, useMemo } from 'react'
import { columnsDefaultVisible, TableColumnId } from './types'
import { columns } from './columns'
Expand All @@ -26,7 +30,16 @@ function useVolumesMain() {
columnsDefaultVisible,
})

const response = useVolumesData()
const response = useVolumesData({
config: {
swr: {
refreshInterval: (data) =>
data.find((v) => isOperationInProgress(v))
? secondsInMilliseconds(5)
: secondsInMilliseconds(60),
},
},
})

const dataset = useDataset({
response,
Expand Down Expand Up @@ -76,3 +89,7 @@ export function VolumesProvider({ children }: Props) {
<VolumesContext.Provider value={state}>{children}</VolumesContext.Provider>
)
}

function isOperationInProgress(volume: VolumeMeta) {
return !['ready', 'unavailable'].includes(volume.status)
}
6 changes: 4 additions & 2 deletions apps/renterd/contexts/app/useAutopilot.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { secondsInMilliseconds } from '@siafoundation/design-system'
import { useAutopilotState } from '@siafoundation/react-renterd'
import { useEffect, useState } from 'react'

export function useAutopilot() {
const state = useAutopilotState({
config: {
swr: {
dedupingInterval: 5_000,
dedupingInterval: secondsInMilliseconds(5),
revalidateOnFocus: false,
refreshInterval: (data) => (!data ? 1_000 : 60_000),
refreshInterval: (data) =>
!data ? secondsInMilliseconds(1) : secondsInMilliseconds(60),
},
},
})
Expand Down
19 changes: 19 additions & 0 deletions apps/renterd/contexts/config/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
useOnInvalid,
monthsToBlocks,
TBToBytes,
minutesInMilliseconds,
} from '@siafoundation/design-system'
import BigNumber from 'bignumber.js'
import { useCallback, useEffect, useMemo, useState } from 'react'
Expand Down Expand Up @@ -59,6 +60,7 @@ export function useConfigMain() {
config: {
swr: {
errorRetryCount: 0,
refreshInterval: minutesInMilliseconds(1),
},
},
})
Expand All @@ -67,6 +69,7 @@ export function useConfigMain() {
config: {
swr: {
errorRetryCount: 0,
refreshInterval: minutesInMilliseconds(1),
},
},
})
Expand All @@ -75,18 +78,34 @@ export function useConfigMain() {
config: {
swr: {
errorRetryCount: 0,
refreshInterval: minutesInMilliseconds(1),
},
},
})
// settings with initial defaults
const gouging = useGougingSettings({
standalone: 'configFormGouging',
config: {
swr: {
refreshInterval: minutesInMilliseconds(1),
},
},
})
const redundancy = useRedundancySettings({
standalone: 'configFormRedundancy',
config: {
swr: {
refreshInterval: minutesInMilliseconds(1),
},
},
})
const uploadPacking = useUploadPackingSettings({
standalone: 'configFormUploadPacking',
config: {
swr: {
refreshInterval: minutesInMilliseconds(1),
},
},
})

const settingUpdate = useSettingUpdate()
Expand Down
Loading