From e68be0cae597ff06f2d468a216d66a1b4b80035e Mon Sep 17 00:00:00 2001 From: Alex Freska Date: Mon, 25 Mar 2024 12:02:13 -0400 Subject: [PATCH] fix: renterd contract set change alert --- apps/renterd/contexts/alerts/SetChange.tsx | 152 ++++++++++++++++----- 1 file changed, 115 insertions(+), 37 deletions(-) diff --git a/apps/renterd/contexts/alerts/SetChange.tsx b/apps/renterd/contexts/alerts/SetChange.tsx index 77618a216..5ff90ca58 100644 --- a/apps/renterd/contexts/alerts/SetChange.tsx +++ b/apps/renterd/contexts/alerts/SetChange.tsx @@ -2,7 +2,7 @@ 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 { formatRelative } from 'date-fns' import { useMemo } from 'react' import { Add16, Subtract16 } from '@siafoundation/react-icons' import { cx } from 'class-variance-authority' @@ -50,36 +50,103 @@ export function SetChangesField({ ...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[], - } - }) + 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[], + } + }) + .sort((a, b) => { + // size in latest event + const aSize = a.events[0].size + const bSize = b.events[0].size + return aSize < bSize ? 1 : -1 + }) }, [setAdditions, setRemovals]) + + // calculate churn %: contracts removed size / total size + const totalSize = useMemo( + () => changes.reduce((acc, { events }) => acc + events[0].size, 0), + [changes] + ) + const removals = useMemo( + () => changes.filter(({ events }) => events[0].type === 'removal'), + [changes] + ) + const additions = useMemo( + () => changes.filter(({ events }) => events[0].type === 'addition'), + [changes] + ) + const removedSize = useMemo( + () => removals.reduce((acc, { events }) => acc + events[0].size, 0), + [removals] + ) + const churn = useMemo( + () => (removedSize / totalSize) * 100, + [removedSize, totalSize] + ) + return (
- - contract set changes - +
+ + contract set changes + +
+ +
+ + churn: {churn.toFixed(2)}% + + + ({humanBytes(removedSize)} / {humanBytes(totalSize)}) + +
+
+
+ + + + {additions.length} + + + + + + {removals.length} + + +
+
{changes.map(({ contractId, hostKey, events }, i) => ( -
- +
+
+ {i + 1}. +
contract @@ -119,6 +187,9 @@ function ContractSetChange({ contextMenu={
- {events.map(({ type, reasons, size, time }) => ( + {events.map(({ type, reasons, size, time }, i) => (
@@ -168,15 +246,15 @@ function ContractSetChange({
- + time - {format(new Date(time), 'yyyy-MM-dd HH:mm a')} + {formatRelative(new Date(time), new Date())}
- + size