Mercurial > gemma
comparison client/src/components/stretches/StretchForm.vue @ 4338:08aef146f95a
Define_stretches: upload etd
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Thu, 05 Sep 2019 17:16:54 +0200 |
parents | c9b60130cdfb |
children | 46d97ada1ce7 |
comparison
equal
deleted
inserted
replaced
4337:086640dc0fba | 4338:08aef146f95a |
---|---|
1 <template> | 1 <template> |
2 <div class="d-flex flex-column"> | 2 <div class="d-flex flex-column"> |
3 <div class="d-flex justify-content-between mt-2 px-2"> | 3 <div class="ml-3 mr-3 my-4"> |
4 <div class="text-left flex-fill mr-1"> | 4 <div class="custom-file mt-4"> |
5 <small class="text-muted"> | |
6 <translate>ID</translate> | |
7 </small> | |
8 <input | 5 <input |
9 id="id" | 6 accept=".zip,.txt" |
10 type="text" | 7 type="file" |
11 class="form-control form-control-sm" | 8 @change="fileSelected" |
12 placeholder="AT_Stretch_12" | 9 class="custom-file-input" |
13 v-model="id" | 10 id="uploadFile" |
14 :disabled="editStretch" | |
15 /> | 11 /> |
16 <span class="text-left text-danger"> | 12 <label class="pointer custom-file-label" for="uploadFile"> |
17 <small v-if="errors.id && !id"> | 13 {{ uploadLabel }} |
18 <translate>Please enter an id</translate> | 14 </label> |
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> | 15 </div> |
193 </div> | 16 </div> |
194 <div class="d-flex justify-content-between mt-2 p-2 border-top"> | 17 <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"> | 18 <button @click="$parent.showForm = false" class="btn btn-sm btn-warning"> |
196 <translate>Back</translate> | 19 <translate>Back</translate> |
197 </button> | 20 </button> |
198 <button | 21 <button |
199 @click="save" | 22 @click="save" |
200 type="submit" | 23 type="submit" |
201 class="shadow-sm btn btn-sm btn-info submit-button" | 24 class="shadow-sm btn btn-sm btn-info submit-button" |
25 :disabled="!uploadFile" | |
202 > | 26 > |
203 <translate>Submit</translate> | 27 <translate>Submit</translate> |
204 </button> | 28 </button> |
205 </div> | 29 </div> |
206 </div> | 30 </div> |
207 </template> | 31 </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 | 32 |
217 <script> | 33 <script> |
218 /* This is Free Software under GNU Affero General Public License v >= 3.0 | 34 /* This is Free Software under GNU Affero General Public License v >= 3.0 |
219 * without warranty, see README.md and license for details. | 35 * without warranty, see README.md and license for details. |
220 * | 36 * |
228 * Author(s): | 44 * Author(s): |
229 * Thomas Junk <thomas.junk@intevation.de> | 45 * Thomas Junk <thomas.junk@intevation.de> |
230 * Tom Gottfried <tom.gottfried@intevation.de> | 46 * Tom Gottfried <tom.gottfried@intevation.de> |
231 * Markus Kottländer <markus.kottlaender@intevation.de> | 47 * Markus Kottländer <markus.kottlaender@intevation.de> |
232 */ | 48 */ |
233 import { mapState, mapGetters } from "vuex"; | |
234 import { displayError, displayInfo } from "@/lib/errors"; | 49 import { displayError, displayInfo } from "@/lib/errors"; |
235 import { sortTable } from "@/lib/mixins"; | 50 import { HTTP } from "@/lib/http"; |
236 | 51 |
237 export default { | 52 export default { |
238 mixins: [sortTable], | |
239 props: ["editStretch"], | 53 props: ["editStretch"], |
240 data() { | 54 data() { |
241 return { | 55 return { |
242 pipetteStart: false, | 56 uploadLabel: this.$gettext(this.$options.UPLOADLABEL), |
243 pipetteEnd: false, | 57 uploadFile: null |
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 }; | 58 }; |
265 }, | 59 }, |
266 computed: { | 60 computed: {}, |
267 ...mapState("map", ["identifiedFeatures"]), | 61 methods: { |
268 ...mapGetters("map", ["openLayersMap"]), | 62 initialState() { |
269 pipetteTooltip() { | 63 this.uploadFile = null; |
270 return this.$gettext("Choose a distance mark by clicking on the map."); | 64 this.uploadLabel = this.$options.UPLOADLABEL; |
65 this.$parent.showForm = false; | |
66 }, | |
67 fileSelected(e) { | |
68 const files = e.target.files || e.dataTransfer.files; | |
69 if (!files) return; | |
70 this.uploadLabel = files[0].name; | |
71 this.uploadFile = files[0]; | |
72 }, | |
73 save() { | |
74 let formData = new FormData(); | |
75 formData.append("stsh", this.uploadFile); | |
76 HTTP.post(`/imports/stsh`, formData, { | |
77 headers: { | |
78 "X-Gemma-Auth": localStorage.getItem("token") | |
79 } | |
80 }) | |
81 .then(() => { | |
82 displayInfo({ | |
83 title: this.$gettext("Import"), | |
84 message: this.$gettext("Upload of stretch complete") | |
85 }); | |
86 this.initialState(); | |
87 }) | |
88 .catch(error => { | |
89 const { status, data } = error.response; | |
90 displayError({ | |
91 title: this.$gettext("Backend Error"), | |
92 message: `${status}: ${data.message || data}` | |
93 }); | |
94 }); | |
271 } | 95 } |
272 }, | 96 }, |
273 watch: { | 97 mounted() {}, |
274 identifiedFeatures() { | 98 UPLOADLABEL: "choose a .zip shapefile" |
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 }; | 99 }; |
384 </script> | 100 </script> |