Просмотр исходного кода

Implement SWRInfininite to PageHistory

https://youtrack.weseek.co.jp/issue/GW-7908
- Update return type of SWRInfiniteResponse
- Implement useSWRxInfinitePageRevisions to PageHistory
- Adjust setState data with latestRevision
- Remove pagingLimit and revisions props from PageRevisionTable
- Implemet InfiniteScroll component to PageRevisionTable component
- Remove revisionList method
Mudana-Grune 3 лет назад
Родитель
Сommit
b7bbd4167e

+ 10 - 11
packages/app/src/components/PageHistory.tsx

@@ -3,7 +3,7 @@ import React, { useState, useEffect } from 'react';
 import { IRevisionHasPageId } from '@growi/core';
 
 import { useCurrentPageId } from '~/stores/context';
-import { useSWRxPageRevisions, useCurrentPagePath } from '~/stores/page';
+import { useCurrentPagePath, useSWRxInfinitePageRevisions } from '~/stores/page';
 import loggerFactory from '~/utils/logger';
 
 import { PageRevisionTable } from './PageHistory/PageRevisionTable';
@@ -13,28 +13,29 @@ const logger = loggerFactory('growi:PageHistory');
 
 export const PageHistory: React.FC<{ onClose: () => void }> = ({ onClose }) => {
 
-  const [activePage, setActivePage] = useState(1);
-
   const { data: currentPageId } = useCurrentPageId();
   const { data: currentPagePath } = useCurrentPagePath();
 
-  const { data: revisionsData, mutate: mutatePageRevisions } = useSWRxPageRevisions(activePage, 10, currentPageId);
+  const swrInifiniteResponse = useSWRxInfinitePageRevisions(currentPageId);
+  const { data: revisionsData, mutate: mutatePageRevisions } = swrInifiniteResponse;
+
 
   const [sourceRevision, setSourceRevision] = useState<IRevisionHasPageId>();
   const [targetRevision, setTargetRevision] = useState<IRevisionHasPageId>();
 
+  const latestRevision = revisionsData != null ? revisionsData[0][0] : null;
+
   useEffect(() => {
-    if (revisionsData != null) {
-      setSourceRevision(revisionsData.revisions[0]);
-      setTargetRevision(revisionsData.revisions[0]);
+    if (latestRevision != null) {
+      setSourceRevision(latestRevision);
+      setTargetRevision(latestRevision);
     }
-  }, [revisionsData]);
+  }, [latestRevision]);
 
   useEffect(() => {
     mutatePageRevisions();
   });
 
