changeset 1470:c89a18f8027d bulkreview

Merged back default into bulkreview branch.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 30 Nov 2018 09:17:03 +0100
parents 286a3306f6bf (current diff) 7fa030127b05 (diff)
children 9a0231e6749d
files client/src/store/imports.js
diffstat 26 files changed, 1047 insertions(+), 402 deletions(-) [+]
line wrap: on
line diff
--- a/client/docs/developer.md	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/docs/developer.md	Fri Nov 30 09:17:03 2018 +0100
@@ -101,6 +101,7 @@
 
   - [xgettext fails with some .vue files](https://github.com/Polyconseil/vue-gettext/issues/28) which forces us to use `(`, `)` around templates
   - [translations in attributes](https://github.com/Polyconseil/vue-gettext/issues/9) which leaves us with either interpolating in templates with `<translate></translate>` or use computed properties in Vue components (cf. Login component).
+  - [inconsistent white space handling](https://github.com/Polyconseil/vue-gettext/issues/80) if you need a white space preserved before the translated tag, use `<span v-translate class="fix-trans-space">to be translated</a>` (see `src/assets/application.sass`).
 
 - Is dependend on external (=non JS) tools (`xgettext`) which are not able to consume `.vue`-files directly, which in turn leads to unexpected behaviour.
 -
--- a/client/src/assets/application.sass	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/assets/application.sass	Fri Nov 30 09:17:03 2018 +0100
@@ -77,4 +77,15 @@
   max-width: 999px
   margin-left: 0.5rem
   margin-right: 0.5rem
-  margin-bottom: 0.5rem
+  margin-bottom: 1rem
+
+// needed to fix the whitespace problem of
+//   https://github.com/Polyconseil/vue-gettext/issues/80
+// use like
+//    <a href="..">link</a>
+//    <span v-translate class="fix-trans-space">contributors.</span>
+//
+// done centrally, so we can fix it centrally for better vue-gettext version
+.fix-trans-space
+  &:before
+    content: " "
--- a/client/src/components/Sidebar.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/Sidebar.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -9,7 +9,7 @@
     <div class="menu text-nowrap text-left">
       <router-link to="/">
         <font-awesome-icon icon="map-marked-alt" fixed-width></font-awesome-icon>
-        <translate>Map</translate>
+        <span v-translate class="fix-trans-space">Map</span>
       </router-link>
       <a
         href="#"
@@ -17,7 +17,7 @@
         :class="['secondary', { active: isActive('bottlenecks') }]"
       >
         <font-awesome-icon icon="ship" fixed-width></font-awesome-icon>
-        <translate>Bottlenecks</translate>
+        <span v-translate class="fix-trans-space">Bottlenecks</span>
       </a>
       <div v-if="isWaterwayAdmin">
         <a
@@ -26,7 +26,7 @@
           :class="['secondary', { active: isActive('imports') }]"
         >
           <font-awesome-icon icon="upload" fixed-width></font-awesome-icon>
-          <translate>Import soundingresults</translate>
+          <span v-translate class="fix-trans-space">Import soundingresults</span>
         </a>
         <a
           href="#"
@@ -34,33 +34,40 @@
           :class="['secondary', { active: isActive('staging') }]"
         >
           <font-awesome-icon icon="clipboard-check" fixed-width></font-awesome-icon>
-          <translate>Staging area</translate>
+          <span v-translate class="fix-trans-space">Staging area</span>
         </a>
-        <small class="text-muted pl-3"><translate>Systemadministration</translate></small>
+        <small class="text-muted pl-3">
+          <translate>Systemadministration</translate>
+        </small>
         <hr class="m-0">
         <router-link to="usermanagement">
           <font-awesome-icon icon="users-cog" fixed-width></font-awesome-icon>
-          <translate>Users</translate>
+          <span v-translate class="fix-trans-space">Users</span>
         </router-link>
       </div>
       <div v-if="isSysAdmin">
         <router-link to="systemconfiguration">
           <font-awesome-icon icon="wrench" fixed-width></font-awesome-icon>
-          <translate>Systemconfiguration</translate>
+          <span v-translate class="fix-trans-space">Configuration</span>
         </router-link>
         <router-link to="logs">
           <font-awesome-icon icon="book" fixed-width></font-awesome-icon>
-          <translate>Logs</translate>
+          <span v-translate class="fix-trans-space">Logs</span>
         </router-link>
         <router-link to="importqueue">
           <font-awesome-icon icon="tasks" fixed-width></font-awesome-icon>
-          <translate>Importqueue</translate>
+          <span v-translate class="fix-trans-space">Importqueue</span>
+        </router-link>
+        <router-link v-if="this.$options.IMPORTSCHEDULE" to="importschedule">
+          <font-awesome-icon icon="clock" fixed-width></font-awesome-icon>
+          <translate>Importschedule</translate>
         </router-link>
       </div>
       <hr class="m-0">
       <a href="#" @click="logoff">
         <font-awesome-icon icon="power-off" fixed-width></font-awesome-icon>
-        <translate>Logout</translate> {{ user }}
+        <span v-translate class="fix-trans-space">Logout</span>
+        {{ user }}
       </a>
     </div>
   </div>
@@ -105,6 +112,7 @@
       ];
     }
   },
