From f73e40e666351a865721ae08ceb91eaa1819d16e Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Thu, 13 Jun 2024 00:26:13 -0700 Subject: [PATCH] fix: viewing backup details in very long tree view --- webui/src/components/OperationTree.tsx | 104 ++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 4 deletions(-) diff --git a/webui/src/components/OperationTree.tsx b/webui/src/components/OperationTree.tsx index 1ac5074c..71c01865 100644 --- a/webui/src/components/OperationTree.tsx +++ b/webui/src/components/OperationTree.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useState } from "react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; import { BackupInfo, BackupInfoCollector, @@ -231,9 +231,13 @@ export const OperationTree = ({ {backupTree} - {selectedBackupId ? ( - b.id === selectedBackupId)} /> - ) : null} + + {selectedBackupId ? ( + b.id === selectedBackupId)} + /> + ) : null} + ); @@ -313,6 +317,98 @@ const sortByKeyReverse = (a: OpTreeNode, b: OpTreeNode) => { return -sortByKey(a, b); }; +const BackupViewContainer = ({ children }: { children: React.ReactNode }) => { + const ref = useRef(null); + const innerRef = useRef(null); + const refresh = useState(0)[1]; + const [offset, setOffset] = useState(0); + + // THE RULES + // the top can not be more than windowHeight - divHeight pixels beyond the top + // the bottom can not poke more than windowHeight - divHeight pixels beyond the bottom + + useEffect(() => { + let offset = 0; + + // handle scroll events to keep the fixed container in view. + const handleScroll = () => { + const rect = ref.current?.getBoundingClientRect(); + const innerRect = innerRef.current?.getBoundingClientRect(); + + if (!rect || !innerRect) { + return; + } + + if (innerRect.height <= window.innerHeight) { + if (rect.top <= 0) { + console.log("top overflow", rect.top, offset); + offset = -rect.top; + setOffset(offset); + return; + } + console.log("just do the default stuff"); + setOffset(0); + refresh(Math.random()); + return; + } + + const maxOverflow = innerRect.height - window.innerHeight; + + if (rect.top + offset < -maxOverflow) { + offset = -maxOverflow - rect.top; + setOffset(offset); + return; + } + + if (rect.top + offset > 0) { + console.log("bottom overflow", rect.top + offset, maxOverflow); + offset = -rect.top; + setOffset(offset); + return; + } + refresh(Math.random()); + }; + window.addEventListener("scroll", handleScroll); + + // attach resize observer to ref to update the width of the fixed container. + const resizeObserver = new ResizeObserver(() => { + refresh(Math.random()); + }); + if (ref.current) { + resizeObserver.observe(ref.current); + resizeObserver.observe(innerRef.current!); + } + return () => { + window.removeEventListener("scroll", handleScroll); + resizeObserver.disconnect(); + }; + }, [ref.current, innerRef.current]); + + const rect = ref.current?.getBoundingClientRect(); + + return ( +
+
+ {children} +
+
+ ); +}; + const BackupView = ({ backup }: { backup?: BackupInfo }) => { const alertApi = useAlertApi(); if (!backup) {