view client/src/components/map/contextbox/ImportSoundingresults.vue @ 1285:f674ce380de1

layout soundingresults
author Thomas Junk <thomas.junk@intevation.de>
date Thu, 22 Nov 2018 11:18:46 +0100
parents f1b096e1ee69
children 2738a6ae9ad8
line wrap: on
line source

<template>
    <div>
        <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center">
            <i class="fa fa-upload mr-2"></i>
            Import Soundingresults
        </h6>
        <div v-if="editState" class="ml-auto mr-auto mt-4 w-95">
            <div class="d-flex flex-row input-group mb-4">
                <div class="offset-r">
                    <label for="bottleneck" class="label-text" id="bottlenecklabel">Bottleneck</label>
                </div>
                <input
                    id="bottleneck"
                    type="text"
                    class="form-control"
                    placeholder="Name of Bottleneck"
                    aria-label="bottleneck"
                    aria-describedby="bottlenecklabel"
                    v-model="bottleneck"
                >
            </div>
            <div class="d-flex flex-row input-group mb-4">
                <div class="offset-r">
                    <label class="label-text" for="importdate" id="importdatelabel">Date</label>
                </div>
                <input
                    id="importdate"
                    type="date"
                    class="form-control"
                    placeholder="Date of import"
                    aria-label="bottleneck"
                    aria-describedby="bottlenecklabel"
                    v-model="importDate"
                >
                <div class="offset-r">
                    <label
                        class="label-text w-100 depthreferencelabel"
                        for="depthreference"
                    >Depthreference</label>
                </div>
                <select v-model="depthReference" class="custom-select" id="depthreference">
                    <option
                        v-for="option in this.$options.depthReferenceOptions"
                        :key="option"
                    >{{option}}</option>
                </select>
            </div>
        </div>
        <div class="w-95 ml-auto mr-auto mt-4 mb-4">
            <div v-if="uploadState" class="d-flex flex-row input-group mb-4">
                <div class="custom-file">
                    <input
                        type="file"
                        @change="fileSelected"
                        class="custom-file-input"
                        id="uploadFile"
                    >
                    <label class="custom-file-label" for="uploadFile">{{uploadLabel}}</label>
                </div>
            </div>
            <div class="buttons text-right">
                <a
                    v-if="editState"
                    download="meta.json"
                    :href="dataLink "
                    class="btn btn-outline-info pull-left"
                >Download Meta.json</a>
                <button
                    v-if="editState"
                    @click="deleteTempData"
                    class="btn btn-danger"
                    type="button"
                >Cancel Upload</button>
                <button
                    :disabled="disableUpload"
                    @click="submit"
                    class="btn btn-info"
                    type="button"
                >{{uploadState?"Upload":"Confirm"}}</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";

const defaultLabel = "Choose .zip-file";
const IMPORTSTATE = { UPLOAD: "UPLOAD", EDIT: "EDIT" };

export default {
  name: "imports",
  data() {
    return {
      importState: IMPORTSTATE.UPLOAD,
      depthReference: "",
      bottleneck: "",
      importDate: "",
      uploadLabel: defaultLabel,
      uploadFile: null,
      disableUpload: false,
      token: null
    };
  },
  methods: {
    initialState() {
      this.importState = IMPORTSTATE.UPLOAD;
      this.depthReference = "";
      this.bottleneck = "";
      this.importDate = "";
      this.uploadLabel = defaultLabel;
      this.uploadFile = null;
      this.disableUpload = false;
      this.token = null;
    },
    fileSelected(e) {
      const files = e.target.files || e.dataTransfer.files;
      if (!files) return;
      this.uploadLabel = files[0].name;
      this.uploadFile = files[0];
    },
    deleteTempData() {
      HTTP.delete("/imports/soundingresult-upload/" + this.token, {
        headers: {
          "X-Gemma-Auth": localStorage.getItem("token")
        }
      })
        .then(() => {
          this.initialState();
        })
        .catch(error => {
          const { status, data } = error.response;
          displayError({
            title: "Backend Error",
            message: `${status}: ${data.message || data}`
          });
        });
    },
    submit() {
      if (!this.uploadFile || this.disableUpload) return;
      if (this.importState === IMPORTSTATE.UPLOAD) {
        this.upload();
      } else {
        this.confirm();
      }
    },
    upload() {
      let formData = new FormData();
      formData.append("soundingresult", this.uploadFile);
      HTTP.post("/imports/soundingresult-upload", formData, {
        headers: {
          "X-Gemma-Auth": localStorage.getItem("token"),
          "Content-Type": "multipart/form-data"
        }
      })
        .then(response => {
          const { bottleneck, date } = response.data.meta;
          const depthReference = response.data.meta["depth-reference"];
          this.importState = IMPORTSTATE.EDIT;
          this.bottleneck = bottleneck;
          this.depthReference = depthReference;
          this.importDate = new Date(date).toISOString().split("T")[0];
          this.token = response.data.token;
        })
        .catch(error => {
          const { status, data } = error.response;
          const messages = data.messages ? data.messages.join(", ") : "";
          displayError({
            title: "Backend Error",
            message: `${status}: ${messages}`
          });
        });
    },
    confirm() {
      let formData = new FormData();
      formData.append("token", this.token);
      ["bottleneck", "importDate", "depthReference"].forEach(x => {
        if (this[x]) formData.append(x, this[x]);
      });
      HTTP.post("/imports/soundingresult", formData, {
        headers: {
          "X-Gemma-Auth": localStorage.getItem("token"),
          "Content-Type": "multipart/form-data"
        }
      })
        .then(() => {
          displayInfo({
            title: "Import",
            message: "Starting import for " + this.bottleneck
          });
          this.initialState();
        })
        .catch(error => {
          const { status, data } = error.response;
          displayError({
            title: "Backend Error",
            message: `${status}: ${data.message || data}`
          });
        });
    }
  },
  computed: {
    editState() {
      return this.importState === IMPORTSTATE.EDIT;
    },
    uploadState() {
      return this.importState === IMPORTSTATE.UPLOAD;
    },
    dataLink() {
      return (
        "data:text/json;charset=utf-8," +
        encodeURIComponent(
          JSON.stringify({
            depthReference: this.depthReference,
            bottleneck: this.bottleneck,
            date: this.importDate
          })
        )
      );
    }
  },
  depthReferenceOptions: [
    "",
    "NAP",
    "KP",
    "FZP",
    "ADR",
    "TAW",
    "PUL",
    "NGM",
    "ETRS",
    "POT",
    "LDC",
    "HDC",
    "ZPG",
    "GLW",
    "HSW",
    "LNW",
    "HNW",
    "IGN",
    "WGS",
    "RN",
    "HBO"
  ]
};
</script>

<style lang="sass" scoped>
.depthreferencelabel
  margin-left: $small-offset

.offset-r
  margin-right: $small-offset

.buttons button
  margin-left: $offset !important

.label-text
  width: 5rem
  text-align: left
  line-height: 2.25rem
</style>