Browse Source

Merge branch 'feat/switch-sidebar-content' into dev/4.0.x

Yuki Takei 6 years ago
parent
commit
fc82d21437

+ 71 - 59
src/client/js/components/Sidebar.jsx

@@ -1,74 +1,83 @@
 import React from 'react';
-// import PropTypes from 'prop-types';
+import PropTypes from 'prop-types';
 
 import { withTranslation } from 'react-i18next';
 
-import BacklogIcon from '@atlaskit/icon/glyph/backlog';
-import BoardIcon from '@atlaskit/icon/glyph/board';
-import GraphLineIcon from '@atlaskit/icon/glyph/graph-line';
-import ShortcutIcon from '@atlaskit/icon/glyph/shortcut';
-import { JiraWordmark } from '@atlaskit/logo';
-
 import {
-  GroupHeading,
-  HeaderSection,
-  Item,
+  withNavigationUIController,
   LayoutManager,
-  MenuSection,
   NavigationProvider,
-  Separator,
-  Wordmark,
   ThemeProvider, modeGenerator,
 } from '@atlaskit/navigation-next';
 
+import Drawer from '@atlaskit/drawer';
+
 import { createSubscribedElement } from './UnstatedUtils';
 import AppContainer from '../services/AppContainer';
 
+import GrowiLogo from './GrowiLogo';
 import SidebarNav from './Sidebar/SidebarNav';
+import History from './Sidebar/History';
+import CustomSidebar from './Sidebar/CustomSidebar';
 
 class Sidebar extends React.Component {
 
   static propTypes = {
+    navigationUIController: PropTypes.any.isRequired,
   };
 
   state = {
+    currentContentsId: 'custom',
+    isDrawerOpen: false,
   };
 
-  renderSidebarContents = () => (
+  openDrawer = () => this.setState({ isDrawerOpen: true });
+
+  closeDrawer = () => this.setState({ isDrawerOpen: false });
+
+  itemSelectedHandler = (contentsId) => {
+    const { navigationUIController } = this.props;
+    const { currentContentsId } = this.state;
+
+    // already selected
+    if (currentContentsId === contentsId) {
+      navigationUIController.toggleCollapse();
+    }
+    // switch and expand
+    else {
+      this.setState({ currentContentsId: contentsId });
+      navigationUIController.expand();
+    }
+
+    // if (contentsId === 'drawer') {
+    //   this.openDrawer();
+    // }
+  }
+
+  renderGlobalNavigation = () => (
     <>
-      <HeaderSection>
-        { () => (
-          <div className="grw-product-nav-header">
-            <Wordmark wordmark={JiraWordmark} />
-          </div>
-        ) }
-      </HeaderSection>
-      <MenuSection>
-        { () => (
-          <div className="grw-product-nav-menu">
-            <Item
-              before={BacklogIcon}
-              text="Backlog"
-              isSelected
-            />
-            <Item
-              before={BoardIcon}
-              text="Active sprints"
-            />
-            <Item
-              before={GraphLineIcon}
-              text="Reports"
-            />
-            <Separator />
-            <GroupHeading>Shortcuts</GroupHeading>
-            <Item before={ShortcutIcon} text="Project space" />
-            <Item before={ShortcutIcon} text="Looooooooooooooooooooooooooooooong Menu" />
-          </div>
-        ) }
-      </MenuSection>
+      <div className="grw-logo">
+        <a href="/"><GrowiLogo /></a>
+      </div>
+      <SidebarNav currentContentsId={this.state.currentContentsId} onItemSelected={this.itemSelectedHandler} />
+      <Drawer onClose={this.closeDrawer} isOpen={this.state.isDrawerOpen} width="wide">
+        <code>Drawer contents</code>
+      </Drawer>
     </>
   );
 
+  renderSidebarContents = () => {
+    let contents = <CustomSidebar></CustomSidebar>;
+
+    switch (this.state.currentContentsId) {
+      case 'history':
+        contents = <History></History>;
+        break;
+    }
+
+    return contents;
+  }
+
   render() {
     return (
       <ThemeProvider
@@ -80,31 +89,34 @@ class Sidebar extends React.Component {
           }),
         })}
       >
-        <NavigationProvider>
-          <LayoutManager
-            globalNavigation={SidebarNav}
-            productNavigation={() => null}
-            containerNavigation={this.renderSidebarContents}
-            experimental_flyoutOnHover
-            experimental_alternateFlyoutBehaviour
-            // experimental_fullWidthFlyout
-            shouldHideGlobalNavShadow
-            showContextualNavigation
-          >
-          </LayoutManager>
-        </NavigationProvider>
+        <LayoutManager
+          globalNavigation={this.renderGlobalNavigation}
+          productNavigation={() => null}
+          containerNavigation={this.renderSidebarContents}
+          experimental_hideNavVisuallyOnCollapse
+          experimental_flyoutOnHover
+          experimental_alternateFlyoutBehaviour
+          // experimental_fullWidthFlyout
+          shouldHideGlobalNavShadow
+          showContextualNavigation
+        >
+        </LayoutManager>
       </ThemeProvider>
     );
   }
 
 }
 
+const SidebarWithNavigationUI = withNavigationUIController(Sidebar);
+const SidebarWithNavigationUIAndTranslation = withTranslation()(SidebarWithNavigationUI);
 
 /**
  * Wrapper component for using unstated
  */
 const SidebarWrapper = (props) => {
-  return createSubscribedElement(Sidebar, props, [AppContainer]);
+  return createSubscribedElement(SidebarWithNavigationUIAndTranslation, props, [AppContainer]);
 };
 
