changeset 3041:ccda334eed92

client: panes: improved panes rotation, works with pure css so that components don't need to be re-mounted
author Markus Kottlaender <markus@intevation.de>
date Sat, 13 Apr 2019 14:51:56 +0200
parents a661e9b8f3b6
children 762b140e91a0
files client/src/assets/application.scss client/src/components/Main.vue client/src/components/toolbar/PaneControl.vue client/src/store/application.js
diffstat 4 files changed, 64 insertions(+), 130 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/assets/application.scss	Fri Apr 12 17:27:21 2019 +0200
+++ b/client/src/assets/application.scss	Sat Apr 13 14:51:56 2019 +0200
@@ -217,3 +217,8 @@
   width: 100% !important;
   height: 100% !important;
 }
+
+.wh-50 {
+  width: 50% !important;
+  height: 50% !important;
+}
--- a/client/src/components/Main.vue	Fri Apr 12 17:27:21 2019 +0200
+++ b/client/src/components/Main.vue	Sat Apr 13 14:51:56 2019 +0200
@@ -1,94 +1,32 @@
 <template>
-  <div
-    id="panes"
-    :class="[
-      'd-flex flex-wrap position-absolute',
-      { 'flex-column': ['left', 'right'].includes(paneMode) }
-    ]"
-  >
-    <template v-if="panes.length === 1">
-      <div id="pane1" class="pane d-flex wh-100">
-        <component :is="panes[0]" />
-      </div>
-    </template>
+  <div id="panes" :class="'d-flex position-absolute rotate' + paneRotate">
+    <div id="pane1" :class="'pane d-flex ' + pane1Class">
+      <component :is="panes[0]" />
+    </div>
 
     <template v-if="panes.length === 2">
-      <template v-if="paneMode === 'horizontal'">
-        <div id="pane1" class="pane d-flex w-100 h-50">
-          <component :is="panes[0]" />
-        </div>
-        <div id="pane2" class="pane d-flex w-100 h-50">
-          <component :is="panes[1]" />
-        </div>
-      </template>
-      <template v-if="paneMode === 'vertical'">
-        <div id="pane1" class="pane d-flex w-50 h-100">
-          <component :is="panes[0]" />
-        </div>
-        <div id="pane2" class="pane d-flex w-50 h-100">
-          <component :is="panes[1]" />
-        </div>
-      </template>
+      <div id="pane2" :class="'pane d-flex ' + pane2Class">
+        <component :is="panes[1]" />
+      </div>
     </template>
 
     <template v-if="panes.length === 3">
-      <template v-if="paneMode === 'top'">
-        <div id="pane1" class="pane d-flex w-100 h-50">
-          <component :is="panes[0]" />
-        </div>
-        <div id="pane3" class="pane d-flex w-50 h-50">
-          <component :is="panes[2]" />
-        </div>
-        <div id="pane2" class="pane d-flex w-50 h-50">
-          <component :is="panes[1]" />
-        </div>
-      </template>
-      <template v-if="paneMode === 'right'">
-        <div id="pane3" class="pane d-flex w-50 h-50">
-          <component :is="panes[2]" />
-        </div>
-        <div id="pane2" class="pane d-flex w-50 h-50">
-          <component :is="panes[1]" />
-        </div>
-        <div id="pane1" class="pane d-flex w-50 h-100">
-          <component :is="panes[0]" />
-        </div>
-      </template>
-      <template v-if="paneMode === 'bottom'">
-        <div id="pane2" class="pane d-flex w-50 h-50">
-          <component :is="panes[1]" />
-        </div>
-        <div id="pane3" class="pane d-flex w-50 h-50">
-          <component :is="panes[2]" />
-        </div>
-        <div id="pane1" class="pane d-flex w-100 h-50">
-          <component :is="panes[0]" />
-        </div>
-      </template>
-      <template v-if="paneMode === 'left'">
-        <div id="pane1" class="pane d-flex w-50 h-100">
-          <component :is="panes[0]" />
-        </div>
-        <div id="pane2" class="pane d-flex w-50 h-50">
-          <component :is="panes[1]" />
-        </div>
-        <div id="pane3" class="pane d-flex w-50 h-50">
-          <component :is="panes[2]" />
-        </div>
-      </template>
+      <div id="pane3" class="pane d-flex wh-50">
+        <component :is="panes[2]" />
+      </div>
+      <div id="pane2" class="pane d-flex wh-50">
+        <component :is="panes[1]" />
+      </div>
     </template>
 
     <template v-if="panes.length === 4">
-      <div id="pane1" class="pane d-flex w-50 h-50">
-        <component :is="panes[0]" />
-      </div>
-      <div id="pane2" class="pane d-flex w-50 h-50">
+      <div id="pane2" class="pane d-flex wh-50">
         <component :is="panes[1]" />
       </div>
-      <div id="pane4" class="pane d-flex w-50 h-50">
+      <div id="pane4" class="pane d-flex wh-50">
         <component :is="panes[3]" />
       </div>