+  IMPORTSCHEDULE: process.env.VUE_APP_FEATURE_IMPORTSCHEDULE,
   methods: {
     logoff() {
       this.$store.commit("reset");
@@ -143,10 +151,8 @@
     padding: 0.5rem 1rem
     color: #333
     text-decoration: none
-    svg
-      margin-right: 0.5rem
-      path
-        fill: #666
+    svg path
+      fill: #666
     &:hover
       background-color: #f8f8f8
     &.router-link-exact-active
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/admin/importschedule/Importschedule.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -0,0 +1,157 @@
+<template>
+  <div class="d-flex flex-row">
+    <div :class="spacerStyle"></div>
+    <div class="mt-3">
+      <div class="card schedulecard">
+        <div class="card-header shadow-sm text-white bg-info mb-3">
+          <translate>Importschedule</translate>
+        </div>
+        <div class="card-body schedulecardbody">
+          <div class="card-body schedulecardbody">
+            <div class="searchandfilter d-flex flex-row">
+              <div class="searchgroup input-group">
+                <div class="input-group-prepend">
+                  <span class="input-group-text" id="search">
+                    <font-awesome-icon icon="search"></font-awesome-icon>
+                  </span>
+                </div>
+                <input
+                  v-model="searchQuery"
+                  type="text"
+                  class="form-control"
+                  placeholder
+                  aria-label="Search"
+                  aria-describedby="search"
+                >
+              </div>
+            </div>
+            <table v-if="schedules.length" class="table">
+              <thead>
+                <tr>
+                  <th>
+                    <translate>Import</translate>
+                  </th>
+                  <th>
+                    <translate>Type</translate>
+                  </th>
+                  <th>
+                    <translate>Author</translate>
+                  </th>
+                  <th>
+                    <translate>Schedule</translate>
+                  </th>
+                  <th>
+                    <translate>Email</translate>
+                  </th>
+                  <th>&nbsp;</th>
+                  <th>&nbsp;</th>
+                </tr>
+              </thead>
+              <tbody>
+                <tr v-for="(schedule, index) in schedules" :key="index">
+                  <td></td>
+                  <td></td>
+                  <td></td>
+                  <td></td>
+                  <td></td>
+                  <td>
+                    <font-awesome-icon icon="pencil-alt" fixed-width></font-awesome-icon>
+                  </td>
+                  <td>
+                    <font-awesome-icon @click="deleteSchedule" icon="trash" fixed-width></font-awesome-icon>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+            <div v-else class="mt-4 small text-center py-3">
+              <translate>No schedules</translate>
+            </div>
+            <button @click="newImport" class="btn btn-info position-absolute newbutton">
+              <translate>New Import</translate>
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+    <Importscheduledetail></Importscheduledetail>
+  </div>
+</template>
+
+<script>
+/* This is Free Software under GNU Affero General Public License v >= 3.0
+ * without warranty, see README.md and license for details.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ * License-Filename: LICENSES/AGPL-3.0.txt
+ *
+ * Copyright (C) 2018 by via donau
+ *   – Österreichische Wasserstraßen-Gesellschaft mbH
+ * Software engineering by Intevation GmbH
+ *
+ * Author(s):
+ * Thomas Junk <thomas.junk@intevation.de>
+ */
+
+import { mapState } from "vuex";
+import Importscheduledetail from "./Importscheduledetail";
+//import { SCHEDULES } from "../../store/imports.js";
+
+export default {
+  name: "importschedule",
+  components: {
+    Importscheduledetail
+  },
+  data() {
+    return {
+      searchQuery: ""
+    };
+  },
+  methods: {
+    newImport() {
+      this.$store.commit("imports/setImportScheduleDetailVisible");
+    },
+    deleteSchedule(index) {
+      this.$store.commit("imports/deleteSchedule", index);
+    }
+  },
+  computed: {
+    ...mapState("application", ["showSidebar"]),
+    ...mapState("imports", ["schedules"]),
+    spacerStyle() {
+      return [
+        "spacer ml-3",
+        {
+          "spacer-expanded": this.showSidebar,
+          "spacer-collapsed": !this.showSidebar
+        }
+      ];
+    }
+  }
+};
+</script>
+
+<style lang="sass" scoped>
+.spacer
+  height: 100vh
+
+.spacer-collapsed
+  min-width: $icon-width + $offset
+  transition: $transition-fast
+
+.spacer-expanded
+  min-width: $sidebar-width + $offset
+
+.schedulecard
+  width: 40vw
+  min-height: 20rem
+
+.schedulecard-body
+  width: 100%
+  margin-left: auto
+  margin-right: aut
+
+.newbutton
+  position:absolute
+  bottom: $offset
+  right: $offset
+</style>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/admin/importschedule/Importscheduledetail.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -0,0 +1,35 @@
+<template>
+  <div v-if="importScheduleDetailVisible">
+    <div class="card">
+      <div class="card-header shadow-sm text-white bg-info mb-3">
+        <span @click="closeDetailview" class="pull-right">
+          <font-awesome-icon icon="times"></font-awesome-icon>
+        </span>
+      </div>
+      <div class="card-body">
+        <h1>lalala</h1>
+        <form @submit.prevent="save" class="ml-3"></form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from "vuex";
+
+export default {
+  name: "importscheduledetail",
+  computed: {
+    ...mapState("imports", ["importScheduleDetailVisible"])
+  },
+  methods: {
+    closeDetailview() {
+      this.$store.commit("imports/clearImportScheduleDetail");
+      this.$store.commit("imports/setImportScheduleDetailInvisible");
+    }
+  }
+};
+</script>
+
+<style>
+</style>
--- a/client/src/components/admin/usermanagement/Userdetail.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/admin/usermanagement/Userdetail.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -11,7 +11,9 @@
         <form @submit.prevent="save" class="ml-3">
           <div class="formfields">
             <div v-if="currentUser.isNew" class="form-group row">
-              <label for="user">Username</label>
+              <label for="user">
+                <translate>Username</translate>
+              </label>
               <input
                 type="user"
                 :placeholder="userNamePlaceholder"
@@ -28,13 +30,17 @@
               </div>
             </div>
             <div class="form-group row">
-              <label for="country">Country</label>
+              <label for="country">
+                <translate>Country</translate>
+              </label>
               <select
                 class="form-control form-control-sm"
                 v-on:change="validateCountry"
                 v-model="currentUser.country"
               >
-                <option disabled value>Please select one</option>
+                <option disabled value>
+                  <translate>Please select one</translate>
+                </option>
                 <option
                   v-for="country in countries"
                   v-bind:value="country"
@@ -49,7 +55,9 @@
               </div>
             </div>
             <div class="form-group row">
-              <label for="email">Email address</label>
+              <label for="email">
+                <translate>Email address</translate>
+              </label>
               <input
                 type="email"
                 v-on:change="validateEmailaddress"
@@ -66,16 +74,26 @@
               </div>
             </div>
             <div class="form-group row">
-              <label for="role">Role</label>
+              <label for="role">
+                <translate>Role</translate>
+              </label>
               <select
                 class="form-control form-control-sm"
                 v-on:change="validateRole"
                 v-model="currentUser.role"
               >
-                <option disabled value>Please select one</option>
-                <option value="sys_admin">Sysadmin</option>
-                <option value="waterway_admin">Waterway Admin</option>
-                <option value="waterway_user">Waterway User</option>
+                <option disabled value>
+                  <translate>Please select one</translate>
+                </option>
+                <option value="sys_admin">
+                  <translate>Sysadmin</translate>
+                </option>
+                <option value="waterway_admin">
+                  <translate>Waterway Admin</translate>
+                </option>
+                <option value="waterway_user">
+                  <translate>Waterway User</translate>
+                </option>
               </select>
               <div v-show="errors.role" class="text-danger">
                 <small>
@@ -102,20 +120,21 @@
             </div>
           </div>
           <div>
-            <button
-              type="submit"
-              :disabled="submitted"
-              class="shadow-sm btn btn-info pull-right"
-            >Submit</button>
+            <button type="submit" :disabled="submitted" class="shadow-sm btn btn-info pull-right">
+              <translate>Submit</translate>
+            </button>
           </div>
           <div
             v-if="currentUser.role !='waterway_user' "
             class="form-group row d-flex flex-row justify-content-start mailbutton"
           >
             <a @click="sendTestMail" class="btn btn-light">
-              <font-awesome-icon icon="paper-plane"></font-awesome-icon>Send testmail
+              <font-awesome-icon icon="paper-plane"></font-awesome-icon>
+              <translate>Send testmail</translate>
             </a>
-            <div v-if="mailsent">Mail was sent</div>
+            <div v-if="mailsent">
+              <translate>Mail was sent</translate>
+            </div>
           </div>
         </form>
       </div>
--- a/client/src/components/admin/usermanagement/Usermanagement.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/admin/usermanagement/Usermanagement.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -5,7 +5,9 @@
       <div class="d-flex flex-row">
         <div :class="userlistStyle">
           <div class="card">
-            <div class="card-header shadow-sm text-white bg-info mb-3">Users</div>
+            <div class="card-header shadow-sm text-white bg-info mb-3">
+              <translate>Users</translate>
+            </div>
             <div class="card-body">
               <table id="datatable" :class="tableStyle">
                 <thead>
@@ -66,7 +68,9 @@
               </button>
             </div>
             <div class="mr-3 pb-3">
-              <button @click="addUser " class="btn btn-info pull-right shadow-sm">Add User</button>
+              <button @click="addUser " class="btn btn-info pull-right shadow-sm">
+                <translate>Add User</translate>
+              </button>
             </div>
           </div>
         </div>
--- a/client/src/components/map/Identify.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/Identify.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -1,54 +1,59 @@
 <template>
-    <div :class="['box ui-element rounded bg-white text-nowrap', { expanded: showIdentify }]">
-        <div style="width: 20rem">
-            <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center">
-              <font-awesome-icon icon="info" class="mr-2"></font-awesome-icon>
-              <translate>Identified</translate>
-              <font-awesome-icon
-                  icon="times"
-                  class="ml-auto text-muted"
-                  @click="$store.commit('application/showIdentify', false)"
-              ></font-awesome-icon>
-            </h6>
-            <div class="d-flex flex-column features p-3 flex-grow-1 text-left">
-                <div v-if="currentMeasurement">
-                    <b>
-                      {{ currentMeasurement.quantity }}
-                      ({{ currentMeasurement.unitSymbol }}):
-                    </b><br>
-                    <small>{{ currentMeasurement.value }}</small>
-                </div>
-                <div v-for="(feature, i) of identifiedFeatures" :key="feature.getId()" >
-                    <div v-if="feature.getId()" :class="{ 'mt-2': i }">
-                        <b>{{ feature.getId().replace(/[.][^.]*$/,"") /* cut away everything from the last . to the end */}}:</b>
-                        <small
-                            v-for="(value, key) in prepareProperties(feature)"
-                            :key="key"
-                        >
-                            <div v-if="value">{{key}}:{{value}}</div>
-                        </small>
-                    </div>
-                </div>
-                <div v-if="!currentMeasurement && !identifiedFeatures.length" class="text-muted small text-center my-auto">
-                    <translate>No features identified.</translate>
-                </div>
-            </div>
-            <div class="versioninfo border-top p-3 text-left">
-              <translate>This app uses </translate><i>gemma</i>,<translate> which is Free Software under</translate>
-              <br>
-              AGPL-3.0-or-later
-              <translate> without warranty, see docs for details.</translate><br>
+  <div :class="['box ui-element rounded bg-white text-nowrap', { expanded: showIdentify }]">
+    <div style="width: 20rem">
+      <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center">
+        <font-awesome-icon icon="info" class="mr-2"></font-awesome-icon>
+        <translate>Identified</translate>
+        <font-awesome-icon
+          icon="times"
+          class="ml-auto text-muted"
+          @click="$store.commit('application/showIdentify', false)"
+        ></font-awesome-icon>
+      </h6>
+      <div class="d-flex flex-column features p-3 flex-grow-1 text-left">
+        <div v-if="currentMeasurement">
+          <b>
+            {{ currentMeasurement.quantity }}
+            ({{ currentMeasurement.unitSymbol }}):
+          </b>
+          <br>
+          <small>{{ currentMeasurement.value }}</small>
+        </div>
+        <div v-for="(feature, i) of identifiedFeatures" :key="feature.getId()">
+          <div v-if="feature.getId()" :class="{ 'mt-2': i }">
+            <b>{{ feature.getId().replace(/[.][^.]*$/,"") /* cut away everything from the last . to the end */}}:</b>
+            <small v-for="(value, key) in prepareProperties(feature)" :key="key">
+              <div v-if="value">{{key}}:{{value}}</div>
+            </small>
+          </div>
+        </div>
+        <div
+          v-if="!currentMeasurement && !identifiedFeatures.length"
+          class="text-muted small text-center my-auto"
+        >
+          <translate>No features identified.</translate>
+        </div>
+      </div>
+      <div class="versioninfo border-top p-3 text-left">
+        <translate>This app uses</translate>
+        <i>gemma</i>,
+        <translate>which is Free Software under</translate>
+        <br>AGPL-3.0-or-later
+        <translate>without warranty, see docs for details.</translate>
+        <br>
 
-              <a href="https://hg.intevation.de/gemma/file/tip"><translate>source-code</translate></a>
-              {{ versionStr }}
-              <br>
-              © via donau. &#x24D4; Intevation.
-              <br><translate>Some data </translate>©
-              <a href="https://www.openstreetmap.org/copyright">OpenSteetMap</a>
-              <translate>contributors.</translate>
-            </div>
-        </div>
+        <a href="https://hg.intevation.de/gemma/file/tip">
+          <translate>source-code</translate>
+        </a>
+        {{ versionStr }}
+        <br>© via donau. &#x24D4; Intevation.
+        <br>
+        <translate>Some data</translate>©
+        <a href="https://www.openstreetmap.org/copyright">OpenSteetMap</a>
+        <span v-translate class="fix-trans-space">contributors.</span>
+      </div>
     </div>
+  </div>
 </template>
 
 <style lang="sass" scoped>
@@ -58,7 +63,7 @@
 
 .versioninfo
   font-size: 60%
-  white-space:normal
+  white-space: normal
 </style>
 
 <script>
--- a/client/src/components/map/Maplayer.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/Maplayer.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -43,7 +43,6 @@
 import { Map, View } from "ol";
 import { WFS, GeoJSON } from "ol/format.js";
 import { Stroke, Style, Fill } from "ol/style.js";
-import { getCenter } from "ol/extent";
 
 /* for the sake of debugging */
 /* eslint-disable no-console */
@@ -55,7 +54,7 @@
     };
   },
   computed: {
-    ...mapGetters("map", ["getLayerByName"]),
+    ...mapGetters("map", ["getLayerByName", "getVSourceByName"]),
     ...mapState("map", [
       "extent",
       "layers",
@@ -82,68 +81,6 @@
     }
   },
   methods: {
-    identify(coordinate, pixel) {
-      if (!this.hasActiveInteractions) {
-        this.$store.commit("map/setIdentifiedFeatures", []);
-        // checking our WFS layers
-        var features = this.openLayersMap.getFeaturesAtPixel(pixel);
-        if (features) {
-          this.$store.commit("map/setIdentifiedFeatures", features);
-
-          // get selected bottleneck from identified features
-          for (let feature of features) {
-            let id = feature.getId();
-            // RegExp.prototype.test() works with number, str and undefined
-            if (/^bottlenecks\./.test(id)) {
-              this.$store.dispatch(
-                "bottlenecks/setSelectedBottleneck",
-                feature.get("objnam")
-              );
-              this.$store.commit("map/moveMap", {
-                coordinates: getCenter(
-                  feature
-                    .getGeometry()
-                    .clone()
-                    .transform("EPSG:3857", "EPSG:4326")
-                    .getExtent()
-                ),
-                zoom: 17,
-                preventZoomOut: true
-              });
-            }
-          }
-        }
-
-        // DEBUG output and example how to remove the GeometryName
-        /*
-        for (let feature of features) {
-          console.log("Identified:", feature.getId());
-          for (let key of feature.getKeys()) {
-            if (key != feature.getGeometryName()) {
-              console.log(key, feature.get(key));
-            }
-          }
-        }
-        */
-
-        // trying the GetFeatureInfo way for WMS
-        var wmsSource = this.getLayerByName(
-          "Inland ECDIS chart Danube"
-        ).data.getSource();
-        var url = wmsSource.getGetFeatureInfoUrl(
-          coordinate,
-          100 /* resolution */,
-          "EPSG:3857",
-          // { INFO_FORMAT: "application/vnd.ogc.gml" } // not allowed by d4d
-          { INFO_FORMAT: "text/plain" }
-        );
-
-        if (url) {
-          // cannot directly query here because of SOP
-          console.log("GetFeatureInfo url:", url);
-        }
-      }
-    },
     buildVectorLoader(featureRequestOptions, endpoint, vectorSource) {
       // build a function to be used for VectorSource.setLoader()
       // make use of WFS().writeGetFeature to build the request
@@ -189,10 +126,11 @@
     },
     updateBottleneckFilter(bottleneck_id, datestr) {
       console.log("updating filter with", bottleneck_id, datestr);
-      var layer = this.getLayerByName("Bottleneck isolines");
-      var wmsSrc = layer.data.getSource();
+      const layer = this.getLayerByName("Bottleneck isolines");
+      const wmsSrc = layer.data.getSource();
+      const exists = bottleneck_id != "does_not_exist";
 
-      if (bottleneck_id != "does_not_exist") {
+      if (exists) {
         wmsSrc.updateParams({
           cql_filter:
             "date_info='" +
@@ -201,12 +139,9 @@
             bottleneck_id +
             "'"
         });
-        layer.isVisible = true;
-        layer.data.setVisible(true);
-      } else {
-        layer.isVisible = false;
-        layer.data.setVisible(false);
       }
+      layer.isVisible = exists;
+      layer.data.setVisible(exists);
     },
     onBeforePrint(/* evt */) {
       // console.log("onBeforePrint(", evt ,")");
@@ -300,11 +235,9 @@
         }
       }
     ).then(response => {
-      var features = new GeoJSON().readFeatures(JSON.stringify(response.data));
-      var vectorSrc = this.getLayerByName(
-        "Fairway Dimensions"
-      ).data.getSource();
-      vectorSrc.addFeatures(features);
+      this.getVSourceByName("Fairway Dimensions").addFeatures(
+        new GeoJSON().readFeatures(JSON.stringify(response.data))
+      );
       // would scale to the extend of all resulting features
       // this.openLayersMap.getView().fit(vectorSrc.getExtent());
     });
@@ -430,9 +363,7 @@
 
     // so none is shown
     this.updateBottleneckFilter("does_not_exist", "1999-10-01");
-    this.openLayersMap.on(["singleclick", "dblclick"], event => {
-      this.identify(event.coordinate, event.pixel);
-    });
+    this.$store.dispatch("map/enableIdentifyTool");
     this.$store.dispatch("bottlenecks/loadBottlenecks");
   }
 };
