diff client/src/components/importoverview/ImportOverview.vue @ 2651:9f3856337f55

import_overview: new unified interface as default
author Thomas Junk <thomas.junk@intevation.de>
date Thu, 14 Mar 2019 14:53:17 +0100
parents client/src/components/importoverview/ImportOverviewAlt.vue@6c1730fc3dc1
children 3c04c8e46bd4
line wrap: on
line diff
--- a/client/src/components/importoverview/ImportOverview.vue	Thu Mar 14 14:50:20 2019 +0100
+++ b/client/src/components/importoverview/ImportOverview.vue	Thu Mar 14 14:53:17 2019 +0100
@@ -4,68 +4,50 @@
       icon="clipboard-check"
       title="Staging Area"
       :closeCallback="$parent.close"
+      :actions="[{ callback: loadLogs, icon: 'redo' }]"
     />
-    <div class="d-flex flex-row w-100 justify-content-end">
-      <button
-        class="btn btn-sm btn-outline-info align-self-start mr-3"
-        @click="refresh"
-      >
-        <font-awesome-icon icon="redo"></font-awesome-icon>
-      </button>
-    </div>
-    <div class="d-flex flex-row w-100 border-bottom">
-      <font-awesome-icon
-        class="pointer"
-        @click="toggleStaging()"
-        v-if="stagingVisible && staging.length > 0"
-        icon="angle-up"
-        fixed-width
-      ></font-awesome-icon>
-      <font-awesome-icon
-        class="pointer"
-        @click="toggleStaging()"
-        v-if="!stagingVisible && staging.length > 0"
-        icon="angle-down"
-        fixed-width
-      ></font-awesome-icon>
-      <span style="width:1.25em;" v-if="!(staging.length > 0)"></span>
-      <Staging v-if="stagingVisible && staging.length > 0"></Staging>
-      <div v-else class="d-flex flex-row">
-        <h6>
-          <small><translate>Review</translate></small>
-        </h6>
-        <small class="ml-3" v-if="!(staging.length > 0)"
-          ><translate>Nothing to review</translate></small
+    <div class="position-relative">
+      <transition name="fade">
+        <div
+          class="loading d-flex justify-content-center align-items-center"
+          v-if="loading"
         >
-      </div>
-    </div>
-    <div class="mt-2">
-      <div class="d-flex flex-row">
-        <font-awesome-icon
-          class="pointer"
-          @click="toggleLogs()"
-          v-if="logsVisible"
-          icon="angle-up"
-          fixed-width
-        ></font-awesome-icon>
-        <font-awesome-icon
-          class="pointer"
-          @click="toggleLogs()"
-          v-if="!logsVisible"
-          icon="angle-down"
-          fixed-width
-        ></font-awesome-icon>
-        <Logs v-if="logsVisible" :reload="reload"></Logs>
-        <div v-else>
-          <h6>
-            <small><translate>Logs</translate></small>
-          </h6>
+          <font-awesome-icon icon="spinner" spin />
+        </div>
+      </transition>
+      <div class="p-2 d-flex flex-row flex-fill justify-content-between">
+        <Filters></Filters>
+        <div>
+          <button
+            class="btn btn-sm btn-info"
+            :disabled="!reviewed.length"
+            @click="save"
+          >
+            <translate>Commit</translate> {{ reviewed.length }}
+          </button>
         </div>
       </div>
+      <LogEntry
+        class="border-top d-flex-flex-column w-100"
+        :entry="entry"
+        v-for="entry in imports"
+        :key="entry.id"
+      ></LogEntry>
     </div>
   </div>
 </template>
 
+<style lang="sass" scoped>
+.loading
+  background: rgba(255, 255, 255, 0.9)
+  position: absolute
+  z-index: 99
+  top: 0
+  right: 0
+  bottom: 0
+  left: 0
+</style>
+
 <script>
 /* This is Free Software under GNU Affero General Public License v >= 3.0
  * without warranty, see README.md and license for details.
@@ -80,54 +62,32 @@
  * Author(s):
  * Thomas Junk <thomas.junk@intevation.de>
  */
-import { displayError } from "@/lib/errors.js";
+
 import { mapState } from "vuex";
