comparison client/src/components/importqueue/Importqueuedetail.vue @ 1559:5d84dcb79a54

layout importqueue
author Thomas Junk <thomas.junk@intevation.de>
date Wed, 12 Dec 2018 09:48:37 +0100
parents client/src/components/Importqueuedetail.vue@0ded4c56978e
children ad3a19e222bb
comparison
equal deleted inserted replaced
1558:0ded4c56978e 1559:5d84dcb79a54
1 <template>
2 <div class="entry d-flex flex-column py-1 border-bottom w-50">
3 <div class="d-flex flex-row position-relative">
4 <div @click="showDetails(job.id)" class="jobid ml-2 mt-1 mr-2">
5 {{ job.id }}
6 </div>
7 <div @click="showDetails(job.id)" class="enqueued mt-1 mr-2">
8 {{ formatDate(job.enqueued) }}
9 </div>
10 <div @click="showDetails(job.id)" class="kind mt-1 mr-2">
11 {{ job.kind }}
12 </div>
13 <div @click="showDetails(job.id)" class="user mt-1 mr-2">
14 {{ job.user }}
15 </div>
16 <div @click="showDetails(job.id)" class="signer mt-1 mr-2">
17 {{ job.signer }}
18 </div>
19 <div @click="showDetails(job.id)" class="state mt-1 mr-2">
20 {{ job.state }}
21 </div>
22 <div @click="showDetails(job.id)" class="mt-1 text-info detailsbutton">
23 <font-awesome-icon
24 v-if="show"
25 icon="angle-up"
26 fixed-width
27 ></font-awesome-icon>
28 <font-awesome-icon
29 v-else
30 icon="angle-down"
31 fixed-width
32 ></font-awesome-icon>
33 </div>
34 </div>
35 <div class="detailstable d-flex flex-row">
36 <div :class="collapse">
37 <table class="table table-responsive">
38 <thead>
39 <tr>
40 <th class="first pb-0">
41 <small class="condensed"><translate>Kind</translate></small>
42 </th>
43 <th class="second pb-0">
44 <a href="#" @click="sortAsc = !sortAsc" class="sort-link"
45 ><small class="condensed"><translate>Date</translate></small>
46 <small class="condensed"
47 ><font-awesome-icon
48 :icon="sortIcon"
49 class="ml-1"
50 ></font-awesome-icon></small
51 ></a>
52 </th>
53 <th class="third pb-0">
54 <small class="condensed"><translate>Message</translate></small>
55 </th>
56 </tr>
57 </thead>
58 <tbody>
59 <tr
60 v-for="(entry, index) in sortedEntries"
61 :key="index"
62 class="detailsrow"
63 >
64 <td class="first">
65 <span class="condensed">{{ entry.kind }}</span>
66 </td>
67 <td class="second">
68 <span class="condensed">{{ formatDate(entry.time) }}</span>
69 </td>
70 <td class="third">
71 <span class="condensed">{{ entry.message }}</span>
72 </td>
73 </tr>
74 </tbody>
75 </table>
76 </div>
77 </div>
78 </div>
79 </template>
80
81 <script>
82 /* This is Free Software under GNU Affero General Public License v >= 3.0
83 * without warranty, see README.md and license for details.
84 *
85 * SPDX-License-Identifier: AGPL-3.0-or-later
86 * License-Filename: LICENSES/AGPL-3.0.txt
87 *
88 * Copyright (C) 2018 by via donau
89 * – Österreichische Wasserstraßen-Gesellschaft mbH
90 * Software engineering by Intevation GmbH
91 *
92 * Author(s):
93 * Thomas Junk <thomas.junk@intevation.de>
94 */
95
96 import { HTTP } from "../../lib/http.js";
97 import { displayError } from "../../lib/errors.js";
98 import locale2 from "locale2";
99
100 export default {
101 name: "importqueuedetail",
102 props: ["job"],
103 data() {
104 return {
105 show: false,
106 entries: [],
107 sortAsc: true
108 };
109 },
110 methods: {
111 formatDate(date) {
112 return date
113 ? new Date(date).toLocaleDateString(locale2, {
114 day: "2-digit",
115 month: "2-digit",
116 year: "numeric"
117 })
118 : "";
119 },
120 showDetails(id) {
121 if (this.show) {
122 this.show = false;
123 return;
124 }
125 if (this.entries.length === 0) {
126 HTTP.get("/imports/" + id, {
127 headers: { "X-Gemma-Auth": localStorage.getItem("token") }
128 })
129 .then(response => {
130 const { entries } = response.data;
131 this.entries = entries;
132 this.show = true;
133 })
134 .catch(error => {
135 const { status, data } = error.response;
136 displayError({
137 title: this.$gettext("Backend Error"),
138 message: `${status}: ${data.message || data}`
139 });
140 });
141 } else {
142 this.show = true;
143 }
144 }
145 },
146 computed: {
147 sortedEntries() {
148 let sorted = this.entries.slice();
149 sorted.sort((r1, r2) => {
150 let d1 = new Date(r1.time);
151 let d2 = new Date(r2.time);
152 if (d2 < d1) {
153 return !this.sortAsc ? -1 : 1;
154 }
155 if (d2 > d1) {
156 return !this.sortAsc ? 1 : -1;
157 }
158 return 0;
159 });
160 return sorted;
161 },
162 sortIcon() {
163 return this.sortAsc ? "sort-amount-down" : "sort-amount-up";
164 },
165 icon() {
166 return {
167 "angle-up": !this.show,
168 "angle-down": this.show
169 };
170 },
171 collapse() {
172 return {
173 details: true,
174 collapse: true,
175 show: this.show,
176 "w-100": true
177 };
178 }
179 }
180 };
181 </script>
182
183 <style lang="scss" scoped>
184 .condensed {
185 font-stretch: condensed;
186 }
187
188 .entry {
189 background-color: white;
190 cursor: pointer;
191 }
192
193 .entry:hover {
194 background-color: #efefef;
195 transition: 1.5s;
196 }
197
198 .detailstable {
199 margin-left: $offset;
200 margin-right: $large-offset;
201 }
202
203 .detailsbutton {
204 position: absolute;
205 top: 0;
206 right: 0;
207 height: 100%;
208 }
209 .jobid {
210 width: 80px;
211 }
212
213 .enqueued {
214 width: 120px;
215 }
216
217 .user {
218 width: 80px;
219 }
220
221 .signer {
222 width: 80px;
223 }
224
225 .kind {
226 width: 80px;
227 }
228
229 .state {
230 width: 80px;
231 }
232
233 .details {
234 width: 50%;
235 }
236
237 .detailsrow {
238 line-height: 0.1em;
239 }
240
241 .first {
242 width: 65px;
243 padding-left: 0px;
244 border-top: 0px;
245 padding-bottom: $small-offset;
246 }
247
248 .second {
249 width: 100px;
250 padding-left: 0px;
251 border-top: 0px;
252 padding-bottom: $small-offset;
253 }
254
255 .third {
256 width: 600px;
257 padding-left: 0px;
258 border-top: 0px;
259 padding-bottom: $small-offset;
260 }
261
262 thead,
263 tbody {
264 display: block;
265 }
266
267 tbody {
268 height: 150px;
269 overflow-y: auto;
270 overflow-x: hidden;
271 }
272 </style>