Mercurial > gemma
comparison client/src/components/importoverview/ImportOverview.vue @ 2557:91c68153e7b6
staging: switch route to new design per default
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Fri, 08 Mar 2019 12:24:42 +0100 |
parents | client/src/components/importoverview/ImportOverviewAlt.vue@ebaa0e93b05a |
children | d9e1db955d49 |
comparison
equal
deleted
inserted
replaced
2556:5b3d778db00c | 2557:91c68153e7b6 |
---|---|
3 <UIBoxHeader | 3 <UIBoxHeader |
4 icon="clipboard-check" | 4 icon="clipboard-check" |
5 title="Staging Area" | 5 title="Staging Area" |
6 :closeCallback="$parent.close" | 6 :closeCallback="$parent.close" |
7 /> | 7 /> |
8 <div class="d-flex flex-row w-100 justify-content-end"> | 8 <div class="imports text-left ml-1 mr-1"> |
9 <button | 9 <div class="mt-3 d-flex flex-row border-bottom"> |
10 class="btn btn-sm btn-outline-info align-self-start mr-3" | 10 <div class="icons small condensed"> </div> |
11 @click="refresh" | 11 <div class="id small condensed">Id</div> |
12 > | 12 <div class="kind small condensed">Kind</div> |
13 <font-awesome-icon icon="redo"></font-awesome-icon> | 13 <div class="date small condensed"> |
14 </button> | 14 Date |
15 </div> | 15 </div> |
16 <div class="d-flex flex-row w-100 border-bottom"> | 16 <div class="enqueued small condensed"> |
17 <font-awesome-icon | 17 Imported |
18 class="pointer" | 18 </div> |
19 @click="toggleStaging()" | 19 <div class="user small condensed">User</div> |
20 v-if="stagingVisible && staging.length > 0" | 20 <div class="state small condensed">State</div> |
21 icon="angle-up" | 21 <div class="actions small condensed"> </div> |
22 fixed-width | |
23 ></font-awesome-icon> | |
24 <font-awesome-icon | |
25 class="pointer" | |
26 @click="toggleStaging()" | |
27 v-if="!stagingVisible && staging.length > 0" | |
28 icon="angle-down" | |
29 fixed-width | |
30 ></font-awesome-icon> | |
31 <span style="width:1.25em;" v-if="!(staging.length > 0)"></span> | |
32 <Staging v-if="stagingVisible && staging.length > 0"></Staging> | |
33 <div v-else class="d-flex flex-row"> | |
34 <h6> | |
35 <small><translate>Review</translate></small> | |
36 </h6> | |
37 <small class="ml-3" v-if="!(staging.length > 0)" | |
38 ><translate>Nothing to review</translate></small | |
39 > | |
40 </div> | 22 </div> |
41 </div> | 23 <div class="d-flex flex-row" v-for="entry in importQueue" :key="entry.id"> |
42 <div class="mt-2"> | 24 <div class="d-flex flex-column w-100"> |
43 <div class="d-flex flex-row"> | 25 <div class="d-flex flex-row"> |
44 <font-awesome-icon | 26 <div class="icons"> |
45 class="pointer" | 27 <font-awesome-icon |
46 @click="toggleLogs()" | 28 @click="toggleDetails(entry.id)" |
47 v-if="logsVisible" | 29 class="pointer text-info" |
48 icon="angle-up" | 30 v-if="show != entry.id" |
49 fixed-width | 31 icon="angle-right" |
50 ></font-awesome-icon> | 32 fixed-width |
51 <font-awesome-icon | 33 ></font-awesome-icon> |
52 class="pointer" | 34 <font-awesome-icon |
53 @click="toggleLogs()" | 35 @click="toggleDetails(entry.id)" |
54 v-if="!logsVisible" | 36 class="pointer text-info" |
55 icon="angle-down" | 37 v-if="show == entry.id" |
56 fixed-width | 38 icon="angle-down" |
57 ></font-awesome-icon> | 39 fixed-width |
58 <Logs v-if="logsVisible" :reload="reload"></Logs> | 40 ></font-awesome-icon> |
59 <div v-else> | 41 </div> |
60 <h6> | 42 <div class="id small condensed">{{ entry.id }}</div> |
61 <small><translate>Logs</translate></small> | 43 <div class="kind small condensed"> |
62 </h6> | 44 {{ entry.kind.toUpperCase() }} |
45 </div> | |
46 <div class="date small condensed"> | |
47 {{ entry.summary.date | surveyDate }} | |
48 </div> | |
49 <div class="enqueued small condensed"> | |
50 {{ entry.enqueued.split("T")[0] | surveyDate }} | |
51 </div> | |
52 <div class="user small condensed">{{ entry.user }}</div> | |
53 <div class="state small condensed"> | |
54 {{ entry.state }} | |
55 </div> | |
56 <div class="actions small condensed"> | |
57 <font-awesome-icon | |
58 v-if="entry.warnings" | |
59 class="ml-1 text-warning text-info" | |
60 icon="exclamation-triangle" | |
61 fixed-width | |
62 ></font-awesome-icon> | |
63 <font-awesome-icon | |
64 v-if="!entry.warnings" | |
65 class="ml-1 text-white" | |
66 icon="exclamation-triangle" | |
67 fixed-width | |
68 ></font-awesome-icon> | |
69 <font-awesome-icon | |
70 class="ml-1 text-mute" | |
71 icon="check" | |
72 fixed-width | |
73 ></font-awesome-icon> | |
74 <font-awesome-icon | |
75 class="ml-1 text-mute" | |
76 icon="times" | |
77 fixed-width | |
78 ></font-awesome-icon> | |
79 </div> | |
80 </div> | |
81 <div class="d-flex flex-row" v-if="show == entry.id"> | |
82 <div class="ml-1 details d-flex flex-column"> | |
83 <div | |
84 v-if="isApprovedGaugeMeasurement(entry.kind.toUpperCase())" | |
85 class="d-flex flex-row" | |
86 > | |
87 <font-awesome-icon | |
88 @click="toggleAdditional(entry.id)" | |
89 class="pointer text-info" | |
90 v-if="showAdditional != entry.id" | |
91 icon="angle-right" | |
92 fixed-width | |
93 ></font-awesome-icon> | |
94 <font-awesome-icon | |
95 @click="toggleAdditional(entry.id)" | |
96 class="pointer text-info" | |
97 v-if="showAdditional == entry.id" | |
98 icon="angle-down" | |
99 fixed-width | |
100 ></font-awesome-icon> | |
101 <small class="condensed">Additional Info</small> | |
102 </div> | |
103 <div | |
104 v-if="showAdditional == entry.id" | |
105 class="additionalinfo ml-4" | |
106 > | |
107 <div v-for="(result, index) in entry.summary" :key="index"> | |
108 <font-awesome-icon | |
109 @click="toggleDiff(index)" | |
110 class="pointer text-info" | |
111 v-if="showDiff != index" | |
112 icon="angle-right" | |
113 fixed-width | |
114 ></font-awesome-icon> | |
115 <font-awesome-icon | |
116 @click="toggleDiff(index)" | |
117 class="pointer text-info" | |
118 v-if="showDiff == index" | |
119 icon="angle-down" | |
120 fixed-width | |
121 ></font-awesome-icon> | |
122 <span | |
123 v-if="result.versions.length == 1" | |
124 class="agmcode text-left" | |
125 ><small | |
126 >{{ result["fk-gauge-id"] }} | |
127 <translate class="mr-1">( New )</translate></small | |
128 ></span | |
129 > | |
130 <span | |
131 v-if="result.versions.length == 2" | |
132 class="agmcode text-left" | |
133 ><small>{{ result["fk-gauge-id"] }}</small></span | |
134 > | |
135 <span class="agmdetail text-left" | |
136 ><small>{{ | |
137 result["measure-date"] | datetime | |
138 }}</small></span | |
139 > | |
140 <div v-if="showDiff == index" class="ml-1"> | |
141 <div> | |
142 <div class="d-flex flex-row pl-3 text-left"> | |
143 <div class="header border-bottom agmdetailskeys"> | |
144 <small><translate>Value</translate></small> | |
145 </div> | |
146 <div | |
147 v-if="result.versions.length == 2" | |
148 class="header border-bottom agmdetailsvalues" | |
149 > | |
150 <small><translate>Old</translate></small> | |
151 </div> | |
152 <div class="header border-bottom agmdetailsvalues"> | |
153 <small><translate>New</translate></small> | |
154 </div> | |
155 </div> | |
156 <div | |
157 class="d-flex flex-row pl-3 text-left" | |
158 v-for="(entry, index) in Object.keys( | |
159 result.versions[0] | |
160 )" | |
161 :key="index" | |
162 > | |
163 <div | |
164 v-if=" | |
165 result.versions.length == 1 || | |
166 result.versions[0][entry] != | |
167 result.versions[1][entry] | |
168 " | |
169 class="agmdetailskeys" | |
170 > | |
171 <small>{{ entry }}</small> | |
172 </div> | |
173 <div | |
174 v-if=" | |
175 result.versions.length == 1 || | |
176 result.versions[0][entry] != | |
177 result.versions[1][entry] | |
178 " | |
179 class="agmdetailsvalues" | |
180 > | |
181 <small>{{ result.versions[0][entry] }}</small> | |
182 </div> | |
183 <div | |
184 v-if=" | |
185 result.versions.length == 2 && | |
186 result.versions[0][entry] != | |
187 result.versions[1][entry] | |
188 " | |
189 class="agmdetailsvalues" | |
190 > | |
191 <small>{{ result.versions[1][entry] }}</small> | |
192 </div> | |
193 </div> | |
194 </div> | |
195 </div> | |
196 </div> | |
197 </div> | |
198 <div class="d-flex flex-row"> | |
199 <div class="d-flex flex-column"> | |
200 <div class="d-flex flex-row"> | |
201 <font-awesome-icon | |
202 @click="toggleLogs(entry.id)" | |
203 class="pointer text-info" | |
204 v-if="showLogs != entry.id" | |
205 icon="angle-right" | |
206 fixed-width | |
207 ></font-awesome-icon> | |
208 <font-awesome-icon | |
209 @click="toggleLogs(entry.id)" | |
210 class="pointer text-info" | |
211 v-if="showLogs == entry.id" | |
212 icon="angle-down" | |
213 fixed-width | |
214 ></font-awesome-icon> | |
215 <small class="condensed">Logs</small> | |
216 </div> | |
217 <div v-if="showLogs == entry.id" class="ml-4 logentries"> | |
218 <div | |
219 v-for="(logentry, index) in logEntries" | |
220 :key="index" | |
221 class="d-flex flex-row" | |
222 > | |
223 <small | |
224 :class="[ | |
225 'condensed type', | |
226 { | |
227 'text-danger': | |
228 logentry.kind.toUpperCase() == 'ERROR', | |
229 'text-warning': | |
230 logentry.kind.toUpperCase() == 'WARN' | |
231 } | |
232 ]" | |
233 >{{ logentry.kind.toUpperCase() }}</small | |
234 > | |
235 <small | |
236 :class="[ | |
237 'condensed type', | |
238 { | |
239 'text-danger': | |
240 logentry.kind.toUpperCase() == 'ERROR', | |
241 'text-warning': | |
242 logentry.kind.toUpperCase() == 'WARN' | |
243 } | |
244 ]" | |
245 >{{ logentry.time }}</small | |
246 > | |
247 <small | |
248 :class="[ | |
249 'condensed type', | |
250 { | |
251 'text-danger': | |
252 logentry.kind.toUpperCase() == 'ERROR', | |
253 'text-warning': | |
254 logentry.kind.toUpperCase() == 'WARN' | |
255 } | |
256 ]" | |
257 >{{ logentry.message }}</small | |
258 > | |
259 </div> | |
260 </div> | |
261 </div> | |
262 </div> | |
263 </div> | |
264 </div> | |
63 </div> | 265 </div> |
64 </div> | 266 </div> |
65 </div> | 267 </div> |
66 </div> | 268 </div> |
67 </template> | 269 </template> |
68 | 270 |
69 <script> | 271 <script> |
70 /* This is Free Software under GNU Affero General Public License v >= 3.0 | |
71 * without warranty, see README.md and license for details. | |
72 * | |
73 * SPDX-License-Identifier: AGPL-3.0-or-later | |
74 * License-Filename: LICENSES/AGPL-3.0.txt | |
75 * | |
76 * Copyright (C) 2018 by via donau | |
77 * – Österreichische Wasserstraßen-Gesellschaft mbH | |
78 * Software engineering by Intevation GmbH | |
79 * | |
80 * Author(s): | |
81 * Thomas Junk <thomas.junk@intevation.de> | |
82 */ | |
83 import { displayError } from "@/lib/errors.js"; | 272 import { displayError } from "@/lib/errors.js"; |
84 import { mapState } from "vuex"; | 273 import { HTTP } from "@/lib/http"; |
274 | |
275 //import { mapState } from "vuex"; | |
276 | |
277 const NODETAILS = -1; | |
278 const NODIFF = -1; | |
85 | 279 |
86 export default { | 280 export default { |
87 name: "importoverview", | 281 name: "importoverviewalt", |
88 data() { | 282 data() { |
89 return { | 283 return { |
90 reload: false | 284 showDiff: NODIFF, |
285 importQueue: [], | |
286 logEntries: [], | |
287 show: NODETAILS, | |
288 showAdditional: NODETAILS, | |
289 showLogs: NODETAILS | |
91 }; | 290 }; |
92 }, | 291 }, |
93 components: { | |
94 Staging: () => import("./staging/Staging.vue"), | |
95 Logs: () => import("./importlogs/Logs.vue") | |
96 }, | |
97 computed: { | |
98 ...mapState("imports", ["stagingVisible", "logsVisible", "staging"]) | |
99 }, | |
100 methods: { | 292 methods: { |
101 toggleStaging() { | 293 isFairwayDimension(kind) { |
102 this.$store.commit("imports/setStagingVisibility", !this.stagingVisible); | 294 return kind === "FD"; |
103 }, | 295 }, |
104 toggleLogs() { | 296 isApprovedGaugeMeasurement(kind) { |
105 this.$store.commit("imports/setLogsVisibility", !this.logsVisible); | 297 return kind === "AGM"; |
298 }, | |
299 isBottleneck(kind) { | |
300 return kind === "BN" || kind === "UBN"; | |
301 }, | |
302 isStretch(kind) { | |
303 return kind === "ST"; | |
304 }, | |
305 toggleAdditional(id) { | |
306 if (id === this.showAdditional) { | |
307 this.showAdditional = NODETAILS; | |
308 return; | |
309 } | |
310 this.showAdditional = id; | |
311 }, | |
312 toggleDiff(id) { | |
313 if (id === this.showDiff) { | |
314 this.showDiff = NODIFF; | |
315 return; | |
316 } | |
317 this.showDiff = id; | |
318 }, | |
319 toggleLogs(id) { | |
320 if (id === this.showLogs) { | |
321 this.showLogs = NODETAILS; | |
322 return; | |
323 } | |
324 this.loadLogEntries(id); | |
325 }, | |
326 toggleDetails(id) { | |
327 if (id === this.show) { | |
328 this.show = NODETAILS; | |
329 this.showAdditional = NODETAILS; | |
330 this.showLogs = NODETAILS; | |
331 return; | |
332 } | |
333 this.show = id; | |
106 }, | 334 }, |
107 refresh() { | 335 refresh() { |
108 this.reload = true; | 336 this.reload = true; |
109 this.loadImportQueue(); | 337 this.loadImportQueue(); |
110 this.loadLogs(); | 338 this.loadLogs(); |
111 }, | 339 }, |
340 loadLogEntries(id) { | |
341 HTTP.get("/imports/" + id, { | |
342 headers: { "X-Gemma-Auth": localStorage.getItem("token") } | |
343 }) | |
344 .then(response => { | |
345 const { entries } = response.data; | |
346 this.logEntries = entries; | |
347 this.showLogs = id; | |
348 }) | |
349 .catch(error => { | |
350 const { status, data } = error.response; | |
351 displayError({ | |
352 title: this.$gettext("Backend Error"), | |
353 message: `${status}: ${data.message || data}` | |
354 }); | |
355 }); | |
356 }, | |
112 loadImportQueue() { | 357 loadImportQueue() { |
113 this.$store | 358 HTTP.get("/imports?states=running,pending", { |
114 .dispatch("imports/getStaging") | 359 headers: { "X-Gemma-Auth": localStorage.getItem("token") } |
115 .then(() => { | 360 }) |
116 this.reload = false; | 361 .then(response => { |
362 this.importQueue = response.data.imports; | |
117 }) | 363 }) |
118 .catch(error => { | 364 .catch(error => { |
119 const { status, data } = error.response; | 365 const { status, data } = error.response; |
120 displayError({ | 366 displayError({ |
121 title: "Backend Error", | 367 title: "Backend Error", |
138 }); | 384 }); |
139 } | 385 } |
140 }, | 386 }, |
141 mounted() { | 387 mounted() { |
142 this.refresh(); | 388 this.refresh(); |
143 } | 389 }, |
390 NODETAILS: NODETAILS | |
144 }; | 391 }; |
145 </script> | 392 </script> |
146 | 393 |
147 <style lang="scss" scoped> | 394 <style lang="scss" scoped> |
395 .agmdetailskeys { | |
396 width: 100px; | |
397 } | |
398 | |
399 .agmdetailsvalues { | |
400 width: 200px; | |
401 } | |
402 | |
148 .overview { | 403 .overview { |
149 max-height: 850px; | 404 max-height: 800px; |
405 } | |
406 .logentries { | |
407 max-height: 400px; | |
408 max-width: 600px; | |
409 font-size: smaller; | |
410 white-space: nowrap; | |
411 line-height: 1.1em; | |
412 overflow: auto; | |
413 } | |
414 | |
415 .additionalinfo { | |
416 max-width: 650px; | |
417 max-height: 350px; | |
150 overflow-y: auto; | 418 overflow-y: auto; |
151 } | 419 } |
420 | |
421 .additionalinfo > div:hover { | |
422 background: #eee; | |
423 } | |
424 | |
425 .logentries > div:hover { | |
426 background: #eee; | |
427 } | |
428 | |
429 .details { | |
430 width: 100%; | |
431 padding: 5px; | |
432 cursor: pointer; | |
433 } | |
434 | |
435 .imports { | |
436 line-height: 1.5rem; | |
437 } | |
438 | |
439 .icons { | |
440 width: 4%; | |
441 } | |
442 | |
443 .id { | |
444 width: 10%; | |
445 } | |
446 | |
447 .kind { | |
448 width: 10%; | |
449 } | |
450 | |
451 .date { | |
452 width: 20%; | |
453 } | |
454 | |
455 .enqueued { | |
456 width: 20%; | |
457 } | |
458 | |
459 .user { | |
460 width: 10%; | |
461 } | |
462 | |
463 .state { | |
464 width: 10%; | |
465 } | |
466 | |
467 .actions { | |
468 width: 16%; | |
469 } | |
152 </style> | 470 </style> |