view client/src/components/fairway/AvailableFairwayDepthDialogue.vue @ 4231:6f31a99cd92d

clinet: fix translations process and update source strings * move strings for translations from *.po files to the component itself to let gettext() mark only the strings without the html elements. (make makemessages complains to have html elements in the .po files and stops the process).
author Fadi Abbud <fadi.abbud@intevation.de>
date Wed, 21 Aug 2019 11:13:12 +0200
parents 242057dbc8c3
children d6c38a22c71e
line wrap: on
line source

<template>
  <div
    :class="[
      'box ui-element rounded bg-white text-nowrap',
      { expanded: showFairwayDepth }
    ]"
  >
    <div style="width: 18rem">
      <UIBoxHeader icon="chart-line" :title="label" :closeCallback="close" />
      <div class="box-body">
        <UISpinnerOverlay v-if="loading" />
        <div class="mb-2 d-flex justify-content-between align-items-center">
          <div class="custom-control custom-radio custom-control-inline mr-2">
            <input
              :value="$options.BOTTLENECK"
              type="radio"
              v-model="type"
              id="type-bottleneck"
              class="custom-control-input"
            />
            <label
              class="custom-control-label small d-flex align-items-center"
              for="type-bottleneck"
            >
              <translate>Bottlenecks</translate>
            </label>
          </div>
          <div class="custom-control custom-radio custom-control-inline mr-2">
            <input
              :value="$options.STRETCH"
              type="radio"
              v-model="type"
              id="type-stretch"
              class="custom-control-input"
            />
            <label
              class="custom-control-label small d-flex align-items-center"
              for="type-stretch"
            >
              <translate>Stretches</translate>
            </label>
          </div>
          <div class="custom-control custom-radio custom-control-inline">
            <input
              :value="$options.SECTION"
              type="radio"
              v-model="type"
              id="type-section"
              class="custom-control-input"
            />
            <label
              class="custom-control-label small d-flex align-items-center"
              for="type-section"
            >
              <translate>Sections</translate>
            </label>
          </div>
        </div>
        <select
          v-if="type === $options.BOTTLENECK"
          @change="entrySelected"
          class="form-control font-weight-bold"
          v-model="selectedEntry"
        >
          <option :value="null">{{ placeholder }}</option>
          <optgroup
            v-for="(bottlenecksForCountry, cc) in orderedBottlenecks"
            :key="cc"
            :label="cc"
          >
            <option
              v-for="bn in bottlenecksForCountry"
              :key="bn.properties.id"
              :value="bn"
            >
              {{ bn.properties.name }}
            </option>
          </optgroup>
        </select>
        <select
          v-else-if="type === $options.STRETCH"
          @change="entrySelected"
          class="form-control font-weight-bold"
          v-model="selectedEntry"
        >
          <option :value="null">{{ placeholder }}</option>
          <option
            v-for="stretch in stretches"
            :value="stretch"
            :key="stretch.id"
          >
            {{ stretch.properties.name }}
          </option>
        </select>
        <select
          v-else-if="type === $options.SECTION"
          @change="entrySelected"
          class="form-control font-weight-bold"
          v-model="selectedEntry"
        >
          <option :value="null">{{ placeholder }}</option>
          <option
            v-for="section in sections"
            :value="section"
            :key="section.id"
          >
            {{ section.properties.name }}
          </option>
        </select>
        <div class="d-flex mt-2">
          <div class="d-flex flex-column w-50 mr-1">
            <small class="my-auto text-muted">
              <translate>Type</translate>
            </small>
            <select
              v-model="selectedFrequency"
              class="form-control form-control-sm"
            >
              <option
                v-for="(option, index) in $options.FREQUENCIES"
                :value="index"
                :key="index"
              >
                {{ option }}
              </option>
            </select>
          </div>
          <div class="d-flex flex-column w-50 ml-1">
            <small class="my-auto text-muted"><translate>LOS</translate></small>
            <select v-model="los" class="form-control form-control-sm">
              <option value="1">1</option>
              <option value="2">2</option>
              <option value="3">3</option>
            </select>
          </div>
        </div>
        <div class="d-flex mt-2">
          <div class="d-flex flex-column w-50 mr-1">
            <small for="from" class="my-auto text-muted">
              <translate>Date from</translate>
            </small>
            <input
              id="from"
              v-model="fromDate"
              class="form-control form-control-sm"
              type="date"
            />
          </div>
          <div class="d-flex flex-column w-50 ml-1">
            <small for="to" class="my-auto text-muted">
              <translate>Date to</translate>
            </small>
            <input
              id="to"
              v-model="toDate"
              class="form-control form-control-sm"
              type="date"
            />
          </div>
        </div>

        <div v-if="depthLimitVisible" class="d-flex mt-2" :key="1">
          <div class="d-flex flex-column w-50 mr-1">
            <small for="from" class="my-auto text-muted">
              <translate>Depthlimit 1 (in cm)</translate>
            </small>
            <input
              id="depthlimit1"
              v-model.number="depthLimit1"
              class="form-control form-control-sm"
              type="number"
              min="0"
            />
          </div>
          <div
            v-if="depthLimitVisible"
            class="d-flex flex-column w-50 ml-1"
            :key="2"
          >
            <small for="to" class="my-auto text-muted">
              <translate>Depthlimit 2 ( in cm)</translate>
            </small>
            <input
              id="depthlimit2"
              v-model.number="depthLimit2"
              class="form-control form-control-sm"
              type="number"
              min="0"
            />
          </div>
        </div>
        <div v-if="widthLimitVisible" class="d-flex mt-2" :key="3">
          <div class="d-flex flex-column w-50 mr-1">
            <small for="from" class="my-auto text-muted">
              <translate>Widthlimit 1</translate>
            </small>
            <input
              id="widthLimit"
              v-model.number="widthLimit1"
              class="form-control form-control-sm"
              type="number"
              min="0"
            />
          </div>
          <div
            v-if="widthLimitVisible"
            class="d-flex flex-column w-50 mr-1"
            :key="4"
          >
            <small for="from" class="my-auto text-muted">
              <translate>Widthlimit 2</translate>
            </small>
            <input
              id="widthLimit"
              v-model.number="widthLimit2"
              class="form-control form-control-sm"
              type="number"
              min="0"
            />
          </div>
        </div>

        <div class="mt-3">
          <button
            @click="openFairwaydepthDiagram"
            :disabled="!isComplete"
            class="btn btn-info btn-sm d-block w-100"
          >
            <translate>Available fairway depth</translate>
          </button>
          <button
            @click="openFairwaydepthLNWLDiagram"
            :disabled="!isComplete"
            class="btn btn-info btn-sm d-block w-100 mt-2"
          >
            <translate>Available fairway depth vs LNWL</translate>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="sass" scoped>
