Mercurial > gemma
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 } });