Manual Reference Source

basic/pagination/Pagination.js

  1. /**
  2. * Created by pawelposel on 17/11/2016.
  3. */
  4.  
  5. import PropTypes from 'prop-types';
  6.  
  7. import React, { Component } from 'react';
  8. import { Icon, Message } from 'semantic-ui-react';
  9. import PaginationInfo from './PaginationInfo';
  10. import TotalSizePaginator from './TotalSizePaginator';
  11. import FetchSizePaginator from './FetchSizePaginator';
  12. import Popup from '../Popup';
  13.  
  14. export default class Pagination extends Component {
  15. static PAGE_SIZE_LIST = PaginationInfo.pageSizes;
  16.  
  17. constructor(props, context) {
  18. super(props, context);
  19.  
  20. this.state = {
  21. pageSize: props.pageSize,
  22. currentPage: 1,
  23. showWarningPopup: false
  24. };
  25.  
  26. this.disableStateUpdate = false;
  27. }
  28.  
  29. static propTypes = {
  30. children: PropTypes.any.isRequired,
  31. fetchData: PropTypes.func.isRequired,
  32. pageSize: PropTypes.number.isRequired,
  33. totalSize: PropTypes.number,
  34. fetchSize: PropTypes.number,
  35. sizeMultiplier: PropTypes.number
  36. };
  37.  
  38. static defaultProps = {
  39. totalSize: 0,
  40. fetchSize: 0,
  41. sizeMultiplier: 5,
  42. pageSize: Pagination.PAGE_SIZE_LIST(5)[0]
  43. };
  44.  
  45. _changePageSize(size) {
  46. const minPageSize = 1;
  47. const maxPageSize = 500;
  48. const popupShowTimeout = 3000;
  49. let pageSize = parseInt(size);
  50. let showWarningPopup = false;
  51.  
  52. if (_.isNaN(pageSize) || pageSize < minPageSize || pageSize > maxPageSize) {
  53. pageSize = Pagination.PAGE_SIZE_LIST(this.props.sizeMultiplier)[0];
  54. showWarningPopup = true;
  55. }
  56.  
  57. this.setState({ pageSize, currentPage: 1, showWarningPopup }, () => {
  58. if (showWarningPopup) {
  59. setTimeout(() => this.setState({ showWarningPopup: false }), popupShowTimeout);
  60. }
  61. return this.props.fetchData();
  62. });
  63. }
  64.  
  65. _changePage(page, pageSize) {
  66. this.setState({ currentPage: page, pageSize: pageSize || this.state.pageSize }, () => {
  67. this.props.fetchData();
  68. });
  69. }
  70.  
  71. reset(callback) {
  72. this.setState({ currentPage: 1 }, callback);
  73. }
  74.  
  75. componentDidUpdate(prevProps) {
  76. const changedProps = {};
  77.  
  78. if (prevProps.pageSize !== this.props.pageSize) {
  79. changedProps.pageSize = this.props.pageSize;
  80. }
  81.  
  82. if (this.props.totalSize >= 0 && this.state.currentPage !== 1) {
  83. const pageCount = Math.ceil(this.props.totalSize / this.props.pageSize);
  84. if (this.state.currentPage > pageCount) {
  85. changedProps.currentPage = 1;
  86. }
  87. }
  88.  
  89. if (!_.isEmpty(changedProps)) {
  90. this._changePage(changedProps.currentPage || this.state.currentPage, changedProps.pageSize);
  91. }
  92. }
  93.  
  94. render() {
  95. return (
  96. <div>
  97. {this.props.children}
  98.  
  99. {(this.props.totalSize > Pagination.PAGE_SIZE_LIST(this.props.sizeMultiplier)[0] ||
  100. this.props.fetchSize > 0 ||
  101. this.state.currentPage > 1) && (
  102. <div className="ui two column grid gridPagination">
  103. <div className="column">
  104. <Popup open={this.state.showWarningPopup} wide="very">
  105. <Popup.Trigger>
  106. <PaginationInfo
  107. currentPage={this.state.currentPage}
  108. pageSize={this.state.pageSize}
  109. totalSize={this.props.totalSize}
  110. fetchSize={this.props.fetchSize}
  111. onPageSizeChange={this._changePageSize.bind(this)}
  112. sizeMultiplier={this.props.sizeMultiplier}
  113. />
  114. </Popup.Trigger>
  115. <Popup.Content>
  116. <Message warning>
  117. <Icon name="warning sign" />
  118. Only integer values between 1 and 500 are allowed.
  119. </Message>
  120. </Popup.Content>
  121. </Popup>
  122. </div>
  123. <div className="right aligned column">
  124. {this.props.totalSize > 0 ? (
  125. <TotalSizePaginator
  126. currentPage={this.state.currentPage}
  127. pageSize={this.state.pageSize}
  128. totalSize={this.props.totalSize}
  129. onPageChange={this._changePage.bind(this)}
  130. />
  131. ) : (
  132. <FetchSizePaginator
  133. currentPage={this.state.currentPage}
  134. pageSize={this.state.pageSize}
  135. fetchSize={this.props.fetchSize}
  136. onPageChange={this._changePage.bind(this)}
  137. />
  138. )}
  139. </div>
  140. </div>
  141. )}
  142. </div>
  143. );
  144. }
  145. }