1196
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
1 <template>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
2 <div :class="searchbarContainerStyle">
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
3 <div class="input-group-prepend shadow">
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
4 <span @click="toggleSearchbar" :class="searchButtonStyle" for="search">
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
5 <i class="fa fa-search d-print-none"></i>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
6 </span>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
7 </div>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
8 <div class="searchgroup flex-fill">
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
9 <input
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
10 @keyup.enter="takeFirstSearchresult"
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
11 v-if="showSearchbar"
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
12 id="search"
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
13 v-model="searchQuery"
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
14 type="text"
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
15 class="form-control ui-element search searchbar d-print-none"
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
16 >
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
17 <ul v-if="showSearchbar && searchResults !== null " class="list-group d-print-none">
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
18 <li v-for="entry of searchResults" :key="entry.name" class="list-group-item">
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
19 <a href="#" @click.prevent="moveToSearchResult(entry)">{{entry.name}}</a>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
20 </li>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
21 </ul>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
22 </div>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
23 </div>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
24 </template>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
25
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
26 <style lang="sass" scoped>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
27 .searchcontainer
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
28 height: $icon-height
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
29 border-radius: 0.25rem
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
30
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
31 .searchbar-expanded
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
32 width: $searchbar-width !important
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
33 .searchbar
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
34 border-top-left-radius: 0 !important
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
35 border-bottom-left-radius: 0 !important
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
36
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
37
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
38 .searchbar-collapsed
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
39 width: $icon-width !important
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
40 transition: $transition-fast
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
41
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
42 .searchbar
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
43 height: $icon-height !important
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
44
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
45 .searchlabel
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
46 background-color: white !important
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
47
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
48 .input-group-text
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
49 height: $icon-height
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
50 width: $icon-width
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
51
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
52 .list-group
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
53 pointer-events: auto
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
54 </style>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
55
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
56 <script>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
57 /*
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
58 * This is Free Software under GNU Affero General Public License v >= 3.0
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
59 * without warranty, see README.md and license for details.
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
60 *
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
61 * SPDX-License-Identifier: AGPL-3.0-or-later
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
62 * License-Filename: LICENSES/AGPL-3.0.txt
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
63 *
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
64 * Copyright (C) 2018 by via donau
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
65 * – Österreichische Wasserstraßen-Gesellschaft mbH
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
66 * Software engineering by Intevation GmbH
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
67 *
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
68 * Author(s):
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
69 * Markus Kottländer <markus.kottlaender@intevation.de>
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
70 */
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
71 import debounce from "lodash.debounce";
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
72 import { mapState } from "vuex";
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
73
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
74 import { displayError } from "../application/lib/errors.js";
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
75 import { HTTP } from "../application/lib/http";
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
76
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
77 const setFocus = () => document.querySelector("#search").focus();
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
78
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
79 export default {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
80 name: "search",
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
81 data() {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
82 return {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
83 searchQuery: "",
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
84 searchQueryIsDirty: false,
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
85 searchResults: null,
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
86 isSearching: false
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
87 };
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
88 },
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
89 computed: {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
90 ...mapState("application", ["showSearchbar"]),
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
91 searchIndicator: function() {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
92 if (this.isSearching) {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
93 return "⟳";
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
94 } else if (this.searchQueryIsDirty) {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
95 return "";
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
96 } else {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
97 return "✓";
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
98 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
99 },
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
100 searchbarContainerStyle() {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
101 return [
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
102 "d-flex input-group searchcontainer",
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
103 {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
104 "searchbar-collapsed": !this.showSearchbar,
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
105 "searchbar-expanded": this.showSearchbar
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
106 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
107 ];
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
108 },
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
109 searchButtonStyle() {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
110 return [
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
111 "ui-element input-group-text p-0 d-flex justify-content-center searchlabel d-print-none",
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
112 {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
113 rounded: !this.showSearchbar,
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
114 "rounded-left": this.showSearchbar
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
115 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
116 ];
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
117 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
118 },
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
119 watch: {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
120 searchQuery: function() {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
121 this.searchQueryIsDirty = true;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
122 this.triggerSearch();
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
123 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
124 },
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
125 methods: {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
126 takeFirstSearchresult() {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
127 if (!this.searchResults || this.searchResults.length != 1) return;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
128 this.moveToSearchResult(this.searchResults[0]);
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
129 },
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
130 triggerSearch: debounce(function() {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
131 this.doSearch();
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
132 }, 500),
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
133 doSearch() {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
134 this.isCalculating = true;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
135 this.searchResults = null;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
136
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
137 if (this.searchQuery == "") {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
138 return;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
139 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
140
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
141 HTTP.post(
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
142 "/search",
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
143 { string: this.searchQuery },
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
144 {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
145 headers: {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
146 "X-Gemma-Auth": localStorage.getItem("token"),
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
147 "Content-type": "text/xml; charset=UTF-8"
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
148 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
149 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
150 )
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
151 .then(response => {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
152 // console.log("got:", response.data);
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
153 this.searchResults = response.data;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
154 })
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
155 .catch(error => {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
156 const { status, data } = error.response;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
157 displayError({
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
158 title: "Backend Error",
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
159 message: `${status}: ${data.message || data}`
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
160 });
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
161 });
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
162
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
163 this.isCalculating = false;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
164 this.searchQueryIsDirty = false;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
165 },
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
166 moveToSearchResult(resultEntry) {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
167 // DEBUG console.log("Moving to", resultEntry);
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
168 if (resultEntry.geom.type == "Point") {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
169 let zoom = 11;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
170 if (resultEntry.type === "bottleneck") zoom = 17;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
171 if (resultEntry.type === "rhm") zoom = 15;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
172 if (resultEntry.type === "city") zoom = 13;
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
173
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
174 this.$store.commit("map/moveMap", {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
175 coordinates: resultEntry.geom.coordinates,
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
176 zoom,
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
177 preventZoomOut: true
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
178 });
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
179 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
180 // this.searchQuery = ""; // clear search query again
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
181 this.toggleSearchbar();
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
182 },
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
183 toggleSearchbar() {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
184 if (!this.showSearchbar) {
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
185 setTimeout(setFocus, 300);
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
186 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
187 this.$store.commit("application/showSearchbar", !this.showSearchbar);
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
188 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
189 }
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
190 };
|
Markus Kottlaender <markus@intevation.de>
parents:
diff
changeset
|
191 </script>
|