view client/src/components/systemconfiguration/PDFTemplates.vue @ 2640:4bcb26542767

client: use new btn-xs class in tables
author Markus Kottlaender <markus@intevation.de>
date Thu, 14 Mar 2019 11:23:42 +0100
parents 47b9a4f9a05c
children add2d47c2567
line wrap: on
line source

<template>
  <div class="d-flex flex-column">
    <div class="d-flex flex-row justify-content-between">
      <h5><translate>PDF-Templates</translate></h5>
      <input
        @change="uploadTemplate"
        id="uploadTemplate"
        ref="uploadTemplate"
        type="file"
        style="visibility:hidden"
      />
    </div>
    <div class="mt-1 border-bottom pb-4">
      <UITableHeader
        :columns="[
          { id: 'name', title: 'Name', class: 'col-4' },
          { id: 'date', title: 'Date', class: 'col-4' },
          { id: 'country', title: 'Country', class: 'col-2' }
        ]"
        :sortable="false"
      />
      <UITableBody :data="templates" v-slot="{ item: template }">
        <div class="py-1 col-4">{{ template.name }}</div>
        <div class="py-1 col-4">{{ template.time }}</div>
        <div class="py-1 col-2" v-if="template.country">
          {{ template.country }}
        </div>
        <div class="py-1 col-2" v-else><i>global</i></div>
        <div class="col py-1 text-right">
          <button
            class="btn btn-xs btn-info mr-1"
            ref="downloadTemplate"
            @click="downloadTemplate(template)"
          >
            <font-awesome-icon icon="download" fixed-width />
          </button>
          <button class="btn btn-xs btn-dark" @click="deleteTemplate(template)">
            <font-awesome-icon icon="trash" fixed-width />
          </button>
        </div>
      </UITableBody>
      <button class="btn btn-info mt-2" @click="$refs.uploadTemplate.click()">
        <font-awesome-icon
          icon="spinner"
          class="fa-spin fa-fw"
          v-if="uploading"
        />
        <font-awesome-icon icon="upload" class="fa-fw" v-else />
        <translate>Upload new template</translate>
      </button>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.table th,
td {
  font-size: $smaller;
  border-top: 0px !important;
  text-align: left;
  padding: $small-offset !important;
}
</style>

<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, 2019 by via donau
 *   – Österreichische Wasserstraßen-Gesellschaft mbH
 * Software engineering by Intevation GmbH
 *
 * Author(s):
 * Markus Kottländer <markus@intevation.de>
 * Fadi Abbud <fadi.abbud@intevation.de>
 */
import { HTTP } from "@/lib/http";
import { displayError, displayInfo } from "@/lib/errors.js";

export default {
  name: "pdftemplates",
  data() {
    return {
      templates: [],
      uploading: false
    };
  },
  methods: {
    downloadTemplate(template) {
      if (template) {
        var templateData = "";
        var element = document.createElement("a");
        element.style.display = "none";
        element.setAttribute("download", template.name + ".json");
        document.body.appendChild(element);
        HTTP.get("/templates/print/" + template.name, {
          headers: {
            "X-Gemma-Auth": localStorage.getItem("token"),
            "Content-type": "text/xml; charset=UTF-8"
          }
        })
          .then(response => {
            templateData = response.data.template_data;
            element.setAttribute(
              "href",
              "data:text/json;charset=utf-8," +
                encodeURIComponent(
                  JSON.stringify(
                    {
                      name: templateData.name,
                      properties: templateData.properties,
                      elements: templateData.elements
                    },
                    null,
                    2
                  )
                )
            );
            element.click();
          })
          .catch(e => {
            const { status, data } = e.response;
            displayError({
              title: this.$gettext("Backend Error"),
              message: `${status}: ${data.message || data}`
            });
          })
          .finally(() => {
            document.body.removeChild(element);
          });
      }
    },
    uploadTemplate() {
      const reader = new FileReader();
      reader.onload = event => {
        let template;
        try {
          template = JSON.parse(event.target.result);
        } catch (e) {
          displayError({
            title: this.$gettext("Format Error"),
            message: this.$gettext(
              "Uploaded file does not contain valid json data."
            )
          });
        }
        if (template.name) {
          this.uploading = true;
          HTTP.post(
            "/templates/print/" + template.name,
            {
              template_name: template.name,
              template_data: template
            },
            {
              headers: {
                "X-Gemma-Auth": localStorage.getItem("token"),
                "Content-type": "text/xml; charset=UTF-8"
              }
            }
          )
            .then(() => {
              this.loadTemplates();
              displayInfo({
                message:
                  template.name + " " + this.$gettext("uploaded successfully")
              });
            })
            .catch(e => {
              const { status, data } = e.response;
              if (status === 400) {
                displayError({
                  title: this.$gettext("Error"),
                  message: `${data.message || data}`
                });
              } else {
                displayError({
                  title: this.$gettext("Backend Error"),
                  message: `${status}: ${data.message || data}`
                });
              }
            })
            .finally(() => {
              this.uploading = false;
              this.$refs.uploadTemplate.value = null;
            });
        } else {
          displayError({
            title: this.$gettext("Format Error"),
            message: this.$gettext(
              "The provided template has no name property."
            )
          });
        }
      };
      reader.onerror = error => console.log(error);
      reader.readAsText(this.$refs.uploadTemplate.files[0]);
    },
    loadTemplates() {
      HTTP.get("/templates/print", {
        headers: {
          "X-Gemma-Auth": localStorage.getItem("token"),
          "Content-type": "text/xml; charset=UTF-8"
        }
      })
        .then(response => {
          this.templates = response.data;
        })
        .catch(e => {
          const { status, data } = e.response;
          displayError({
            title: this.$gettext("Backend Error"),
            message: `${status}: ${data.message || data}`
          });
        });
    },
    deleteTemplate(template) {
      this.$store.commit("application/popup", {
        icon: "trash",
        title: this.$gettext("Delete Template"),
        content:
          this.$gettext(
            "Do you really want to delete the following template:"
          ) +
          `<br>
        <b>${template.name}</b>`,
        confirm: {
          label: this.$gettext("Delete"),
          icon: "trash",
          callback: () => {
            HTTP.delete("/templates/print/" + template.name, {
              headers: {
                "X-Gemma-Auth": localStorage.getItem("token"),
                "Content-type": "text/xml; charset=UTF-8"
              }
            }).then(() => {
              let removeIndex = this.templates.findIndex(
                t => t.name === template.name
              );
              if (removeIndex !== -1) {
                this.templates.splice(removeIndex, 1);
                displayInfo({
                  message:
                    template.name + " " + this.$gettext("deleted successfully")
                });
              }
            });
          }
        },
        cancel: {
          label: this.$gettext("Cancel"),
          icon: "times"
        }
      });
    }
  },
  mounted() {
    this.loadTemplates();
  }
};
</script>