From cb3818be27a68f927bf3e2483a2b983c10ebe95b Mon Sep 17 00:00:00 2001 From: Kanagaraj M Date: Thu, 22 Mar 2018 23:28:48 +0530 Subject: [PATCH] adding local pagination to bucket list (#5684) * adding local pagination to bucket list When there are more than 5000 buckets, browser ui becomes unresponsive since react needs to create 5000 elements which takes browser resources. So we show only 100 buckets for the first time, and load more buckets when the user is scrolling down. * move inline styles to less file --- browser/app/js/buckets/BucketList.js | 45 ++++++++++++++++--- .../js/buckets/__tests__/selectors.test.js | 12 ++--- browser/app/js/buckets/selectors.js | 2 +- browser/app/less/inc/sidebar.less | 5 +++ 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/browser/app/js/buckets/BucketList.js b/browser/app/js/buckets/BucketList.js index beab8478c..67ea13890 100644 --- a/browser/app/js/buckets/BucketList.js +++ b/browser/app/js/buckets/BucketList.js @@ -17,14 +17,28 @@ import React from "react" import { connect } from "react-redux" import { Scrollbars } from "react-custom-scrollbars" +import InfiniteScroll from "react-infinite-scroller" import * as actionsBuckets from "./actions" -import { getVisibleBuckets } from "./selectors" +import { getFilteredBuckets } from "./selectors" import BucketContainer from "./BucketContainer" import web from "../web" import history from "../history" import { pathSlice } from "../utils" export class BucketList extends React.Component { + constructor(props) { + super(props) + this.state = { + page: 1 + } + } + componentWillReceiveProps(nexProps) { + if (this.props.filter != nexProps.filter) { + this.setState({ + page: 1 + }) + } + } componentWillMount() { const { fetchBuckets, setBucketList, selectBucket } = this.props if (web.LoggedIn()) { @@ -39,13 +53,29 @@ export class BucketList extends React.Component { } } } + loadNextPage() { + this.setState({ + page: this.state.page + 1 + }) + } render() { - const { visibleBuckets } = this.props + const { filteredBuckets } = this.props + const visibleBuckets = filteredBuckets.slice(0, this.state.page * 100) return (
- {visibleBuckets.map(bucket => ( - - ))} + visibleBuckets.length} + useWindow={false} + element="div" + initialLoad={false} + className="buckets__scroll" + > + {visibleBuckets.map(bucket => ( + + ))} +
) } @@ -53,7 +83,8 @@ export class BucketList extends React.Component { const mapStateToProps = state => { return { - visibleBuckets: getVisibleBuckets(state), + filteredBuckets: getFilteredBuckets(state), + filter: state.buckets.filter } } @@ -61,7 +92,7 @@ const mapDispatchToProps = dispatch => { return { fetchBuckets: () => dispatch(actionsBuckets.fetchBuckets()), setBucketList: buckets => dispatch(actionsBuckets.setList(buckets)), - selectBucket: bucket => dispatch(actionsBuckets.selectBucket(bucket)), + selectBucket: bucket => dispatch(actionsBuckets.selectBucket(bucket)) } } diff --git a/browser/app/js/buckets/__tests__/selectors.test.js b/browser/app/js/buckets/__tests__/selectors.test.js index 896755952..c5e2172b4 100644 --- a/browser/app/js/buckets/__tests__/selectors.test.js +++ b/browser/app/js/buckets/__tests__/selectors.test.js @@ -14,25 +14,25 @@ * limitations under the License. */ -import { getVisibleBuckets, getCurrentBucket } from "../selectors" +import { getFilteredBuckets, getCurrentBucket } from "../selectors" -describe("getVisibleBuckets", () => { +describe("getFilteredBuckets", () => { let state beforeEach(() => { state = { buckets: { - list: ["test1", "test11", "test2"], - }, + list: ["test1", "test11", "test2"] + } } }) it("should return all buckets if no filter specified", () => { state.buckets.filter = "" - expect(getVisibleBuckets(state)).toEqual(["test1", "test11", "test2"]) + expect(getFilteredBuckets(state)).toEqual(["test1", "test11", "test2"]) }) it("should return all matching buckets if filter is specified", () => { state.buckets.filter = "test1" - expect(getVisibleBuckets(state)).toEqual(["test1", "test11"]) + expect(getFilteredBuckets(state)).toEqual(["test1", "test11"]) }) }) diff --git a/browser/app/js/buckets/selectors.js b/browser/app/js/buckets/selectors.js index 98541754d..c16e89e86 100644 --- a/browser/app/js/buckets/selectors.js +++ b/browser/app/js/buckets/selectors.js @@ -19,7 +19,7 @@ import { createSelector } from "reselect" const bucketsSelector = state => state.buckets.list const bucketsFilterSelector = state => state.buckets.filter -export const getVisibleBuckets = createSelector( +export const getFilteredBuckets = createSelector( bucketsSelector, bucketsFilterSelector, (buckets, filter) => buckets.filter(bucket => bucket.indexOf(filter) > -1), diff --git a/browser/app/less/inc/sidebar.less b/browser/app/less/inc/sidebar.less index 673e30b30..9129bd920 100644 --- a/browser/app/less/inc/sidebar.less +++ b/browser/app/less/inc/sidebar.less @@ -82,6 +82,11 @@ margin-bottom: 1rem; } +.buckets__list { + height: calc(~"100vh - 246px"); + overflow: auto; +} + .buckets__item { padding: 0.8rem @sidebar-padding 0.8rem @sidebar-padding*2.2; background: url(../../img/icons/bucket.svg) no-repeat left 2.2rem center;