diff client/src/components/Bottlenecks.vue @ 2462:9ae2a2f758bb

client: make use of new table header/body components
author Markus Kottlaender <markus@intevation.de>
date Mon, 04 Mar 2019 14:50:23 +0100
parents 64ff5984351e
children 468c8dc796cf
line wrap: on
line diff
--- a/client/src/components/Bottlenecks.vue	Mon Mar 04 13:53:09 2019 +0100
+++ b/client/src/components/Bottlenecks.vue	Mon Mar 04 14:50:23 2019 +0100
@@ -5,123 +5,109 @@
       title="Bottlenecks"
       :closeCallback="$parent.close"
     />
-    <div class="row p-2 text-left small">
-      <div class="col-5">
-        <a href="#" @click="sortBy('name')" class="sort-link">
-          <translate>Name</translate>
-        </a>
-        <font-awesome-icon
-          :icon="sortIcon"
-          class="ml-1"
-          v-if="sortColumn === 'name'"
-        ></font-awesome-icon>
+    <UITableHeader
+      :columns="[
+        { id: 'name', title: 'Name', class: 'col-4' },
+        {
+          id: 'latestMeasurement',
+          title: 'Latest Measurement',
+          class: 'col-3'
+        },
+        { id: 'chainage', title: 'Chainage', class: 'col-3' }
+      ]"
+      @sortingChanged="sortBy"
+    />
+    <UITableBody
+      :data="filteredAndSortedBottlenecks()"
+      :maxHeight="(showSplitscreen ? 18 : 35) + 'rem'"
+      :active="openBottleneck"
+      v-slot="{ item: bottleneck }"
+    >
+      <div class="col-4 py-2 text-left">
+        <a href="#" @click="selectBottleneck(bottleneck)">{{
+          bottleneck.properties.name
+        }}</a>
       </div>
-      <div class="col-2">
-        <a href="#" @click="sortBy('latestMeasurement')" class="sort-link">
-          <translate>Latest</translate> <br />
-          <translate>Measurement</translate>
-        </a>
-        <font-awesome-icon
-          :icon="sortIcon"
-          class="ml-1"
-          v-if="sortColumn === 'latestMeasurement'"
-        ></font-awesome-icon>
+      <div class="col-3 py-2">
+        {{ formatSurveyDate(bottleneck.properties.current) }}
+      </div>
+      <div class="col-3 py-2">
+        {{
+          displayCurrentChainage(
+            bottleneck.properties.from,
+            bottleneck.properties.to
+          )
+        }}
       </div>
-      <div class="col-3">
-        <a href="#" @click="sortBy('chainage')" class="sort-link">
-          <translate>Chainage</translate>
+      <div class="col-2 pr-0 text-right d-flex flex-column">
+        <a
+          class="text-info mt-auto mb-auto mr-2"
+          @click="loadSurveys(bottleneck)"
+          v-if="bottleneck.properties.current"
+        >
+          <font-awesome-icon
+            class="pointer"
+            icon="spinner"
+            fixed-width
+            spin
+            v-if="loading === bottleneck"
+          ></font-awesome-icon>
+          <font-awesome-icon
+            class="pointer"
+            icon="angle-down"
+            fixed-width
+            v-if="loading !== bottleneck && openBottleneck !== bottleneck"
+          ></font-awesome-icon>
+          <font-awesome-icon
+            class="pointer"
+            icon="angle-up"
+            fixed-width
+            v-if="loading !== bottleneck && openBottleneck === bottleneck"
+          ></font-awesome-icon>
         </a>
-        <font-awesome-icon
-          :icon="sortIcon"
-          class="ml-1"
-          v-if="sortColumn === 'chainage'"
-        ></font-awesome-icon>
       </div>
-      <div class="col-2"></div>
-    </div>
-    <div
-      class="bottleneck-list small text-left"
-      :style="'max-height: ' + (showSplitscreen ? 18 : 35) + 'rem'"
-      v-if="filteredAndSortedBottlenecks().length"
-    >
       <div
-        v-for="bottleneck in filteredAndSortedBottlenecks()"
-        :key="bottleneck.properties.name"
-        class="border-top row bottleneck-row mx-0"
+        :class="[
+          'col-12 p-0',
+          'surveys',
+          { open: openBottleneck === bottleneck }
+        ]"
       >
