|
@@ -1,54 +1,62 @@
|
|
|
|
|
|
|
|
-import React, { useCallback, useEffect, useState } from 'react';
|
|
|
|
|
|
|
+import React from 'react';
|
|
|
|
|
|
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
|
+import { toastSuccess } from '~/client/util/apiNotification';
|
|
|
|
|
+import { IPageToDeleteWithMeta } from '~/interfaces/page';
|
|
|
|
|
+import { useIsGuestUser } from '~/stores/context';
|
|
|
|
|
+import { usePageDeleteModal } from '~/stores/modal';
|
|
|
|
|
+import { useSWRxCurrentUserBookmarks } from '~/stores/bookmark';
|
|
|
|
|
+import { OnDeletedFunction } from '~/interfaces/ui';
|
|
|
|
|
|
|
|
-import { toastError } from '~/client/util/apiNotification';
|
|
|
|
|
-import { apiv3Get } from '~/client/util/apiv3-client';
|
|
|
|
|
-import { IPageHasId } from '~/interfaces/page';
|
|
|
|
|
-import { useCurrentUser, useIsGuestUser } from '~/stores/context';
|
|
|
|
|
-import loggerFactory from '~/utils/logger';
|
|
|
|
|
|
|
|
|
|
import BookmarkItem from './Bookmarks/BookmarkItem';
|
|
import BookmarkItem from './Bookmarks/BookmarkItem';
|
|
|
|
|
|
|
|
-const logger = loggerFactory('growi:BookmarkList');
|
|
|
|
|
-// TODO: Remove pagination and apply scrolling (not infinity)
|
|
|
|
|
-const ACTIVE_PAGE = 1;
|
|
|
|
|
|
|
|
|
|
const Bookmarks = () : JSX.Element => {
|
|
const Bookmarks = () : JSX.Element => {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
- const { data: currentUser } = useCurrentUser();
|
|
|
|
|
const { data: isGuestUser } = useIsGuestUser();
|
|
const { data: isGuestUser } = useIsGuestUser();
|
|
|
- const [pages, setPages] = useState<IPageHasId[]>([]);
|
|
|
|
|
- const page = ACTIVE_PAGE;
|
|
|
|
|
|
|
+ const { data: currentUserBookmarksData, mutate: mutateCurrentUserBookmarks } = useSWRxCurrentUserBookmarks();
|
|
|
|
|
+ const { open: openDeleteModal } = usePageDeleteModal();
|
|
|
|
|
|
|
|
- const getMyBookmarkList = useCallback(async() => {
|
|
|
|
|
- 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, page]);
|
|
|
|
|
|
|
+ const onBookmarkItemDeleted = (pageToDelete: IPageToDeleteWithMeta):void => {
|
|
|
|
|
+ const onDeletedHandler: OnDeletedFunction = (pathOrPathsToDelete, _isRecursively, isCompletely) => {
|
|
|
|
|
+ if (typeof pathOrPathsToDelete !== 'string') {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const path = pathOrPathsToDelete;
|
|
|
|
|
|
|
|
- useEffect(() => {
|
|
|
|
|
- getMyBookmarkList();
|
|
|
|
|
- }, [getMyBookmarkList]);
|
|
|
|
|
|
|
+ if (isCompletely) {
|
|
|
|
|
+ toastSuccess(t('deleted_pages_completely', { path }));
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ toastSuccess(t('deleted_pages', { path }));
|
|
|
|
|
+ }
|
|
|
|
|
+ mutateCurrentUserBookmarks();
|
|
|
|
|
+ };
|
|
|
|
|
+ openDeleteModal([pageToDelete], { onDeleted: onDeletedHandler });
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- const generateBookmarkList = () => {
|
|
|
|
|
|
|
+ const renderBookmarkList = () => {
|
|
|
|
|
+ if (currentUserBookmarksData?.length === 0) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <h4 className="pl-3">
|
|
|
|
|
+ { t('No bookmarks yet') }
|
|
|
|
|
+ </h4>
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
return (
|
|
return (
|
|
|
<ul className="grw-bookmarks-list list-group p-3">
|
|
<ul className="grw-bookmarks-list list-group p-3">
|
|
|
<div className="grw-bookmarks-item-container">
|
|
<div className="grw-bookmarks-item-container">
|
|
|
- { pages.map((page) => {
|
|
|
|
|
|
|
+ { currentUserBookmarksData?.map((currentUserBookmark) => {
|
|
|
return (
|
|
return (
|
|
|
- <BookmarkItem key={page._id} page={page} refreshBookmarkList={getMyBookmarkList} />
|
|
|
|
|
|
|
+ <BookmarkItem
|
|
|
|
|
+ key={currentUserBookmark._id}
|
|
|
|
|
+ bookmarkedPage={currentUserBookmark}
|
|
|
|
|
+ onUnbookmarked={mutateCurrentUserBookmarks}
|
|
|
|
|
+ onRenamed={mutateCurrentUserBookmarks}
|
|
|
|
|
+ onDeleted={onBookmarkItemDeleted}
|
|
|
|
|
+ />
|
|
|
);
|
|
);
|
|
|
})}
|
|
})}
|
|
|
</div>
|
|
</div>
|
|
@@ -56,17 +64,6 @@ const Bookmarks = () : JSX.Element => {
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const renderBookmarksItem = () => {
|
|
|
|
|
- if (pages?.length === 0) {
|
|
|
|
|
- return (
|
|
|
|
|
- <h3 className="pl-3">
|
|
|
|
|
- { t('No bookmarks yet') }
|
|
|
|
|
- </h3>
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- return generateBookmarkList();
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
return (
|
|
return (
|
|
|
<>
|
|
<>
|
|
|
<div className="grw-sidebar-content-header p-3">
|
|
<div className="grw-sidebar-content-header p-3">
|
|
@@ -74,15 +71,13 @@ const Bookmarks = () : JSX.Element => {
|
|
|
</div>
|
|
</div>
|
|
|
{ isGuestUser
|
|
{ isGuestUser
|
|
|
? (
|
|
? (
|
|
|
- <h3 className="pl-3">
|
|
|
|
|
|
|
+ <h4 className="pl-3">
|
|
|
{ t('Not available for guest') }
|
|
{ t('Not available for guest') }
|
|
|
- </h3>
|
|
|
|
|
- ) : renderBookmarksItem()
|
|
|
|
|
|
|
+ </h4>
|
|
|
|
|
+ ) : renderBookmarkList()
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
</>
|
|
</>
|
|
|
);
|
|
);
|
|
|
-
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
export default Bookmarks;
|
|
export default Bookmarks;
|