-  const pagingLimit = 10;
 
   if (revisionsData == null || sourceRevision == null || targetRevision == null || currentPageId == null || currentPagePath == null) {
     return (
@@ -47,8 +48,6 @@ export const PageHistory: React.FC<{ onClose: () => void }> = ({ onClose }) => {
   return (
     <div className="revision-history" data-testid="page-history">
       <PageRevisionTable
-        revisions={revisionsData.revisions}
-        pagingLimit={pagingLimit}
         sourceRevision={sourceRevision}
         targetRevision={targetRevision}
         currentPageId={currentPageId}

+ 36 - 24
packages/app/src/components/PageHistory/PageRevisionTable.tsx

@@ -3,13 +3,15 @@ import React from 'react';
 import { IRevisionHasId } from '@growi/core';
 import { useTranslation } from 'next-i18next';
 
+import { useSWRxInfinitePageRevisions } from '~/stores/page';
+
+import InfiniteScroll from '../Sidebar/InfiniteScroll';
+
 import { Revision } from './Revision';
 
 import styles from './PageRevisionTable.module.scss';
 
 type PageRevisionTAble = {
-  revisions: IRevisionHasId[],
-  pagingLimit: number,
   sourceRevision: IRevisionHasId,
   targetRevision: IRevisionHasId,
   currentPageId: string,
@@ -22,14 +24,23 @@ type PageRevisionTAble = {
 export const PageRevisionTable = (props: PageRevisionTAble): JSX.Element => {
   const { t } = useTranslation();
 
+  const REVISIONS_PER_PAGE = 10;
+
   const {
-    revisions, pagingLimit, sourceRevision, targetRevision, currentPageId, currentPagePath,
+    sourceRevision, targetRevision, currentPageId, currentPagePath,
     onChangeSourceInvoked, onChangeTargetInvoked, onClose,
   } = props;
 
-  const revisionCount = revisions.length;
-  const latestRevision = revisions[0];
-  const oldestRevision = revisions[revisions.length - 1];
+  const swrInifiniteResponse = useSWRxInfinitePageRevisions(currentPageId);
+
+  const { data: revisionsData } = swrInifiniteResponse;
+  const revisions = revisionsData && revisionsData[0];
+  const oldestRevision = revisions && revisions[revisions.length - 1];
+
+
+  const isEmpty = revisionsData?.[0].length === 0;
+  const isReachingEnd = isEmpty
+   || (revisionsData && revisionsData[revisionsData.length - 1]?.length < REVISIONS_PER_PAGE);
 
   const renderRow = (revision: IRevisionHasId, previousRevision: IRevisionHasId, latestRevision: IRevisionHasId,
       isOldestRevision: boolean, hasDiff: boolean) => {
@@ -118,23 +129,6 @@ export const PageRevisionTable = (props: PageRevisionTAble): JSX.Element => {
     );
   };
 
-  const revisionList = revisions.map((revision, idx) => {
-    // Returns null because the last revision is for the bottom diff display
-    if (idx === pagingLimit) {
-      return null;
-    }
-
-    // if it is the first revision, show full text as diff text
-    const previousRevision = (idx + 1 < revisionCount) ? revisions[idx + 1] : revision;
-
-    const isOldestRevision = revision === oldestRevision;
-
-    // set 'true' if undefined for backward compatibility
-    const hasDiff = revision.hasDiffToPrev !== false;
-
-    return renderRow(revision, previousRevision, latestRevision, isOldestRevision, hasDiff);
-  });
-
   return (
     <table className={`${styles['revision-history-table']} table revision-history-table`}>
       <thead>
@@ -145,7 +139,25 @@ export const PageRevisionTable = (props: PageRevisionTAble): JSX.Element => {
         </tr>
       </thead>
       <tbody className="overflow-auto d-block">
-        {revisionList}
+        {revisions && (
+          <InfiniteScroll
+            swrInifiniteResponse={swrInifiniteResponse}
+            isReachingEnd= {isReachingEnd}
+          >
+            {pageRevisions => pageRevisions.map((revision, idx) => {
+
+              const previousRevision = (idx + 1 < revisions?.length) ? revisions[idx + 1] : revision;
+
+              const isOldestRevision = revision === oldestRevision;
+              const latestRevision = revisions[0];
+
+              // set 'true' if undefined for backward compatibility
+              const hasDiff = revision.hasDiffToPrev !== false;
+              return renderRow(revision, previousRevision, latestRevision, isOldestRevision, hasDiff);
+
+            })}
+          </InfiniteScroll>
+        )}
       </tbody>
     </table>
   );

+ 5 - 7
packages/app/src/stores/page.tsx

@@ -1,7 +1,7 @@
 import { useEffect } from 'react';
 
 import type {
-  IPageInfoForEntity, IPagePopulatedToShowRevision, Nullable,
+  IPageInfoForEntity, IPagePopulatedToShowRevision, IRevisionHasPageId, Nullable,
 } from '@growi/core';
 import { isClient, pagePathUtils } from '@growi/core';
 import useSWR, { Key, SWRResponse } from 'swr';
@@ -146,7 +146,7 @@ export const useSWRxPageRevisions = (
 
 export const useSWRxInfinitePageRevisions = (
     pageId: string | null | undefined,
-) : SWRInfiniteResponse<(IRevisionsForPagination), Error> => {
+) : SWRInfiniteResponse<IRevisionHasPageId[], Error> => {
   const LIMIT = 10;
   const getKey = (page: number) => {
     return `/revisions/list?pageId=${pageId}&page=${page + 1}&limit=${LIMIT}`;
@@ -154,11 +154,9 @@ export const useSWRxInfinitePageRevisions = (
   return useSWRInfinite(
     getKey,
     (endpoint: string) => apiv3Get(endpoint).then((response) => {
-      const revisions = {
-        revisions: response.data.docs,
-        totalCounts: response.data.totalDocs,
-      };
-      return revisions;
+      return response.data.docs.map((data) => {
+        return data;
+      });
     }),
     {
       revalidateFirstPage: false,