Mercurial > gemma
view client/src/components/Bottlenecks.vue @ 2068:5a898da60b87
dma added
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Wed, 30 Jan 2019 15:43:08 +0100 |
parents | f2d24dceecc7 |
children | 3138d60dd1a6 |
line wrap: on
line source
<template> <div> <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center"> <font-awesome-icon icon="ship" class="mr-2"></font-awesome-icon> <translate>Bottlenecks</translate> </h6> <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> </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> <div class="col-3"> <a href="#" @click="sortBy('chainage')" class="sort-link"> <translate>Chainage</translate> </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" > <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 icon="spinner" fixed-width spin v-if="loading === bottleneck.properties.name" ></font-awesome-icon> <font-awesome-icon icon="angle-down" fixed-width v-if=" loading !== bottleneck.properties.name && openBottleneck !== bottleneck.properties.name " ></font-awesome-icon> <font-awesome-icon 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-block px-3 py-2" v-for="(survey, index) in openBottleneckSurveys" :key="index" @click="selectSurvey(survey, bottleneck)" >{{ formatSurveyDate(survey.date_info) }}</a > </div> </div> </div> <div v-else class="small text-center py-3 border-top"> <translate>No results.</translate> </div> </div> </template> <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 by via donau * – Österreichische Wasserstraßen-Gesellschaft mbH * Software engineering by Intevation GmbH * * Author(s): * Markus Kottländer <markus.kottlaender@intevation.de> */ import { mapState } from "vuex"; import { HTTP } from "@/lib/http"; import { displayError } from "@/lib/errors.js"; import { formatSurveyDate } from "@/lib/date.js"; export default { name: "bottlenecks", data() { return { sortColumn: "name", sortDirection: "ASC", openBottleneck: null, openBottleneckSurveys: null, loading: null }; }, computed: { ...mapState("application", [ "searchQuery", "showSearchbarLastState", "showSplitscreen" ]), ...mapState("bottlenecks", ["bottlenecks"]), sortIcon() { return this.sortDirection === "ASC" ? "sort-amount-down" : "sort-amount-up"; } }, methods: { formatSurveyDate(date) { return formatSurveyDate(date); }, filteredAndSortedBottlenecks() { return this.bottlenecks .filter(bn => { return bn.properties.name .toLowerCase() .includes(this.searchQuery.toLowerCase()); }) .sort((bnA, bnB) => { switch (this.sortColumn) { case "name": if ( bnA.properties.name.toLowerCase() < bnB.properties.name.toLowerCase() ) return this.sortDirection === "ASC" ? -1 : 1; if ( bnA.properties.name.toLowerCase() > bnB.properties.name.toLowerCase() ) return this.sortDirection === "ASC" ? 1 : -1; return 0; case "latestMeasurement": { if ( (bnA.properties.current || "") < (bnB.properties.current || "") ) return this.sortDirection === "ASC" ? -1 : 1; if ( (bnA.properties.current || "") > (bnB.properties.current || "") ) return this.sortDirection === "ASC" ? 1 : -1; return 0; } case "chainage": if (bnA.properties.from < bnB.properties.from) return this.sortDirection === "ASC" ? -1 : 1; if (bnA.properties.from > bnB.properties.from) return this.sortDirection === "ASC" ? 1 : -1; return 0; default: return 0; } }); }, selectSurvey(survey, bottleneck) { this.$store .dispatch( "bottlenecks/setSelectedBottleneck", bottleneck.properties.name ) .then(() => { this.$store.commit("bottlenecks/selectedSurvey", survey); }) .then(() => { this.$store.commit("map/moveMap", { coordinates: bottleneck.geometry.coordinates, zoom: 17, preventZoomOut: true }); }); }, selectBottleneck(bottleneck) { this.$store .dispatch( "bottlenecks/setSelectedBottleneck", bottleneck.properties.name ) .then(() => { this.$store.commit("bottlenecks/setFirstSurveySelected"); }) .then(() => { this.$store.commit("map/moveMap", { coordinates: bottleneck.geometry.coordinates, zoom: 17, preventZoomOut: true }); }); }, sortBy(column) { this.sortColumn = column; this.sortDirection = this.sortDirection === "ASC" ? "DESC" : "ASC"; }, loadSurveys(name) { this.openBottleneckSurveys = null; if (name === this.openBottleneck) { this.openBottleneck = null; } else { this.openBottleneck = name; this.loading = name; HTTP.get("/surveys/" + name, { headers: { "X-Gemma-Auth": localStorage.getItem("token"), "Content-type": "text/xml; charset=UTF-8" } }) .then(response => { this.openBottleneckSurveys = response.data.surveys.sort((a, b) => { return a.date_info < b.date_info ? 1 : -1; }); }) .catch(error => { const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }) .finally(() => (this.loading = null)); } }, displayCurrentChainage(from, to) { return from / 10 + " - " + to / 10; } }, mounted() { this.$store.dispatch("bottlenecks/loadBottlenecks"); } }; </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>