view client/src/components/importoverview/BottleneckDetail.vue @ 5629:84d01a536bec 729-node-js-newer-version

Transformed scss and sass styles into css
author Luisa Beerboom <lbeerboom@intevation.de>
date Thu, 11 May 2023 13:23:52 +0200
parents 0f258757e73a
children
line wrap: on
line source

<template>
  <div
    :class="{
      bottleneckdetails: true,
      full: !showLogs,
      split: showLogs
    }"
  >
    <div v-for="(bottleneck, index) in bottlenecks" :key="index">
      <div class="d-flex pl-2">
        <div
          @click="showBottleneckDetails(index)"
          class="mt-auto mb-auto text-info text-left"
        >
          <UISpinnerButton
            :state="showBottleneckDetail === index"
            :icons="['angle-right', 'angle-down']"
            class="text-info"
          />
        </div>
        <a @click="moveToBottleneck(index)" href="#">
          {{ bottleneck.properties.objnam }}
          <!-- objnam for Text is okay-->
        </a>
      </div>

      <div class="d-flex properties" v-if="showBottleneckDetail === index">
        <table class="w-100">
          <tr
            v-for="(info, index) in Object.keys(bottleneck.properties)"
            :key="index"
          >
            <td class="pl-4">{{ info }}</td>
            <td>
              {{ bottleneck.properties[info] }}
            </td>
          </tr>
        </table>
      </div>
    </div>
  </div>
</template>

<style scoped>
.bottleneckdetails {
  width: 100%;
  overflow-y: auto;
}
.bottleneckdetails > div {
  border-top: dashed 1px #dee2e6;
}
.bottleneckdetails > div:first-child {
  border-top: none;
}
.bottleneckdetails > div .properties {
  position: relative;
  overflow: hidden;
}
.bottleneckdetails > div .properties::after {
  content: "";
  position: absolute;
  top: 0;
  right: -5px;
  bottom: 0;
  left: -5px;
  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.4);
}
.bottleneckdetails > div .properties tr {
  font-size: 0.7rem;
}
.bottleneckdetails > div .properties tr:nth-child(odd) {
  background-color: #f8f9fa;
}

.split {
  max-height: 35vh;
}
</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 { HTTP } from "@/lib/http";
import { WFS } from "ol/format";
import { or as orFilter, equalTo as equalToFilter } from "ol/format/filter";
import { displayError } from "@/lib/errors";
import { mapState, mapGetters } from "vuex";

export default {
  data() {
    return {
      bottlenecks: [],
      showBottleneckDetail: null
    };
  },
  mounted() {
    this.loadBottlenecks();
    this.reloadBottleneckLayer();
  },
  computed: {
    ...mapState("map", ["openLayersMaps"]),
    ...mapState("imports", ["showLogs", "details"]),
    ...mapGetters("map", ["openLayersMap"])
  },
  methods: {
    reloadBottleneckLayer() {
      this.openLayersMaps.forEach(map => {
        map
          .getLayer("BOTTLENECKISOLINE")
          .getSource()
          .refresh();
      });
    },
    loadBottlenecks() {
      const generateFilter = () => {
        const { bottlenecks } = this.details.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.openLayersMap()
        .getLayer("BOTTLENECKS")
        .setVisible(true);
      this.$store.dispatch("map/moveToFeauture", {
        feature: this.bottlenecks[index],
        zoom: 17,
        preventZoomOut: true
      });
    },
    showBottleneckDetails(index) {
      if (index === this.showBottleneckDetail) {
        this.showBottleneckDetail = null;
      } else {
        this.showBottleneckDetail = index;
      }
    }
  }
};
</script>