Bookmarks.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import React, { useCallback, useEffect, useState } from 'react';
  2. import { DevidedPagePath } from '@growi/core';
  3. import { useTranslation } from 'react-i18next';
  4. import { UncontrolledTooltip } from 'reactstrap';
  5. import { toastError } from '~/client/util/apiNotification';
  6. import { apiv3Get } from '~/client/util/apiv3-client';
  7. import { IPageHasId } from '~/interfaces/page';
  8. import { useCurrentUser, useIsGuestUser } from '~/stores/context';
  9. import loggerFactory from '~/utils/logger';
  10. const logger = loggerFactory('growi:BookmarkList');
  11. // TODO: Remove pagination and apply scrolling (not infinity)
  12. const ACTIVE_PAGE = 1;
  13. type Props = {
  14. pages: IPageHasId[]
  15. }
  16. const BookmarksItem = (props: Props) => {
  17. const { pages } = props;
  18. const generateBookmarkedPageList = pages.map((page) => {
  19. const dPagePath = new DevidedPagePath(page.path, false, true);
  20. const { latter: pageTitle, former: formerPagePath } = dPagePath;
  21. return (
  22. <div key={page._id}>
  23. <li className="list-group-item list-group-item-action border-0 py-0 pr-3 d-flex align-items-center" id={`bookmark-item-${page._id}`}>
  24. <a href={`/${page._id}`} className="grw-bookmarks-title-anchor flex-grow-1">
  25. <p className={`text-truncate m-auto ${page.isEmpty && 'grw-sidebar-text-muted'}`}>{pageTitle}</p>
  26. </a>
  27. </li>
  28. <UncontrolledTooltip
  29. modifiers={{ preventOverflow: { boundariesElement: 'window' } }}
  30. autohide={false}
  31. placement="right"
  32. target={`bookmark-item-${page._id}`}
  33. >
  34. { formerPagePath || '/' }
  35. </UncontrolledTooltip>
  36. </div>
  37. );
  38. });
  39. return (
  40. <>
  41. <ul className="grw-bookmarks-list list-group p-3">
  42. <div className="grw-bookmarks-item-container">
  43. {generateBookmarkedPageList}
  44. </div>
  45. </ul>
  46. </>
  47. );
  48. };
  49. const Bookmarks = () : JSX.Element => {
  50. const { t } = useTranslation();
  51. const { data: currentUser } = useCurrentUser();
  52. const { data: isGuestUser } = useIsGuestUser();
  53. const [pages, setPages] = useState<IPageHasId[]>([]);
  54. const getMyBookmarkList = useCallback(async() => {
  55. // TODO: Remove pagination and apply scrolling (not infinity)
  56. const page = ACTIVE_PAGE;
  57. try {
  58. const res = await apiv3Get(`/bookmarks/${currentUser?._id}`, { page });
  59. const { paginationResult } = res.data;
  60. setPages(paginationResult.docs.map((page) => {
  61. return {
  62. ...page.page,
  63. };
  64. }));
  65. }
  66. catch (error) {
  67. logger.error('failed to fetch data', error);
  68. toastError(error, 'Error occurred in bookmark page list');
  69. }
  70. }, [currentUser]);
  71. useEffect(() => {
  72. getMyBookmarkList();
  73. }, [getMyBookmarkList]);
  74. const renderBookmarkList = () => {
  75. if (pages.length === 0) {
  76. return (
  77. <h3 className="pl-3">
  78. { t('No bookmarks yet') }
  79. </h3>
  80. );
  81. }
  82. return <BookmarksItem pages={pages} />;
  83. };
  84. return (
  85. <>
  86. <div className="grw-sidebar-content-header p-3">
  87. <h3 className="mb-0">{t('Bookmarks')}</h3>
  88. </div>
  89. { isGuestUser
  90. ? (
  91. <h3 className="pl-3">
  92. { t('Not available for guest') }
  93. </h3>
  94. ) : (
  95. { renderBookmarkList }
  96. )
  97. }
  98. </>
  99. );
  100. };
  101. export default Bookmarks;