view client/src/components/sections/SectionForm.vue @ 3644:9e91b416d5bb

client: cross profile: display arrow in diagram consciously diceded to not draw it in the svg so it will not be exported to pdf since there it does not make sense without the map
author Markus Kottlaender <markus@intevation.de>
date Wed, 12 Jun 2019 17:10:49 +0200
parents 0358bf723769
children 008bc1ae8897
line wrap: on
line source

<template>
  <div class="d-flex flex-column">
    <div class="d-flex justify-content-between mt-2 px-2">
      <div class="text-left flex-fill">
        <small class="text-muted">
          <translate>ID</translate>
        </small>
        <input
          id="id"
          type="text"
          class="form-control form-control-sm"
          placeholder="AT_Section_12"
          v-model="id"
          :disabled="editSection"
        />
        <span class="text-left text-danger">
          <small v-if="errors.id && !id">
            <translate>Please enter an id</translate>
          </small>
        </span>
      </div>
    </div>
    <div class="d-flex justify-content-between mt-2 px-2">
      <div class="text-left flex-fill">
        <small class="text-muted">
          <translate>Start rhm</translate>
        </small>
        <div class="d-flex flex-row position-relative">
          <input
            id="startrhm"
            type="text"
            class="form-control form-control-sm"
            placeholder="e.g. ATXXX000010000019900"
            v-model="startrhm"
            ref="startrhm"
            @focus="enablePipette('start')"
            @blur="disablePipette('start')"
          />
          <span
            class="input-group-text position-absolute input-button"
            @click="$refs.startrhm.focus()"
            v-tooltip="pipetteTooltip"
          >
            <font-awesome-icon
              :class="{ 'text-info': pipetteStart }"
              icon="crosshairs"
            />
          </span>
        </div>
        <span class="text-left text-danger">
          <small v-if="errors.startrhm && !startrhm">
            <translate>Please enter a start point</translate>
          </small>
        </span>
      </div>
      <div class="text-left flex-fill ml-2">
        <small class="text-muted">
          <translate>End rhm</translate>
        </small>
        <div class="d-flex flex-row position-relative">
          <input
            id="endrhm"
            type="text"
            class="form-control form-control-sm"
            placeholder="e.g. ATXXX000010000019900"
            v-model="endrhm"
            ref="endrhm"
            @focus="enablePipette('end')"
            @blur="disablePipette('end')"
          />
          <span
            class="input-group-text position-absolute input-button"
            @click="$refs.endrhm.focus()"
            v-tooltip="pipetteTooltip"
          >
            <font-awesome-icon
              :class="{ 'text-info': pipetteEnd }"
              icon="crosshairs"
            />
          </span>
        </div>
        <span class="text-left text-danger">
          <small v-if="errors.endrhm && !endrhm">
            <translate>Please enter an end point</translate>
          </small>
        </span>
      </div>
      <div class="text-left ml-2" v-if="!editSection">
        <small class="text-muted">
          <translate>Tolerance for snapping to axis</translate>
        </small>
        <div class="d-flex flex-row position-relative">
          <input
            class="form-control form-control-sm"
            v-model.number="tolerance"
            type="number"
            min="0"
            step="any"
            id="tolerance"
          />
          <span class="input-group-text position-absolute input-button">
            m
          </span>
        </div>
        <span class="text-left text-danger">
          <small v-if="errors.tolerance && !tolerance">
            <translate>Please enter a tolerance value</translate>
          </small>
        </span>
      </div>
    </div>
    <div class="d-flex flex-row justify-content-between px-2">
      <div class="mt-2 mr-2 w-50 text-left">
        <small class="text-muted">
          <translate>Object name</translate>
        </small>
        <input
          id="objbn"
          type="text"
          class="form-control form-control-sm"
          placeholder=""
          v-model="objbn"
        />
        <span class="text-left text-danger">
          <small v-if="errors.objbn && !objbn">
            <translate>Please enter an objectname</translate>
          </small>
        </span>
      </div>
      <div class="mt-2 w-50 text-left">
        <small class="text-muted">
          <translate>National Object name</translate>
        </small>
        <input
          id="nobjbn"
          type="text"
          class="form-control form-control-sm"
          v-model="nobjbn"
        />
      </div>
    </div>
    <div class="d-flex flex-row justify-content-between px-2">
      <div class="mt-2 w-50 text-left">
        <small class="text-muted">
          <translate>Date info</translate>
        </small>
        <input
          id="date_info"
          type="date"
          class="form-control form-control-sm"
          placeholder="date_info"
          v-model="date_info"
        />
        <span class="text-left text-danger">
          <small v-if="errors.date_info && !date_info">
            <translate>Please enter a date</translate>
          </small>
        </span>
      </div>
      <div class="mt-2 ml-2 w-50 text-left">
        <small class="text-muted">
          <translate>Source Organization</translate>
        </small>
        <input
          id="source_organization"
          type="text"
          class="form-control form-control-sm"
          v-model="source_organization"
        />
        <span class="text-left text-danger">
          <small v-if="errors.source_organization && !source_organization">
            <translate>Please enter a source organization</translate>
          </small>
        </span>
      </div>
    </div>
    <div class="d-flex justify-content-between mt-2 p-2 border-top">
      <button @click="$parent.showForm = false" class="btn btn-sm btn-warning">
        <translate>Back</translate>
      </button>
      <button
        @click="save"
        type="submit"
        class="shadow-sm btn btn-sm btn-info submit-button"
      >
        <translate>Submit</translate>
      </button>
    </div>
  </div>
