Ver código fonte

InfiniteScoll fix

https://youtrack.weseek.co.jp/issue/GW-7756
- Rename swr to swrInfiniteResponse
- Rename type parameter for useIntersection and InfiniteScroll
- Modify null check of useIntersection function
- Added default loading indicator cmponent
- Adjust  InfiniteScroll props in RecentChanges component
- Add condition for paginate function
- Remove unused variable
- Adjust paginate options
I Komang Mudana 4 anos atrás
pai
commit
27dfa99821

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

@@ -4,7 +4,7 @@ import React, {
 import type { SWRInfiniteResponse } from 'swr/infinite';
 
 type Props<T> = {
-  swr: SWRInfiniteResponse<T>
+  swrInifiniteResponse : SWRInfiniteResponse<T>
   children: React.ReactChild | ((item: T) => React.ReactNode),
   loadingIndicator?: React.ReactNode
   endingIndicator?: React.ReactNode
@@ -12,23 +12,33 @@ type Props<T> = {
   offset?: number
 }
 
-const useIntersection = <T extends HTMLElement>(): [boolean, Ref<T>] => {
+const useIntersection = <E extends HTMLElement>(): [boolean, Ref<E>] => {
   const [intersecting, setIntersecting] = useState<boolean>(false);
   const [element, setElement] = useState<HTMLElement>();
   useEffect(() => {
-    if (!element) return;
-    const observer = new IntersectionObserver((entries) => {
-      setIntersecting(entries[0]?.isIntersecting);
-    });
-    observer.observe(element);
-    return () => observer.unobserve(element);
+    if (element != null) {
+      const observer = new IntersectionObserver((entries) => {
+        setIntersecting(entries[0]?.isIntersecting);
+      });
+      observer.observe(element);
+      return () => observer.unobserve(element);
+    }
+    return;
   }, [element]);
   return [intersecting, el => el && setElement(el)];
 };
 
-const InfiniteScroll = <T, >(props: Props<T>): React.ReactElement<Props<T>> => {
+const LoadingIndicator = (): React.ReactElement => {
+  return (
+    <div className="text-muted text-center">
+      <i className="fa fa-2x fa-spinner fa-pulse mr-1"></i>
+    </div>
+  );
+};
+
+const InfiniteScroll = <E, >(props: Props<E>): React.ReactElement<Props<E>> => {
   const {
-    swr: {
+    swrInifiniteResponse: {
       setSize, data, isValidating,
     },
     children,
@@ -51,7 +61,10 @@ const InfiniteScroll = <T, >(props: Props<T>): React.ReactElement<Props<T>> => {
       {typeof children === 'function' ? data?.map(item => children(item)) : children}
       <div style={{ position: 'relative' }}>
         <div ref={ref} style={{ position: 'absolute', top: offset }}></div>
-        {isReachingEnd ? endingIndicator : loadingIndicator}
+        {isReachingEnd
+          ? endingIndicator
+          : loadingIndicator || <LoadingIndicator />
+        }
       </div>
     </>
   );

+ 1 - 10
packages/app/src/components/Sidebar/RecentChanges.tsx

@@ -120,14 +120,6 @@ SmallPageItem.propTypes = {
   page: PropTypes.any,
 };
 
-function LoadingIndicator() {
-  return (
-    <div className="text-muted text-center">
-      <i className="fa fa-2x fa-spinner fa-pulse mr-1"></i>
-    </div>
-  );
-}
-
 const RecentChanges = (): JSX.Element => {
   const PER_PAGE = 20;
   const { t } = useTranslation();
@@ -175,8 +167,7 @@ const RecentChanges = (): JSX.Element => {
       <div className="grw-recent-changes p-3">
         <ul className="list-group list-group-flush">
           <InfiniteScroll
-            swr={swr}
-            loadingIndicator={<LoadingIndicator />}
+            swrInifiniteResponse={swr}
             isReachingEnd={isReachingEnd}
           >
             {pages => pages.map(page => (

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

@@ -497,36 +497,36 @@ export const getPageSchema = (crowi) => {
     // add grant conditions
     await addConditionToFilteringByViewerForList(builder, user, showAnyoneKnowsLink);
 
-    // count
-    // const totalCount = await builder.query.exec('count');
 
-    // find
-    // builder.addConditionToPagenate(opt.offset, opt.limit, sortOpt);
+    builder.populateDataToList(User.USER_FIELDS_EXCEPT_CONFIDENTIAL);
+
+    if (!opt.page) {
+      // count
+      const totalCount = await builder.query.exec('count');
+
+      // find
+      builder.addConditionToPagenate(opt.offset, opt.limit, sortOpt);
+      const pages = await builder.query.lean().clone().exec('find');
+      const result = {
+        pages, totalCount, offset: opt.offset, limit: opt.limit,
+      };
+      return result;
+    }
+
+    // Pagination for infinite scroll
+    // Paginate with mongoose paginate v2 & `page` exists is in options
     const skip = opt.page ? (+opt.page - 1) * opt.limit : opt.offset;
-    const customLabels = {
-      totalDocs: 'totalCount',
-      docs: 'pages',
-      limit: 'limit',
-      page: 'currentPage',
-      nextPage: 'nextPage',
-      prevPage: 'prevPage',
-      totalPages: 'pageCount',
-    };
 
     const paginationOptions = {
       lean: true,
-      ...(opt.limit) && { limit: opt.limit },
-      ...(opt.offset) && { offset: skip },
-      ...(opt.page) && { page: opt.page },
+      limit: opt.limit,
+      offset: skip,
+      page: opt.page,
       sort: sortOpt,
-      customLabels,
     };
-
-    builder.populateDataToList(User.USER_FIELDS_EXCEPT_CONFIDENTIAL);
-
     const paginatedPages = await Page.paginate(builder.query.clone(), paginationOptions);
     const result = {
-      pages: paginatedPages.pages, totalCount: paginatedPages.totalCount, offset: opt.offset, limit: opt.limit,
+      pages: paginatedPages.docs, totalCount: paginatedPages.totalDocs, offset: opt.offset, limit: opt.limit,
     };
 
     return result;