changeset 1554:15d736a402c9

importqueue as collapsible
author Thomas Junk <thomas.junk@intevation.de>
date Tue, 11 Dec 2018 13:33:52 +0100
parents 35f85da41fdb
children a3c2b192daa2
files client/package.json client/src/components/admin/Importqueue.vue client/src/components/admin/Importqueuedetail.vue client/src/main.js client/yarn.lock
diffstat 5 files changed, 265 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/client/package.json	Tue Dec 11 09:59:23 2018 +0100
+++ b/client/package.json	Tue Dec 11 13:33:52 2018 +0100
@@ -41,7 +41,6 @@
     "vue-clipboard2": "^0.2.1",
     "vue-color": "^2.6.0",
     "vue-highlightjs": "^1.3.3",
-    "vue-js-modal": "^1.3.27",
     "vue-js-toggle-button": "^1.3.0",
     "vue-router": "^3.0.2",
     "vue-snotify": "^3.2.1",
--- a/client/src/components/admin/Importqueue.vue	Tue Dec 11 09:59:23 2018 +0100
+++ b/client/src/components/admin/Importqueue.vue	Tue Dec 11 13:33:52 2018 +0100
@@ -48,30 +48,29 @@
                 </button>
               </div>
             </div>
-            <table class="table">
-              <thead>
-                <tr>
-                  <th><translate>Enqueued</translate></th>
-                  <th><translate>Kind</translate></th>
-                  <th><translate>User</translate></th>
-                  <th><translate>Signer</translate></th>
-                  <th><translate>State</translate></th>
-                </tr>
-              </thead>
-              <tbody>
-                <tr
-                  @click="showDetails(job.id)"
-                  v-for="job in filteredImports"
-                  :key="job.id"
-                >
-                  <td>{{ formatSurveyDate(job.enqueued) }}</td>
-                  <td>{{ job.kind }}</td>
-                  <td>{{ job.user }}</td>
-                  <td>{{ job.signer }}</td>
-                  <td>{{ job.state }}</td>
-                </tr>
-              </tbody>
-            </table>
+            <div class="text-left d-flex flex-row border-bottom">
+              <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="text-left" v-for="job in filteredImports" :key="job.id">
+              <Importqueuedetail :job="job"></Importqueuedetail>
+            </div>
             <div>
               <button @click="refresh" class="btn btn-info refresh">
                 <translate>Refresh</translate>
@@ -81,37 +80,6 @@
         </div>
       </div>
     </div>
-    <modal name="details" :heigth="400" :width="600" :scrollable="true">
-      <div @click="close" class="ui-element closebutton">
-        <font-awesome-icon icon="times"></font-awesome-icon>
-      </div>
-      <div class="details">
-        <table class="table">
-          <thead>
-            <tr>
-              <th class="first"><translate>Kind</translate></th>
-              <th class="second">
-                <a href="#" @click="sortAsc = !sortAsc" class="sort-link"
-                  ><translate>Date</translate>
-                  <font-awesome-icon
-                    :icon="sortIcon"
-                    class="ml-1"
-                  ></font-awesome-icon
-                ></a>
-              </th>
-              <th class="third"><translate>Message</translate></th>
-            </tr>
-          </thead>
-          <tbody>
-            <tr v-for="(entry, index) in sortedEntries" :key="index">
-              <td class="first">{{ entry.kind }}</td>
-              <td class="second">{{ formatSurveyDate(entry.time) }}</td>
-              <td class="third">{{ entry.message }}</td>
-            </tr>
-          </tbody>
-        </table>
-      </div>
-    </modal>
   </div>
 </template>
 
@@ -132,10 +100,13 @@
 import { displayError } from "../../lib/errors.js";
 import { mapState } from "vuex";
 import { HTTP } from "../../lib/http.js";
