PageTimeline.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import React, { useCallback, useEffect, useState } from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import Link from 'next/link';
  4. import { apiv3Get } from '~/client/util/apiv3-client';
  5. import { IPageHasId } from '~/interfaces/page';
  6. import { useCurrentPagePath } from '~/stores/page';
  7. import { useTimelineOptions } from '~/stores/renderer';
  8. import { RevisionLoader } from './Page/RevisionLoader';
  9. import PaginationWrapper from './PaginationWrapper';
  10. import styles from './PageTimeline.module.scss';
  11. type TimelineCardProps = {
  12. page: IPageHasId,
  13. }
  14. const TimelineCard = ({ page }: TimelineCardProps): JSX.Element => {
  15. const { data: rendererOptions } = useTimelineOptions(page.path);
  16. return (
  17. <div className={`card card-timeline ${styles['card-timeline']}`}>
  18. <div className="card-header h4 p-3">
  19. <Link href={page.path} prefetch={false}>
  20. <a>{page.path}</a>
  21. </Link>
  22. </div>
  23. <div className="card-body">
  24. { rendererOptions != null && (
  25. <RevisionLoader
  26. lazy
  27. rendererOptions={rendererOptions}
  28. pageId={page._id}
  29. revisionId={page.revision}
  30. />
  31. ) }
  32. </div>
  33. </div>
  34. );
  35. };
  36. export const PageTimeline = (): JSX.Element => {
  37. const [activePage, setActivePage] = useState(1);
  38. const [totalPageItems, setTotalPageItems] = useState(0);
  39. const [limit, setLimit] = useState(10);
  40. const [pages, setPages] = useState<IPageHasId[] | null>(null);
  41. const { data: currentPagePath } = useCurrentPagePath();
  42. const { t } = useTranslation();
  43. const handlePage = useCallback(async(selectedPage: number) => {
  44. if (currentPagePath == null) { return }
  45. const res = await apiv3Get('/pages/list', { path: currentPagePath, selectedPage });
  46. setTotalPageItems(res.data.totalCount);
  47. setPages(res.data.pages);
  48. setLimit(res.data.limit);
  49. setActivePage(selectedPage);
  50. }, [currentPagePath]);
  51. useEffect(() => {
  52. handlePage(1);
  53. }, [handlePage]);
  54. if (pages == null || pages.length === 0) {
  55. return (
  56. <div className="mt-2">
  57. {/* eslint-disable-next-line react/no-danger */}
  58. <p>{t('custom_navigation.no_page_list')}</p>
  59. </div>
  60. );
  61. }
  62. return (
  63. <div>
  64. { pages.map(page => <TimelineCard key={page._id} page={page} />) }
  65. <PaginationWrapper
  66. activePage={activePage}
  67. changePage={handlePage}
  68. totalItemsCount={totalPageItems}
  69. pagingLimit={limit}
  70. align="center"
  71. />
  72. </div>
  73. );
  74. };