From d555093325cdd612b7f2e6aeee79e0a216fc07d2 Mon Sep 17 00:00:00 2001 From: Keith Grant Date: Thu, 28 Jul 2022 12:26:25 -0700 Subject: [PATCH] Fix job output follow mode & scrolling (#12555) * reworks/fixes follow mode * reduces batch size for better job output perceived performance * improves job output scroll button behavior --- awx/ui/src/screens/Job/JobOutput/JobOutput.js | 43 +++++++++++++------ .../screens/Job/JobOutput/JobOutputSearch.js | 5 +-- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/awx/ui/src/screens/Job/JobOutput/JobOutput.js b/awx/ui/src/screens/Job/JobOutput/JobOutput.js index 386fb87c56..851df3344f 100644 --- a/awx/ui/src/screens/Job/JobOutput/JobOutput.js +++ b/awx/ui/src/screens/Job/JobOutput/JobOutput.js @@ -163,6 +163,11 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { } addEvents(onReadyEvents); setOnReadyEvents([]); + if (isFollowModeEnabled) { + setTimeout(() => { + scrollToEnd(); + }, 0); + } }, [isTreeReady, onReadyEvents]); // eslint-disable-line react-hooks/exhaustive-deps const totalNonCollapsedRows = Math.max( @@ -188,9 +193,6 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { }, [location.search]); // eslint-disable-line react-hooks/exhaustive-deps useEffect(() => { - if (!isJobRunning(jobStatus)) { - setIsFollowModeEnabled(false); - } rebuildEventsTree(); }, [isFlatMode]); // eslint-disable-line react-hooks/exhaustive-deps @@ -242,7 +244,7 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { if (data.group_name === `${job.type}_events`) { batchedEvents.push(data); clearTimeout(batchTimeout); - if (batchedEvents.length >= 25) { + if (batchedEvents.length >= 10) { addBatchedEvents(); } else { batchTimeout = setTimeout(addBatchedEvents, 500); @@ -268,6 +270,12 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { }; }, [isJobRunning(jobStatus)]); // eslint-disable-line react-hooks/exhaustive-deps + useEffect(() => { + if (isFollowModeEnabled) { + scrollToEnd(); + } + }, [wsEvents.length, isFollowModeEnabled]); // eslint-disable-line react-hooks/exhaustive-deps + useEffect(() => { if (listRef.current?.recomputeRowHeights) { listRef.current.recomputeRowHeights(); @@ -419,9 +427,6 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { }; const rowRenderer = ({ index, parent, key, style }) => { - if (listRef.current && isFollowModeEnabled) { - setTimeout(() => scrollToRow(remoteRowCount - 1), 0); - } let event; let node; try { @@ -568,6 +573,9 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { loadRange.forEach((n) => { cache.clear(n); }); + if (isFollowModeEnabled) { + scrollToEnd(); + } }; const scrollToRow = (rowIndex) => { @@ -580,14 +588,16 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { const handleScrollPrevious = () => { const startIndex = listRef.current.Grid._renderedRowStartIndex; const stopIndex = listRef.current.Grid._renderedRowStopIndex; - const scrollRange = stopIndex - startIndex + 1; + const scrollRange = stopIndex - startIndex; scrollToRow(Math.max(0, startIndex - scrollRange)); setIsFollowModeEnabled(false); }; const handleScrollNext = () => { + const startIndex = listRef.current.Grid._renderedRowStartIndex; const stopIndex = listRef.current.Grid._renderedRowStopIndex; - scrollToRow(stopIndex - 1); + const scrollRange = stopIndex - startIndex; + scrollToRow(stopIndex + scrollRange); }; const handleScrollFirst = () => { @@ -595,8 +605,14 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { setIsFollowModeEnabled(false); }; + const scrollToEnd = () => { + scrollToRow(-1); + setTimeout(() => scrollToRow(-1), 100); + }; + const handleScrollLast = () => { - scrollToRow(totalNonCollapsedRows + wsEvents.length); + scrollToEnd(); + setIsFollowModeEnabled(true); }; const handleResize = ({ width }) => { @@ -619,6 +635,9 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { } scrollTop.current = e.scrollTop; scrollHeight.current = e.scrollHeight; + if (e.scrollTop + e.clientHeight >= e.scrollHeight) { + setIsFollowModeEnabled(true); + } }; const handleExpandCollapseAll = () => { @@ -658,8 +677,7 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { job={job} eventRelatedSearchableKeys={eventRelatedSearchableKeys} eventSearchableKeys={eventSearchableKeys} - remoteRowCount={remoteRowCount} - scrollToRow={scrollToRow} + scrollToEnd={scrollToEnd} isFollowModeEnabled={isFollowModeEnabled} setIsFollowModeEnabled={setIsFollowModeEnabled} /> @@ -718,7 +736,6 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) { rowCount={totalNonCollapsedRows + wsEvents.length} rowHeight={cache.rowHeight} rowRenderer={rowRenderer} - scrollToAlignment="start" width={width || 1} overscanRowCount={20} onScroll={handleScroll} diff --git a/awx/ui/src/screens/Job/JobOutput/JobOutputSearch.js b/awx/ui/src/screens/Job/JobOutput/JobOutputSearch.js index a5c3acc63b..5b72eace02 100644 --- a/awx/ui/src/screens/Job/JobOutput/JobOutputSearch.js +++ b/awx/ui/src/screens/Job/JobOutput/JobOutputSearch.js @@ -30,8 +30,7 @@ function JobOutputSearch({ job, eventRelatedSearchableKeys, eventSearchableKeys, - remoteRowCount, - scrollToRow, + scrollToEnd, isFollowModeEnabled, setIsFollowModeEnabled, }) { @@ -83,7 +82,7 @@ function JobOutputSearch({ setIsFollowModeEnabled(false); } else { setIsFollowModeEnabled(true); - scrollToRow(remoteRowCount - 1); + scrollToEnd(); } };