changeset 581:fb5d9d5ff320

refac: UI redesign
author Thomas Junk <thomas.junk@intevation.de>
date Thu, 06 Sep 2018 17:42:28 +0200
parents e78bdbb6cac8
children 93e90f6be2ad
files client/src/App.vue client/src/assets/application.scss client/src/components/Maplayer.vue client/src/components/Sidebar.vue client/src/components/Topbar.vue client/src/router.js client/src/store.js
diffstat 7 files changed, 89 insertions(+), 151 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/App.vue	Thu Sep 06 16:27:17 2018 +0200
+++ b/client/src/App.vue	Thu Sep 06 17:42:28 2018 +0200
@@ -1,7 +1,9 @@
 <template>
   <div id="app main d-flex flex-column">
-    <Topbar v-if="isAuthenticated"></Topbar>
-    <Sidebar v-if="isAuthenticated"></Sidebar>
+    <div class="userinterface">
+      <Topbar v-if="isAuthenticated"></Topbar>
+      <Sidebar v-if="isAuthenticated"></Sidebar>
+    </div>
     <router-view/>
   </div>
 </template>
@@ -18,9 +20,19 @@
   background-color: #efefef !important;
 }
 
+.userinterface {
+  position: absolute;
+  top: 0;
+  left: 0;
+  height: 100vh;
+  width: 100vw;
+  z-index: 4;
+  pointer-events: none;
+}
+
 #app {
-  height: 100%;
-  width: 100%;
+  height: 100vh;
+  width: 100vw;
   font-family: "Avenir", Helvetica, Arial, sans-serif;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
--- a/client/src/assets/application.scss	Thu Sep 06 16:27:17 2018 +0200
+++ b/client/src/assets/application.scss	Thu Sep 06 17:42:28 2018 +0200
@@ -18,3 +18,7 @@
   left: 50%;
   transform: translate(-50%, -50%);
 }
+
+.ui-element {
+  pointer-events: auto;
+}
--- a/client/src/components/Maplayer.vue	Thu Sep 06 16:27:17 2018 +0200
+++ b/client/src/components/Maplayer.vue	Thu Sep 06 17:42:28 2018 +0200
@@ -1,20 +1,9 @@
 <template>
   <div class="mapdisplay">
     <div id="map"></div>
-    <div v-if="this.openLayersMap" class="card layerselection shadow">
-      <div class="card-body">
-        <div class="headline">
-          <h4 class="card-title">Layers</h4>
-        </div>
-        <hr>
-        <div class="d-flex flex-column">
-          <Layerselect :layerindex="index" :layername="layer.name" v-for="(layer, index) in layers" :key="layer.name" :isVisible="layer.isVisible" @visibilityToggled="visibilityToggled"></Layerselect>
-        </div>
-      </div>
-    </div>
-    <div class="profile d-flex flex-row">
+    <!-- <div class="profile d-flex flex-row">
       <Fairwayprofile height="300" width="1024" :xScale="[0, 300]" :yScaleLeft="[191, 199]" :yScaleRight="[-6, 1]" :margin="{ top: 20, right: 40, bottom: 20, left: 40 }"></Fairwayprofile>
-    </div>
+    </div> -->
   </div>
 </template>
 
@@ -27,23 +16,19 @@
 }
 
 .mapdisplay {
-  height: 100%;
+  height: 100vh;
 }
 
 #map {
-  margin-top: $topbarheight;
-  height: 50vh;
+  height: 100vh;
 }
 