--- a/client/src/components/map/Pdftool.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/Pdftool.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -23,7 +23,7 @@
             v-model="form.downloadType"
             selected
           >
-          <label for="pdfexport-downloadtype-download" class="ml-1 mr-2"><translate>Dvownload</translate></label>
+          <label for="pdfexport-downloadtype-download" class="ml-1 mr-2"><translate>Download</translate></label>
           <input
             type="radio"
             id="pdfexport-downloadtype-open"
--- a/client/src/components/map/Search.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/Search.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -5,7 +5,7 @@
         <font-awesome-icon icon="search"></font-awesome-icon>
       </span>
     </div>
-    <div :class="['searchgroup', {'searchgroup-collapsed': !showSearchbar}]">
+    <div :class="['searchgroup', {'searchgroup-collapsed': !showSearchbar, big: showContextBox && ['bottlenecks', 'staging'].indexOf(contextBoxContent) !== -1 }]">
       <input
         @keyup.enter="takeFirstSearchresult"
         id="search"
@@ -40,8 +40,10 @@
   .searchgroup
     margin-left: -3px
     transition: width 0.3s
-    width: 571px
+    width: 300px
     overflow: hidden
+    &.big
+      width: 571px
 
   .searchgroup-collapsed
     width: 0
--- a/client/src/components/map/contextbox/Bottlenecks.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/contextbox/Bottlenecks.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -28,32 +28,36 @@
       <div
         v-for="bottleneck in filteredAndSortedBottlenecks()"
         :key="bottleneck.properties.name"
-        class="border-top row mx-0 py-2"
+        class="border-top row bottleneck-row mx-0"
       >
-        <div class="col-5 text-left">
+        <div class="col-5 py-2 text-left">
           <a
             href="#"
-            class="d-block"
-            @click="moveToBottleneck(bottleneck)"
+            @click="selectBottleneck(bottleneck)"
           >{{ bottleneck.properties.name }}</a>
         </div>
-        <div class="col-2">{{ displayCurrentSurvey(bottleneck.properties.current) }}</div>
-        <div
-          class="col-3"
-        >{{ displayCurrentChainage(bottleneck.properties.from, bottleneck.properties.from) }}</div>
-        <div class="col-2 text-right">
+        <div class="col-2 py-2">
+          {{ displayCurrentSurvey(bottleneck.properties.current) }}
+        </div>
+        <div class="col-3 py-2">
+          {{ displayCurrentChainage(bottleneck.properties.from, bottleneck.properties.from) }}
+        </div>
+        <div class="col-2 pr-0 text-right">
           <button
             type="button"
-            class="btn btn-sm btn-info"
-            @click="toggleBottleneck(bottleneck.properties.name)"
+            class="btn btn-sm btn-info rounded-0 h-100"
+            @click="loadSurveys(bottleneck.properties.name)"
+            v-if="bottleneck.properties.current"
           >
-            <font-awesome-icon icon="angle-down"></font-awesome-icon>
+            <font-awesome-icon icon="spinner" fixed-width spin v-if="loading === bottleneck.properties.name"></font-awesome-icon>
+            <font-awesome-icon icon="angle-down" fixed-width v-if="loading !== bottleneck.properties.name && openBottleneck !== bottleneck.properties.name"></font-awesome-icon>
+            <font-awesome-icon icon="angle-up" fixed-width v-if="loading !== bottleneck.properties.name && openBottleneck === bottleneck.properties.name"></font-awesome-icon>
           </button>
         </div>
-        <div :class="['col-12', 'surveys', {open: openBottleneck === bottleneck.properties.name}]">
+        <div :class="['col-12 p-0', 'surveys', {open: openBottleneck === bottleneck.properties.name}]">
           <a
             href="#"
-            class="d-block p-2"
+            class="d-block px-3 py-2"
             v-for="(survey, index) in openBottleneckSurveys"
             :key="index"
             @click="selectSurvey(survey, bottleneck)"
@@ -90,7 +94,8 @@
       sortColumn: "name",
       sortDirection: "ASC",
       openBottleneck: null,