+import { displayError, displayInfo } from "@/lib/errors.js";
+import { STATES } from "@/store/imports.js";
 
 export default {
-  name: "importoverview",
+  name: "importoverviewalt",
+  components: {
+    Filters: () => import("./Filters.vue"),
+    LogEntry: () => import("./LogEntry.vue")
+  },
   data() {
     return {
-      reload: false
+      loading: false
     };
   },
-  components: {
-    Staging: () => import("./staging/Staging.vue"),
-    Logs: () => import("./importlogs/Logs.vue")
-  },
   computed: {
-    ...mapState("imports", ["stagingVisible", "logsVisible", "staging"])
+    ...mapState("imports", ["imports", "filters", "reviewed"])
   },
   methods: {
-    toggleStaging() {
-      this.$store.commit("imports/setStagingVisibility", !this.stagingVisible);
-    },
-    toggleLogs() {
-      this.$store.commit("imports/setLogsVisibility", !this.logsVisible);
-    },
-    refresh() {
-      this.reload = true;
-      this.loadImportQueue();
-      this.loadLogs();
-    },
-    loadImportQueue() {
-      this.$store
-        .dispatch("imports/getStaging")
-        .then(() => {
-          this.reload = false;
-        })
-        .catch(error => {
-          const { status, data } = error.response;
-          displayError({
-            title: "Backend Error",
-            message: `${status}: ${data.message || data}`
-          });
-        });
-    },
     loadLogs() {
+      this.loading = true;
       this.$store
         .dispatch("imports/getImports")
         .then(() => {
-          this.reload = false;
+          this.loading = false;
         })
         .catch(error => {
           const { status, data } = error.response;
@@ -136,17 +96,81 @@
             message: `${status}: ${data.message || data}`
           });
         });
+    },
+    save() {
+      if (!this.reviewed.length) return;
+
+      let popupContent = `<table class="table table-sm small mb-0 border-0" style="margin-top: -1px;">`;
+      this.reviewed.forEach(r => {
+        let imp = this.imports.find(i => i.id === r.id);
+        let approved = STATES.APPROVED === r.status;
+        popupContent += `<tr>
+          <td>${imp.id}</td>
+          <td>${imp.kind.toUpperCase()}</td>
+          <td>${this.$options.filters.dateTime(imp.enqueued)}</td>
+          <td class="text-${approved ? "success" : "danger"}">
+            ${this.$gettext(approved ? "approved" : "declined")}
+          </td>
+        </tr>`;
+      });
+      popupContent += "</table>";
+
+      this.$store.commit("application/popup", {
+        icon: "clipboard-check",
+        title: this.$gettext("Finish Review"),
+        padding: false,
+        big: true,
+        content: popupContent,
+        confirm: {
+          icon: "check",
+          callback: () => {
+            let data = this.reviewed.map(r => ({
+              id: r.id,
+              state: r.status
+            }));
+            this.$store
+              .dispatch("imports/confirmReview", data)
+              .then(response => {
+                this.loadLogs();
+                this.$store.commit("imports/setReviewed", []);
+                const messages = response.data
+                  .map(x => {
+                    if (x.message) return x.message;
+                    if (x.error) return x.error;
+                  })
+                  .join("\n\n");
+                displayInfo({
+                  title: "Staging Area",
+                  message: messages,
+                  options: {
+                    timeout: 0,
+                    buttons: [{ text: "Ok", action: null, bold: true }]
+                  }
+                });
+              })
+              .catch(error => {
+                const { status, data } = error.response;
+                displayError({
+                  title: "Backend Error",
+                  message: `${status}: ${data.message || data}`
+                });
+              });
+          }
+        },
+        cancel: {
+          label: this.$gettext("Cancel"),
+          icon: "times"
+        }
+      });
+    }
+  },
+  watch: {
+    filters() {
+      this.$store.dispatch("imports/getImports", this.filters);
     }
   },
   mounted() {
-    this.refresh();
+    this.loadLogs();
   }
 };
 </script>
-
-<style lang="scss" scoped>
-.overview {
-  max-height: 850px;
-  overflow-y: auto;
-}
-</style>