Просмотр исходного кода

refactor CopyDropdown

use child node for dropdown toggle contents
Yuki Takei 5 лет назад
Родитель
Сommit
8535f05447

+ 12 - 5
src/client/js/components/Navbar/GrowiSubNavigation.jsx

@@ -12,7 +12,7 @@ import AppContainer from '../../services/AppContainer';
 import NavigationContainer from '../../services/NavigationContainer';
 import PageContainer from '../../services/PageContainer';
 
-import RevisionPathControls from '../Page/RevisionPathControls';
+import CopyDropdown from '../Page/CopyDropdown';
 import TagLabels from '../Page/TagLabels';
 import SubnavButtons from './SubNavButtons';
 import PageEditorModeManager from './PageEditorModeManager';
@@ -22,7 +22,7 @@ import DrawerToggler from './DrawerToggler';
 
 const PagePathNav = ({
   // eslint-disable-next-line react/prop-types
-  pageId, pagePath, isEditorMode,
+  pageId, pagePath, isEditorMode, isCompactMode,
 }) => {
 
   const dPagePath = new DevidedPagePath(pagePath, false, true);
@@ -43,16 +43,23 @@ const PagePathNav = ({
     latterLink = <PagePathHierarchicalLink linkedPagePath={linkedPagePathLatter} basePath={dPagePath.former} />;
   }
 
+  const copyDropdownId = `copydropdown${isCompactMode ? '-subnav-compact' : ''}-${pageId}`;
+  const copyDropdownToggleClassName = 'd-block text-muted bg-transparent btn-copy border-0';
+
   return (
     <div className="grw-page-path-nav">
       {formerLink}
       <span className="d-flex align-items-center">
         <h1 className="m-0">{latterLink}</h1>
         <div className="mx-2">
-          <RevisionPathControls
+          <CopyDropdown
             pageId={pageId}
             pagePath={pagePath}
-          />
+            dropdownToggleId={copyDropdownId}
+            dropdownToggleClassName={copyDropdownToggleClassName}
+          >
+            <i className="ti-clipboard"></i>
+          </CopyDropdown>
         </div>
       </span>
     </div>
@@ -94,7 +101,7 @@ const GrowiSubNavigation = (props) => {
               <TagLabels editorMode={editorMode} />
             </div>
           ) }
-          <PagePathNav pageId={pageId} pagePath={path} isEditorMode={isEditorMode} />
+          <PagePathNav pageId={pageId} pagePath={path} isEditorMode={isEditorMode} isCompactMode />
         </div>
       </div>
 

+ 23 - 39
src/client/js/components/Page/CopyDropdown.jsx

@@ -37,12 +37,6 @@ const CopyDropdown = (props) => {
   const [tooltipOpen, setTooltipOpen] = useState(false);
   const [isParamsAppended, setParamsAppended] = useState(true);
 
-  // states for labels and URLs
-  const [pagePathUrl, setPagePathUrl] = useState();
-  const [permalink, setParmalink] = useState();
-  const [markdownLink, setMarkdownLink] = useState();
-
-
   /*
    * functions to construct labels and URLs
    */
@@ -63,12 +57,12 @@ const CopyDropdown = (props) => {
     return decodeURI(`${pagePath}${getUriParams()}`);
   }, [props, getUriParams]);
 
-  const generatePagePathUrl = useCallback(() => {
+  const pagePathUrl = useMemo(() => {
     const { origin } = window.location;
     return `${origin}${encodeSpaces(pagePathWithParams)}`;
   }, [pagePathWithParams]);
 
-  const generatePermalink = useCallback(() => {
+  const permalink = useMemo(() => {
     const { origin } = window.location;
     const { pageId, isShareLinkMode } = props;
 
@@ -82,33 +76,27 @@ const CopyDropdown = (props) => {
     return encodeSpaces(decodeURI(`${origin}/${pageId}${getUriParams()}`));
   }, [props, getUriParams]);
 
-  const generateMarkdownLink = useCallback(() => {
+  const markdownLink = useMemo(() => {
     const { pagePath } = props;
 
     const label = decodeURI(`${pagePath}${getUriParams()}`);
-    const permalink = generatePermalink();
+    // const permalink = generatePermalink();
 
     return `[${label}](${permalink})`;
-  }, [props, getUriParams, generatePermalink]);
+  }, [props, getUriParams, permalink]);
 
 
   /**
-   * dropdown control
+   * control
    */
-  const toggle = useCallback(() => {
-    // regenerate labels and URLs
-    if (!dropdownOpen) {
-      setPagePathUrl(generatePagePathUrl());
-      setParmalink(generatePermalink());
-      setMarkdownLink(generateMarkdownLink());
-    }
-
+  const toggleDropdown = useCallback(() => {
     setDropdownOpen(!dropdownOpen);
-  }, [dropdownOpen, generatePagePathUrl, generatePermalink, generateMarkdownLink]);
+  }, [dropdownOpen]);
+
+  const toggleAppendParams = useCallback(() => {
+    setParamsAppended(!isParamsAppended);
+  }, [isParamsAppended]);
 
-  /**
-   * tooltip control
-   */
   const showToolTip = useCallback(() => {
     setTooltipOpen(true);
     setTimeout(() => {
@@ -121,26 +109,19 @@ const CopyDropdown = (props) => {
    * render
    */
   const {
-    t, pageId, isShareLinkMode, buttonStyle,
+    t, dropdownToggleId, pageId, dropdownToggleClassName, children,
   } = props;
 
-  const copyTarget = isShareLinkMode ? `copyShareLink${pageId}` : 'copyPagePathDropdown';
-  const dropdownToggleStyle = isShareLinkMode ? 'btn btn-secondary' : 'd-block text-muted bg-transparent btn-copy border-0';
-
-  const customSwitchForParamsId = `customSwitchForParams_${pageId}`;
-
+  const customSwitchForParamsId = `customSwitchForParams_${dropdownToggleId}`;
 
   return (
     <>
-      <Dropdown id={copyTarget} className="grw-copy-dropdown" isOpen={dropdownOpen} toggle={toggle}>
+      <Dropdown className="grw-copy-dropdown" isOpen={dropdownOpen} toggle={toggleDropdown}>
         <DropdownToggle
           caret
-          className={dropdownToggleStyle}
-          style={buttonStyle}
+          className={dropdownToggleClassName}
         >
-          { isShareLinkMode ? (
-            <>Copy Link</>
-          ) : (<i className="ti-clipboard"></i>)}
+          <span id={dropdownToggleId}>{children}</span>
         </DropdownToggle>
 
         <DropdownMenu positionFixed modifiers={{ preventOverflow: { boundariesElement: null } }}>
@@ -155,7 +136,7 @@ const CopyDropdown = (props) => {
                 id={customSwitchForParamsId}
                 className="custom-control-input"
                 checked={isParamsAppended}
-                onChange={() => setParamsAppended(!isParamsAppended)}
+                onChange={toggleAppendParams}
               />
               <label className="custom-control-label small" htmlFor={customSwitchForParamsId}>Append params</label>
             </div>
@@ -214,7 +195,7 @@ const CopyDropdown = (props) => {
 
       </Dropdown>
 
-      <Tooltip placement="bottom" isOpen={tooltipOpen} target={copyTarget} fade={false}>
+      <Tooltip placement="bottom" isOpen={tooltipOpen} target={dropdownToggleId} fade={false}>
         copied!
       </Tooltip>
     </>
@@ -224,9 +205,12 @@ const CopyDropdown = (props) => {
 CopyDropdown.propTypes = {
   t: PropTypes.func.isRequired, // i18next
 
+  children: PropTypes.node.isRequired,
+  dropdownToggleId: PropTypes.string.isRequired,
   pagePath: PropTypes.string.isRequired,
+
   pageId: PropTypes.string,
-  buttonStyle: PropTypes.object,
+  dropdownToggleClassName: PropTypes.string,
   isShareLinkMode: PropTypes.bool,
 };
 

+ 0 - 30
src/client/js/components/Page/RevisionPathControls.jsx

@@ -1,30 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import CopyDropdown from './CopyDropdown';
-
-const RevisionPathControls = (props) => {
-  // define styles
-  const buttonStyle = {
-    marginLeft: '0.5em',
-    padding: '0 2px',
-  };
-
-  const {
-    pagePath, pageId,
-  } = props;
-
-
-  return (
-    <>
-      <CopyDropdown pagePath={pagePath} pageId={pageId} buttonStyle={buttonStyle} />
-    </>
-  );
-};
-
-RevisionPathControls.propTypes = {
-  pagePath: PropTypes.string.isRequired,
-  pageId: PropTypes.string,
-};
-
-export default RevisionPathControls;

+ 8 - 1
src/client/js/components/ShareLink/ShareLinkList.jsx

@@ -28,7 +28,14 @@ const ShareLinkList = (props) => {
             <td>
               <div className="d-flex">
                 <span className="mr-auto my-auto">{shareLink._id}</span>
-                <CopyDropdown isShareLinkMode pagePath={shareLink.relatedPage.path} pageId={shareLink._id} />
+                <CopyDropdown
+                  pagePath={shareLink.relatedPage.path}
+                  dropdownToggleId={`copydropdown-${shareLink._id}`}
+                  pageId={shareLink._id}
+                  isShareLinkMode
+                >
+                  Copy Link
+                </CopyDropdown>
               </div>
             </td>
             {props.isAdmin && <td><a href={shareLink.relatedPage.path}>{shareLink.relatedPage.path}</a></td>}