basic/pagination/Pagination.js
/**
* Created by pawelposel on 17/11/2016.
*/
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Icon, Message } from 'semantic-ui-react';
import PaginationInfo from './PaginationInfo';
import TotalSizePaginator from './TotalSizePaginator';
import FetchSizePaginator from './FetchSizePaginator';
import Popup from '../Popup';
export default class Pagination extends Component {
static PAGE_SIZE_LIST = PaginationInfo.pageSizes;
constructor(props, context) {
super(props, context);
this.state = {
pageSize: props.pageSize,
currentPage: 1,
showWarningPopup: false
};
this.disableStateUpdate = false;
}
static propTypes = {
children: PropTypes.any.isRequired,
fetchData: PropTypes.func.isRequired,
pageSize: PropTypes.number.isRequired,
totalSize: PropTypes.number,
fetchSize: PropTypes.number,
sizeMultiplier: PropTypes.number
};
static defaultProps = {
totalSize: 0,
fetchSize: 0,
sizeMultiplier: 5,
pageSize: Pagination.PAGE_SIZE_LIST(5)[0]
};
_changePageSize(size) {
const minPageSize = 1;
const maxPageSize = 500;
const popupShowTimeout = 3000;
let pageSize = parseInt(size);
let showWarningPopup = false;
if (_.isNaN(pageSize) || pageSize < minPageSize || pageSize > maxPageSize) {
pageSize = Pagination.PAGE_SIZE_LIST(this.props.sizeMultiplier)[0];
showWarningPopup = true;
}
this.setState({ pageSize, currentPage: 1, showWarningPopup }, () => {
if (showWarningPopup) {
setTimeout(() => this.setState({ showWarningPopup: false }), popupShowTimeout);
}
return this.props.fetchData();
});
}
_changePage(page, pageSize) {
this.setState({ currentPage: page, pageSize: pageSize || this.state.pageSize }, () => {
this.props.fetchData();
});
}
reset(callback) {
this.setState({ currentPage: 1 }, callback);
}
componentDidUpdate(prevProps) {
const changedProps = {};
if (prevProps.pageSize !== this.props.pageSize) {
changedProps.pageSize = this.props.pageSize;
}
if (this.props.totalSize >= 0 && this.state.currentPage !== 1) {
const pageCount = Math.ceil(this.props.totalSize / this.props.pageSize);
if (this.state.currentPage > pageCount) {
changedProps.currentPage = 1;
}
}
if (!_.isEmpty(changedProps)) {
this._changePage(changedProps.currentPage || this.state.currentPage, changedProps.pageSize);
}
}
render() {
return (
<div>
{this.props.children}
{(this.props.totalSize > Pagination.PAGE_SIZE_LIST(this.props.sizeMultiplier)[0] ||
this.props.fetchSize > 0 ||
this.state.currentPage > 1) && (
<div className="ui two column grid gridPagination">
<div className="column">
<Popup open={this.state.showWarningPopup} wide="very">
<Popup.Trigger>
<PaginationInfo
currentPage={this.state.currentPage}
pageSize={this.state.pageSize}
totalSize={this.props.totalSize}
fetchSize={this.props.fetchSize}
onPageSizeChange={this._changePageSize.bind(this)}
sizeMultiplier={this.props.sizeMultiplier}
/>
</Popup.Trigger>
<Popup.Content>
<Message warning>
<Icon name="warning sign" />
Only integer values between 1 and 500 are allowed.
</Message>
</Popup.Content>
</Popup>
</div>
<div className="right aligned column">
{this.props.totalSize > 0 ? (
<TotalSizePaginator
currentPage={this.state.currentPage}
pageSize={this.state.pageSize}
totalSize={this.props.totalSize}
onPageChange={this._changePage.bind(this)}
/>
) : (
<FetchSizePaginator
currentPage={this.state.currentPage}
pageSize={this.state.pageSize}
fetchSize={this.props.fetchSize}
onPageChange={this._changePage.bind(this)}
/>
)}
</div>
</div>
)}
</div>
);
}
}