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

Merge pull request #3010 from weseek/fix/gw-4309-refactor-table-of-contents

Fix/gw 4309 refactor table of contents
Yuki Takei 5 лет назад
Родитель
Сommit
6f77db18ec

+ 3 - 1
src/client/js/app.jsx

@@ -29,6 +29,7 @@ import BookmarkList from './components/PageList/BookmarkList';
 import SeenUserList from './components/User/SeenUserList';
 import LikerList from './components/User/LikerList';
 import TableOfContents from './components/TableOfContents';
+import PageAccessories from './components/PageAccessories';
 import UserInfo from './components/User/UserInfo';
 import Fab from './components/Fab';
 
@@ -107,7 +108,8 @@ if (pageContainer.state.pageId != null) {
     'page-comments-list': <PageComments />,
     'page-comment-write': <CommentEditorLazyRenderer />,
     'page-management': <PageManagement />,
-    'revision-toc': <TableOfContents isGuestUserMode={appContainer.currentUser == null} />,
+    'page-accessories': <PageAccessories isGuestUserMode={appContainer.currentUser == null} />,
+    'revision-toc': <TableOfContents />,
     'seen-user-list': <SeenUserList />,
     'liker-list': <LikerList />,
 

+ 35 - 0
src/client/js/components/PageAccessories.jsx

@@ -0,0 +1,35 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import PageAccessoriesModalControl from './PageAccessoriesModalControl';
+import PageAccessoriesModal from './PageAccessoriesModal';
+
+import { withUnstatedContainers } from './UnstatedUtils';
+import PageAccessoriesContainer from '../services/PageAccessoriesContainer';
+
+const PageAccessories = (props) => {
+  const { pageAccessoriesContainer, isGuestUserMode } = props;
+
+  return (
+    <>
+      <PageAccessoriesModalControl isGuestUserMode={isGuestUserMode} />
+      <PageAccessoriesModal
+        isGuestUserMode={isGuestUserMode}
+        isOpen={pageAccessoriesContainer.state.isPageAccessoriesModalShown}
+        onClose={pageAccessoriesContainer.closePageAccessoriesModal}
+      />
+    </>
+  );
+};
+/**
+ * Wrapper component for using unstated
+ */
+const PageAccessoriesWrapper = withUnstatedContainers(PageAccessories, [PageAccessoriesContainer]);
+
+PageAccessories.propTypes = {
+  pageAccessoriesContainer: PropTypes.instanceOf(PageAccessoriesContainer).isRequired,
+
+  isGuestUserMode: PropTypes.bool.isRequired,
+};
+
+export default PageAccessoriesWrapper;

+ 91 - 0
src/client/js/components/PageAccessoriesModalControl.jsx

@@ -0,0 +1,91 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { withTranslation } from 'react-i18next';
+
+import { UncontrolledTooltip } from 'reactstrap';
+import PageAccessoriesContainer from '../services/PageAccessoriesContainer';
+
+import PageListIcon from './Icons/PageListIcon';
+import TimeLineIcon from './Icons/TimeLineIcon';
+import HistoryIcon from './Icons/HistoryIcon';
+import AttachmentIcon from './Icons/AttachmentIcon';
+import ShareLinkIcon from './Icons/ShareLinkIcon';
+
+import { withUnstatedContainers } from './UnstatedUtils';
+
+const PageAccessoriesModalControl = (props) => {
+  const { t, pageAccessoriesContainer, isGuestUserMode } = props;
+
+  return (
+    <div className="top-of-table-contents d-flex align-items-end pb-1">
+      <button
+        type="button"
+        className="btn btn-link grw-btn-top-of-table"
+        onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('pagelist')}
+      >
+        <PageListIcon />
+      </button>
+
+      <button
+        type="button"
+        className="btn btn-link grw-btn-top-of-table"
+        onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('timeline')}
+      >
+        <TimeLineIcon />
+      </button>
+
+      <button
+        type="button"
+        className="btn btn-link grw-btn-top-of-table"
+        onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('pageHistory')}
+      >
+        <HistoryIcon />
+      </button>
+
+      <button
+        type="button"
+        className="btn btn-link grw-btn-top-of-table"
+        onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('attachment')}
+      >
+        <AttachmentIcon />
+      </button>
+
+      <div id="shareLink-btn-wrapper-for-tooltip">
+        <button
+          type="button"
+          className={`btn btn-link grw-btn-top-of-table ${isGuestUserMode && 'disabled'}`}
+          onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('shareLink')}
+        >
+          <ShareLinkIcon />
+        </button>
+      </div>
+      {isGuestUserMode && (
+        <UncontrolledTooltip placement="top" target="shareLink-btn-wrapper-for-tooltip" fade={false}>
+          {t('Not available for guest')}
+        </UncontrolledTooltip>
+      )}
+      <div
+        id="seen-user-list"
+        data-user-ids-str="{{ page.seenUsers|slice(-15)|default([])|reverse|join(',') }}"
+        data-sum-of-seen-users="{{ page.seenUsers.length|default(0) }}"
+        className="grw-seen-user-list ml-1 pl-1"
+      >
+      </div>
+    </div>
+  );
+};
+/**
+ * Wrapper component for using unstated
+ */
+const PageAccessoriesModalControlWrapper = withUnstatedContainers(PageAccessoriesModalControl, [PageAccessoriesContainer]);
+
+PageAccessoriesModalControl.propTypes = {
+  t: PropTypes.func.isRequired, //  i18next
+
+  pageAccessoriesContainer: PropTypes.instanceOf(PageAccessoriesContainer).isRequired,
+
+  isGuestUserMode: PropTypes.bool.isRequired,
+};
+
+export default withTranslation()(PageAccessoriesModalControlWrapper);

