2
0

PageTimeline.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import React from 'react';
  2. import type { IPageHasId } from '@growi/core';
  3. import { useTranslation } from 'next-i18next';
  4. import Link from 'next/link';
  5. import { useCurrentPagePath } from '~/stores/page';
  6. import { useSWRINFxPageTimeline } from '~/stores/page-timeline';
  7. import { useTimelineOptions } from '~/stores/renderer';
  8. import InfiniteScroll from './InfiniteScroll';
  9. import { RevisionLoader } from './Page/RevisionLoader';
  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. {page.path}
  21. </Link>
  22. </div>
  23. <div className="card-body">
  24. { rendererOptions != null && page.revision != null && (
  25. <RevisionLoader
  26. rendererOptions={rendererOptions}
  27. pageId={page._id}
  28. revisionId={page.revision}
  29. />
  30. ) }
  31. </div>
  32. </div>
  33. );
  34. };
  35. export const PageTimeline = (): JSX.Element => {
  36. const PER_PAGE = 3;
  37. const { t } = useTranslation();
  38. const { data: currentPagePath } = useCurrentPagePath();
  39. const swrInfinitexPageTimeline = useSWRINFxPageTimeline(currentPagePath, PER_PAGE);
  40. const { data } = swrInfinitexPageTimeline;
  41. const isEmpty = data?.[0]?.pages.length === 0;
  42. const isReachingEnd = isEmpty || (data != null && data[data.length - 1]?.pages.length < PER_PAGE);
  43. if (data == null || isEmpty) {
  44. return (
  45. <div className="mt-2">
  46. <p>{t('custom_navigation.no_pages_under_this_page')}</p>
  47. </div>
  48. );
  49. }
  50. return (
  51. <div>
  52. <InfiniteScroll
  53. swrInifiniteResponse={swrInfinitexPageTimeline}
  54. isReachingEnd={isReachingEnd}
  55. >
  56. { data != null && data.flatMap(apiResult => apiResult.pages)
  57. .map(page => (
  58. <TimelineCard key={page._id} page={page} />
  59. ))
  60. }
  61. </InfiniteScroll>
  62. </div>
  63. );
  64. };