PageTimeline.jsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import AppContainer from '../services/AppContainer';
  5. import PageContainer from '../services/PageContainer';
  6. import PaginationWrapper from './PaginationWrapper';
  7. import { withUnstatedContainers } from './UnstatedUtils';
  8. import RevisionLoader from './Page/RevisionLoader';
  9. class PageTimeline extends React.Component {
  10. constructor(props) {
  11. super(props);
  12. this.state = {
  13. activePage: 1,
  14. totalPageItems: 0,
  15. limit: null,
  16. // TODO: remove after when timeline is implemented with React and inject data with props
  17. pages: this.props.pages,
  18. };
  19. this.handlePage = this.handlePage.bind(this);
  20. }
  21. async handlePage(selectedPage) {
  22. const { appContainer, pageContainer } = this.props;
  23. const { path } = pageContainer.state;
  24. const page = selectedPage;
  25. const res = await appContainer.apiv3Get('/pages/list', { path, page });
  26. const totalPageItems = res.data.totalCount;
  27. const pages = res.data.pages;
  28. const pagingLimit = res.data.limit;
  29. this.setState({
  30. activePage: selectedPage,
  31. totalPageItems,
  32. pages,
  33. limit: pagingLimit,
  34. });
  35. }
  36. componentWillMount() {
  37. const { appContainer } = this.props;
  38. // initialize GrowiRenderer
  39. this.growiRenderer = appContainer.getRenderer('timeline');
  40. }
  41. async componentDidMount() {
  42. await this.handlePage(1);
  43. this.setState({
  44. activePage: 1,
  45. });
  46. }
  47. render() {
  48. const { t } = this.props;
  49. const { pages } = this.state;
  50. const { path } = this.props.pageContainer.state;
  51. if (pages == null || pages.length === 0) {
  52. return (
  53. <div className="mt-2">
  54. {/* eslint-disable-next-line react/no-danger */}
  55. <p dangerouslySetInnerHTML={{ __html: t('custom_navigation.no_page_list', { path }) }} />
  56. </div>
  57. );
  58. }
  59. return (
  60. <div>
  61. { pages.map((page) => {
  62. return (
  63. <div className="timeline-body" key={`key-${page.id}`}>
  64. <div className="card card-timeline">
  65. <div className="card-header"><a href={page.path}>{page.path}</a></div>
  66. <div className="card-body">
  67. <RevisionLoader
  68. lazy
  69. growiRenderer={this.growiRenderer}
  70. pageId={page.id}
  71. revisionId={page.revision}
  72. />
  73. </div>
  74. </div>
  75. </div>
  76. );
  77. }) }
  78. <PaginationWrapper
  79. activePage={this.state.activePage}
  80. changePage={this.handlePage}
  81. totalItemsCount={this.state.totalPageItems}
  82. pagingLimit={this.state.limit}
  83. align="center"
  84. />
  85. </div>
  86. );
  87. }
  88. }
  89. /**
  90. * Wrapper component for using unstated
  91. */
  92. const PageTimelineWrapper = withUnstatedContainers(PageTimeline, [AppContainer, PageContainer]);
  93. PageTimeline.propTypes = {
  94. t: PropTypes.func.isRequired, // i18next
  95. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  96. pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  97. pages: PropTypes.arrayOf(PropTypes.object),
  98. };
  99. export default withTranslation()(PageTimelineWrapper);