changeset 2647:c52bf6f994c0

overview2: bottleneckview added
author Thomas Junk <thomas.junk@intevation.de>
date Thu, 14 Mar 2019 14:07:25 +0100
parents 30697735a7bc
children 4ffae834276e 9b6a02923bb4
files client/src/components/importoverview/AdditionalDetail.vue client/src/components/importoverview/BottleneckDetail.vue client/src/components/importoverview/LogDetail.vue
diffstat 3 files changed, 144 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/importoverview/AdditionalDetail.vue	Thu Mar 14 13:38:59 2019 +0100
+++ b/client/src/components/importoverview/AdditionalDetail.vue	Thu Mar 14 14:07:25 2019 +0100
@@ -53,4 +53,4 @@
 };
 </script>
 
-<style></style>
+<style lang="scss" scoped></style>
--- a/client/src/components/importoverview/BottleneckDetail.vue	Thu Mar 14 13:38:59 2019 +0100
+++ b/client/src/components/importoverview/BottleneckDetail.vue	Thu Mar 14 14:07:25 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/LogDetail.vue	Thu Mar 14 13:38:59 2019 +0100
+++ b/client/src/components/importoverview/LogDetail.vue	Thu Mar 14 14:07:25 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";