Răsfoiți Sursa

Merge pull request #5724 from weseek/feat/84030-add-count-badge-in-toc

feat: gr84030 add count badge in toc
cao 4 ani în urmă
părinte
comite
cbccb7a0bc

+ 17 - 0
packages/app/src/components/Common/CountBadge.tsx

@@ -0,0 +1,17 @@
+import React, { FC } from 'react';
+
+type CountProps = {
+  count: number
+}
+
+const CountBadge: FC<CountProps> = (props:CountProps) => {
+  return (
+    <>
+      <span className="grw-count-badge px-2 badge badge-pill badge-light">
+        {props.count}
+      </span>
+    </>
+  );
+};
+
+export default CountBadge;

+ 18 - 14
packages/app/src/components/Page/DisplaySwitcher.tsx

@@ -1,27 +1,29 @@
 import React, { useMemo } from 'react';
 import React, { useMemo } from 'react';
+
+import { pagePathUtils } from '@growi/core';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 import { TabContent, TabPane } from 'reactstrap';
 import { TabContent, TabPane } from 'reactstrap';
 
 
-import { pagePathUtils } from '@growi/core';
 
 
-import { EditorMode, useEditorMode } from '~/stores/ui';
-import { useDescendantsPageListModal } from '~/stores/modal';
+import { smoothScrollIntoView } from '~/client/util/smooth-scroll';
+import { useSWRxPageComment } from '~/stores/comment';
 import {
 import {
   useCurrentPagePath, useIsSharedUser, useIsEditable, useCurrentPageId, useIsUserPage, usePageUser,
   useCurrentPagePath, useIsSharedUser, useIsEditable, useCurrentPageId, useIsUserPage, usePageUser,
 } from '~/stores/context';
 } from '~/stores/context';
+import { useDescendantsPageListModal } from '~/stores/modal';
+import { useSWRxPageList } from '~/stores/page';
+import { EditorMode, useEditorMode } from '~/stores/ui';
 
 
-
-import { smoothScrollIntoView } from '~/client/util/smooth-scroll';
-
+import CountBadge from '../Common/CountBadge';
+import ContentLinkButtons from '../ContentLinkButtons';
+import HashChanged from '../EventListeneres/HashChanged';
 import PageListIcon from '../Icons/PageListIcon';
 import PageListIcon from '../Icons/PageListIcon';
-import Editor from '../PageEditor';
 import Page from '../Page';
 import Page from '../Page';
-import UserInfo from '../User/UserInfo';
-import TableOfContents from '../TableOfContents';
-import ContentLinkButtons from '../ContentLinkButtons';
-import PageEditorByHackmd from '../PageEditorByHackmd';
+import Editor from '../PageEditor';
 import EditorNavbarBottom from '../PageEditor/EditorNavbarBottom';
 import EditorNavbarBottom from '../PageEditor/EditorNavbarBottom';
-import HashChanged from '../EventListeneres/HashChanged';
+import PageEditorByHackmd from '../PageEditorByHackmd';
+import TableOfContents from '../TableOfContents';
+import UserInfo from '../User/UserInfo';
 
 
 
 
 const WIKI_HEADER_LINK = 120;
 const WIKI_HEADER_LINK = 120;
@@ -43,6 +45,8 @@ const DisplaySwitcher = (): JSX.Element => {
   const { data: isUserPage } = useIsUserPage();
   const { data: isUserPage } = useIsUserPage();
   const { data: isEditable } = useIsEditable();
   const { data: isEditable } = useIsEditable();
   const { data: pageUser } = usePageUser();
   const { data: pageUser } = usePageUser();
+  const { data: comments } = useSWRxPageComment(currentPageId);
+  const { data: pagingResult } = useSWRxPageList(currentPath ?? null);
 
 
   const { data: editorMode } = useEditorMode();
   const { data: editorMode } = useEditorMode();
 
 
@@ -74,7 +78,7 @@ const DisplaySwitcher = (): JSX.Element => {
                           <PageListIcon />
                           <PageListIcon />
                         </div>
                         </div>
                         {t('page_list')}
                         {t('page_list')}
-                        <span></span> {/* for a count badge */}
+                        {pagingResult != null && <CountBadge count={pagingResult.totalCount} />}
                       </button>
                       </button>
                     ) }
                     ) }
                   </div>
                   </div>
