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

Get parent of target folder

https://youtrack.weseek.co.jp/issue/GW-7913
- Create method to get all ancestors of target folder
- Add api route to get anestors
- Implement api request in BookmarkFolderItem component
- Get isDroppable by ancestor folder data
Mudana-Grune 3 лет назад
Родитель
Сommit
2f99d14c92

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

@@ -7,7 +7,9 @@ import { useDrag, useDrop } from 'react-dnd';
 import { DropdownToggle } from 'reactstrap';
 
 import { toastError, toastSuccess } from '~/client/util/apiNotification';
-import { apiv3Delete, apiv3Post, apiv3Put } from '~/client/util/apiv3-client';
+import {
+  apiv3Delete, apiv3Get, apiv3Post, apiv3Put,
+} from '~/client/util/apiv3-client';
 import CountBadge from '~/components/Common/CountBadge';
 import FolderIcon from '~/components/Icons/FolderIcon';
 import TriangleIcon from '~/components/Icons/TriangleIcon';
@@ -186,8 +188,23 @@ const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkFolderIt
     // TODO: Implement update parent folder
   };
 
+  const getAllDesc = async(folderId: string) => {
+    try {
+      const res = await apiv3Get(`/bookmark-folder/get-parents/${folderId}`);
+      return res.data;
+    }
+    catch (err) {
+      toastError(err);
+    }
+  };
   const isDropable = (item: BookmarkFolderItems, target: BookmarkFolderItems) => {
     let dropable = false;
+    getAllDesc(bookmarkFolder._id).then((result) => {
+      if (result.ancestors.includes(item._id)) {
+        dropable = false;
+      }
+    });
+
     if (target.parent === item._id || target._id === item._id || target.children?.includes(item)) {
       dropable = false;
     }

+ 15 - 1
packages/app/src/server/models/bookmark-folder.ts

@@ -10,6 +10,7 @@ import { IPageHasId } from '~/interfaces/page';
 import loggerFactory from '../../utils/logger';
 import { getOrCreateModel } from '../util/mongoose-utils';
 
+import bookmark from './bookmark';
 import { InvalidParentBookmarkFolderError } from './errors';
 
 
@@ -32,6 +33,7 @@ export interface BookmarkFolderModel extends Model<BookmarkFolderDocument>{
   deleteFolderAndChildren(bookmarkFolderId: Types.ObjectId | string): Promise<{deletedCount: number}>
   updateBookmarkFolder(bookmarkFolderId: string, name: string, parent: string): Promise<BookmarkFolderDocument>
   insertOrUpdateBookmarkedPage(pageId: IPageHasId, userId: Types.ObjectId | string, folderId: string): Promise<BookmarkFolderDocument>
+  getAllAncestors(folderId: string): Promise<BookmarkFolderItems[]>
 }
 
 const bookmarkFolderSchema = new Schema<BookmarkFolderDocument, BookmarkFolderModel>({
@@ -170,5 +172,17 @@ Promise<BookmarkFolderDocument> {
   return bookmarkFolder;
 };
 
-
+bookmarkFolderSchema.statics.getAllAncestors = async function(folderId: string): Promise<string[]> {
+  const getParent = async(folderId) => {
+    let currentParent : string[] = [];
+    const parentFolder = await this.findById(folderId);
+    if (parentFolder && parentFolder.parent != null) {
+      currentParent.push(parentFolder.id);
+      currentParent = currentParent.concat(await getParent(parentFolder.parent));
+    }
+    return currentParent;
+  };
+  const parents = await getParent(folderId);
+  return parents;
+};
 export default getOrCreateModel<BookmarkFolderDocument, BookmarkFolderModel>('BookmarkFolder', bookmarkFolderSchema);

+ 10 - 0
packages/app/src/server/routes/apiv3/bookmark-folder.ts

@@ -108,6 +108,16 @@ module.exports = (crowi) => {
     }
   });
 
+  router.get('/get-parents/:folderId', accessTokenParser, loginRequiredStrictly, async(req, res) => {
+    const { folderId } = req.params;
 
+    try {
+      const ancestors = await BookmarkFolder.getAllAncestors(folderId);
+      return res.apiv3({ ancestors });
+    }
+    catch (err) {
+      return res.apiv3Err(err, 500);
+    }
+  });
   return router;
 };