view client/src/components/importoverview/LogEntry.vue @ 5736:55892008ec96 default tip

Fixed a bunch of corner cases in WG import.
author Sascha Wilde <wilde@sha-bang.de>
date Wed, 29 May 2024 19:02:42 +0200
parents 84d01a536bec
children
line wrap: on
line source

<template>
  <div class="row w-100 no-gutters text-left">
    <div style="width: 70px;" class="table-cell d-flex justify-content-between">
      <UISpinnerButton
        @click="toggleDetails"
        :loading="loading"
        :state="entry.id === show"
        :icons="['angle-right', 'angle-down']"
      />
      {{ entry.id }}
    </div>
    <div style="width: 125px;" class="table-cell center">
      {{ entry.kind.replace("fm_", "").toUpperCase() }}
    </div>
    <div style="width: 135px;" class="table-cell center">
      {{ entry.enqueued | dateTime }}
    </div>
    <div style="width: 80px;" class="table-cell truncate">
      {{ entry.user }}
    </div>
    <div style="width: 50px;" class="table-cell center">
      {{ userCountries[entry.user] }}
    </div>
    <div style="width: 80px;" class="table-cell truncate">
      {{ entry.signer }}
    </div>
    <div style="width: 72px;" :class="stateStyle">
      {{ entry.state }}
    </div>
    <div style="width: 138px;" class="table-cell center">
      {{ entry.changed | dateTime }}
    </div>
    <div style="width: 44px;" class="table-cell center">
      <font-awesome-icon
        v-if="entry.warnings || entry.errors"
        :class="{
          'text-warning': entry.warnings && !entry.errors,
          'text-danger': entry.errors
        }"
        icon="exclamation-triangle"
        fixed-width
      />
    </div>
    <div style="flex-grow: 1; padding: 0;" class="table-cell text-right">
      <button
        :class="['action approved', { active: isApproved }]"
        @click="toggleApproval($options.STATES.APPROVED)"
        v-if="entry.state === 'pending'"
      >
        <font-awesome-icon class="small pointer" icon="check" />
      </button>
      <button
        :class="['action rejected', { active: isRejected }]"
        @click="toggleApproval($options.STATES.REJECTED)"
        v-if="entry.state === 'pending'"
      >
        <font-awesome-icon icon="times" class="small pointer" />
      </button>
    </div>
  </div>
</template>

<style scoped>
.action {
  height: 100%;
  width: 50%;
  border: 0;
  background: white;
  outline: none;
}
.action.approved {
  color: green;
}
.action.approved.active,
.action.approved:hover {
  color: white;
  background: green;
}
.action.rejected {
  border-left: 1px solid #dee2e6;
  color: red;
}
.action.rejected.active,
.action.rejected:hover {
  color: white;
  background: red;
}

.active .action {
  background-color: #d2eaee;
}
.active .action.rejected {
  border-left: solid 1px rgba(255, 255, 255, 0.3);
}
</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):
 * * Thomas Junk <thomas.junk@intevation.de>
 * * Markus Kottländer <markus.kottlaender@intevation.de>
 */
import { mapState, mapGetters } from "vuex";
import { STATES } from "@/store/imports";
import { displayError } from "@/lib/errors";
import { HTTP } from "@/lib/http";

export default {
  STATES,
  props: ["entry"],
  data() {
    return {
      loading: false
    };
  },
  computed: {
    ...mapState("imports", ["show"]),
    ...mapGetters("usermanagement", ["userCountries"]),
    stateStyle() {
      return [
        "table-cell",
        "center",
        {
          "text-danger": this.entry.state === "failed",
          "font-weight-bolder": this.entry.state === "running"
        }
      ];
    },
    needsApproval() {
      return this.entry.status === STATES.NEEDSAPPROVAL;
    },
    isRejected() {
      return this.entry.status === STATES.REJECTED;
    },
    isApproved() {
      return this.entry.status === STATES.APPROVED;
    }
  },
  methods: {
    toggleApproval(state) {
      this.$store.commit("imports/toggleApprove", {
        id: this.entry.id,
        newStatus: state
      });
    },
    toggleDetails() {
      const { id } = this.entry;
      if (id === this.show) {
        this.$store.commit("imports/hideDetails");
        this.$store.commit("imports/hideAdditionalInfo");
        this.$store.commit("imports/hideAdditionalLogs");
        this.$store.commit("map/reviewActive", false);
      } else {
        this.loading = true;
        HTTP.get("/imports/" + this.entry.id, {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            this.$store.commit("imports/showDetailsFor", id);
            this.$store.commit("imports/setCurrentDetails", response.data);
          })
          .catch(error => {
            let message = "Backend not reachable";
            if (error.response) {
              const { status, data } = error.response;
              message = `${status}: ${data.message || data}`;
            }
            displayError({
              title: this.$gettext("Backend Error"),
              message: message
            });
          })
          .finally(() => (this.loading = false));
      }
    }
  }
};
</script>