view client/src/components/importqueue/Importqueuedetail.vue @ 1892:b43ee5f73c05

fix: consequentially uppercasing import kind in all overviews
author Thomas Junk <thomas.junk@intevation.de>
date Fri, 18 Jan 2019 10:48:13 +0100
parents c0532a94a0b5
children 16b8448345bd
line wrap: on
line source

<template>
  <div class="entry d-flex flex-column py-1 border-bottom">
    <div class="d-flex flex-row position-relative">
      <div @click="showDetails(job.id)" class="jobid ml-2 mt-1 mr-2">
        {{ job.id }}
      </div>
      <div @click="showDetails(job.id)" class="enqueued mt-1  mr-2">
        {{ formatDate(job.enqueued) }}
      </div>
      <div @click="showDetails(job.id)" class="kind mt-1 mr-2">
        {{ job.kind.toUpperCase() }}
      </div>
      <div @click="showDetails(job.id)" class="user mt-1 mr-2">
        {{ job.user }}
      </div>
      <div @click="showDetails(job.id)" class="signer mt-1 mr-2">
        {{ job.signer }}
      </div>
      <div @click="showDetails(job.id)" class="state mt-1 mr-2">
        {{ job.state }}
      </div>
      <div @click="showDetails(job.id)" class="mt-1 text-info detailsbutton">
        <font-awesome-icon
          v-if="show"
          icon="angle-up"
          fixed-width
        ></font-awesome-icon>
        <font-awesome-icon
          v-if="loading"
          icon="spinner"
          fixed-width
        ></font-awesome-icon>
        <font-awesome-icon
          v-if="!show && !loading"
          icon="angle-down"
          fixed-width
        ></font-awesome-icon>
      </div>
    </div>
    <div class="detailstable d-flex flex-row">
      <div :class="collapse">
        <table class="table table-responsive">
          <thead>
            <tr>
              <th class="type pb-0">
                <small class="condensed"><translate>Kind</translate></small>
              </th>
              <th class="datetime  pb-0">
                <a href="#" @click="sortAsc = !sortAsc" class="sort-link"
                  ><small class="condensed"><translate>Date</translate></small>
                  <small class="condensed"
                    ><font-awesome-icon
                      :icon="sortIcon"
                      class="ml-1"
                    ></font-awesome-icon></small
                ></a>
              </th>
              <th class="message pb-0">
                <small class="condensed"><translate>Message</translate></small>
              </th>
            </tr>
          </thead>
          <tbody>
            <tr
              v-for="(entry, index) in sortedEntries"
              :key="index"
              class="detailsrow"
            >
              <td class="type">
                <span class="condensed">{{ entry.kind.toUpperCase() }}</span>
              </td>
              <td class="datetime">
                <span class="condensed">{{ formatDateTime(entry.time) }}</span>
              </td>
              <td class="message">
                <span class="condensed">{{ entry.message }}</span>
              </td>
            </tr>
          </tbody>
        </table>
      </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>
 */

import { HTTP } from "@/lib/http.js";
import { displayError } from "@/lib/errors.js";
import locale2 from "locale2";

export default {
  name: "importqueuedetail",
  props: ["job", "reload"],
  data() {
    return {
      loading: false,
      show: false,
      entries: [],
      sortAsc: true
    };
  },
  mounted() {
    this.openSpecificDetail();
  },
  watch: {
    $route() {
      this.openSpecificDetail();
    },
    reload() {
      if (this.reload) {
        this.entries = [];
        this.show = false;
      }
    }
  },
  methods: {
    openSpecificDetail() {
      const { id } = this.$route.params;
      if (id == this.job.id) {
        this.showDetails(id);
      } else {
        this.show = false;
      }
    },
    formatDate(date) {
      return date
        ? new Date(date).toLocaleDateString(locale2, {
            day: "2-digit",
            month: "2-digit",
            year: "numeric"
          })
        : "";
    },
    formatDateTime(date) {
      if (!date) return "";
      const d = new Date(date);
      return (
        d.toLocaleDateString(locale2, {
          day: "2-digit",
          month: "2-digit",
          year: "numeric"
        }) +
        " - " +
        d.toLocaleTimeString(locale2, {
          hour12: false
        })
      );
    },
    showDetails(id) {
      if (this.show) {
        this.show = false;
        return;
      }
      if (this.entries.length === 0) {
        this.loading = true;
        HTTP.get("/imports/" + id, {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            const { entries } = response.data;
            this.entries = entries;
            this.show = true;
            this.loading = false;
          })
          .catch(error => {
            const { status, data } = error.response;
            displayError({
              title: this.$gettext("Backend Error"),
              message: `${status}: ${data.message || data}`
            });
          });
      } else {
        this.show = true;
      }
    }
  },
  computed: {
    sortedEntries() {
      let sorted = this.entries.slice();
      sorted.sort((r1, r2) => {
        let d1 = new Date(r1.time);
        let d2 = new Date(r2.time);
        if (d2 < d1) {
          return !this.sortAsc ? -1 : 1;
        }
        if (d2 > d1) {
          return !this.sortAsc ? 1 : -1;
        }
        return 0;
      });
      return sorted;
    },
    sortIcon() {
      return this.sortAsc ? "sort-amount-down" : "sort-amount-up";
    },
    icon() {
      return {
        "angle-up": !this.show,
        "angle-down": this.show
      };
    },
    collapse() {
      return {
        details: true,
        collapse: true,
        show: this.show,
        "w-100": true
      };
    }
  }
};
</script>

<style lang="scss" scoped>
.condensed {
  font-stretch: condensed;
}

.entry {
  background-color: white;
  cursor: pointer;
  width: 100%;
}

.entry:hover {
  background-color: #efefef;
  transition: 1.6s;
}

.detailstable {
  margin-left: $offset;
  margin-right: $large-offset;
}

.detailsbutton {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
}
.jobid {
  width: 15%;
}

.enqueued {
  width: 20%;
}

.user {
  width: 15%;
}

.signer {
  width: 20%;
}

.kind {
  width: 10%;
}

.state {
  width: 20%;
}

.details {
  width: 50%;
}

.detailsrow {
  line-height: 0.1em;
}

.type {
  width: 65px;
  white-space: nowrap;
  padding-left: 0px;
  border-top: 0px;
  padding-bottom: $small-offset;
}

.datetime {
  width: 200px;
  white-space: nowrap;
  padding-left: 0px;
  border-top: 0px;
  padding-bottom: $small-offset;
}

.message {
  min-width: 700px;
  white-space: nowrap;
  padding-left: 0px;
  border-top: 0px;
  padding-bottom: $small-offset;
}

thead,
tbody {
  display: block;
}

tbody {
  height: 150px;
  overflow-y: auto;
  overflow-x: auto;
}
</style>