Mercurial > gemma
comparison client/src/components/Bottlenecks.vue @ 1558:0ded4c56978e
refac: component filestructure. remove admin/map hierarchy
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Wed, 12 Dec 2018 09:22:20 +0100 |
parents | client/src/components/map/contextbox/Bottlenecks.vue@276df8dadc14 |
children | 70421380142d |
comparison
equal
deleted
inserted
replaced
1557:62171cd9a42b | 1558:0ded4c56978e |
---|---|
1 <template> | |
2 <div> | |
3 <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center"> | |
4 <font-awesome-icon icon="ship" class="mr-2"></font-awesome-icon> | |
5 <translate>Bottlenecks</translate> | |
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"> | |
10 <translate>Name</translate> | |
11 </a> | |
12 <font-awesome-icon | |
13 :icon="sortIcon" | |
14 class="ml-1" | |
15 v-if="sortColumn === 'name'" | |
16 ></font-awesome-icon> | |
17 </div> | |
18 <div class="col-2"> | |
19 <a href="#" @click="sortBy('latestMeasurement')" class="sort-link"> | |
20 <translate>Latest</translate> <br /> | |
21 <translate>Measurement</translate> | |
22 </a> | |
23 <font-awesome-icon | |
24 :icon="sortIcon" | |
25 class="ml-1" | |
26 v-if="sortColumn === 'latestMeasurement'" | |
27 ></font-awesome-icon> | |
28 </div> | |
29 <div class="col-3"> | |
30 <a href="#" @click="sortBy('chainage')" class="sort-link"> | |
31 <translate>Chainage</translate> | |
32 </a> | |
33 <font-awesome-icon | |
34 :icon="sortIcon" | |
35 class="ml-1" | |
36 v-if="sortColumn === 'chainage'" | |
37 ></font-awesome-icon> | |
38 </div> | |
39 <div class="col-2"></div> | |
40 </div> | |
41 <div | |
42 class="bottleneck-list small text-left" | |
43 :style="'max-height: ' + (showSplitscreen ? 18 : 35) + 'rem'" | |
44 v-if="filteredAndSortedBottlenecks().length" | |
45 > | |
46 <div | |
47 v-for="bottleneck in filteredAndSortedBottlenecks()" | |
48 :key="bottleneck.properties.name" | |
49 class="border-top row bottleneck-row mx-0" | |
50 > | |
51 <div class="col-5 py-2 text-left"> | |
52 <a href="#" @click="selectBottleneck(bottleneck)">{{ | |
53 bottleneck.properties.name | |
54 }}</a> | |
55 </div> | |
56 <div class="col-2 py-2"> | |
57 {{ formatSurveyDate(bottleneck.properties.current) }} | |
58 </div> | |
59 <div class="col-3 py-2"> | |
60 {{ | |
61 displayCurrentChainage( | |
62 bottleneck.properties.from, | |
63 bottleneck.properties.to | |
64 ) | |
65 }} | |
66 </div> | |
67 <div class="col-2 pr-0 text-right"> | |
68 <button | |
69 type="button" | |
70 class="btn btn-sm btn-info rounded-0 h-100" | |
71 @click="loadSurveys(bottleneck.properties.name)" | |
72 v-if="bottleneck.properties.current" | |
73 > | |
74 <font-awesome-icon | |
75 icon="spinner" | |
76 fixed-width | |
77 spin | |
78 v-if="loading === bottleneck.properties.name" | |
79 ></font-awesome-icon> | |
80 <font-awesome-icon | |
81 icon="angle-down" | |
82 fixed-width | |
83 v-if=" | |
84 loading !== bottleneck.properties.name && | |
85 openBottleneck !== bottleneck.properties.name | |
86 " | |
87 ></font-awesome-icon> | |
88 <font-awesome-icon | |
89 icon="angle-up" | |
90 fixed-width | |
91 v-if=" | |
92 loading !== bottleneck.properties.name && | |
93 openBottleneck === bottleneck.properties.name | |
94 " | |
95 ></font-awesome-icon> | |
96 </button> | |
97 </div> | |
98 <div | |
99 :class="[ | |
100 'col-12 p-0', | |
101 'surveys', | |
102 { open: openBottleneck === bottleneck.properties.name } | |
103 ]" | |
104 > | |
105 <a | |
106 href="#" | |
107 class="d-block px-3 py-2" | |
108 v-for="(survey, index) in openBottleneckSurveys" | |
109 :key="index" | |
110 @click="selectSurvey(survey, bottleneck)" | |
111 >{{ formatSurveyDate(survey.date_info) }}</a | |
112 > | |
113 </div> | |
114 </div> | |
115 </div> | |
116 <div v-else class="small text-center py-3 border-top"> | |
117 <translate>No results.</translate> | |
118 </div> | |
119 </div> | |
120 </template> | |
121 | |
122 <script> | |
123 /* This is Free Software under GNU Affero General Public License v >= 3.0 | |
124 * without warranty, see README.md and license for details. | |
125 * | |
126 * SPDX-License-Identifier: AGPL-3.0-or-later | |
127 * License-Filename: LICENSES/AGPL-3.0.txt | |
128 * | |
129 * Copyright (C) 2018 by via donau | |
130 * – Österreichische Wasserstraßen-Gesellschaft mbH | |
131 * Software engineering by Intevation GmbH | |
132 * | |
133 * Author(s): | |
134 * Markus Kottländer <markus.kottlaender@intevation.de> | |
135 */ | |
136 import { mapState } from "vuex"; | |
137 import { HTTP } from "../lib/http"; | |
138 import { displayError } from "../lib/errors.js"; | |
139 import { formatSurveyDate } from "../lib/date.js"; | |
140 | |
141 export default { | |
142 name: "bottlenecks", | |
143 data() { | |
144 return { | |
145 sortColumn: "name", | |
146 sortDirection: "ASC", | |
147 openBottleneck: null, | |
148 openBottleneckSurveys: null, | |
149 loading: null | |
150 }; | |
151 }, | |
152 computed: { | |
153 ...mapState("application", [ | |
154 "searchQuery", | |
155 "showSearchbarLastState", | |
156 "showSplitscreen" | |
157 ]), | |
158 ...mapState("bottlenecks", ["bottlenecks"]), | |
159 sortIcon() { | |
160 return this.sortDirection === "ASC" | |
161 ? "sort-amount-down" | |
162 : "sort-amount-up"; | |
163 } | |
164 }, | |
165 methods: { | |
166 formatSurveyDate(date) { | |
167 return formatSurveyDate(date); | |
168 }, | |
169 filteredAndSortedBottlenecks() { | |
170 return this.bottlenecks | |
171 .filter(bn => { | |
172 return bn.properties.name | |
173 .toLowerCase() | |
174 .includes(this.searchQuery.toLowerCase()); | |
175 }) | |
176 .sort((bnA, bnB) => { | |
177 switch (this.sortColumn) { | |
178 case "name": | |
179 if ( | |
180 bnA.properties.name.toLowerCase() < | |
181 bnB.properties.name.toLowerCase() | |
182 ) | |
183 return this.sortDirection === "ASC" ? -1 : 1; | |
184 if ( | |
185 bnA.properties.name.toLowerCase() > | |
186 bnB.properties.name.toLowerCase() | |
187 ) | |
188 return this.sortDirection === "ASC" ? 1 : -1; | |
189 return 0; | |
190 | |
191 case "latestMeasurement": { | |
192 if ( | |
193 (bnA.properties.current || "") < (bnB.properties.current || "") | |
194 ) | |
195 return this.sortDirection === "ASC" ? -1 : 1; | |
196 if ( | |
197 (bnA.properties.current || "") > (bnB.properties.current || "") | |
198 ) | |
199 return this.sortDirection === "ASC" ? 1 : -1; | |
200 return 0; | |
201 } | |
202 | |
203 case "chainage": | |
204 if (bnA.properties.from < bnB.properties.from) | |
205 return this.sortDirection === "ASC" ? -1 : 1; | |
206 if (bnA.properties.from > bnB.properties.from) | |
207 return this.sortDirection === "ASC" ? 1 : -1; | |
208 return 0; | |
209 | |
210 default: | |
211 return 0; | |
212 } | |
213 }); | |
214 }, | |
215 selectSurvey(survey, bottleneck) { | |
216 this.$store | |
217 .dispatch( | |
218 "bottlenecks/setSelectedBottleneck", | |
219 bottleneck.properties.name | |
220 ) | |
221 .then(() => { | |
222 this.$store.commit("bottlenecks/selectedSurvey", survey); | |
223 }) | |
224 .then(() => { | |
225 this.$store.commit("map/moveMap", { | |
226 coordinates: bottleneck.geometry.coordinates, | |
227 zoom: 17, | |
228 preventZoomOut: true | |
229 }); | |
230 }); | |
231 }, | |
232 selectBottleneck(bottleneck) { | |
233 this.$store | |
234 .dispatch( | |
235 "bottlenecks/setSelectedBottleneck", | |
236 bottleneck.properties.name | |
237 ) | |
238 .then(() => { | |
239 this.$store.commit("bottlenecks/setFirstSurveySelected"); | |
240 }) | |
241 .then(() => { | |
242 this.$store.commit("map/moveMap", { | |
243 coordinates: bottleneck.geometry.coordinates, | |
244 zoom: 17, | |
245 preventZoomOut: true | |
246 }); | |
247 }); | |
248 }, | |
249 sortBy(column) { | |
250 this.sortColumn = column; | |
251 this.sortDirection = this.sortDirection === "ASC" ? "DESC" : "ASC"; | |
252 }, | |
253 loadSurveys(name) { | |
254 this.openBottleneckSurveys = null; | |
255 if (name === this.openBottleneck) { | |
256 this.openBottleneck = null; | |
257 } else { | |
258 this.openBottleneck = name; | |
259 this.loading = name; | |
260 | |
261 HTTP.get("/surveys/" + name, { | |
262 headers: { | |
263 "X-Gemma-Auth": localStorage.getItem("token"), | |
264 "Content-type": "text/xml; charset=UTF-8" | |
265 } | |
266 }) | |
267 .then(response => { | |
268 this.openBottleneckSurveys = response.data.surveys.sort((a, b) => { | |
269 return a.date_info < b.date_info ? 1 : -1; | |
270 }); | |
271 }) | |
272 .catch(error => { | |
273 const { status, data } = error.response; | |
274 displayError({ | |
275 title: this.$gettext("Backend Error"), | |
276 message: `${status}: ${data.message || data}` | |
277 }); | |
278 }) | |
279 .finally(() => (this.loading = null)); | |
280 } | |
281 }, | |
282 displayCurrentChainage(from, to) { | |
283 return from / 10 + " - " + to / 10; | |
284 } | |
285 }, | |
286 mounted() { | |
287 this.$store.dispatch("bottlenecks/loadBottlenecks"); | |
288 } | |
289 }; | |
290 </script> | |
291 | |
292 <style lang="scss" scoped> | |
293 .bottleneck-list { | |
294 overflow-y: auto; | |
295 } | |
296 | |
297 .bottleneck-list .bottleneck-row a { | |
298 text-decoration: none; | |
299 } | |
300 | |
301 .bottleneck-list .bottleneck-row:hover { | |
302 background: #fbfbfb; | |
303 } | |
304 | |
305 .surveys { | |
306 max-height: 0; | |
307 min-height: 0; | |
308 overflow: hidden; | |
309 } | |
310 | |
311 .surveys a:hover { | |
312 background: #f3f3f3; | |
313 } | |
314 | |
315 .surveys.open { | |
316 max-height: 250px; | |
317 overflow: auto; | |
318 } | |
319 | |
320 .sort-link { | |
321 color: #444; | |
322 font-weight: bold; | |
323 } | |
324 </style> |