فهرست منبع

Code improvement

https://youtrack.weseek.co.jp/issue/GW-7839
- Use SWR to fetch currentUser bookmark list
- Implement useSWRCurrentUserBookmark to load bookmark and refresh bookmark list
- Add refreshBookmarkList props to BookmarksItem component
Mudana-Grune 3 سال پیش
والد
کامیت
826bbcaa45
2فایلهای تغییر یافته به همراه34 افزوده شده و 36 حذف شده
  1. 17 35
      packages/app/src/components/Sidebar/Bookmarks.tsx
  2. 17 1
      packages/app/src/stores/bookmark.ts

+ 17 - 35
packages/app/src/components/Sidebar/Bookmarks.tsx

@@ -1,36 +1,40 @@
 
 
-import React, { useCallback, useEffect, useState } from 'react';
+import React from 'react';
 
 
 import { DevidedPagePath } from '@growi/core';
 import { DevidedPagePath } from '@growi/core';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 import { UncontrolledTooltip, DropdownToggle } from 'reactstrap';
 import { UncontrolledTooltip, DropdownToggle } from 'reactstrap';
 
 
-import { toastError } from '~/client/util/apiNotification';
-import { apiv3Get } from '~/client/util/apiv3-client';
+import { unbookmark } from '~/client/services/page-operation';
 import { IPageHasId } from '~/interfaces/page';
 import { IPageHasId } from '~/interfaces/page';
+import { useSWRCurrentUserBookmark } from '~/stores/bookmark';
 import { useCurrentUser, useIsGuestUser } from '~/stores/context';
 import { useCurrentUser, useIsGuestUser } from '~/stores/context';
-import loggerFactory from '~/utils/logger';
-
 
 
 import { MenuItemType, PageItemControl } from '../Common/Dropdown/PageItemControl';
 import { MenuItemType, PageItemControl } from '../Common/Dropdown/PageItemControl';
 
 
