From 161c7706bc15a346aa205b03e6f0cde4ffc47306 Mon Sep 17 00:00:00 2001 From: Marliana Lara Date: Mon, 22 Jul 2019 13:23:31 -0400 Subject: [PATCH] Add InfiniteLoader to fetch rows as needed --- .../src/screens/Job/JobOutput/JobOutput.jsx | 117 +++++++++++------- 1 file changed, 73 insertions(+), 44 deletions(-) diff --git a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx index 551b8343da..29641a51a0 100644 --- a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx +++ b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx @@ -3,6 +3,7 @@ import { AutoSizer, CellMeasurer, CellMeasurerCache, + InfiniteLoader, List, } from 'react-virtualized'; @@ -47,8 +48,10 @@ class JobOutput extends Component { hasContentLoading: true, results: [], scrollToIndex: -1, - startIndex: 0, - stopIndex: 0, + loadedRowCount: 0, + loadedRowsMap: {}, + loadingRowCount: 0, + remoteRowCount: 0, }; this.cache = new CellMeasurerCache({ @@ -57,13 +60,14 @@ class JobOutput extends Component { }); this.loadJobEvents = this.loadJobEvents.bind(this); - this.renderRow = this.renderRow.bind(this); + this.rowRenderer = this.rowRenderer.bind(this); this.handleScrollTop = this.handleScrollTop.bind(this); this.handleScrollBottom = this.handleScrollBottom.bind(this); this.handleScrollNext = this.handleScrollNext.bind(this); this.handleScrollPrevious = this.handleScrollPrevious.bind(this); this.handleResize = this.handleResize.bind(this); - this.onRowsRendered = this.onRowsRendered.bind(this); + this.isRowLoaded = this.isRowLoaded.bind(this); + this.loadMoreRows = this.loadMoreRows.bind(this); } componentDidMount() { @@ -76,12 +80,12 @@ class JobOutput extends Component { this.setState({ hasContentLoading: true }); try { const { - data: { results = [] }, + data: { results = [], count }, } = await JobsAPI.readEvents(job.id, job.type, { - page_size: 200, + page_size: 50, order_by: 'start_line', }); - this.setState({ results }); + this.setState({ results, remoteRowCount: count + 1 }); } catch (err) { this.setState({ contentError: err }); } finally { @@ -89,8 +93,16 @@ class JobOutput extends Component { } } - renderRow({ index, parent, key, style }) { + isRowLoaded({ index }) { const { results } = this.state; + return !!results[index]; + } + + rowRenderer({ index, parent, key, style }) { + const { results } = this.state; + if (!results[index]) { + return; + } const { created, event, stdout, start_line } = results[index]; return ( { + this.setState({ results: [...results, ...response.data.results] }); + }); } handleScrollPrevious() { - const { startIndex, stopIndex } = this.state; - const index = startIndex - (stopIndex - startIndex); - this.setState({ scrollToIndex: Math.max(0, index) }); + const startIndex = this.listRef.Grid._renderedRowStartIndex; + const stopIndex = this.listRef.Grid._renderedRowStopIndex; + const range = stopIndex - startIndex + 1; + this.listRef.scrollToRow(Math.max(0, startIndex - range)); } handleScrollNext() { - const { stopIndex } = this.state; - this.setState({ scrollToIndex: stopIndex + 1 }); + const stopIndex = this.listRef.Grid._renderedRowStopIndex; + this.listRef.scrollToRow(stopIndex - 1); } handleScrollTop() { - this.setState({ scrollToIndex: 0 }); + this.listRef.scrollToRow(0); } handleScrollBottom() { - const { results } = this.state; - this.setState({ scrollToIndex: results.length - 1 }); + const { remoteRowCount } = this.state; + this.listRef.scrollToRow(remoteRowCount - 1); } handleResize({ width }) { if (width !== this._previousWidth) { this.cache.clearAll(); - this.listRef.current.recomputeRowHeights(); + this.listRef.recomputeRowHeights(); } this._previousWidth = width; } @@ -147,12 +171,10 @@ class JobOutput extends Component { render() { const { job } = this.props; const { - results, hasContentLoading, contentError, scrollToIndex, - startIndex, - stopIndex, + remoteRowCount, } = this.state; if (hasContentLoading) { @@ -175,28 +197,35 @@ class JobOutput extends Component { /> - - {({ width, height }) => { - console.log('scroll to index', scrollToIndex); - console.log('start index', startIndex); - console.log('stop index', stopIndex); - return ( - - ); - }} - + + {({ onRowsRendered, registerChild }) => ( + + {({ width, height }) => { + return ( + { + this.listRef = ref; + registerChild(ref); + }} + deferredMeasurementCache={this.cache} + height={height} + onRowsRendered={onRowsRendered} + rowCount={remoteRowCount} + rowHeight={this.cache.rowHeight} + rowRenderer={this.rowRenderer} + scrollToAlignment="start" + scrollToIndex={scrollToIndex} + width={width} + /> + ); + }} + + )} +