Mercurial > gemma
comparison client/src/components/ImportSoundingresults.vue @ 1558:0ded4c56978e
refac: component filestructure. remove admin/map hierarchy
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Wed, 12 Dec 2018 09:22:20 +0100 |
parents | client/src/components/map/contextbox/ImportSoundingresults.vue@4af7eaca44a1 |
children | 38f91897ca69 |
comparison
equal
deleted
inserted
replaced
1557:62171cd9a42b | 1558:0ded4c56978e |
---|---|
1 <template> | |
2 <div> | |
3 <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center"> | |
4 <font-awesome-icon icon="upload" class="mr-2"></font-awesome-icon> | |
5 <translate>Import Soundingresults</translate> | |
6 </h6> | |
7 <div v-if="editState" class="ml-auto mr-auto mt-4 w-95"> | |
8 <div class="d-flex flex-column"> | |
9 <div class="d-flex flex-row"> | |
10 <div class="mt-1 text-left w-50 ml-2 mr-4"> | |
11 <small class="text-muted"> | |
12 <translate>Bottleneck</translate> | |
13 </small> | |
14 <select v-model="bottleneck" class="custom-select"> | |
15 <option | |
16 v-for="bottleneck in availableBottlenecks" | |
17 :key="bottleneck" | |
18 >{{ bottleneck }}</option | |
19 > | |
20 </select> | |
21 <span class="text-danger"> | |
22 <small v-if="!bottleneck"> | |
23 <translate>Please select a bottleneck</translate> | |
24 </small> | |
25 </span> | |
26 </div> | |
27 <div class="d-flex flex-column mt-1 text-left w-50 mr-2"> | |
28 <small class="text-muted"> | |
29 <translate>Projection</translate> (EPSG) | |
30 </small> | |
31 <input | |
32 class="form-control" | |
33 v-model="projection" | |
34 value="4326" | |
35 placeholder="e.g. 4326" | |
36 type="number" | |
37 /> | |
38 <span class="text-left text-danger"> | |
39 <small v-if="!projection"> | |
40 <translate>Please enter a projection</translate> | |
41 </small> | |
42 </span> | |
43 </div> | |
44 </div> | |
45 <div class="d-flex flex-row"> | |
46 <div class="mt-1 text-left w-50 ml-2 mr-4"> | |
47 <small class="text-muted"> | |
48 <translate>Depthreference</translate> | |
49 </small> | |
50 <select | |
51 v-model="depthReference" | |
52 class="custom-select" | |
53 id="depthreference" | |
54 > | |
55 <option | |
56 v-for="option in this.$options.depthReferenceOptions" | |
57 :key="option" | |
58 >{{ option }}</option | |
59 > | |
60 </select> | |
61 <span class="text-left text-danger"> | |
62 <small v-if="!depthReference"> | |
63 <translate>Please enter a reference</translate> | |
64 </small> | |
65 </span> | |
66 </div> | |
67 <div class="mt-1 text-left w-50 mr-2"> | |
68 <small class="text-muted"> <translate>Date</translate> </small> | |
69 <input | |
70 id="importdate" | |
71 type="date" | |
72 class="form-control" | |
73 placeholder="Date of import" | |
74 aria-label="bottleneck" | |
75 aria-describedby="bottlenecklabel" | |
76 v-model="importDate" | |
77 /> | |
78 <span class="text-left text-danger"> | |
79 <small v-if="!importDate"> | |
80 <translate>Please enter a date</translate> | |
81 </small> | |
82 </span> | |
83 </div> | |
84 </div> | |
85 </div> | |
86 <div class="ml-2 mt-2 text-left"> | |
87 <small v-for="(message, index) in messages" :key="index"> | |
88 {{ message }} | |
89 </small> | |
90 </div> | |
91 </div> | |
92 <div class="w-95 ml-auto mr-auto mt-4 mb-4"> | |
93 <div v-if="uploadState" class="d-flex flex-row input-group mb-4"> | |
94 <div class="custom-file"> | |
95 <input | |
96 accept=".zip" | |
97 type="file" | |
98 @change="fileSelected" | |
99 class="custom-file-input" | |
100 id="uploadFile" | |
101 /> | |
102 <label class="custom-file-label" for="uploadFile"> | |
103 {{ uploadLabel }} | |
104 </label> | |
105 </div> | |
106 </div> | |
107 <div class="buttons text-right"> | |
108 <a | |
109 v-if="editState" | |
110 download="meta.json" | |
111 :href="dataLink" | |
112 class="btn btn-outline-info pull-left" | |
113 > | |
114 <translate>Download Meta.json</translate> | |
115 </a> | |
116 <button | |
117 v-if="editState" | |
118 @click="deleteTempData" | |
119 class="btn btn-danger" | |
120 type="button" | |
121 > | |
122 <translate>Cancel Upload</translate> | |
123 </button> | |
124 <button | |
125 :disabled="disableUploadButton" | |
126 @click="submit" | |
127 class="btn btn-info" | |
128 type="button" | |
129 > | |
130 {{ uploadState ? Upload : Confirm }} | |
131 </button> | |
132 </div> | |
133 </div> | |
134 </div> | |
135 </template> | |
136 | |
137 <script> | |
138 /* This is Free Software under GNU Affero General Public License v >= 3.0 | |
139 * without warranty, see README.md and license for details. | |
140 * | |
141 * SPDX-License-Identifier: AGPL-3.0-or-later | |
142 * License-Filename: LICENSES/AGPL-3.0.txt | |
143 * | |
144 * Copyright (C) 2018 by via donau | |
145 * – Österreichische Wasserstraßen-Gesellschaft mbH | |
146 * Software engineering by Intevation GmbH | |
147 * | |
148 * Author(s): | |
149 * Thomas Junk <thomas.junk@intevation.de> | |
150 * Markus Kottländer <markus.kottlaender@intevation.de> | |
151 */ | |
152 import { HTTP } from "../lib/http"; | |
153 import { displayError, displayInfo } from "../lib/errors.js"; | |
154 import { mapState } from "vuex"; | |
155 | |
156 const IMPORTSTATE = { UPLOAD: "UPLOAD", EDIT: "EDIT" }; | |
157 | |
158 export default { | |
159 name: "imports", | |
160 data() { | |
161 return { | |
162 importState: IMPORTSTATE.UPLOAD, | |
163 depthReference: "", | |
164 bottleneck: "", | |
165 projection: "", | |
166 importDate: "", | |
167 uploadLabel: this.$gettext("choose .zip- file"), | |
168 uploadFile: null, | |
169 disableUpload: false, | |
170 token: null, | |
171 messages: [] | |
172 }; | |
173 }, | |
174 methods: { | |
175 initialState() { | |
176 this.importState = IMPORTSTATE.UPLOAD; | |
177 this.depthReference = ""; | |
178 this.bottleneck = ""; | |
179 this.projection = ""; | |
180 this.importDate = ""; | |
181 this.uploadLabel = this.$gettext("choose .zip- file"); | |
182 this.uploadFile = null; | |
183 this.disableUpload = false; | |
184 this.token = null; | |
185 this.messages = []; | |
186 }, | |
187 fileSelected(e) { | |
188 const files = e.target.files || e.dataTransfer.files; | |
189 if (!files) return; | |
190 this.uploadLabel = files[0].name; | |
191 this.uploadFile = files[0]; | |
192 }, | |
193 deleteTempData() { | |
194 HTTP.delete("/imports/soundingresult-upload/" + this.token, { | |
195 headers: { | |
196 "X-Gemma-Auth": localStorage.getItem("token") | |
197 } | |
198 }) | |
199 .then(() => { | |
200 this.initialState(); | |
201 }) | |
202 .catch(error => { | |
203 const { status, data } = error.response; | |
204 displayError({ | |
205 title: this.$gettext("Backend Error"), | |
206 message: `${status}: ${data.message || data}` | |
207 }); | |
208 }); | |
209 }, | |
210 submit() { | |
211 if (!this.uploadFile || this.disableUpload) return; | |
212 if (this.importState === IMPORTSTATE.UPLOAD) { | |
213 this.upload(); | |
214 } else { | |
215 this.confirm(); | |
216 } | |
217 }, | |
218 upload() { | |
219 let formData = new FormData(); | |
220 formData.append("soundingresult", this.uploadFile); | |
221 HTTP.post("/imports/soundingresult-upload", formData, { | |
222 headers: { | |
223 "X-Gemma-Auth": localStorage.getItem("token"), | |
224 "Content-Type": "multipart/form-data" | |
225 } | |
226 }) | |
227 .then(response => { | |
228 if (response.data.meta) { | |
229 const { bottleneck, date, epsg } = response.data.meta; | |
230 const depthReference = response.data.meta["depth-reference"]; | |
231 this.bottleneck = bottleneck; | |
232 this.depthReference = depthReference; | |
233 this.importDate = new Date(date).toISOString().split("T")[0]; | |
234 this.projection = epsg; | |
235 } | |
236 this.importState = IMPORTSTATE.EDIT; | |
237 this.token = response.data.token; | |
238 this.messages = response.data.messages; | |
239 }) | |
240 .catch(error => { | |
241 const { status, data } = error.response; | |
242 const messages = data.messages ? data.messages.join(", ") : ""; | |
243 displayError({ | |
244 title: this.$gettext("Backend Error"), | |
245 message: `${status}: ${messages}` | |
246 }); | |
247 }); | |
248 }, | |
249 confirm() { | |
250 let formData = new FormData(); | |
251 formData.append("token", this.token); | |
252 if (this.bottleneck) formData.append("bottleneck", this.bottleneck); | |
253 if (this.importDate) | |
254 formData.append("date", this.importDate.split("T")[0]); | |
255 if (this.depthReference) | |
256 formData.append("depth-reference", this.depthReference); | |
257 if (this.projection) formData.append("", this.projection); | |
258 | |
259 HTTP.post("/imports/soundingresult", formData, { | |
260 headers: { | |
261 "X-Gemma-Auth": localStorage.getItem("token"), | |
262 "Content-Type": "multipart/form-data" | |
263 } | |
264 }) | |
265 .then(() => { | |
266 displayInfo({ | |
267 title: this.$gettext("Import"), | |
268 message: this.$gettext("Starting import for ") + this.bottleneck | |
269 }); | |
270 this.initialState(); | |
271 }) | |
272 .catch(error => { | |
273 const { status, data } = error.response; | |
274 displayError({ | |
275 title: this.$gettext("Backend Error"), | |
276 message: `${status}: ${data.message || data}` | |
277 }); | |
278 }); | |
279 } | |
280 }, | |
281 mounted() { | |
282 this.$store.dispatch("bottlenecks/loadBottlenecks"); | |
283 }, | |
284 watch: { | |
285 showContextBox() { | |
286 if (!this.showContextBox && this.token) this.deleteTempData(); | |
287 } | |
288 }, | |
289 computed: { | |
290 ...mapState("application", ["showContextBox"]), | |
291 ...mapState("bottlenecks", ["bottlenecks"]), | |
292 disableUploadButton() { | |
293 if (this.importState === IMPORTSTATE.UPLOAD) return this.disableUpload; | |
294 if ( | |
295 !this.bottleneck || | |
296 !this.importDate || | |
297 !this.depthReference || | |
298 !this.projection | |
299 ) | |
300 return true; | |
301 return this.disableUpload; | |
302 }, | |
303 availableBottlenecks() { | |
304 return this.bottlenecks.map(x => x.properties.name); | |
305 }, | |
306 editState() { | |
307 return this.importState === IMPORTSTATE.EDIT; | |
308 }, | |
309 uploadState() { | |
310 return this.importState === IMPORTSTATE.UPLOAD; | |
311 }, | |
312 Upload() { | |
313 return this.$gettext("Upload"); | |
314 }, | |
315 Confirm() { | |
316 return this.$gettext("Confirm"); | |
317 }, | |
318 dataLink() { | |
319 return ( | |
320 "data:text/json;charset=utf-8," + | |
321 encodeURIComponent( | |
322 JSON.stringify({ | |
323 depthReference: this.depthReference, | |
324 bottleneck: this.bottleneck, | |
325 date: this.importDate | |
326 }) | |
327 ) | |
328 ); | |
329 } | |
330 }, | |
331 depthReferenceOptions: [ | |
332 "", | |
333 // "NAP", | |
334 // "KP", | |
335 // "FZP", | |
336 // "ADR", | |
337 // "TAW", | |
338 // "PUL", | |
339 // "NGM", | |
340 // "ETRS", | |
341 // "POT", | |
342 // "LDC", | |
343 // "HDC", | |
344 // "ZPG", | |
345 // "GLW", | |
346 // "HSW", | |
347 // "LNW", | |
348 // "HNW", | |
349 // "IGN", | |
350 // "WGS", | |
351 "RN" //, | |
352 // "HBO" | |
353 ] | |
354 }; | |
355 </script> | |
356 | |
357 <style lang="scss" scoped> | |
358 .projectionLabel { | |
359 margin-left: $small-offset; | |
360 } | |
361 | |
362 .depthreferencelabel { | |
363 margin-left: $small-offset; | |
364 } | |
365 | |
366 .offset-r { | |
367 margin-right: $small-offset; | |
368 } | |
369 | |
370 .buttons button { | |
371 margin-left: $offset !important; | |
372 } | |
373 | |
374 .label-text { | |
375 width: 5rem; | |
376 text-align: left; | |
377 line-height: 2.25rem; | |
378 } | |
379 </style> |