Mercurial > gemma
comparison client/src/components/importoverview/ImportOverview.vue @ 2559:d9e1db955d49
Backed out changeset 91c68153e7b6
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Fri, 08 Mar 2019 13:36:24 +0100 |
parents | 91c68153e7b6 |
children | 0d2650dd8f62 |
comparison
equal
deleted
inserted
replaced
2557:91c68153e7b6 | 2559:d9e1db955d49 |
---|---|
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="imports text-left ml-1 mr-1"> | 8 <div class="d-flex flex-row w-100 justify-content-end"> |
9 <div class="mt-3 d-flex flex-row border-bottom"> | 9 <button |
10 <div class="icons small condensed"> </div> | 10 class="btn btn-sm btn-outline-info align-self-start mr-3" |
11 <div class="id small condensed">Id</div> | 11 @click="refresh" |
12 <div class="kind small condensed">Kind</div> | 12 > |
13 <div class="date small condensed"> | 13 <font-awesome-icon icon="redo"></font-awesome-icon> |
14 Date | 14 </button> |
15 </div> | 15 </div> |
16 <div class="enqueued small condensed"> | 16 <div class="d-flex flex-row w-100 border-bottom"> |
17 Imported | 17 <font-awesome-icon |
18 </div> | 18 class="pointer" |
19 <div class="user small condensed">User</div> | 19 @click="toggleStaging()" |
20 <div class="state small condensed">State</div> | 20 v-if="stagingVisible && staging.length > 0" |
21 <div class="actions small condensed"> </div> | 21 icon="angle-up" |
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 > | |
22 </div> | 40 </div> |
23 <div class="d-flex flex-row" v-for="entry in importQueue" :key="entry.id"> | 41 </div> |
24 <div class="d-flex flex-column w-100"> | 42 <div class="mt-2"> |
25 <div class="d-flex flex-row"> | 43 <div class="d-flex flex-row"> |
26 <div class="icons"> | 44 <font-awesome-icon |
27 <font-awesome-icon | 45 class="pointer" |
28 @click="toggleDetails(entry.id)" | 46 @click="toggleLogs()" |
29 class="pointer text-info" | 47 v-if="logsVisible" |
30 v-if="show != entry.id" | 48 icon="angle-up" |
31 icon="angle-right" | 49 fixed-width |
32 fixed-width | 50 ></font-awesome-icon> |
33 ></font-awesome-icon> | 51 <font-awesome-icon |
34 <font-awesome-icon | 52 class="pointer" |
35 @click="toggleDetails(entry.id)" | 53 @click="toggleLogs()" |
36 class="pointer text-info" | 54 v-if="!logsVisible" |
37 v-if="show == entry.id" | 55 icon="angle-down" |
38 icon="angle-down" | 56 fixed-width |
39 fixed-width | 57 ></font-awesome-icon> |
40 ></font-awesome-icon> | 58 <Logs v-if="logsVisible" :reload="reload"></Logs> |
41 </div> | 59 <div v-else> |
42 <div class="id small condensed">{{ entry.id }}</div> | 60 <h6> |
43 <div class="kind small condensed"> | 61 <small><translate>Logs</translate></small> |
44 {{ entry.kind.toUpperCase() }} | 62 </h6> |
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> | |
265 </div> | 63 </div> |
266 </div> | 64 </div> |
267 </div> | 65 </div> |
268 </div> | 66 </div> |
269 </template> | 67 </template> |
270 | 68 |
271 <script> | 69 <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 */ | |
272 import { displayError } from "@/lib/errors.js"; | 83 import { displayError } from "@/lib/errors.js"; |
273 import { HTTP } from "@/lib/http"; | 84 import { mapState } from "vuex"; |
274 | |
275 //import { mapState } from "vuex"; | |
276 | |
277 const NODETAILS = -1; | |
278 const NODIFF = -1; | |
279 | 85 |
280 export default { | 86 export default { |
281 name: "importoverviewalt", | 87 name: "importoverview", |
282 data() { | 88 data() { |
283 return { | 89 return { |
284 showDiff: NODIFF, | 90 reload: false |
285 importQueue: [], | |
286 logEntries: [], | |
287 show: NODETAILS, | |
288 showAdditional: NODETAILS, | |
289 showLogs: NODETAILS | |
290 }; | 91 }; |
291 }, | 92 }, |
93 components: { | |
94 Staging: () => import("./staging/Staging.vue"), | |
95 Logs: () => import("./importlogs/Logs.vue") | |
96 }, | |
97 computed: { | |
98 ...mapState("imports", ["stagingVisible", "logsVisible", "staging"]) | |
99 }, | |
292 methods: { | 100 methods: { |
293 isFairwayDimension(kind) { | 101 toggleStaging() { |
294 return kind === "FD"; | 102 this.$store.commit("imports/setStagingVisibility", !this.stagingVisible); |
295 }, | 103 }, |
296 isApprovedGaugeMeasurement(kind) { | 104 toggleLogs() { |
297 return kind === "AGM"; | 105 this.$store.commit("imports/setLogsVisibility", !this.logsVisible); |
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; | |
334 }, | 106 }, |
335 refresh() { | 107 refresh() { |
336 this.reload = true; | 108 this.reload = true; |
337 this.loadImportQueue(); | 109 this.loadImportQueue(); |
338 this.loadLogs(); | 110 this.loadLogs(); |
339 }, | 111 }, |
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 }, | |
357 loadImportQueue() { | 112 loadImportQueue() { |
358 HTTP.get("/imports?states=running,pending", { | 113 this.$store |
359 headers: { "X-Gemma-Auth": localStorage.getItem("token") } | 114 .dispatch("imports/getStaging") |
360 }) | 115 .then(() => { |
361 .then(response => { | 116 this.reload = false; |
362 this.importQueue = response.data.imports; | |
363 }) | 117 }) |
364 .catch(error => { | 118 .catch(error => { |
365 const { status, data } = error.response; | 119 const { status, data } = error.response; |
366 displayError({ | 120 displayError({ |
367 title: "Backend Error", | 121 title: "Backend Error", |
384 }); | 138 }); |
385 } | 139 } |
386 }, | 140 }, |
387 mounted() { | 141 mounted() { |
388 this.refresh(); | 142 this.refresh(); |
389 }, | 143 } |
390 NODETAILS: NODETAILS | |
391 }; | 144 }; |
392 </script> | 145 </script> |
393 | 146 |
394 <style lang="scss" scoped> | 147 <style lang="scss" scoped> |
395 .agmdetailskeys { | |
396 width: 100px; | |
397 } | |
398 | |
399 .agmdetailsvalues { | |
400 width: 200px; | |
401 } | |
402 | |
403 .overview { | 148 .overview { |
404 max-height: 800px; | 149 max-height: 850px; |
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; | |
418 overflow-y: auto; | 150 overflow-y: auto; |
419 } | 151 } |
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 } | |
470 </style> | 152 </style> |