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>&nbsp;(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>