Selaa lähdekoodia

improve links

Yuki Takei 3 vuotta sitten
vanhempi
sitoutus
2c9a3b1da0

+ 24 - 15
packages/app/src/components/PagePathHierarchicalLink.jsx

@@ -1,13 +1,14 @@
-import React from 'react';
-import PropTypes from 'prop-types';
+import React, { memo } from 'react';
 
 
+import Link from 'next/link';
+import PropTypes from 'prop-types';
 import urljoin from 'url-join';
 import urljoin from 'url-join';
 
 
 import LinkedPagePath from '../models/linked-page-path';
 import LinkedPagePath from '../models/linked-page-path';
 
 
 
 
 // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
-const PagePathHierarchicalLink = (props) => {
+const PagePathHierarchicalLink = memo((props) => {
   const {
   const {
     linkedPagePath, linkedPagePathByHtml, basePath, isInTrash,
     linkedPagePath, linkedPagePathByHtml, basePath, isInTrash,
   } = props;
   } = props;
@@ -21,7 +22,9 @@ const PagePathHierarchicalLink = (props) => {
       ? (
       ? (
         <>
         <>
           <span className="path-segment">
           <span className="path-segment">
-            <a href="/trash"><i className="icon-trash"></i></a>
+            <Link href="/trash">
+              <a ><i className="icon-trash"></i></a>
+            </Link>
           </span>
           </span>
           <span className="separator"><a href="/">/</a></span>
           <span className="separator"><a href="/">/</a></span>
         </>
         </>
@@ -29,10 +32,12 @@ const PagePathHierarchicalLink = (props) => {
       : (
       : (
         <>
         <>
           <span className="path-segment">
           <span className="path-segment">
-            <a href="/">
-              <i className="icon-home"></i>
-              <span className="separator">/</span>
-            </a>
+            <Link href="/">
+              <a >
+                <i className="icon-home"></i>
+                <span className="separator">/</span>
+              </a>
+            </Link>
           </span>
           </span>
         </>
         </>
       );
       );
@@ -68,16 +73,20 @@ const PagePathHierarchicalLink = (props) => {
         <span className="separator">/</span>
         <span className="separator">/</span>
       ) }
       ) }
 
 
-      {
-        shouldDangerouslySetInnerHTML
-          // eslint-disable-next-line react/no-danger
-          ? <a className="page-segment" href={href} dangerouslySetInnerHTML={{ __html: linkedPagePathByHtml.pathName }}></a>
-          : <a className="page-segment" href={href}>{linkedPagePath.pathName}</a>
-      }
+      <Link href={href}>
+        {
+          shouldDangerouslySetInnerHTML
+            // eslint-disable-next-line react/no-danger
+            ? <a className="page-segment" dangerouslySetInnerHTML={{ __html: linkedPagePathByHtml.pathName }}></a>
+            : <a className="page-segment" >{linkedPagePath.pathName}</a>
+        }
+      </Link>
 
 
     </RootElm>
     </RootElm>
   );
   );
-};
+});
+PagePathHierarchicalLink.displayName = 'PagePathHierarchicalLink';
+
 
 
 PagePathHierarchicalLink.propTypes = {
 PagePathHierarchicalLink.propTypes = {
   linkedPagePath: PropTypes.instanceOf(LinkedPagePath).isRequired,
   linkedPagePath: PropTypes.instanceOf(LinkedPagePath).isRequired,

+ 6 - 3
packages/app/src/components/Sidebar/PageTree/Item.tsx

@@ -6,6 +6,7 @@ import nodePath from 'path';
 
 
 import { pathUtils, pagePathUtils } from '@growi/core';
 import { pathUtils, pagePathUtils } from '@growi/core';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
+import Link from 'next/link';
 import { useDrag, useDrop } from 'react-dnd';
 import { useDrag, useDrop } from 'react-dnd';
 import { UncontrolledTooltip, DropdownToggle } from 'reactstrap';
 import { UncontrolledTooltip, DropdownToggle } from 'reactstrap';
 
 
@@ -459,9 +460,11 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
                 </>
                 </>
               )}
               )}
 
 
