Mercurial > gemma
comparison client/src/components/map/contextbox/Bottlenecks.vue @ 1276:aec9ed491dad
more cleanup in client/src
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Thu, 22 Nov 2018 07:40:23 +0100 |
parents | |
children | a7dd8a3356fc |
comparison
equal
deleted
inserted
replaced
1275:9e23a2b02b32 | 1276:aec9ed491dad |
---|---|
1 <template> | |
2 <div> | |
3 <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center"> | |
4 <i class="fa fa-ship mr-2"></i> | |
5 Bottlenecks | |
6 </h6> | |
7 <div class="row p-2 text-left small"> | |
8 <div class="col-5"> | |
9 <a href="#" @click="sortBy('name')" class="sort-link">Name</a> | |
10 <i :class="sortClass" v-if="sortColumn === 'name'"></i> | |
11 </div> | |
12 <div class="col-2"> | |
13 <a | |
14 href="#" | |
15 @click="sortBy('latestMeasurement')" | |
16 class="sort-link" | |
17 >Latest Measurement</a> | |
18 <i :class="sortClass" v-if="sortColumn === 'latestMeasurement'"></i> | |
19 </div> | |
20 <div class="col-3"> | |
21 <a href="#" @click="sortBy('chainage')" class="sort-link">Chainage</a> | |
22 <i :class="sortClass" v-if="sortColumn === 'chainage'"></i> | |
23 </div> | |
24 <div class="col-2"></div> | |
25 </div> | |
26 <div class="bottleneck-list small text-left" v-if="filteredAndSortedBottlenecks().length"> | |
27 <div | |
28 v-for="bottleneck in filteredAndSortedBottlenecks()" | |
29 :key="bottleneck.properties.name" | |
30 class="border-top row mx-0 py-2" | |
31 > | |
32 <div class="col-5 text-left"> | |
33 <a | |
34 href="#" | |
35 class="d-block" | |
36 @click="moveToBottleneck(bottleneck)" | |
37 >{{ bottleneck.properties.name }}</a> | |
38 </div> | |
39 <div class="col-2">{{ displayCurrentSurvey(bottleneck.properties.current) }}</div> | |
40 <div | |
41 class="col-3" | |
42 >{{ displayCurrentChainage(bottleneck.properties.from, bottleneck.properties.from) }}</div> | |
43 <div class="col-2 text-right"> | |
44 <button | |
45 type="button" | |
46 class="btn btn-sm btn-outline-secondary" | |
47 @click="toggleBottleneck(bottleneck.properties.name)" | |
48 > | |
49 <i class="fa fa-angle-down"></i> | |
50 </button> | |
51 </div> | |
52 <div | |
53 :class="['col-12', 'surveys', {open: openBottleneck === bottleneck.properties.name}]" | |
54 > | |
55 <a | |
56 href="#" | |
57 class="d-block p-2" | |
58 v-for="(survey, index) in openBottleneckSurveys" | |
59 :key="index" | |
60 @click="selectSurvey(survey, bottleneck)" | |
61 >{{ survey.date_info }}</a> | |
62 </div> | |
63 </div> | |
64 </div> | |
65 <div v-else class="small text-center py-3 border-top"> | |
66 No results. | |
67 </div> | |
68 </div> | |
69 </template> | |
70 | |
71 <script> | |
72 /* | |
73 * This is Free Software under GNU Affero General Public License v >= 3.0 | |
74 * without warranty, see README.md and license for details. | |
75 * | |
76 * SPDX-License-Identifier: AGPL-3.0-or-later | |
77 * License-Filename: LICENSES/AGPL-3.0.txt | |
78 * | |
79 * Copyright (C) 2018 by via donau | |
80 * – Österreichische Wasserstraßen-Gesellschaft mbH | |
81 * Software engineering by Intevation GmbH | |
82 * | |
83 * Author(s): | |
84 * Markus Kottländer <markus.kottlaender@intevation.de> | |
85 */ | |
86 import { mapState } from "vuex"; | |
87 import { HTTP } from "../../../lib/http"; | |
88 import { displayError } from "../../../lib/errors.js"; | |
89 | |
90 export default { | |
91 name: "bottlenecks", | |
92 data() { | |
93 return { | |
94 sortColumn: "name", | |
95 sortDirection: "ASC", | |
96 openBottleneck: null, | |
97 openBottleneckSurveys: null | |
98 }; | |
99 }, | |
100 computed: { | |
101 ...mapState("application", ["searchQuery", "showSearchbarLastState"]), | |
102 ...mapState("bottlenecks", ["bottlenecks"]), | |
103 sortClass() { | |
104 return [ | |
105 "fa ml-1", | |
106 { | |
107 "fa-sort-amount-asc": this.sortDirection === "ASC", | |
108 "fa-sort-amount-desc": this.sortDirection === "DESC" | |
109 } | |
110 ]; | |
111 } | |
112 }, | |
113 methods: { | |
114 filteredAndSortedBottlenecks() { | |
115 return this.bottlenecks | |
116 .filter(bn => { | |
117 return bn.properties.name | |
118 .toLowerCase() | |
119 .includes(this.searchQuery.toLowerCase()); | |
120 }) | |
121 .sort((bnA, bnB) => { | |
122 switch (this.sortColumn) { | |
123 case "name": | |
124 if ( | |
125 bnA.properties.name.toLowerCase() < | |
126 bnB.properties.name.toLowerCase() | |
127 ) | |
128 return this.sortDirection === "ASC" ? -1 : 1; | |
129 if ( | |
130 bnA.properties.name.toLowerCase() > | |
131 bnB.properties.name.toLowerCase() | |
132 ) | |
133 return this.sortDirection === "ASC" ? 1 : -1; | |
134 return 0; | |
135 | |
136 case "latestMeasurement": { | |
137 if ( | |
138 (bnA.properties.current || "") < (bnB.properties.current || "") | |
139 ) | |
140 return this.sortDirection === "ASC" ? -1 : 1; | |
141 if ( | |
142 (bnA.properties.current || "") > (bnB.properties.current || "") | |
143 ) | |
144 return this.sortDirection === "ASC" ? 1 : -1; | |
145 return 0; | |
146 } | |
147 | |
148 case "chainage": | |
149 if (bnA.properties.from < bnB.properties.from) | |
150 return this.sortDirection === "ASC" ? -1 : 1; | |
151 if (bnA.properties.from > bnB.properties.from) | |
152 return this.sortDirection === "ASC" ? 1 : -1; | |
153 return 0; | |
154 | |
155 default: | |
156 return 0; | |
157 } | |
158 }); | |
159 }, | |
160 selectSurvey(survey, bottleneck) { | |
161 this.$store.dispatch( | |
162 "bottlenecks/setSelectedBottleneck", | |
163 bottleneck.properties.name | |
164 ); | |
165 this.$store.commit("bottlenecks/setSelectedSurvey", survey); | |
166 this.moveToBottleneck(bottleneck); | |
167 }, | |
168 moveToBottleneck(bottleneck) { | |
169 this.$store.commit("map/moveMap", { | |
170 coordinates: bottleneck.geometry.coordinates, | |
171 zoom: 17, | |
172 preventZoomOut: true | |
173 }); | |
174 }, | |
175 sortBy(column) { | |
176 this.sortColumn = column; | |
177 this.sortDirection = this.sortDirection === "ASC" ? "DESC" : "ASC"; | |
178 }, | |
179 toggleBottleneck(name) { | |
180 this.openBottleneckSurveys = null; | |
181 if (name === this.openBottleneck) { | |
182 this.openBottleneck = null; | |
183 } else { | |
184 this.openBottleneck = name; | |
185 | |
186 HTTP.get("/surveys/" + name, { | |
187 headers: { | |
188 "X-Gemma-Auth": localStorage.getItem("token"), | |
189 "Content-type": "text/xml; charset=UTF-8" | |
190 } | |
191 }) | |
192 .then(response => { | |
193 this.openBottleneckSurveys = response.data.surveys; | |
194 }) | |
195 .catch(error => { | |
196 const { status, data } = error.response; | |
197 displayError({ | |
198 title: "Backend Error", | |
199 message: `${status}: ${data.message || data}` | |
200 }); | |
201 }); | |
202 } | |
203 }, | |
204 displayCurrentSurvey(current) { | |
205 return current ? current.substr(0, current.length - 1) : ""; | |
206 }, | |
207 displayCurrentChainage(from, to) { | |
208 return from / 10 + " - " + to / 10; | |
209 } | |
210 }, | |
211 mounted() { | |
212 this.$store.dispatch("bottlenecks/loadBottlenecks"); | |
213 } | |
214 }; | |
215 </script> | |
216 | |
217 <style lang="sass" scoped> | |
218 .bottleneck-list | |
219 overflow-y: auto | |
220 max-height: 500px | |
221 | |
222 .surveys | |
223 max-height: 0 | |
224 overflow: hidden | |
225 transition: max-height 0.3s ease | |
226 | |
227 .surveys.open | |
228 max-height: 999px | |
229 | |
230 .sort-link | |
231 color: #444 | |
232 font-weight: bold | |
233 </style> |