diff client/src/components/sections/Sections.vue @ 3290:3ada3d0347bd

client: define sections: duplicated and adjusted code from stretches
author Markus Kottlaender <markus@intevation.de>
date Thu, 16 May 2019 13:18:11 +0200
parents
children dc435fbb2d7a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/sections/Sections.vue	Thu May 16 13:18:11 2019 +0200
@@ -0,0 +1,249 @@
+<template>
+  <div class="d-flex flex-column">
+    <UIBoxHeader icon="road" :title="title" :closeCallback="$parent.close" />
+    <div class="position-relative">
+      <UISpinnerOverlay v-if="loading" />
+      <SectionForm v-if="showForm" :editSection="editSection" />
+      <div v-else>
+        <UITableHeader
+          :columns="[
+            { id: 'properties.name', title: `${nameLabel}`, class: 'col-4' },
+            {
+              id: 'properties.date_info',
+              title: `${dateLabel}`,
+              class: 'col-2'
+            },
+            {
+              id: 'properties.source_organization',
+              title: `${sourceorganizationLabel}`,
+              class: 'col-3'
+            }
+          ]"
+        />
+        <UITableBody
+          :data="filteredSections() | sortTable(sortColumn, sortDirection)"
+        >
+          <template v-slot:row="{ item: section }">
+            <div class="py-1 px-2 col-4">
+              <a @click="moveMapToSection(section)" href="#">
+                {{ section.properties.name }}
+              </a>
+            </div>
+            <div class="py-1 px-2 col-2">
+              {{ section.properties.date_info | surveyDate }}
+            </div>
+            <div class="py-1 px-2 col-3">
+              {{ section.properties.source_organization }}
+            </div>
+            <div class="py-1 px-2 col text-right">
+              <button
+                v-if="isInStaging(section.properties.name)"
+                @click="gotoStaging(section.properties.name)"
+                class="btn btn-xs btn-danger mr-1"
+              >
+                <font-awesome-icon
+                  icon="exclamation-triangle"
+                  fixed-width
+                  v-tooltip="reviewTooltip"
+                />
+              </button>
+              <button
+                class="btn btn-xs btn-dark mr-1"
+                @click="
+                  showForm = true;
+                  editSection = section;
+                "
+              >
+                <font-awesome-icon icon="pencil-alt" fixed-width />
+              </button>
+              <button
+                class="btn btn-xs btn-dark"
+                @click="deleteSection(section)"
+              >
+                <font-awesome-icon icon="trash" fixed-width />
+              </button>
+            </div>
+          </template>
+        </UITableBody>
+        <div class="text-right p-2 border-top">
+          <button
+            @click="
+              showForm = true;
+              editSection = null;
+            "
+            class="btn btn-sm btn-info"
+          >
+            <translate>New section</translate>
+          </button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang="sass" scoped>
+.input-button
+  border-top-left-radius: 0
+  border-bottom-left-radius: 0
+  right: 0
+  height: 31px
+</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>
+ * Tom Gottfried <tom.gottfried@intevation.de>
+ */
+import { mapState, mapGetters } from "vuex";
+import { displayError, displayInfo } from "@/lib/errors";
+import { HTTP } from "@/lib/http";
+import { sortTable } from "@/lib/mixins";
+
+export default {
+  mixins: [sortTable],
+  components: {
+    SectionForm: () => import("./SectionForm")
+  },
+  data() {
+    return {
+      staging: [],
+      loading: false,
+      showForm: false,
+      editSection: null
+    };
+  },
+  computed: {
+    ...mapState("application", ["searchQuery"]),
+    ...mapGetters("map", ["openLayersMap"]),
+    ...mapState("imports", ["sections"]),
+    title() {
+      return this.$gettext("Define Sections");
+    },
+    nameLabel() {
+      return this.$gettext("Name");
+    },
+    dateLabel() {
+      return this.$gettext("Date");
+    },
+    sourceorganizationLabel() {
+      return this.$gettext("Source organization");
+    },
+    reviewTooltip() {
+      return this.$gettext("Review pending import");
+    }
+  },
+  methods: {
+    filteredSections() {
+      return this.sections.filter(s => {
+        return (s.properties.name + s.properties.source_organization)
+          .toLowerCase()
+          .includes(this.searchQuery.toLowerCase());
+      });
+    },
+    gotoStaging(sectionName) {
+      let pendingImport = this.staging.find(s => s.name === sectionName);
+      if (pendingImport)
+        this.$router.push("/imports/overview/" + pendingImport.id);
+    },
+    isInStaging(sectionName) {
+      return !!this.staging.find(s => s.name === sectionName);
+    },
+    loadStagingData() {
+      HTTP.get("/imports?states=pending&kinds=sec", {
+        headers: { "X-Gemma-Auth": localStorage.getItem("token") }
+      })
+        .then(response => {
+          response.data.imports.forEach(i => {
+            HTTP.get("/imports/" + i.id, {
+              headers: { "X-Gemma-Auth": localStorage.getItem("token") }
+            })
+              .then(response => {
+                this.staging.push({
+                  id: i.id,
+                  name: response.data.summary.section
+                });
+              })
+              .catch(error => {
+                const { status, data } = error.response;
+                displayError({
+                  title: this.$gettext("Backend Error"),
+                  message: `${status}: ${data.message || data}`
+                });
+              })
+              .finally(() => (this.loading = false));
+          });
+        })
+        .catch(error => {
+          const { status, data } = error.response;
+          displayError({
+            title: this.$gettext("Backend Error"),
+            message: `${status}: ${data.message || data}`
+          });
+        });
+    },
+    deleteSection(section) {
+      this.$store.commit("application/popup", {
+        icon: "trash",
+        title: this.$gettext("Delete Section"),
+        content:
+          this.$gettext("Do you really want to delete this section:") +
+          `<br>
+        <b>${section.properties.name}, ${
+            section.properties.source_organization
+          } (${section.properties.countries})</b>`,
+        confirm: {
+          label: this.$gettext("Delete"),
+          icon: "trash",
+          callback: () => {
+            displayInfo({
+              title: this.$gettext("Not implemented"),
+              message: this.$gettext("Deleting ") + section.id
+            });
+          }
+        },
+        cancel: {
+          label: this.$gettext("Cancel"),
+          icon: "times"
+        }
+      });
+    },
+    moveMapToSection(section) {
+      this.$store.commit("imports/selectedSectionId", section.id);
+      this.$store.commit("fairwayavailability/type", "sections");
+      this.$store.commit("application/showFairwayDepth", true);
+      this.openLayersMap()
+        .getLayer("SECTIONS")
+        .setVisible(true);
+      this.$store.dispatch("map/moveToFeauture", {
+        feature: section,
+        zoom: 17,
+        preventZoomOut: true
+      });
+    }
+  },
+  mounted() {
+    this.loading = true;
+    this.$store
+      .dispatch("imports/loadSections")
+      .catch(error => {
+        const { status, data } = error.response;
+        displayError({
+          title: this.$gettext("Backend Error"),
+          message: `${status}: ${data.message || data}`
+        });
+      })
+      .finally(() => (this.loading = false));
+    this.loadStagingData();
+  }
+};
+</script>