PageList.jsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import React, { useEffect, useCallback, useState } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import Page from './PageList/Page';
  5. import { withUnstatedContainers } from './UnstatedUtils';
  6. import AppContainer from '~/client/services/AppContainer';
  7. import PageContainer from '~/client/services/PageContainer';
  8. import PaginationWrapper from './PaginationWrapper';
  9. const PageList = (props) => {
  10. const { appContainer, pageContainer, t } = props;
  11. const { path } = pageContainer.state;
  12. const [pages, setPages] = useState(null);
  13. const [isLoading, setIsLoading] = useState(true);
  14. const [activePage, setActivePage] = useState(1);
  15. const [totalPages, setTotalPages] = useState(0);
  16. const [limit, setLimit] = useState(Infinity);
  17. function setPageNumber(selectedPageNumber) {
  18. setActivePage(selectedPageNumber);
  19. }
  20. const updatePageList = useCallback(async() => {
  21. const page = activePage;
  22. const res = await appContainer.apiv3Get('/pages/list', { path, page });
  23. setPages(res.data.pages);
  24. setIsLoading(false);
  25. setTotalPages(res.data.totalCount);
  26. setLimit(res.data.limit);
  27. }, [appContainer, path, activePage]);
  28. useEffect(() => {
  29. updatePageList();
  30. }, [updatePageList]);
  31. if (isLoading) {
  32. return (
  33. <div className="wiki">
  34. <div className="text-muted text-center">
  35. <i className="fa fa-2x fa-spinner fa-pulse mr-1"></i>
  36. </div>
  37. </div>
  38. );
  39. }
  40. const liClasses = props.liClasses.join(' ');
  41. const pageList = pages.map(page => (
  42. <li key={page._id} className={liClasses}>
  43. <Page page={page} />
  44. </li>
  45. ));
  46. if (pageList.length === 0) {
  47. return (
  48. <div className="mt-2">
  49. {/* eslint-disable-next-line react/no-danger */}
  50. <p>{t('custom_navigation.no_page_list')}</p>
  51. </div>
  52. );
  53. }
  54. if (appContainer.config.disableLinkSharing) {
  55. return (
  56. <div className="mt-2">
  57. {/* eslint-disable-next-line react/no-danger */}
  58. <p>{t('custom_navigation.link_sharing_is_disabled')}</p>
  59. </div>
  60. );
  61. }
  62. return (
  63. <div className="page-list">
  64. <ul className="page-list-ul page-list-ul-flat">
  65. {pageList}
  66. </ul>
  67. <PaginationWrapper
  68. activePage={activePage}
  69. changePage={setPageNumber}
  70. totalItemsCount={totalPages}
  71. pagingLimit={limit}
  72. align="center"
  73. />
  74. </div>
  75. );
  76. };
  77. const PageListWrapper = withUnstatedContainers(PageList, [AppContainer, PageContainer]);
  78. const PageListTranslation = withTranslation()(PageListWrapper);
  79. PageList.propTypes = {
  80. t: PropTypes.func.isRequired, // i18next
  81. appContainer: PropTypes.instanceOf(AppContainer),
  82. pageContainer: PropTypes.instanceOf(PageContainer),
  83. liClasses: PropTypes.arrayOf(PropTypes.string),
  84. };
  85. PageList.defaultProps = {
  86. liClasses: ['mb-3'],
  87. };
  88. export default PageListTranslation;