Mercurial > gemma
view client/src/components/importqueue/Importqueue.vue @ 2350:ed6b0a43d42f
staging: open detailsview for UBN too
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Wed, 20 Feb 2019 10:58:32 +0100 |
parents | bc43cd047ead |
children | f185503ef35a |
line wrap: on
line source
<template> <div class="d-flex flex-row"> <Spacer></Spacer> <div class="mt-3 importqueuecard flex-grow-1"> <div class="card shadow-xs"> <h6 class="mb-0 py-2 px-3 border-bottom d-flex text-info align-items-center" > <font-awesome-icon icon="tasks" class="mr-2"></font-awesome-icon> <translate class="headline">Importqueue</translate> </h6> <div class="card-body importcardbody"> <div class="card-body importcardbody"> <div class="searchandfilter d-flex flex-row"> <div class="searchgroup input-group"> <div class="input-group-prepend"> <span class="input-group-text" id="search"> <font-awesome-icon icon="search"></font-awesome-icon> </span> </div> <input v-model="searchQuery" type="text" class="form-control" placeholder aria-label="Search" aria-describedby="search" /> </div> <div class="filters"> <button @click="setFilter('failed')" :class="failedStyle"> <translate>Failed</translate> </button> <button @click="setFilter('pending')" :class="pendingStyle"> <translate>Pending</translate> </button> <button @click="setFilter('rejected')" :class="rejectedStyle"> <translate>Rejected</translate> </button> <button @click="setFilter('accepted')" :class="acceptedStyle"> <translate>Accepted</translate> </button> <button @click="setFilter('warning')" :class="warningStyle"> <translate>Warning</translate> </button> </div> </div> <div class="text-left d-flex flex-row border-bottom entries"> <div class="header py-1 jobid mr-2"> <translate>Id</translate> </div> <div class="header py-1 enqueued mr-2"> <translate>Enqueued</translate> </div> <div class="header py-1 kind mr-2"> <translate>Kind</translate> </div> <div class="header py-1 user mr-2"> <translate>User</translate> </div> <div class="header py-1 signer mr-2"> <translate>Signer</translate> </div> <div class="header py-1 state mr-2"> <translate>State</translate> </div> </div> <div class="importqueuedetail"> <div class="text-left" v-for="job in filteredImports" :key="job.id" > <Importqueuedetail :reload="reload" :job="job" ></Importqueuedetail> </div> </div> <div> <button @click="refresh" class="btn btn-info refresh"> <translate>Refresh</translate> </button> </div> </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): * Markus Kottländer <markus@intevation.de> */ import { displayError } from "@/lib/errors.js"; import { mapState } from "vuex"; import { HTTP } from "@/lib/http.js"; export default { name: "importqueue", components: { Importqueuedetail: () => import("./Importqueuedetail"), Spacer: () => import("@/components/Spacer") }, data() { return { reload: false, searchQuery: "", successful: false, failed: false, pending: false, rejected: false, accepted: false, warning: false }; }, mounted() { this.loadQueue(); }, methods: { setFilter(name) { this[name] = !this[name]; const allSet = this.failed && this.pending && this.accepted && this.rejected && this.warning; if (allSet) { this.warning = false; this.successful = false; this.failed = false; this.pending = false; this.accepted = false; this.rejected = false; } }, loadQueue() { this.reload = true; this.$store .dispatch("imports/getImports") .then(() => { this.reload = false; }) .catch(error => { const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); }, refresh() { this.loadQueue(); }, showDetails(id) { HTTP.get("/imports/" + id, { headers: { "X-Gemma-Auth": localStorage.getItem("token") } }) .then(response => { const { entries } = response.data; this.entries = entries; this.$modal.show("details"); }) .catch(error => { const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); }, close() { this.$modal.hide("details"); } }, computed: { ...mapState("imports", ["imports"]), ...mapState("application", ["showSidebar"]), sortIcon() { return this.sortAsc ? "sort-amount-down" : "sort-amount-up"; }, filteredImports() { const filtered = this.imports .filter(element => { if (!this.searchQuery) return true; return [(element.kind, element.user, element.enqueued)].some(x => { return x.toLowerCase().includes(this.searchQuery.toLowerCase()); }); }) .filter(y => { if ( !this.failed && !this.pending && !this.accepted && !this.rejected && !this.warning ) return true; let filterCriteria = []; if (this.failed) filterCriteria.push("failed"); if (this.pending) filterCriteria.push("pending"); if (this.accepted) filterCriteria.push("accepted"); if (this.rejected) filterCriteria.push("declined"); const result = filterCriteria.map(selectedState => { return y.state === selectedState; }); if (this.warning) return result.some(x => x) || y.warnings; return result.some(x => x); }); return filtered; }, pendingStyle() { return { btn: true, "btn-light": !this.pending, "btn-dark": this.pending }; }, failedStyle() { return { btn: true, "btn-light": !this.failed, "btn-dark": this.failed }; }, rejectedStyle() { return { btn: true, "btn-light": !this.rejected, "btn-dark": this.rejected }; }, acceptedStyle() { return { btn: true, "btn-light": !this.accepted, "btn-dark": this.accepted }; }, warningStyle() { return { btn: true, "btn-light": !this.warning, "btn-dark": this.warning }; } } }; </script> <style lang="scss" scoped> .importqueuedetail { margin-bottom: 3rem; } .entries { width: 100%; } .jobid { width: 15%; } .enqueued { width: 15%; } .user { width: 15%; } .signer { width: 15%; } .kind { width: 10%; } .state { width: 15%; } .details thead { display: block; } .details tbody { display: block; } .details tbody { height: 260px; overflow-y: auto; overflow-x: hidden; } .closebutton { top: $small-offset; } .refresh { position: absolute; right: $offset; bottom: $offset; } .importqueuecard { width: 97%; margin-right: $offset; min-height: 20rem; } .card-body { width: 100%; margin-left: auto; margin-right: auto; } .searchandfilter { position: relative; margin-bottom: $xx-large-offset; } .filters { position: absolute; right: 0; } .filters button { margin-right: $small-offset; } .table td, .table th { border-top: 0 !important; text-align: left; padding: $small-offset !important; } .searchgroup { position: absolute; left: 0; width: 45%; } </style>