PaginationWrapper.jsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import React, { useCallback, useMemo } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import { Pagination, PaginationItem, PaginationLink } from 'reactstrap';
  5. function PaginationWrapper(props) {
  6. const paginationNumbers = {};
  7. const {
  8. activePage, changePage, totalItemsCount, limit, align,
  9. } = props;
  10. // super(props);
  11. // this.state = {
  12. // activePage: 1,
  13. // totalItemsCount: 0,
  14. // paginationNumbers: {},
  15. // limit: this.props.pagingLimit || Infinity,
  16. // };
  17. // this.calculatePagination = this.calculatePagination.bind(this);
  18. // }
  19. // componentWillReceiveProps(nextProps) {
  20. // this.setState({
  21. // activePage: nextProps.activePage,
  22. // totalItemsCount: nextProps.totalItemsCount,
  23. // limit: nextProps.pagingLimit,
  24. // }, () => {
  25. // const activePage = this.state.activePage;
  26. // const totalCount = this.state.totalItemsCount;
  27. // const limit = this.state.limit;
  28. // const paginationNumbers = this.calculatePagination(limit, totalCount, activePage);
  29. // this.setState({ paginationNumbers });
  30. // });
  31. // }
  32. // calculatePagination(limit, totalCount, activePage) {
  33. // // calc totalPageNumber
  34. // const totalPage = Math.floor(totalCount / limit) + (totalCount % limit === 0 ? 0 : 1);
  35. // let paginationStart = activePage - 2;
  36. // let maxViewPageNum = activePage + 2;
  37. // // if pagiNation Number area size = 5 , pageNumber is calculated here
  38. // // activePage Position calculate ex. 4 5 [6] 7 8 (Page8 over is Max), 3 4 5 [6] 7 (Page7 is Max)
  39. // if (paginationStart < 1) {
  40. // const diff = 1 - paginationStart;
  41. // paginationStart += diff;
  42. // maxViewPageNum = Math.min(totalPage, maxViewPageNum + diff);
  43. // }
  44. // if (maxViewPageNum > totalPage) {
  45. // const diff = maxViewPageNum - totalPage;
  46. // maxViewPageNum -= diff;
  47. // paginationStart = Math.max(1, paginationStart - diff);
  48. // }
  49. // return {
  50. // totalPage,
  51. // paginationStart,
  52. // maxViewPageNum,
  53. // };
  54. // }
  55. /**
  56. * generate Elements of Pagination First Prev
  57. * ex. << < 1 2 3 > >>
  58. * this function set << & <
  59. */
  60. const generateFirstPrev = useCallback(() => {
  61. if (activePage !== 1) {
  62. return (
  63. <>
  64. <PaginationItem key="painationItemFirst">
  65. <PaginationLink first onClick={() => { return changePage(1) }} />
  66. </PaginationItem>
  67. <PaginationItem key="painationItemPrevious">
  68. <PaginationLink previous onClick={() => { return changePage(activePage - 1) }} />
  69. </PaginationItem>
  70. </>
  71. );
  72. }
  73. return (
  74. <>
  75. <PaginationItem key="painationItemFirst" disabled>
  76. <PaginationLink first />
  77. </PaginationItem>
  78. <PaginationItem key="painationItemPrevious" disabled>
  79. <PaginationLink previous />
  80. </PaginationItem>
  81. </>
  82. );
  83. }, [activePage, changePage]);
  84. /**
  85. * generate Elements of Pagination First Prev
  86. * ex. << < 4 5 6 7 8 > >>, << < 1 2 3 4 > >>
  87. * this function set numbers
  88. */
  89. const generatePaginations = (activePage, paginationStart, maxViewPageNum) => {
  90. const paginationItems = [];
  91. for (let number = paginationStart; number <= maxViewPageNum; number++) {
  92. paginationItems.push(
  93. <PaginationItem key={`paginationItem-${number}`} active={number === activePage}>
  94. <PaginationLink onClick={() => { return props.changePage(number) }}>
  95. {number}
  96. </PaginationLink>
  97. </PaginationItem>,
  98. );
  99. }
  100. return paginationItems;
  101. };
  102. /**
  103. * generate Elements of Pagination First Prev
  104. * ex. << < 1 2 3 > >>
  105. * this function set > & >>
  106. */
  107. const generateNextLast = (activePage, totalPage) => {
  108. const paginationItems = [];
  109. if (totalPage !== activePage) {
  110. paginationItems.push(
  111. <PaginationItem key="painationItemNext">
  112. <PaginationLink next onClick={() => { return props.changePage(activePage + 1) }} />
  113. </PaginationItem>,
  114. <PaginationItem key="painationItemLast">
  115. <PaginationLink last onClick={() => { return props.changePage(totalPage) }} />
  116. </PaginationItem>,
  117. );
  118. }
  119. else {
  120. paginationItems.push(
  121. <PaginationItem key="painationItemNext" disabled>
  122. <PaginationLink next />
  123. </PaginationItem>,
  124. <PaginationItem key="painationItemLast" disabled>
  125. <PaginationLink last />
  126. </PaginationItem>,
  127. );
  128. }
  129. return paginationItems;
  130. };
  131. const getListClassName = useMemo(() => {
  132. const listClassNames = [];
  133. if (align === 'center') {
  134. listClassNames.push('justify-content-center');
  135. }
  136. if (align === 'right') {
  137. listClassNames.push('justify-content-end');
  138. }
  139. return listClassNames.join(' ');
  140. }, [align]);
  141. const paginationItems = [];
  142. const totalPage = paginationNumbers.totalPage;
  143. const paginationStart = paginationNumbers.paginationStart;
  144. const maxViewPageNum = paginationNumbers.maxViewPageNum;
  145. const paginations = generatePaginations(activePage, paginationStart, maxViewPageNum);
  146. paginationItems.push(paginations);
  147. const nextLastItems = generateNextLast(activePage, totalPage);
  148. paginationItems.push(nextLastItems);
  149. return (
  150. <React.Fragment>
  151. <Pagination size={props.size} listClassName={getListClassName}>
  152. {generateFirstPrev()}
  153. {paginationItems}
  154. </Pagination>
  155. </React.Fragment>
  156. );
  157. }
  158. PaginationWrapper.propTypes = {
  159. activePage: PropTypes.number.isRequired,
  160. changePage: PropTypes.func.isRequired,
  161. totalItemsCount: PropTypes.number.isRequired,
  162. pagingLimit: PropTypes.number.isRequired,
  163. align: PropTypes.string,
  164. size: PropTypes.string,
  165. };
  166. PaginationWrapper.defaultProps = {
  167. align: 'left',
  168. size: 'md',
  169. };
  170. export default withTranslation()(PaginationWrapper);