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

Merge pull request #2633 from weseek/imprv/gw3301-add-attachment-contents-new

Imprv/gw3301 add attachment contents new
Yuki Takei 5 лет назад
Родитель
Сommit
0f3497da0e

+ 24 - 23
src/client/js/components/PageAccessoriesModal.jsx

@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 
 import {
-  Modal, ModalBody, Nav, NavItem, NavLink, TabContent,
+  Modal, ModalBody, Nav, NavItem, NavLink, TabContent, TabPane,
 } from 'reactstrap';
 
 import { withTranslation } from 'react-i18next';
@@ -13,10 +13,13 @@ import RecentChangesIcon from './Icons/RecentChangesIcon';
 import AttachmentIcon from './Icons/AttachmentIcon';
 
 import { withUnstatedContainers } from './UnstatedUtils';
-import PageContainer from '../services/PageContainer';
+import PageAccessoriesContainer from '../services/PageAccessoriesContainer';
+import PageAttachment from './PageAttachment';
 
 const PageAccessoriesModal = (props) => {
-  const { t } = props;
+  const { t, pageAccessoriesContainer } = props;
+  const { switchActiveTab } = pageAccessoriesContainer;
+  const { activeTab } = pageAccessoriesContainer.state;
 
   function closeModalHandler() {
     if (props.onClose == null) {
@@ -25,13 +28,6 @@ const PageAccessoriesModal = (props) => {
     props.onClose();
   }
 
-  function switchTabHandler(clickedTab) {
-    if (props.onSwitch == null) {
-      return;
-    }
-    props.onSwitch(clickedTab);
-  }
-
   return (
     <React.Fragment>
       <Modal
@@ -42,40 +38,46 @@ const PageAccessoriesModal = (props) => {
       >
         <ModalBody>
           <Nav className="nav-title border-bottom">
-            <NavItem className={`nav-link ${props.activeTab === 'pageList' && 'active'}`}>
+            <NavItem type="button" className={`nav-link ${activeTab === 'pagelist' && 'active active-border'}`}>
               <NavLink
-                onClick={() => { switchTabHandler('pageList') }}
+                onClick={() => { switchActiveTab('pagelist') }}
               >
                 <PageListIcon />
                 { t('page_list') }
               </NavLink>
             </NavItem>
-            <NavItem className={`nav-link ${props.activeTab === 'timeLine' && 'active'}`}>
+            <NavItem type="button" className={`nav-link ${activeTab === 'timeline' && 'active active-border'}`}>
               <NavLink
-                onClick={() => { switchTabHandler('timeLine') }}
+                onClick={() => { switchActiveTab('timeline') }}
               >
                 <TimeLineIcon />
                 { t('Timeline View') }
               </NavLink>
             </NavItem>
-            <NavItem className={`nav-link ${props.activeTab === 'recentChanges' && 'active'}`}>
+            <NavItem type="button" className={`nav-link ${activeTab === 'recent-changes' && 'active active-border'}`}>
               <NavLink
-                onClick={() => { switchTabHandler('recentChanges') }}
+                onClick={() => { switchActiveTab('recent-changes') }}
               >
                 <RecentChangesIcon />
                 { t('History') }
               </NavLink>
             </NavItem>
-            <NavItem className={`nav-link ${props.activeTab === 'attachment' && 'active'}`}>
+            <NavItem type="button" className={`nav-link ${activeTab === 'attachment' && 'active active-border'}`}>
               <NavLink
-                onClick={() => { switchTabHandler('attachment') }}
+                onClick={() => { switchActiveTab('attachment') }}
               >
                 <AttachmentIcon />
                 { t('attachment_data') }
               </NavLink>
             </NavItem>
           </Nav>
-          <TabContent>
+          <TabContent activeTab={activeTab}>
+            <TabPane tabId="pagelist"></TabPane>
+            <TabPane tabId="timeline"></TabPane>
+            <TabPane tabId="recent-changes"></TabPane>
+            <TabPane tabId="attachment" className="p-4">
+              {pageAccessoriesContainer.state.activeComponents.has('attachment') && <PageAttachment /> }
+            </TabPane>
           </TabContent>
         </ModalBody>
       </Modal>
@@ -87,17 +89,16 @@ const PageAccessoriesModal = (props) => {
 /**
  * Wrapper component for using unstated
  */
-const PageAccessoriesModalWrapper = withUnstatedContainers(PageAccessoriesModal, [PageContainer]);
+const PageAccessoriesModalWrapper = withUnstatedContainers(PageAccessoriesModal, [PageAccessoriesContainer]);
 
 
 PageAccessoriesModal.propTypes = {
   t: PropTypes.func.isRequired, //  i18next
-  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+  // pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+  pageAccessoriesContainer: PropTypes.instanceOf(PageAccessoriesContainer).isRequired,
 
   isOpen: PropTypes.bool.isRequired,
   onClose: PropTypes.func,
-  activeTab: PropTypes.string.isRequired,
-  onSwitch: PropTypes.func,
 };
 
 export default withTranslation()(PageAccessoriesModalWrapper);

+ 11 - 32
src/client/js/components/TopOfTableContents.jsx

@@ -1,9 +1,9 @@
-import React, { useState } from 'react';
+import React from 'react';
 import PropTypes from 'prop-types';
 
 import { withTranslation } from 'react-i18next';
 
-import PageContainer from '../services/PageContainer';
+import PageAccessoriesContainer from '../services/PageAccessoriesContainer';
 
 import PageListIcon from './Icons/PageListIcon';
 import TimeLineIcon from './Icons/TimeLineIcon';
@@ -15,35 +15,14 @@ import PageAccessoriesModal from './PageAccessoriesModal';
 import { withUnstatedContainers } from './UnstatedUtils';
 
 const TopOfTableContents = (props) => {
-
-  const [isPageAccessoriesModalShown, setIsPageAccessoriesModalShown] = useState(false);
-  const [activeTab, setActiveTab] = useState('');
-  // Prevent unnecessary rendering
-  const [activeComponents, setActiveComponents] = useState(new Set(['']));
-
-  function openPageAccessoriesModal(activeTab) {
-    setIsPageAccessoriesModalShown(true);
-    setActiveTab(activeTab);
-  }
-
-  function switchActiveTab(clickedTab) {
-    activeComponents.add(clickedTab);
-    setActiveComponents(activeComponents);
-    setActiveTab(clickedTab);
-  }
-
-  function closePageAccessoriesModal() {
-    setIsPageAccessoriesModalShown(false);
-  }
+  const { pageAccessoriesContainer } = props;
 
   function renderModal() {
     return (
       <>
         <PageAccessoriesModal
-          isOpen={isPageAccessoriesModalShown}
-          onClose={closePageAccessoriesModal}
-          activeTab={activeTab}
-          onSwitch={switchActiveTab}
+          isOpen={pageAccessoriesContainer.state.isPageAccessoriesModalShown}
+          onClose={pageAccessoriesContainer.closePageAccessoriesModal}
         />
       </>
     );
@@ -52,19 +31,19 @@ const TopOfTableContents = (props) => {
   return (
     <>
       <div className="top-of-table-contents d-flex align-items-end pb-1">
-        <button type="button" className="bg-transparent border-0" onClick={() => openPageAccessoriesModal('pageList')}>
+        <button type="button" className="bg-transparent border-0" onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('pagelist')}>
           <PageListIcon />
         </button>
 
-        <button type="button" className="bg-transparent border-0 active" onClick={() => openPageAccessoriesModal('timeLine')}>
+        <button type="button" className="bg-transparent border-0 active" onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('timeline')}>
           <TimeLineIcon />
         </button>
 
-        <button type="button" className="bg-transparent border-0" onClick={() => openPageAccessoriesModal('recentChanges')}>
+        <button type="button" className="bg-transparent border-0" onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('recent-changes')}>
           <RecentChangesIcon />
         </button>
 
-        <button type="button" className="bg-transparent border-0" onClick={() => openPageAccessoriesModal('attachment')}>
+        <button type="button" className="bg-transparent border-0" onClick={() => pageAccessoriesContainer.openPageAccessoriesModal('attachment')}>
           <AttachmentIcon />
         </button>
         {/* [TODO: setting Footprints' icon by GW-3308] */}
@@ -82,10 +61,10 @@ const TopOfTableContents = (props) => {
 /**
  * Wrapper component for using unstated
  */
-const TopOfTableContentsWrapper = withUnstatedContainers(TopOfTableContents, [PageContainer]);
+const TopOfTableContentsWrapper = withUnstatedContainers(TopOfTableContents, [PageAccessoriesContainer]);
 
 TopOfTableContents.propTypes = {
-  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+  pageAccessoriesContainer: PropTypes.instanceOf(PageAccessoriesContainer).isRequired,
 };
 
 export default withTranslation()(TopOfTableContentsWrapper);

+ 53 - 0
src/client/js/services/PageAccessoriesContainer.js

@@ -0,0 +1,53 @@
+import { Container } from 'unstated';
+
+/**
+ * Service container related to options for Application
+ * @extends {Container} unstated Container
+ */
+
+export default class PageAccessoriesContainer extends Container {
+
+  constructor(appContainer) {
+    super();
+
+    this.appContainer = appContainer;
+
+    this.state = {
+      isPageAccessoriesModalShown: false,
+      activeTab: '',
+      // Prevent unnecessary rendering
+      activeComponents: new Set(['']),
+    };
+    this.openPageAccessoriesModal = this.openPageAccessoriesModal.bind(this);
+    this.closePageAccessoriesModal = this.closePageAccessoriesModal.bind(this);
+    this.switchActiveTab = this.switchActiveTab.bind(this);
+  }
+
+  /**
+   * Workaround for the mangling in production build to break constructor.name
+   */
+  static getClassName() {
+    return 'PageAccessoriesContainer';
+  }
+
+
+  openPageAccessoriesModal(activeTab) {
+    this.setState({
+      isPageAccessoriesModalShown: true,
+    });
+    this.switchActiveTab(activeTab);
+  }
+
+  closePageAccessoriesModal() {
+    this.setState({
+      isPageAccessoriesModalShown: false,
+    });
+  }
+
+  switchActiveTab(activeTab) {
+    this.setState({
+      activeTab, activeComponents: this.state.activeComponents.add(activeTab),
+    });
+  }
+
+}

+ 1 - 1
src/client/styles/scss/theme/_apply-colors.scss

@@ -273,7 +273,7 @@ pre:not(.hljs):not(.CodeMirror-line) {
   .table-top-icon {
     fill: $color-link;
   }
-  .active {
+  .active-border {
     border-bottom: 2px solid $color-link;
   }
 }