-      openBottleneckSurveys: null
+      openBottleneckSurveys: null,
+      loading: null
     };
   },
   computed: {
@@ -154,14 +159,14 @@
         });
     },
     selectSurvey(survey, bottleneck) {
+      this.selectBottleneck(bottleneck);
+      this.$store.commit("bottlenecks/selectedSurvey", survey);
+    },
+    selectBottleneck(bottleneck) {
       this.$store.dispatch(
         "bottlenecks/setSelectedBottleneck",
         bottleneck.properties.name
       );
-      this.$store.commit("bottlenecks/selectedSurvey", survey);
-      this.moveToBottleneck(bottleneck);
-    },
-    moveToBottleneck(bottleneck) {
       this.$store.commit("map/moveMap", {
         coordinates: bottleneck.geometry.coordinates,
         zoom: 17,
@@ -172,12 +177,13 @@
       this.sortColumn = column;
       this.sortDirection = this.sortDirection === "ASC" ? "DESC" : "ASC";
     },
-    toggleBottleneck(name) {
+    loadSurveys(name) {
       this.openBottleneckSurveys = null;
       if (name === this.openBottleneck) {
         this.openBottleneck = null;
       } else {
         this.openBottleneck = name;
+        this.loading = name;
 
         HTTP.get("/surveys/" + name, {
           headers: {
@@ -186,7 +192,9 @@
           }
         })
           .then(response => {
-            this.openBottleneckSurveys = response.data.surveys;
+            this.openBottleneckSurveys = response.data.surveys.sort(
+              (a, b) => (a.date_info < b.date_info ? 1 : -1)
+            );
           })
           .catch(error => {
             const { status, data } = error.response;
@@ -194,7 +202,8 @@
               title: "Backend Error",
               message: `${status}: ${data.message || data}`
             });
-          });
+          })
+          .finally(() => (this.loading = null));
       }
     },
     displayCurrentSurvey(current) {
@@ -213,14 +222,23 @@
 <style lang="sass" scoped>
 .bottleneck-list
   overflow-y: auto
+  .bottleneck-row
+    a
+      text-decoration: none
+    &:hover
+      background: #fbfbfb
 
 .surveys
   max-height: 0
+  min-height: 0
   overflow: hidden
-  transition: max-height 0.3s ease
+  a
+    &:hover
+      background: #f3f3f3
 
 .surveys.open
-  max-height: 999px
+  max-height: 250px
+  overflow: auto
 
 .sort-link
   color: #444
--- a/client/src/components/map/fairway/Fairwayprofile.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/fairway/Fairwayprofile.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -109,7 +109,6 @@
     };
   },
   computed: {
-    ...mapGetters("map", ["getLayerByName"]),
     ...mapGetters("fairwayprofile", ["totalLength"]),
     ...mapState("application", ["showSplitscreen"]),
     ...mapState("fairwayprofile", [
@@ -122,7 +121,6 @@
       "fairwayCoordinates",
       "waterLevels",
       "selectedWaterLevel",
-      "previousCuts",
       "profileLoading"
     ]),
     ...mapState("bottlenecks", [
--- a/client/src/components/map/fairway/Profiles.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/fairway/Profiles.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -3,7 +3,7 @@
     <div style="width: 20rem">
       <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center">
         <font-awesome-icon icon="chart-area" class="mr-2"></font-awesome-icon>
-        Profiles
+        <translate>Profiles</translate>
         <font-awesome-icon
           icon="times"
           class="ml-auto text-muted"
@@ -11,11 +11,20 @@
         ></font-awesome-icon>
       </h6>
       <div class="d-flex flex-column p-3 flex-grow-1 text-left position-relative">
-        <div class="loading d-flex justify-content-center align-items-center" v-if="surveysLoading || profileLoading">
-          <font-awesome-icon icon="spinner" spin />
+        <div
+          class="loading d-flex justify-content-center align-items-center"
+          v-if="surveysLoading || profileLoading"
+        >
+          <font-awesome-icon icon="spinner" spin/>
         </div>
-        <select @click="moveToBottleneck" v-model="selectedBottleneck" class="form-control font-weight-bold">
-          <option :value="null">Select Bottleneck</option>
+        <select
+          @click="moveToBottleneck"
+          v-model="selectedBottleneck"
+          class="form-control font-weight-bold"
+        >
+          <option :value="null">
+            <translate>Select Bottleneck</translate>
+          </option>
           <option
             v-for="bn in bottlenecks"
             :key="bn.properties.name"
@@ -25,7 +34,9 @@
         <div v-if="selectedBottleneck">
           <div class="d-flex mt-2">
             <div class="flex-fill">
-              <small class="text-muted">Sounding Result:</small>
+              <small class="text-muted">
+                <translate>Sounding Result</translate>:
+              </small>
               <select v-model="selectedSurvey" class="form-control form-control-sm">
                 <option
                   v-for="survey in surveys"
@@ -35,7 +46,9 @@
               </select>
             </div>
             <div class="flex-fill ml-3" v-if="selectedSurvey && surveys.length > 1">
-              <small class="text-muted mt-1">Compare with:</small>
+              <small class="text-muted mt-1">
+                <translate>Compare with</translate>:
+              </small>
               <select v-model="additionalSurvey" class="form-control form-control-sm">
                 <option :value="null">None</option>
                 <option
@@ -47,43 +60,62 @@
             </div>
           </div>
           <hr class="w-100 mb-0">
-          <small class="text-muted d-block mt-2">Saved cross profiles:</small>
+          <small class="text-muted d-block mt-2">
+            <translate>Saved cross profiles</translate>:
+          </small>
           <div class="d-flex">
-            <select :class="['form-control form-control-sm flex-fill', { 'rounded-left-only': selectedCut }]" v-model="selectedCut">
+            <select
+              :class="['form-control form-control-sm flex-fill', { 'rounded-left-only': selectedCut }]"
+              v-model="selectedCut"
+            >
               <option></option>
-              <option v-for="(cut, index) in previousCuts" :value="cut" :key="index">
-                {{ cut.label }}
-              </option>
+              <option v-for="(cut, index) in previousCuts" :value="cut" :key="index">{{ cut.label }}</option>
             </select>
             <button
               class="btn btn-sm btn-danger input-button-right"
               @click="confirmDeleteSelectedCut = true"
               v-if="selectedCut && !confirmDeleteSelectedCut"
-            ><font-awesome-icon icon="trash" /></button>
+            >
+              <font-awesome-icon icon="trash"/>
+            </button>
             <button
               class="btn btn-sm btn-info rounded-0"
               @click="confirmDeleteSelectedCut = false"
               v-if="selectedCut && confirmDeleteSelectedCut"
-            ><font-awesome-icon icon="times" /></button>
+            >
+              <font-awesome-icon icon="times"/>
+            </button>
             <button
               class="btn btn-sm btn-danger input-button-right"
               @click="deleteSelectedCut"
               v-if="selectedCut && confirmDeleteSelectedCut"
-            ><font-awesome-icon icon="check" /></button>
+            >
+              <font-awesome-icon icon="check"/>
+            </button>
           </div>
-          <small class="text-muted d-block mt-2">Enter coordinates manually:</small>
+          <small class="text-muted d-block mt-2">
+            <translate>Enter coordinates manually</translate>:
+          </small>
           <div class="position-relative">
-            <input class="form-control form-control-sm pr-5" placeholder="Lat,Lon,Lat,Lon" v-model="coordinatesInput" />
+            <input
+              class="form-control form-control-sm pr-5"
+              placeholder="Lat,Lon,Lat,Lon"
+              v-model="coordinatesInput"
+            >
             <button
-              class="btn btn-sm btn-info position-absolute input-button-right" 
+              class="btn btn-sm btn-info position-absolute input-button-right"
               @click="applyManualCoordinates"
               style="top: 0; right: 0;"
               v-if="coordinatesInputIsValid"
-            ><font-awesome-icon icon="check" /></button>
+            >
+              <font-awesome-icon icon="check"/>
+            </button>
           </div>
           <small class="d-flex text-left mt-2" v-if="startPoint && endPoint">
             <div class="text-nowrap mr-3">
-              <b>Start:</b>
+              <b>
+                <translate>Start</translate>:
+              </b>
               <br>
               Lat: {{ startPoint[1] }}
               <br>
@@ -96,41 +128,42 @@
               <br>
               Lon: {{ endPoint[0] }}
             </div>
-            <button v-clipboard:copy="coordinatesForClipboard"
+            <button
+              v-clipboard:copy="coordinatesForClipboard"
               v-clipboard:success="onCopyCoordinates"
               class="btn btn-info btn-sm ml-auto mt-auto"
-            ><font-awesome-icon icon="copy" /></button>
+            >
+              <font-awesome-icon icon="copy"/>
+            </button>
           </small>
           <div class="d-flex mt-3">
             <div class="pr-3 w-50" v-if="startPoint && endPoint && !selectedCut">
-              <button
-                class="btn btn-info btn-sm w-100"
-                @click="showLabelInput = !showLabelInput"
-              >
-                <font-awesome-icon :icon="showLabelInput ? 'times' : 'check'" />
+              <button class="btn btn-info btn-sm w-100" @click="showLabelInput = !showLabelInput">
+                <font-awesome-icon :icon="showLabelInput ? 'times' : 'check'"/>
                 {{ showLabelInput ? "Cancel" : "Save" }}
               </button>
             </div>
             <div :class="startPoint && endPoint && !selectedCut ? 'w-50' : 'w-100'">
-              <button
-                class="btn btn-info btn-sm w-100"
-                @click="toggleCutTool"
-              >
+              <button class="btn btn-info btn-sm w-100" @click="toggleCutTool">
                 <font-awesome-icon :icon="cutTool && cutTool.getActive() ? 'times' : 'plus'"></font-awesome-icon>
                 {{ cutTool && cutTool.getActive() ? "Cancel" : "New" }}
               </button>
             </div>
           </div>
           <div v-if="showLabelInput" class="mt-2">
-            <small class="text-muted">Enter label for cross profile:</small>
+            <small class="text-muted">
+              <translate>Enter label for cross profile</translate>:
+            </small>
             <div class="position-relative">
-              <input class="form-control form-control-sm pr-5" v-model="cutLabel" />
+              <input class="form-control form-control-sm pr-5" v-model="cutLabel">
               <button
                 class="btn btn-sm btn-info position-absolute input-button-right"
                 @click="saveCut"
                 v-if="cutLabel"
                 style="top: 0; right: 0;"
-              ><font-awesome-icon icon="check" /></button>
+              >
+                <font-awesome-icon icon="check"/>
+              </button>
             </div>
           </div>
         </div>
@@ -160,7 +193,7 @@
     border-bottom-right-radius: 0 !important
     border-top-left-radius: $border-radius
     border-bottom-left-radius: $border-radius
-    
+
 </style>
 
 <script>
@@ -170,7 +203,7 @@
  * SPDX-License-Identifier: AGPL-3.0-or-later
  * License-Filename: LICENSES/AGPL-3.0.txt
  *
- * Copyright (C) 2018 by via donau 
+ * Copyright (C) 2018 by via donau
  *   – Österreichische Wasserstraßen-Gesellschaft mbH
  * Software engineering by Intevation GmbH
  *
@@ -299,6 +332,13 @@
         this.lineTool.setActive(false);
         this.polygonTool.setActive(false);
         this.$store.commit("map/setCurrentMeasurement", null);
+
+        // toggle identifyTool (map events singleclick and dblclick)
+        this.$store.dispatch(
+          this.cutTool.getActive()
+            ? "map/disableIdentifyTool"
+            : "map/enableIdentifyTool"
+        );
       }
     },
     onCopyCoordinates() {
--- a/client/src/components/map/toolbar/Identify.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/toolbar/Identify.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -1,6 +1,9 @@
 <template>
     <div @click="$store.commit('application/showIdentify', !showIdentify)" class="toolbar-button">
         <font-awesome-icon icon="info" :class="{'text-info': showIdentify}"></font-awesome-icon>
+        <span :class="['indicator', { show: !showIdentify && (identifiedFeatures.length || currentMeasurement) }]">
+          {{ badgeCount }}
+        </span>
     </div>
 </template>
 
@@ -23,7 +26,11 @@
 export default {
   name: "identify",
   computed: {
-    ...mapState("application", ["showIdentify"])
+    ...mapState("application", ["showIdentify"]),
+    ...mapState("map", ["identifiedFeatures", "currentMeasurement"]),
+    badgeCount() {
+      return this.identifiedFeatures.length + !!this.currentMeasurement;
+    }
   }
 };
 </script>
--- a/client/src/components/map/toolbar/Linetool.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/toolbar/Linetool.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -32,9 +32,7 @@
       this.polygonTool.setActive(false);
       this.cutTool.setActive(false);
       this.$store.commit("map/setCurrentMeasurement", null);
-      this.getLayerByName("Draw Tool")
-        .data.getSource()
-        .clear();
+      this.getVSourceByName("Draw Tool").clear();
     }
   }
 };
