view client/src/components/gauge/Gauges.vue @ 4478:51dc4811a0e6

Gauges: Instead of dynamically scroll use crosshairs button
author Thomas Junk <thomas.junk@intevation.de>
date Wed, 25 Sep 2019 16:52:40 +0200
parents acb21e7362ce
children 008bc1ae8897
line wrap: on
line source

<template>
  <div
    :class="[
      'box ui-element rounded bg-white text-nowrap',
      { expanded: showGauges }
    ]"
  >
    <div style="width: 18rem">
      <UIBoxHeader
        icon="ruler-vertical"
        :title="gaugesLabel"
        :closeCallback="close"
      />
      <div class="box-body">
        <UISpinnerOverlay v-if="loading" />
        <div class="d-flex">
          <select
            v-model="selectedGaugeISRS"
            class="form-control font-weight-bold"
          >
            <option :value="null">
              <translate>Select Gauge</translate>
            </option>
            <optgroup
              v-for="(gaugesForCountry, cc) in orderedGauges"
              :key="cc"
              :label="cc"
            >
              <option
                v-for="g in gaugesForCountry"
                :key="g.properties.isrs_code"
                :value="g.properties.isrs_code"
              >
                {{ gaugeLabel(g) }}
              </option>
            </optgroup>
          </select>
          <button @click="takeMeThere" class="btn btn-sm btn-info">
            <font-awesome-icon icon="crosshairs" />
          </button>
        </div>
        <div v-if="selectedGaugeISRS" class="mt-2">
          <hr class="mb-1" />
          <div class="row no-gutters mb-2">
            <div class="col-6 pr-1">
              <small class="text-muted"><translate>From</translate>:</small>
              <input
                type="date"
                class="form-control form-control-sm small"
                :value="dateFrom && dateFrom.toISOString().split('T')[0]"
                @input="dateFrom = $event.target.valueAsDate"
              />
            </div>
            <div class="col-6 pl-1">
              <small class="text-muted"><translate>To</translate>:</small>
              <input
                type="date"
                class="form-control form-control-sm small"
                :value="dateTo && dateTo.toISOString().split('T')[0]"
                @input="dateTo = $event.target.valueAsDate"
              />
            </div>
          </div>
          <button
            @click="showWaterlevelDiagram()"
            class="btn btn-sm btn-info d-block w-100"
          >
            <translate>Show Waterlevels</translate>
          </button>
          <hr class="mb-1" />
          <div class="row no-gutters mb-2">
            <small class="text-muted">
              <translate>Compare to</translate>:
            </small>
            <input
              type="number"
              step="1"
              min="1900"
              :max="new Date().getFullYear()"
              class="form-control form-control-sm small"
              v-model="yearCompare"
            />
          </div>
          <button
            @click="showHydrologicalConditionsDiagram()"
            class="btn btn-sm btn-info d-block w-100 mt-2"
          >
            <translate>Show Hydrological Conditions</translate>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
input,
select {
  font-size: 0.8em;
}
</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):
 * Markus Kottländer <markus.kottlaender@intevation.de>
 */

import { mapState, mapGetters } from "vuex";
import { displayError } from "@/lib/errors";
import { pdfgen } from "@/lib/mixins";

export default {
  mixins: [pdfgen],
  data() {
    return {
      loading: false
    };
  },
  computed: {
    ...mapState("application", ["showGauges", "paneSetup"]),
    ...mapState("gauges", ["gauges", "longtermInterval"]),
    ...mapGetters("gauges", ["selectedGauge"]),
    gaugesLabel() {
      return this.$gettext("Gauges");
    },
    orderedGauges() {
      let orderedGauges = {};
      this.gauges.forEach(g => {
        let isrsInfo = this.isrsInfo(g);
        if (orderedGauges.hasOwnProperty(isrsInfo.countryCode)) {
          orderedGauges[isrsInfo.countryCode].push(g);
        } else {
          orderedGauges[isrsInfo.countryCode] = [g];
        }
      });
      return orderedGauges;
    },
    selectedGaugeISRS: {
      get() {
        return this.$store.state.gauges.selectedGaugeISRS;
      },
      set(isrs) {
        this.$store.dispatch("gauges/setSelectedGaugeISRS", isrs);
      }
    },
    dateFrom: {
      get() {
        return this.$store.state.gauges.dateFrom;
      },
      set(date) {
        this.$store.commit("gauges/dateFrom", date);
      }
    },
    dateTo: {
      get() {
        return this.$store.state.gauges.dateTo;
      },
      set(date) {
        this.$store.commit("gauges/dateTo", date);
      }
    },
    yearCompare: {
      get() {
        return this.$store.state.gauges.yearCompare;
      },
      set(year) {
        this.$store.commit("gauges/yearCompare", year);
      }
    }
  },
  watch: {
    selectedGaugeISRS(gauge) {
      if (!gauge) {
        this.$store.commit("application/paneSetup", "DEFAULT");
      }
    }
  },
  methods: {
    takeMeThere() {
      let coordinates = this.selectedGauge.geometry.coordinates;
      this.$store.dispatch("map/moveMap", {
        coordinates,
        zoom: 15,
        preventZoomOut: true
      });
    },
    close() {
      this.$store.commit("application/showGauges", false);
    },
    showWaterlevelDiagram() {
      this.loading = true;
      Promise.all([
        this.$store.dispatch("gauges/loadWaterlevels"),
        this.$store.dispatch("gauges/loadNashSutcliffe")
      ])
        .catch(error => {
          const { status, data } = error.response;
          displayError({
            title: "Backend Error",
            message: `${status}: ${data.message || data}`
          });
        })
        .finally(() => {
          this.$store.commit(
            "application/paneSetup",
            [
              "GAUGE_HYDROLOGICALCONDITIONS",
              "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS"
            ].includes(this.paneSetup)
              ? "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS"
              : "GAUGE_WATERLEVEL"
          );
          this.loading = false;
        });
    },
    showHydrologicalConditionsDiagram() {
      this.loading = true;

      Promise.all([
        this.$store.dispatch("gauges/loadLongtermWaterlevels"),
        this.$store.dispatch("gauges/loadYearWaterlevels")
      ])
        .catch(error => {
          const { status, data } = error.response;
          displayError({
            title: "Backend Error",
            message: `${status}: ${data.message || data}`
          });
        })
        .finally(() => {
          this.$store.commit(
            "application/paneSetup",
            [
              "GAUGE_WATERLEVEL",
              "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS"
            ].includes(this.paneSetup)
              ? "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS"
              : "GAUGE_HYDROLOGICALCONDITIONS"
          );
          this.loading = false;
        });
    },
    gaugeLabel(gauge) {
      return `${gauge.properties.objname} (${this.isrsInfo(gauge).orc})`;
    }
  },
  mounted() {
    this.$store.dispatch("gauges/loadGauges");
  }
};
</script>