mirror of
https://github.com/minio/minio
synced 2024-11-05 17:34:01 +00:00
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
This commit is contained in:
parent
1459c4be1e
commit
cb3818be27
4 changed files with 50 additions and 14 deletions
|
@ -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 (
|
||||
<div className="buckets__list">
|
||||
{visibleBuckets.map(bucket => (
|
||||
<BucketContainer key={bucket} bucket={bucket} />
|
||||
))}
|
||||
<InfiniteScroll
|
||||
pageStart={0}
|
||||
loadMore={this.loadNextPage.bind(this)}
|
||||
hasMore={filteredBuckets.length > visibleBuckets.length}
|
||||
useWindow={false}
|
||||
element="div"
|
||||
initialLoad={false}
|
||||
className="buckets__scroll"
|
||||
>
|
||||
{visibleBuckets.map(bucket => (
|
||||
<BucketContainer key={bucket} bucket={bucket} />
|
||||
))}
|
||||
</InfiniteScroll>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"])
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue