|
@@ -1,15 +1,21 @@
|
|
|
import type { FC } from 'react';
|
|
import type { FC } from 'react';
|
|
|
import { useCallback, useState } from 'react';
|
|
import { useCallback, useState } from 'react';
|
|
|
-
|
|
|
|
|
import type { IPageToDeleteWithMeta } from '@growi/core';
|
|
import type { IPageToDeleteWithMeta } from '@growi/core';
|
|
|
import { DropdownToggle } from 'reactstrap';
|
|
import { DropdownToggle } from 'reactstrap';
|
|
|
|
|
|
|
|
import { FolderIcon } from '~/client/components/Icons/FolderIcon';
|
|
import { FolderIcon } from '~/client/components/Icons/FolderIcon';
|
|
|
import {
|
|
import {
|
|
|
- addBookmarkToFolder, addNewFolder, hasChildren, updateBookmarkFolder,
|
|
|
|
|
|
|
+ addBookmarkToFolder,
|
|
|
|
|
+ addNewFolder,
|
|
|
|
|
+ hasChildren,
|
|
|
|
|
+ updateBookmarkFolder,
|
|
|
} from '~/client/util/bookmark-utils';
|
|
} from '~/client/util/bookmark-utils';
|
|
|
import { toastError } from '~/client/util/toastr';
|
|
import { toastError } from '~/client/util/toastr';
|
|
|
-import type { BookmarkFolderItems, DragItemDataType, DragItemType } from '~/interfaces/bookmark-info';
|
|
|
|
|
|
|
+import type {
|
|
|
|
|
+ BookmarkFolderItems,
|
|
|
|
|
+ DragItemDataType,
|
|
|
|
|
+ DragItemType,
|
|
|
|
|
+} from '~/interfaces/bookmark-info';
|
|
|
import { DRAG_ITEM_TYPE } from '~/interfaces/bookmark-info';
|
|
import { DRAG_ITEM_TYPE } from '~/interfaces/bookmark-info';
|
|
|
import type { onDeletedBookmarkFolderFunction } from '~/interfaces/ui';
|
|
import type { onDeletedBookmarkFolderFunction } from '~/interfaces/ui';
|
|
|
import { useDeleteBookmarkFolderModalActions } from '~/states/ui/modal/delete-bookmark-folder';
|
|
import { useDeleteBookmarkFolderModalActions } from '~/states/ui/modal/delete-bookmark-folder';
|
|
@@ -20,28 +26,43 @@ import { BookmarkItem } from './BookmarkItem';
|
|
|
import { DragAndDropWrapper } from './DragAndDropWrapper';
|
|
import { DragAndDropWrapper } from './DragAndDropWrapper';
|
|
|
|
|
|
|
|
type BookmarkFolderItemProps = {
|
|
type BookmarkFolderItemProps = {
|
|
|
- isReadOnlyUser: boolean
|
|
|
|
|
- bookmarkFolder: BookmarkFolderItems
|
|
|
|
|
- isOpen?: boolean
|
|
|
|
|
- isOperable: boolean,
|
|
|
|
|
- level: number
|
|
|
|
|
- root: string
|
|
|
|
|
- isUserHomepage?: boolean
|
|
|
|
|
- onClickDeleteMenuItemHandler: (pageToDelete: IPageToDeleteWithMeta) => void
|
|
|
|
|
- bookmarkFolderTreeMutation: () => void
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkFolderItemProps) => {
|
|
|
|
|
|
|
+ isReadOnlyUser: boolean;
|
|
|
|
|
+ bookmarkFolder: BookmarkFolderItems;
|
|
|
|
|
+ isOpen?: boolean;
|
|
|
|
|
+ isOperable: boolean;
|
|
|
|
|
+ level: number;
|
|
|
|
|
+ root: string;
|
|
|
|
|
+ isUserHomepage?: boolean;
|
|
|
|
|
+ onClickDeleteMenuItemHandler: (pageToDelete: IPageToDeleteWithMeta) => void;
|
|
|
|
|
+ bookmarkFolderTreeMutation: () => void;
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
|
|
+export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (
|
|
|
|
|
+ props: BookmarkFolderItemProps,
|
|
|
|
|
+) => {
|
|
|
const BASE_FOLDER_PADDING = 15;
|
|
const BASE_FOLDER_PADDING = 15;
|
|
|
- const acceptedTypes: DragItemType[] = [DRAG_ITEM_TYPE.FOLDER, DRAG_ITEM_TYPE.BOOKMARK];
|
|
|
|
|
|
|
+ const acceptedTypes: DragItemType[] = [
|
|
|
|
|
+ DRAG_ITEM_TYPE.FOLDER,
|
|
|
|
|
+ DRAG_ITEM_TYPE.BOOKMARK,
|
|
|
|
|
+ ];
|
|
|
const {
|
|
const {
|
|
|
- isReadOnlyUser, bookmarkFolder, isOpen: _isOpen = false, isOperable, level, root, isUserHomepage,
|
|
|
|
|
- onClickDeleteMenuItemHandler, bookmarkFolderTreeMutation,
|
|
|
|
|
|
|
+ isReadOnlyUser,
|
|
|
|
|
+ bookmarkFolder,
|
|
|
|
|
+ isOpen: _isOpen = false,
|
|
|
|
|
+ isOperable,
|
|
|
|
|
+ level,
|
|
|
|
|
+ root,
|
|
|
|
|
+ isUserHomepage,
|
|
|
|
|
+ onClickDeleteMenuItemHandler,
|
|
|
|
|
+ bookmarkFolderTreeMutation,
|
|
|
} = props;
|
|
} = props;
|
|
|
|
|
|
|
|
const {
|
|
const {
|
|
|
- name, _id: folderId, childFolder, parent, bookmarks,
|
|
|
|
|
|
|
+ name,
|
|
|
|
|
+ _id: folderId,
|
|
|
|
|
+ childFolder,
|
|
|
|
|
+ parent,
|
|
|
|
|
+ bookmarks,
|
|
|
} = bookmarkFolder;
|
|
} = bookmarkFolder;
|
|
|
|
|
|
|
|
const [targetFolder, setTargetFolder] = useState<string | null>(folderId);
|
|
const [targetFolder, setTargetFolder] = useState<string | null>(folderId);
|
|
@@ -49,13 +70,14 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
|
|
|
const [isRenameAction, setIsRenameAction] = useState<boolean>(false);
|
|
const [isRenameAction, setIsRenameAction] = useState<boolean>(false);
|
|
|
const [isCreateAction, setIsCreateAction] = useState<boolean>(false);
|
|
const [isCreateAction, setIsCreateAction] = useState<boolean>(false);
|
|
|
|
|
|
|
|
- const { open: openDeleteBookmarkFolderModal } = useDeleteBookmarkFolderModalActions();
|
|
|
|
|
|
|
+ const { open: openDeleteBookmarkFolderModal } =
|
|
|
|
|
+ useDeleteBookmarkFolderModalActions();
|
|
|
|
|
|
|
|
const childrenExists = hasChildren({ childFolder, bookmarks });
|
|
const childrenExists = hasChildren({ childFolder, bookmarks });
|
|
|
|
|
|
|
|
const paddingLeft = BASE_FOLDER_PADDING * level;
|
|
const paddingLeft = BASE_FOLDER_PADDING * level;
|
|
|
|
|
|
|
|
- const loadChildFolder = useCallback(async() => {
|
|
|
|
|
|
|
+ const loadChildFolder = useCallback(async () => {
|
|
|
setIsOpen(!isOpen);
|
|
setIsOpen(!isOpen);
|
|
|
setTargetFolder(folderId);
|
|
setTargetFolder(folderId);
|
|
|
}, [folderId, isOpen]);
|
|
}, [folderId, isOpen]);
|
|
@@ -66,95 +88,127 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
|
|
|
}, []);
|
|
}, []);
|
|
|
|
|
|
|
|
// Rename for bookmark folder handler
|
|
// Rename for bookmark folder handler
|
|
|
- const rename = useCallback(async(folderName: string) => {
|
|
|
|
|
- if (folderName.trim() === '') {
|
|
|
|
|
- return cancel();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const rename = useCallback(
|
|
|
|
|
+ async (folderName: string) => {
|
|
|
|
|
+ if (folderName.trim() === '') {
|
|
|
|
|
+ return cancel();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- // TODO: do not use any type
|
|
|
|
|
- await updateBookmarkFolder(folderId, folderName.trim(), parent as any, childFolder);
|
|
|
|
|
- bookmarkFolderTreeMutation();
|
|
|
|
|
- setIsRenameAction(false);
|
|
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
- toastError(err);
|
|
|
|
|
- }
|
|
|
|
|
- }, [bookmarkFolderTreeMutation, cancel, childFolder, folderId, parent]);
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ // TODO: do not use any type
|
|
|
|
|
+ await updateBookmarkFolder(
|
|
|
|
|
+ folderId,
|
|
|
|
|
+ folderName.trim(),
|
|
|
|
|
+ parent as any,
|
|
|
|
|
+ childFolder,
|
|
|
|
|
+ );
|
|
|
|
|
+ bookmarkFolderTreeMutation();
|
|
|
|
|
+ setIsRenameAction(false);
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ toastError(err);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ [bookmarkFolderTreeMutation, cancel, childFolder, folderId, parent],
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
// Create new folder / subfolder handler
|
|
// Create new folder / subfolder handler
|
|
|
- const create = useCallback(async(folderName: string) => {
|
|
|
|
|
- if (folderName.trim() === '') {
|
|
|
|
|
- return cancel();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const create = useCallback(
|
|
|
|
|
+ async (folderName: string) => {
|
|
|
|
|
+ if (folderName.trim() === '') {
|
|
|
|
|
+ return cancel();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- await addNewFolder(folderName.trim(), targetFolder);
|
|
|
|
|
- setIsOpen(true);
|
|
|
|
|
- setIsCreateAction(false);
|
|
|
|
|
- bookmarkFolderTreeMutation();
|
|
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
- toastError(err);
|
|
|
|
|
- }
|
|
|
|
|
- }, [bookmarkFolderTreeMutation, cancel, targetFolder]);
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ await addNewFolder(folderName.trim(), targetFolder);
|
|
|
|
|
+ setIsOpen(true);
|
|
|
|
|
+ setIsCreateAction(false);
|
|
|
|
|
+ bookmarkFolderTreeMutation();
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ toastError(err);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ [bookmarkFolderTreeMutation, cancel, targetFolder],
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
- const onClickPlusButton = useCallback(async(e) => {
|
|
|
|
|
- e.stopPropagation();
|
|
|
|
|
- if (!isOpen && childrenExists) {
|
|
|
|
|
- setIsOpen(true);
|
|
|
|
|
- }
|
|
|
|
|
- setIsCreateAction(true);
|
|
|
|
|
- }, [childrenExists, isOpen]);
|
|
|
|
|
|
|
+ const onClickPlusButton = useCallback(
|
|
|
|
|
+ async (e) => {
|
|
|
|
|
+ e.stopPropagation();
|
|
|
|
|
+ if (!isOpen && childrenExists) {
|
|
|
|
|
+ setIsOpen(true);
|
|
|
|
|
+ }
|
|
|
|
|
+ setIsCreateAction(true);
|
|
|
|
|
+ },
|
|
|
|
|
+ [childrenExists, isOpen],
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
- const itemDropHandler = async(item: DragItemDataType, dragItemType: string | symbol | null) => {
|
|
|
|
|
|
|
+ const itemDropHandler = async (
|
|
|
|
|
+ item: DragItemDataType,
|
|
|
|
|
+ dragItemType: string | symbol | null,
|
|
|
|
|
+ ) => {
|
|
|
if (dragItemType === DRAG_ITEM_TYPE.FOLDER) {
|
|
if (dragItemType === DRAG_ITEM_TYPE.FOLDER) {
|
|
|
try {
|
|
try {
|
|
|
if (item.bookmarkFolder != null) {
|
|
if (item.bookmarkFolder != null) {
|
|
|
- await updateBookmarkFolder(item.bookmarkFolder._id, item.bookmarkFolder.name, bookmarkFolder._id, item.bookmarkFolder.childFolder);
|
|
|
|
|
|
|
+ await updateBookmarkFolder(
|
|
|
|
|
+ item.bookmarkFolder._id,
|
|
|
|
|
+ item.bookmarkFolder.name,
|
|
|
|
|
+ bookmarkFolder._id,
|
|
|
|
|
+ item.bookmarkFolder.childFolder,
|
|
|
|
|
+ );
|
|
|
bookmarkFolderTreeMutation();
|
|
bookmarkFolderTreeMutation();
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
|
|
+ } catch (err) {
|
|
|
toastError(err);
|
|
toastError(err);
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
|
|
+ } else {
|
|
|
try {
|
|
try {
|
|
|
if (item != null) {
|
|
if (item != null) {
|
|
|
await addBookmarkToFolder(item._id, bookmarkFolder._id);
|
|
await addBookmarkToFolder(item._id, bookmarkFolder._id);
|
|
|
bookmarkFolderTreeMutation();
|
|
bookmarkFolderTreeMutation();
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
|
|
+ } catch (err) {
|
|
|
toastError(err);
|
|
toastError(err);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const isDropable = (item: DragItemDataType, type: string | null | symbol): boolean => {
|
|
|
|
|
|
|
+ const isDropable = (
|
|
|
|
|
+ item: DragItemDataType,
|
|
|
|
|
+ type: string | null | symbol,
|
|
|
|
|
+ ): boolean => {
|
|
|
if (type === DRAG_ITEM_TYPE.FOLDER) {
|
|
if (type === DRAG_ITEM_TYPE.FOLDER) {
|
|
|
- if (item.bookmarkFolder.parent === bookmarkFolder._id || item.bookmarkFolder._id === bookmarkFolder._id) {
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ item.bookmarkFolder.parent === bookmarkFolder._id ||
|
|
|
|
|
+ item.bookmarkFolder._id === bookmarkFolder._id
|
|
|
|
|
+ ) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Maximum folder hierarchy of 2 levels
|
|
// Maximum folder hierarchy of 2 levels
|
|
|
// If the drop source folder has child folders, the drop source folder cannot be moved because the drop source folder hierarchy is already 2.
|
|
// If the drop source folder has child folders, the drop source folder cannot be moved because the drop source folder hierarchy is already 2.
|
|
|
// If the destination folder has a parent, the source folder cannot be moved because the destination folder hierarchy is already 2.
|
|
// If the destination folder has a parent, the source folder cannot be moved because the destination folder hierarchy is already 2.
|
|
|
- if (item.bookmarkFolder.childFolder.length !== 0 || bookmarkFolder.parent != null) {
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ item.bookmarkFolder.childFolder.length !== 0 ||
|
|
|
|
|
+ bookmarkFolder.parent != null
|
|
|
|
|
+ ) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return item.root !== root || item.level >= level;
|
|
return item.root !== root || item.level >= level;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (item.parentFolder != null && item.parentFolder._id === bookmarkFolder._id) {
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ item.parentFolder != null &&
|
|
|
|
|
+ item.parentFolder._id === bookmarkFolder._id
|
|
|
|
|
+ ) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
return true;
|
|
return true;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const triangleBtnClassName = (isOpen: boolean, childrenExists: boolean): string => {
|
|
|
|
|
|
|
+ const triangleBtnClassName = (
|
|
|
|
|
+ isOpen: boolean,
|
|
|
|
|
+ childrenExists: boolean,
|
|
|
|
|
+ ): string => {
|
|
|
if (!childrenExists) {
|
|
if (!childrenExists) {
|
|
|
return 'grw-foldertree-triangle-btn btn px-0 opacity-25';
|
|
return 'grw-foldertree-triangle-btn btn px-0 opacity-25';
|
|
|
}
|
|
}
|
|
@@ -162,41 +216,47 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const renderChildFolder = () => {
|
|
const renderChildFolder = () => {
|
|
|
- return isOpen && childFolder?.map((childFolder) => {
|
|
|
|
|
- return (
|
|
|
|
|
- <div key={childFolder._id} className="grw-foldertree-item-children">
|
|
|
|
|
- <BookmarkFolderItem
|
|
|
|
|
- key={childFolder._id}
|
|
|
|
|
|
|
+ return (
|
|
|
|
|
+ isOpen &&
|
|
|
|
|
+ childFolder?.map((childFolder) => {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div key={childFolder._id} className="grw-foldertree-item-children">
|
|
|
|
|
+ <BookmarkFolderItem
|
|
|
|
|
+ key={childFolder._id}
|
|
|
|
|
+ isReadOnlyUser={isReadOnlyUser}
|
|
|
|
|
+ isOperable={props.isOperable}
|
|
|
|
|
+ bookmarkFolder={childFolder}
|
|
|
|
|
+ level={level + 1}
|
|
|
|
|
+ root={root}
|
|
|
|
|
+ isUserHomepage={isUserHomepage}
|
|
|
|
|
+ onClickDeleteMenuItemHandler={onClickDeleteMenuItemHandler}
|
|
|
|
|
+ bookmarkFolderTreeMutation={bookmarkFolderTreeMutation}
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ );
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const renderBookmarkItem = () => {
|
|
|
|
|
+ return (
|
|
|
|
|
+ isOpen &&
|
|
|
|
|
+ bookmarks?.map((bookmark) => {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <BookmarkItem
|
|
|
|
|
+ key={bookmark._id}
|
|
|
isReadOnlyUser={isReadOnlyUser}
|
|
isReadOnlyUser={isReadOnlyUser}
|
|
|
isOperable={props.isOperable}
|
|
isOperable={props.isOperable}
|
|
|
- bookmarkFolder={childFolder}
|
|
|
|
|
|
|
+ bookmarkedPage={bookmark.page}
|
|
|
level={level + 1}
|
|
level={level + 1}
|
|
|
- root={root}
|
|
|
|
|
- isUserHomepage={isUserHomepage}
|
|
|
|
|
|
|
+ parentFolder={bookmarkFolder}
|
|
|
|
|
+ canMoveToRoot
|
|
|
onClickDeleteMenuItemHandler={onClickDeleteMenuItemHandler}
|
|
onClickDeleteMenuItemHandler={onClickDeleteMenuItemHandler}
|
|
|
bookmarkFolderTreeMutation={bookmarkFolderTreeMutation}
|
|
bookmarkFolderTreeMutation={bookmarkFolderTreeMutation}
|
|
|
/>
|
|
/>
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
- });
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const renderBookmarkItem = () => {
|
|
|
|
|
- return isOpen && bookmarks?.map((bookmark) => {
|
|
|
|
|
- return (
|
|
|
|
|
- <BookmarkItem
|
|
|
|
|
- key={bookmark._id}
|
|
|
|
|
- isReadOnlyUser={isReadOnlyUser}
|
|
|
|
|
- isOperable={props.isOperable}
|
|
|
|
|
- bookmarkedPage={bookmark.page}
|
|
|
|
|
- level={level + 1}
|
|
|
|
|
- parentFolder={bookmarkFolder}
|
|
|
|
|
- canMoveToRoot
|
|
|
|
|
- onClickDeleteMenuItemHandler={onClickDeleteMenuItemHandler}
|
|
|
|
|
- bookmarkFolderTreeMutation={bookmarkFolderTreeMutation}
|
|
|
|
|
- />
|
|
|
|
|
- );
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ );
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const onClickRenameHandler = useCallback(() => {
|
|
const onClickRenameHandler = useCallback(() => {
|
|
@@ -204,7 +264,9 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
|
|
|
}, []);
|
|
}, []);
|
|
|
|
|
|
|
|
const onClickDeleteHandler = useCallback(() => {
|
|
const onClickDeleteHandler = useCallback(() => {
|
|
|
- const bookmarkFolderDeleteHandler: onDeletedBookmarkFolderFunction = (folderId) => {
|
|
|
|
|
|
|
+ const bookmarkFolderDeleteHandler: onDeletedBookmarkFolderFunction = (
|
|
|
|
|
+ folderId,
|
|
|
|
|
+ ) => {
|
|
|
if (typeof folderId !== 'string') {
|
|
if (typeof folderId !== 'string') {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
@@ -214,21 +276,39 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
|
|
|
if (bookmarkFolder == null) {
|
|
if (bookmarkFolder == null) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- openDeleteBookmarkFolderModal(bookmarkFolder, { onDeleted: bookmarkFolderDeleteHandler });
|
|
|
|
|
- }, [bookmarkFolder, bookmarkFolderTreeMutation, openDeleteBookmarkFolderModal]);
|
|
|
|
|
-
|
|
|
|
|
- const onClickMoveToRootHandlerForBookmarkFolderItemControl = useCallback(async() => {
|
|
|
|
|
- try {
|
|
|
|
|
- await updateBookmarkFolder(bookmarkFolder._id, bookmarkFolder.name, null, bookmarkFolder.childFolder);
|
|
|
|
|
- bookmarkFolderTreeMutation();
|
|
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
- toastError(err);
|
|
|
|
|
- }
|
|
|
|
|
- }, [bookmarkFolder._id, bookmarkFolder.childFolder, bookmarkFolder.name, bookmarkFolderTreeMutation]);
|
|
|
|
|
|
|
+ openDeleteBookmarkFolderModal(bookmarkFolder, {
|
|
|
|
|
+ onDeleted: bookmarkFolderDeleteHandler,
|
|
|
|
|
+ });
|
|
|
|
|
+ }, [
|
|
|
|
|
+ bookmarkFolder,
|
|
|
|
|
+ bookmarkFolderTreeMutation,
|
|
|
|
|
+ openDeleteBookmarkFolderModal,
|
|
|
|
|
+ ]);
|
|
|
|
|
|
|
|
|
|
+ const onClickMoveToRootHandlerForBookmarkFolderItemControl =
|
|
|
|
|
+ useCallback(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await updateBookmarkFolder(
|
|
|
|
|
+ bookmarkFolder._id,
|
|
|
|
|
+ bookmarkFolder.name,
|
|
|
|
|
+ null,
|
|
|
|
|
+ bookmarkFolder.childFolder,
|
|
|
|
|
+ );
|
|
|
|
|
+ bookmarkFolderTreeMutation();
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ toastError(err);
|
|
|
|
|
+ }
|
|
|
|
|
+ }, [
|
|
|
|
|
+ bookmarkFolder._id,
|
|
|
|
|
+ bookmarkFolder.childFolder,
|
|
|
|
|
+ bookmarkFolder.name,
|
|
|
|
|
+ bookmarkFolderTreeMutation,
|
|
|
|
|
+ ]);
|
|
|
return (
|
|
return (
|
|
|
- <div id={`grw-bookmark-folder-item-${folderId}`} className="grw-foldertree-item-container">
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ id={`grw-bookmark-folder-item-${folderId}`}
|
|
|
|
|
+ className="grw-foldertree-item-container"
|
|
|
|
|
+ >
|
|
|
<DragAndDropWrapper
|
|
<DragAndDropWrapper
|
|
|
key={folderId}
|
|
key={folderId}
|
|
|
type={acceptedTypes}
|
|
type={acceptedTypes}
|
|
@@ -240,23 +320,8 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
|
|
|
>
|
|
>
|
|
|
<li
|
|
<li
|
|
|
className="list-group-item list-group-item-action border-0 py-2 d-flex align-items-center rounded-1"
|
|
className="list-group-item list-group-item-action border-0 py-2 d-flex align-items-center rounded-1"
|
|
|
- onClick={loadChildFolder}
|
|
|
|
|
style={{ paddingLeft }}
|
|
style={{ paddingLeft }}
|
|
|
>
|
|
>
|
|
|
- <div className="grw-triangle-container d-flex justify-content-center">
|
|
|
|
|
- <button
|
|
|
|
|
- type="button"
|
|
|
|
|
- className={triangleBtnClassName(isOpen, childrenExists)}
|
|
|
|
|
- onClick={loadChildFolder}
|
|
|
|
|
- >
|
|
|
|
|
- <div className="d-flex justify-content-center">
|
|
|
|
|
- <span className="material-symbols-outlined fs-5">arrow_right</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- </button>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div>
|
|
|
|
|
- <FolderIcon isOpen={isOpen} />
|
|
|
|
|
- </div>
|
|
|
|
|
{isRenameAction ? (
|
|
{isRenameAction ? (
|
|
|
<div className="flex-fill">
|
|
<div className="flex-fill">
|
|
|
<BookmarkFolderNameInput
|
|
<BookmarkFolderNameInput
|
|
@@ -266,27 +331,46 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
) : (
|
|
) : (
|
|
|
- <>
|
|
|
|
|
|
|
+ <button
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ className="d-flex align-items-center flex-fill border-0 bg-transparent p-0 text-start"
|
|
|
|
|
+ onClick={loadChildFolder}
|
|
|
|
|
+ >
|
|
|
|
|
+ <div className="grw-triangle-container d-flex justify-content-center">
|
|
|
|
|
+ <span className={triangleBtnClassName(isOpen, childrenExists)}>
|
|
|
|
|
+ <span className="material-symbols-outlined fs-5">
|
|
|
|
|
+ arrow_right
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <FolderIcon isOpen={isOpen} />
|
|
|
|
|
+ </div>
|
|
|
<div className="grw-foldertree-title-anchor ps-1">
|
|
<div className="grw-foldertree-title-anchor ps-1">
|
|
|
<p className="text-truncate m-auto">{name}</p>
|
|
<p className="text-truncate m-auto">{name}</p>
|
|
|
</div>
|
|
</div>
|
|
|
- </>
|
|
|
|
|
|
|
+ </button>
|
|
|
)}
|
|
)}
|
|
|
{isOperable && (
|
|
{isOperable && (
|
|
|
<div className="grw-foldertree-control d-flex">
|
|
<div className="grw-foldertree-control d-flex">
|
|
|
<BookmarkFolderItemControl
|
|
<BookmarkFolderItemControl
|
|
|
onClickRename={onClickRenameHandler}
|
|
onClickRename={onClickRenameHandler}
|
|
|
onClickDelete={onClickDeleteHandler}
|
|
onClickDelete={onClickDeleteHandler}
|
|
|
- onClickMoveToRoot={bookmarkFolder.parent != null
|
|
|
|
|
- ? onClickMoveToRootHandlerForBookmarkFolderItemControl
|
|
|
|
|
- : undefined
|
|
|
|
|
|
|
+ onClickMoveToRoot={
|
|
|
|
|
+ bookmarkFolder.parent != null
|
|
|
|
|
+ ? onClickMoveToRootHandlerForBookmarkFolderItemControl
|
|
|
|
|
+ : undefined
|
|
|
}
|
|
}
|
|
|
>
|
|
>
|
|
|
- <div onClick={e => e.stopPropagation()}>
|
|
|
|
|
- <DropdownToggle color="transparent" className="border-0 rounded btn-page-item-control p-0 grw-visible-on-hover me-1">
|
|
|
|
|
- <span className="material-symbols-outlined">more_vert</span>
|
|
|
|
|
- </DropdownToggle>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <DropdownToggle
|
|
|
|
|
+ color="transparent"
|
|
|
|
|
+ className="border-0 rounded btn-page-item-control p-0 grw-visible-on-hover me-1"
|
|
|
|
|
+ onClick={(event) => {
|
|
|
|
|
+ event.stopPropagation();
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <span className="material-symbols-outlined">more_vert</span>
|
|
|
|
|
+ </DropdownToggle>
|
|
|
</BookmarkFolderItemControl>
|
|
</BookmarkFolderItemControl>
|
|
|
{/* Maximum folder hierarchy of 2 levels */}
|
|
{/* Maximum folder hierarchy of 2 levels */}
|
|
|
{!(bookmarkFolder.parent != null) && (
|
|
{!(bookmarkFolder.parent != null) && (
|
|
@@ -304,17 +388,10 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
|
|
|
</li>
|
|
</li>
|
|
|
</DragAndDropWrapper>
|
|
</DragAndDropWrapper>
|
|
|
{isCreateAction && (
|
|
{isCreateAction && (
|
|
|
- <BookmarkFolderNameInput
|
|
|
|
|
- onSubmit={create}
|
|
|
|
|
- onCancel={cancel}
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ <BookmarkFolderNameInput onSubmit={create} onCancel={cancel} />
|
|
|
)}
|
|
)}
|
|
|
- {
|
|
|
|
|
- renderChildFolder()
|
|
|
|
|
- }
|
|
|
|
|
- {
|
|
|
|
|
- renderBookmarkItem()
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ {renderChildFolder()}
|
|
|
|
|
+ {renderBookmarkItem()}
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|