--- a/client/src/components/map/toolbar/Polygontool.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/toolbar/Polygontool.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -32,9 +32,7 @@
       this.lineTool.setActive(false);
       this.cutTool.setActive(false);
       this.$store.commit("map/setCurrentMeasurement", null);
-      this.getLayerByName("Draw Tool")
-        .data.getSource()
-        .clear();
+      this.getVSourceByName("Draw Tool").clear();
     }
   }
 };
--- a/client/src/components/map/toolbar/Profiles.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/toolbar/Profiles.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -1,5 +1,5 @@
 <template>
-    <div @click="$store.commit('application/showProfiles', !showProfiles)" class="toolbar-button">
+    <div @click="$store.commit('application/showProfiles', !showProfiles)" class="toolbar-button border-0">
         <font-awesome-icon icon="chart-area" :class="{ 'text-info': showProfiles }"></font-awesome-icon>
     </div>
 </template>
--- a/client/src/components/map/toolbar/Toolbar.vue	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/components/map/toolbar/Toolbar.vue	Fri Nov 30 09:17:03 2018 +0100
@@ -1,28 +1,29 @@
 <template>
-    <div class="ml-2">
-        <div :class="'toolbar toolbar-' + (expandToolbar ? 'expanded' : 'collapsed')">
-            <Identify></Identify>
-            <Layers></Layers>
-            <Profiles></Profiles>
-            <Linetool></Linetool>
-            <Polygontool></Polygontool>
-            <Pdftool></Pdftool>
-        </div>
-        <div @click="$store.commit('application/expandToolbar', !expandToolbar)" class="toolbar-button bg-info text-white">
-            <font-awesome-icon :icon="expandToolbar ? 'angle-up' : 'angle-down'"></font-awesome-icon>
-        </div>
-    </div>
+  <div :class="'ml-2 toolbar toolbar-' + (expandToolbar ? 'expanded' : 'collapsed')">
+      <Identify></Identify>
+      <Layers></Layers>
+      <Profiles></Profiles>
+      <div @click="$store.commit('application/expandToolbar', !expandToolbar)" class="toolbar-button toolbar-toggle bg-info text-white">
+          <font-awesome-icon :icon="expandToolbar ? 'angle-up' : 'angle-down'"></font-awesome-icon>
+      </div>
+      <Linetool></Linetool>
+      <Polygontool></Polygontool>
+      <Pdftool></Pdftool>
+  </div>
 </template>
 
 <style lang="sass">
 // not scoped to affect nested components
 // doen't work when put in application/assets/application.sass... why??? o_O
 .toolbar
+  box-shadow: $shadow-xs
   overflow: hidden
   transition: max-height 0.4s
+  margin-bottom: auto
+  border-radius: $border-radius
 
 .toolbar-collapsed
-  max-height: (3 * $icon-height) + (3 * $offset)
+  max-height: (3 * $icon-height) + 1.2rem
 
 .toolbar-expanded
   max-height: 100%
@@ -36,15 +37,35 @@
   justify-content: center
   display: flex
   background: #fff
-  margin-bottom: $offset
-  border-radius: $border-radius
-  box-shadow: $shadow-xs
+  border-bottom: 1px solid #dee2e6
   z-index: 2
   pointer-events: auto
+  position: relative
+  overflow: hidden
+  &:last-child
+    border-bottom: none
   .inverted
     color: $color-info
   .grey
     color: #ddd
+  .indicator
+    color: #fff
+    background: $color-info
+    position: absolute
+    bottom: -14px
+    left: -14px
+    padding: 2px 4px 1px
+    font-size: 11px
+    line-height: 11px
+    border-top-right-radius: $border-radius
+    transition: bottom 0.3s, left 0.3s
+    &.show
+      left: 0
+      bottom: 0
+
+.toolbar-toggle
+  height: 1.2rem
+  border-bottom: none
 </style>
 
 <script>
@@ -74,7 +95,7 @@
     Pdftool: () => import("./Pdftool.vue")
   },
   computed: {
-    ...mapGetters("map", ["getLayerByName"]),
+    ...mapGetters("map", ["getVSourceByName"]),
     ...mapState("map", ["lineTool", "polygonTool", "cutTool"]),
     ...mapState("application", ["expandToolbar"])
   },
@@ -86,9 +107,8 @@
         this.polygonTool.setActive(false);
         this.cutTool.setActive(false);
         this.$store.commit("map/setCurrentMeasurement", null);
-        this.getLayerByName("Draw Tool")
-          .data.getSource()
-          .clear();
+        this.$store.dispatch("map/enableIdentifyTool");
+        this.getVSourceByName("Draw Tool").clear();
       }
     });
   }
--- a/client/src/locale/de_AT/LC_MESSAGES/app.po	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/locale/de_AT/LC_MESSAGES/app.po	Fri Nov 30 09:17:03 2018 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: wamosjs 0.1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-11-28 17:09+0100\n"
+"POT-Creation-Date: 2018-11-29 17:47+0100\n"
 "PO-Revision-Date: 2018-07-03 17:00+0200\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -26,11 +26,19 @@
 msgid "Accesslog"
 msgstr ""
 
+#: src/components/admin/usermanagement/Usermanagement.vue:71
+msgid "Add User"
+msgstr ""
+
+#: src/components/admin/importschedule/Importschedule.vue:37
+msgid "Author"
+msgstr ""
+
 #: src/components/Login.vue:59
 msgid "back to login"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:9
+#: src/components/map/contextbox/ImportSoundingresults.vue:11
 msgid "Bottleneck"
 msgstr ""
 
@@ -47,7 +55,7 @@
 msgid "Bottlenecks"
 msgstr "Engstellen"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:87
+#: src/components/map/contextbox/ImportSoundingresults.vue:110
 msgid "Cancel Upload"
 msgstr ""
 
@@ -59,34 +67,62 @@
 msgid "Chose format:"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:54
+#: src/components/map/fairway/Profiles.vue:49
+msgid "Compare with"
+msgstr ""
+
+#: src/components/Sidebar.vue:50
+msgid "Configuration"
+msgstr ""
+
+#: src/components/map/contextbox/Staging.vue:65
 msgid "Confirm"
 msgstr ""
 
-#: src/components/map/Identify.vue:47
+#: src/components/map/Identify.vue:52
 msgid "contributors."
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:22
+#: src/components/admin/usermanagement/Userdetail.vue:33
+msgid "Country"
+msgstr ""
+
+#: src/components/map/contextbox/Staging.vue:16
 msgid "Date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:39
+#: src/components/map/contextbox/ImportSoundingresults.vue:42
 msgid "Depthreference"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:81
+#: src/components/map/Pdftool.vue:25
 msgid "Download"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:25
-msgid "Dvownload"
+#: src/components/map/contextbox/ImportSoundingresults.vue:107
+msgid "Download Meta.json"
+msgstr ""
+
+#: src/components/admin/importschedule/Importschedule.vue:43
+msgid "Email"
+msgstr ""
+
+#: src/components/admin/usermanagement/Userdetail.vue:58
+msgid "Email address"
 msgstr ""
 
 #: src/components/admin/Importqueue.vue:35
 msgid "Enqueued"
 msgstr ""
 
+#: src/components/map/fairway/Profiles.vue:96
+msgid "Enter coordinates manually"
+msgstr ""
+
+#: src/components/map/fairway/Profiles.vue:154
+msgid "Enter label for cross profile"
+msgstr ""
+
 #: src/components/Login.vue:141
 msgid "Enter passphrase"
 msgstr "Passphrase"
