From 1053c50626ec1783859b9c199d580a791b49a81d Mon Sep 17 00:00:00 2001 From: Alex Freska Date: Thu, 21 Mar 2024 14:23:43 -0400 Subject: [PATCH] feat: renterd alert improvements and reset account drift --- .changeset/dull-birds-compare.md | 5 + .changeset/fuzzy-brooms-poke.md | 5 + .changeset/khaki-pots-deny.md | 5 + .changeset/nine-wolves-build.md | 5 + .changeset/ninety-donkeys-turn.md | 7 + .changeset/purple-moose-wink.md | 5 + .changeset/wicked-mirrors-smell.md | 5 + .../Contracts/ContractContextMenu.tsx | 4 +- .../components/Volumes/VolumeContextMenu.tsx | 4 +- .../renterd/components/AccountContextMenu.tsx | 73 +++++++ .../components/Alerts/AlertContextMenu.tsx | 4 +- .../Contracts/ContractContextMenu.tsx | 97 ++++++--- .../Contracts/ContractContextMenuFromId.tsx | 60 +++--- .../components/Hosts/HostContextMenu.tsx | 66 ++++-- .../Hosts/HostContextMenuFromId.tsx | 47 ---- .../Hosts/HostContextMenuFromKey.tsx | 53 +++++ .../components/Keys/KeyContextMenu.tsx | 4 +- apps/renterd/contexts/alerts/SetChange.tsx | 191 +++++++++++++++++ apps/renterd/contexts/alerts/columns.tsx | 31 ++- apps/renterd/contexts/alerts/data.tsx | 200 ++++-------------- apps/renterd/contexts/contracts/columns.tsx | 2 +- apps/walletd/contexts/addresses/columns.tsx | 4 +- apps/walletd/contexts/wallets/columns.tsx | 4 +- .../src/components/Table/TableRow.tsx | 17 +- .../src/components/Table/index.tsx | 2 + libs/react-renterd/src/bus.ts | 11 + 26 files changed, 605 insertions(+), 306 deletions(-) create mode 100644 .changeset/dull-birds-compare.md create mode 100644 .changeset/fuzzy-brooms-poke.md create mode 100644 .changeset/khaki-pots-deny.md create mode 100644 .changeset/nine-wolves-build.md create mode 100644 .changeset/ninety-donkeys-turn.md create mode 100644 .changeset/purple-moose-wink.md create mode 100644 .changeset/wicked-mirrors-smell.md create mode 100644 apps/renterd/components/AccountContextMenu.tsx delete mode 100644 apps/renterd/components/Hosts/HostContextMenuFromId.tsx create mode 100644 apps/renterd/components/Hosts/HostContextMenuFromKey.tsx create mode 100644 apps/renterd/contexts/alerts/SetChange.tsx diff --git a/.changeset/dull-birds-compare.md b/.changeset/dull-birds-compare.md new file mode 100644 index 000000000..2ac93dce6 --- /dev/null +++ b/.changeset/dull-birds-compare.md @@ -0,0 +1,5 @@ +--- +'@siafoundation/react-renterd': minor +--- + +Added useAccountResetDrift. diff --git a/.changeset/fuzzy-brooms-poke.md b/.changeset/fuzzy-brooms-poke.md new file mode 100644 index 000000000..613416a07 --- /dev/null +++ b/.changeset/fuzzy-brooms-poke.md @@ -0,0 +1,5 @@ +--- +'renterd': patch +--- + +Fixed an issue where the alerts list would trigger an excessive number of API calls to fetch contract and host metadata. diff --git a/.changeset/khaki-pots-deny.md b/.changeset/khaki-pots-deny.md new file mode 100644 index 000000000..3f237ea18 --- /dev/null +++ b/.changeset/khaki-pots-deny.md @@ -0,0 +1,5 @@ +--- +'@siafoundation/design-system': minor +--- + +Table now has row specific cell class name props that do not apply to the table header. diff --git a/.changeset/nine-wolves-build.md b/.changeset/nine-wolves-build.md new file mode 100644 index 000000000..c77f96749 --- /dev/null +++ b/.changeset/nine-wolves-build.md @@ -0,0 +1,5 @@ +--- +'renterd': minor +--- + +Account alerts now feature an accounts context menu with the option to reset account drift. Closes https://github.com/SiaFoundation/web/issues/524 diff --git a/.changeset/ninety-donkeys-turn.md b/.changeset/ninety-donkeys-turn.md new file mode 100644 index 000000000..e10077482 --- /dev/null +++ b/.changeset/ninety-donkeys-turn.md @@ -0,0 +1,7 @@ +--- +'hostd': minor +'renterd': minor +'walletd': minor +--- + +Context menus now all use a caret icon. diff --git a/.changeset/purple-moose-wink.md b/.changeset/purple-moose-wink.md new file mode 100644 index 000000000..1dc120d14 --- /dev/null +++ b/.changeset/purple-moose-wink.md @@ -0,0 +1,5 @@ +--- +'renterd': minor +--- + +The contract set change alert data fields are now displayed as one field that shows additions and removals for each contract in one timeline. diff --git a/.changeset/wicked-mirrors-smell.md b/.changeset/wicked-mirrors-smell.md new file mode 100644 index 000000000..8008327d5 --- /dev/null +++ b/.changeset/wicked-mirrors-smell.md @@ -0,0 +1,5 @@ +--- +'renterd': minor +--- + +Alert table row cell content is now aligned to the top of each row. diff --git a/apps/hostd/components/Contracts/ContractContextMenu.tsx b/apps/hostd/components/Contracts/ContractContextMenu.tsx index 8bf36f3dc..5b3f52986 100644 --- a/apps/hostd/components/Contracts/ContractContextMenu.tsx +++ b/apps/hostd/components/Contracts/ContractContextMenu.tsx @@ -11,7 +11,7 @@ import { Tooltip, Text, } from '@siafoundation/design-system' -import { Draggable16, DataCheck16 } from '@siafoundation/react-icons' +import { CaretDown16, DataCheck16 } from '@siafoundation/react-icons' import { ContractStatus, useContractsIntegrityCheck, @@ -62,7 +62,7 @@ export function ContractContextMenu({ - + } contentProps={{ align: 'start', ...contentProps }} diff --git a/apps/hostd/components/Volumes/VolumeContextMenu.tsx b/apps/hostd/components/Volumes/VolumeContextMenu.tsx index 3812f6ba9..1b84b2ac8 100644 --- a/apps/hostd/components/Volumes/VolumeContextMenu.tsx +++ b/apps/hostd/components/Volumes/VolumeContextMenu.tsx @@ -10,7 +10,7 @@ import { truncate, } from '@siafoundation/design-system' import { - Draggable16, + CaretDown16, Ruler16, Delete16, Locked16, @@ -47,7 +47,7 @@ export function VolumeContextMenu({ id, contentProps, buttonProps }: Props) { - + } contentProps={{ align: 'start', ...contentProps }} diff --git a/apps/renterd/components/AccountContextMenu.tsx b/apps/renterd/components/AccountContextMenu.tsx new file mode 100644 index 000000000..4cdb06922 --- /dev/null +++ b/apps/renterd/components/AccountContextMenu.tsx @@ -0,0 +1,73 @@ +import { + DropdownMenu, + DropdownMenuItem, + Button, + DropdownMenuLeftSlot, + DropdownMenuLabel, + Text, + copyToClipboard, +} from '@siafoundation/design-system' +import { Copy16, ResetAlt16, CaretDown16 } from '@siafoundation/react-icons' +import { useAccountResetDrift } from '@siafoundation/react-renterd' + +type Props = { + id: string + contentProps?: React.ComponentProps['contentProps'] + buttonProps?: React.ComponentProps + trigger?: React.ReactNode +} + +export function AccountContextMenu({ + id, + contentProps, + buttonProps, + trigger, +}: Props) { + const resetDrift = useAccountResetDrift() + return ( + + + + ) + } + contentProps={{ + align: 'start', + ...contentProps, + onClick: (e) => { + e.stopPropagation() + }, + }} + > +
+ + Account {id.slice(0, 20)}... + +
+ Actions + + resetDrift.post({ + params: { + id, + }, + }) + } + > + + + + Reset account drift + + Copy + copyToClipboard(id, 'account ID')}> + + + + Account ID + +
+ ) +} diff --git a/apps/renterd/components/Alerts/AlertContextMenu.tsx b/apps/renterd/components/Alerts/AlertContextMenu.tsx index e637fb44b..8624d4412 100644 --- a/apps/renterd/components/Alerts/AlertContextMenu.tsx +++ b/apps/renterd/components/Alerts/AlertContextMenu.tsx @@ -6,7 +6,7 @@ import { DropdownMenuLabel, Text, } from '@siafoundation/design-system' -import { Draggable16, Checkmark16 } from '@siafoundation/react-icons' +import { CaretDown16, Checkmark16 } from '@siafoundation/react-icons' import { useAlerts } from '../../contexts/alerts' type Props = { @@ -22,7 +22,7 @@ export function AlertContextMenu({ id, contentProps, buttonProps }: Props) { - + } contentProps={{ diff --git a/apps/renterd/components/Contracts/ContractContextMenu.tsx b/apps/renterd/components/Contracts/ContractContextMenu.tsx index d3549190f..66c35ab0c 100644 --- a/apps/renterd/components/Contracts/ContractContextMenu.tsx +++ b/apps/renterd/components/Contracts/ContractContextMenu.tsx @@ -8,7 +8,7 @@ import { copyToClipboard, } from '@siafoundation/design-system' import { - Draggable16, + CaretDown16, ListChecked16, Filter16, Copy16, @@ -31,8 +31,8 @@ import { useContractConfirmDelete } from './useContractConfirmDelete' type Props = { id: string trigger?: React.ReactNode - address: string - publicKey: string + hostAddress: string + hostKey: string contentProps?: React.ComponentProps['contentProps'] buttonProps?: React.ComponentProps } @@ -40,27 +40,17 @@ type Props = { export function ContractContextMenu({ id, trigger, - address, - publicKey, + hostAddress, + hostKey, contentProps, buttonProps, }: Props) { - const router = useRouter() - const { setFilter: setHostsFilter, resetFilters: resetHostsFilters } = - useHosts() - const { setFilter: setContractsFilter, resetFilters: resetContractsFilters } = - useContracts() - const blocklist = useHostsBlocklist() - const allowlist = useHostsAllowlist() - const blocklistUpdate = useBlocklistUpdate() - const allowlistUpdate = useAllowlistUpdate() - const contractConfirmDelete = useContractConfirmDelete() return ( - + ) } @@ -72,19 +62,50 @@ export function ContractContextMenu({ }, }} > + + + ) +} + +export function ContractContextMenuContent({ + id, + hostAddress, + hostKey, +}: { + id: string + hostAddress?: string + hostKey?: string +}) { + const router = useRouter() + const { setFilter: setHostsFilter, resetFilters: resetHostsFilters } = + useHosts() + const { setFilter: setContractsFilter, resetFilters: resetContractsFilters } = + useContracts() + const blocklist = useHostsBlocklist() + const allowlist = useHostsAllowlist() + const blocklistUpdate = useBlocklistUpdate() + const allowlistUpdate = useAllowlistUpdate() + const contractConfirmDelete = useContractConfirmDelete() + return ( + <>
- Contract {publicKey.slice(0, 24)}... + Contract {id.slice(0, 24)}...
Filters { resetHostsFilters() setHostsFilter({ id: 'addressContains', - value: address, - label: `Address contains ${address}`, + value: hostAddress, + label: `Address contains ${hostAddress}`, }) router.push(routes.hosts.index) }} @@ -95,9 +116,10 @@ export function ContractContextMenu({ Filter hosts by host address { resetContractsFilters() - setContractsFilter(addressContainsFilter(address)) + setContractsFilter(addressContainsFilter(hostAddress)) router.push(routes.contracts.index) }} > @@ -107,9 +129,10 @@ export function ContractContextMenu({ Filter contracts by host address { resetContractsFilters() - setContractsFilter(publicKeyContainsFilter(publicKey)) + setContractsFilter(publicKeyContainsFilter(hostKey)) router.push(routes.contracts.index) }} > @@ -119,30 +142,42 @@ export function ContractContextMenu({ Filter contracts by host public key Actions - {blocklist.data?.find((l) => l === address) ? ( - blocklistUpdate([], [address])}> + {blocklist.data?.find((l) => l === hostAddress) ? ( + blocklistUpdate([], [hostAddress])} + > Remove host address from blocklist ) : ( - blocklistUpdate([address], [])}> + blocklistUpdate([hostAddress], [])} + > Add host address to blocklist )} - {allowlist.data?.find((l) => l === publicKey) ? ( - allowlistUpdate([], [publicKey])}> + {allowlist.data?.find((l) => l === hostKey) ? ( + allowlistUpdate([], [hostKey])} + > Remove host public key from allowlist ) : ( - allowlistUpdate([publicKey], [])}> + allowlistUpdate([hostKey], [])} + > @@ -163,7 +198,8 @@ export function ContractContextMenu({ Contract ID copyToClipboard(publicKey, 'host public key')} + disabled={!hostKey} + onSelect={() => copyToClipboard(hostKey, 'host public key')} > @@ -171,13 +207,14 @@ export function ContractContextMenu({ Host public key copyToClipboard(address, 'host address')} + disabled={!hostAddress} + onSelect={() => copyToClipboard(hostAddress, 'host address')} > Host address -
+ ) } diff --git a/apps/renterd/components/Contracts/ContractContextMenuFromId.tsx b/apps/renterd/components/Contracts/ContractContextMenuFromId.tsx index f548e9946..02b82e2f6 100644 --- a/apps/renterd/components/Contracts/ContractContextMenuFromId.tsx +++ b/apps/renterd/components/Contracts/ContractContextMenuFromId.tsx @@ -1,50 +1,54 @@ -import { Button } from '@siafoundation/design-system' +import { Button, DropdownMenu } from '@siafoundation/design-system' import { CaretDown16 } from '@siafoundation/react-icons' import { useContract } from '@siafoundation/react-renterd' -import { ContractContextMenu } from './ContractContextMenu' +import { ContractContextMenuContent } from './ContractContextMenu' type Props = { id: string - contentProps?: React.ComponentProps< - typeof ContractContextMenu - >['contentProps'] + trigger?: React.ReactNode + contentProps?: React.ComponentProps['contentProps'] buttonProps?: React.ComponentProps } export function ContractContextMenuFromId({ id, + trigger, contentProps, buttonProps, }: Props) { + return ( + + + + ) + } + contentProps={{ + align: 'start', + ...contentProps, + onClick: (e) => { + e.stopPropagation() + }, + }} + > + + + ) +} + +// Only trigger a fetch when the dropdown is opened +function ContractContextMenuFromIdContent({ id }: Props) { const contract = useContract({ params: { id }, }) - if (!contract.data) { - return ( - - ) - } return ( - - - - } + hostAddress={contract.data?.hostIP} + hostKey={contract.data?.hostKey} /> ) } diff --git a/apps/renterd/components/Hosts/HostContextMenu.tsx b/apps/renterd/components/Hosts/HostContextMenu.tsx index e627c42be..8cbd634d8 100644 --- a/apps/renterd/components/Hosts/HostContextMenu.tsx +++ b/apps/renterd/components/Hosts/HostContextMenu.tsx @@ -10,12 +10,12 @@ import { copyToClipboard, } from '@siafoundation/design-system' import { - Draggable16, DataView16, ListChecked16, Filter16, Copy16, ResetAlt16, + CaretDown16, } from '@siafoundation/react-icons' import { useHostResetLostSectorCount, @@ -48,23 +48,12 @@ export function HostContextMenu({ buttonProps, trigger, }: Props) { - const router = useRouter() - const { setFilter: setHostsFilter, resetFilters: resetHostsFilters } = - useHosts() - const { setFilter: setContractsFilter, resetFilters: resetContractsFilters } = - useContracts() - const blocklist = useHostsBlocklist() - const allowlist = useHostsAllowlist() - const blocklistUpdate = useBlocklistUpdate() - const allowlistUpdate = useAllowlistUpdate() - const rescan = useRhpScan() - const resetLostSectors = useHostResetLostSectorCount() return ( - + ) } @@ -76,6 +65,31 @@ export function HostContextMenu({ }, }} > + + + ) +} + +export function HostContextMenuContent({ + address, + publicKey, +}: { + address?: string + publicKey: string +}) { + const router = useRouter() + const { setFilter: setHostsFilter, resetFilters: resetHostsFilters } = + useHosts() + const { setFilter: setContractsFilter, resetFilters: resetContractsFilters } = + useContracts() + const blocklist = useHostsBlocklist() + const allowlist = useHostsAllowlist() + const blocklistUpdate = useBlocklistUpdate() + const allowlistUpdate = useAllowlistUpdate() + const rescan = useRhpScan() + const resetLostSectors = useHostResetLostSectorCount() + return ( + <>
Host {publicKey.slice(0, 24)}... @@ -83,6 +97,7 @@ export function HostContextMenu({
Filters { resetHostsFilters() setHostsFilter({ @@ -111,6 +126,7 @@ export function HostContextMenu({ Filter hosts by public key { resetContractsFilters() setContractsFilter(addressContainsFilter(address)) @@ -136,7 +152,8 @@ export function HostContextMenu({ Actions + disabled={!address} + onSelect={() => { rescan.post({ payload: { hostKey: publicKey, @@ -144,22 +161,28 @@ export function HostContextMenu({ timeout: secondsInMilliseconds(30), }, }) - } + }} > Rescan host - {blocklist.data?.find((l) => l === address) ? ( - blocklistUpdate([], [address])}> + {address && blocklist.data?.find((l) => l === address) ? ( + blocklistUpdate([], [address])} + > Remove address from blocklist ) : ( - blocklistUpdate([address], [])}> + blocklistUpdate([address], [])} + > @@ -205,13 +228,16 @@ export function HostContextMenu({ Host public key copyToClipboard(address, 'host address')} + disabled={!address} + onSelect={() => { + copyToClipboard(address, 'host address') + }} > Host address -
+ ) } diff --git a/apps/renterd/components/Hosts/HostContextMenuFromId.tsx b/apps/renterd/components/Hosts/HostContextMenuFromId.tsx deleted file mode 100644 index 72e3ff4da..000000000 --- a/apps/renterd/components/Hosts/HostContextMenuFromId.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Button } from '@siafoundation/design-system' -import { CaretDown16 } from '@siafoundation/react-icons' -import { useHost } from '@siafoundation/react-renterd' -import { HostContextMenu } from './HostContextMenu' - -type Props = { - hostKey: string - contentProps?: React.ComponentProps['contentProps'] - buttonProps?: React.ComponentProps -} - -export function HostContextMenuFromKey({ - hostKey, - contentProps, - buttonProps, -}: Props) { - const host = useHost({ - params: { hostKey }, - }) - - if (!host.data) { - return ( - - ) - } - return ( - - - - } - /> - ) -} diff --git a/apps/renterd/components/Hosts/HostContextMenuFromKey.tsx b/apps/renterd/components/Hosts/HostContextMenuFromKey.tsx new file mode 100644 index 000000000..ad9318ffc --- /dev/null +++ b/apps/renterd/components/Hosts/HostContextMenuFromKey.tsx @@ -0,0 +1,53 @@ +import { Button, DropdownMenu } from '@siafoundation/design-system' +import { CaretDown16 } from '@siafoundation/react-icons' +import { useHost } from '@siafoundation/react-renterd' +import { HostContextMenuContent } from './HostContextMenu' + +type Props = { + hostKey: string + contentProps?: React.ComponentProps['contentProps'] + buttonProps?: React.ComponentProps + trigger?: React.ReactNode +} + +export function HostContextMenuFromKey({ + hostKey, + contentProps, + buttonProps, + trigger, +}: Props) { + return ( + + + + ) + } + contentProps={{ + align: 'start', + ...contentProps, + onClick: (e) => { + e.stopPropagation() + }, + }} + > + + + ) +} + +// Only trigger a fetch when the dropdown is opened +function HostContextMenuFromKeyContent({ hostKey }: { hostKey: string }) { + const host = useHost({ + params: { hostKey }, + }) + + return ( + + ) +} diff --git a/apps/renterd/components/Keys/KeyContextMenu.tsx b/apps/renterd/components/Keys/KeyContextMenu.tsx index 246b8218f..db87f6c8e 100644 --- a/apps/renterd/components/Keys/KeyContextMenu.tsx +++ b/apps/renterd/components/Keys/KeyContextMenu.tsx @@ -10,7 +10,7 @@ import { triggerErrorToast, truncate, } from '@siafoundation/design-system' -import { Draggable16, Delete16 } from '@siafoundation/react-icons' +import { CaretDown16, Delete16 } from '@siafoundation/react-icons' import { useSettingUpdate } from '@siafoundation/react-renterd' import { useS3AuthenticationSettings } from '../../hooks/useS3AuthenticationSettings' import { useCallback } from 'react' @@ -48,7 +48,7 @@ export function KeyContextMenu({ s3Key, contentProps, buttonProps }: Props) { - + } contentProps={{ diff --git a/apps/renterd/contexts/alerts/SetChange.tsx b/apps/renterd/contexts/alerts/SetChange.tsx new file mode 100644 index 000000000..77618a216 --- /dev/null +++ b/apps/renterd/contexts/alerts/SetChange.tsx @@ -0,0 +1,191 @@ +import { Text, Tooltip, ValueCopyable } from '@siafoundation/design-system' +import { HostContextMenuFromKey } from '../../components/Hosts/HostContextMenuFromKey' +import { ContractContextMenuFromId } from '../../components/Contracts/ContractContextMenuFromId' +import { humanBytes } from '@siafoundation/units' +import { format } from 'date-fns' +import { useMemo } from 'react' +import { Add16, Subtract16 } from '@siafoundation/react-icons' +import { cx } from 'class-variance-authority' +import { uniq } from '@technically/lodash' + +type ChangeEvent = { + type: 'addition' | 'removal' + reasons?: string + size: number + time: string +} + +type Change = { + contractId: string + hostKey: string + events: ChangeEvent[] +} + +export type SetAdditions = Record< + string, + { + hostKey: string + additions: { size: number; time: string }[] + } +> + +export type SetRemovals = Record< + string, + { + hostKey: string + removals: { reasons: string; size: number; time: string }[] + } +> + +export function SetChangesField({ + setAdditions, + setRemovals, +}: { + setAdditions: SetAdditions + setRemovals: SetRemovals +}) { + const changes = useMemo(() => { + // Merge all unique contract ids from additions and removals together + const contractIds = uniq([ + ...Object.keys(setAdditions), + ...Object.keys(setRemovals), + ]) + return contractIds.map((contractId) => { + const additions = setAdditions[contractId]?.additions || [] + const removals = setRemovals[contractId]?.removals || [] + return { + contractId, + hostKey: + setAdditions[contractId]?.hostKey || setRemovals[contractId]?.hostKey, + events: [ + ...additions.map((a) => ({ + type: 'addition', + size: a.size, + time: a.time, + })), + ...removals.map((r) => ({ + type: 'removal', + size: r.size, + time: r.time, + reasons: r.reasons, + })), + ].sort((a, b) => + new Date(a.time).getTime() > new Date(b.time).getTime() ? 1 : -1 + ) as ChangeEvent[], + } + }) + }, [setAdditions, setRemovals]) + return ( +
+ + contract set changes + +
+ {changes.map(({ contractId, hostKey, events }, i) => ( + + ))} +
+
+ ) +} + +function ContractSetChange({ + contractId, + hostKey, + events, + i, +}: Change & { + i: number +}) { + return ( +
+
+ + {i + 1}. + +
+ + contract + + + } + /> +
+
+ + host + + + } + /> +
+
+ {events.map(({ type, reasons, size, time }) => ( + +
+
+ + {type === 'addition' ? : } + + + {reasons} + +
+
+
+ + time + + + {format(new Date(time), 'yyyy-MM-dd HH:mm a')} + +
+
+ + size + + + {humanBytes(size)} + +
+
+ + ))} +
+ ) +} diff --git a/apps/renterd/contexts/alerts/columns.tsx b/apps/renterd/contexts/alerts/columns.tsx index 9933f74b9..4744d4543 100644 --- a/apps/renterd/contexts/alerts/columns.tsx +++ b/apps/renterd/contexts/alerts/columns.tsx @@ -9,6 +9,7 @@ import { } from '@siafoundation/design-system' import { AlertData, TableColumnId } from './types' import { dataFields } from './data' +import { SetAdditions, SetChangesField, SetRemovals } from './SetChange' import { Checkmark16 } from '@carbon/icons-react' import { formatRelative } from 'date-fns' import { Fragment, useMemo } from 'react' @@ -26,6 +27,7 @@ export const columns: KeysTableColumn[] = [ label: '', fixed: true, cellClassName: 'w-[50px] !pr-4 [&+*]:!pl-0', + rowCellClassName: 'align-top pt-[19px]', render: ({ data: { dismiss } }) => ( } contentProps={{ align: 'start' }} diff --git a/apps/walletd/contexts/wallets/columns.tsx b/apps/walletd/contexts/wallets/columns.tsx index 5404eba96..a1929dd52 100644 --- a/apps/walletd/contexts/wallets/columns.tsx +++ b/apps/walletd/contexts/wallets/columns.tsx @@ -8,7 +8,7 @@ import { ValueSf, ValueScFiat, } from '@siafoundation/design-system' -import { Locked16, Unlocked16, Draggable16 } from '@siafoundation/react-icons' +import { Locked16, Unlocked16, CaretDown16 } from '@siafoundation/react-icons' import { humanDate } from '@siafoundation/units' import { humanTimeAndUnits } from '../../lib/time' import { walletTypes } from '../../config/walletTypes' @@ -36,7 +36,7 @@ export const columns: WalletsTableColumn[] = [ - + } contentProps={{ align: 'start' }} diff --git a/libs/design-system/src/components/Table/TableRow.tsx b/libs/design-system/src/components/Table/TableRow.tsx index ff2d8cb14..ab482aedb 100644 --- a/libs/design-system/src/components/Table/TableRow.tsx +++ b/libs/design-system/src/components/Table/TableRow.tsx @@ -28,6 +28,8 @@ export type TableColumn = { size?: number | string cellClassName?: string contentClassName?: string + rowCellClassName?: string + rowContentClassName?: string render: React.FC> } @@ -97,15 +99,21 @@ export function createTableRow< { id, render: Render, - contentClassName: className, + contentClassName, cellClassName, + rowCellClassName, + rowContentClassName, }, i ) => (
= { size?: number | string cellClassName?: string contentClassName?: string + rowCellClassName?: string + rowContentClassName?: string render: React.FC> } diff --git a/libs/react-renterd/src/bus.ts b/libs/react-renterd/src/bus.ts index 2cc83223e..7b8df7a16 100644 --- a/libs/react-renterd/src/bus.ts +++ b/libs/react-renterd/src/bus.ts @@ -417,6 +417,17 @@ export function useHostResetLostSectorCount( }) } +// accounts + +export function useAccountResetDrift( + args?: HookArgsCallback<{ id: string }, void, void> +) { + return usePostFunc({ + ...args, + route: '/bus/account/:id/resetdrift', + }) +} + // contracts const contractsActiveRoute = '/bus/contracts'