comparison 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
comparison
equal deleted inserted replaced
3288:c2d753ef5aa1 3289:c2cba529658d
1 <template>
2 <div class="d-flex flex-column">
3 <div class="d-flex justify-content-between mt-2 px-2">
4 <div class="text-left flex-fill mr-1">
5 <small class="text-muted">
6 <translate>ID</translate>
7 </small>
8 <input
9 id="id"
10 type="text"
11 class="form-control form-control-sm"
12 placeholder="AT_Section_12"
13 v-model="id"
14 :disabled="editStretch"
15 />
16 <span class="text-left text-danger">
17 <small v-if="errors.id && !id">
18 <translate>Please enter an id</translate>
19 </small>
20 </span>
21 </div>
22 <div class="text-left flex-fill ml-1">
23 <small class="text-muted">
24 <translate>Countrycode</translate>
25 </small>
26 <input
27 id="countryCode"
28 type="text"
29 class="form-control form-control-sm"
30 placeholder="AT"
31 v-model="countryCode"
32 />
33 <span class="text-left text-danger">
34 <small v-if="errors.countryCode && !countryCode">
35 <translate>Please enter a countrycode </translate>
36 </small>
37 </span>
38 </div>
39 </div>
40 <div class="d-flex justify-content-between mt-2 px-2">
41 <div class="text-left flex-fill">
42 <small class="text-muted">
43 <translate>Start rhm</translate>
44 </small>
45 <div class="d-flex flex-row position-relative">
46 <input
47 id="startrhm"
48 type="text"
49 class="form-control form-control-sm"
50 placeholder="e.g. ATXXX000010000019900"
51 v-model="startrhm"
52 ref="startrhm"
53 @focus="enablePipette('start')"
54 @blur="disablePipette('start')"
55 />
56 <span
57 class="input-group-text position-absolute input-button"
58 @click="$refs.startrhm.focus()"
59 v-tooltip="pipetteTooltip"
60 >
61 <font-awesome-icon
62 :class="{ 'text-info': pipetteStart }"
63 icon="crosshairs"
64 />
65 </span>
66 </div>
67 <span class="text-left text-danger">
68 <small v-if="errors.startrhm && !startrhm">
69 <translate>Please enter a start point</translate>
70 </small>
71 </span>
72 </div>
73 <div class="text-left flex-fill ml-2">
74 <small class="text-muted">
75 <translate>End rhm</translate>
76 </small>
77 <div class="d-flex flex-row position-relative">
78 <input
79 id="endrhm"
80 type="text"
81 class="form-control form-control-sm"
82 placeholder="e.g. ATXXX000010000019900"
83 v-model="endrhm"
84 ref="endrhm"
85 @focus="enablePipette('end')"
86 @blur="disablePipette('end')"
87 />
88 <span
89 class="input-group-text position-absolute input-button"
90 @click="$refs.endrhm.focus()"
91 v-tooltip="pipetteTooltip"
92 >
93 <font-awesome-icon
94 :class="{ 'text-info': pipetteEnd }"
95 icon="crosshairs"
96 />
97 </span>
98 </div>
99 <span class="text-left text-danger">
100 <small v-if="errors.endrhm && !endrhm">
101 <translate>Please enter an end point</translate>
102 </small>
103 </span>
104 </div>
105 <div class="text-left ml-2" v-if="!editStretch">
106 <small class="text-muted">
107 <translate>Tolerance for snapping to axis</translate>
108 </small>
109 <div class="d-flex flex-row position-relative">
110 <input
111 class="form-control form-control-sm"
112 v-model.number="tolerance"
113 type="number"
114 min="0"
115 step="any"
116 id="tolerance"
117 />
118 <span class="input-group-text position-absolute input-button">
119 m
120 </span>
121 </div>
122 <span class="text-left text-danger">
123 <small v-if="errors.tolerance && !tolerance">
124 <translate>Please enter a tolerance value</translate>
125 </small>
126 </span>
127 </div>
128 </div>
129 <div class="d-flex flex-row justify-content-between px-2">
130 <div class="mt-2 mr-2 w-50 text-left">
131 <small class="text-muted">
132 <translate>Object name</translate>
133 </small>
134 <input
135 id="objbn"
136 type="text"
137 class="form-control form-control-sm"
138 placeholder=""
139 v-model="objbn"
140 />
141 <span class="text-left text-danger">
142 <small v-if="errors.objbn && !objbn">
143 <translate>Please enter an objectname</translate>
144 </small>
145 </span>
146 </div>
147 <div class="mt-2 w-50 text-left">
148 <small class="text-muted">
149 <translate>National Object name</translate>
150 </small>
151 <input
152 id="nobjbn"
153 type="text"
154 class="form-control form-control-sm"
155 v-model="nobjbn"
156 />
157 </div>
158 </div>
159 <div class="d-flex flex-row justify-content-between px-2">
160 <div class="mt-2 w-50 text-left">
161 <small class="text-muted">
162 <translate>Date info</translate>
163 </small>
164 <input
165 id="date_info"
166 type="date"
167 class="form-control form-control-sm"
168 placeholder="date_info"
169 v-model="date_info"
170 />
171 <span class="text-left text-danger">
172 <small v-if="errors.date_info && !date_info">
173 <translate>Please enter a date</translate>
174 </small>
175 </span>
176 </div>
177 <div class="mt-2 ml-2 w-50 text-left">
178 <small class="text-muted">
179 <translate>Source Organization</translate>
180 </small>
181 <input
182 id="source_organization"
183 type="text"
184 class="form-control form-control-sm"
185 v-model="source_organization"
186 />
187 <span class="text-left text-danger">
188 <small v-if="errors.source_organization && !source_organization">
189 <translate>Please enter a source organization</translate>
190 </small>
191 </span>
192 </div>
193 </div>
194 <div class="d-flex justify-content-between mt-2 p-2 border-top">
195 <button @click="$parent.showForm = false" class="btn btn-sm btn-warning">
196 <translate>Back</translate>
197 </button>
198 <button
199 @click="save"
200 type="submit"
201 class="shadow-sm btn btn-sm btn-info submit-button"
202 >
203 <translate>Submit</translate>
204 </button>
205 </div>
206 </div>
207 </template>
208
209 <style lang="sass" scoped>
210 .input-button
211 border-top-left-radius: 0
212 border-bottom-left-radius: 0
213 right: 0
214 height: 31px
215 </style>
216
217 <script>
218 /* This is Free Software under GNU Affero General Public License v >= 3.0
219 * without warranty, see README.md and license for details.
220 *
221 * SPDX-License-Identifier: AGPL-3.0-or-later
222 * License-Filename: LICENSES/AGPL-3.0.txt
223 *
224 * Copyright (C) 2018, 2019 by via donau
225 * – Österreichische Wasserstraßen-Gesellschaft mbH
226 * Software engineering by Intevation GmbH
227 *
228 * Author(s):
229 * Thomas Junk <thomas.junk@intevation.de>
230 * Tom Gottfried <tom.gottfried@intevation.de>
231 * Markus Kottländer <markus.kottlaender@intevation.de>
232 */
233 import { mapState, mapGetters } from "vuex";
234 import { displayError, displayInfo } from "@/lib/errors";
235 import { sortTable } from "@/lib/mixins";
236
237 export default {
238 mixins: [sortTable],
239 props: ["editStretch"],
240 data() {
241 return {
242 pipetteStart: false,
243 pipetteEnd: false,
244 id: null,
245 startrhm: null,
246 endrhm: null,
247 tolerance: 5,
248 objbn: null,
249 nobjbn: null,
250 date_info: new Date().toISOString().split("T")[0],
251 source_organization: null,
252 countryCode: null,
253 errors: {
254 id: false,
255 startrhm: false,
256 endrhm: false,
257 tolerance: false,
258 objbn: false,
259 nobjbn: false,
260 date_info: false,
261 source_organization: false,
262 countryCode: false
263 }
264 };
265 },
266 computed: {
267 ...mapState("map", ["identifiedFeatures"]),
268 ...mapGetters("map", ["openLayersMap"]),
269 pipetteTooltip() {
270 return this.$gettext("Choose a distance mark by clicking on the map.");
271 }
272 },
273 watch: {
274 identifiedFeatures() {
275 const distanceMark = this.identifiedFeatures.find(x =>
276 /^distance_marks_geoserver/.test(x["id_"])
277 );
278 if (distanceMark) {
279 const location = distanceMark.get("location");
280 this.startrhm = this.pipetteStart ? location : this.startrhm;
281 this.endrhm = this.pipetteEnd ? location : this.endrhm;
282 this.pipetteStart = false;
283 this.pipetteEnd = false;
284 this.$store.commit("map/mapPopupEnabled", true);
285 }
286 }
287 },
288 methods: {
289 enablePipette(t) {
290 this.openLayersMap()
291 .getLayer("DISTANCEMARKSAXIS")
292 .setVisible(true);
293 this.$store.commit("map/mapPopupEnabled", false);
294 if (t === "start") {
295 this.pipetteStart = true;
296 this.pipetteEnd = false;
297 } else {
298 this.pipetteStart = false;
299 this.pipetteEnd = true;
300 }
301 },
302 disablePipette() {
303 this.$store.commit("map/mapPopupEnabled", true);
304 this.pipetteStart = false;
305 this.pipetteEnd = false;
306 },
307 validate() {
308 const fields = [
309 "id",
310 "startrhm",
311 "endrhm",
312 "objbn",
313 "countryCode",
314 "date_info",
315 "source_organization"
316 ];
317 if (!this.editStretch) fields.push("tolerance");
318 fields.forEach(field => {
319 if (!this[field]) {
320 this.errors[field] = true;
321 } else {
322 this.errors[field] = false;
323 }
324 });
325
326 // return true if no errors
327 return !Object.values(this.errors).reduce((a, b) => a + b, 0);
328 },
329 save() {
330 if (this.validate()) {
331 const data = {
332 name: this.id,
333 from: this.startrhm,
334 to: this.endrhm,
335 "source-organization": this.source_organization,
336 "date-info": this.date_info,
337 objnam: this.objbn,
338 nobjnam: this.nobjbn,
339 countries: this.countryCode.split(",").map(x => {
340 return x.trim();
341 })
342 };
343 if (!this.editStretch) {
344 data["tolerance"] = this.tolerance;
345 }
346 this.$parent.loading = true;
347 this.$store
348 .dispatch("imports/saveStretch", data)
349 .then(() => {
350 displayInfo({
351 title: this.$gettext("Import"),
352 message: this.$gettext("Starting import of stretch")
353 });
354 this.$store.dispatch("imports/loadStretches").then(() => {
355 this.$parent.loading = false;
356 this.$parent.showForm = false;
357 });
358 })
359 .catch(error => {
360 const { status, data } = error.response;
361 displayError({
362 title: this.$gettext("Backend Error"),
363 message: `${status}: ${data.message || data}`
364 });
365 });
366 }
367 }
368 },
369 mounted() {
370 if (this.editStretch) {
371 const props = this.editStretch.properties;
372 this.id = props.name;
373 this.startrhm = props.lower.replace(/[,()]/g, "");
374 this.endrhm = props.upper.replace(/[,()]/g, "");
375 this.tolerance = props.tolerance;
376 this.objbn = props.objnam;
377 this.nobjbn = props.nobjnam;
378 this.date_info = props.date_info.split("T")[0];
379 this.source_organization = props.source_organization;
380 this.countryCode = props.countries;
381 }
382 }
383 };
384 </script>