Mercurial > gemma
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> |