-const logger = loggerFactory('growi:BookmarkList');
 
 
 // TODO: Remove pagination and apply  scrolling (not infinity)
 // TODO: Remove pagination and apply  scrolling (not infinity)
 const ACTIVE_PAGE = 1;
 const ACTIVE_PAGE = 1;
 
 
 type Props = {
 type Props = {
-  pages: IPageHasId[]
+  pages: IPageHasId[] | undefined,
+  refreshBookmarkList: () => void
 }
 }
 
 
 const BookmarksItem = (props: Props) => {
 const BookmarksItem = (props: Props) => {
-  const { pages } = props;
+  const { pages, refreshBookmarkList } = props;
 
 
-  const generateBookmarkedPageList = pages.map((page) => {
+  const generateBookmarkedPageList = pages?.map((page) => {
     const dPagePath = new DevidedPagePath(page.path, false, true);
     const dPagePath = new DevidedPagePath(page.path, false, true);
     const { latter: pageTitle, former: formerPagePath } = dPagePath;
     const { latter: pageTitle, former: formerPagePath } = dPagePath;
     const bookmarkItemId = `bookmark-item-${page._id}`;
     const bookmarkItemId = `bookmark-item-${page._id}`;
 
 
+    const bookmarkMenuItemClickHandler = (async() => {
+      await unbookmark(page._id);
+      refreshBookmarkList();
+    });
+
+
     return (
     return (
       <div className="d-flex justify-content-between" key={page._id}>
       <div className="d-flex justify-content-between" key={page._id}>
         <li className="list-group-item list-group-item-action border-0 py-0 pr-3 d-flex align-items-center" id={bookmarkItemId}>
         <li className="list-group-item list-group-item-action border-0 py-0 pr-3 d-flex align-items-center" id={bookmarkItemId}>
@@ -41,6 +45,7 @@ const BookmarksItem = (props: Props) => {
             pageId={page._id}
             pageId={page._id}
             isEnableActions
             isEnableActions
             forceHideMenuItems={[MenuItemType.DUPLICATE]}
             forceHideMenuItems={[MenuItemType.DUPLICATE]}
+            onClickBookmarkMenuItem={bookmarkMenuItemClickHandler}
           >
           >
             <DropdownToggle color="transparent" className="border-0 rounded btn-page-item-control p-0 grw-visible-on-hover mr-1">
             <DropdownToggle color="transparent" className="border-0 rounded btn-page-item-control p-0 grw-visible-on-hover mr-1">
               <i className="icon-options fa fa-rotate-90 p-1"></i>
               <i className="icon-options fa fa-rotate-90 p-1"></i>
@@ -76,30 +81,7 @@ const Bookmarks = () : JSX.Element => {
   const { t } = useTranslation();
   const { t } = useTranslation();
   const { data: currentUser } = useCurrentUser();
   const { data: currentUser } = useCurrentUser();
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isGuestUser } = useIsGuestUser();
-  const [pages, setPages] = useState<IPageHasId[]>([]);
-
-  const getMyBookmarkList = useCallback(async() => {
-    // TODO: Remove pagination and apply  scrolling (not infinity)
-    const page = ACTIVE_PAGE;
-
-    try {
-      const res = await apiv3Get(`/bookmarks/${currentUser?._id}`, { page });
-      const { paginationResult } = res.data;
-      setPages(paginationResult.docs.map((page) => {
-        return {
-          ...page.page,
-        };
-      }));
-    }
-    catch (error) {
-      logger.error('failed to fetch data', error);
-      toastError(error, 'Error occurred in bookmark page list');
-    }
-  }, [currentUser]);
-
-  useEffect(() => {
-    getMyBookmarkList();
-  }, [getMyBookmarkList]);
+  const { data: pages, mutate: mutateCurrentUserBookmark } = useSWRCurrentUserBookmark(currentUser?._id, ACTIVE_PAGE);
 
 
   const renderBar = () => {
   const renderBar = () => {
     if (isGuestUser) {
     if (isGuestUser) {
@@ -109,7 +91,7 @@ const Bookmarks = () : JSX.Element => {
         </h3>
         </h3>
       );
       );
     }
     }
-    if (pages.length === 0) {
+    if (pages?.length === 0) {
       return (
       return (
         <h3 className="pl-3">
         <h3 className="pl-3">
           { t('No bookmarks yet') }
           { t('No bookmarks yet') }
@@ -125,7 +107,7 @@ const Bookmarks = () : JSX.Element => {
         <h3 className="mb-0">{t('Bookmarks')}</h3>
         <h3 className="mb-0">{t('Bookmarks')}</h3>
       </div>
       </div>
       { renderBar() }
       { renderBar() }
-      <BookmarksItem pages={pages} />
+      <BookmarksItem pages={pages} refreshBookmarkList={mutateCurrentUserBookmark} />
     </>
     </>
   );
   );
 
 

+ 17 - 1
packages/app/src/stores/bookmark.ts

@@ -1,6 +1,8 @@
-import { SWRResponse } from 'swr';
+import useSWR, { SWRResponse } from 'swr';
 import useSWRImmutable from 'swr/immutable';
 import useSWRImmutable from 'swr/immutable';
 
 
+import { IPageHasId } from '~/interfaces/page';
+
 import { apiv3Get } from '../client/util/apiv3-client';
 import { apiv3Get } from '../client/util/apiv3-client';
 import { IBookmarkInfo } from '../interfaces/bookmark-info';
 import { IBookmarkInfo } from '../interfaces/bookmark-info';
 
 
@@ -17,3 +19,17 @@ export const useSWRBookmarkInfo = (pageId: string | null | undefined): SWRRespon
     }),
     }),
   );
   );
 };
 };
+
+export const useSWRCurrentUserBookmark = (userId: string | null | undefined, page: number | null | undefined): SWRResponse<IPageHasId[], Error> => {
+  return useSWR(
+    userId != null ? `/bookmarks/${userId}` : null,
+    endpoint => apiv3Get(endpoint, { page }).then((response) => {
+      const { paginationResult } = response.data;
+      return paginationResult.docs.map((item) => {
+        return {
+          ...item.page,
+        };
+      });
+    }),
+  );
+};