input,
select
  font-size: 0.8em

.custom-control
  padding-left: 1.2rem
  .custom-control-label
    &::before,
    &::after
      left: -1.2rem
</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>
 * Thomas Junk <thomas.junk@intevation.de>
 */

import app from "@/main";
import { displayError } from "@/lib/errors";
import { mapState, mapGetters } from "vuex";
import { LIMITINGFACTORS } from "@/store/fairwayavailability";

export default {
  data() {
    return {
      loading: false
    };
  },
  computed: {
    ...mapState("application", [
      "showFairwayDepth",
      "paneSetup",
      "showProfiles"
    ]),
    ...mapState("fairwayavailability", [
      "selectedFairwayAvailabilityFeature",
      "from",
      "to",
      "frequency",
      "LOS",
      "depthlimit1",
      "depthlimit2",
      "widthlimit1",
      "widthlimit2"
    ]),
    ...mapState("imports", [
      "stretches",
      "sections",
      "selectedStretchId",
      "selectedSectionId"
    ]),
    ...mapState("bottlenecks", ["bottlenecksList", "selectedBottleneck"]),
    ...mapGetters("map", ["openLayersMap"]),
    ...mapGetters("bottlenecks", [
      "orderedBottlenecks",
      "limitingFactorsPerBottleneck"
    ]),
    depthLimitVisible() {
      if (this.type !== this.$options.BOTTLENECK) return true;
      if (
        this.selectedEntry &&
        this.limitingFactorsPerBottleneck[this.selectedEntry.properties.name] ==
          this.$options.LIMITINGFACTORS.DEPTH
      )
        return true;
      return false;
    },
    widthLimitVisible() {
      if (this.type !== this.$options.BOTTLENECK) return true;
      if (
        this.selectedEntry &&
        this.limitingFactorsPerBottleneck[this.selectedEntry.properties.name] ==
          this.$options.LIMITINGFACTORS.WIDTH
      )
        return true;
    },
    limitingFactor() {
      if (this.type !== this.$options.BOTTLENECK) return;
      if (this.selectedEntry)
        return this.limitingFactorsPerBottleneck[
          this.selectedEntry.properties.name
        ];
    },
    isComplete() {
      return (
        this.from !== null &&
        this.to !== null &&
        this.frequency !== null &&
        this.los !== null &&
        this.selectedFairwayAvailabilityFeature !== null
      );
    },
    type: {
      get() {
        return this.$store.state.fairwayavailability.type;
      },
      set(type) {
        this.$store.commit("fairwayavailability/type", type);
      }
    },
    los: {
      get() {
        return this.LOS;
      },
      set(value) {
        this.$store.commit("fairwayavailability/setLOS", value);
      }
    },
    fromDate: {
      get() {
        return this.from;
      },
      set(value) {
        this.$store.commit("fairwayavailability/setFrom", value);
      }
    },
    toDate: {
      get() {
        return this.to;
      },
      set(value) {
        this.$store.commit("fairwayavailability/setTo", value);
      }
    },
    depthLimit1: {
      get() {
        return this.depthlimit1;
      },
      set(value) {
        this.$store.commit("fairwayavailability/setDepthlimit1", value);
      }
    },
    depthLimit2: {
      get() {
        return this.depthlimit2;
      },
      set(value) {
        this.$store.commit("fairwayavailability/setDepthlimit2", value);
      }
    },
    widthLimit1: {
      get() {
        return this.widthlimit1;
      },
      set(value) {
        this.$store.commit("fairwayavailability/setWidthlimit1", value);
      }
    },
    widthLimit2: {
      get() {
        return this.widthlimit2;
      },
      set(value) {
        this.$store.commit("fairwayavailability/setWidthlimit2", value);
      }
    },
    selectedFrequency: {
      get() {
        return this.frequency;
      },
      set(value) {
        this.$store.commit("fairwayavailability/setFrequency", value);
      }
    },
    selectedEntry: {
      get() {
        return this.selectedFairwayAvailabilityFeature;
      },
      set(feature) {
        this.$store.commit(
          "fairwayavailability/setSelectedFairwayAvailability",
          feature
        );
      }
    },
    label() {
      return this.$gettext("Available fairway depth");
    },
    placeholder() {
      if (this.type === this.$options.BOTTLENECK)
        return this.$gettext("Select bottleneck");
      if (this.type === this.$options.STRETCH)
        return this.$gettext("Select stretch");
      return this.$gettext("Select section");
    }
  },
  watch: {
    selectedBottleneck() {
      this.type = this.$options.BOTTLENECK;
      this.setSelectedBottleneck();
    },
    selectedStretchId() {
      this.type = this.$options.STRETCH;
      this.setSelectedStretch();
    },
    selectedSectionId() {
      this.type = this.$options.SECTION;
      this.setSelectedSection();
    },
    type(type) {
      if (type === this.$options.BOTTLENECK && this.selectedBottleneck) {
        this.openLayersMap()
          .getLayer("BOTTLENECKS")
          .setVisible(true);
        this.setSelectedBottleneck();
      } else if (type === this.$options.STRETCH && this.selectedStretchId) {
        this.openLayersMap()
          .getLayer("STRETCHES")
          .setVisible(true);
        this.setSelectedStretch();
      } else if (type === this.$options.SECTION && this.selectedSectionId) {
        this.openLayersMap()
          .getLayer("SECTIONS")
          .setVisible(true);
        this.setSelectedSection();
      } else {
        this.$store.commit(
          "fairwayavailability/setSelectedFairwayAvailability",
          null
        );
      }
    },
    showFairwayDepth() {
      if (this.showFairwayDepth) {
        this.loading = true;
        Promise.all([
          this.$store.dispatch("bottlenecks/loadBottlenecks"),
          this.$store.dispatch("bottlenecks/loadBottlenecksList"),
          this.$store.dispatch("imports/loadStretches"),
          this.$store.dispatch("imports/loadSections")
        ])
          .then(() => {
            if (this.selectedBottleneck) this.setSelectedBottleneck();
          })
          .finally(() => (this.loading = false));
      }
    }
  },
  methods: {
    openFairwaydepthLNWLDiagram() {
      this.loading = true;
      this.$store
        .dispatch("fairwayavailability/loadAvailableFairwayDepthLNWLDiagram", {
          feature: this.selectedFairwayAvailabilityFeature,
          from: this.from,
          to: this.to,
          frequency: this.frequency,
          LOS: this.los,
          type: this.type,
          depthLimit1: this.depthLimit1,
          depthLimit2: this.depthLimit2,
          widthLimit1: this.widthLimit1,
          widthLimit2: this.widthLimit2,
          limitingFactor: this.limitingFactor
        })
        .then(() => {
          this.$store.commit(
            "application/paneSetup",
            "AVAILABLEFAIRWAYDEPTHLNWL"
          );
        })
        .catch(error => {
          const { status, data } = error.response;
          displayError({
            title: this.$gettext("Backend Error"),
            message: `${status}: ${data.message || data}`
          });
        })
        .finally(() => {
          this.loading = false;
        });
    },
    openFairwaydepthDiagram() {
      this.loading = true;
      this.$store
        .dispatch("fairwayavailability/loadAvailableFairwayDepth", {
          feature: this.selectedFairwayAvailabilityFeature,
          from: this.from,
          to: this.to,
          frequency: this.frequency,
          LOS: this.los,
          type: this.type,
          depthLimit1: this.depthLimit1,
          depthLimit2: this.depthLimit2,
          widthLimit1: this.widthLimit1,
          widthLimit2: this.widthLimit2,
          limitingFactor: this.limitingFactor
        })
        .then(() => {
          this.$store.commit("application/paneSetup", "AVAILABLEFAIRWAYDEPTH");
        })
        .catch(error => {
          console.log(error);
          const { status, data } = error.response;
          displayError({
            title: this.$gettext("Backend Error"),
            message: `${status}: ${data.message || data}`
          });
        })
        .finally(() => {
          this.loading = false;
        });
    },
    close() {
      this.$store.commit("application/showFairwayDepth", false);
      this.$store.commit("application/showFairwayDepthLNWL", false);
    },
    entrySelected() {
      if (this.type === this.$options.BOTTLENECK) {
        this.openLayersMap()
          .getLayer("BOTTLENECKS")
          .setVisible(true);
        if (this.showProfiles) {
          this.$store.dispatch(
            "bottlenecks/setSelectedBottleneck",
            this.selectedFairwayAvailabilityFeature.properties.name
          );
        }
      }
      if (this.type === this.$options.STRETCH) {
        this.openLayersMap()
          .getLayer("STRETCHES")
          .setVisible(true);
      }
      if (this.type === this.$options.SECTION) {
        this.openLayersMap()
          .getLayer("SECTIONS")
          .setVisible(true);
      }
      if (this.selectedFairwayAvailabilityFeature) {
        this.$store.dispatch("map/moveToFeauture", {
          feature: this.selectedFairwayAvailabilityFeature,
          zoom: 17,
          preventZoomOut: true
        });
      }
    },
    setSelectedBottleneck() {
      const bn = this.bottlenecksList.filter(
        x => x.properties.name === this.selectedBottleneck
      )[0];
      this.$store.commit(
        "fairwayavailability/setSelectedFairwayAvailability",
        bn
      );
    },
    setSelectedStretch() {
      const stretch = this.stretches.find(x => x.id === this.selectedStretchId);
      this.$store.commit(
        "fairwayavailability/setSelectedFairwayAvailability",
        stretch
      );
    },
    setSelectedSection() {
      const section = this.sections.find(x => x.id === this.selectedSectionId);
      this.$store.commit(
        "fairwayavailability/setSelectedFairwayAvailability",
        section
      );
    }
  },
  BOTTLENECK: "bottleneck",
  SECTION: "section",
  STRETCH: "stretch",
  AVAILABLEFAIRWAYDEPTH: app.$gettext("Available Fairway Depth"),
  FREQUENCIES: {
    monthly: app.$gettext("monthly"),
    quarterly: app.$gettext("quarterly"),
    yearly: app.$gettext("yearly")
  },
  LIMITINGFACTORS: LIMITINGFACTORS
};
</script>