view client/src/components/Bottlenecks.vue @ 5443:4046432ccc9d marking-single-beam

Backout Bottleneckoverview: Put selector for older scans into date column
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 13 Jul 2021 18:30:07 +0200
parents 7d7b1bf53189
children 2ad3a29e0e14
line wrap: on
line source

<template>
  <div>
    <UIBoxHeader
      icon="ship"
      :title="bottlenecksLabel"
      :closeCallback="$parent.close"
    />
    <UITableHeader
      :columns="[
        { id: 'properties.name', title: `${nameLabel}`, width: '230px' },
        {
          id: 'properties.responsible_country',
          title: `${countryLabel}`,
          width: '100px'
        },
        {
          id: 'properties.current',
          title: `${latestmeasurementLabel}`,
          width: '150px'
        },
        { id: 'properties.from', title: `${chainageLabel}`, width: '135px' }
      ]"
    />
    <UITableBody
      :data="filteredBottlenecks() | sortTable(sortColumn, sortDirection)"
      maxHeight="35rem"
      :isActive="item => item === this.openBottleneck"
    >
      <template v-slot:row="{ item: bottleneck }">
        <div class="table-cell truncate text-left" style="width: 230px">
          <a href="#" @click="selectBottleneck(bottleneck)">{{
            bottleneck.properties.name
          }}</a>
        </div>
        <div class="table-cell text-center" style="width: 100px">
          {{ bottleneck.properties.responsible_country }}
        </div>
        <div class="table-cell" style="width: 150px">
          {{ bottleneck.properties.current | surveyDate }}
        </div>
        <div class="table-cell" style="width: 135px">
          {{
            displayCurrentChainage(
              bottleneck.properties.from,
              bottleneck.properties.to
            )
          }}
        </div>
        <div class="table-cell center" style="flex-grow: 1">
          <UISpinnerButton
            @click="loadSurveys(bottleneck)"
            :loading="loading === bottleneck"
            :state="bottleneck === openBottleneck"
            v-if="bottleneck.properties.current"
          />
        </div>
      </template>
      <template v-slot:expand="{ item: bottleneck }">
        <a
          href="#"
          class="d-inline-block px-3 py-2"
          v-for="(survey, index) in openBottleneckSurveys"
          :key="index"
          @click="selectSurvey(survey, bottleneck)"
        >
          {{ survey.date_info | surveyDate }}
        </a>
      </template>
    </UITableBody>
  </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):
 * Markus Kottländer <markus.kottlaender@intevation.de>
 */
import { mapState } from "vuex";
import { HTTP } from "@/lib/http";
import { displayError } from "@/lib/errors";
import { sortTable } from "@/lib/mixins";

export default {
  name: "bottlenecks",
  mixins: [sortTable],
  data() {
    return {
      sortColumn: "properties.name",
      openBottleneck: null,
      openBottleneckSurveys: null,
      loading: null
    };
  },
  computed: {
    ...mapState("application", ["searchQuery", "showSearchbarLastState"]),
    ...mapState("bottlenecks", ["bottlenecksList"]),
    bottlenecksLabel() {
      return this.$gettext("Bottlenecks");
    },
    countryLabel() {
      return this.$gettext("Country");
    },
    nameLabel() {
      return this.$gettext("Name");
    },
    latestmeasurementLabel() {
      return this.$gettext("Latest Measurement");
    },
    chainageLabel() {
      return this.$gettext("Chainage");
    },
    sortIcon() {
      return this.sortDirection === "ASC"
        ? "sort-amount-down"
        : "sort-amount-up";
    }
  },
  methods: {
    filteredBottlenecks() {
      return this.bottlenecksList.filter(bn => {
        return bn.properties.name
          .toLowerCase()
          .includes(this.searchQuery.toLowerCase());
      });
    },
    selectSurvey(survey, bottleneck) {
      this.$store
        .dispatch(
          "bottlenecks/setSelectedBottleneck",
          bottleneck.properties.name
        )
        .then(() => {
          this.$store.commit("bottlenecks/selectedSurvey", survey);
        })
        .then(() => {
          this.$store.dispatch("map/moveToFeauture", {
            feature: bottleneck,
            zoom: 16,
            preventZoomOut: true
          });
        });
    },
    selectBottleneck(bottleneck) {
      this.$store
        .dispatch(
          "bottlenecks/setSelectedBottleneck",
          bottleneck.properties.name
        )
        .then(() => {
          this.$store.dispatch("map/moveToFeauture", {
            feature: bottleneck,
            zoom: 16,
            preventZoomOut: true
          });
        });
      this.$store.commit(
        "bottlenecks/setBottleneckForPrint",
        bottleneck.properties.name
      );
    },
    loadSurveys(bottleneck) {
      if (bottleneck === this.openBottleneck) {
        this.openBottleneck = null;
        this.openBottleneckSurveys = null;
      } else {
        this.loading = bottleneck;
        HTTP.get("/surveys/" + encodeURIComponent(bottleneck.properties.name), {
          headers: {
            "X-Gemma-Auth": localStorage.getItem("token"),
            "Content-type": "text/xml; charset=UTF-8"
          }
        })
          .then(response => {
            this.openBottleneckSurveys = response.data.surveys.sort((a, b) => {
              return a.date_info < b.date_info ? 1 : -1;
            });
            this.openBottleneck = bottleneck;
          })
          .catch(error => {
            let message = "Backend not reachable";
            if (error.response) {
              const { status, data } = error.response;
              message = `${status}: ${data.message || data}`;
            }
            displayError({
              title: this.$gettext("Backend Error"),
              message: message
            });
          })
          .finally(() => (this.loading = null));
      }
    },
    displayCurrentChainage(from, to) {
      return from / 10 + " - " + to / 10;
    }
  },
  mounted() {
    this.$store.dispatch("bottlenecks/loadBottlenecksList");
  }
};
</script>