-.layerselection {
-  position: absolute;
-  top: 40px + $small-offset;
-  margin-top: $small-offset;
-  right: $small-offset;
-  min-height: 20%;
-  min-width: 10%;
+.ol-zoom {
+  display: flex;
+  left: 15vw;
+  margin-top: 2vh;
+  z-index: 5;
   background-color: white;
-  z-index: 10;
 }
 </style>
 
@@ -54,72 +39,30 @@
 // needed for vector filter example
 // import { greaterThan as greaterThanFilter } from "ol/format/filter.js";
 import { WFS, GeoJSON } from "ol/format.js";
-import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer.js";
-import VectorSource from "ol/source/Vector.js";
-import { Stroke, Style } from "ol/style.js";
-import OSM from "ol/source/OSM";
-import TileWMS from "ol/source/TileWMS.js";
-import Layerselect from "./Layerselect";
+import { mapGetters } from "vuex";
 import Fairwayprofile from "./Fairwayprofile";
 
 export default {
   name: "maplayer",
   props: ["lat", "long", "zoom"],
   components: {
-    Layerselect,
     Fairwayprofile
   },
   data() {
     return {
       projection: "EPSG:3857",
-      openLayersMap: null,
-      layers: [
-        {
-          name: "Open Streetmap",
-          data: new TileLayer({
-            source: new OSM()
-          }),
-          isVisible: true
-        },
-        {
-          name: "D4D",
-          data: new TileLayer({
-            source: new TileWMS({
-              url: "https://demo.d4d-portal.info/wms",
-              params: { LAYERS: "d4d", VERSION: "1.1.1", TILED: true }
-            })
-          }),
-          isVisible: true
-        },
-        {
-          name: "Fairways Dimensions",
-          data: new VectorLayer({
-            source: new VectorSource(),
-            style: new Style({
-              stroke: new Stroke({
-                color: "rgba(0, 0, 255, 1.0)",
-                width: 2
-              })
-            })
-          }),
-          isVisible: true
-        }
-      ]
+      openLayersMap: null
     };
   },
   computed: {
+    ...mapGetters("mapstore", ["layers"]),
     layerData() {
       return this.layers.map(x => {
         return x.data;
       });
     }
   },
-  methods: {
-    visibilityToggled(layer) {
-      this.layers[layer].isVisible = !this.layers[layer].isVisible;
-      this.layers[layer].data.setVisible(this.layers[layer].isVisible);
-    }
-  },
+  methods: {},
   mounted() {
     var that = this;
     this.openLayersMap = new Map({
--- a/client/src/components/Sidebar.vue	Thu Sep 06 16:27:17 2018 +0200
+++ b/client/src/components/Sidebar.vue	Thu Sep 06 17:42:28 2018 +0200
@@ -6,19 +6,24 @@
       <div v-if="isSysAdmin">
         <hr/>
         <div class="nav-link d-flex menupadding text-muted">Administration</div>
-        <router-link class="text-body d-flex flex-row nav-link" to="users">
+        <router-link class="text-body d-flex flex-row nav-link" to="usermanagement">
           <i class="fa fa-address-card-o align-self-center navicon"></i>Users
         </router-link>
       </div>
     </div>
+    <User></User>
   </div>
 </template>
 
 <script>
 import { mapGetters } from "vuex";
+import User from "../components/User";
 
 export default {
   name: "sidebar",
+  components: {
+    User: User
+  },
   computed: {
     ...mapGetters("user", ["isSysAdmin"]),
     ...mapGetters("application", ["sidebarCollapsed"]),
@@ -31,6 +36,7 @@
     },
     sidebarStyle() {
       return {
+        "ui-element": true,
         sidebar: true,
         overlay: true,
         sidebarcollapsed: this.sidebarCollapsed,
@@ -54,19 +60,21 @@
 }
 
 .menu {
+  padding-top: 10vh;
   height: 90%;
 }
 
 .sidebar {
-  margin-top: $topbarheight;
+  top: 0;
   background-color: #ffffff;
   padding-top: $large-offset;
-  height: 100vh-$topbarheight;
+  height: 100vh;
+  opacity: 0.96;
 }
 
 .overlay {
   position: absolute;
-  z-index: 1;
+  z-index: -1;
 }
 
 .sidebarcollapsed {
--- a/client/src/components/Topbar.vue	Thu Sep 06 16:27:17 2018 +0200
+++ b/client/src/components/Topbar.vue	Thu Sep 06 17:42:28 2018 +0200
@@ -1,96 +1,65 @@
 <template>
-  <div class="topbar shadow-sm d-flex flex-row justify-content-between">
-    <div class="align-self-center">
-      <i @click="toggleSidebar" class="menubutton fa fa-bars"></i>
+  <div class="topbar d-flex flex-row justify-content-between">
+    <div>
+      <i @click="toggleSidebar" class="ui-element menubutton fa fa-bars"></i>
     </div>
-    <div class="searchcontainer align-self-center">
-      <label class="searchlabel" for="search">
-        <i class="fa fa-search"></i>
-      </label>
-      <input id="search" type="text" class="search searchbar">
+    <div class="input-group searchcontainer">
+      <div class="input-group-prepend">
+        <span class="input-group-text searchlabel" for="search">
+          <i class="fa fa-search"></i>
+        </span>
+      </div>
+      <input id="search" type="text" class="form-control ui-element search searchbar">
     </div>
-    <div class="align-self-center usermanagement">
-      <img class="userpic" src="../assets/user.png">
-      <span class="username">{{ userinfo }}</span>
-      <span class="logout" @click="logoff">
-        <i class="fa fa-power-off"></i>
-      </span>
-    </div>
+    <Layers></Layers>
   </div>
 </template>
 
 <style lang="scss">
 @import "../assets/application.scss";
-.topbar {
-  position: absolute;
-  width: 100vw;
-  height: $topbarheight;
-  min-height: 40px;
+
+.menubutton {
   background-color: white;
-  z-index: 100;
-}
-.menubutton {
-  cursor: pointer;
-}
-.searchcontainer {
-  margin-left: auto;
+  padding: 0.5rem;
 }
 
-.usermanagement {
-  margin-left: auto;
-}
-.logout {
-  position: relative;
-  top: 3px;
-  font-size: x-large;
-  font-weight: bold;
-  margin-right: $offset;
-}
-
-.userpic {
-  margin-right: 0.5rem;
-}
-.username {
-  font-weight: bold;
-  margin-right: 1.5rem;
-}
-
-.searchlabel {
-  color: #aaaaaa;
-  position: relative;
-  top: 2px;
-  font-size: x-large;
-  margin-right: $small-offset;
+.searchcontainer {
+  margin-left: 20vw;
+  margin-right: auto;
+  width: 50vw !important;
+  height: 39px;
+  border-radius: 0.25rem;
 }
 
 .searchbar {
-  width: 30vw;
-  border: 1px solid;
-  border-color: #aaaaaa;
-  border-radius: 10px;
-  padding-left: 1rem;
-  padding-right: 1rem;
+  margin-left: auto;
+  margin-right: auto;
+  height: 50px;
+}
+
+.topbar {
+  padding-top: 2vh;
+  margin-right: 1vw;
+  margin-left: 0;
+}
+
+.logout {
+  font-size: x-large;
 }
 </style>
 
 
 <script>
-import { mapGetters } from "vuex";
-
+import Layers from "./Layers";
 export default {
   name: "topbar",
+  components: {
+    Layers: Layers
+  },
   methods: {
     toggleSidebar() {
       this.$store.commit("application/toggleSidebar");
-    },
-    logoff() {
-      this.$store.commit("user/clear_auth");
-      this.$store.commit("application/resetSidebar");
-      this.$router.push("/login");
     }
-  },
-  computed: {
-    ...mapGetters("user", ["userinfo"])
   }
 };
 </script>
--- a/client/src/router.js	Thu Sep 06 16:27:17 2018 +0200
+++ b/client/src/router.js	Thu Sep 06 17:42:28 2018 +0200
@@ -6,7 +6,7 @@
 /*  facilitate codesplitting */
 const Login = () => import("./views/Login.vue");
 const Main = () => import("./views/Main.vue");
-const Users = () => import("./views/Users.vue");
+const Usermanagement = () => import("./views/Usermanagement.vue");
 
 Vue.use(Router);
 
@@ -18,9 +18,9 @@
       component: Login
     },
     {
-      path: "/users",
-      name: "users",
-      component: Users,
+      path: "/usermanagement",
+      name: "usermanagement",
+      component: Usermanagement,
       meta: {
         requiresAuth: true
       },
--- a/client/src/store.js	Thu Sep 06 16:27:17 2018 +0200
+++ b/client/src/store.js	Thu Sep 06 17:42:28 2018 +0200
@@ -3,6 +3,7 @@
 import Application from "./stores/application";
 import user from "./stores/user";
 import usermanagement from "./stores/usermanagement";
+import mapstore from "./stores/mapstore";
 
 Vue.use(Vuex);
 
@@ -10,6 +11,7 @@
   modules: {
     application: Application,
     user: user,
-    usermanagement: usermanagement
+    usermanagement: usermanagement,
+    mapstore: mapstore
   }
 });