mirror of
https://github.com/ansible/awx.git
synced 2026-03-03 09:48:51 -03:30
Add InfiniteLoader to fetch rows as needed
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
|||||||
AutoSizer,
|
AutoSizer,
|
||||||
CellMeasurer,
|
CellMeasurer,
|
||||||
CellMeasurerCache,
|
CellMeasurerCache,
|
||||||
|
InfiniteLoader,
|
||||||
List,
|
List,
|
||||||
} from 'react-virtualized';
|
} from 'react-virtualized';
|
||||||
|
|
||||||
@@ -47,8 +48,10 @@ class JobOutput extends Component {
|
|||||||
hasContentLoading: true,
|
hasContentLoading: true,
|
||||||
results: [],
|
results: [],
|
||||||
scrollToIndex: -1,
|
scrollToIndex: -1,
|
||||||
startIndex: 0,
|
loadedRowCount: 0,
|
||||||
stopIndex: 0,
|
loadedRowsMap: {},
|
||||||
|
loadingRowCount: 0,
|
||||||
|
remoteRowCount: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cache = new CellMeasurerCache({
|
this.cache = new CellMeasurerCache({
|
||||||
@@ -57,13 +60,14 @@ class JobOutput extends Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.loadJobEvents = this.loadJobEvents.bind(this);
|
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.handleScrollTop = this.handleScrollTop.bind(this);
|
||||||
this.handleScrollBottom = this.handleScrollBottom.bind(this);
|
this.handleScrollBottom = this.handleScrollBottom.bind(this);
|
||||||
this.handleScrollNext = this.handleScrollNext.bind(this);
|
this.handleScrollNext = this.handleScrollNext.bind(this);
|
||||||
this.handleScrollPrevious = this.handleScrollPrevious.bind(this);
|
this.handleScrollPrevious = this.handleScrollPrevious.bind(this);
|
||||||
this.handleResize = this.handleResize.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() {
|
componentDidMount() {
|
||||||
@@ -76,12 +80,12 @@ class JobOutput extends Component {
|
|||||||
this.setState({ hasContentLoading: true });
|
this.setState({ hasContentLoading: true });
|
||||||
try {
|
try {
|
||||||
const {
|
const {
|
||||||
data: { results = [] },
|
data: { results = [], count },
|
||||||
} = await JobsAPI.readEvents(job.id, job.type, {
|
} = await JobsAPI.readEvents(job.id, job.type, {
|
||||||
page_size: 200,
|
page_size: 50,
|
||||||
order_by: 'start_line',
|
order_by: 'start_line',
|
||||||
});
|
});
|
||||||
this.setState({ results });
|
this.setState({ results, remoteRowCount: count + 1 });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.setState({ contentError: err });
|
this.setState({ contentError: err });
|
||||||
} finally {
|
} finally {
|
||||||
@@ -89,8 +93,16 @@ class JobOutput extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderRow({ index, parent, key, style }) {
|
isRowLoaded({ index }) {
|
||||||
const { results } = this.state;
|
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];
|
const { created, event, stdout, start_line } = results[index];
|
||||||
return (
|
return (
|
||||||
<CellMeasurer
|
<CellMeasurer
|
||||||
@@ -112,34 +124,46 @@ class JobOutput extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onRowsRendered({ startIndex, stopIndex }) {
|
async loadMoreRows({ startIndex, stopIndex }) {
|
||||||
this.setState({ startIndex, stopIndex });
|
const { job } = this.props;
|
||||||
|
const { results } = this.state;
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
counter__gte: startIndex,
|
||||||
|
counter__lte: stopIndex,
|
||||||
|
order_by: 'start_line',
|
||||||
|
};
|
||||||
|
|
||||||
|
return await JobsAPI.readEvents(job.id, job.type, params).then(response => {
|
||||||
|
this.setState({ results: [...results, ...response.data.results] });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleScrollPrevious() {
|
handleScrollPrevious() {
|
||||||
const { startIndex, stopIndex } = this.state;
|
const startIndex = this.listRef.Grid._renderedRowStartIndex;
|
||||||
const index = startIndex - (stopIndex - startIndex);
|
const stopIndex = this.listRef.Grid._renderedRowStopIndex;
|
||||||
this.setState({ scrollToIndex: Math.max(0, index) });
|
const range = stopIndex - startIndex + 1;
|
||||||
|
this.listRef.scrollToRow(Math.max(0, startIndex - range));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleScrollNext() {
|
handleScrollNext() {
|
||||||
const { stopIndex } = this.state;
|
const stopIndex = this.listRef.Grid._renderedRowStopIndex;
|
||||||
this.setState({ scrollToIndex: stopIndex + 1 });
|
this.listRef.scrollToRow(stopIndex - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleScrollTop() {
|
handleScrollTop() {
|
||||||
this.setState({ scrollToIndex: 0 });
|
this.listRef.scrollToRow(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleScrollBottom() {
|
handleScrollBottom() {
|
||||||
const { results } = this.state;
|
const { remoteRowCount } = this.state;
|
||||||
this.setState({ scrollToIndex: results.length - 1 });
|
this.listRef.scrollToRow(remoteRowCount - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleResize({ width }) {
|
handleResize({ width }) {
|
||||||
if (width !== this._previousWidth) {
|
if (width !== this._previousWidth) {
|
||||||
this.cache.clearAll();
|
this.cache.clearAll();
|
||||||
this.listRef.current.recomputeRowHeights();
|
this.listRef.recomputeRowHeights();
|
||||||
}
|
}
|
||||||
this._previousWidth = width;
|
this._previousWidth = width;
|
||||||
}
|
}
|
||||||
@@ -147,12 +171,10 @@ class JobOutput extends Component {
|
|||||||
render() {
|
render() {
|
||||||
const { job } = this.props;
|
const { job } = this.props;
|
||||||
const {
|
const {
|
||||||
results,
|
|
||||||
hasContentLoading,
|
hasContentLoading,
|
||||||
contentError,
|
contentError,
|
||||||
scrollToIndex,
|
scrollToIndex,
|
||||||
startIndex,
|
remoteRowCount,
|
||||||
stopIndex,
|
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
if (hasContentLoading) {
|
if (hasContentLoading) {
|
||||||
@@ -175,28 +197,35 @@ class JobOutput extends Component {
|
|||||||
/>
|
/>
|
||||||
</OutputToolbar>
|
</OutputToolbar>
|
||||||
<OutputWrapper>
|
<OutputWrapper>
|
||||||
<AutoSizer onResize={this.handleResize}>
|
<InfiniteLoader
|
||||||
{({ width, height }) => {
|
isRowLoaded={this.isRowLoaded}
|
||||||
console.log('scroll to index', scrollToIndex);
|
loadMoreRows={this.loadMoreRows}
|
||||||
console.log('start index', startIndex);
|
rowCount={remoteRowCount}
|
||||||
console.log('stop index', stopIndex);
|
>
|
||||||
return (
|
{({ onRowsRendered, registerChild }) => (
|
||||||
<List
|
<AutoSizer onResize={this.handleResize}>
|
||||||
ref={this.listRef}
|
{({ width, height }) => {
|
||||||
width={width}
|
return (
|
||||||
height={height}
|
<List
|
||||||
deferredMeasurementCache={this.cache}
|
ref={ref => {
|
||||||
rowHeight={this.cache.rowHeight}
|
this.listRef = ref;
|
||||||
rowRenderer={this.renderRow}
|
registerChild(ref);
|
||||||
rowCount={results.length}
|
}}
|
||||||
overscanRowCount={50}
|
deferredMeasurementCache={this.cache}
|
||||||
scrollToIndex={scrollToIndex}
|
height={height}
|
||||||
onRowsRendered={this.onRowsRendered}
|
onRowsRendered={onRowsRendered}
|
||||||
scrollToAlignment="start"
|
rowCount={remoteRowCount}
|
||||||
/>
|
rowHeight={this.cache.rowHeight}
|
||||||
);
|
rowRenderer={this.rowRenderer}
|
||||||
}}
|
scrollToAlignment="start"
|
||||||
</AutoSizer>
|
scrollToIndex={scrollToIndex}
|
||||||
|
width={width}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</AutoSizer>
|
||||||
|
)}
|
||||||
|
</InfiniteLoader>
|
||||||
<OutputFooter />
|
<OutputFooter />
|
||||||
</OutputWrapper>
|
</OutputWrapper>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
|
|||||||
Reference in New Issue
Block a user