-import { formatSurveyDate } from "../../lib/date.js";
+import Importqueuedetail from "./Importqueuedetail";
 
 export default {
   name: "importqueue",
+  components: {
+    Importqueuedetail
+  },
   data() {
     return {
       searchQuery: "",
@@ -143,21 +114,13 @@
       failed: false,
       pending: false,
       rejected: false,
-      accepted: false,
-      entries: [],
-      sortAsc: true
+      accepted: false
     };
   },
   mounted() {
     this.loadQueue();
   },
   methods: {
-    formatSurveyDate(date) {
-      return formatSurveyDate(date);
-    },
-    clearEntries() {
-      this.entries = [];
-    },
     setFilter(name) {
       this[name] = !this[name];
       const allSet =
@@ -210,21 +173,6 @@
   computed: {
     ...mapState("imports", ["imports"]),
     ...mapState("application", ["showSidebar"]),
-    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";
     },
@@ -307,6 +255,35 @@
 </script>
 
 <style lang="scss" scoped>
+.jobid {
+  width: 80px;
+}
+
+.enqueued {
+  width: 120px;
+}
+
+.user {
+  width: 80px;
+}
+
+.signer {
+  width: 80px;
+}
+
+.kind {
+  width: 80px;
+}
+
+.state {
+  width: 80px;
+}
+
+.header {
+  font-weight: bold;
+  font-size: 0.9em;
+}
+
 .details thead {
   display: block;
 }
@@ -320,21 +297,6 @@
   overflow-x: hidden;
 }
 
-.first {
-  width: 65px;
-  padding-left: 0px;
-}
-
-.second {
-  width: 180px;
-  padding-left: 0px;
-}
-
-.third {
-  width: 355px;
-  padding-left: 0px;
-}
-
 .closebutton {
   top: $small-offset;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/admin/Importqueuedetail.vue	Tue Dec 11 13:33:52 2018 +0100
@@ -0,0 +1,208 @@
+<template>
+  <div class="d-flex flex-column py-1">
+    <div class="d-flex flex-row">
+      <div @click="showDetails(job.id)" class="jobid mr-2">{{ job.id }}</div>
+      <div @click="showDetails(job.id)" class="enqueued mr-2">
+        {{ formatDate(job.enqueued) }}
+      </div>
+      <div @click="showDetails(job.id)" class="kind mr-2">{{ job.kind }}</div>
+      <div @click="showDetails(job.id)" class="user mr-2">{{ job.user }}</div>
+      <div @click="showDetails(job.id)" class="signer mr-2">
+        {{ job.signer }}
+      </div>
+      <div @click="showDetails(job.id)" class="state mr-2">{{ job.state }}</div>
+    </div>
+    <div class="d-flex flex-row">
+      <div :class="collapse">
+        <table class="table table-responsive">
+          <thead>
+            <tr>
+              <th class="first">
+                <small><translate>Kind</translate></small>
+              </th>
+              <th class="second">
+                <a href="#" @click="sortAsc = !sortAsc" class="sort-link"
+                  ><small><translate>Date</translate></small>
+                  <small
+                    ><font-awesome-icon
+                      :icon="sortIcon"
+                      class="ml-1"
+                    ></font-awesome-icon></small
+                ></a>
+              </th>
+              <th class="third">
+                <small><translate>Message</translate></small>
+              </th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr
+              v-for="(entry, index) in sortedEntries"
+              :key="index"
+              class="detailsrow"
+            >
+              <td class="first">
+                <small>{{ entry.kind }}</small>
+              </td>
+              <td class="second">
+                <small>{{ formatDate(entry.time) }}</small>
+              </td>
+              <td class="third">
+                <small>{{ entry.message }}</small>
+              </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"],
+  data() {
+    return {
+      show: false,
+      entries: [],
+      sortAsc: true
+    };
+  },
+  methods: {
+    formatDate(date) {
+      return date
+        ? new Date(date).toLocaleDateString(locale2, {
+            day: "2-digit",
+            month: "2-digit",
+            year: "numeric"
+          })
+        : "";
+    },
+    showDetails(id) {
+      if (this.show) {
+        this.show = false;
+        return;
+      }
+      HTTP.get("/imports/" + id, {
+        headers: { "X-Gemma-Auth": localStorage.getItem("token") }
+      })
+        .then(response => {
+          const { entries } = response.data;
+          this.entries = entries;
+          this.show = true;
+        })
+        .catch(error => {
+          const { status, data } = error.response;
+          displayError({
+            title: this.$gettext("Backend Error"),
+            message: `${status}: ${data.message || data}`
+          });
+        });
+    }
+  },
+  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";
+    },
+    collapse() {
+      return {
+        animated: true,
+        fadeIn: this.show,
+        details: true,
+        collapse: true,
+        show: this.show
+      };
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.jobid {
+  width: 80px;
+}
+
+.enqueued {
+  width: 120px;
+}
+
+.user {
+  width: 80px;
+}
+
+.signer {
+  width: 80px;
+}
+
+.kind {
+  width: 80px;
+}
+
+.state {
+  width: 80px;
+}
+
+.details {
+  background-color: #fafafa;
+  width: 50%;
+}
+
+.detailsrow {
+  line-height: 0.1em;
+}
+
+.first {
+  width: 65px;
+  padding-left: 0px;
+  border-top: 0px;
+  padding-bottom: $small-offset;
+}
+
+.second {
+  width: 100px;
+  padding-left: 0px;
+  border-top: 0px;
+  padding-bottom: $small-offset;
+}
+
+.third {
+  width: 355px;
+  padding-left: 0px;
+  border-top: 0px;
+  padding-bottom: $small-offset;
+}
+</style>
--- a/client/src/main.js	Tue Dec 11 09:59:23 2018 +0100
+++ b/client/src/main.js	Tue Dec 11 13:33:52 2018 +0100
@@ -120,9 +120,7 @@
   faWrench
 );
 import ToggleButton from "vue-js-toggle-button";
-import VModal from "vue-js-modal";
 
-Vue.use(VModal);
 Vue.use(ToggleButton);
 
 Vue.component("font-awesome-icon", FontAwesomeIcon);
--- a/client/yarn.lock	Tue Dec 11 09:59:23 2018 +0100
+++ b/client/yarn.lock	Tue Dec 11 13:33:52 2018 +0100
@@ -10768,11 +10768,6 @@
     tsconfig "^7.0.0"
     vue-template-es2015-compiler "^1.6.0"
 
-vue-js-modal@^1.3.27:
-  version "1.3.27"
-  resolved "https://registry.yarnpkg.com/vue-js-modal/-/vue-js-modal-1.3.27.tgz#c0733d439c9f3c0f0e6a271b3d85604d5328e039"
-  integrity sha512-w27jHJWTRlcA7qQLs3yM6mi2wFsMHdqHTfyTxO7ENOCInoBY2bIECpAZZ9e8mD8Ka39AaBVkECf95NHE7/oqNg==
-
 vue-js-toggle-button@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/vue-js-toggle-button/-/vue-js-toggle-button-1.3.0.tgz#59240f215fd502f54f0c210c5fac878960b0131c"