view client/src/components/fairway/AvailableFairwayDepthDialogue.vue @ 4454:69166db6ba8a

console.log removed
author Thomas Junk <thomas.junk@intevation.de>
date Mon, 23 Sep 2019 09:19:03 +0200
parents 950fecfec4ca
children 130e929bab8f
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 [m]</translate>
            </small>
            <input
              id="depthlimit1"
              v-model.number="depthLimit1"
              class="form-control form-control-sm"
              type="number"
              min="0"
              step="0.1"
            />
          </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 [m]</translate>
            </small>
            <input
              id="depthlimit2"
              v-model.number="depthLimit2"
              class="form-control form-control-sm"
              type="number"
              min="0"
              step="0.1"
            />
          </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 [m]</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 [m]</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 &&
        !!this.to &&
        !!this.frequency &&
        !!this.los &&
        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 / 100;
      },
      set(value) {
        this.$store.commit(
          "fairwayavailability/setDepthlimit1",
          Math.round(value * 100)
        );
      }
    },
    depthLimit2: {
      get() {
        return this.depthlimit2 / 100;
      },
      set(value) {
        this.$store.commit(
          "fairwayavailability/setDepthlimit2",
          Math.round(value * 100)
        );
      }
    },
    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: {
    depthLimitVisible() {
      if (this.depthLimitVisible) {
        this.depthLimit1 = 2.3;
        this.depthLimit2 = 2.5;
      }
    },
    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.clearInvisibleFormValues();
      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;
        });
    },
    clearInvisibleFormValues() {
      if (!this.widthLimitVisible) {
        this.widthLimit1 = null;
        this.widthLimit2 = null;
      }
      if (!this.depthLimitVisible) {
        this.depthLimit1 = null;
        this.depthLimit2 = null;
      }
    },
    openFairwaydepthDiagram() {
      this.loading = true;
      this.clearInvisibleFormValues();
      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 => {
          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>