label layout for graph name (#76)

* update graphname layout

* removed log

Co-authored-by: moon19960501@gmail.com <wenzhenhe1@gmail.com>
diff --git a/frontend/src/app/reducers.js b/frontend/src/app/reducers.js
index a9fef12..1c9e069 100644
--- a/frontend/src/app/reducers.js
+++ b/frontend/src/app/reducers.js
@@ -26,6 +26,7 @@
 import CypherReducer from '../features/cypher/CypherSlice';
 import AlertReducer from '../features/alert/AlertSlice';
 import EditorSlice from '../features/editor/EditorSlice';
+import LayoutSlice from '../features/layout/LayoutSlice';
 
 const rootReducer = combineReducers({
   navigator: MenuReducer,
@@ -36,6 +37,7 @@
   cypher: CypherReducer,
   alerts: AlertReducer,
   editor: EditorSlice,
+  layout: LayoutSlice,
 });
 
 export default rootReducer;
diff --git a/frontend/src/components/contents/containers/Editor.js b/frontend/src/components/contents/containers/Editor.js
index 4b1c3e4..1ef5e4a 100644
--- a/frontend/src/components/contents/containers/Editor.js
+++ b/frontend/src/components/contents/containers/Editor.js
@@ -25,6 +25,7 @@
 import { addCommandHistory, addCommandFavorites, setCommand } from '../../../features/editor/EditorSlice';
 import { toggleMenu } from '../../../features/menu/MenuSlice';
 import { getMetaData } from '../../../features/database/MetadataSlice';
+import { setLabel } from '../../../features/layout/LayoutSlice';
 
 import Editor from '../presentations/Editor';
 
@@ -34,6 +35,7 @@
   command: state.editor.command,
   isActive: state.navigator.isActive,
   activeRequests: state.cypher.activeRequests,
+  isLabel: state.layout.isLabel,
 });
 
 const mapDispatchToProps = {
@@ -48,6 +50,7 @@
   addCommandFavorites,
   toggleMenu,
   getMetaData,
+  setLabel,
 };
 
 export default connect(mapStateToProps, mapDispatchToProps)(Editor);
diff --git a/frontend/src/components/contents/presentations/Editor.jsx b/frontend/src/components/contents/presentations/Editor.jsx
index 9b50d8c..2ef22a8 100644
--- a/frontend/src/components/contents/presentations/Editor.jsx
+++ b/frontend/src/components/contents/presentations/Editor.jsx
@@ -22,7 +22,7 @@
 import uuid from 'react-uuid';
 import PropTypes from 'prop-types';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faTimesCircle } from '@fortawesome/free-solid-svg-icons';
+import { faTimesCircle, faToggleOff, faToggleOn } from '@fortawesome/free-solid-svg-icons';
 import AlertContainers from '../../alert/containers/AlertContainers';
 import CodeMirror from '../../editor/containers/CodeMirrorWapperContainer';
 import SideBarToggle from '../../editor/containers/SideBarMenuToggleContainer';
@@ -42,6 +42,8 @@
   executeCypherQuery,
   addCommandHistory,
   toggleMenu,
+  setLabel,
+  isLabel,
   // addCommandFavorites,
 }) => {
   const dispatch = useDispatch();
@@ -193,6 +195,17 @@
               >
                 <SideBarToggle isActive={isActive} />
               </button>
+              <button
+                className="frame-head-button btn btn-link"
+                type="button"
+                onClick={() => setLabel()}
+                title="Run Query"
+              >
+                <FontAwesomeIcon
+                  icon={isLabel ? faToggleOn : faToggleOff}
+                  size="2x"
+                />
+              </button>
             </div>
           </div>
         </div>
@@ -225,6 +238,8 @@
   executeCypherQuery: PropTypes.func.isRequired,
   addCommandHistory: PropTypes.func.isRequired,
   toggleMenu: PropTypes.func.isRequired,
+  setLabel: PropTypes.func.isRequired,
+  isLabel: PropTypes.bool.isRequired,
   // addCommandFavorites: PropTypes.func.isRequired,
 };
 
diff --git a/frontend/src/components/sidebar/containers/SidebarHome.js b/frontend/src/components/sidebar/containers/SidebarHome.js
index d414d3e..5336079 100644
--- a/frontend/src/components/sidebar/containers/SidebarHome.js
+++ b/frontend/src/components/sidebar/containers/SidebarHome.js
@@ -36,6 +36,7 @@
     status: state.metadata.status,
     role: currentGraphData.role,
     command: state.editor.command,
+    isLabel: state.layout.isLabel,
   };
 };
 
diff --git a/frontend/src/components/sidebar/presentations/SidebarHome.jsx b/frontend/src/components/sidebar/presentations/SidebarHome.jsx
index 0e0db2f..a96ee40 100644
--- a/frontend/src/components/sidebar/presentations/SidebarHome.jsx
+++ b/frontend/src/components/sidebar/presentations/SidebarHome.jsx
@@ -240,6 +240,70 @@
   setCommand: PropTypes.func.isRequired,
 };
 
