changeset 2666:0d2650dd8f62 import-overview-rework

Merged default into import-overview-rework branch.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 14 Mar 2019 15:44:40 +0100
parents fea12fc850d2 (current diff) 3c04c8e46bd4 (diff)
children 5ece2c51d1f0
files client/src/components/importoverview/ImportOverview.vue client/src/components/importoverview/ImportOverviewAlt.vue client/src/components/importoverview/importlogs/LogDetail.vue client/src/components/importoverview/importlogs/Logs.vue client/src/components/importoverview/staging/Staging.vue client/src/components/importoverview/staging/StagingDetail.vue
diffstat 21 files changed, 482 insertions(+), 1631 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/Contextbox.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/Contextbox.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -6,9 +6,6 @@
     <ImportOverview
       v-if="contextBoxContent === 'importoverview'"
     ></ImportOverview>
-    <ImportOverviewAlt
-      v-if="contextBoxContent === 'importoverview2'"
-    ></ImportOverviewAlt>
   </div>
 </template>
 
@@ -34,9 +31,7 @@
     Bottlenecks: () => import("@/components/Bottlenecks"),
     Stretches: () => import("@/components/ImportStretches.vue"),
     ImportOverview: () =>
-      import("@/components/importoverview/ImportOverview.vue"),
-    ImportOverviewAlt: () =>
-      import("@/components/importoverview/ImportOverviewAlt.vue")
+      import("@/components/importoverview/ImportOverview.vue")
   },
   computed: {
     ...mapState("application", [
--- a/client/src/components/ImportStretches.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/ImportStretches.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -281,11 +281,13 @@
 import { mapState, mapGetters } from "vuex";
 import { displayError, displayInfo } from "@/lib/errors.js";
 import { LAYERS } from "@/store/map.js";
+import { HTTP } from "@/lib/http";
 
 export default {
   name: "importstretches",
   data() {
     return {
+      staging: [],
       edit: false,
       editExistingStretch: false,
       id: "",
@@ -346,9 +348,12 @@
     },
     loadStagingData() {
       return new Promise((resolve, reject) => {
-        this.$store
-          .dispatch("imports/getStaging")
+        HTTP.get("/imports?states=pending", {
+          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
+        })
           .then(response => {
+            const { imports } = response.data;
+            this.staging = imports;
             resolve(response);
           })
           .catch(error => {
@@ -544,7 +549,7 @@
   computed: {
     ...mapState("map", ["identifiedFeatures", "currentMeasurement"]),
     ...mapGetters("user", ["isSysAdmin"]),
-    ...mapState("imports", ["stretches", "staging"]),
+    ...mapState("imports", ["stretches"]),
     stretchesInStaging() {
       const result = [];
       for (let stretch of this.stretches) {
--- a/client/src/components/Sidebar.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/Sidebar.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -1,7 +1,7 @@
 <template>
   <div class="position-relative">
-    <span class="indicator" v-if="!showSidebar && staging.length">
-      {{ staging.length }}
+    <span class="indicator" v-if="!showSidebar && stagingNotifications">
+      {{ stagingNotifications }}
     </span>
     <div :class="sidebarStyle">
       <div
@@ -35,8 +35,8 @@
               icon="clipboard-check"
             ></font-awesome-icon>
             <span class="fix-trans-space" v-translate>Staging area</span>
-            <span class="indicator" v-if="showSidebar && staging.length">
-              {{ staging.length }}
+            <span class="indicator" v-if="showSidebar && stagingNotifications">
+              {{ stagingNotifications }}
             </span>
           </router-link>
         </div>
@@ -154,14 +154,19 @@
 import { mapGetters, mapState } from "vuex";
 import { logOff } from "@/lib/session.js";
 import { displayError } from "@/lib/errors";
+import { HTTP } from "@/lib/http";
 
 export default {
   name: "sidebar",
   props: ["routeName"],
+  data() {
+    return {
+      stagingNotifications: null
+    };
+  },
   computed: {
     ...mapGetters("user", ["isSysAdmin", "isWaterwayAdmin"]),
     ...mapState("user", ["user"]),
-    ...mapState("imports", ["staging"]),
     ...mapState("application", [
       "showSidebar",
       "showSearchbarLastState",
@@ -197,13 +202,21 @@
       );
     },
     updateIndicators() {
-      this.$store.dispatch("imports/getStaging").catch(error => {
-        const { status, data } = error.response;
-        displayError({
-          title: "Backend Error",
-          message: `${status}: ${data.message || data}`
+      this.$store;
+      HTTP.get("/imports?states=pending", {
+        headers: { "X-Gemma-Auth": localStorage.getItem("token") }
+      })
+        .then(response => {
+          const { imports } = response.data;
+          this.stagingNotifications = imports.length;
+        })
+        .catch(error => {
+          const { status, data } = error.response;
+          displayError({
+            title: "Backend Error",
+            message: `${status}: ${data.message || data}`
+          });
         });
-      });
     }
   },
   mounted() {
--- a/client/src/components/gauge/Gauges.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/gauge/Gauges.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -20,7 +20,7 @@
         </div>
         <select
           @change="moveToGauge"
-          v-model="selectedGaugeName"
+          v-model="selectedGaugeISRS"
           class="form-control font-weight-bold"
         >
           <option :value="null">
@@ -28,13 +28,13 @@
           </option>
           <option
             v-for="g in gauges"
-            :key="g.properties.objname"
-            :value="g.properties.objname"
+            :key="g.properties.isrs_code"
+            :value="g.properties.isrs_code"
           >
-            {{ g.properties.objname }}
+            {{ gaugeLabel(g) }}
           </option>
         </select>
-        <div v-if="selectedGaugeName" class="mt-2">
+        <div v-if="selectedGaugeISRS" class="mt-2">
           <hr class="mb-1" />
           <small class="text-muted">
             <translate>Time period</translate>:
@@ -103,12 +103,12 @@
     ...mapState("application", ["showGauges"]),
     ...mapState("gauges", ["gauges"]),
     ...mapGetters("gauges", ["selectedGauge"]),
-    selectedGaugeName: {
+    selectedGaugeISRS: {
       get() {
-        return this.$store.state.gauges.selectedGaugeName;
+        return this.$store.state.gauges.selectedGaugeISRS;
       },
-      set(name) {
-        this.$store.dispatch("gauges/selectedGaugeName", name);
+      set(isrs) {
+        this.$store.dispatch("gauges/selectedGaugeISRS", isrs);
       }
     }
   },
@@ -125,19 +125,27 @@
       });
     },
     showWaterlevelDiagram() {
+      // for panning the map to the gauge on opening the diagram: needs to be
+      // set outside of the expandCallback to not always refer to the currently
+      // selectedGauge
+      let coordinates = this.selectedGauge.geometry.coordinates;
+
       // configure splitscreen
       let splitscreenConf = {
         id: "gauge-waterlevel",
         component: "waterlevel",
-        title: this.$gettext("Waterlevel") + ": " + this.selectedGaugeName,
+        title:
+          this.$gettext("Waterlevel") +
+          ": " +
+          this.gaugeLabel(this.selectedGauge),
         icon: "ruler-vertical",
         closeCallback: () => {
-          this.$store.commit("gauges/selectedGaugeName", null);
+          this.$store.commit("gauges/selectedGaugeISRS", null);
           this.$store.commit("gauges/waterlevels", []);
         },
         expandCallback: () => {
           this.$store.commit("map/moveMap", {
-            coordinates: this.selectedGauge.geometry.coordinates,
+            coordinates,
             zoom: 17,
             preventZoomOut: true
           });
@@ -154,6 +162,13 @@
           this.$store.commit("application/splitscreenLoading", false);
           this.loading = false;
         });
+    },
+    gaugeLabel(gauge) {
+      let details = gauge.id
+        .split(".")[1]
+        .replace(/[()]/g, "")
+        .split(",");
+      return `${gauge.properties.objname} (${details[3]})`;
     }
   },
   mounted() {
--- a/client/src/components/gauge/Waterlevel.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/gauge/Waterlevel.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -11,11 +11,6 @@
       fill: transparent
       clip-path: url(#clip)
 
-    .zoom
-      cursor: move
-      fill: none
-      pointer-events: all
-
     .hdc-line,
     .ldc-line,
     .mw-line
@@ -31,11 +26,24 @@
     .ref-waterlevel-label
       font-size: 11px
       fill: #999
+    .hdc-ldc-area
+      fill: rgba(0, 255, 0, 0.15)
+
+    .tick
+      line
+        stroke-dasharray: 5
+        stroke: #ccc
+
+    .zoom
+      cursor: move
+      fill: none
+      pointer-events: all
     .brush
       .selection
         stroke: transparent
         fill-opacity: 0.2
       .handle
+        stroke: rgba($color-info, 0.5)
         fill: rgba($color-info, 0.5)
 </style>
 
@@ -89,9 +97,9 @@
         .append("svg")
         .attr("width", "100%")
         .attr("height", "100%");
-      let mainMargin = { top: 50, right: 20, bottom: 110, left: 80 },
+      let mainMargin = { top: 20, right: 20, bottom: 110, left: 80 },
         navMargin = {
-          top: svgHeight - mainMargin.top - 35,
+          top: svgHeight - mainMargin.top - 65,
           right: 20,
           bottom: 30,
           left: 80
@@ -124,9 +132,15 @@
       x2.domain(x.domain());
       y2.domain(y.domain());
       // creating the axes based on these scales
-      let xAxis = d3.axisBottom(x),
-        xAxis2 = d3.axisBottom(x2),
-        yAxis = d3.axisLeft(y);
+      let xAxis = d3
+        .axisTop(x)
+        .tickSizeInner(mainHeight)
+        .tickSizeOuter(0);
+      let xAxis2 = d3.axisBottom(x2);
+      let yAxis = d3
+        .axisRight(y)
+        .tickSizeInner(width)
+        .tickSizeOuter(0);
 
       // PREPARING CHART FUNCTIONS
 
@@ -167,23 +181,32 @@
       // axes
       mainChart
         .append("g")
+        .attr("class", "axis--x")
         .attr("transform", `translate(0, ${mainHeight})`)
-        .call(xAxis);
+        .call(xAxis)
+        .selectAll(".tick text")
+        .attr("y", 15);
       mainChart // label
         .append("text")
         .text(this.$gettext("Waterlevel [cm]"))
         .attr("text-anchor", "middle")
         .attr("transform", `translate(-45, ${mainHeight / 2}) rotate(-90)`);
-      mainChart.append("g").call(yAxis);
-
-      // waterlevel chart
       mainChart
-        .append("path")
-        .datum(this.waterlevels)
-        .attr("class", "line")
-        .attr("d", mainLineChart);
+        .append("g")
+        .call(yAxis)
+        .selectAll(".tick text")
+        .attr("x", -25);
 
       // reference waterlevels
+      // filling area between HDC and LDC
+      mainChart
+        .append("rect")
+        .attr("class", "hdc-ldc-area")
+        .attr("x", 0)
+        .attr("y", y(refWaterLevels.HDC))
+        .attr("width", width)
+        .attr("height", y(refWaterLevels.LDC) - y(refWaterLevels.HDC));
+
       let lastDate = this.waterlevels[this.waterlevels.length - 1].date;
       // HDC
       mainChart
@@ -231,6 +254,13 @@
         .attr("x", x(lastDate) - 20)
         .attr("y", y(refWaterLevels.MW) - 3);
 
+      // waterlevel chart
+      mainChart
+        .append("path")
+        .datum(this.waterlevels)
+        .attr("class", "line")
+        .attr("d", mainLineChart);
+
       // DRAWING NAVCHART
 
       let navChart = svg
@@ -264,7 +294,11 @@
           let s = d3.event.selection || x2.range();
           x.domain(s.map(x2.invert, x2));
           mainChart.select(".line").attr("d", mainLineChart);
-          mainChart.select(".axis--x").call(xAxis);
+          mainChart
+            .select(".axis--x")
+            .call(xAxis)
+            .selectAll(".tick text")
+            .attr("y", 15);
           svg
             .select(".zoom")
             .call(
@@ -285,7 +319,11 @@
           let t = d3.event.transform;
           x.domain(t.rescaleX(x2).domain());
           mainChart.select(".line").attr("d", mainLineChart);
-          mainChart.select(".axis--x").call(xAxis);
+          mainChart
+            .select(".axis--x")
+            .call(xAxis)
+            .selectAll(".tick text")
+            .attr("y", 15);
           navChart
             .select(".brush")
             .call(brush.move, x.range().map(t.invertX, t));
--- a/client/src/components/importoverview/AdditionalDetail.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/importoverview/AdditionalDetail.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -53,4 +53,4 @@
 };
 </script>
 
-<style></style>
+<style lang="scss" scoped></style>
--- a/client/src/components/importoverview/BottleneckDetail.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/importoverview/BottleneckDetail.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -1,5 +1,51 @@
 <template>
-  <div>Bottlenecks</div>
+  <div class="bottleneckdetails">
+    <div
+      v-for="(bottleneck, index) in bottlenecks"
+      :key="index"
+      class="d-flex flex-row"
+    >
+      <div class="d-flex flex-column">
+        <div class="d-flex flex-row">
+          <div
+            @click="showBottleneckDetails(index)"
+            class="mt-auto mb-auto text-info text-left"
+          >
+            <font-awesome-icon
+              class="pointer"
+              v-if="showBottleneckDetail === index"
+              icon="angle-down"
+              fixed-width
+            ></font-awesome-icon>
+            <font-awesome-icon
+              class="pointer"
+              v-if="!(showBottleneckDetail === index)"
+              icon="angle-right"
+              fixed-width
+            ></font-awesome-icon>
+          </div>
+          <a @click="moveToBottleneck(index)" class="small" href="#">{{
+            bottleneck.properties.objnam
+          }}</a>
+        </div>
+
+        <div class="ml-3 d-flex flex-row" v-if="showBottleneckDetail === index">
+          <table>
+            <tr
+              v-for="(info, index) in Object.keys(bottleneck.properties)"
+              :key="index"
+              class="mr-1 condensed small text-muted"
+            >
+              <td class="text-left">{{ info }}</td>
+              <td class="pl-3 text-left">
+                {{ bottleneck.properties[info] }}
+              </td>
+            </tr>
+          </table>
+        </div>
+      </div>
+    </div>
+  </div>
 </template>
 
 <script>
@@ -16,9 +62,96 @@
  * Author(s):
  * Thomas Junk <thomas.junk@intevation.de>
  */
+
+import { LAYERS } from "@/store/map.js";
+import { HTTP } from "@/lib/http";
+import { WFS } from "ol/format.js";
+import { or as orFilter, equalTo as equalToFilter } from "ol/format/filter.js";
+import { displayError } from "@/lib/errors.js";
+
+const NO_BOTTLENECK = -1;
+
 export default {
-  name: "bottleneckdetails"
+  name: "bottleneckdetails",
+  props: ["entry"],
+  data() {
+    return {
+      bottlenecks: [],
+      showBottleneckDetail: NO_BOTTLENECK
+    };
+  },
+  mounted() {
+    this.loadBottlenecks();
+  },
+  methods: {
+    loadBottlenecks() {
+      const generateFilter = () => {
+        const { bottlenecks } = this.entry.summary;
+        if (bottlenecks.length === 1)
+          return equalToFilter("bottleneck_id", bottlenecks[0]);
+        const orExpressions = bottlenecks.map(x => {
+          return equalToFilter("bottleneck_id", x);
+        });
+        return orFilter(...orExpressions);
+      };
+      const filterExpression = generateFilter();
+      const bottleneckFeatureCollectionRequest = new WFS().writeGetFeature({
+        srsName: "EPSG:4326",
+        featureNS: "gemma",
+        featurePrefix: "gemma",
+        featureTypes: ["bottlenecks_geoserver"],
+        outputFormat: "application/json",
+        filter: filterExpression
+      });
+      HTTP.post(
+        "/internal/wfs",
+        new XMLSerializer().serializeToString(
+          bottleneckFeatureCollectionRequest
+        ),
+        {
+          headers: {
+            "X-Gemma-Auth": localStorage.getItem("token"),
+            "Content-type": "text/xml; charset=UTF-8"
+          }
+        }
+      )
+        .then(response => {
+          this.bottlenecks = response.data.features;
+        })
+        .catch(error => {
+          const { status, data } = error.response;
+          displayError({
+            title: this.$gettext("Backend Error"),
+            message: `${status}: ${data.message || data}`
+          });
+        });
+    },
+    moveToBottleneck(index) {
+      this.$store.commit("map/setLayerVisible", LAYERS.BOTTLENECKS);
+      this.moveToExtent(this.bottlenecks[index]);
+    },
+    moveToExtent(feature) {
+      this.$store.commit("map/moveToExtent", {
+        feature: feature,
+        zoom: 17,
+        preventZoomOut: true
+      });
+    },
+    showBottleneckDetails(index) {
+      if (index == this.showBottleneckDetail) {
+        this.showBottleneckDetail = NO_BOTTLENECK;
+        return;
+      }
+      this.showBottleneckDetail = index;
+    }
+  }
 };
 </script>
 
-<style></style>
+<style lang="scss" scoped>
+.bottleneckdetails {
+  width: 615px;
+  max-height: 15vh;
+  overflow-y: auto;
+}
+</style>
--- a/client/src/components/importoverview/Filters.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/importoverview/Filters.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -19,47 +19,37 @@
 </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";
+
 export default {
   name: "importfilters",
-  data() {
-    return {
-      failed: false,
-      pending: false,
-      accepted: false,
-      declined: false,
-      warning: false
-    };
-  },
   methods: {
     setFilter(name) {
       if (this.loading) return;
-      this[name] = !this[name];
-      const allSet =
-        this.failed &&
-        this.pending &&
-        this.accepted &&
-        this.declined &&
-        this.warning;
-      if (allSet) {
-        this.warning = false;
-        this.successful = false;
-        this.failed = false;
-        this.pending = false;
-        this.accepted = false;
-        this.declined = false;
-        this.$store.commit("imports/clearFilers");
-      }
-      const filters = [
-        "failed",
-        "pending",
-        "accepted",
-        "declined",
-        "warning"
-      ].filter(x => this[x]);
-      this.$store.commit("imports/setFilters", filters);
+      this.$store.commit("imports/toggleFilter", name);
     }
   },
   computed: {
+    ...mapState("imports", [
+      "pending",
+      "failed",
+      "accepted",
+      "warning",
+      "declined"
+    ]),
     pendingStyle() {
       return {
         btn: true,
--- a/client/src/components/importoverview/ImportOverview.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/importoverview/ImportOverview.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -4,68 +4,50 @@
       icon="clipboard-check"
       title="Staging Area"
       :closeCallback="$parent.close"
+      :actions="[{ callback: loadLogs, icon: 'redo' }]"
     />
-    <div class="d-flex flex-row w-100 justify-content-end">
-      <button
-        class="btn btn-sm btn-outline-info align-self-start mr-3"
-        @click="refresh"
-      >
-        <font-awesome-icon icon="redo"></font-awesome-icon>
-      </button>
-    </div>
-    <div class="d-flex flex-row w-100 border-bottom">
-      <font-awesome-icon
-        class="pointer"
-        @click="toggleStaging()"
-        v-if="stagingVisible && staging.length > 0"
-        icon="angle-up"
-        fixed-width
-      ></font-awesome-icon>
-      <font-awesome-icon
-        class="pointer"
-        @click="toggleStaging()"
-        v-if="!stagingVisible && staging.length > 0"
-        icon="angle-down"
-        fixed-width
-      ></font-awesome-icon>
-      <span style="width:1.25em;" v-if="!(staging.length > 0)"></span>
-      <Staging v-if="stagingVisible && staging.length > 0"></Staging>
-      <div v-else class="d-flex flex-row">
-        <h6>
-          <small><translate>Review</translate></small>
-        </h6>
-        <small class="ml-3" v-if="!(staging.length > 0)"
-          ><translate>Nothing to review</translate></small
+    <div class="position-relative">
+      <transition name="fade">
+        <div
+          class="loading d-flex justify-content-center align-items-center"
+          v-if="loading"
         >
-      </div>
-    </div>
-    <div class="mt-2">
-      <div class="d-flex flex-row">
-        <font-awesome-icon
-          class="pointer"
-          @click="toggleLogs()"
-          v-if="logsVisible"
-          icon="angle-up"
-          fixed-width
-        ></font-awesome-icon>
-        <font-awesome-icon
-          class="pointer"
-          @click="toggleLogs()"
-          v-if="!logsVisible"
-          icon="angle-down"
-          fixed-width
-        ></font-awesome-icon>
-        <Logs v-if="logsVisible" :reload="reload"></Logs>
-        <div v-else>
-          <h6>
-            <small><translate>Logs</translate></small>
-          </h6>
+          <font-awesome-icon icon="spinner" spin />
+        </div>
+      </transition>
+      <div class="p-2 d-flex flex-row flex-fill justify-content-between">
+        <Filters></Filters>
+        <div>
+          <button
+            class="btn btn-sm btn-info"
+            :disabled="!reviewed.length"
+            @click="save"
+          >
+            <translate>Commit</translate> {{ reviewed.length }}
+          </button>
         </div>
       </div>
+      <LogEntry
+        class="border-top d-flex-flex-column w-100"
+        :entry="entry"
+        v-for="entry in imports"
+        :key="entry.id"
+      ></LogEntry>
     </div>
   </div>
 </template>
 
+<style lang="sass" scoped>
+.loading
+  background: rgba(255, 255, 255, 0.9)
+  position: absolute
+  z-index: 99
+  top: 0
+  right: 0
+  bottom: 0
+  left: 0
+</style>
+
 <script>
 /* This is Free Software under GNU Affero General Public License v >= 3.0
  * without warranty, see README.md and license for details.
@@ -80,54 +62,33 @@
  * Author(s):
  * Thomas Junk <thomas.junk@intevation.de>
  */
-import { displayError } from "@/lib/errors.js";
-import { mapState } from "vuex";
+
+import { mapState, mapGetters } from "vuex";
+import { displayError, displayInfo } from "@/lib/errors.js";
+import { STATES } from "@/store/imports.js";
 
 export default {
-  name: "importoverview",
+  name: "importoverviewalt",
+  components: {
+    Filters: () => import("./Filters.vue"),
+    LogEntry: () => import("./LogEntry.vue")
+  },
   data() {
     return {
-      reload: false
+      loading: false
     };
   },
-  components: {
-    Staging: () => import("./staging/Staging.vue"),
-    Logs: () => import("./importlogs/Logs.vue")
-  },
   computed: {
-    ...mapState("imports", ["stagingVisible", "logsVisible", "staging"])
+    ...mapState("imports", ["imports", "reviewed"]),
+    ...mapGetters("imports", ["filters"])
   },
   methods: {
-    toggleStaging() {
-      this.$store.commit("imports/setStagingVisibility", !this.stagingVisible);
-    },
-    toggleLogs() {
-      this.$store.commit("imports/setLogsVisibility", !this.logsVisible);
-    },
-    refresh() {
-      this.reload = true;
-      this.loadImportQueue();
-      this.loadLogs();
-    },
-    loadImportQueue() {
+    loadLogs() {
+      this.loading = true;
       this.$store
-        .dispatch("imports/getStaging")
+        .dispatch("imports/getImports", this.filters)
         .then(() => {
-          this.reload = false;
-        })
-        .catch(error => {
-          const { status, data } = error.response;
-          displayError({
-            title: "Backend Error",
-            message: `${status}: ${data.message || data}`
-          });
-        });
-    },
-    loadLogs() {
-      this.$store
-        .dispatch("imports/getImports")
-        .then(() => {
-          this.reload = false;
+          this.loading = false;
         })
         .catch(error => {
           const { status, data } = error.response;
@@ -136,17 +97,81 @@
             message: `${status}: ${data.message || data}`
           });
         });
+    },
+    save() {
+      if (!this.reviewed.length) return;
+
+      let popupContent = `<table class="table table-sm small mb-0 border-0" style="margin-top: -1px;">`;
+      this.reviewed.forEach(r => {
+        let imp = this.imports.find(i => i.id === r.id);
+        let approved = STATES.APPROVED === r.status;
+        popupContent += `<tr>
+          <td>${imp.id}</td>
+          <td>${imp.kind.toUpperCase()}</td>
+          <td>${this.$options.filters.dateTime(imp.enqueued)}</td>
+          <td class="text-${approved ? "success" : "danger"}">
+            ${this.$gettext(approved ? "approved" : "declined")}
+          </td>
+        </tr>`;
+      });
+      popupContent += "</table>";
+
+      this.$store.commit("application/popup", {
+        icon: "clipboard-check",
+        title: this.$gettext("Finish Review"),
+        padding: false,
+        big: true,
+        content: popupContent,
+        confirm: {
+          icon: "check",
+          callback: () => {
+            let data = this.reviewed.map(r => ({
+              id: r.id,
+              state: r.status
+            }));
+            this.$store
+              .dispatch("imports/confirmReview", data)
+              .then(response => {
+                this.loadLogs();
+                this.$store.commit("imports/setReviewed", []);
+                const messages = response.data
+                  .map(x => {
+                    if (x.message) return x.message;
+                    if (x.error) return x.error;
+                  })
+                  .join("\n\n");
+                displayInfo({
+                  title: "Staging Area",
+                  message: messages,
+                  options: {
+                    timeout: 0,
+                    buttons: [{ text: "Ok", action: null, bold: true }]
+                  }
+                });
+              })
+              .catch(error => {
+                const { status, data } = error.response;
+                displayError({
+                  title: "Backend Error",
+                  message: `${status}: ${data.message || data}`
+                });
+              });
+          }
+        },
+        cancel: {
+          label: this.$gettext("Cancel"),
+          icon: "times"
+        }
+      });
+    }
+  },
+  watch: {
+    filters() {
+      this.$store.dispatch("imports/getImports", this.filters);
     }
   },
   mounted() {
-    this.refresh();
+    this.loadLogs();
   }
 };
 </script>
-
-<style lang="scss" scoped>
-.overview {
-  max-height: 850px;
-  overflow-y: auto;
-}
-</style>
--- a/client/src/components/importoverview/ImportOverviewAlt.vue	Thu Mar 14 15:44:02 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-<template>
-  <div class="overview">
-    <UIBoxHeader
-      icon="clipboard-check"
-      title="Staging Area"
-      :closeCallback="$parent.close"
-      :actions="[{ callback: loadLogs, icon: 'redo' }]"
-    />
-    <div class="position-relative">
-      <transition name="fade">
-        <div
-          class="loading d-flex justify-content-center align-items-center"
-          v-if="loading"
-        >
-          <font-awesome-icon icon="spinner" spin />
-        </div>
-      </transition>
-      <div class="p-2 d-flex flex-row flex-fill justify-content-between">
-        <Filters></Filters>
-        <div>
-          <button
-            class="btn btn-sm btn-info"
-            :disabled="!reviewed.length"
-            @click="save"
-          >
-            <translate>Commit</translate> {{ reviewed.length }}
-          </button>
-        </div>
-      </div>
-      <LogEntry
-        class="border-top d-flex-flex-column w-100"
-        :entry="entry"
-        v-for="entry in imports"
-        :key="entry.id"
-      ></LogEntry>
-    </div>
-  </div>
-</template>
-
-<style lang="sass" scoped>
-.loading
-  background: rgba(255, 255, 255, 0.9)
-  position: absolute
-  z-index: 99
-  top: 0
-  right: 0
-  bottom: 0
-  left: 0
-</style>
-
-<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 { displayError, displayInfo } from "@/lib/errors.js";
-import { STATES } from "@/store/imports.js";
-
-export default {
-  name: "importoverviewalt",
-  components: {
-    Filters: () => import("./Filters.vue"),
-    LogEntry: () => import("./LogEntry.vue")
-  },
-  data() {
-    return {
-      loading: false
-    };
-  },
-  computed: {
-    ...mapState("imports", ["imports", "filters", "reviewed"])
-  },
-  methods: {
-    loadLogs() {
-      this.loading = true;
-      this.$store
-        .dispatch("imports/getImports")
-        .then(() => {
-          this.loading = false;
-        })
-        .catch(error => {
-          const { status, data } = error.response;
-          displayError({
-            title: this.$gettext("Backend Error"),
-            message: `${status}: ${data.message || data}`
-          });
-        });
-    },
-    save() {
-      if (!this.reviewed.length) return;
-
-      let popupContent = `<table class="table table-sm small mb-0 border-0" style="margin-top: -1px;">`;
-      this.reviewed.forEach(r => {
-        let imp = this.imports.find(i => i.id === r.id);
-        let approved = STATES.APPROVED === r.status;
-        popupContent += `<tr>
-          <td>${imp.id}</td>
-          <td>${imp.kind.toUpperCase()}</td>
-          <td>${this.$options.filters.dateTime(imp.enqueued)}</td>
-          <td class="text-${approved ? "success" : "danger"}">
-            ${this.$gettext(approved ? "approved" : "declined")}
-          </td>
-        </tr>`;
-      });
-      popupContent += "</table>";
-
-      this.$store.commit("application/popup", {
-        icon: "clipboard-check",
-        title: this.$gettext("Finish Review"),
-        padding: false,
-        big: true,
-        content: popupContent,
-        confirm: {
-          icon: "check",
-          callback: () => {
-            let data = this.reviewed.map(r => ({
-              id: r.id,
-              state: r.status
-            }));
-            this.$store
-              .dispatch("imports/confirmReview", data)
-              .then(response => {
-                this.loadLogs();
-                this.$store.commit("imports/setReviewed", []);
-                const messages = response.data
-                  .map(x => {
-                    if (x.message) return x.message;
-                    if (x.error) return x.error;
-                  })
-                  .join("\n\n");
-                displayInfo({
-                  title: "Staging Area",
-                  message: messages,
-                  options: {
-                    timeout: 0,
-                    buttons: [{ text: "Ok", action: null, bold: true }]
-                  }
-                });
-              })
-              .catch(error => {
-                const { status, data } = error.response;
-                displayError({
-                  title: "Backend Error",
-                  message: `${status}: ${data.message || data}`
-                });
-              });
-          }
-        },
-        cancel: {
-          label: this.$gettext("Cancel"),
-          icon: "times"
-        }
-      });
-    }
-  },
-  watch: {
-    filters() {
-      this.$store.dispatch("imports/getImports", this.filters);
-    }
-  },
-  mounted() {
-    this.loadLogs();
-  }
-};
-</script>
--- a/client/src/components/importoverview/LogDetail.vue	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/components/importoverview/LogDetail.vue	Thu Mar 14 15:44:40 2019 +0100
@@ -20,9 +20,9 @@
         <span class="text-info" v-if="isApprovedGaugeMeasurement">
           ({{ entry.summary.length }})</span
         >
-        <span v-if="isBottleneck" class="text-left">{{
-          data.summary.bottlenecks.length
-        }}</span>
+        <span v-if="isBottleneck" class="text-info text-left">
+          ({{ entry.summary.bottlenecks.length }})</span
+        >
         <span class="text-left" v-if="isFairwayDimension"
           >{{ entry.summary["source-organization"] }} (LOS:
           {{ entry.summary.los }})</span
@@ -113,7 +113,10 @@
       return this.entry.kind.toUpperCase();
     },
     hasAdditionalInfo() {
-      return this.entry.state == "pending" && this.isApprovedGaugeMeasurement;
+      return (
+        this.entry.state == "pending" &&
+        (this.isApprovedGaugeMeasurement || this.isBottleneck)
+      );
     },
     isFairwayDimension() {
       return this.kind === "FD";
--- a/client/src/components/importoverview/importlogs/LogDetail.vue	Thu Mar 14 15:44:02 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,329 +0,0 @@
-<template>
-  <div class="entry d-flex flex-column py-1 border-bottom">
-    <div class="d-flex flex-row position-relative">
-      <small @click="showDetails(job.id)" class="jobid ml-2 mt-1 mr-2">
-        {{ job.id }}
-      </small>
-      <small @click="showDetails(job.id)" class="enqueued mt-1  mr-2">
-        {{ formatDateTime(job.enqueued) }}
-      </small>
-      <small @click="showDetails(job.id)" class="kind mt-1 mr-2">
-        {{ job.kind.toUpperCase() }}
-      </small>
-      <small @click="showDetails(job.id)" class="user mt-1 mr-2">
-        {{ job.user }}
-      </small>
-      <small @click="showDetails(job.id)" class="signer mt-1 mr-2">
-        {{ job.signer }}
-      </small>
-      <small @click="showDetails(job.id)" class="state mt-1 mr-2">
-        <span :class="{ 'text-danger': job.state.toUpperCase() == 'FAILED' }"
-          >{{ job.state
-          }}<font-awesome-icon
-            v-if="job.warnings"
-            class="ml-1 text-warning"
-            icon="exclamation-triangle"
-            fixed-width
-          ></font-awesome-icon>
-        </span>
-        <span v-if="!job.warnings" style="margin-right: 1.6em;"></span>
-      </small>
-      <div @click="showDetails(job.id)" class="mt-1 text-info detailsbutton">
-        <font-awesome-icon
-          class="pointer"
-          v-if="show"
-          icon="angle-up"
-          fixed-width
-        ></font-awesome-icon>
-        <font-awesome-icon
-          class="pointer"
-          v-if="loading"
-          icon="spinner"
-          fixed-width
-        ></font-awesome-icon>
-        <font-awesome-icon
-          class="pointer"
-          v-if="!show && !loading"
-          icon="angle-down"
-          fixed-width
-        ></font-awesome-icon>
-      </div>
-    </div>
-    <div class="detailstable d-flex flex-row">
-      <div :class="collapse">
-        <div class="text-left">
-          <small style="margin-right:10px" class="type condensed"
-            ><translate>Kind</translate></small
-          >
-          <a
-            href="#"
-            @click="sortAsc = !sortAsc"
-            style="margin-right:58px"
-            class="datetime sort-link"
-            ><small class="condensed"><translate>Date</translate></small>
-            <small class="message condensed"
-              ><font-awesome-icon
-                :icon="sortIcon"
-                class="ml-1"
-              ></font-awesome-icon></small
-          ></a>
-          <small class="condensed"><translate>Message</translate></small>
-        </div>
-        <div class="logentries">
-          <div
-            v-for="(entry, index) in sortedEntries"
-            :key="index"
-            class="detailsrow text-left"
-          >
-            <small
-              :class="[
-                'condensed type',
-                {
-                  'text-danger': entry.kind.toUpperCase() == 'ERROR',
-                  'text-warning': entry.kind.toUpperCase() == 'WARN'
-                }
-              ]"
-              >{{ entry.kind.toUpperCase() }}</small
-            >
-            <small
-              :class="[
-                'condensed datetime',
-                {
-                  'text-danger': entry.kind.toUpperCase() == 'ERROR',
-                  'text-warning': entry.kind.toUpperCase() == 'WARN'
-                }
-              ]"
-              >{{ formatDateTime(entry.time) }}</small
-            >
-            <small
-              :class="[
-                'condensed message',
-                {
-                  'text-danger': entry.kind.toUpperCase() == 'ERROR',
-                  'text-warning': entry.kind.toUpperCase() == 'WARN'
-                }
-              ]"
-              >{{ entry.message }}</small
-            >
-          </div>
-        </div>
-      </div>
-    </div>
-  </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 { HTTP } from "@/lib/http.js";
-import { displayError } from "@/lib/errors.js";
-import locale2 from "locale2";
-
-export default {
-  name: "importqueuedetail",
-  props: ["job", "reload"],
-  data() {
-    return {
-      loading: false,
-      show: false,
-      entries: [],
-      sortAsc: true
-    };
-  },
-  mounted() {
-    this.openSpecificDetail();
-  },
-  watch: {
-    $route() {
-      this.openSpecificDetail();
-    },
-    reload() {
-      if (this.reload) {
-        this.entries = [];
-        this.show = false;
-      }
-    }
-  },
-  methods: {
-    openSpecificDetail() {
-      const { id } = this.$route.params;
-      if (id == this.job.id) {
-        this.showDetails(id);
-      } else {
-        this.show = false;
-      }
-    },
-    formatDate(date) {
-      return date
-        ? new Date(date).toLocaleDateString(locale2, {
-            day: "2-digit",
-            month: "2-digit",
-            year: "numeric"
-          })
-        : "";
-    },
-    formatDateTime(date) {
-      if (!date) return "";
-      const d = new Date(date);
-      return (
-        d.toLocaleDateString(locale2, {
-          day: "2-digit",
-          month: "2-digit",
-          year: "numeric"
-        }) +
-        " - " +
-        d.toLocaleTimeString(locale2, {
-          hour12: false
-        })
-      );
-    },
-    showDetails(id) {
-      if (this.show) {
-        this.show = false;
-        return;
-      }
-      if (this.entries.length === 0) {
-        this.loading = true;
-        HTTP.get("/imports/" + id, {
-          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
-        })
-          .then(response => {
-            const { entries } = response.data;
-            this.entries = entries;
-            this.show = true;
-            this.loading = false;
-          })
-          .catch(error => {
-            const { status, data } = error.response;
-            displayError({
-              title: this.$gettext("Backend Error"),
-              message: `${status}: ${data.message || data}`
-            });
-          });
-      } else {
-        this.show = true;
-      }
-    }
-  },
-  computed: {
-    sortedEntries() {
-      let sorted = this.entries.slice();
-      sorted.sort((r1, r2) => {
-        let d1 = new Date(r1.time);
-        let d2 = new Date(r2.time);
-        if (d2 < d1) {
-          return !this.sortAsc ? -1 : 1;
-        }
-        if (d2 > d1) {
-          return !this.sortAsc ? 1 : -1;
-        }
-        return 0;
-      });
-      return sorted;
-    },
-    sortIcon() {
-      return this.sortAsc ? "sort-amount-down" : "sort-amount-up";
-    },
-    icon() {
-      return {
-        "angle-up": !this.show,
-        "angle-down": this.show
-      };
-    },
-    collapse() {
-      return {
-        details: true,
-        collapse: true,
-        show: this.show,
-        "w-100": true
-      };
-    }
-  }
-};
-</script>
-
-<style lang="scss" scoped>
-.logentries {
-  overflow: auto;
-}
-
-.condensed {
-  font-stretch: condensed;
-}
-
-.entry {
-  background-color: white;
-  cursor: pointer;
-  width: 100%;
-}
-
-.entry:hover {
-  background-color: #efefef;
-  transition: 1.6s;
-}
-
-.detailstable {
-  margin-left: $offset;
-  margin-right: $large-offset;
-}
-
-.detailsbutton {
-  position: absolute;
-  top: 0;
-  right: 0;
-  height: 100%;
-}
-.jobid {
-  width: 5%;
-}
-
-.user {
-  width: 15%;
-}
-
-.signer {
-  width: 15%;
-}
-
-.kind {
-  width: 10%;
-}
-
-.state {
-  width: 15%;
-}
-
-.details {
-  width: 50%;
-}
-
-.detailsrow {
-  line-height: 0.7rem;
-}
-
-.type {
-  white-space: nowrap;
-}
-
-.datetime {
-  white-space: nowrap;
-  padding-left: 10px;
-  padding-right: 10px;
-}
-
-.message {
-  white-space: nowrap;
-}
-</style>
--- a/client/src/components/importoverview/importlogs/Logs.vue	Thu Mar 14 15:44:02 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-<template>
-  <div class="w-95">
-    <div class="text-left">
-      <h6><translate>Logs</translate></h6>
-    </div>
-    <div class="d-flex justify-content-between flex-row">
-      <button @click="setFilter('failed')" :class="failedStyle">
-        <translate>Failed</translate>
-      </button>
-      <button @click="setFilter('pending')" :class="pendingStyle">
-        <translate>Pending</translate>
-      </button>
-      <button @click="setFilter('declined')" :class="rejectedStyle">
-        <translate>Rejected</translate>
-      </button>
-      <button @click="setFilter('accepted')" :class="acceptedStyle">
-        <translate>Accepted</translate>
-      </button>
-      <button @click="setFilter('warning')" :class="warningStyle">
-        <translate>Warning</translate>
-      </button>
-    </div>
-    <div class="mt-3 logdetails">
-      <div v-for="job in imports" :key="job.id" class="d-flex flex-row">
-        <LogDetail :job="job"></LogDetail>
-      </div>
-    </div>
-  </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 { displayError } from "@/lib/errors.js";
-
-export default {
-  name: "logsection",
-  components: {
-    LogDetail: () => import("./LogDetail.vue")
-  },
-  props: ["reload"],
-  data() {
-    return {
-      loading: false,
-      failed: false,
-      pending: false,
-      declined: false,
-      accepted: false,
-      warning: false
-    };
-  },
-  computed: {
-    ...mapState("imports", ["imports"]),
-    pendingStyle() {
-      return {
-        btn: true,
-        "btn-sm": true,
-        "btn-outline-info": !this.pending,
-        "btn-info": this.pending
-      };
-    },
-    failedStyle() {
-      return {
-        btn: true,
-        "btn-sm": true,
-        "btn-outline-info": !this.failed,
-        "btn-info": this.failed
-      };
-    },
-    rejectedStyle() {
-      return {
-        btn: true,
-        "btn-sm": true,
-        "btn-outline-info": !this.declined,
-        "btn-info": this.declined
-      };
-    },
-    acceptedStyle() {
-      return {
-        btn: true,
-        "btn-sm": true,
-        "btn-outline-info": !this.accepted,
-        "btn-info": this.accepted
-      };
-    },
-    warningStyle() {
-      return {
-        btn: true,
-        "btn-sm": true,
-        "btn-outline-info": !this.warning,
-        "btn-info": this.warning
-      };
-    }
-  },
-  watch: {
-    reload() {
-      if (!this.reload) return;
-      this.warning = false;
-      this.successful = false;
-      this.failed = false;
-      this.pending = false;
-      this.accepted = false;
-      this.declined = false;
-    }
-  },
-  methods: {
-    setFilter(name) {
-      if (this.loading) return;
-      this[name] = !this[name];
-      const allSet =
-        this.failed &&
-        this.pending &&
-        this.accepted &&
-        this.declined &&
-        this.warning;
-      if (allSet) {
-        this.warning = false;
-        this.successful = false;
-        this.failed = false;
-        this.pending = false;
-        this.accepted = false;
-        this.declined = false;
-      }
-      this.loadFiltered();
-    },
-    loadFiltered() {
-      this.loading = true;
-      const filter = [
-        "failed",
-        "pending",
-        "accepted",
-        "declined",
-        "warning"
-      ].filter(x => this[x]);
-      this.$store
-        .dispatch("imports/getImports", filter)
-        .then(() => {
-          this.loading = false;
-        })
-        .catch(error => {
-          this.loading = false;
-          const { status, data } = error.response;
-          displayError({
-            title: this.$gettext("Backend Error"),
-            message: `${status}: ${data.message || data}`
-          });
-        });
-    }
-  }
-};
-</script>
-
-<style lang="scss" scoped>
-.logdetails {
-  overflow-y: auto;
-  max-height: 650px;
-}
-</style>
--- a/client/src/components/importoverview/staging/Staging.vue	Thu Mar 14 15:44:02 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-<template>
-  <div class="w-100">
-    <div class="d-flex justify-content-between flex-row w-100 border-bottom">
-      <h6><translate>Review</translate></h6>
-      <button class="btn btn-sm btn-info align-self-end" @click="save">
-        <translate>Confirm</translate>
-      </button>
-    </div>
-    <StagingDetail
-      :key="data.id"
-      v-for="data in filteredData"
-      :data="data"
-    ></StagingDetail>
-  </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>
- * Markus Kottländer <markus@intevation.de>
- */
-import { mapState, mapGetters } from "vuex";
-import { displayError, displayInfo } from "@/lib/errors.js";
-
-export default {
-  name: "stagingsection",
-  computed: {
-    ...mapState("imports", ["staging"]),
-    ...mapGetters("imports", ["processedReviews"]),
-    filteredData() {
-      return this.staging;
-    }
-  },
-  methods: {
-    loadImportQueue() {
-      this.$store.dispatch("imports/getStaging").catch(error => {
-        const { status, data } = error.response;
-        displayError({
-          title: "Backend Error",
-          message: `${status}: ${data.message || data}`
-        });
-      });
-    },
-    save() {
-      if (!this.processedReviews.length) return;
-      this.$store
-        .dispatch("imports/confirmReview", this.processedReviews)
-        .then(response => {
-          this.loadImportQueue();
-          const messages = response.data
-            .map(x => {
-              if (x.message) return x.message;
-              if (x.error) return x.error;
-            })
-            .join("\n\n");
-          displayInfo({
-            title: "Staging Area",
-            message: messages,
-            options: {
-              timeout: 0,
-              buttons: [{ text: "Ok", action: null, bold: true }]
-            }
-          });
-        })
-        .catch(error => {
-          const { status, data } = error.response;
-          displayError({
-            title: "Backend Error",
-            message: `${status}: ${data.message || data}`
-          });
-        });
-    }
-  },
-  components: {
-    StagingDetail: () => import("./StagingDetail.vue")
-  }
-};
-</script>
-
-<style></style>
--- a/client/src/components/importoverview/staging/StagingDetail.vue	Thu Mar 14 15:44:02 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,552 +0,0 @@
-<template>
-  <div :class="detail">
-    <div class="d-flex flex-row">
-      <div class="mt-auto d-flex flex-row mb-auto small name text-left">
-        <a
-          v-if="isSoundingResult(data.kind.toUpperCase())"
-          class="text-left"
-          @click="zoomTo()"
-          href="#"
-          >{{ data.summary.bottleneck }}</a
-        >
-        <span v-if="isBottleneck(data.kind.toUpperCase())" class="text-left"
-          ><translate>Bottlenecks</translate> ({{
-            data.summary.bottlenecks.length
-          }})</span
-        >
-        <a
-          v-if="isApprovedGaugeMeasurement(data.kind.toUpperCase())"
-          class="text-left"
-          ><translate>Approved Gauge Measurements</translate> ({{
-            data.summary.length
-          }})</a
-        >
-        <span
-          class="text-left"
-          v-if="isFairwayDimension(data.kind.toUpperCase())"
-          >{{ data.summary["source-organization"] }} (LOS:
-          {{ data.summary.los }})</span
-        >
-        <a
-          href="#"
-          class="text-left"
-          @click="zoomToStretch(data.summary.stretch)"
-          v-if="isStretch(data.kind.toUpperCase())"
-          >{{ data.summary.stretch }}</a
-        >
-      </div>
-      <div class="mt-auto mb-auto small text-left type">
-        {{ data.kind.toUpperCase() }}
-      </div>
-      <div v-if="data.summary" class="mt-auto mb-auto small text-left date">
-        {{ data.summary.date | surveyDate }}
-      </div>
-      <div v-else class="mt-auto mb-auto small text-left date">-</div>
-      <div class="mt-auto mb-auto small text-left imported">
-        {{ data.enqueued.split("T")[0] | surveyDate }}
-      </div>
-      <div class="mt-auto mb-auto small text-left username">
-        {{ data.user }}
-      </div>
-      <div class="controls d-flex flex-row justify-content-end">
-        <div>
-          <button
-            :class="{
-              'ml-3': true,
-              'mr-3': true,
-              btn: true,
-              'btn-outline-success': needsApproval(data) || isRejected(data),
-              'btn-success': isApproved(data),
-              actions: true
-            }"
-            @click="toggleApproval(data.id, $options.STATES.APPROVED)"
-          >
-            <font-awesome-icon
-              class="small pointer mb-2"
-              icon="check"
-            ></font-awesome-icon>
-          </button>
-        </div>
-        <div>
-          <button
-            :class="{
-              'mr-3': true,
-              btn: true,
-              'btn-outline-danger': needsApproval(data) || isApproved(data),
-              'btn-danger': isRejected(data),
-              actions: true
-            }"
-            @click="toggleApproval(data.id, $options.STATES.REJECTED)"
-          >
-            <font-awesome-icon
-              icon="times"
-              class="small pointer mb-2"
-            ></font-awesome-icon>
-          </button>
-        </div>
-        <div
-          v-if="
-            !isBottleneck(data.kind.toUpperCase()) ||
-              isApprovedGaugeMeasurement(data.kind.toUpperCase())
-          "
-          class="expander"
-        ></div>
-        <div v-if="isBottleneck(data.kind.toUpperCase())">
-          <div class="mt-auto mb-auto text-info text-left">
-            <font-awesome-icon
-              class="pointer"
-              @click="showDetails()"
-              v-if="show"
-              icon="angle-up"
-              fixed-width
-            ></font-awesome-icon>
-            <font-awesome-icon
-              class="pointer"
-              @click="showDetails()"
-              v-if="loading"
-              icon="spinner"
-              fixed-width
-            ></font-awesome-icon>
-            <font-awesome-icon
-              @click="showDetails()"
-              class="pointer"
-              v-if="!show && !loading"
-              icon="angle-down"
-              fixed-width
-            ></font-awesome-icon>
-          </div>
-        </div>
-        <div v-if="isApprovedGaugeMeasurement(data.kind.toUpperCase())">
-          <div
-            @click="showAGMDetails = !showAGMDetails"
-            class="mt-auto mb-auto text-info text-left"
-          >
-            <font-awesome-icon
-              class="pointer"
-              v-if="showAGMDetails"
-              icon="angle-up"
-              fixed-width
-            ></font-awesome-icon>
-            <font-awesome-icon
-              class="pointer"
-              v-if="!showAGMDetails"
-              icon="angle-down"
-              fixed-width
-            ></font-awesome-icon>
-          </div>
-        </div>
-        <div v-else class="empty"></div>
-      </div>
-    </div>
-    <div v-if="show && bottlenecks.length > 0" class="bottlenecksdetails">
-      <div
-        v-for="(bottleneck, index) in bottlenecks"
-        :key="index"
-        class="d-flex flex-row"
-      >
-        <div class="d-flex flex-column">
-          <div class="d-flex flex-row">
-            <a @click="moveToBottleneck(index)" class="small" href="#">{{
-              bottleneck.properties.objnam
-            }}</a>
-            <div
-              @click="showBottleneckDetails(index)"
-              class="small mt-auto mb-auto text-info text-left"
-            >
-              <font-awesome-icon
-                class="pointer"
-                v-if="showBottleneckDetail === index"
-                icon="angle-up"
-                fixed-width
-              ></font-awesome-icon>
-              <font-awesome-icon
-                class="pointer"
-                v-if="!(showBottleneckDetail === index)"
-                icon="angle-down"
-                fixed-width
-              ></font-awesome-icon>
-            </div>
-          </div>
-
-          <div class="d-flex flex-row" v-if="showBottleneckDetail === index">
-            <table>
-              <tr
-                v-for="(info, index) in Object.keys(bottleneck.properties)"
-                :key="index"
-                class="mr-1 small text-muted"
-              >
-                <td class="text-left">{{ info }}</td>
-                <td class="pl-3 text-left">
-                  {{ bottleneck.properties[info] }}
-                </td>
-              </tr>
-            </table>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="agmdetails" v-if="showAGMDetails">
-      <div class="pl-3 d-flex flex-row">
-        <span class="agmcode text-left"
-          ><small><translate>ISRS Code</translate></small></span
-        >
-        <span class="agmdetail text-left"
-          ><small><translate>Date of measurement</translate></small></span
-        >
-      </div>
-      <div class="diffs">
-        <div v-for="(result, index) in data.summary" :key="index">
-          <div class="pl-3 d-flex flex-row">
-            <span v-if="result.versions.length == 1" class="agmcode text-left"
-              ><small
-                >{{ result["fk-gauge-id"] }}
-                <translate>( New )</translate></small
-              ></span
-            >
-            <span v-if="result.versions.length == 2" class="agmcode text-left"
-              ><small>{{ result["fk-gauge-id"] }}</small></span
-            >
-            <span class="agmdetail text-left"
-              ><small>{{ result["measure-date"] | dateTime }}</small></span
-            >
-            <div
-              @click="toggleDiff(index)"
-              class="small ml-auto mt-auto mb-auto text-info text-left"
-            >
-              <font-awesome-icon
-                class="pointer"
-                v-if="showDiff == index"
-                icon="angle-up"
-                fixed-width
-              ></font-awesome-icon>
-              <font-awesome-icon
-                class="pointer"
-                v-if="showDiff != index"
-                icon="angle-down"
-                fixed-width
-              ></font-awesome-icon>
-            </div>
-          </div>
-          <div v-if="showDiff == index" class="pl-3 d-flex flex-row">
-            <div>
-              <div class="d-flex flex-row pl-3 text-left">
-                <div class="header border-bottom agmdetailskeys">
-                  <small><translate>Value</translate></small>
-                </div>
-                <div
-                  v-if="result.versions.length == 2"
-                  class="header border-bottom agmdetailsvalues"
-                >
-                  <small><translate>Old</translate></small>
-                </div>
-                <div class="header border-bottom agmdetailsvalues">
-                  <small><translate>New</translate></small>
-                </div>
-              </div>
-              <div
-                class="d-flex flex-row pl-3 text-left"
-                v-for="(entry, index) in Object.keys(result.versions[0])"
-                :key="index"
-              >
-                <div
-                  v-if="
-                    result.versions.length == 1 ||
-                      result.versions[0][entry] != result.versions[1][entry]
-                  "
-                  class="agmdetailskeys"
-                >
-                  <small>{{ entry }}</small>
-                </div>
-                <div
-                  v-if="
-                    result.versions.length == 1 ||
-                      result.versions[0][entry] != result.versions[1][entry]
-                  "
-                  class="agmdetailsvalues"
-                >
-                  <small>{{ result.versions[0][entry] }}</small>
-                </div>
-                <div
-                  v-if="
-                    result.versions.length == 2 &&
-                      result.versions[0][entry] != result.versions[1][entry]
-                  "
-                  class="agmdetailsvalues"
-                >
-                  <small>{{ result.versions[1][entry] }}</small>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </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 { STATES } from "@/store/imports.js";
-import { HTTP } from "@/lib/http";
-import { WFS } from "ol/format.js";
-import { or as orFilter, equalTo as equalToFilter } from "ol/format/filter.js";
-import { displayError } from "@/lib/errors.js";
-import { mapState } from "vuex";
-import { LAYERS } from "@/store/map.js";
-
-const NO_DIFF = -1;
-const NO_BOTTLENECK = -1;
-
-export default {
-  name: "stagingdetail",
-  props: ["data"],
-  data() {
-    return {
-      showDiff: NO_DIFF,
-      showAGMDetails: false,
-      showBottleneckDetail: NO_BOTTLENECK,
-      show: false,
-      loading: false,
-      bottlenecks: []
-    };
-  },
-  mounted() {
-    this.bottlenecks = [];
-    const { id } = this.$route.params;
-    this.$store.commit("imports/setImportToReview", id);
-    if (this.open) this.showDetails();
-  },
-  computed: {
-    ...mapState("imports", ["importToReview"]),
-    open() {
-      return this.importToReview == this.data.id;
-    },
-    detail() {
-      return [
-        "staging",
-        "d-flex",
-        "flex-column",
-        "w-100",
-        {
-          highlight: this.open && this.needsApproval(this.data)
-        }
-      ];
-    }
-  },
-  watch: {
-    showAGMDetails() {
-      if (!this.showAGMDetails) this.showDiff = NO_DIFF;
-    },
-    open() {
-      this.show = this.open;
-    },
-    $route() {
-      const { id } = this.$route.params;
-      this.$store.commit("imports/setImportToReview", id);
-      if (this.open) this.showDetails();
-    }
-  },
-  methods: {
-    showBottleneckDetails(index) {
-      if (index == this.showBottleneckDetail) {
-        this.showBottleneckDetail = NO_BOTTLENECK;
-        return;
-      }
-      this.showBottleneckDetail = index;
-    },
-    toggleDiff(number) {
-      if (this.showDiff !== number || this.showDiff == -1) {
-        this.showDiff = number;
-      } else {
-        this.showDiff = -1;
-      }
-    },
-    zoomToStretch(name) {
-      this.$store.commit("map/setLayerVisible", LAYERS.STRETCHES);
-      this.$store
-        .dispatch("imports/loadStretch", name)
-        .then(response => {
-          if (response.data.features.length < 1)
-            throw new Error("no feaures found for: " + name);
-          this.moveToExtent(response.data.features[0]);
-        })
-        .catch(error => {
-          console.log(error);
-          const { status, data } = error.response;
-          displayError({
-            title: this.$gettext("Backend Error"),
-            message: `${status}: ${data.message || data}`
-          });
-        });
-    },
-    showDetails() {
-      if (!this.isBottleneck(this.data.kind.toUpperCase())) return;
-      if (this.show) {
-        this.show = false;
-        return;
-      }
-      if (this.bottlenecks.length > 0) {
-        this.show = true;
-        return;
-      }
-      this.loading = true;
-      const generateFilter = () => {
-        const { bottlenecks } = this.data.summary;
-        if (bottlenecks.length === 1)
-          return equalToFilter("bottleneck_id", bottlenecks[0]);
-        const orExpressions = bottlenecks.map(x => {
-          return equalToFilter("bottleneck_id", x);
-        });
-        return orFilter(...orExpressions);
-      };
-      const filterExpression = generateFilter();
-      const bottleneckFeatureCollectionRequest = new WFS().writeGetFeature({
-        srsName: "EPSG:4326",
-        featureNS: "gemma",
-        featurePrefix: "gemma",
-        featureTypes: ["bottlenecks_geoserver"],
-        outputFormat: "application/json",
-        filter: filterExpression
-      });
-      HTTP.post(
-        "/internal/wfs",
-        new XMLSerializer().serializeToString(
-          bottleneckFeatureCollectionRequest
-        ),
-        {
-          headers: {
-            "X-Gemma-Auth": localStorage.getItem("token"),
-            "Content-type": "text/xml; charset=UTF-8"
-          }
-        }
-      )
-        .then(response => {
-          this.bottlenecks = response.data.features;
-          this.show = true;
-          this.loading = false;
-        })
-        .catch(error => {
-          const { status, data } = error.response;
-          displayError({
-            title: this.$gettext("Backend Error"),
-            message: `${status}: ${data.message || data}`
-          });
-        });
-    },
-    isFairwayDimension(kind) {
-      return kind === "FD";
-    },
-    isApprovedGaugeMeasurement(kind) {
-      return kind === "AGM";
-    },
-    isBottleneck(kind) {
-      return kind === "BN" || kind === "UBN";
-    },
-    isStretch(kind) {
-      return kind === "ST";
-    },
-    isSoundingResult(kind) {
-      return kind === "SR";
-    },
-    needsApproval(item) {
-      return item.status === STATES.NEEDSAPPROVAL;
-    },
-    isRejected(item) {
-      return item.status === STATES.REJECTED;
-    },
-    isApproved(item) {
-      return item.status === STATES.APPROVED;
-    },
-    moveToBottleneck(index) {
-      this.$store.commit("map/setLayerVisible", LAYERS.BOTTLENECKS);
-      this.moveToExtent(this.bottlenecks[index]);
-    },
-    moveToExtent(feature) {
-      this.$store.commit("map/moveToExtent", {
-        feature: feature,
-        zoom: 17,
-        preventZoomOut: true
-      });
-    },
-    moveMap(coordinates) {
-      this.$store.commit("map/moveMap", {
-        coordinates: coordinates,
-        zoom: 17,
-        preventZoomOut: true
-      });
-    },
-    zoomTo() {
-      const { lat, lon, bottleneck, date } = this.data.summary;
-      const coordinates = [lat, lon];
-      this.moveMap(coordinates);
-      this.$store
-        .dispatch("bottlenecks/setSelectedBottleneck", bottleneck)
-        .then(() => {
-          this.$store.commit("bottlenecks/setSelectedSurveyByDate", date);
-        });
-    },
-    toggleApproval(id, newStatus) {
-      this.$store.commit("imports/toggleApproval", {
-        id: id,
-        newStatus: newStatus
-      });
-    }
-  },
-  STATES: STATES
-};
-</script>
-
-<style lang="scss" scoped>
-.name {
-  width: 230px;
-}
-
-.type {
-  width: 40px;
-}
-
-.date {
-  width: 100px;
-}
-
-.imported {
-  width: 100px;
-}
-
-.username {
-  width: 50px;
-}
-
-.actions {
-  padding: 3px;
-  width: 21px;
-  height: 21px;
-}
-
-.bottlenecksdetails {
-  max-height: 300px;
-  overflow-y: auto;
-  font-stretch: condensed;
-  line-height: 0.9rem;
-}
-
-.agmdetails {
-  max-height: 300px;
-  overflow-y: auto;
-  font-stretch: condensed;
-  line-height: 0.9rem;
-}
-</style>
--- a/client/src/router.js	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/router.js	Thu Mar 14 15:44:40 2019 +0100
@@ -194,25 +194,6 @@
       }
     },
     {
-      path: "/imports/overview2/:id?",
-      name: "importoverview2",
-      component: Main,
-      meta: {
-        requiresAuth: true
-      },
-      beforeEnter: (to, from, next) => {
-        const isWaterwayAdmin = store.getters["user/isWaterwayAdmin"];
-        if (!isWaterwayAdmin) {
-          next("/");
-        } else {
-          store.commit("application/showContextBox", true);
-          store.commit("application/contextBoxContent", "importoverview2");
-          store.commit("application/showSearchbar", true);
-          next();
-        }
-      }
-    },
-    {
       path: "/stretches",
       name: "stretches",
       component: Main,
--- a/client/src/store/gauges.js	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/store/gauges.js	Thu Mar 14 15:44:40 2019 +0100
@@ -17,7 +17,7 @@
 const init = () => {
   return {
     gauges: [],
-    selectedGaugeName: null,
+    selectedGaugeISRS: null,
     waterlevels: [],
     loading: false
   };
@@ -30,7 +30,7 @@
   getters: {
     selectedGauge: state => {
       return state.gauges.find(
-        g => g.properties.objname === state.selectedGaugeName
+        g => g.properties.isrs_code === state.selectedGaugeISRS
       );
     }
   },
@@ -38,8 +38,8 @@
     gauges: (state, gauges) => {
       state.gauges = gauges;
     },
-    selectedGaugeName: (state, name) => {
-      state.selectedGaugeName = name;
+    selectedGaugeISRS: (state, isrs) => {
+      state.selectedGaugeISRS = isrs;
     },
     waterlevels: (state, data) => {
       state.waterlevels = data;
@@ -49,8 +49,8 @@
     }
   },
   actions: {
-    selectedGaugeName: ({ commit }, name) => {
-      commit("selectedGaugeName", name);
+    selectedGaugeISRS: ({ commit }, isrs) => {
+      commit("selectedGaugeISRS", isrs);
       commit("application/showGauges", true, { root: true });
       commit("application/showSplitscreen", false, { root: true });
     },
@@ -84,7 +84,7 @@
     },
     loadWaterlevels({ state, commit }, timePeriod) {
       return new Promise(resolve => {
-        if (state.selectedGaugeName && timePeriod) {
+        if (state.selectedGaugeISRS && timePeriod) {
           // generate some demo values
           setTimeout(() => {
             let data = [];
--- a/client/src/store/imports.js	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/store/imports.js	Thu Mar 14 15:44:40 2019 +0100
@@ -29,14 +29,14 @@
 // initial state
 const init = () => {
   return {
-    filters: [],
+    failed: false,
+    pending: false,
+    accepted: false,
+    declined: false,
+    warning: false,
     stretches: [],
     imports: [],
-    staging: [],
     reviewed: [],
-    importToReview: null,
-    stagingVisible: true,
-    logsVisible: true,
     show: NODETAILS,
     showAdditional: NODETAILS,
     showLogs: NODETAILS
@@ -72,28 +72,41 @@
   });
 };
 
+const clearFilterCriteria = state => {
+  state.warning = false;
+  state.successful = false;
+  state.failed = false;
+  state.pending = false;
+  state.accepted = false;
+  state.declined = false;
+};
+
 const imports = {
   init,
   namespaced: true,
   state: init(),
   getters: {
-    processedReviews: state => {
-      return state.staging
-        .filter(x => x.status !== STATES.NEEDSAPPROVAL)
-        .map(r => {
-          return {
-            id: r.id,
-            state: r.status
-          };
-        });
+    filters: state => {
+      return ["failed", "pending", "accepted", "declined", "warning"].filter(
+        x => state[x]
+      );
     }
   },
   mutations: {
-    setFilters: (state, filters) => {
-      state.filters = filters;
+    toggleFilter: (state, name) => {
+      state[name] = !state[name];
+      const allSet =
+        state.failed &&
+        state.pending &&
+        state.accepted &&
+        state.declined &&
+        state.warning;
+      if (allSet) {
+        clearFilterCriteria(state);
+      }
     },
     clearFilters: state => {
-      state.filters = [];
+      clearFilterCriteria(state);
     },
     setStretches: (state, stretches) => {
       state.stretches = stretches;
@@ -120,18 +133,6 @@
       });
       state.imports = imports;
     },
-    setStagingVisibility: (state, visibility) => {
-      state.stagingVisible = visibility;
-    },
-    setLogsVisibility: (state, visibility) => {
-      state.logsVisible = visibility;
-    },
-    setStaging: (state, staging) => {
-      const enriched = staging.map(x => {
-        return { ...x, status: STATES.NEEDSAPPROVAL };
-      });
-      state.staging = enriched;
-    },
     showDetailsFor: (state, id) => {
       state.show = id;
     },
@@ -150,11 +151,6 @@
     hideAdditionalLogs: state => {
       state.showLogs = NODETAILS;
     },
-    setImportToReview: (state, id) => {
-      if (!isNaN(parseFloat(id)) && isFinite(id)) {
-        state.importToReview = id;
-      }
-    },
     toggleApprove: (state, change) => {
       const { id, newStatus } = change;
       const stagedResult = state.imports.find(e => {
@@ -172,17 +168,6 @@
           state.reviewed.push({ id: stagedResult.id, status: newStatus });
         }
       }
-    },
-    toggleApproval: (state, change) => {
-      const { id, newStatus } = change;
-      const stagedResult = state.staging.find(e => {
-        return e.id === id;
-      });
-      if (stagedResult.status === newStatus) {
-        stagedResult.status = STATES.NEEDSAPPROVAL;
-      } else {
-        stagedResult.status = newStatus;
-      }
     }
   },
   actions: {
@@ -244,20 +229,6 @@
           });
       });
     },
-    getStaging({ commit }) {
-      return new Promise((resolve, reject) => {
-        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);
-          });
-      });
-    },
     confirmReview({ state }, reviewResults) {
       return new Promise((resolve, reject) => {
         HTTP.patch("/imports", reviewResults, {
--- a/client/src/store/map.js	Thu Mar 14 15:44:02 2019 +0100
+++ b/client/src/store/map.js	Thu Mar 14 15:44:40 2019 +0100
@@ -794,12 +794,12 @@
                 // get selected gauge
                 if (/^gauges/.test(id)) {
                   if (
-                    rootState.gauges.selectedGaugeName !==
-                    feature.get("objname")
+                    rootState.gauges.selectedGaugeISRS !==
+                    feature.get("isrs_code")
                   ) {
                     dispatch(
-                      "gauges/selectedGaugeName",
-                      feature.get("objname"),
+                      "gauges/selectedGaugeISRS",
+                      feature.get("isrs_code"),
                       {
                         root: true
                       }
--- a/pkg/imports/wa.go	Thu Mar 14 15:44:02 2019 +0100
+++ b/pkg/imports/wa.go	Thu Mar 14 15:44:40 2019 +0100
@@ -4,12 +4,13 @@
 // SPDX-License-Identifier: AGPL-3.0-or-later
 // License-Filename: LICENSES/AGPL-3.0.txt
 //
-// Copyright (C) 2018 by via donau
+// Copyright (C) 2018, 2019 by via donau
 //   – Österreichische Wasserstraßen-Gesellschaft mbH
 // Software engineering by Intevation GmbH
 //
 // Author(s):
 //  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+//  * Tom Gottfried <tom.gottfried@intevation.de>
 
 package imports
 
@@ -82,9 +83,9 @@
   WHERE country = users.current_user_country()
 )
 DELETE FROM waterway.waterway_area
-WHERE ST_Covers(
-  (SELECT a FROM resp),
-  ST_Transform(area::geometry, (SELECT t FROM resp)))
+WHERE pg_has_role('sys_admin', 'MEMBER')
+  OR ST_Covers((SELECT a FROM resp),
+    ST_Transform(area::geometry, (SELECT t FROM resp)))
 `
 	insertWaterwayAreaSQL = `
 WITH resp AS (
@@ -94,18 +95,17 @@
   WHERE country = users.current_user_country()
 )
 INSERT INTO waterway.waterway_area (area, catccl, dirimp)
-SELECT ST_Transform(clipped.geom, 4326)::geography, $3, $4 FROM (
-    SELECT (ST_Dump(
-       ST_Intersection(
-         (SELECT ST_Buffer(a, 0.0001) FROM resp),
-         ST_CollectionExtract(ST_MakeValid(ST_Transform(
-           ST_GeomFromWKB($1, $2::integer),
-           (SELECT t FROM resp)
-         )),3)
-       )
-     )).geom AS geom
-  ) AS clipped
-  WHERE clipped.geom IS NOT NULL
+SELECT ST_Transform(clipped.geom, 4326)::geography, $3, $4
+  FROM resp,
+    ST_CollectionExtract(ST_MakeValid(ST_Transform(
+      ST_GeomFromWKB($1, $2::integer), t)), 3) AS new_area (new_area),
+    LATERAL (SELECT (ST_Dump(
+      CASE WHEN pg_has_role('sys_admin', 'MEMBER')
+        THEN new_area
+        ELSE ST_Intersection(a, new_area)
+        END
+      )).geom AS geom
+    ) AS clipped
 `
 )
 
--- a/pkg/imports/wx.go	Thu Mar 14 15:44:02 2019 +0100
+++ b/pkg/imports/wx.go	Thu Mar 14 15:44:40 2019 +0100
@@ -4,12 +4,13 @@
 // SPDX-License-Identifier: AGPL-3.0-or-later
 // License-Filename: LICENSES/AGPL-3.0.txt
 //
-// Copyright (C) 2018 by via donau
+// Copyright (C) 2018, 2019 by via donau
 //   – Österreichische Wasserstraßen-Gesellschaft mbH
 // Software engineering by Intevation GmbH
 //
 // Author(s):
 //  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+//  * Tom Gottfried <tom.gottfried@intevation.de>
 
 package imports
 
@@ -81,9 +82,9 @@
   WHERE country = users.current_user_country()
 )
 DELETE FROM waterway.waterway_axis
-WHERE ST_Covers(
-  (SELECT a FROM resp),
-  ST_Transform(wtwaxs::geometry, (SELECT t FROM resp)))
+WHERE pg_has_role('sys_admin', 'MEMBER')
+  OR ST_Covers((SELECT a FROM resp),
+    ST_Transform(wtwaxs::geometry, (SELECT t FROM resp)))
 `
 
 	insertWaterwayAxisSQL = `
@@ -94,18 +95,17 @@
   WHERE country = users.current_user_country()
 )
 INSERT INTO waterway.waterway_axis (wtwaxs, objnam, nobjnam)
-SELECT ST_Transform(clipped.geom, 4326)::geography, $3, $4 FROM (
-    SELECT (ST_Dump(
-       ST_Intersection(
-         (SELECT a FROM resp),
-         ST_Transform(
-           ST_GeomFromWKB($1, $2::integer),
-           (SELECT t FROM resp)
-         )
-       )
-     )).geom AS geom
-  ) AS clipped
-  WHERE clipped.geom IS NOT NULL
+SELECT ST_Transform(clipped.geom, 4326)::geography, $3, $4
+  FROM resp,
+    ST_Node(ST_Transform(
+      ST_GeomFromWKB($1, $2::integer), t)) AS new_line (new_line),
+    LATERAL (SELECT (ST_Dump(
+      CASE WHEN pg_has_role('sys_admin', 'MEMBER')
+        THEN new_line
+        ELSE ST_Intersection(a, new_line)
+        END
+      )).geom AS geom
+    ) AS clipped
 `
 )