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

Update bookmark content after drag and drop

https://youtrack.weseek.co.jp/issue/GW-7913
- Implement mutation to update bookmark folder content after drag and drop success
- Update render condition of bookmark item
- Add new props of parentFolder to BookmarkItem
- Import new toaster module
- Update style for bookmark items
Mudana-Grune 3 лет назад
Родитель
Сommit
e389f9c8e4

+ 2 - 1
packages/app/src/components/Bookmarks/BookmarkFolderItem.tsx

@@ -6,10 +6,10 @@ import { useTranslation } from 'next-i18next';
 import { useDrag, useDrop } from 'react-dnd';
 import { useDrag, useDrop } from 'react-dnd';
 import { DropdownToggle } from 'reactstrap';
 import { DropdownToggle } from 'reactstrap';
 
 
-import { toastError, toastSuccess } from '~/client/util/apiNotification';
 import {
 import {
   apiv3Delete, apiv3Post, apiv3Put,
   apiv3Delete, apiv3Post, apiv3Put,
 } from '~/client/util/apiv3-client';
 } from '~/client/util/apiv3-client';
+import { toastError, toastSuccess } from '~/client/util/toastr';
 import CountBadge from '~/components/Common/CountBadge';
 import CountBadge from '~/components/Common/CountBadge';
 import FolderIcon from '~/components/Icons/FolderIcon';
 import FolderIcon from '~/components/Icons/FolderIcon';
 import TriangleIcon from '~/components/Icons/TriangleIcon';
 import TriangleIcon from '~/components/Icons/TriangleIcon';
@@ -265,6 +265,7 @@ const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkFolderIt
           onUnbookmarked={onUnbookmarkHandler}
           onUnbookmarked={onUnbookmarkHandler}
           onRenamed={mutateParentBookmarkFolder}
           onRenamed={mutateParentBookmarkFolder}
           onClickDeleteMenuItem={onClickDeleteBookmarkHandler}
           onClickDeleteMenuItem={onClickDeleteBookmarkHandler}
+          parentFolder={bookmarkFolder}
         />
         />
       );
       );
     });
     });

+ 65 - 42
packages/app/src/components/Bookmarks/BookmarkItem.tsx

