Skip to content

Commit 39dd2d1

Browse files
committed
feat(indexd): add reset lost sector functionality for hosts
1 parent f57a53b commit 39dd2d1

File tree

4 files changed

+98
-5
lines changed

4 files changed

+98
-5
lines changed

.changeset/funky-lamps-greet.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'indexd': minor
3+
---
4+
5+
Added button to reset lost sectors on hosts. Closes https://github.com/SiaFoundation/indexd/issues/732

apps/indexd/components/Data/Hosts/SidePanelHost.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { useHostsParams } from './useHostsParams'
2222
import { SidePanelHeadingCopyable } from '../SidePanelHeadingCopyable'
2323
import { SidePanelSkeleton } from '../SidePanelSkeleton'
2424
import { BlockReasons } from './BlockReasons'
25+
import { BulkHostResetLostSectors } from './bulkActions/BulkHostResetLostSectors'
2526

2627
export function SidePanelHost() {
2728
const { panelId, setPanelId } = useHostsParams()
@@ -76,11 +77,14 @@ export function SidePanelHost() {
7677
}
7778
actions={
7879
host ? (
79-
host.blocked ? (
80-
<BulkHostBlocklistRemove hosts={[host]} />
81-
) : (
82-
<BulkHostBlocklistAdd hosts={[host]} />
83-
)
80+
<>
81+
{host.blocked ? (
82+
<BulkHostBlocklistRemove hosts={[host]} />
83+
) : (
84+
<BulkHostBlocklistAdd hosts={[host]} />
85+
)}
86+
<BulkHostResetLostSectors hosts={[host]} />
87+
</>
8488
) : null
8589
}
8690
>

apps/indexd/components/Data/Hosts/SidePanelHostList.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { HostDataTableState } from './types'
33
import { useMapHosts } from '../useMapHosts'
44
import { BulkHostBlocklistAdd } from './bulkActions/BulkHostBlocklistAdd'
55
import { BulkHostBlocklistRemove } from './bulkActions/BulkHostBlocklistRemove'
6+
import { BulkHostResetLostSectors } from './bulkActions/BulkHostResetLostSectors'
67
import { SidePanel } from '../SidePanel'
78
import { useMemo } from 'react'
89
import { useHostsParams } from './useHostsParams'
@@ -29,6 +30,7 @@ export function SidePanelHostList({ table }: { table: HostDataTableState }) {
2930
<>
3031
<BulkHostBlocklistAdd hosts={hosts} />
3132
<BulkHostBlocklistRemove hosts={hosts} />
33+
<BulkHostResetLostSectors hosts={hosts} />
3234
</>
3335
) : null
3436
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { Button, handleBatchOperation } from '@siafoundation/design-system'
2+
import { useAdminHostResetLostSectors } from '@siafoundation/indexd-react'
3+
import { useCallback, useMemo } from 'react'
4+
import { pluralize } from '@siafoundation/units'
5+
import { HostData } from '../types'
6+
import { useMutate } from '@siafoundation/react-core'
7+
import { adminHostRoute, adminHostsRoute } from '@siafoundation/indexd-types'
8+
import { Row } from '@tanstack/react-table'
9+
import { ResetAlt16 } from '@siafoundation/react-icons'
10+
import { useDialog } from '../../../../contexts/dialog'
11+
12+
export function BulkHostResetLostSectors({
13+
hosts,
14+
}: {
15+
hosts: HostData[] | Row<HostData>[]
16+
}) {
17+
const resetLostSectors = useAdminHostResetLostSectors()
18+
const mutate = useMutate()
19+
const { openConfirmDialog } = useDialog()
20+
21+
const hostsWithLostSectors = useMemo(
22+
() =>
23+
hosts
24+
.map((host) =>
25+
'publicKey' in host ? host : (host.original as HostData)
26+
)
27+
.filter((host) => host.lostSectors > 0),
28+
[hosts]
29+
)
30+
31+
const operation = useCallback(async () => {
32+
await handleBatchOperation(
33+
hostsWithLostSectors.map((host) =>
34+
resetLostSectors.post({
35+
params: {
36+
hostkey: host.publicKey,
37+
},
38+
})
39+
),
40+
{
41+
toastError: ({ successCount, errorCount, totalCount }) => ({
42+
title: `Reset lost sectors for ${pluralize(successCount, 'host')}`,
43+
body: `Error resetting lost sectors for ${errorCount}/${totalCount} total hosts.`,
44+
}),
45+
toastSuccess: ({ totalCount }) => ({
46+
title: `Reset lost sectors for ${pluralize(totalCount, 'host')}`,
47+
}),
48+
}
49+
)
50+
await mutate((key) => key.startsWith(adminHostsRoute))
51+
await Promise.all(
52+
hostsWithLostSectors.map((host) =>
53+
mutate((key) =>
54+
key.startsWith(
55+
adminHostRoute.replace(':hostkey', host.publicKey)
56+
)
57+
)
58+
)
59+
)
60+
}, [hostsWithLostSectors, resetLostSectors, mutate])
61+
62+
if (hostsWithLostSectors.length === 0) {
63+
return null
64+
}
65+
66+
return (
67+
<Button
68+
onClick={() =>
69+
openConfirmDialog({
70+
title: `Reset lost sectors for ${pluralize(hostsWithLostSectors.length, 'host')}?`,
71+
action: 'Reset',
72+
variant: 'red',
73+
body: null,
74+
onConfirm: operation,
75+
})
76+
}
77+
>
78+
<ResetAlt16 />
79+
Reset lost sectors{hosts.length > 1 ? ` (${hostsWithLostSectors.length})` : ''}
80+
</Button>
81+
)
82+
}

0 commit comments

Comments
 (0)