comparison client/src/components/usermanagement/Usermanagement.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/admin/usermanagement/Usermanagement.vue@31c6c7bd6190
children 32a34151d9d7
comparison
equal deleted inserted replaced
1557:62171cd9a42b 1558:0ded4c56978e
1 <template>
2 <div class="main d-flex flex-row">
3 <div :class="spacerStyle"></div>
4 <div class="d-flex content flex-column">
5 <div class="d-flex flex-row">
6 <div :class="userlistStyle">
7 <div class="card">
8 <h6
9 class="mb-0 py-2 px-3 border-bottom d-flex text-info align-items-center"
10 >
11 <font-awesome-icon
12 icon="users-cog"
13 class="mr-2 fa-fw"
14 ></font-awesome-icon>
15 <translate class="headline">Users</translate>
16 </h6>
17 <div class="card-body">
18 <table id="datatable" :class="tableStyle">
19 <thead>
20 <tr>
21 <th scope="col" @click="sortBy('user')">
22 <span
23 >Username&nbsp;
24 <font-awesome-icon
25 v-if="sortCriterion == 'user'"
26 icon="angle-down"
27 ></font-awesome-icon>
28 </span>
29 </th>
30 <th scope="col" @click="sortBy('country')">
31 <span
32 >Country&nbsp;
33 <font-awesome-icon
34 v-if="sortCriterion == 'country'"
35 icon="angle-down"
36 ></font-awesome-icon>
37 </span>
38 </th>
39 <th scope="col" @click="sortBy('email')">
40 <span
41 >Email&nbsp;
42 <font-awesome-icon
43 v-if="sortCriterion == 'email'"
44 icon="angle-down"
45 ></font-awesome-icon>
46 </span>
47 </th>
48 <th scope="col" @click="sortBy('role')">
49 <span
50 >Role&nbsp;
51 <font-awesome-icon
52 v-if="sortCriterion == 'role'"
53 icon="angle-down"
54 ></font-awesome-icon>
55 </span>
56 </th>
57 <th scope="col"></th>
58 </tr>
59 </thead>
60 <tbody>
61 <tr
62 v-for="user in users"
63 :key="user.user"
64 @click="selectUser(user.user)"
65 >
66 <td>{{ user.user }}</td>
67 <td>{{ user.country }}</td>
68 <td>{{ user.email }}</td>
69 <td>
70 <font-awesome-icon
71 :icon="roleIcon(user.role)"
72 @click="deleteUser(user.user)"
73 ></font-awesome-icon>
74 </td>
75 <td>
76 <font-awesome-icon
77 icon="trash"
78 @click="deleteUser(user.user)"
79 ></font-awesome-icon>
80 </td>
81 </tr>
82 </tbody>
83 </table>
84 </div>
85 <div class="d-flex mx-auto align-items-center">
86 <button
87 @click="prevPage"
88 v-if="this.currentPage !== 1"
89 class="mr-2 btn btn-sm btn-light align-self-center"
90 >
91 <font-awesome-icon icon="angle-left"></font-awesome-icon>
92 </button>
93 {{ this.currentPage }} / {{ this.pages }}
94 <button
95 @click="nextPage"
96 v-if="this.currentPage !== this.pages"
97 class="ml-2 btn btn-sm btn-light align-self-center"
98 >
99 <font-awesome-icon icon="angle-right"></font-awesome-icon>
100 </button>
101 </div>
102 <div class="mr-3 pb-3">
103 <button @click="addUser" class="btn btn-info addbutton shadow-sm">
104 <translate>Add User</translate>
105 </button>
106 </div>
107 </div>
108 </div>
109 <Userdetail
110 class="d-flex userdetails"
111 v-if="isUserDetailsVisible"
112 ></Userdetail>
113 </div>
114 </div>
115 </div>
116 </template>
117
118 <style scoped lang="scss">
119 @import "../../assets/tooltip.scss";
120
121 .addbutton {
122 position: absolute;
123 bottom: $offset;
124 right: $offset;
125 }
126
127 .content {
128 width: 100%;
129 }
130
131 .userdetails {
132 width: 50%;
133 }
134 .spacer {
135 height: 100vh;
136 margin-left: $offset;
137 }
138
139 .spacer-collapsed {
140 min-width: $icon-width + $offset;
141 transition: $transition-fast;
142 }
143
144 .spacer-expanded {
145 min-width: $sidebar-width + $offset;
146 }
147
148 .main {
149 height: 100vh;
150 }
151
152 .icon {
153 font-size: large;
154 }
155
156 .userlist {
157 min-width: 520px;
158 height: 100%;
159 }
160
161 .userlistsmall {
162 width: 100%;
163 }
164
165 .userlistextended {
166 width: 100%;
167 }
168
169 .table {
170 width: 90% !important;
171 margin: auto;
172 }
173
174 .table th {
175 cursor: pointer;
176 }
177
178 .table th,
179 td {
180 font-size: $smaller;
181 border-top: 0px !important;
182 text-align: left;
183 padding: $small-offset !important;
184 }
185
186 .table td {
187 font-size: $smaller;
188 cursor: pointer;
189 }
190
191 tr span {
192 display: flex;
193 }
194 </style>
195
196 <script>
197 /* This is Free Software under GNU Affero General Public License v >= 3.0
198 * without warranty, see README.md and license for details.
199 *
200 * SPDX-License-Identifier: AGPL-3.0-or-later
201 * License-Filename: LICENSES/AGPL-3.0.txt
202 *
203 * Copyright (C) 2018 by via donau
204 * – Österreichische Wasserstraßen-Gesellschaft mbH
205 * Software engineering by Intevation GmbH
206 *
207 * Author(s):
208 * Thomas Junk <thomas.junk@intevation.de>
209 */
210 import Userdetail from "./Userdetail";
211 import store from "../../store";
212 import { mapGetters, mapState } from "vuex";
213 import { displayError } from "../../lib/errors.js";
214
215 export default {
216 name: "userview",
217 data() {
218 return {
219 sortCriterion: "user",
220 pageSize: 10,
221 currentPage: 1
222 };
223 },
224 components: {
225 Userdetail
226 },
227 computed: {
228 ...mapGetters("usermanagement", ["isUserDetailsVisible"]),
229 ...mapState("application", ["showSidebar"]),
230 spacerStyle() {
231 return [
232 "spacer",
233 {
234 "spacer-expanded": this.showSidebar,
235 "spacer-collapsed": !this.showSidebar
236 }
237 ];
238 },
239 users() {
240 let users = [...this.$store.getters["usermanagement/users"]];
241 users.sort((a, b) => {
242 if (
243 a[this.sortCriterion].toLowerCase() <
244 b[this.sortCriterion].toLowerCase()
245 )
246 return -1;
247 if (
248 a[this.sortCriterion].toLowerCase() >
249 b[this.sortCriterion].toLowerCase()
250 )
251 return 1;
252 return 0;
253 });
254 const start = (this.currentPage - 1) * this.pageSize;
255 return users.slice(start, start + this.pageSize);
256 },
257 pages() {
258 let users = [...this.$store.getters["usermanagement/users"]];
259 return Math.ceil(users.length / this.pageSize);
260 },
261 tableStyle() {
262 return {
263 table: true,
264 "table-hover": true,
265 "table-sm": this.isUserDetailsVisible,
266 fadeIn: true,
267 animated: true
268 };
269 },
270 userlistStyle() {
271 return [
272 "userlist mt-3 mr-3 shadow-xs",
273 {
274 userlistsmall: this.isUserDetailsVisible,
275 userlistextended: !this.isUserDetailsVisible
276 }
277 ];
278 }
279 },
280 methods: {
281 tween() {},
282 nextPage() {
283 if (this.currentPage < this.pages) {
284 document.querySelector("#datatable").classList.add("fadeOut");
285 setTimeout(() => {
286 document.querySelector("#datatable").classList.remove("fadeOut");
287 this.currentPage += 1;
288 }, 10);
289 }
290 return;
291 },
292 prevPage() {
293 if (this.currentPage > 0) {
294 document.querySelector("#datatable").classList.add("fadeOut");
295 setTimeout(() => {
296 document.querySelector("#datatable").classList.remove("fadeOut");
297 this.currentPage -= 1;
298 }, 10);
299 }
300 return;
301 },
302 sortBy(criterion) {
303 this.sortCriterion = criterion;
304 },
305 deleteUser(name) {
306 this.$store
307 .dispatch("usermanagement/deleteUser", { name: name })
308 .then(() => {
309 this.submitted = false;
310 this.$store.dispatch("usermanagement/loadUsers").catch(error => {
311 const { status, data } = error.response;
312 displayError({
313 title: this.$gettext("Backend Error"),
314 message: `${status}: ${data.message || data}`
315 });
316 });
317 })
318 .catch(error => {
319 const { status, data } = error.response;
320 displayError({
321 title: this.$gettext("Backend Error"),
322 message: `${status}: ${data.message || data}`
323 });
324 });
325 },
326 addUser() {
327 this.$store.commit("usermanagement/clearCurrentUser");
328 this.$store.commit("usermanagement/setUserDetailsVisible");
329 },
330 selectUser(name) {
331 const user = this.$store.getters["usermanagement/getUserByName"](name);
332 this.$store.commit("usermanagement/setCurrentUser", user);
333 },
334 roleIcon(role) {
335 if (role === "sys_admin") return "star";
336 if (role === "waterway_admin") return ["fab", "adn"];
337 return "user";
338 }
339 },
340 beforeRouteEnter(to, from, next) {
341 store
342 .dispatch("usermanagement/loadUsers")
343 .then(next)
344 .catch(error => {
345 const { status, data } = error.response;
346 displayError({
347 title: this.$gettext("Backend Error"),
348 message: `${status}: ${data}`
349 });
350 });
351 },
352 beforeRouteLeave(to, from, next) {
353 store.commit("usermanagement/clearCurrentUser");
354 store.commit("usermanagement/setUserDetailsInvisible");
355 next();
356 }
357 };
358 </script>