@@ -1,4 +1,4 @@
-import React, { useCallback, useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
 
 
 import nodePath from 'path';
 import nodePath from 'path';
 
 
@@ -10,8 +10,9 @@ import { UncontrolledTooltip, DropdownToggle } from 'reactstrap';
 import { unbookmark } from '~/client/services/page-operation';
 import { unbookmark } from '~/client/services/page-operation';
 import { toastError, toastSuccess } from '~/client/util/apiNotification';
 import { toastError, toastSuccess } from '~/client/util/apiNotification';
 import { apiv3Put } from '~/client/util/apiv3-client';
 import { apiv3Put } from '~/client/util/apiv3-client';
+import { BookmarkFolderItems } from '~/interfaces/bookmark-info';
 import { IPageHasId, IPageInfoAll, IPageToDeleteWithMeta } from '~/interfaces/page';
 import { IPageHasId, IPageInfoAll, IPageToDeleteWithMeta } from '~/interfaces/page';
-
+import { useSWRxBookamrkFolderAndChild } from '~/stores/bookmark-folder';
 
 
 import ClosableTextInput, { AlertInfo, AlertType } from '../Common/ClosableTextInput';
 import ClosableTextInput, { AlertInfo, AlertType } from '../Common/ClosableTextInput';
 import { MenuItemType, PageItemControl } from '../Common/Dropdown/PageItemControl';
 import { MenuItemType, PageItemControl } from '../Common/Dropdown/PageItemControl';
@@ -21,18 +22,29 @@ type Props = {
   bookmarkedPage: IPageHasId,
   bookmarkedPage: IPageHasId,
   onUnbookmarked: () => void,
   onUnbookmarked: () => void,
   onRenamed: () => void,
   onRenamed: () => void,
-  onClickDeleteMenuItem: (pageToDelete: IPageToDeleteWithMeta) => void
+  onClickDeleteMenuItem: (pageToDelete: IPageToDeleteWithMeta) => void,
+  parentFolder: BookmarkFolderItems
 }
 }
 
 
 const BookmarkItem = (props: Props): JSX.Element => {
 const BookmarkItem = (props: Props): JSX.Element => {
   const { t } = useTranslation();
   const { t } = useTranslation();
   const {
   const {
-    bookmarkedPage, onUnbookmarked, onRenamed, onClickDeleteMenuItem,
+    bookmarkedPage, onUnbookmarked, onRenamed, onClickDeleteMenuItem, parentFolder,
   } = props;
   } = props;
   const [isRenameInputShown, setRenameInputShown] = useState(false);
   const [isRenameInputShown, setRenameInputShown] = useState(false);
   const dPagePath = new DevidedPagePath(bookmarkedPage.path, false, true);
   const dPagePath = new DevidedPagePath(bookmarkedPage.path, false, true);
   const { latter: pageTitle, former: formerPagePath } = dPagePath;
   const { latter: pageTitle, former: formerPagePath } = dPagePath;
   const bookmarkItemId = `bookmark-item-${bookmarkedPage._id}`;
   const bookmarkItemId = `bookmark-item-${bookmarkedPage._id}`;
+  const [parentId, setParentId] = useState(parentFolder._id);
+  const { mutate: mutateParentBookmarkData } = useSWRxBookamrkFolderAndChild();
+  const { mutate: mutateChildFolderData } = useSWRxBookamrkFolderAndChild(parentId);
+
+
+  useEffect(() => {
+    if (parentId != null) {
+      mutateChildFolderData();
+    }
+  }, [parentId, mutateChildFolderData]);
 
 
   const bookmarkMenuItemClickHandler = useCallback(async() => {
   const bookmarkMenuItemClickHandler = useCallback(async() => {
     await unbookmark(bookmarkedPage._id);
     await unbookmark(bookmarkedPage._id);
@@ -98,6 +110,15 @@ const BookmarkItem = (props: Props): JSX.Element => {
   const [, bookmarkItemDragRef] = useDrag({
   const [, bookmarkItemDragRef] = useDrag({
     type: 'BOOKMARK',
     type: 'BOOKMARK',
     item:  bookmarkedPage,
     item:  bookmarkedPage,
+    end: (item) => {
+      if (parentFolder.parent == null) {
+        mutateParentBookmarkData();
+      }
+      if (parentId != null) {
+        setParentId(parentFolder.parent);
+        mutateChildFolderData();
+      }
+    },
     collect: monitor => ({
     collect: monitor => ({
       isDragging: monitor.isDragging(),
       isDragging: monitor.isDragging(),
       canDrag: monitor.canDrag(),
       canDrag: monitor.canDrag(),
@@ -106,44 +127,46 @@ const BookmarkItem = (props: Props): JSX.Element => {
 
 
 
 
   return (
   return (
-    <div className="grw-foldertree-item-container" key={bookmarkedPage._id} ref={(c) => { bookmarkItemDragRef(c) }}>
-      <li className="bookmark-item-list list-group-item list-group-item-action border-0 py-0 pl-5 d-flex align-items-center" id={bookmarkItemId}>
-        { isRenameInputShown ? (
-          <ClosableTextInput
-            value={nodePath.basename(bookmarkedPage.path ?? '')}
-            placeholder={t('Input page name')}
-            onClickOutside={() => { setRenameInputShown(false) }}
-            onPressEnter={pressEnterForRenameHandler}
-            inputValidator={inputValidator}
-          />
-        ) : (
-          <a href={`/${bookmarkedPage._id}`} className="grw-foldertree-title-anchor flex-grow-1 pr-3">
-            <p className={`text-truncate m-auto ${bookmarkedPage.isEmpty && 'grw-sidebar-text-muted'}`}>{pageTitle}</p>
-          </a>
-        )}
-        <PageItemControl
-          pageId={bookmarkedPage._id}
-          isEnableActions
-          forceHideMenuItems={[MenuItemType.DUPLICATE]}
-          onClickBookmarkMenuItem={bookmarkMenuItemClickHandler}
-          onClickRenameMenuItem={renameMenuItemClickHandler}
-          onClickDeleteMenuItem={deleteMenuItemClickHandler}
-        >
-          <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>
-          </DropdownToggle>
-        </PageItemControl>
-        <UncontrolledTooltip
-          modifiers={{ preventOverflow: { boundariesElement: 'window' } }}
-          autohide={false}
-          placement="right"
-          target={bookmarkItemId}
-          fade={false}
-        >
-          { formerPagePath !== null ? `${formerPagePath}/` : '/' }
-        </UncontrolledTooltip>
-      </li>
-    </div>
+    <li
+      className="bookmark-item-list list-group-item list-group-item-action border-0 py-0 pr-3 d-flex align-items-center"
+      key={bookmarkedPage._id} ref={(c) => { bookmarkItemDragRef(c) }}
+      id={bookmarkItemId}
+    >
+      { isRenameInputShown ? (
+        <ClosableTextInput
+          value={nodePath.basename(bookmarkedPage.path ?? '')}
+          placeholder={t('Input page name')}
+          onClickOutside={() => { setRenameInputShown(false) }}
+          onPressEnter={pressEnterForRenameHandler}
+          inputValidator={inputValidator}
+        />
+      ) : (
+        <a href={`/${bookmarkedPage._id}`} className="grw-foldertree-title-anchor flex-grow-1 pr-3">
+          <p className={`text-truncate m-auto ${bookmarkedPage.isEmpty && 'grw-sidebar-text-muted'}`}>{pageTitle}</p>
+        </a>
+      )}
+      <PageItemControl
+        pageId={bookmarkedPage._id}
+        isEnableActions
+        forceHideMenuItems={[MenuItemType.DUPLICATE]}
+        onClickBookmarkMenuItem={bookmarkMenuItemClickHandler}
+        onClickRenameMenuItem={renameMenuItemClickHandler}
+        onClickDeleteMenuItem={deleteMenuItemClickHandler}
+      >
+        <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>
+        </DropdownToggle>
+      </PageItemControl>
+      <UncontrolledTooltip
+        modifiers={{ preventOverflow: { boundariesElement: 'window' } }}
+        autohide={false}
+        placement="right"
+        target={bookmarkItemId}
+        fade={false}
+      >
+        { formerPagePath !== null ? `${formerPagePath}/` : '/' }
+      </UncontrolledTooltip>
+    </li>
   );
   );
 };
 };
 
 

+ 34 - 0
packages/app/src/styles/molecules/_bookmark-folder-tree.scss

@@ -1,5 +1,6 @@
 @use '~/styles/variables' as var;
 @use '~/styles/variables' as var;
 $grw-foldertree-item-padding-left: 10px;
 $grw-foldertree-item-padding-left: 10px;
+$grw-bookmark-item-padding-left: 45px;
 
 
 .grw-foldertree {
 .grw-foldertree {
   :global {
   :global {
@@ -67,56 +68,89 @@ $grw-foldertree-item-padding-left: 10px;
       > .list-group-item {
       > .list-group-item {
         padding-left: 0;
         padding-left: 0;
       }
       }
+      > .list-group-item.bookmark-item-list {
+        padding-left: $grw-bookmark-item-padding-left;
+      }
       > .grw-foldertree-item-children {
       > .grw-foldertree-item-children {
         > .grw-foldertree-item-container {
         > .grw-foldertree-item-container {
           > .list-group-item {
           > .list-group-item {
             padding-left: $grw-foldertree-item-padding-left;
             padding-left: $grw-foldertree-item-padding-left;
           }
           }
+          > .list-group-item.bookmark-item-list {
+            padding-left: $grw-foldertree-item-padding-left + $grw-bookmark-item-padding-left;
+          }
           > .grw-foldertree-item-children {
           > .grw-foldertree-item-children {
             > .grw-foldertree-item-container {
             > .grw-foldertree-item-container {
               > .list-group-item {
               > .list-group-item {
                 padding-left: $grw-foldertree-item-padding-left * 2;
                 padding-left: $grw-foldertree-item-padding-left * 2;
               }
               }
+              > .list-group-item.bookmark-item-list {
+                padding-left: ($grw-foldertree-item-padding-left * 2) + $grw-bookmark-item-padding-left;
+              }
               > .grw-foldertree-item-children {
               > .grw-foldertree-item-children {
                 > .grw-foldertree-item-container {
                 > .grw-foldertree-item-container {
                   > .list-group-item {
                   > .list-group-item {
                     padding-left: $grw-foldertree-item-padding-left * 3;
                     padding-left: $grw-foldertree-item-padding-left * 3;
                   }
                   }
+                  > .list-group-item.bookmark-item-list {
+                    padding-left: ($grw-foldertree-item-padding-left * 3) +  $grw-bookmark-item-padding-left;
+                  }
                   > .grw-foldertree-item-children {
                   > .grw-foldertree-item-children {
                     > .grw-foldertree-item-container {
                     > .grw-foldertree-item-container {
                       > .list-group-item {
                       > .list-group-item {
                         padding-left: $grw-foldertree-item-padding-left * 4;
                         padding-left: $grw-foldertree-item-padding-left * 4;
                       }
                       }
+                      > .list-group-item.bookmark-item-list {
+                        padding-left: ($grw-foldertree-item-padding-left * 4) +  $grw-bookmark-item-padding-left;
+                      }
                       > .grw-foldertree-item-children {
                       > .grw-foldertree-item-children {
                         > .grw-foldertree-item-container {
                         > .grw-foldertree-item-container {
                           > .list-group-item {
                           > .list-group-item {
                             padding-left: $grw-foldertree-item-padding-left * 5;
                             padding-left: $grw-foldertree-item-padding-left * 5;
                           }
                           }
+                          > .list-group-item.bookmark-item-list {
+                            padding-left: ($grw-foldertree-item-padding-left * 5) +  $grw-bookmark-item-padding-left;
+                          }
                           > .grw-foldertree-item-children {
                           > .grw-foldertree-item-children {
                             > .grw-foldertree-item-container {
                             > .grw-foldertree-item-container {
                               > .list-group-item {
                               > .list-group-item {
                                 padding-left: $grw-foldertree-item-padding-left * 6;
                                 padding-left: $grw-foldertree-item-padding-left * 6;
                               }
                               }
+                              > .list-group-item.bookmark-item-list {
+                                padding-left:  ($grw-foldertree-item-padding-left * 6) +  $grw-bookmark-item-padding-left;
+                              }
                               > .grw-foldertree-item-children {
                               > .grw-foldertree-item-children {
                                 > .grw-foldertree-item-container {
                                 > .grw-foldertree-item-container {
                                   > .list-group-item {
                                   > .list-group-item {
                                     padding-left: $grw-foldertree-item-padding-left * 7;
                                     padding-left: $grw-foldertree-item-padding-left * 7;
                                   }
                                   }
+                                  > .list-group-item.bookmark-item-list {
+                                    padding-left: ($grw-foldertree-item-padding-left * 7) +  $grw-bookmark-item-padding-left;
+                                  }
                                   > .grw-foldertree-item-children {
                                   > .grw-foldertree-item-children {
                                     > .grw-foldertree-item-container {
                                     > .grw-foldertree-item-container {
                                       > .list-group-item {
                                       > .list-group-item {
                                         padding-left: $grw-foldertree-item-padding-left * 8;
                                         padding-left: $grw-foldertree-item-padding-left * 8;
                                       }
                                       }
+                                      > .list-group-item.bookmark-item-list {
+                                        padding-left: ($grw-foldertree-item-padding-left * 8) +  $grw-bookmark-item-padding-left;
+                                      }
                                       > .grw-foldertree-item-children {
                                       > .grw-foldertree-item-children {
                                         > .grw-foldertree-item-container {
                                         > .grw-foldertree-item-container {
                                           > .list-group-item {
                                           > .list-group-item {
                                             padding-left: $grw-foldertree-item-padding-left * 9;
                                             padding-left: $grw-foldertree-item-padding-left * 9;
                                           }
                                           }
+                                          > .list-group-item.bookmark-item-list {
+                                            padding-left: ($grw-foldertree-item-padding-left * 9) +  $grw-bookmark-item-padding-left;
+                                          }
                                           .grw-foldertree-item-children {
                                           .grw-foldertree-item-children {
                                             > .grw-foldertree-item-container {
                                             > .grw-foldertree-item-container {
                                               > .list-group-item {
                                               > .list-group-item {
                                                 padding-left: $grw-foldertree-item-padding-left * 10;
                                                 padding-left: $grw-foldertree-item-padding-left * 10;
                                               }
                                               }
+                                              > .list-group-item.bookmark-item-list {
+                                                padding-left: ($grw-foldertree-item-padding-left * 10) +  $grw-bookmark-item-padding-left;
+                                              }
                                             }
                                             }
                                           }
                                           }
                                         }
                                         }