@@ -116,20 +152,31 @@
 msgid "Identified"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:3
-msgid ""
-"Import\n"
-"    Soundingresults"
+#: src/components/admin/importschedule/Importschedule.vue:31
+msgid "Import"
 msgstr ""
 
 #: src/components/Sidebar.vue:28
 msgid "Import soundingresults"
 msgstr ""
 
-#: src/components/Sidebar.vue:56 src/components/admin/Importqueue.vue:5
+#: src/components/map/contextbox/ImportSoundingresults.vue:4
+msgid "Import Soundingresults"
+msgstr ""
+
+#: src/components/map/contextbox/Staging.vue:19
+msgid "Imported"
+msgstr ""
+
+#: src/components/Sidebar.vue:58 src/components/admin/Importqueue.vue:5
 msgid "Importqueue"
 msgstr ""
 
+#: src/components/Sidebar.vue:62
+#: src/components/admin/importschedule/Importschedule.vue:6
+msgid "Importschedule"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:36
 msgid "Kind"
 msgstr ""
@@ -158,14 +205,18 @@
 msgid "Login failed"
 msgstr "Login fehlgeschlagen"
 
-#: src/components/Sidebar.vue:62
+#: src/components/Sidebar.vue:68
 msgid "Logout"
 msgstr ""
 
-#: src/components/Sidebar.vue:52
+#: src/components/Sidebar.vue:54
 msgid "Logs"
 msgstr ""
 
+#: src/components/admin/usermanagement/Userdetail.vue:135
+msgid "Mail was sent"
+msgstr ""
+
 #: src/components/Sidebar.vue:11
 msgid "Map"
 msgstr "Karte"
@@ -175,18 +226,27 @@
 msgstr ""
 
 #: src/components/map/contextbox/Bottlenecks.vue:7
+#: src/components/map/contextbox/Staging.vue:10
 msgid "Name"
 msgstr ""
 
-#: src/components/map/Identify.vue:32
+#: src/components/admin/importschedule/Importschedule.vue:69
+msgid "New Import"
+msgstr ""
+
+#: src/components/map/Identify.vue:33
 msgid "No features identified."
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:63
-#: src/components/map/contextbox/Staging.vue:49
+#: src/components/map/contextbox/Bottlenecks.vue:67
+#: src/components/map/contextbox/Staging.vue:58
 msgid "No results."
 msgstr ""
 
+#: src/components/admin/importschedule/Importschedule.vue:66
+msgid "No schedules"
+msgstr ""
+
 #: src/components/map/Pdftool.vue:32
 msgid "Open in new window"
 msgstr ""
@@ -199,22 +259,39 @@
 msgid "Pending"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:35
+#: src/components/map/contextbox/ImportSoundingresults.vue:69
 msgid "Please enter a date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:46
+#: src/components/map/contextbox/ImportSoundingresults.vue:34
+msgid "Please enter a projection"
+msgstr ""
+
+#: src/components/map/contextbox/ImportSoundingresults.vue:52
 msgid "Please enter a reference"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:16
+#: src/components/map/contextbox/ImportSoundingresults.vue:18
 msgid "Please select a bottleneck"
 msgstr ""
 
+#: src/components/admin/usermanagement/Userdetail.vue:41
+#: src/components/admin/usermanagement/Userdetail.vue:85
+msgid "Please select one"
+msgstr ""
+
 #: src/components/map/Pdftool.vue:15
 msgid "portrait"
 msgstr ""
 
+#: src/components/map/fairway/Profiles.vue:5
+msgid "Profiles"
+msgstr ""
+
+#: src/components/map/contextbox/ImportSoundingresults.vue:24
+msgid "Projection"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:51 src/components/admin/Logs.vue:32
 msgid "Refresh"
 msgstr ""
@@ -227,15 +304,40 @@
 msgid "Request password reset!"
 msgstr ""
 
+#: src/components/admin/usermanagement/Userdetail.vue:77
+msgid "Role"
+msgstr ""
+
+#: src/components/map/fairway/Profiles.vue:63
+msgid "Saved cross profiles"
+msgstr ""
+
+#: src/components/admin/importschedule/Importschedule.vue:40
+msgid "Schedule"
+msgstr ""
+
+#: src/components/map/fairway/Profiles.vue:25
+#, fuzzy
+msgid "Select Bottleneck"
+msgstr "Engstellen"
+
 #: src/components/admin/Systemconfiguration.vue:14
 msgid "Send"
 msgstr ""
 
-#: src/components/map/Identify.vue:45
+#: src/components/admin/usermanagement/Userdetail.vue:132
+msgid "Send testmail"
+msgstr ""
+
+#: src/components/map/Identify.vue:50
 msgid "Some data"
 msgstr ""
 
-#: src/components/map/Identify.vue:41
+#: src/components/map/fairway/Profiles.vue:37
+msgid "Sounding Result"
+msgstr ""
+
+#: src/components/map/Identify.vue:45
 msgid "source-code"
 msgstr ""
 
@@ -243,42 +345,74 @@
 msgid "Staging area"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:3
+#: src/components/map/contextbox/Staging.vue:4
 msgid "Staging Area"
 msgstr ""
 
+#: src/components/map/fairway/Profiles.vue:116
+msgid "Start"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:38
 msgid "State"
 msgstr ""
 
+#: src/components/admin/usermanagement/Userdetail.vue:123
+msgid "Submit"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:25
 msgid "Successful"
 msgstr ""
 
-#: src/components/Sidebar.vue:38
+#: src/components/admin/usermanagement/Userdetail.vue:88
+msgid "Sysadmin"
+msgstr ""
+
+#: src/components/Sidebar.vue:39
 msgid "Systemadministration"
 msgstr ""
 
-#: src/components/Sidebar.vue:48 src/components/admin/Systemconfiguration.vue:3
+#: src/components/admin/Systemconfiguration.vue:3
 msgid "Systemconfiguration"
 msgstr ""
 
-#: src/components/map/Identify.vue:36
+#: src/components/map/Identify.vue:37
 msgid "This app uses"
 msgstr ""
 
+#: src/components/admin/importschedule/Importschedule.vue:34
+#: src/components/map/contextbox/Staging.vue:13
+msgid "Type"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:37
 msgid "User"
 msgstr ""
 
-#: src/components/Sidebar.vue:42
+#: src/components/admin/usermanagement/Userdetail.vue:14
+#: src/components/map/contextbox/Staging.vue:22
+#, fuzzy
+msgid "Username"
+msgstr "Passphrase"
+
+#: src/components/Sidebar.vue:44
+#: src/components/admin/usermanagement/Usermanagement.vue:8
 msgid "Users"
 msgstr ""
 
-#: src/components/map/Identify.vue:36
+#: src/components/admin/usermanagement/Userdetail.vue:91
+msgid "Waterway Admin"
+msgstr ""
+
+#: src/components/admin/usermanagement/Userdetail.vue:94
+msgid "Waterway User"
+msgstr ""
+
+#: src/components/map/Identify.vue:39
 msgid "which is Free Software under"
 msgstr ""
 
-#: src/components/map/Identify.vue:39
+#: src/components/map/Identify.vue:41
 msgid "without warranty, see docs for details."
 msgstr ""
--- a/client/src/locale/en_GB/LC_MESSAGES/app.po	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/locale/en_GB/LC_MESSAGES/app.po	Fri Nov 30 09:17:03 2018 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: wamosjs 0.1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-11-28 17:09+0100\n"
+"POT-Creation-Date: 2018-11-29 17:47+0100\n"
 "PO-Revision-Date: 2018-07-03 17:18+0200\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -25,11 +25,19 @@
 msgid "Accesslog"
 msgstr ""
 
+#: src/components/admin/usermanagement/Usermanagement.vue:71
+msgid "Add User"
+msgstr ""
+
+#: src/components/admin/importschedule/Importschedule.vue:37
+msgid "Author"
+msgstr ""
+
 #: src/components/Login.vue:59
 msgid "back to login"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:9
+#: src/components/map/contextbox/ImportSoundingresults.vue:11
 msgid "Bottleneck"
 msgstr ""
 
@@ -46,7 +54,7 @@
 msgid "Bottlenecks"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:87
+#: src/components/map/contextbox/ImportSoundingresults.vue:110
 msgid "Cancel Upload"
 msgstr ""
 
@@ -58,34 +66,62 @@
 msgid "Chose format:"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:54
+#: src/components/map/fairway/Profiles.vue:49
+msgid "Compare with"
+msgstr ""
+
+#: src/components/Sidebar.vue:50
+msgid "Configuration"
+msgstr ""
+
+#: src/components/map/contextbox/Staging.vue:65
 msgid "Confirm"
 msgstr ""
 
-#: src/components/map/Identify.vue:47
+#: src/components/map/Identify.vue:52
 msgid "contributors."
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:22
+#: src/components/admin/usermanagement/Userdetail.vue:33
+msgid "Country"
+msgstr ""
+
+#: src/components/map/contextbox/Staging.vue:16
 msgid "Date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:39
+#: src/components/map/contextbox/ImportSoundingresults.vue:42
 msgid "Depthreference"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:81
+#: src/components/map/Pdftool.vue:25
 msgid "Download"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:25
-msgid "Dvownload"
+#: src/components/map/contextbox/ImportSoundingresults.vue:107
+msgid "Download Meta.json"
+msgstr ""
+
+#: src/components/admin/importschedule/Importschedule.vue:43
+msgid "Email"
+msgstr ""
+
+#: src/components/admin/usermanagement/Userdetail.vue:58
+msgid "Email address"
 msgstr ""
 
 #: src/components/admin/Importqueue.vue:35
 msgid "Enqueued"
 msgstr ""
 
