view client/src/components/sections/SectionForm.vue @ 3297:0358bf723769

client: define sections: removed margin in form
author Markus Kottlaender <markus@intevation.de>
date Thu, 16 May 2019 16:27:28 +0200
parents 3ada3d0347bd
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>