changeset 1177:48ae4458710d

save cross profiles to local storage to restore them from a dropdown
author Markus Kottlaender <markus@intevation.de>
date Thu, 15 Nov 2018 09:27:16 +0100
parents fdab87f013e2
children 1ffb4b9ca5ee
files client/src/fairway/Fairwayprofile.vue client/src/store/fairway.js
diffstat 2 files changed, 107 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/fairway/Fairwayprofile.vue	Wed Nov 14 14:45:34 2018 +0100
+++ b/client/src/fairway/Fairwayprofile.vue	Thu Nov 15 09:27:16 2018 +0100
@@ -43,16 +43,39 @@
                                 <br>
                                 Lon: {{ endPoint[0] }}
                             </div>
+                            <button class="btn btn-outline-secondary btn-sm ml-2 mt-auto"
+                                    @click="showLabelInput = !showLabelInput">
+                              <i :class="'fa fa-' + (showLabelInput ? 'times' : 'save')"></i>
+                            </button>
                             <button v-clipboard:copy="coordinatesForClipboard"
                                     v-clipboard:success="onCopyCoordinates"
                                     class="btn btn-outline-secondary btn-sm ml-2 mt-auto">
                               <i class="fa fa-copy"></i>
                             </button>
                         </div>
-                        Enter manually:
+                        <div v-if="showLabelInput">
+                          Enter label for cross profile:
+                          <div class="position-relative">
+                              <input class="form-control form-control-sm pr-5" v-model="cutLabel" /><br>
+                              <button class="btn btn-sm btn-outline-secondary position-absolute"
+                                      @click="saveCut"
+                                      v-if="cutLabel"
+                                      style="top: 0; right: 0;">
+                                <i class="fa fa-check"></i>
+                              </button>
+                          </div>
+                        </div>
+                        Saved cross profiles:
+                        <select class="form-control form-control-sm mb-2" v-model="coordinatesSelect">
+                            <option></option>
+                            <option v-for="(cut, index) in previousCuts" :value="cut.coordinates" :key="index">
+                              {{ cut.label }}
+                            </option>
+                        </select>
+                        Enter coordinates manually:
                         <div class="position-relative">
                             <input class="form-control form-control-sm pr-5" placeholder="Lat,Lon,Lat,Lon" v-model="coordinatesInput" /><br>
-                            <button class="btn btn-sm btn-outline-secondary position-absolute" @click="applyCoordinates" style="top: 0; right: 0;">
+                            <button class="btn btn-sm btn-outline-secondary position-absolute" @click="applyManualCoordinates" style="top: 0; right: 0;">
                               <i class="fa fa-check"></i>
                             </button>
                         </div>
@@ -97,6 +120,7 @@
   margin-bottom: auto
   margin-right: $large-offset
   margin-left: auto
+  max-width: 300px
 
 .additionalsurveys input
   margin-right: $small-offset
@@ -144,7 +168,10 @@
   data() {
     return {
       wait: false,
-      coordinatesInput: ""
+      coordinatesInput: "",
+      coordinatesSelect: null,
+      cutLabel: "",
+      showLabelInput: false
     };
   },
   computed: {
@@ -159,7 +186,8 @@
       "totalLength",
       "fairwayCoordinates",
       "waterLevels",
-      "selectedWaterLevel"
+      "selectedWaterLevel",
+      "previousCuts"
     ]),
     ...mapState("bottlenecks", ["selectedBottleneck", "selectedSurvey"]),
     additionalSurvey: {
@@ -226,6 +254,14 @@
     },
     fairwayCoordinates() {
       this.drawDiagram();
+    },
+    selectedBottleneck() {
+      this.$store.dispatch("fairwayprofile/previousCuts");
+      this.cutLabel =
+        this.selectedBottleneck + " (" + new Date().toISOString() + ")";
+    },
+    coordinatesSelect(newValue) {
+      this.applyCoordinates(newValue);
     }
   },
   methods: {
@@ -259,6 +295,7 @@
         });
     },
     drawDiagram() {
+      this.coordinatesSelect = null;
       const chartDiv = document.querySelector(".fairwayprofile");
       d3.select("svg").remove();
       let svg = d3.select(chartDiv).append("svg");
@@ -477,27 +514,56 @@
         message: "Coordinates copied to clipboard!"
       });
     },
