diff --git a/webui/src/components/ActivityBar.tsx b/webui/src/components/ActivityBar.tsx index ca094caf..ef3b3688 100644 --- a/webui/src/components/ActivityBar.tsx +++ b/webui/src/components/ActivityBar.tsx @@ -40,7 +40,7 @@ export const ActivityBar = () => { return () => { unsubscribeFromOperations(callback); }; - }); + }, []); const details = activeOperations.map((op) => { return { diff --git a/webui/src/components/OperationList.tsx b/webui/src/components/OperationList.tsx index 9b3489b2..43cf38f0 100644 --- a/webui/src/components/OperationList.tsx +++ b/webui/src/components/OperationList.tsx @@ -71,7 +71,7 @@ export const OperationList = ({ setBackups(backups); }, 100, - { leading: true, trailing: true } + { trailing: true } ) ); @@ -108,11 +108,11 @@ export const OperationList = ({ itemLayout="horizontal" size="small" dataSource={operations} - renderItem={(op) => { + renderItem={(op, index) => { return ( diff --git a/webui/src/components/OperationRow.tsx b/webui/src/components/OperationRow.tsx index 062bc157..477c1289 100644 --- a/webui/src/components/OperationRow.tsx +++ b/webui/src/components/OperationRow.tsx @@ -329,7 +329,7 @@ export const OperationRow = ({ children.push(body); return ( - + ); diff --git a/webui/src/components/StatsPanel.tsx b/webui/src/components/StatsPanel.tsx index 6c46f03b..77579f6d 100644 --- a/webui/src/components/StatsPanel.tsx +++ b/webui/src/components/StatsPanel.tsx @@ -22,6 +22,7 @@ import { BackupInfoCollector, getOperations, subscribeToOperations, + unsubscribeFromOperations, } from "../state/oplog"; import { MAX_OPERATION_HISTORY } from "../constants"; import { GetOperationsRequest, OpSelector } from "../../gen/ts/v1/service_pb"; @@ -36,38 +37,42 @@ const StatsPanel = ({ repoId }: { repoId: string }) => { return; } - const refreshOperations = _.debounce(() => { - const backupCollector = new BackupInfoCollector((op) => { - return ( - op.status === OperationStatus.STATUS_SUCCESS && - op.op.case === "operationStats" && - !!op.op.value.stats - ); - }); + const refreshOperations = _.debounce( + () => { + const backupCollector = new BackupInfoCollector((op) => { + return ( + op.status === OperationStatus.STATUS_SUCCESS && + op.op.case === "operationStats" && + !!op.op.value.stats + ); + }); - getOperations( - new GetOperationsRequest({ - selector: new OpSelector({ - repoId: repoId, - }), - lastN: BigInt(MAX_OPERATION_HISTORY), - }) - ) - .then((ops) => { - backupCollector.bulkAddOperations(ops); + getOperations( + new GetOperationsRequest({ + selector: new OpSelector({ + repoId: repoId, + }), + lastN: BigInt(MAX_OPERATION_HISTORY), + }) + ) + .then((ops) => { + backupCollector.bulkAddOperations(ops); - const operations = backupCollector - .getAll() - .flatMap((b) => b.operations); - operations.sort((a, b) => { - return Number(b.unixTimeEndMs - a.unixTimeEndMs); + const operations = backupCollector + .getAll() + .flatMap((b) => b.operations); + operations.sort((a, b) => { + return Number(b.unixTimeEndMs - a.unixTimeEndMs); + }); + setOperations(() => operations); + }) + .catch((e) => { + alertApi!.error("Failed to fetch operations: " + e.message); }); - setOperations(operations); - }) - .catch((e) => { - alertApi!.error("Failed to fetch operations: " + e.message); - }); - }, 1000); + }, + 100, + { trailing: true } + ); refreshOperations(); @@ -82,7 +87,9 @@ const StatsPanel = ({ repoId }: { repoId: string }) => { subscribeToOperations(handler); - return () => {}; // cleanup + return () => { + unsubscribeFromOperations(handler); + }; }, [repoId]); if (operations.length === 0) { @@ -108,9 +115,6 @@ const StatsPanel = ({ repoId }: { repoId: string }) => { }; }); - const minTime = Math.min(...dataset.map((d) => d.time)); - const maxTime = Math.max(...dataset.map((d) => d.time)); - return ( <> diff --git a/webui/src/state/oplog.ts b/webui/src/state/oplog.ts index 96c188e0..c377b1bc 100644 --- a/webui/src/state/oplog.ts +++ b/webui/src/state/oplog.ts @@ -45,6 +45,7 @@ export const subscribeToOperations = ( callback: (event: OperationEvent) => void, ) => { subscribers.push(callback); + console.log("subscribed to operations, subscriber count: ", subscribers.length); }; export const unsubscribeFromOperations = ( @@ -55,6 +56,7 @@ export const unsubscribeFromOperations = ( subscribers[index] = subscribers[subscribers.length - 1]; subscribers.pop(); } + console.log("unsubscribed from operations, subscriber count: ", subscribers.length); }; export const getStatusForSelector = async (sel: OpSelector) => { diff --git a/webui/src/views/GettingStartedGuide.tsx b/webui/src/views/GettingStartedGuide.tsx index 76f1f224..82df007e 100644 --- a/webui/src/views/GettingStartedGuide.tsx +++ b/webui/src/views/GettingStartedGuide.tsx @@ -64,28 +64,30 @@ export const GettingStartedGuide = () => { configured either at the plan or repo level. - Config View {isDevBuild && ( -