-        <div class="col-5 py-2 text-left">
-          <a href="#" @click="selectBottleneck(bottleneck)">{{
-            bottleneck.properties.name
-          }}</a>
-        </div>
-        <div class="col-2 py-2">
-          {{ formatSurveyDate(bottleneck.properties.current) }}
-        </div>
-        <div class="col-3 py-2">
-          {{
-            displayCurrentChainage(
-              bottleneck.properties.from,
-              bottleneck.properties.to
-            )
-          }}
-        </div>
-        <div class="col-2 pr-0 text-right d-flex flex-column">
-          <a
-            class="text-info mt-auto mb-auto mr-2"
-            @click="loadSurveys(bottleneck.properties.name)"
-            v-if="bottleneck.properties.current"
-          >
-            <font-awesome-icon
-              class="pointer"
-              icon="spinner"
-              fixed-width
-              spin
-              v-if="loading === bottleneck.properties.name"
-            ></font-awesome-icon>
-            <font-awesome-icon
-              class="pointer"
-              icon="angle-down"
-              fixed-width
-              v-if="
-                loading !== bottleneck.properties.name &&
-                  openBottleneck !== bottleneck.properties.name
-              "
-            ></font-awesome-icon>
-            <font-awesome-icon
-              class="pointer"
-              icon="angle-up"
-              fixed-width
-              v-if="
-                loading !== bottleneck.properties.name &&
-                  openBottleneck === bottleneck.properties.name
-              "
-            ></font-awesome-icon>
-          </a>
-        </div>
-        <div
-          :class="[
-            'col-12 p-0',
-            'surveys',
-            { open: openBottleneck === bottleneck.properties.name }
-          ]"
+        <a
+          href="#"
+          class="d-inline-block px-3 py-2"
+          v-for="(survey, index) in openBottleneckSurveys"
+          :key="index"
+          @click="selectSurvey(survey, bottleneck)"
         >
-          <a
-            href="#"
-            class="d-block px-3 py-2"
-            v-for="(survey, index) in openBottleneckSurveys"
-            :key="index"
-            @click="selectSurvey(survey, bottleneck)"
-            >{{ formatSurveyDate(survey.date_info) }}</a
-          >
-        </div>
+          {{ formatSurveyDate(survey.date_info) }}
+        </a>
       </div>
-    </div>
-    <div v-else class="small text-center py-3 border-top">
-      <translate>No results.</translate>
-    </div>
+    </UITableBody>
   </div>
 </template>
 
+<style lang="sass" scoped>
+.table-body
+  .row
+    > div:not(:last-child)
+      transition: background-color 0.3s, color 0.3s
+    &.active
+      > div:not(:last-child)
+        background-color: $color-info
+        color: #fff
+        a
+          color: #fff !important
+      .surveys
+        border-bottom: solid 1px $color-info
+    .surveys
+      overflow: hidden
+      max-height: 0
+      &.open
+        overflow-y: auto
+        max-height: 5rem
+</style>
+
 <script>
 /* This is Free Software under GNU Affero General Public License v >= 3.0
  * without warranty, see README.md and license for details.
@@ -249,19 +235,18 @@
           });
         });
     },
-    sortBy(column) {
-      this.sortColumn = column;
-      this.sortDirection = this.sortDirection === "ASC" ? "DESC" : "ASC";
+    sortBy(sorting) {
+      this.sortColumn = sorting.sortColumn;
+      this.sortDirection = sorting.sortDirection;
     },
-    loadSurveys(name) {
-      this.openBottleneckSurveys = null;
-      if (name === this.openBottleneck) {
+    loadSurveys(bottleneck) {
+      if (bottleneck === this.openBottleneck) {
         this.openBottleneck = null;
+        this.openBottleneckSurveys = null;
       } else {
-        this.openBottleneck = name;
-        this.loading = name;
+        this.loading = bottleneck;
 
-        HTTP.get("/surveys/" + name, {
+        HTTP.get("/surveys/" + bottleneck.properties.name, {
           headers: {
             "X-Gemma-Auth": localStorage.getItem("token"),
             "Content-type": "text/xml; charset=UTF-8"
@@ -271,6 +256,7 @@
             this.openBottleneckSurveys = response.data.surveys.sort((a, b) => {
               return a.date_info < b.date_info ? 1 : -1;
             });
+            this.openBottleneck = bottleneck;
           })
           .catch(error => {
             const { status, data } = error.response;
@@ -291,37 +277,3 @@
   }
 };
 </script>
-
-<style lang="scss" scoped>
-.bottleneck-list {
-  overflow-y: auto;
-}
-
-.bottleneck-list .bottleneck-row a {
-  text-decoration: none;
-}
-
-.bottleneck-list .bottleneck-row:hover {
-  background: #fbfbfb;
-}
-
-.surveys {
-  max-height: 0;
-  min-height: 0;
-  overflow: hidden;
-}
-
-.surveys a:hover {
-  background: #f3f3f3;
-}
-
-.surveys.open {
-  max-height: 250px;
-  overflow: auto;
-}
-
-.sort-link {
-  color: #444;
-  font-weight: bold;
-}
-</style>