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;