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

Improve dropdown menu

https://youtrack.weseek.co.jp/issue/GW-7910
- Update render condition of bookmark folder menu item
- Create function to render bookmark folder menu item
- Set direction props up for UncontrolledDropdown
- Show bookmark folder name input for all  folders and sub folders
- Delete Bookmark on delete containing bookmark folder
Mudana-Grune 3 лет назад
Родитель
Сommit
02e6627e42

+ 21 - 25
packages/app/src/components/Bookmarks/BookmarkFolderMenu.tsx

@@ -70,20 +70,15 @@ const BookmarkFolderMenu = (props: Props): JSX.Element => {
       await apiv3Post('/bookmark-folder/add-boookmark-to-folder', { pageId: currentPage?._id, folderId: itemId });
       setSelectedItem(itemId);
       toastSuccess('Bookmark added to bookmark folder successfully');
-
     }
     catch (err) {
       toastError(err);
     }
-  }, [currentPage?._id]);
+  }, [currentPage]);
 
-  return (
-    <UncontrolledDropdown className={`grw-bookmark-folder-dropdown ${styles['grw-bookmark-folder-dropdown']}`}>
-      {children}
-      <DropdownMenu
-        right
-        className='grw-bookmark-folder-menu'
-      >
+  const renderBookmarkMenuItem = useCallback(() => {
+    return (
+      <>
         { isCreateAction ? (
           <div className='mx-2'>
             <BookmarkFolderNameInput
@@ -100,7 +95,7 @@ const BookmarkFolderMenu = (props: Props): JSX.Element => {
         <DropdownItem divider />
         {bookmarkFolders?.map(folder => (
           <div key={folder._id} >
-            { folder.children.length > 0 ? (
+            {
               <div className='dropdown-item grw-bookmark-folder-menu-item' tabIndex={0} role="menuitem" onClick={() => onMenuItemClickHandler(folder._id)}>
                 <BookmarkFolderMenuItem
                   isSelected={selectedItem === folder._id}
@@ -108,23 +103,24 @@ const BookmarkFolderMenu = (props: Props): JSX.Element => {
                   onSelectedChild={() => setSelectedItem(null)}
                 />
               </div>
-            ) : (
-              <div className='dropdown-item grw-bookmark-folder-menu-item' tabIndex={0} role="menuitem" onClick={() => onMenuItemClickHandler(folder._id)}>
-                <input
-                  type="radio"
-                  checked={selectedItem === folder._id}
-                  name="bookmark-folder-menu-item"
-                  id={`bookmark-folder-menu-item-${folder._id}`}
-                  onChange={e => e.stopPropagation()}
-                  onClick={e => e.stopPropagation()}
-                />
-                <label htmlFor={`bookmark-folder-menu-item-${folder._id}`} className='p-2 m-0 grw-bookmark-folder-menu-item-title mr-auto'>
-                  {folder.name}
-                </label>
-              </div>
-            )}
+            }
           </div>
         ))}
+      </>
+    );
+  }, [bookmarkFolders, isCreateAction, onClickNewBookmarkFolder, onMenuItemClickHandler, onPressEnterHandlerForCreate, selectedItem, t]);
+
+  return (
+    <UncontrolledDropdown
+      direction='up'
+      className={`grw-bookmark-folder-dropdown ${styles['grw-bookmark-folder-dropdown']}`}>
+      {children}
+      <DropdownMenu
+        right
+        className='grw-bookmark-folder-menu'
+        positionFixed
+      >
+        { renderBookmarkMenuItem() }
       </DropdownMenu>
     </UncontrolledDropdown>
   );

+ 46 - 50
packages/app/src/components/Bookmarks/BookmarkFolderMenuItem.tsx

@@ -96,8 +96,50 @@ const BookmarkFolderMenuItem = (props: Props):JSX.Element => {
     catch (err) {
       toastError(err);
     }
-    onSelectedChild();
-  }, [currentPage, onSelectedChild]);
+    // onSelectedChild();
+  }, [currentPage]);
+
+  const renderBookmarkSubMenuItem = useCallback(() => {
+    return (
+      <>
+        { childFolders != null && (
+          <DropdownMenu className='m-0'>
+            { isCreateAction ? (
+              <div className='mx-2' onClick={e => e.stopPropagation()}>
+                <BookmarkFolderNameInput
+                  onClickOutside={() => setIsCreateAction(false)}
+                  onPressEnter={onPressEnterHandlerForCreate}
+                />
+              </div>
+            ) : (
+              <DropdownItem toggle={false} onClick={e => onClickNewBookmarkFolder(e) } className='grw-bookmark-folder-menu-item'>
+                <FolderIcon isOpen={false}/>
+                <span className="mx-2 ">{t('bookmark_folder.new_folder')}</span>
+              </DropdownItem>
+            )}
+
+            { childFolders && childFolders?.length > 0 && (<DropdownItem divider />)}
+
+            {childFolders?.map(child => (
+              <div key={child._id} >
+
+                <div
+                  className='dropdown-item grw-bookmark-folder-menu-item'
+                  tabIndex={0} role="menuitem"
+                  onClick={e => onClickChildMenuItemHandler(e, child)}>
+                  <BookmarkFolderMenuItem
+                    onSelectedChild={() => setSelectedItem(null)}
+                    isSelected={selectedItem === child._id}
+                    item={child}
+                  />
+                </div>
+              </div>
+            ))}
+          </DropdownMenu>
+        )}
+      </>
+    );
+  }, [childFolders, isCreateAction, onClickChildMenuItemHandler, onClickNewBookmarkFolder, onPressEnterHandlerForCreate, selectedItem, t]);
 
   return (
     <UncontrolledDropdown
@@ -126,55 +168,9 @@ const BookmarkFolderMenuItem = (props: Props):JSX.Element => {
         onClick={e => e.stopPropagation()}
         onMouseEnter={onMouseEnterHandler}
       >
-        <TriangleIcon/>
+        { childFolders && childFolders?.length > 0 && <TriangleIcon/> }
       </DropdownToggle>
-      { childFolders != null && (
-        <DropdownMenu className='m-0'>
-          { isCreateAction ? (
-            <div className='mx-2' onClick={e => e.stopPropagation()}>
-              <BookmarkFolderNameInput
-                onClickOutside={() => setIsCreateAction(false)}
-                onPressEnter={onPressEnterHandlerForCreate}
-              />
-            </div>
-          ) : (
-            <DropdownItem toggle={false} onClick={e => onClickNewBookmarkFolder(e) } className='grw-bookmark-folder-menu-item'>
-              <FolderIcon isOpen={false}/>
-              <span className="mx-2 ">{t('bookmark_folder.new_folder')}</span>
-            </DropdownItem>
-          )}
-          <DropdownItem divider />
-
-          {childFolders?.map(child => (
-            <div key={child._id} >
-              {child.children.length > 0 ? (
-                <div className='dropdown-item grw-bookmark-folder-menu-item' tabIndex={0} role="menuitem" onClick={e => onClickChildMenuItemHandler(e, child)}>
-                  <BookmarkFolderMenuItem
-                    onSelectedChild={() => setSelectedItem(null)}
-                    isSelected={selectedItem === child._id}
-                    item={child}
-                  />
-                </div>
-              ) : (
-                <div className='dropdown-item grw-bookmark-folder-menu-item' tabIndex={0} role="menuitem" onClick={e => onClickChildMenuItemHandler(e, child)}>
-                  <input
-                    type="radio"
-                    checked={selectedItem === child._id}
-                    name="bookmark-folder-menu-item"
-                    id={`bookmark-folder-menu-item-${child._id}`}
-                    onChange={e => e.stopPropagation()}
-                    onClick={e => e.stopPropagation() }
-                  />
-                  <label htmlFor={`bookmark-folder-menu-item-${child._id}`} className='p-2 m-0 grw-bookmark-folder-menu-item-title mr-auto'>
-                    {child.name}
-                  </label>
-                </div>
-              )}
-            </div>
-          ))}
-        </DropdownMenu>
-      )
-      }
+      { renderBookmarkSubMenuItem() }
     </UncontrolledDropdown >
   );
 };

+ 8 - 2
packages/app/src/server/models/bookmark-folder.ts

@@ -105,11 +105,16 @@ bookmarkFolderSchema.statics.findChildFolderById = async function(parentFolderId
   return childFolders;
 };
 
-bookmarkFolderSchema.statics.deleteFolderAndChildren = async function(boookmarkFolderId: Types.ObjectId | string): Promise<{deletedCount: number}> {
+bookmarkFolderSchema.statics.deleteFolderAndChildren = async function(bookmarkFolderId: Types.ObjectId | string): Promise<{deletedCount: number}> {
+  const bookmarkFolder = await this.findById(bookmarkFolderId);
   // Delete parent and all children folder
-  const bookmarkFolder = await this.findByIdAndDelete(boookmarkFolderId);
   let deletedCount = 0;
   if (bookmarkFolder != null) {
+    // Delete Bookmarks
+    const bookmarks = bookmarkFolder?.bookmarks;
+    if (bookmarks && bookmarks.length > 0) {
+      await Bookmark.deleteMany({ _id: { $in: bookmarks } });
+    }
     // Delete all child recursively and update deleted count
     const childFolders = await this.find({ parent: bookmarkFolder });
     await Promise.all(childFolders.map(async(child) => {
@@ -118,6 +123,7 @@ bookmarkFolderSchema.statics.deleteFolderAndChildren = async function(boookmarkF
     }));
     const deletedChild = await this.deleteMany({ parent: bookmarkFolder });
     deletedCount += deletedChild.deletedCount + 1;
+    bookmarkFolder.delete();
   }
   return { deletedCount };
 };