+#: src/components/map/fairway/Profiles.vue:96
+msgid "Enter coordinates manually"
+msgstr ""
+
+#: src/components/map/fairway/Profiles.vue:154
+msgid "Enter label for cross profile"
+msgstr ""
+
 #: src/components/Login.vue:141
 msgid "Enter passphrase"
 msgstr "Enter passphrase"
@@ -115,20 +151,31 @@
 msgid "Identified"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:3
-msgid ""
-"Import\n"
-"    Soundingresults"
+#: src/components/admin/importschedule/Importschedule.vue:31
+msgid "Import"
 msgstr ""
 
 #: src/components/Sidebar.vue:28
 msgid "Import soundingresults"
 msgstr ""
 
-#: src/components/Sidebar.vue:56 src/components/admin/Importqueue.vue:5
+#: src/components/map/contextbox/ImportSoundingresults.vue:4
+msgid "Import Soundingresults"
+msgstr ""
+
+#: src/components/map/contextbox/Staging.vue:19
+msgid "Imported"
+msgstr ""
+
+#: src/components/Sidebar.vue:58 src/components/admin/Importqueue.vue:5
 msgid "Importqueue"
 msgstr ""
 
+#: src/components/Sidebar.vue:62
+#: src/components/admin/importschedule/Importschedule.vue:6
+msgid "Importschedule"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:36
 msgid "Kind"
 msgstr ""
@@ -157,14 +204,18 @@
 msgid "Login failed"
 msgstr "Login failed"
 
-#: src/components/Sidebar.vue:62
+#: src/components/Sidebar.vue:68
 msgid "Logout"
 msgstr ""
 
-#: src/components/Sidebar.vue:52
+#: src/components/Sidebar.vue:54
 msgid "Logs"
 msgstr ""
 
+#: src/components/admin/usermanagement/Userdetail.vue:135
+msgid "Mail was sent"
+msgstr ""
+
 #: src/components/Sidebar.vue:11
 msgid "Map"
 msgstr ""
@@ -174,18 +225,27 @@
 msgstr ""
 
 #: src/components/map/contextbox/Bottlenecks.vue:7
+#: src/components/map/contextbox/Staging.vue:10
 msgid "Name"
 msgstr ""
 
-#: src/components/map/Identify.vue:32
+#: src/components/admin/importschedule/Importschedule.vue:69
+msgid "New Import"
+msgstr ""
+
+#: src/components/map/Identify.vue:33
 msgid "No features identified."
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:63
-#: src/components/map/contextbox/Staging.vue:49
+#: src/components/map/contextbox/Bottlenecks.vue:67
+#: src/components/map/contextbox/Staging.vue:58
 msgid "No results."
 msgstr ""
 
+#: src/components/admin/importschedule/Importschedule.vue:66
+msgid "No schedules"
+msgstr ""
+
 #: src/components/map/Pdftool.vue:32
 msgid "Open in new window"
 msgstr ""
@@ -198,22 +258,39 @@
 msgid "Pending"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:35
+#: src/components/map/contextbox/ImportSoundingresults.vue:69
 msgid "Please enter a date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:46
+#: src/components/map/contextbox/ImportSoundingresults.vue:34
+msgid "Please enter a projection"
+msgstr ""
+
+#: src/components/map/contextbox/ImportSoundingresults.vue:52
 msgid "Please enter a reference"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:16
+#: src/components/map/contextbox/ImportSoundingresults.vue:18
 msgid "Please select a bottleneck"
 msgstr ""
 
+#: src/components/admin/usermanagement/Userdetail.vue:41
+#: src/components/admin/usermanagement/Userdetail.vue:85
+msgid "Please select one"
+msgstr ""
+
 #: src/components/map/Pdftool.vue:15
 msgid "portrait"
 msgstr ""
 
+#: src/components/map/fairway/Profiles.vue:5
+msgid "Profiles"
+msgstr ""
+
+#: src/components/map/contextbox/ImportSoundingresults.vue:24
+msgid "Projection"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:51 src/components/admin/Logs.vue:32
 msgid "Refresh"
 msgstr ""
@@ -226,15 +303,39 @@
 msgid "Request password reset!"
 msgstr ""
 
+#: src/components/admin/usermanagement/Userdetail.vue:77
+msgid "Role"
+msgstr ""
+
+#: src/components/map/fairway/Profiles.vue:63
+msgid "Saved cross profiles"
+msgstr ""
+
+#: src/components/admin/importschedule/Importschedule.vue:40
+msgid "Schedule"
+msgstr ""
+
+#: src/components/map/fairway/Profiles.vue:25
+msgid "Select Bottleneck"
+msgstr ""
+
 #: src/components/admin/Systemconfiguration.vue:14
 msgid "Send"
 msgstr ""
 
-#: src/components/map/Identify.vue:45
+#: src/components/admin/usermanagement/Userdetail.vue:132
+msgid "Send testmail"
+msgstr ""
+
+#: src/components/map/Identify.vue:50
 msgid "Some data"
 msgstr ""
 
-#: src/components/map/Identify.vue:41
+#: src/components/map/fairway/Profiles.vue:37
+msgid "Sounding Result"
+msgstr ""
+
+#: src/components/map/Identify.vue:45
 msgid "source-code"
 msgstr ""
 
@@ -242,42 +343,74 @@
 msgid "Staging area"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:3
+#: src/components/map/contextbox/Staging.vue:4
 msgid "Staging Area"
 msgstr ""
 
+#: src/components/map/fairway/Profiles.vue:116
+msgid "Start"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:38
 msgid "State"
 msgstr ""
 
+#: src/components/admin/usermanagement/Userdetail.vue:123
+msgid "Submit"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:25
 msgid "Successful"
 msgstr ""
 
-#: src/components/Sidebar.vue:38
+#: src/components/admin/usermanagement/Userdetail.vue:88
+msgid "Sysadmin"
+msgstr ""
+
+#: src/components/Sidebar.vue:39
 msgid "Systemadministration"
 msgstr ""
 
-#: src/components/Sidebar.vue:48 src/components/admin/Systemconfiguration.vue:3
+#: src/components/admin/Systemconfiguration.vue:3
 msgid "Systemconfiguration"
 msgstr ""
 
-#: src/components/map/Identify.vue:36
+#: src/components/map/Identify.vue:37
 msgid "This app uses"
 msgstr ""
 
+#: src/components/admin/importschedule/Importschedule.vue:34
+#: src/components/map/contextbox/Staging.vue:13
+msgid "Type"
+msgstr ""
+
 #: src/components/admin/Importqueue.vue:37
 msgid "User"
 msgstr ""
 
-#: src/components/Sidebar.vue:42
+#: src/components/admin/usermanagement/Userdetail.vue:14
+#: src/components/map/contextbox/Staging.vue:22
+#, fuzzy
+msgid "Username"
+msgstr "Enter passphrase"
+
+#: src/components/Sidebar.vue:44
+#: src/components/admin/usermanagement/Usermanagement.vue:8
 msgid "Users"
 msgstr ""
 
-#: src/components/map/Identify.vue:36
+#: src/components/admin/usermanagement/Userdetail.vue:91
+msgid "Waterway Admin"
+msgstr ""
+
+#: src/components/admin/usermanagement/Userdetail.vue:94
+msgid "Waterway User"
+msgstr ""
+
+#: src/components/map/Identify.vue:39
 msgid "which is Free Software under"
 msgstr ""
 
-#: src/components/map/Identify.vue:39
+#: src/components/map/Identify.vue:41
 msgid "without warranty, see docs for details."
 msgstr ""
--- a/client/src/main.js	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/main.js	Fri Nov 30 09:17:03 2018 +0100
@@ -29,91 +29,95 @@
 import VTooltip from "v-tooltip";
 import { library } from "@fortawesome/fontawesome-svg-core";
 import {
+  faAngleDown,
+  faAngleLeft,
+  faAngleRight,
+  faAngleUp,
+  faBars,
+  faBook,
+  faChartArea,
+  faCheck,
+  faCity,
+  faClipboardCheck,
+  faClock,
+  faCopy,
+  faDrawPolygon,
+  faExclamationTriangle,
   faEye,
   faEyeSlash,
-  faCopy,
-  faCheck,
-  faTimes,
+  faFilePdf,
+  faFolderPlus,
   faInfo,
   faLayerGroup,
-  faChartArea,
+  faMapMarkedAlt,
+  faMinus,
+  faPaperPlane,
+  faPencilAlt,
+  faPlus,
+  faPowerOff,
   faRuler,
-  faDrawPolygon,
-  faAngleDown,
-  faAngleUp,
-  faAngleLeft,
-  faAngleRight,
-  faFolderPlus,
-  faFilePdf,
-  faBars,
   faSearch,
   faShip,
-  faUpload,
-  faTasks,
-  faUsersCog,
-  faMapMarkedAlt,
-  faClipboardCheck,
-  faWrench,
-  faBook,
-  faPowerOff,
-  faTrash,
+  faSortAmountDown,
+  faSortAmountUp,
+  faSpinner,
   faStar,
+  faTasks,
+  faTimes,
+  faTrash,
+  faUpload,
   faUser,
-  faExclamationTriangle,
-  faPaperPlane,
-  faPlus,
-  faMinus,
-  faSortAmountUp,
-  faSortAmountDown,
-  faSpinner,
-  faCity,
-  faWater
+  faUsersCog,
+  faWater,
+  faWrench
 } from "@fortawesome/free-solid-svg-icons";
 import { faAdn } from "@fortawesome/free-brands-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
 import VueClipboard from "vue-clipboard2";
 
 library.add(
+  faAdn,
+  faAngleDown,
+  faAngleLeft,
+  faAngleRight,
+  faAngleUp,
+  faBars,
+  faBook,
+  faChartArea,
+  faCheck,
+  faCity,
+  faClipboardCheck,
+  faClock,
+  faCopy,
+  faDrawPolygon,
+  faExclamationTriangle,
   faEye,
   faEyeSlash,
-  faCopy,
-  faCheck,
-  faTimes,
+  faFilePdf,
+  faFolderPlus,
   faInfo,
   faLayerGroup,
-  faChartArea,
+  faMapMarkedAlt,
+  faMinus,
+  faPaperPlane,
+  faPencilAlt,
+  faPlus,
+  faPowerOff,
   faRuler,
-  faDrawPolygon,
-  faAngleDown,
-  faAngleUp,
-  faAngleLeft,
-  faAngleRight,
-  faFolderPlus,
-  faFilePdf,
-  faBars,
   faSearch,
   faShip,
-  faUpload,
-  faTasks,
-  faUsersCog,
-  faMapMarkedAlt,
-  faClipboardCheck,
-  faWrench,
-  faBook,
-  faPowerOff,
-  faTrash,
+  faSortAmountDown,
+  faSortAmountUp,
+  faSpinner,
   faStar,
-  faAdn,
+  faTasks,
+  faTimes,
+  faTrash,
+  faUpload,
   faUser,
-  faExclamationTriangle,
-  faPaperPlane,
-  faPlus,
-  faMinus,
-  faSortAmountUp,
-  faSortAmountDown,
-  faSpinner,
-  faCity,
-  faWater
+  faUsersCog,
+  faWater,
+  faWrench
 );
 Vue.component("font-awesome-icon", FontAwesomeIcon);
 