</template>

<style lang="sass" scoped>
.input-button
  border-top-left-radius: 0
  border-bottom-left-radius: 0
  right: 0
  height: 31px
</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, 2019 by via donau
 *   – Österreichische Wasserstraßen-Gesellschaft mbH
 * Software engineering by Intevation GmbH
 *
 * Author(s):
 * Thomas Junk <thomas.junk@intevation.de>
 * Tom Gottfried <tom.gottfried@intevation.de>
 * Markus Kottländer <markus.kottlaender@intevation.de>
 */
import { mapState, mapGetters } from "vuex";
import { displayError, displayInfo } from "@/lib/errors";
import { sortTable } from "@/lib/mixins";

export default {
  mixins: [sortTable],
  props: ["editSection"],
  data() {
    return {
      pipetteStart: false,
      pipetteEnd: false,
      id: null,
      startrhm: null,
      endrhm: null,
      tolerance: 5,
      objbn: null,
      nobjbn: null,
      date_info: new Date().toISOString().split("T")[0],
      source_organization: null,
      errors: {
        id: false,
        startrhm: false,
        endrhm: false,
        tolerance: false,
        objbn: false,
        nobjbn: false,
        date_info: false,
        source_organization: false
      }
    };
  },
  computed: {
    ...mapState("map", ["identifiedFeatures"]),
    ...mapGetters("map", ["openLayersMap"]),
    pipetteTooltip() {
      return this.$gettext("Choose a distance mark by clicking on the map.");
    }
  },
  watch: {
    identifiedFeatures() {
      const distanceMark = this.identifiedFeatures.find(x =>
        /^distance_marks_geoserver/.test(x["id_"])
      );
      if (distanceMark) {
        const location = distanceMark.get("location");
        this.startrhm = this.pipetteStart ? location : this.startrhm;
        this.endrhm = this.pipetteEnd ? location : this.endrhm;
        this.pipetteStart = false;
        this.pipetteEnd = false;
        this.$store.commit("map/mapPopupEnabled", true);
      }
    }
  },
  methods: {
    enablePipette(t) {
      this.openLayersMap()
        .getLayer("DISTANCEMARKSAXIS")
        .setVisible(true);
      this.$store.commit("map/mapPopupEnabled", false);
      if (t === "start") {
        this.pipetteStart = true;
        this.pipetteEnd = false;
      } else {
        this.pipetteStart = false;
        this.pipetteEnd = true;
      }
    },
    disablePipette() {
      this.$store.commit("map/mapPopupEnabled", true);
      this.pipetteStart = false;
      this.pipetteEnd = false;
    },
    validate() {
      const fields = [
        "id",
        "startrhm",
        "endrhm",
        "objbn",
        "date_info",
        "source_organization"
      ];
      if (!this.editSection) fields.push("tolerance");
      fields.forEach(field => {
        if (!this[field]) {
          this.errors[field] = true;
        } else {
          this.errors[field] = false;
        }
      });

      // return true if no errors
      return !Object.values(this.errors).reduce((a, b) => a + b, 0);
    },
    save() {
      if (this.validate()) {
        const data = {
          name: this.id,
          from: this.startrhm,
          to: this.endrhm,
          "source-organization": this.source_organization,
          "date-info": this.date_info,
          objnam: this.objbn,
          nobjnam: this.nobjbn
        };
        if (!this.editSection) {
          data["tolerance"] = this.tolerance;
        }
        this.$parent.loading = true;
        this.$store
          .dispatch("imports/saveSection", data)
          .then(() => {
            displayInfo({
              title: this.$gettext("Import"),
              message: this.$gettext("Starting import of section")
            });
            this.$store.dispatch("imports/loadSections").then(() => {
              this.$parent.loading = false;
              this.$parent.showForm = false;
            });
          })
          .catch(error => {
            const { status, data } = error.response;
            displayError({
              title: this.$gettext("Backend Error"),
              message: `${status}: ${data.message || data}`
            });
          });
      }
    }
  },
  mounted() {
    if (this.editSection) {
      const props = this.editSection.properties;
      this.id = props.name;
      this.startrhm = props.lower.replace(/[,()]/g, "");
      this.endrhm = props.upper.replace(/[,()]/g, "");
      this.tolerance = props.tolerance;
      this.objbn = props.objnam;
      this.nobjbn = props.nobjnam;
      this.date_info = props.date_info.split("T")[0];
      this.source_organization = props.source_organization;
    }
  }
};
</script>