Mercurial > gemma
view client/src/components/ImportSoundingresults.vue @ 2704:84145179ec72
import_overview: open logs and details in parallel
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Mon, 18 Mar 2019 15:56:54 +0100 |
parents | bb5286acfee2 |
children | c6fba10926cc |
line wrap: on
line source
<template> <div class="main d-flex flex-column"> <div class="d-flex flex-row"> <Spacer></Spacer> <div class="card shadow-xs mt-2 mr-2 w-100 h-100"> <UIBoxHeader icon="upload" title="Import Soundingresults" /> <div v-if="editState"> <div v-for="(message, index) in messages" :key="index" class="alert alert-warning small rounded-0" > {{ message }} </div> <div class="container"> <div class="row"> <div class="col-5"> <small class="text-muted"> <translate>Bottleneck</translate> </small> <select v-model="bottleneck" class="custom-select"> <option v-for="bottleneck in availableBottlenecks" :value="bottleneck" :key="bottleneck.properties.objnam" > {{ bottleneck.properties.objnam }} </option> </select> <span class="text-danger"> <small v-if="!bottleneck"> <translate>Please select a bottleneck</translate> </small> </span> </div> <div class="col-2"> <small class="text-muted"> <translate>Projection</translate> (EPSG) </small> <input class="form-control" v-model="projection" value="4326" placeholder="e.g. 4326" type="number" /> <span class="text-left text-danger"> <small v-if="!projection"> <translate>Please enter a projection</translate> </small> </span> </div> <div class="col-2"> <small class="text-muted"> <translate>Depthreference</translate> </small> <select v-model="depthReference" class="custom-select" id="depthreference" > <option v-for="option in this.depthReferenceOptions" :key="option" >{{ option }}</option > </select> <span class="text-left text-danger"> <small v-if="!depthReference"> <translate>Please enter a reference</translate> </small> </span> </div> <div class="col-3"> <small class="text-muted"> <translate>Date</translate> </small> <input id="importdate" type="date" class="form-control" placeholder="Date of import" aria-label="bottleneck" aria-describedby="bottlenecklabel" v-model="importDate" /> <span class="text-left text-danger"> <small v-if="!importDate"> <translate>Please enter a date</translate> </small> </span> </div> </div> <div class="row"></div> </div> </div> <div class="container py-5"> <div v-if="uploadState" class="input-group"> <div class="custom-file"> <input accept=".zip" type="file" @change="fileSelected" class="custom-file-input" id="uploadFile" /> <label class="pointer custom-file-label" for="uploadFile"> {{ uploadLabel }} </label> </div> </div> <div class="d-flex justify-content-between" v-if="editState"> <a download="meta.json" :href="dataLink" :class="[ 'btn btn-outline-info', { disabled: !bottleneck || !importDate || !depthReference } ]" > <translate>Download Meta.json</translate> </a> <span> <button @click="deleteTempData" class="btn btn-danger" type="button" > <translate>Cancel Upload</translate> </button> <button :disabled="disableUploadButton" @click="confirm" class="btn btn-info ml-2" type="button" > <translate>Confirm</translate> </button> </span> </div> </div> </div> </div> </div> </template> <script> /* This is Free Software under GNU Affero General Public License v >= 3.0 * without warranty, see README.md and license for details. * * SPDX-License-Identifier: AGPL-3.0-or-later * License-Filename: LICENSES/AGPL-3.0.txt * * Copyright (C) 2018 by via donau * – Österreichische Wasserstraßen-Gesellschaft mbH * Software engineering by Intevation GmbH * * Author(s): * Thomas Junk <thomas.junk@intevation.de> * Markus Kottländer <markus.kottlaender@intevation.de> */ import { HTTP } from "@/lib/http"; import { displayError, displayInfo } from "@/lib/errors.js"; import { mapState } from "vuex"; import Spacer from "./Spacer"; const IMPORTSTATE = { UPLOAD: "UPLOAD", EDIT: "EDIT" }; export default { name: "imports", components: { Spacer }, data() { return { importState: IMPORTSTATE.UPLOAD, depthReference: "", bottleneck: "", projection: "", importDate: "", uploadLabel: this.$gettext("choose .zip- file"), uploadFile: null, disableUpload: false, token: null, messages: [] }; }, methods: { initialState() { this.importState = IMPORTSTATE.UPLOAD; this.depthReference = ""; this.bottleneck = null; this.projection = ""; this.importDate = ""; this.uploadLabel = this.$gettext("choose .zip- file"); this.uploadFile = null; this.disableUpload = false; this.token = null; this.messages = []; }, fileSelected(e) { const files = e.target.files || e.dataTransfer.files; if (!files) return; this.uploadLabel = files[0].name; this.uploadFile = files[0]; this.upload(); }, deleteTempData() { HTTP.delete("/imports/sr-upload/" + this.token, { headers: { "X-Gemma-Auth": localStorage.getItem("token") } }) .then(() => { this.initialState(); }) .catch(error => { const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); }, upload() { let formData = new FormData(); formData.append("soundingresult", this.uploadFile); HTTP.post("/imports/sr-upload", formData, { headers: { "X-Gemma-Auth": localStorage.getItem("token"), "Content-Type": "multipart/form-data" } }) .then(response => { if (response.data.meta) { const { bottleneck, date, epsg } = response.data.meta; const depthReference = response.data.meta["depth-reference"]; this.bottleneck = this.bottlenecks.find( bn => bn.properties.objnam === bottleneck ); this.depthReference = depthReference; this.importDate = new Date(date).toISOString().split("T")[0]; this.projection = epsg; } this.importState = IMPORTSTATE.EDIT; this.token = response.data.token; this.messages = response.data.messages; }) .catch(error => { const { status, data } = error.response; const messages = data.messages ? data.messages.join(", ") : ""; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${messages}` }); }); }, confirm() { let formData = new FormData(); formData.append("token", this.token); if (this.bottleneck) formData.append("bottleneck", this.bottleneck.properties.objnam); if (this.importDate) formData.append("date", this.importDate.split("T")[0]); if (this.depthReference) formData.append("depth-reference", this.depthReference); if (this.projection) formData.append("", this.projection); HTTP.post("/imports/sr", formData, { headers: { "X-Gemma-Auth": localStorage.getItem("token"), "Content-Type": "multipart/form-data" } }) .then(() => { displayInfo({ title: this.$gettext("Import"), message: this.$gettext("Starting import for ") + this.bottleneck.properties.objnam }); this.initialState(); }) .catch(error => { const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); } }, mounted() { this.$store.dispatch("bottlenecks/loadBottlenecks"); }, watch: { showContextBox() { if (!this.showContextBox && this.token) this.deleteTempData(); } }, computed: { ...mapState("application", ["showContextBox"]), ...mapState("bottlenecks", ["bottlenecks"]), disableUploadButton() { if (this.importState === IMPORTSTATE.UPLOAD) return this.disableUpload; if ( !this.bottleneck || !this.importDate || !this.depthReference || !this.projection ) return true; return this.disableUpload; }, availableBottlenecks() { return this.bottlenecks; }, editState() { return this.importState === IMPORTSTATE.EDIT; }, uploadState() { return this.importState === IMPORTSTATE.UPLOAD; }, Upload() { return this.$gettext("Upload"); }, Confirm() { return this.$gettext("Confirm"); }, dataLink() { if (this.bottleneck && this.depthReference && this.import) { return ( "data:text/json;charset=utf-8," + encodeURIComponent( JSON.stringify({ depthReference: this.depthReference, bottleneck: this.bottleneck.properties.objnam, date: this.importDate }) ) ); } }, depthReferenceOptions() { if ( this.bottleneck && this.bottleneck.properties.reference_water_levels ) { return Object.keys( JSON.parse(this.bottleneck.properties.reference_water_levels) ); } return []; } } }; </script>