-      <div id="pane3" class="pane d-flex w-50 h-50">
+      <div id="pane3" class="pane d-flex wh-50">
         <component :is="panes[2]" />
       </div>
     </template>
@@ -102,6 +40,18 @@
   bottom: -0.5px
   left: -0.5px
   z-index: 1
+  &.rotate1
+    flex-wrap: wrap
+    flex-direction: row
+  &.rotate2
+    flex-wrap: wrap-reverse
+    flex-direction: column
+  &.rotate3
+    flex-wrap: wrap-reverse
+    flex-direction: row-reverse
+  &.rotate4
+    flex-wrap: wrap
+    flex-direction: column-reverse
   .pane
     border: solid 0.5px #fff
     background: #fff
@@ -135,7 +85,27 @@
     HydrologicalConditions: () => import("./gauge/HydrologicalConditions")
   },
   computed: {
-    ...mapState("application", ["panes", "paneMode"])
+    ...mapState("application", ["panes", "paneRotate"]),
+    // pane 1 and 2 are the only ones that can have varying size
+    // thats why tehre is no pane3class or pane4class
+    pane1Class() {
+      if (this.panes.length === 1) return "wh-100";
+      if (this.panes.length === 2 || this.panes.length === 3) {
+        if (this.paneRotate === 1 || this.paneRotate === 3) return "w-100 h-50";
+        if (this.paneRotate === 2 || this.paneRotate === 4) return "w-50 h-100";
+      }
+      if (this.panes.length === 4) {
+        return "wh-50";
+      }
+    },
+    pane2Class() {
+      if (this.panes.length === 2) {
+        if (this.paneRotate === 1 || this.paneRotate === 3) return "w-100 h-50";
+        if (this.paneRotate === 2 || this.paneRotate === 4) return "w-50 h-100";
+      } else {
+        return "wh-50";
+      }
+    }
   }
 };
 </script>
--- a/client/src/components/toolbar/PaneControl.vue	Fri Apr 12 17:27:21 2019 +0200
+++ b/client/src/components/toolbar/PaneControl.vue	Sat Apr 13 14:51:56 2019 +0200
@@ -1,6 +1,6 @@
 <template>
   <div
-    @click="togglePaneMode"
+    @click="rotate"
     :class="['toolbar-button', { disabled: panes.length < 2 }]"
     v-tooltip.right="label"
   >
@@ -25,59 +25,18 @@
 import { mapState } from "vuex";
 
 export default {
-  data() {
-    return {
-      // This is needed to accomplish a true rotation of components/panes with
-      // two panes. On every second "rotation" the components are fliped. This way
-      // toggling between horizontal and vertical mode feels like the components
-      // are actually rotating. See: togglePaneMode()
-      rotations: 0
-    };
-  },
   computed: {
-    ...mapState("application", ["panes", "paneMode"]),
+    ...mapState("application", ["panes", "paneRotate"]),
     label() {
       return this.$gettext("Rotate Panes");
     }
   },
-  watch: {
-    panes(panes) {
-      if (panes.length !== 2) this.rotations = 0;
-    }
-  },
   methods: {
-    rotateComponents() {
-      this.panes.unshift(this.panes.pop());
-    },
-    togglePaneMode() {
-      if (this.panes.length === 2) {
-        this.$store.commit(
-          "application/paneMode",
-          this.paneMode === "horizontal" ? "vertical" : "horizontal"
-        );
-        if (++this.rotations % 2) {
-          this.rotateComponents();
-        }
-      }
-      if (this.panes.length === 3) {
-        let next;
-        if (this.paneMode === "top") {
-          next = "right";
-        }
-        if (this.paneMode === "right") {
-          next = "bottom";
-        }
-        if (this.paneMode === "bottom") {
-          next = "left";
-        }
-        if (this.paneMode === "left") {
-          next = "top";
-        }
-        this.$store.commit("application/paneMode", next);
-      }
-      if (this.panes.length === 4) {
-        this.rotateComponents();
-      }
+    rotate() {
+      this.$store.commit(
+        "application/paneRotate",
+        this.paneRotate === 4 ? 1 : this.paneRotate + 1
+      );
     }
   }
 };
--- a/client/src/store/application.js	Fri Apr 12 17:27:21 2019 +0200
+++ b/client/src/store/application.js	Sat Apr 13 14:51:56 2019 +0200
@@ -25,7 +25,7 @@
     logoForPDF: process.env.VUE_APP_LOGO_FOR_PDF_URL,
     popup: null,
     panes: ["Map"],
-    paneMode: null,
+    paneRotate: 1,
     splitscreens: [],
     splitscreenLoading: false,
     activeSplitscreenId: null,
@@ -86,8 +86,8 @@
     panes: (state, panes) => {
       state.panes = panes;
     },
-    paneMode: (state, mode) => {
-      state.paneMode = mode;
+    paneRotate: (state, rotate) => {
+      state.paneRotate = rotate;
     },
     showSidebar: (state, show) => {
       state.showSidebar = show;