Mercurial > gemma
comparison client/src/components/stretches/Stretches.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 | 439e1865a2d2 |
children | 4d5cd3b5775a |
comparison
equal
deleted
inserted
replaced
3288:c2d753ef5aa1 | 3289:c2cba529658d |
---|---|
1 <template> | 1 <template> |
2 <div class="d-flex flex-column"> | 2 <div class="d-flex flex-column"> |
3 <UIBoxHeader | 3 <UIBoxHeader icon="road" :title="title" :closeCallback="$parent.close" /> |
4 icon="road" | |
5 :title="defineStretchesLabel" | |
6 :closeCallback="$parent.close" | |
7 /> | |
8 <div class="position-relative"> | 4 <div class="position-relative"> |
9 <UISpinnerOverlay v-if="loading" /> | 5 <UISpinnerOverlay v-if="loading" /> |
10 <div v-if="!edit"> | 6 <StretchForm v-if="showForm" :editStretch="editStretch" /> |
7 <div v-else> | |
11 <UITableHeader | 8 <UITableHeader |
12 :columns="[ | 9 :columns="[ |
13 { id: 'properties.name', title: `${nameLabel}`, class: 'col-4' }, | 10 { id: 'properties.name', title: `${nameLabel}`, class: 'col-4' }, |
14 { | 11 { |
15 id: 'properties.date_info', | 12 id: 'properties.date_info', |
50 v-tooltip="reviewTooltip" | 47 v-tooltip="reviewTooltip" |
51 /> | 48 /> |
52 </button> | 49 </button> |
53 <button | 50 <button |
54 class="btn btn-xs btn-dark mr-1" | 51 class="btn btn-xs btn-dark mr-1" |
55 @click="editStretch(stretch)" | 52 @click=" |
53 showForm = true; | |
54 editStretch = stretch; | |
55 " | |
56 > | 56 > |
57 <font-awesome-icon icon="pencil-alt" fixed-width /> | 57 <font-awesome-icon icon="pencil-alt" fixed-width /> |
58 </button> | 58 </button> |
59 <button | 59 <button |
60 class="btn btn-xs btn-dark" | 60 class="btn btn-xs btn-dark" |
64 </button> | 64 </button> |
65 </div> | 65 </div> |
66 </template> | 66 </template> |
67 </UITableBody> | 67 </UITableBody> |
68 <div class="text-right p-2 border-top"> | 68 <div class="text-right p-2 border-top"> |
69 <button :key="1" @click="startEdit()" class="btn btn-sm btn-info"> | 69 <button |
70 @click=" | |
71 showForm = true; | |
72 editStretch = null; | |
73 " | |
74 class="btn btn-sm btn-info" | |
75 > | |
70 <translate>New stretch</translate> | 76 <translate>New stretch</translate> |
71 </button> | |
72 </div> | |
73 </div> | |
74 <div v-if="edit"> | |
75 <div class="mx-2"> | |
76 <div class="d-flex justify-content-between mt-2"> | |
77 <div class="text-left flex-fill mr-1"> | |
78 <small class="text-muted"> | |
79 <translate>ID</translate> | |
80 </small> | |
81 <input | |
82 id="id" | |
83 type="text" | |
84 class="form-control form-control-sm" | |
85 placeholder="AT_Section_12" | |
86 aria-label="id" | |
87 v-model="id" | |
88 :disabled="editExistingStretch" | |
89 /> | |
90 <span class="text-left text-danger"> | |
91 <small v-if="idError && !id"> | |
92 <translate>Please enter an id</translate> | |
93 </small> | |
94 </span> | |
95 </div> | |
96 <div class="text-left flex-fill ml-1"> | |
97 <small class="text-muted"> | |
98 <translate>Countrycode</translate> | |
99 </small> | |
100 <input | |
101 id="countryCode" | |
102 type="text" | |
103 class="form-control form-control-sm" | |
104 placeholder="AT" | |
105 aria-label="id" | |
106 v-model="countryCode" | |
107 /> | |
108 <span class="text-left text-danger"> | |
109 <small v-if="countryCodeError && !countryCode"> | |
110 <translate>Please enter a countrycode </translate> | |
111 </small> | |
112 </span> | |
113 </div> | |
114 </div> | |
115 <div class="d-flex justify-content-between mt-2"> | |
116 <div class="text-left flex-fill mr-1"> | |
117 <small class="text-muted"> | |
118 <translate>Start rhm</translate> | |
119 </small> | |
120 <div class="d-flex flex-row position-relative"> | |
121 <input | |
122 id="startrhm" | |
123 type="text" | |
124 class="form-control form-control-sm" | |
125 placeholder="e.g. ATXXX000010000019900" | |
126 aria-label="startrhm" | |
127 v-model="startrhm" | |
128 /> | |
129 <span | |
130 class="input-group-text position-absolute input-button" | |
131 @click="togglePipette('start')" | |
132 v-tooltip="pipetteTooltip" | |
133 > | |
134 <font-awesome-icon | |
135 :class="{ 'text-info': pipetteStart }" | |
136 icon="crosshairs" | |
137 /> | |
138 </span> | |
139 </div> | |
140 <span class="text-left text-danger"> | |
141 <small v-if="startrhmError && !startrhm"> | |
142 <translate>Please enter a start point</translate> | |
143 </small> | |
144 </span> | |
145 </div> | |
146 <div class="text-left flex-fill ml-1"> | |
147 <small class="text-muted"> | |
148 <translate>End rhm</translate> | |
149 </small> | |
150 <div class="d-flex flex-row position-relative"> | |
151 <input | |
152 id="endrhm" | |
153 type="text" | |
154 class="form-control form-control-sm" | |
155 placeholder="e.g. ATXXX000010000019900" | |
156 aria-label="endrhm" | |
157 v-model="endrhm" | |
158 /> | |
159 <span | |
160 class="input-group-text position-absolute input-button" | |
161 @click="togglePipette('end')" | |
162 v-tooltip="pipetteTooltip" | |
163 > | |
164 <font-awesome-icon | |
165 :class="{ 'text-info': pipetteEnd }" | |
166 icon="crosshairs" | |
167 /> | |
168 </span> | |
169 </div> | |
170 <span class="text-left text-danger"> | |
171 <small v-if="endrhmError && !endrhm"> | |
172 <translate>Please enter an end point</translate> | |
173 </small> | |
174 </span> | |
175 </div> | |
176 </div> | |
177 <div | |
178 v-if="!editExistingStretch" | |
179 class="d-flex flex-row justify-content-between" | |
180 > | |
181 <div class="mt-2 mr-2 w-50 text-left"> | |
182 <small class="text-muted"> | |
183 <translate | |
184 >Tolerance for snapping of waterway axis [m]</translate | |
185 > | |
186 </small> | |
187 <input | |
188 class="form-control form-control-sm" | |
189 v-model.number="tolerance" | |
190 placeholder="" | |
191 type="number" | |
192 min="0" | |
193 step="any" | |
194 aria-label="tolerance" | |
195 id="tolerance" | |
196 /> | |
197 <span class="text-left text-danger"> | |
198 <small v-if="toleranceError && !tolerance"> | |
199 <translate>Please enter a tolerance value</translate> | |
200 </small> | |
201 </span> | |
202 </div> | |
203 </div> | |
204 <div class="d-flex flex-row justify-content-between"> | |
205 <div class="mt-2 mr-2 w-50 text-left"> | |
206 <small class="text-muted"> | |
207 <translate>Object name</translate> | |
208 </small> | |
209 <input | |
210 id="objbn" | |
211 type="text" | |
212 class="form-control form-control-sm" | |
213 placeholder="" | |
214 aria-label="objbn" | |
215 v-model="objbn" | |
216 /> | |
217 <span class="text-left text-danger"> | |
218 <small v-if="objbnError && !objbn"> | |
219 <translate>Please enter an objectname</translate> | |
220 </small> | |
221 </span> | |
222 </div> | |
223 <div class="mt-2 ml-2 w-50 text-left"> | |
224 <small class="text-muted"> | |
225 <translate>National Object name</translate> | |
226 </small> | |
227 <input | |
228 id="nobjbn" | |
229 type="text" | |
230 class="form-control form-control-sm" | |
231 placeholder="" | |
232 aria-label="nobjbn" | |
233 v-model="nobjbn" | |
234 /> | |
235 </div> | |
236 </div> | |
237 <div class="d-flex flex-row justify-content-between"> | |
238 <div class="mt-2 mr-2 w-50 text-left"> | |
239 <small class="text-muted"> | |
240 <translate>Date info</translate> | |
241 </small> | |
242 <input | |
243 id="date_info" | |
244 type="date" | |
245 class="form-control form-control-sm" | |
246 placeholder="date_info" | |
247 aria-label="date_info" | |
248 v-model="date_info" | |
249 /> | |
250 <span class="text-left text-danger"> | |
251 <small v-if="date_infoError && !date_info"> | |
252 <translate>Please enter a date</translate> | |
253 </small> | |
254 </span> | |
255 </div> | |
256 <div class="mt-2 ml-2 w-50 text-left"> | |
257 <small class="text-muted"> <translate>Source</translate> </small> | |
258 <input | |
259 id="source" | |
260 type="text" | |
261 class="form-control form-control-sm" | |
262 placeholder="source" | |
263 aria-label="source" | |
264 v-model="source" | |
265 /> | |
266 <span class="text-left text-danger"> | |
267 <small v-if="sourceError && !source"> | |
268 <translate>Please enter a source</translate> | |
269 </small> | |
270 </span> | |
271 </div> | |
272 </div> | |
273 </div> | |
274 <div class="d-flex justify-content-between mt-2 p-2 border-top"> | |
275 <button :key="2" @click="edit = false" class="btn btn-sm btn-warning"> | |
276 Back | |
277 </button> | |
278 <button | |
279 @click="save" | |
280 type="submit" | |
281 class="shadow-sm btn btn-sm btn-info submit-button" | |
282 > | |
283 <translate>Submit</translate> | |
284 </button> | 77 </button> |
285 </div> | 78 </div> |
286 </div> | 79 </div> |
287 </div> | 80 </div> |
288 </div> | 81 </div> |
315 import { displayError, displayInfo } from "@/lib/errors"; | 108 import { displayError, displayInfo } from "@/lib/errors"; |
316 import { HTTP } from "@/lib/http"; | 109 import { HTTP } from "@/lib/http"; |
317 import { sortTable } from "@/lib/mixins"; | 110 import { sortTable } from "@/lib/mixins"; |
318 | 111 |
319 export default { | 112 export default { |
320 name: "importstretches", | |
321 mixins: [sortTable], | 113 mixins: [sortTable], |
114 components: { | |
115 StretchForm: () => import("./StretchForm") | |
116 }, | |
322 data() { | 117 data() { |
323 return { | 118 return { |
324 staging: [], | 119 staging: [], |
325 edit: false, | 120 loading: false, |
326 editExistingStretch: false, | 121 showForm: false, |
327 id: "", | 122 editStretch: null |
328 funktion: "", | |
329 startrhm: "", | |
330 endrhm: "", | |
331 tolerance: 5, | |
332 objbn: "", | |
333 nobjbn: "", | |
334 countryCode: "", | |
335 date_info: new Date().toISOString().split("T")[0], | |
336 source: "", | |
337 pipetteStart: false, | |
338 pipetteEnd: false, | |
339 idError: false, | |
340 funktionError: false, | |
341 startrhmError: false, | |
342 endrhmError: false, | |
343 toleranceError: false, | |
344 objbnError: false, | |
345 nobjbnError: false, | |
346 date_infoError: false, | |
347 sourceError: false, | |
348 countryCodeError: false, | |
349 loading: false | |
350 }; | 123 }; |
351 }, | 124 }, |
352 computed: { | 125 computed: { |
353 ...mapState("application", ["searchQuery"]), | 126 ...mapState("application", ["searchQuery"]), |
354 ...mapState("map", ["identifiedFeatures", "currentMeasurement"]), | |
355 ...mapGetters("map", ["openLayersMap"]), | 127 ...mapGetters("map", ["openLayersMap"]), |
356 ...mapGetters("user", ["isSysAdmin"]), | |
357 ...mapState("imports", ["stretches"]), | 128 ...mapState("imports", ["stretches"]), |
358 defineStretchesLabel() { | 129 title() { |
359 return this.$gettext("Define Stretches"); | 130 return this.$gettext("Define Stretches"); |
360 }, | 131 }, |
361 nameLabel() { | 132 nameLabel() { |
362 return this.$gettext("Name"); | 133 return this.$gettext("Name"); |
363 }, | 134 }, |
367 sourceorganizationLabel() { | 138 sourceorganizationLabel() { |
368 return this.$gettext("Source organization"); | 139 return this.$gettext("Source organization"); |
369 }, | 140 }, |
370 reviewTooltip() { | 141 reviewTooltip() { |
371 return this.$gettext("Review pending import"); | 142 return this.$gettext("Review pending import"); |
372 }, | |
373 pipetteTooltip() { | |
374 return this.$gettext("Choose a distance mark by clicking on the map."); | |
375 } | |
376 }, | |
377 watch: { | |
378 identifiedFeatures() { | |
379 const distanceMark = this.identifiedFeatures.find(x => | |
380 /^distance_marks_geoserver/.test(x["id_"]) | |
381 ); | |
382 if (distanceMark) { | |
383 const location = distanceMark.get("location"); | |
384 this.startrhm = this.pipetteStart ? location : this.startrhm; | |
385 this.endrhm = this.pipetteEnd ? location : this.endrhm; | |
386 this.pipetteStart = false; | |
387 this.pipetteEnd = false; | |
388 this.$store.commit("map/mapPopupEnabled", true); | |
389 } | |
390 } | 143 } |
391 }, | 144 }, |
392 methods: { | 145 methods: { |
393 filteredStretches() { | 146 filteredStretches() { |
394 return this.stretches.filter(s => { | 147 return this.stretches.filter(s => { |
436 title: this.$gettext("Backend Error"), | 189 title: this.$gettext("Backend Error"), |
437 message: `${status}: ${data.message || data}` | 190 message: `${status}: ${data.message || data}` |
438 }); | 191 }); |
439 }); | 192 }); |
440 }, | 193 }, |
441 editStretch(stretch) { | |
442 const properties = stretch.properties; | |
443 this.date_info = properties.date_info.split("T")[0]; | |
444 this.id = properties.name; | |
445 this.nobjbn = properties.nobjnam; | |
446 this.objbn = properties.objnam; | |
447 this.countryCode = properties.countries; | |
448 this.source = properties["source_organization"]; | |
449 this.edit = true; | |
450 this.startrhm = properties.lower.replace(/[,()]/g, ""); | |
451 this.endrhm = properties.upper.replace(/[,()]/g, ""); | |
452 this.editExistingStretch = true; | |
453 }, | |
454 deleteStretch(stretch) { | 194 deleteStretch(stretch) { |
455 this.$store.commit("application/popup", { | 195 this.$store.commit("application/popup", { |
456 icon: "trash", | 196 icon: "trash", |
457 title: this.$gettext("Delete Stretch"), | 197 title: this.$gettext("Delete Stretch"), |
458 content: | 198 content: |
487 this.$store.dispatch("map/moveToFeauture", { | 227 this.$store.dispatch("map/moveToFeauture", { |
488 feature: stretch, | 228 feature: stretch, |
489 zoom: 17, | 229 zoom: 17, |
490 preventZoomOut: true | 230 preventZoomOut: true |
491 }); | 231 }); |
492 }, | |
493 clean() { | |
494 this.id = ""; | |
495 this.edit = false; | |
496 this.editExistingStretch = false; | |
497 this.funktion = ""; | |
498 this.startrhm = ""; | |
499 this.tolerance = 5; | |
500 this.endrhm = ""; | |
501 this.objbn = ""; | |
502 this.nobjbn = ""; | |
503 this.countryCode = ""; | |
504 this.date_info = new Date().toISOString().split("T")[0]; | |
505 this.source = ""; | |
506 this.pipetteStart = false; | |
507 this.pipetteEnd = false; | |
508 this.idError = false; | |
509 this.funktionError = false; | |
510 this.startrhmError = false; | |
511 this.endrhmError = false; | |
512 this.toleranceError = false; | |
513 this.objbnError = false; | |
514 this.nobjbnError = false; | |
515 this.date_infoError = false; | |
516 this.sourceError = false; | |
517 this.countryCodeError = false; | |
518 }, | |
519 startEdit() { | |
520 this.clean(); | |
521 this.edit = true; | |
522 }, | |
523 togglePipette(t) { | |
524 this.openLayersMap() | |
525 .getLayer("DISTANCEMARKSAXIS") | |
526 .setVisible(true); | |
527 if (t === "start") { | |
528 this.$store.commit("map/mapPopupEnabled", this.pipetteStart); | |
529 this.pipetteStart = !this.pipetteStart; | |
530 this.pipetteEnd = false; | |
531 } else { | |
532 this.$store.commit("map/mapPopupEnabled", this.pipetteEnd); | |
533 this.pipetteEnd = !this.pipetteEnd; | |
534 this.pipetteStart = false; | |
535 } | |
536 }, | |
537 validate() { | |
538 const fields = [ | |
539 "id", | |
540 "funktion", | |
541 "startrhm", | |
542 "tolerance", | |
543 "endrhm", | |
544 "objbn", | |
545 "nobjbn", | |
546 "countryCode", | |
547 "date_info", | |
548 "source" | |
549 ]; | |
550 fields.forEach(field => { | |
551 if (!this[field]) { | |
552 this[field + "Error"] = true; | |
553 } else { | |
554 this[field + "Error"] = false; | |
555 } | |
556 }); | |
557 }, | |
558 save() { | |
559 this.validate(); | |
560 if ( | |
561 !this.id || | |
562 !this.startrhm || | |
563 !this.endrhm || | |
564 (!this.tolerance && this.editExistingStretch) || | |
565 !this.source || | |
566 !this.date_info || | |
567 !this.objbn || | |
568 !this.countryCode | |
569 ) | |
570 return; | |
571 const data = { | |
572 name: this.id, | |
573 from: this.startrhm, | |
574 to: this.endrhm, | |
575 "source-organization": this.source, | |
576 "date-info": this.date_info, | |
577 objnam: this.objbn, | |
578 nobjnam: this.nobjbn, | |
579 countries: this.countryCode.split(",").map(x => { | |
580 return x.trim(); | |
581 }) | |
582 }; | |
583 if (!this.editExistingStretch) { | |
584 data["tolerance"] = this.tolerance; | |
585 } | |
586 this.$store | |
587 .dispatch("imports/saveStretch", data) | |
588 .then(() => { | |
589 displayInfo({ | |
590 title: this.$gettext("Import"), | |
591 message: this.$gettext("Starting import of stretch") | |
592 }); | |
593 this.clean(); | |
594 this.$store.dispatch("imports/loadStretches").then(() => { | |
595 this.edit = false; | |
596 }); | |
597 }) | |
598 .catch(error => { | |
599 const { status, data } = error.response; | |
600 displayError({ | |
601 title: this.$gettext("Backend Error"), | |
602 message: `${status}: ${data.message || data}` | |
603 }); | |
604 }); | |
605 } | 232 } |
606 }, | 233 }, |
607 mounted() { | 234 mounted() { |
608 this.edit = false; | |
609 this.loading = true; | 235 this.loading = true; |
610 this.$store | 236 this.$store |
611 .dispatch("imports/loadStretches") | 237 .dispatch("imports/loadStretches") |
612 .catch(error => { | 238 .catch(error => { |
613 const { status, data } = error.response; | 239 const { status, data } = error.response; |