Mercurial > gemma
diff client/src/components/stretches/StretchForm.vue @ 3289:c2cba529658d
client: define stretches: seperated list and form into two components
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Thu, 16 May 2019 12:50:20 +0200 |
parents | |
children | c9b60130cdfb |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/components/stretches/StretchForm.vue Thu May 16 12:50:20 2019 +0200 @@ -0,0 +1,384 @@ +<template> + <div class="d-flex flex-column"> + <div class="d-flex justify-content-between mt-2 px-2"> + <div class="text-left flex-fill mr-1"> + <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="editStretch" + /> + <span class="text-left text-danger"> + <small v-if="errors.id && !id"> + <translate>Please enter an id</translate> + </small> + </span> + </div> + <div class="text-left flex-fill ml-1"> + <small class="text-muted"> + <translate>Countrycode</translate> + </small> + <input + id="countryCode" + type="text" + class="form-control form-control-sm" + placeholder="AT" + v-model="countryCode" + /> + <span class="text-left text-danger"> + <small v-if="errors.countryCode && !countryCode"> + <translate>Please enter a countrycode </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="!editStretch"> + <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: ["editStretch"], + 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, + countryCode: null, + errors: { + id: false, + startrhm: false, + endrhm: false, + tolerance: false, + objbn: false, + nobjbn: false, + date_info: false, + source_organization: false, + countryCode: 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", + "countryCode", + "date_info", + "source_organization" + ]; + if (!this.editStretch) 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, + countries: this.countryCode.split(",").map(x => { + return x.trim(); + }) + }; + if (!this.editStretch) { + data["tolerance"] = this.tolerance; + } + this.$parent.loading = true; + this.$store + .dispatch("imports/saveStretch", data) + .then(() => { + displayInfo({ + title: this.$gettext("Import"), + message: this.$gettext("Starting import of stretch") + }); + this.$store.dispatch("imports/loadStretches").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.editStretch) { + const props = this.editStretch.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; + this.countryCode = props.countries; + } + } +}; +</script>