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

re implement mongoose-paginate-v2

https://youtrack.weseek.co.jp/issue/GW-7758
- Update load next page in InfiniteScroll component
- Adjust variable name
- Update isReachingEnd function in RecentChanges component
- Remove unused variables in paging result interface
- Add sort in pagination options
- Modify offset value in apiv3 pages
- Change return type in useSWRInifinitexRecentlyUpdated
I Komang Mudana 4 лет назад
Родитель
Сommit
3f9596f95d

+ 12 - 11
packages/app/src/components/Sidebar/InfiniteScroll.tsx

@@ -1,4 +1,6 @@
-import React, { Ref, useEffect, useState } from 'react';
+import React, {
+  Ref, useEffect, useState,
+} from 'react';
 import type { SWRInfiniteResponse } from 'swr/infinite';
 
 type Props<T> = {
@@ -7,8 +9,7 @@ type Props<T> = {
   loadingIndicator?: React.ReactNode
   endingIndicator?: React.ReactNode
   isReachingEnd?: boolean,
-  offset?: number,
-  nextPage: number
+  offset?: number
 }
 
 const useIntersection = <T extends HTMLElement>(): [boolean, Ref<T>] => {
@@ -27,30 +28,30 @@ const useIntersection = <T extends HTMLElement>(): [boolean, Ref<T>] => {
 
 const InfiniteScroll = <T, >(props: Props<T>): React.ReactElement<Props<T>> => {
   const {
-    swr,
-    swr: { setSize, data, isValidating },
+    swr: {
+      setSize, data, isValidating,
+    },
     children,
     loadingIndicator,
     endingIndicator,
     isReachingEnd,
     offset = 0,
-    nextPage,
   } = props;
 
-  const ending = isReachingEnd;
   const [intersecting, ref] = useIntersection<HTMLDivElement>();
+
   useEffect(() => {
-    if (intersecting && !isValidating && !ending) {
-      setSize(nextPage);
+    if (intersecting && !isValidating && !isReachingEnd) {
+      setSize(size => size + 1);
     }
-  }, [intersecting, isValidating, setSize, ending, nextPage]);
+  }, [setSize, intersecting]);
 
   return (
     <>
       {typeof children === 'function' ? data?.map(item => children(item)) : children}
       <div style={{ position: 'relative' }}>
         <div ref={ref} style={{ position: 'absolute', top: offset }}></div>
-        {ending ? endingIndicator : loadingIndicator}
+        {isReachingEnd ? endingIndicator : loadingIndicator}
       </div>
     </>
   );

+ 4 - 8
packages/app/src/components/Sidebar/RecentChanges.tsx

@@ -10,13 +10,12 @@ import { UserPicture, FootstampIcon } from '@growi/ui';
 import { DevidedPagePath } from '@growi/core';
 
 import PagePathHierarchicalLink from '~/components/PagePathHierarchicalLink';
-import { useSWRxRecentlyUpdated, useSWRInifinitexRecentlyUpdated } from '~/stores/page';
+import { useSWRInifinitexRecentlyUpdated } from '~/stores/page';
 import loggerFactory from '~/utils/logger';
 
 import LinkedPagePath from '~/models/linked-page-path';
 import InfiniteScroll from './InfiniteScroll';
 
-
 import FormattedDistanceDate from '../FormattedDistanceDate';
 
 const logger = loggerFactory('growi:History');
@@ -134,9 +133,8 @@ const RecentChanges = (): JSX.Element => {
   const { t } = useTranslation();
   const swr = useSWRInifinitexRecentlyUpdated();
   const [isRecentChangesSidebarSmall, setIsRecentChangesSidebarSmall] = useState(false);
-  const isReachingEnd = !swr.data?.[0].hasNextPage;
-  const nextPage = swr.data?.[0].nextPage ?? 1;
-
+  const isEmpty = swr.data?.[0].length === 0;
+  const isReachingEnd = isEmpty || (swr.data && swr.data[swr.data.length - 1]?.length < PER_PAGE);
   const retrieveSizePreferenceFromLocalStorage = useCallback(() => {
     if (window.localStorage.isRecentChangesSidebarSmall === 'true') {
       setIsRecentChangesSidebarSmall(true);
@@ -180,9 +178,8 @@ const RecentChanges = (): JSX.Element => {
             swr={swr}
             loadingIndicator={<LoadingIndicator />}
             isReachingEnd={isReachingEnd}
-            nextPage={nextPage}
           >
-            {response => response?.items.map(page => (
+            {pages => pages.map(page => (
               isRecentChangesSidebarSmall
                 ? <SmallPageItem key={page._id} page={page} />
                 : <LargePageItem key={page._id} page={page} />
@@ -195,5 +192,4 @@ const RecentChanges = (): JSX.Element => {
   );
 
 };
-
 export default RecentChanges;

+ 0 - 3
packages/app/src/interfaces/paging-result.ts

@@ -2,7 +2,4 @@ export type IPagingResult<T> = {
   items: T[],
   totalCount: number,
   limit: number,
-  nextPage?: number,
-  prevPage?: number,
-  hasNextPage?: boolean
 }

+ 3 - 6
packages/app/src/server/models/obsolete-page.js

@@ -535,15 +535,12 @@ export const getPageSchema = (crowi) => {
       totalPages: 'pageCount',
     };
     const paginationOptions = {
-      lean: true, limit: opt.limit, offset: opt.offset, page: opt.page, customLabels,
+      lean: true, limit: opt.limit, offset: opt.offset, page: opt.page, customLabels, sort: sortOpt,
     };
     builder.populateDataToList(User.USER_FIELDS_EXCEPT_CONFIDENTIAL);
     const pages = await Page.paginate(builder.query, paginationOptions);
-    // const results = {
-    //   pages: pages.docs, totalCount: pages.totalDocs, offset: opt.offset, limit: opt.limit,
-    // };
-    console.log(pages);
-    return pages;
+    const result = { ...pages, offset: opt.offset };
+    return result;
   }
 
   /**

+ 3 - 4
packages/app/src/server/routes/apiv3/pages.js

@@ -365,11 +365,11 @@ module.exports = (crowi) => {
    */
   router.get('/recent', accessTokenParser, loginRequired, async(req, res) => {
     const limit = 20;
-    const offset = parseInt(req.query.offset) || 0;
+    // const offset = parseInt(req.query.offset) || 0;
     const page = parseInt(req.query.page) || 1;
-    const skip = (+page - 1) * limit;
+    const offset = (+page - 1) * limit;
     const queryOptions = {
-      offset: skip,
+      offset,
       limit,
       includeTrashed: false,
       isRegExpEscapedFromPath: true,
@@ -377,7 +377,6 @@ module.exports = (crowi) => {
       desc: -1,
       page,
     };
-
     try {
       const result = await Page.findListWithDescendants('/', req.user, queryOptions);
       if (result.pages.length > limit) {

+ 4 - 14
packages/app/src/stores/page.tsx

@@ -34,26 +34,16 @@ export const useSWRxRecentlyUpdated = (): SWRResponse<(IPageHasId)[], Error> =>
     endpoint => apiv3Get<{ pages:(IPageHasId)[] }>(endpoint).then(response => response.data?.pages),
   );
 };
-export const useSWRInifinitexRecentlyUpdated = () : SWRInfiniteResponse<IPagingResult<IPageHasId>, Error> => {
-  const getKey = (page: number, previousData: any) => {
-    if (previousData && !previousData.length) return null;
+export const useSWRInifinitexRecentlyUpdated = () : SWRInfiniteResponse<(IPageHasId)[], Error> => {
+  const getKey = (page: number) => {
     return `/pages/recent?page=${page + 1}`;
   };
   return useSWRInfinite(
     getKey,
-    (endpoint: string) => apiv3Get<{
-      pages: IPageHasId[], totalCount: number, limit: number, hasNextPage: boolean, nextPage: number}>(endpoint).then((response) => {
-        return {
-          items: response.data.pages,
-          totalCount: response.data.totalCount,
-          limit: response.data.limit,
-          hasNextPage: response.data.hasNextPage,
-          nextPage: response.data.nextPage,
-        };
-      }),
+    (endpoint: string) => apiv3Get<{ pages:(IPageHasId)[] }>(endpoint).then(response => response.data?.pages),
     {
-      initialSize: 1,
       revalidateFirstPage: false,
+      revalidateAll: false,
     },
   );
 };