@@ -89,7 +93,7 @@ const DisplaySwitcher = (): JSX.Element => {
                       >
                       >
                         <i className="icon-fw icon-bubbles grw-page-accessories-control-icon"></i>
                         <i className="icon-fw icon-bubbles grw-page-accessories-control-icon"></i>
                         <span>Comments</span>
                         <span>Comments</span>
-                        <span></span> {/* for a count badge */}
+                        {comments != null && <CountBadge count={comments.length} />}
                       </button>
                       </button>
                     </div>
                     </div>
                   ) }
                   ) }

+ 15 - 28
packages/app/src/components/Sidebar/PageTree/Item.tsx

@@ -1,32 +1,33 @@
 import React, {
 import React, {
   useCallback, useState, FC, useEffect,
   useCallback, useState, FC, useEffect,
 } from 'react';
 } from 'react';
-import { DropdownToggle } from 'reactstrap';
-import { useTranslation } from 'react-i18next';
-
-import { useDrag, useDrop } from 'react-dnd';
 
 
 import nodePath from 'path';
 import nodePath from 'path';
 
 
 import { pathUtils, pagePathUtils } from '@growi/core';
 import { pathUtils, pagePathUtils } from '@growi/core';
+import { useDrag, useDrop } from 'react-dnd';
+import { useTranslation } from 'react-i18next';
+import { DropdownToggle } from 'reactstrap';
 
 
-import loggerFactory from '~/utils/logger';
 
 
+import { bookmark, unbookmark } from '~/client/services/page-operation';
 import { toastWarning, toastError, toastSuccess } from '~/client/util/apiNotification';
 import { toastWarning, toastError, toastSuccess } from '~/client/util/apiNotification';
-
-import { useSWRxPageChildren } from '~/stores/page-listing';
 import { apiv3Put, apiv3Post } from '~/client/util/apiv3-client';
 import { apiv3Put, apiv3Post } from '~/client/util/apiv3-client';
+import TriangleIcon from '~/components/Icons/TriangleIcon';
+import {
+  IPageHasId, IPageInfoAll, IPageToDeleteWithMeta,
+} from '~/interfaces/page';
 import { IPageForPageDuplicateModal } from '~/stores/modal';
 import { IPageForPageDuplicateModal } from '~/stores/modal';
+import { useSWRxPageChildren } from '~/stores/page-listing';
+import { usePageTreeDescCountMap } from '~/stores/ui';
+import loggerFactory from '~/utils/logger';
+
 
 
-import TriangleIcon from '~/components/Icons/TriangleIcon';
-import { bookmark, unbookmark } from '~/client/services/page-operation';
 import ClosableTextInput, { AlertInfo, AlertType } from '../../Common/ClosableTextInput';
 import ClosableTextInput, { AlertInfo, AlertType } from '../../Common/ClosableTextInput';
+import CountBadge from '../../Common/CountBadge';
 import { PageItemControl } from '../../Common/Dropdown/PageItemControl';
 import { PageItemControl } from '../../Common/Dropdown/PageItemControl';
+
 import { ItemNode } from './ItemNode';
 import { ItemNode } from './ItemNode';
-import { usePageTreeDescCountMap } from '~/stores/ui';
-import {
-  IPageHasId, IPageInfoAll, IPageToDeleteWithMeta,
-} from '~/interfaces/page';
 
 
 
 
 const logger = loggerFactory('growi:cli:Item');
 const logger = loggerFactory('growi:cli:Item');
@@ -94,20 +95,6 @@ const isDroppable = (fromPage?: Partial<IPageHasId>, newParentPage?: Partial<IPa
 };
 };
 
 
 
 
