Mercurial > gemma
changeset 2977:ab26fb7a76f6 unified_import
unified_imports: soundingresults moved to new UI
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Tue, 09 Apr 2019 12:38:23 +0200 |
parents | ac5ba5a0e963 |
children | d6dd158b8071 |
files | client/src/components/ImportSoundingresults.vue client/src/components/Sidebar.vue client/src/components/importconfiguration/ImportDetails.vue client/src/components/importconfiguration/ImportSoundingresults.vue client/src/router.js |
diffstat | 5 files changed, 364 insertions(+), 381 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/components/ImportSoundingresults.vue Tue Apr 09 08:51:02 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,357 +0,0 @@ -<template> - <div class="main d-flex flex-column"> - <div class="d-flex flex-row"> - <Spacer /> - <div class="card shadow-xs mt-2 mr-2 w-100 h-100"> - <UIBoxHeader icon="upload" :title="importSoundingresultsLabel" /> - <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"; - -const IMPORTSTATE = { UPLOAD: "UPLOAD", EDIT: "EDIT" }; - -export default { - name: "imports", - components: { - Spacer: () => import("@/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"]), - importSoundingresultsLabel() { - return this.$gettext("Import Soundingresults"); - }, - 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>
--- a/client/src/components/Sidebar.vue Tue Apr 09 08:51:02 2019 +0200 +++ b/client/src/components/Sidebar.vue Tue Apr 09 12:38:23 2019 +0200 @@ -43,12 +43,6 @@ </router-link> </div> <div v-if="isWaterwayAdmin"> - <small class="text-muted pl-3"> <translate>Import</translate> </small> - <hr class="m-0" /> - <router-link to="/importsoundingresults"> - <font-awesome-icon class="fa-fw mr-2" fixed-width icon="upload" /> - <span class="fix-trans-space" v-translate>Soundingresults</span> - </router-link> <router-link to="/importschedule"> <font-awesome-icon class="fa-fw mr-2" fixed-width icon="clock" /> <translate class="fix-trans-space">Imports</translate>
--- a/client/src/components/importconfiguration/ImportDetails.vue Tue Apr 09 08:51:02 2019 +0200 +++ b/client/src/components/importconfiguration/ImportDetails.vue Tue Apr 09 12:38:23 2019 +0200 @@ -1,5 +1,8 @@ <template> <div class="mt-3 mb-3 mr-3 ml-3"> + <small class="text-muted"> + <translate>Please choose an import type</translate> + </small> <select v-model="Import" class="custom-select" id="importtype"> <optgroup :label="regularLabel"> <option :value="$options.IMPORTTYPES.BOTTLENECK"> @@ -44,8 +47,16 @@ </select> <ApprovedGaugeMeasurement v-if="Import === $options.IMPORTTYPES.APPROVEDGAUGEMEASUREMENTS" + class="mt-3" /> - <WaterwayProfiles v-if="Import === $options.IMPORTTYPES.WATERWAYPROFILES" /> + <WaterwayProfiles + class="mt-3" + v-if="Import === $options.IMPORTTYPES.WATERWAYPROFILES" + /> + <SoundingResults + class="mt-3" + v-if="Import === $options.IMPORTTYPES.SOUNDINGRESULTS" + /> </div> </template> @@ -80,7 +91,8 @@ components: { ApprovedGaugeMeasurement: () => import("./ImportApprovedGaugeMeasurement.vue"), - WaterwayProfiles: () => import("./ImportWaterwayProfiles") + WaterwayProfiles: () => import("./ImportWaterwayProfiles"), + SoundingResults: () => import("./ImportSoundingresults.vue") }, data() { return {};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/components/importconfiguration/ImportSoundingresults.vue Tue Apr 09 12:38:23 2019 +0200 @@ -0,0 +1,350 @@ +<template> + <div> + <div v-if="editState" class="mb-3"> + <div + v-for="(message, index) in messages" + :key="index" + class="alert alert-warning small rounded-0" + > + {{ message }} + </div> + <div class="d-flex flex-row w-100"> + <div class="w-50 mr-2 text-left"> + <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="w-50 ml-3 text-left"> + <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> + <div class="d-flex flex-row w-100 mt-3"> + <div class="w-50 mr-2 text-left"> + <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="w-50 ml-3 text-left"> + <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> + <div class="mt-3"> + <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 mt-3" 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 + :disabled="disableUploadButton" + @click="confirm" + class="btn btn-info mr-2" + type="button" + > + <translate>Confirm</translate> + </button> + <button :key="1" @click="deleteTempData()" class="btn btn-warning"> + Back + </button> + </span> + </div> + <div v-if="uploadState" class="d-flex flex-row-100 mt-3"> + <button :key="2" @click="back()" class="ml-auto btn btn-warning"> + Back + </button> + </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"; + +const IMPORTSTATE = { UPLOAD: "UPLOAD", EDIT: "EDIT" }; + +export default { + data() { + return { + importState: IMPORTSTATE.UPLOAD, + depthReference: "", + bottleneck: "", + projection: "", + importDate: "", + uploadLabel: this.$gettext("choose .zip- file"), + uploadFile: null, + disableUpload: false, + token: null, + messages: [] + }; + }, + methods: { + back() { + this.$store.commit("importschedule/setListMode"); + }, + 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"]), + importSoundingresultsLabel() { + return this.$gettext("Import Soundingresults"); + }, + 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>
--- a/client/src/router.js Tue Apr 09 08:51:02 2019 +0200 +++ b/client/src/router.js Tue Apr 09 12:38:23 2019 +0200 @@ -81,22 +81,6 @@ } }, { - path: "/importsoundingresults", - name: "importsoundingresults", - component: () => import("./components/ImportSoundingresults.vue"), - meta: { - requiresAuth: true - }, - beforeEnter: (to, from, next) => { - const isWaterwayAdmin = store.getters["user/isWaterwayAdmin"]; - if (!isWaterwayAdmin) { - next("/login"); - } else { - next(); - } - } - }, - { path: "/importschedule", name: "importschedule", component: () => import("./components/importschedule/Importschedule.vue"),