-export default withTranslation()(SidebarWrapper);
+export default () => (
+  <NavigationProvider><SidebarWrapper /></NavigationProvider>
+);

+ 53 - 0
src/client/js/components/Sidebar/CustomSidebar.jsx

@@ -0,0 +1,53 @@
+import React from 'react';
+// import PropTypes from 'prop-types';
+
+import { withTranslation } from 'react-i18next';
+
+import { JiraWordmark } from '@atlaskit/logo';
+
+import {
+  HeaderSection,
+  MenuSection,
+  Wordmark,
+} from '@atlaskit/navigation-next';
+
+import { createSubscribedElement } from '../UnstatedUtils';
+import AppContainer from '../../services/AppContainer';
+
+class CustomSidebar extends React.Component {
+
+  static propTypes = {
+  };
+
+  state = {
+  };
+
+  render() {
+    return (
+      <>
+        <HeaderSection>
+          { () => (
+            <div className="grw-product-nav-header">
+              <Wordmark wordmark={JiraWordmark} />
+            </div>
+          ) }
+        </HeaderSection>
+        <MenuSection>
+          { () => (
+            <span>(TBD) CustomSidebar Contents</span>
+          ) }
+        </MenuSection>
+      </>
+    );
+  }
+
+}
+
+/**
+ * Wrapper component for using unstated
+ */
+const CustomSidebarWrapper = (props) => {
+  return createSubscribedElement(CustomSidebar, props, [AppContainer]);
+};
+
+export default withTranslation()(CustomSidebarWrapper);

+ 53 - 0
src/client/js/components/Sidebar/History.jsx

@@ -0,0 +1,53 @@
+import React from 'react';
+// import PropTypes from 'prop-types';
+
+import { withTranslation } from 'react-i18next';
+
+import { JiraWordmark } from '@atlaskit/logo';
+
+import {
+  HeaderSection,
+  MenuSection,
+  Wordmark,
+} from '@atlaskit/navigation-next';
+
+import { createSubscribedElement } from '../UnstatedUtils';
+import AppContainer from '../../services/AppContainer';
+
+class History extends React.Component {
+
+  static propTypes = {
+  };
+
+  state = {
+  };
+
+  render() {
+    return (
+      <>
+        <HeaderSection>
+          { () => (
+            <div className="grw-product-nav-header">
+              <Wordmark wordmark={JiraWordmark} />
+            </div>
+          ) }
+        </HeaderSection>
+        <MenuSection>
+          { () => (
+            <span>(TBD) History Contents</span>
+          ) }
+        </MenuSection>
+      </>
+    );
+  }
+
+}
+
+/**
+ * Wrapper component for using unstated
+ */
+const HistoryWrapper = (props) => {
+  return createSubscribedElement(History, props, [AppContainer]);
+};
+
+export default withTranslation()(HistoryWrapper);

+ 26 - 25
src/client/js/components/Sidebar/SidebarNav.jsx

@@ -1,5 +1,5 @@
 import React from 'react';
-// import PropTypes from 'prop-types';
+import PropTypes from 'prop-types';
 
 import { withTranslation } from 'react-i18next';
 
@@ -9,46 +9,47 @@ import TrayIcon from '@atlaskit/icon/glyph/tray';
 import {
   GlobalNav,
 } from '@atlaskit/navigation-next';
-import Drawer from '@atlaskit/drawer';
 
 import { createSubscribedElement } from '../UnstatedUtils';
 import AppContainer from '../../services/AppContainer';
 
-import GrowiLogo from '../GrowiLogo';
 
 class SidebarNav extends React.Component {
 
-  propTypes = {
+  static propTypes = {
+    currentContentsId: PropTypes.string,
+    onItemSelected: PropTypes.func,
   };
 
   state = {
-    isDrawerOpen: false,
   };
 
-  openDrawer = () => this.setState({ isDrawerOpen: true });
+  itemSelectedHandler = (contentsId) => {
+    const { onItemSelected } = this.props;
+    if (onItemSelected != null) {
+      onItemSelected(contentsId);
+    }
+  }
 
-  closeDrawer = () => this.setState({ isDrawerOpen: false });
+  generateSidebarItemObj(id, icon, label) {
+    return {
+      id,
+      icon,
+      label,
+      isSelected: this.props.currentContentsId === id,
+      onClick: () => this.itemSelectedHandler(id),
+    };
+  }
 
   render() {
-    const { isDrawerOpen } = this.state;
     return (
-      <>
-        <div className="grw-logo">
-          <GrowiLogo />
-        </div>
-        <GlobalNav
-          primaryItems={[
-            { id: 'create', icon: EditIcon, label: 'Create' },
-            {
-              id: 'drawer', icon: TrayIcon, label: 'Drawer', onClick: this.openDrawer,
-            },
-          ]}
-          secondaryItems={[]}
-        />
-        <Drawer onClose={this.closeDrawer} isOpen={isDrawerOpen} width="wide">
-          <code>Drawer contents</code>
-        </Drawer>
-      </>
+      <GlobalNav
+        primaryItems={[
+          this.generateSidebarItemObj('custom', EditIcon, 'Custom Sidebar'),
+          this.generateSidebarItemObj('history', TrayIcon, 'History'),
+        ]}
+        secondaryItems={[]}
+      />
     );
   }