-type ItemCountProps = {
-  descendantCount: number
-}
-
-const ItemCount: FC<ItemCountProps> = (props:ItemCountProps) => {
-  return (
-    <>
-      <span className="grw-pagetree-count badge badge-pill badge-light">
-        {props.descendantCount}
-      </span>
-    </>
-  );
-};
-
 const Item: FC<ItemProps> = (props: ItemProps) => {
 const Item: FC<ItemProps> = (props: ItemProps) => {
   const { t } = useTranslation();
   const { t } = useTranslation();
   const {
   const {
@@ -465,7 +452,7 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
           )}
           )}
         {descendantCount > 0 && !isRenameInputShown && (
         {descendantCount > 0 && !isRenameInputShown && (
           <div className="grw-pagetree-count-wrapper">
           <div className="grw-pagetree-count-wrapper">
-            <ItemCount descendantCount={descendantCount} />
+            <CountBadge count={descendantCount} />
           </div>
           </div>
         )}
         )}
         <div className="grw-pagetree-control d-flex">
         <div className="grw-pagetree-control d-flex">

+ 2 - 2
packages/app/src/styles/_page-tree.scss

@@ -21,7 +21,7 @@ $grw-pagetree-item-padding-left: 10px;
         display: block;
         display: block;
       }
       }
 
 
-      .grw-pagetree-count {
+      .grw-count-badge {
         display: none;
         display: none;
       }
       }
     }
     }
@@ -49,7 +49,7 @@ $grw-pagetree-item-padding-left: 10px;
         display: none;
         display: none;
       }
       }
 
 
-      .grw-pagetree-count {
+      .grw-count-badge {
         min-width: 28px;
         min-width: 28px;
         padding: 0.1rem 0.5rem;
         padding: 0.1rem 0.5rem;
         font-size: 12px;
         font-size: 12px;

+ 6 - 1
packages/app/src/styles/theme/_apply-colors-dark.scss

@@ -287,7 +287,7 @@ ul.pagination {
     .grw-pagetree-triangle-btn {
     .grw-pagetree-triangle-btn {
       @include button-outline-svg-icon-variant($secondary, $gray-200);
       @include button-outline-svg-icon-variant($secondary, $gray-200);
     }
     }
-    .grw-pagetree-count {
+    .grw-count-badge {
       color: $gray-400;
       color: $gray-400;
       background: $gray-700;
       background: $gray-700;
     }
     }
@@ -469,6 +469,11 @@ ul.pagination {
 * grw-side-contents
 * grw-side-contents
 */
 */
 .grw-side-contents-sticky-container {
 .grw-side-contents-sticky-container {
+  .grw-count-badge {
+    color: $gray-400;
+    background: $gray-700;
+  }
+
   .grw-border-vr {
   .grw-border-vr {
     border-color: $border-color-toc;
     border-color: $border-color-toc;
   }
   }

+ 6 - 1
packages/app/src/styles/theme/_apply-colors-light.scss

@@ -192,7 +192,7 @@ $dropdown-link-active-bg: $bgcolor-dropdown-link-active;
     .grw-pagetree-triangle-btn {
     .grw-pagetree-triangle-btn {
       @include button-outline-svg-icon-variant($gray-400, $primary);
       @include button-outline-svg-icon-variant($gray-400, $primary);
     }
     }
-    .grw-pagetree-count {
+    .grw-count-badge {
       color: $gray-500;
       color: $gray-500;
       background: $gray-200;
       background: $gray-200;
     }
     }
@@ -357,6 +357,11 @@ $dropdown-link-active-bg: $bgcolor-dropdown-link-active;
 * grw-side-contents
 * grw-side-contents
 */
 */
 .grw-side-contents-sticky-container {
 .grw-side-contents-sticky-container {
+  .grw-count-badge {
+    color: $primary;
+    background: $gray-200;
+  }
+
   .grw-border-vr {
   .grw-border-vr {
     border-color: $border-color-toc;
     border-color: $border-color-toc;
   }
   }