-    applyCoordinates() {
-      if (this.coordinatesInput) {
-        const coordinates = this.coordinatesInput
-          .split(",")
-          .map(coord => parseFloat(coord.trim()));
-        if (coordinates.length === 4) {
-          // draw line on map
-          const cutLayer = this.getLayerByName("Cut Tool");
-          cutLayer.data.getSource().clear();
-          const cut = new Feature({
-            geometry: new LineString([
-              [coordinates[1], coordinates[0]],
-              [coordinates[3], coordinates[2]]
-            ]).transform("EPSG:4326", "EPSG:3857")
-          });
-          cutLayer.data.getSource().addFeature(cut);
+    applyManualCoordinates() {
+      const coordinates = this.coordinatesInput
+        .split(",")
+        .map(coord => parseFloat(coord.trim()));
+      this.applyCoordinates([
+        coordinates[1],
+        coordinates[0],
+        coordinates[3],
+        coordinates[2]
+      ]);
+    },
+    applyCoordinates(coordinates) {
+      if (coordinates.length === 4) {
+        // draw line on map
+        const cutLayer = this.getLayerByName("Cut Tool");
+        cutLayer.data.getSource().clear();
+        const cut = new Feature({
+          geometry: new LineString([
+            [coordinates[0], coordinates[1]],
+            [coordinates[2], coordinates[3]]
+          ]).transform("EPSG:4326", "EPSG:3857")
+        });
+        cutLayer.data.getSource().addFeature(cut);
 
-          // draw diagram
-          this.$store.dispatch("fairwayprofile/cut", cut);
-        }
+        // draw diagram
+        this.$store.dispatch("fairwayprofile/cut", cut);
       }
+    },
+    saveCut() {
+      const previousCuts =
+        JSON.parse(localStorage.getItem("previousCuts")) || [];
+      const newEntry = {
+        label: this.cutLabel,
+        bottleneckName: this.selectedBottleneck,
+        coordinates: [...this.startPoint, ...this.endPoint]
+      };
+      const existingEntry = previousCuts.find(cut => {
+        return JSON.stringify(cut) === JSON.stringify(newEntry);
+      });
+      if (!existingEntry) previousCuts.push(newEntry);
+      if (previousCuts.length > 100) previousCuts.shift();
+      localStorage.setItem("previousCuts", JSON.stringify(previousCuts));
+      this.$store.dispatch("fairwayprofile/previousCuts");
+
+      this.showLabelInput = false;
+      displayInfo({
+        title: "Coordinates saved!",
+        message:
+          'You can now select these coordinates from the "Saved cross profiles" menu to restore this cross profile.'
+      });
     }
   },
   mounted() {
--- a/client/src/store/fairway.js	Wed Nov 14 14:45:34 2018 +0100
+++ b/client/src/store/fairway.js	Thu Nov 15 09:27:16 2018 +0100
@@ -37,7 +37,8 @@
     selectedWaterLevel: DEMOLEVEL,
     fairwayCoordinates: [],
     startPoint: null,
-    endPoint: null
+    endPoint: null,
+    previousCuts: []
   },
   getters: {
     length: state => {
@@ -94,6 +95,9 @@
       state.fairwayCoordinates = [];
       state.startPoint = null;
       state.endPoint = null;
+    },
+    previousCuts: (state, previousCuts) => {
+      state.previousCuts = previousCuts;
     }
   },
   actions: {
@@ -184,6 +188,7 @@
             commit("application/showSplitscreen", true, { root: true });
           })
           .catch(error => {
+            console.log(error);
             const { status, data } = error.response;
             displayError({
               title: "Backend Error",
@@ -191,6 +196,18 @@
             });
           });
       }
+    },
+    previousCuts({ commit, rootState }) {
+      const previousCuts =
+        JSON.parse(localStorage.getItem("previousCuts")) || [];
+      commit(
+        "previousCuts",
+        previousCuts.filter(cut => {
+          return (
+            cut.bottleneckName === rootState.bottlenecks.selectedBottleneck
+          );
+        })
+      );
     }
   }
 };