+ 2 - 5
src/client/js/components/TableOfContents.jsx

@@ -8,7 +8,7 @@ import PageContainer from '../services/PageContainer';
 import NavigationContainer from '../services/NavigationContainer';
 
 import { withUnstatedContainers } from './UnstatedUtils';
-import TopOfTableContents from './TopOfTableContents';
+
 import StickyStretchableScroller from './StickyStretchableScroller';
 
 import RecentlyCreatedIcon from './Icons/RecentlyCreatedIcon';
@@ -23,7 +23,7 @@ const WIKI_HEADER_LINK = 120;
  */
 const TableOfContents = (props) => {
 
-  const { pageContainer, navigationContainer, isGuestUserMode } = props;
+  const { pageContainer, navigationContainer } = props;
   const { pageUser } = pageContainer.state;
   const isUserPage = pageUser != null;
 
@@ -54,7 +54,6 @@ const TableOfContents = (props) => {
 
   return (
     <>
-      <TopOfTableContents isGuestUserMode={isGuestUserMode} />
       <StickyStretchableScroller
         contentsElemSelector=".revision-toc .markdownIt-TOC"
         stickyElemSelector="#revision-toc"
@@ -103,8 +102,6 @@ const TableOfContentsWrapper = withUnstatedContainers(TableOfContents, [PageCont
 TableOfContents.propTypes = {
   pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
   navigationContainer: PropTypes.instanceOf(NavigationContainer).isRequired,
-
-  isGuestUserMode: PropTypes.bool.isRequired,
 };
 
 export default withTranslation()(TableOfContentsWrapper);

+ 0 - 106
src/client/js/components/TopOfTableContents.jsx

@@ -1,106 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import { withTranslation } from 'react-i18next';
-
-import { UncontrolledTooltip } from 'reactstrap';
-import PageAccessoriesContainer from '../services/PageAccessoriesContainer';
-
-import PageListIcon from './Icons/PageListIcon';
-import TimeLineIcon from './Icons/TimeLineIcon';
-import HistoryIcon from './Icons/HistoryIcon';
-import AttachmentIcon from './Icons/AttachmentIcon';
-import ShareLinkIcon from './Icons/ShareLinkIcon';
-
-import PageAccessoriesModal from './PageAccessoriesModal';
-
-import { withUnstatedContainers } from './UnstatedUtils';
-
-const TopOfTableContents = (props) => {
-  const { t, pageAccessoriesContainer, isGuestUserMode } = props;
-
-  function renderModal() {
-    return (
-      <PageAccessoriesModal
-        isGuestUserMode={isGuestUserMode}
-        isOpen={pageAccessoriesContainer.state.isPageAccessoriesModalShown}
-        onClose={pageAccessoriesContainer.closePageAccessoriesModal}
-      />
-    );
-  }
-
-  return (
-    <>
-      <div className="top-of-table-contents d-flex align-items-end pb-1">
-        <button
-          type="button"
-          className="btn btn-link grw-btn-top-of-table"
-          onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('pagelist')}
-        >
-          <PageListIcon />
-        </button>
-
-        <button
-          type="button"
-          className="btn btn-link grw-btn-top-of-table"
-          onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('timeline')}
-        >
-          <TimeLineIcon />
-        </button>
-
-        <button
-          type="button"
-          className="btn btn-link grw-btn-top-of-table"
-          onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('pageHistory')}
-        >
-          <HistoryIcon />
-        </button>
-
-        <button
-          type="button"
-          className="btn btn-link grw-btn-top-of-table"
-          onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('attachment')}
-        >
-          <AttachmentIcon />
-        </button>
-
-        <div id="shareLink-btn-wrapper-for-tooltip">
-          <button
-            type="button"
-            className={`btn btn-link grw-btn-top-of-table ${isGuestUserMode && 'disabled'}`}
-            onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('shareLink')}
-          >
-            <ShareLinkIcon />
-          </button>
-        </div>
-        {isGuestUserMode && (
-          <UncontrolledTooltip placement="top" target="shareLink-btn-wrapper-for-tooltip" fade={false}>
-            {t('Not available for guest')}
-          </UncontrolledTooltip>
-        )}
-        <div
-          id="seen-user-list"
-          data-user-ids-str="{{ page.seenUsers|slice(-15)|default([])|reverse|join(',') }}"
-          data-sum-of-seen-users="{{ page.seenUsers.length|default(0) }}"
-          className="grw-seen-user-list ml-1 pl-1"
-        >
-        </div>
-      </div>
-      {renderModal()}
-    </>
-  );
-};
-/**
- * Wrapper component for using unstated
- */
-const TopOfTableContentsWrapper = withUnstatedContainers(TopOfTableContents, [PageAccessoriesContainer]);
-
-TopOfTableContents.propTypes = {
-  t: PropTypes.func.isRequired, //  i18next
-
-  pageAccessoriesContainer: PropTypes.instanceOf(PageAccessoriesContainer).isRequired,
-
-  isGuestUserMode: PropTypes.bool.isRequired,
-};
-
-export default withTranslation()(TopOfTableContentsWrapper);

+ 1 - 1
src/client/styles/scss/_on-edit.scss

@@ -72,7 +72,7 @@ body.on-edit {
   }
 
   // hide unnecessary elements for growi layout
-  .revision-toc-container {
+  .side-contents-container {
     display: none !important;
   }
 

+ 2 - 1
src/server/views/widget/page_content.html

@@ -54,7 +54,8 @@
   <div id="page-editor-navbar-bottom-container" class="d-none d-edit-block"></div>
 </div>
 
-<div class="d-none d-lg-block revision-toc-container ml-4">
+<div class="d-none d-lg-block side-contents-container ml-4">
+  <div id="page-accessories" class="page-accessories"></div>
   <div id="revision-toc" class="revision-toc sps sps--abv" data-sps-offset="123">
     <div id="revision-toc-content" class="revision-toc-content"></div>
   </div>