Mercurial > gemma
view client/src/application/Search.vue @ 1207:70116d392387
close bottleneck list: made searchbar collapse only if it was collapsed before
opening the bottleneck list will expand the searchbar, closing the bottleneck list
was always collapsing the searchbar too. Now it stays open if it was open beforeopening the bottleneck list
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Mon, 19 Nov 2018 13:02:48 +0100 |
parents | 0900b341cef0 |
children | 9d93968db2cd |
line wrap: on
line source
<template> <div :class="searchbarContainerStyle"> <div class="input-group-prepend"> <span @click="toggleSearchbar" :class="searchButtonStyle" for="search"> <i class="fa fa-search d-print-none"></i> </span> </div> <div class="searchgroup flex-fill"> <input @keyup.enter="takeFirstSearchresult" v-if="showSearchbar" id="search" v-model="searchQuery" type="text" :class="searchInputStyle" > <ul v-if="showSearchbar && searchResults !== null && !showBottlenecks" class="list-group d-print-none"> <li v-for="entry of searchResults" :key="entry.name" class="list-group-item"> <a href="#" @click.prevent="moveToSearchResult(entry)">{{entry.name}}</a> </li> </ul> </div> </div> </template> <style lang="sass" scoped> .searchcontainer margin-left: $offset height: $icon-height .searchbar-expanded min-width: 600px .searchbar border-top-left-radius: 0 !important border-bottom-left-radius: 0 !important .searchbar-collapsed width: $icon-width !important transition: $transition-fast .searchbar height: $icon-height !important box-shadow: none !important &.rounded-top-right border-radius: 0 !important border-top-right-radius: 0.25rem !important .searchlabel background-color: white !important &.rounded-top-left border-radius: 0 !important border-top-left-radius: 0.25rem !important .input-group-text height: $icon-height width: $icon-width .list-group pointer-events: auto max-height: 40vh overflow: auto </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 by via donau * – Österreichische Wasserstraßen-Gesellschaft mbH * Software engineering by Intevation GmbH * * Author(s): * Markus Kottländer <markus.kottlaender@intevation.de> */ import debounce from "lodash.debounce"; import { mapState } from "vuex"; import { displayError } from "../application/lib/errors.js"; import { HTTP } from "../application/lib/http"; const setFocus = () => document.querySelector("#search").focus(); export default { name: "search", data() { return { searchQueryIsDirty: false, searchResults: null, isSearching: false }; }, computed: { ...mapState("application", [ "showSearchbar", "showBottlenecks", "showImportSoundingResults" ]), searchQuery: { get() { return this.$store.state.application.searchQuery; }, set(value) { this.$store.commit("application/searchQuery", value); } }, searchIndicator: function() { if (this.isSearching) { return "⟳"; } else if (this.searchQueryIsDirty) { return ""; } else { return "✓"; } }, searchbarContainerStyle() { return [ "input-group searchcontainer shadow", { "searchbar-collapsed": !this.showSearchbar, "searchbar-expanded": this.showSearchbar, "d-flex": !this.showImportSoundingResults, "d-none": this.showImportSoundingResults } ]; }, searchInputStyle() { return [ "form-control ui-element search searchbar d-print-none border-0", { "rounded-top-right": this.showSearchbar && this.showBottlenecks } ]; }, searchButtonStyle() { return [ "ui-element input-group-text p-0 d-flex border-0 justify-content-center searchlabel d-print-none", { rounded: !this.showSearchbar, "rounded-left": this.showSearchbar, "rounded-top-left": this.showSearchbar && this.showBottlenecks } ]; } }, watch: { searchQuery: function() { this.searchQueryIsDirty = true; this.triggerSearch(); } }, methods: { takeFirstSearchresult() { if (!this.searchResults || this.searchResults.length != 1) return; this.moveToSearchResult(this.searchResults[0]); }, triggerSearch: debounce(function() { this.doSearch(); }, 500), doSearch() { this.isCalculating = true; this.searchResults = null; if (this.searchQuery == "") { return; } HTTP.post( "/search", { string: this.searchQuery }, { headers: { "X-Gemma-Auth": localStorage.getItem("token"), "Content-type": "text/xml; charset=UTF-8" } } ) .then(response => { // console.log("got:", response.data); this.searchResults = response.data; }) .catch(error => { const { status, data } = error.response; displayError({ title: "Backend Error", message: `${status}: ${data.message || data}` }); }); this.isCalculating = false; this.searchQueryIsDirty = false; }, moveToSearchResult(resultEntry) { // DEBUG console.log("Moving to", resultEntry); if (resultEntry.geom.type == "Point") { let zoom = 11; if (resultEntry.type === "bottleneck") zoom = 17; if (resultEntry.type === "rhm") zoom = 15; if (resultEntry.type === "city") zoom = 13; this.$store.commit("map/moveMap", { coordinates: resultEntry.geom.coordinates, zoom, preventZoomOut: true }); } // this.searchQuery = ""; // clear search query again this.toggleSearchbar(); }, toggleSearchbar() { if (!this.showBottlenecks) { if (!this.showSearchbar) { setTimeout(setFocus, 300); } this.$store.commit("application/showSearchbar", !this.showSearchbar); } } } }; </script>