+const GraphList = ({
+  graphs,
+  currentGraph,
+  changeCurrentGraph,
+  changeGraph,
+}) => {
+  let list;
+  if (graphs) {
+    list = graphs.map((item) => (
+      <GraphItems
+        key={uuid()}
+        graph={item[0]}
+        gid={item[1]}
+        currentGraph={currentGraph}
+        changeCurrentGraph={changeCurrentGraph}
+        changeGraph={changeGraph}
+      />
+    ));
+    return (
+      <div style={{
+        display: 'flex',
+        flexWrap: 'wrap',
+        height: '80px',
+        overflowY: 'auto',
+        marginTop: '12px',
+      }}
+      >
+        {list}
+      </div>
+    );
+  }
+
+  return null;
+};
+GraphList.propTypes = {
+  graphs: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)).isRequired,
+  currentGraph: PropTypes.string.isRequired,
+  changeCurrentGraph: PropTypes.func.isRequired,
+  changeGraph: PropTypes.func.isRequired,
+};
+
+const GraphItems = ({
+  graph,
+  gid,
+  currentGraph,
+  changeCurrentGraph,
+  changeGraph,
+}) => (
+  <button
+    type="button"
+    className={`${graph === currentGraph ? 'graph-item-clicked' : 'graph-item'}`}
+    onClick={() => { changeCurrentGraph({ id: gid }); changeGraph({ graphName: graph }); }}
+  >
+    {graph}
+  </button>
+);
+GraphItems.propTypes = {
+  graph: PropTypes.string.isRequired,
+  gid: PropTypes.string.isRequired,
+  currentGraph: PropTypes.string.isRequired,
+  changeCurrentGraph: PropTypes.func.isRequired,
+  changeGraph: PropTypes.func.isRequired,
+};
+
 const ConnectedText = ({ userName, roleName }) => (
   <div>
     <h6>
@@ -299,6 +363,7 @@
   getMetaData,
   changeCurrentGraph,
   changeGraph,
+  isLabel,
 }) => {
   const dispatch = useDispatch();
   const { confirm } = Modal;
@@ -336,6 +401,23 @@
         <div id="lastHorizontalLine">
           <VerticalLine />
         </div>
+        { isLabel && (
+          <>
+            <div className="form-group sidebar-item">
+              <b>Graphs</b>
+              <br />
+              <GraphList
+                graphs={graphs}
+                currentGraph={currentGraph}
+                changeCurrentGraph={changeCurrentGraph}
+                changeGraph={changeGraph}
+              />
+            </div>
+            <div id="lastHorizontalLine">
+              <VerticalLine />
+            </div>
+          </>
+        ) }
       </div>
       <div className="sidebar-item-disconnect-outer">
         <div className="form-group sidebar-item-disconnect">
@@ -380,15 +462,19 @@
             <br />
             <b>Close Session</b>
           </div>
-          <HorizontalLine />
-          <div className="sidebar-item-disconnect-buttons">
-            <GraphSelectDropdown
-              currentGraph={currentGraph}
-              graphs={graphs}
-              changeCurrentGraph={changeCurrentGraph}
-              changeGraphDB={changeGraph}
-            />
-          </div>
+          { !isLabel && (
+            <>
+              <HorizontalLine />
+              <div className="sidebar-item-disconnect-buttons">
+                <GraphSelectDropdown
+                  currentGraph={currentGraph}
+                  graphs={graphs}
+                  changeCurrentGraph={changeCurrentGraph}
+                  changeGraphDB={changeGraph}
+                />
+              </div>
+            </>
+          ) }
         </div>
       </div>
     </div>
@@ -417,6 +503,7 @@
   currentGraph: PropTypes.string.isRequired,
   graphs: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)).isRequired,
   changeGraph: PropTypes.func.isRequired,
+  isLabel: PropTypes.bool.isRequired,
 };
 
 export default SidebarHome;
diff --git a/frontend/src/features/layout/LayoutSlice.js b/frontend/src/features/layout/LayoutSlice.js
new file mode 100644
index 0000000..dba5ba3
--- /dev/null
+++ b/frontend/src/features/layout/LayoutSlice.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* eslint-disable no-param-reassign */
+import { createSlice } from '@reduxjs/toolkit';
+
+const LayoutSlice = createSlice({
+  name: 'layout',
+  initialState: {
+    isLabel: false,
+  },
+  reducers: {
+    setLabel: {
+      reducer: (state) => {
+        state.isLabel = !state.isLabel;
+      },
+    },
+  },
+});
+
+export const { setLabel } = LayoutSlice.actions;
+
+export default LayoutSlice.reducer;
diff --git a/frontend/src/static/style.css b/frontend/src/static/style.css
index 8ed65f8..29209f6 100644
--- a/frontend/src/static/style.css
+++ b/frontend/src/static/style.css
@@ -345,6 +345,26 @@
     color: #ffffff;
 }
 
+.graph-item {
+    height: 35px;
+    background-color: #ffffff;
+    border: 1px solid #142B80;
+    border-radius: 5px;
+    opacity: 1;
+    color: #142B80;
+    margin: 0px 4px 4px 4px;
+}
+
+.graph-item-clicked {
+    height: 35px;
+    background-color: #2756FF;
+    border: 1px solid #142B80;
+    border-radius: 5px;
+    opacity: 1;
+    color: #ffffff;
+    margin: 0px 4px 4px 4px;
+}
+
 /* ---------------------------------------------------
     MEDIAQUERIES
 ----------------------------------------------------- */