-              <a href={`/${page._id}`} className="grw-pagetree-title-anchor flex-grow-1">
-                <p className={`text-truncate m-auto ${page.isEmpty && 'grw-sidebar-text-muted'}`}>{nodePath.basename(page.path ?? '') || '/'}</p>
-              </a>
+              <Link href={`/${page._id}`}>
+                <a className="grw-pagetree-title-anchor flex-grow-1">
+                  <p className={`text-truncate m-auto ${page.isEmpty && 'grw-sidebar-text-muted'}`}>{nodePath.basename(page.path ?? '') || '/'}</p>
+                </a>
+              </Link>
             </>
             </>
           )}
           )}
         {descendantCount > 0 && !isRenameInputShown && (
         {descendantCount > 0 && !isRenameInputShown && (

+ 28 - 20
packages/app/src/components/Sidebar/RecentChanges.tsx

@@ -1,15 +1,17 @@
 import React, {
 import React, {
-  FC,
-  useCallback, useEffect, useState,
+  memo, useCallback, useEffect, useState,
 } from 'react';
 } from 'react';
 
 
 import { DevidedPagePath } from '@growi/core';
 import { DevidedPagePath } from '@growi/core';
 import { UserPicture, FootstampIcon } from '@growi/ui';
 import { UserPicture, FootstampIcon } from '@growi/ui';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
+import Link from 'next/link';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
 
 
 import PagePathHierarchicalLink from '~/components/PagePathHierarchicalLink';
 import PagePathHierarchicalLink from '~/components/PagePathHierarchicalLink';
+import { isPopulated } from '~/interfaces/common';
+import { IPageHasId } from '~/interfaces/page';
 import LinkedPagePath from '~/models/linked-page-path';
 import LinkedPagePath from '~/models/linked-page-path';
 import { useSWRInifinitexRecentlyUpdated } from '~/stores/page-listing';
 import { useSWRInifinitexRecentlyUpdated } from '~/stores/page-listing';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
@@ -21,7 +23,11 @@ import InfiniteScroll from './InfiniteScroll';
 
 
 const logger = loggerFactory('growi:History');
 const logger = loggerFactory('growi:History');
 
 
-function PageItemLower({ page }) {
+type PageItemProps = {
+  page: IPageHasId,
+}
+
+const PageItemLower = memo(({ page }: PageItemProps): JSX.Element => {
   return (
   return (
     <div className="d-flex justify-content-between grw-recent-changes-item-lower pt-1">
     <div className="d-flex justify-content-between grw-recent-changes-item-lower pt-1">
       <div className="d-flex">
       <div className="d-flex">
@@ -35,11 +41,11 @@ function PageItemLower({ page }) {
       </div>
       </div>
     </div>
     </div>
   );
   );
-}
-PageItemLower.propTypes = {
-  page: PropTypes.any,
-};
-function LargePageItem({ page }) {
+});
+PageItemLower.displayName = 'PageItemLower';
+
+
+const LargePageItem = memo(({ page }: PageItemProps): JSX.Element => {
   const dPagePath = new DevidedPagePath(page.path, false, true);
   const dPagePath = new DevidedPagePath(page.path, false, true);
   const linkedPagePathFormer = new LinkedPagePath(dPagePath.former);
   const linkedPagePathFormer = new LinkedPagePath(dPagePath.former);
   const linkedPagePathLatter = new LinkedPagePath(dPagePath.latter);
   const linkedPagePathLatter = new LinkedPagePath(dPagePath.latter);
@@ -56,10 +62,15 @@ function LargePageItem({ page }) {
 
 
   const tags = page.tags;
   const tags = page.tags;
   const tagElements = tags.map((tag) => {
   const tagElements = tags.map((tag) => {
+    if (!isPopulated(tag)) {
+      return <></>;
+    }
     return (
     return (
-      <a key={tag.name} href={`/_search?q=tag:${tag.name}`} className="grw-tag-label badge badge-secondary mr-2 small">
-        {tag.name}
-      </a>
+      <Link key={tag.name} href={`/_search?q=tag:${tag.name}`}>
+        <a className="grw-tag-label badge badge-secondary mr-2 small">
+          {tag.name}
+        </a>
+      </Link>
     );
     );
   });
   });
 
 
@@ -81,12 +92,11 @@ function LargePageItem({ page }) {
       </div>
       </div>
     </li>
     </li>
   );
   );
-}
-LargePageItem.propTypes = {
-  page: PropTypes.any,
-};
+});
+LargePageItem.displayName = 'LargePageItem';
 
 
-function SmallPageItem({ page }) {
+
+const SmallPageItem = memo(({ page }: PageItemProps): JSX.Element => {
   const dPagePath = new DevidedPagePath(page.path, false, true);
   const dPagePath = new DevidedPagePath(page.path, false, true);
   const linkedPagePathFormer = new LinkedPagePath(dPagePath.former);
   const linkedPagePathFormer = new LinkedPagePath(dPagePath.former);
   const linkedPagePathLatter = new LinkedPagePath(dPagePath.latter);
   const linkedPagePathLatter = new LinkedPagePath(dPagePath.latter);
@@ -116,10 +126,8 @@ function SmallPageItem({ page }) {
       </div>
       </div>
     </li>
     </li>
   );
   );
-}
-SmallPageItem.propTypes = {
-  page: PropTypes.any,
-};
+});
+SmallPageItem.displayName = 'SmallPageItem';
 
 
 const RecentChanges = (): JSX.Element => {
 const RecentChanges = (): JSX.Element => {
   const PER_PAGE = 20;
   const PER_PAGE = 20;