--- a/client/src/router.js	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/router.js	Fri Nov 30 09:17:03 2018 +0100
@@ -25,6 +25,8 @@
   import("./components/admin/usermanagement/Usermanagement.vue");
 const Logs = () => import("./components/admin/Logs.vue");
 const Importqueue = () => import("./components/admin/Importqueue.vue");
+const Importschedule = () =>
+  import("./components/admin/importschedule/Importschedule.vue");
 const Systemconfiguration = () =>
   import("./components/admin/Systemconfiguration.vue");
 
@@ -93,7 +95,23 @@
         requiresAuth: true
       },
       beforeEnter: (to, from, next) => {
-        const isWaterwayAdmin = store.getters["user/isSysAdmin"];
+        const isWaterwayAdmin = store.getters["user/isWaterwayAdmin"];
+        if (!isWaterwayAdmin) {
+          next("/");
+        } else {
+          next();
+        }
+      }
+    },
+    {
+      path: "/importschedule",
+      name: "importschedule",
+      component: Importschedule,
+      meta: {
+        requiresAuth: true
+      },
+      beforeEnter: (to, from, next) => {
+        const isWaterwayAdmin = store.getters["user/isWaterwayAdmin"];
         if (!isWaterwayAdmin) {
           next("/");
         } else {
--- a/client/src/store/fairway.js	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/store/fairway.js	Fri Nov 30 09:17:03 2018 +0100
@@ -118,12 +118,11 @@
   actions: {
     clearSelection({ commit, dispatch, rootGetters, rootState }) {
       dispatch("bottlenecks/setSelectedBottleneck", null, { root: true });
+      dispatch("map/enableIdentifyTool", null, { root: true });
       commit("clearCurrentProfile");
       commit("application/showSplitscreen", false, { root: true });
       rootState.map.cutTool.setActive(false);
-      rootGetters["map/getLayerByName"]("Cut Tool")
-        .data.getSource()
-        .clear();
+      rootGetters["map/getVSourceByName"]("Cut Tool").clear();
     },
     loadProfile({ commit, state }, survey) {
       if (state.startPoint && state.endPoint) {
@@ -190,6 +189,7 @@
         commit("profileLoading", true);
         Promise.all(profileLoaders)
           .then(() => {
+            dispatch("map/enableIdentifyTool", null, { root: true });
             rootState.map.cutTool.setActive(false);
             rootGetters["map/getVSourceByName"](
               "Fairway Dimensions"
--- a/client/src/store/imports.js	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/store/imports.js	Fri Nov 30 09:17:03 2018 +0100
@@ -22,11 +22,29 @@
   REJECTED: "rejected"
 };
 
+const SCHEDULES = {
+  DAILY: "daily",
+  MONTHLY: "monthly"
+};
+
 // initial state
 const init = () => {
   return {
     imports: [],
-    staging: []
+    staging: [],
+    schedules: [],
+    importScheduleDetail: null,
+    importScheduleDetailVisible: false
+  };
+};
+
+const newImportScheduleDetail = () => {
+  return {
+    import: "",
+    type: "",
+    author: "",
+    schedule: "",
+    emailNotification: null
   };
 };
 
@@ -35,6 +53,21 @@
   namespaced: true,
   state: init(),
   mutations: {
+    clearImportScheduleDetail: state => {
+      state.importScheduleDetail = newImportScheduleDetail();
+    },
+    deleteSchedule: (state, index) => {
+      state.schedules.splice(index, 1);
+    },
+    setImportScheduleDetailInvisible: state => {
+      state.importScheduleDetailVisible = false;
+    },
+    setImportScheduleDetailVisible: state => {
+      state.importScheduleDetailVisible = true;
+    },
+    setSchedules: (state, schedules) => {
+      state.schedules = schedules;
+    },
     setImports: (state, imports) => {
       state.imports = imports;
     },
@@ -58,6 +91,21 @@
     }
   },
   actions: {
+    getSchedules({ commit }) {
+      throw new Error("Not Implemented!");
+      return new Promise((resolve, reject) => {
+        HTTP.get("/imports", {
+          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
+        })
+          .then(response => {
+            commit("setImports", response.data.imports);
+            resolve(response);
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+    },
     getImports({ commit }) {
       return new Promise((resolve, reject) => {
         HTTP.get("/imports", {
@@ -85,23 +133,8 @@
             reject(error);
           });
       });
-    },
-    setStaging({ commit }, results) {
-      return new Promise((resolve, reject) => {
-        throw "Not implemented!";
-        HTTP.get("/imports?states=pending", {
-          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
-        })
-          .then(response => {
-            commit("setStaging", response.data.imports);
-            resolve(response);
-          })
-          .catch(error => {
-            reject(error);
-          });
-      });
     }
   }
 };
 
-export { imports, STATES };
+export { imports, STATES, SCHEDULES };
--- a/client/src/store/map.js	Fri Nov 30 09:15:47 2018 +0100
+++ b/client/src/store/map.js	Fri Nov 30 09:17:03 2018 +0100
@@ -26,6 +26,8 @@
 import { HTTP } from "../lib/http";
 import { fromLonLat } from "ol/proj";
 import { getLength, getArea } from "ol/sphere.js";
+import { unByKey } from "ol/Observable";
+import { getCenter } from "ol/extent";
 
 // initial state
 const init = () => {
@@ -36,6 +38,7 @@
       lon: 1819178,
       zoom: 11
     },
+    identifyTool: null, // event binding (singleclick, dblclick)
     identifiedFeatures: [], // map features identified by clicking on the map
     currentMeasurement: null, // distance or area from line-/polygon-/cutTool
     lineTool: null, // open layers interaction object (Draw)
@@ -362,6 +365,9 @@
     openLayersMap: (state, map) => {
       state.openLayersMap = map;
     },
+    identifyTool: (state, events) => {
+      state.identifyTool = events;
+    },
     setIdentifiedFeatures: (state, identifiedFeatures) => {
       state.identifiedFeatures = identifiedFeatures;
     },
@@ -471,6 +477,73 @@
       commit("polygonTool", polygonTool);
       commit("cutTool", cutTool);
       commit("openLayersMap", map);
+    },
+    disableIdentifyTool({ state }) {
+      unByKey(state.identifyTool);
+    },
+    enableIdentifyTool({ state, commit, dispatch, getters }) {
+      state.identifyTool = state.openLayersMap.on(
+        ["singleclick", "dblclick"],
+        event => {
+          commit("setIdentifiedFeatures", []);
+          // checking our WFS layers
+          var features = state.openLayersMap.getFeaturesAtPixel(event.pixel);
+          if (features) {
+            commit("setIdentifiedFeatures", features);
+
+            // get selected bottleneck from identified features
+            for (let feature of features) {
+              let id = feature.getId();
+              // RegExp.prototype.test() works with number, str and undefined
+              if (/^bottlenecks\./.test(id)) {
+                dispatch(
+                  "bottlenecks/setSelectedBottleneck",
+                  feature.get("objnam"),
+                  { root: true }
+                );
+                commit("moveMap", {
+                  coordinates: getCenter(
+                    feature
+                      .getGeometry()
+                      .clone()
+                      .transform("EPSG:3857", "EPSG:4326")
+                      .getExtent()
+                  ),
+                  zoom: 17,
+                  preventZoomOut: true
+                });
+              }
+            }
+          }
+
+          // DEBUG output and example how to remove the GeometryName
+          /*
+          for (let feature of features) {
+            console.log("Identified:", feature.getId());
+            for (let key of feature.getKeys()) {
+              if (key != feature.getGeometryName()) {
+                console.log(key, feature.get(key));
+              }
+            }
+          }
+          */
+
+          // trying the GetFeatureInfo way for WMS
+          var wmsSource = getters.getVSourceByName("Inland ECDIS chart Danube");
+          var url = wmsSource.getGetFeatureInfoUrl(
+            event.coordinate,
+            100 /* resolution */,
+            "EPSG:3857",
+            // { INFO_FORMAT: "application/vnd.ogc.gml" } // not allowed by d4d
+            { INFO_FORMAT: "text/plain" }
+          );
+
+          if (url) {
+            // cannot directly query here because of SOP
+            console.log("GetFeatureInfo url:", url);
+          }
+        }
+      );
     }
   }
 };