Mercurial > gemma
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/components/usermanagement/Usermanagement.vue Wed Dec 12 09:22:20 2018 +0100 @@ -0,0 +1,358 @@ +<template> + <div class="main d-flex flex-row"> + <div :class="spacerStyle"></div> + <div class="d-flex content flex-column"> + <div class="d-flex flex-row"> + <div :class="userlistStyle"> + <div class="card"> + <h6 + class="mb-0 py-2 px-3 border-bottom d-flex text-info align-items-center" + > + <font-awesome-icon + icon="users-cog" + class="mr-2 fa-fw" + ></font-awesome-icon> + <translate class="headline">Users</translate> + </h6> + <div class="card-body"> + <table id="datatable" :class="tableStyle"> + <thead> + <tr> + <th scope="col" @click="sortBy('user')"> + <span + >Username + <font-awesome-icon + v-if="sortCriterion == 'user'" + icon="angle-down" + ></font-awesome-icon> + </span> + </th> + <th scope="col" @click="sortBy('country')"> + <span + >Country + <font-awesome-icon + v-if="sortCriterion == 'country'" + icon="angle-down" + ></font-awesome-icon> + </span> + </th> + <th scope="col" @click="sortBy('email')"> + <span + >Email + <font-awesome-icon + v-if="sortCriterion == 'email'" + icon="angle-down" + ></font-awesome-icon> + </span> + </th> + <th scope="col" @click="sortBy('role')"> + <span + >Role + <font-awesome-icon + v-if="sortCriterion == 'role'" + icon="angle-down" + ></font-awesome-icon> + </span> + </th> + <th scope="col"></th> + </tr> + </thead> + <tbody> + <tr + v-for="user in users" + :key="user.user" + @click="selectUser(user.user)" + > + <td>{{ user.user }}</td> + <td>{{ user.country }}</td> + <td>{{ user.email }}</td> + <td> + <font-awesome-icon + :icon="roleIcon(user.role)" + @click="deleteUser(user.user)" + ></font-awesome-icon> + </td> + <td> + <font-awesome-icon + icon="trash" + @click="deleteUser(user.user)" + ></font-awesome-icon> + </td> + </tr> + </tbody> + </table> + </div> + <div class="d-flex mx-auto align-items-center"> + <button + @click="prevPage" + v-if="this.currentPage !== 1" + class="mr-2 btn btn-sm btn-light align-self-center" + > + <font-awesome-icon icon="angle-left"></font-awesome-icon> + </button> + {{ this.currentPage }} / {{ this.pages }} + <button + @click="nextPage" + v-if="this.currentPage !== this.pages" + class="ml-2 btn btn-sm btn-light align-self-center" + > + <font-awesome-icon icon="angle-right"></font-awesome-icon> + </button> + </div> + <div class="mr-3 pb-3"> + <button @click="addUser" class="btn btn-info addbutton shadow-sm"> + <translate>Add User</translate> + </button> + </div> + </div> + </div> + <Userdetail + class="d-flex userdetails" + v-if="isUserDetailsVisible" + ></Userdetail> + </div> + </div> + </div> +</template> + +<style scoped lang="scss"> +@import "../../assets/tooltip.scss"; + +.addbutton { + position: absolute; + bottom: $offset; + right: $offset; +} + +.content { + width: 100%; +} + +.userdetails { + width: 50%; +} +.spacer { + height: 100vh; + margin-left: $offset; +} + +.spacer-collapsed { + min-width: $icon-width + $offset; + transition: $transition-fast; +} + +.spacer-expanded { + min-width: $sidebar-width + $offset; +} + +.main { + height: 100vh; +} + +.icon { + font-size: large; +} + +.userlist { + min-width: 520px; + height: 100%; +} + +.userlistsmall { + width: 100%; +} + +.userlistextended { + width: 100%; +} + +.table { + width: 90% !important; + margin: auto; +} + +.table th { + cursor: pointer; +} + +.table th, +td { + font-size: $smaller; + border-top: 0px !important; + text-align: left; + padding: $small-offset !important; +} + +.table td { + font-size: $smaller; + cursor: pointer; +} + +tr span { + display: flex; +} +</style> + +<script> +/* This is Free Software under GNU Affero General Public License v >= 3.0 + * without warranty, see README.md and license for details. + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * License-Filename: LICENSES/AGPL-3.0.txt + * + * Copyright (C) 2018 by via donau + * – Österreichische Wasserstraßen-Gesellschaft mbH + * Software engineering by Intevation GmbH + * + * Author(s): + * Thomas Junk <thomas.junk@intevation.de> + */ +import Userdetail from "./Userdetail"; +import store from "../../store"; +import { mapGetters, mapState } from "vuex"; +import { displayError } from "../../lib/errors.js"; + +export default { + name: "userview", + data() { + return { + sortCriterion: "user", + pageSize: 10, + currentPage: 1 + }; + }, + components: { + Userdetail + }, + computed: { + ...mapGetters("usermanagement", ["isUserDetailsVisible"]), + ...mapState("application", ["showSidebar"]), + spacerStyle() { + return [ + "spacer", + { + "spacer-expanded": this.showSidebar, + "spacer-collapsed": !this.showSidebar + } + ]; + }, + users() { + let users = [...this.$store.getters["usermanagement/users"]]; + users.sort((a, b) => { + if ( + a[this.sortCriterion].toLowerCase() < + b[this.sortCriterion].toLowerCase() + ) + return -1; + if ( + a[this.sortCriterion].toLowerCase() > + b[this.sortCriterion].toLowerCase() + ) + return 1; + return 0; + }); + const start = (this.currentPage - 1) * this.pageSize; + return users.slice(start, start + this.pageSize); + }, + pages() { + let users = [...this.$store.getters["usermanagement/users"]]; + return Math.ceil(users.length / this.pageSize); + }, + tableStyle() { + return { + table: true, + "table-hover": true, + "table-sm": this.isUserDetailsVisible, + fadeIn: true, + animated: true + }; + }, + userlistStyle() { + return [ + "userlist mt-3 mr-3 shadow-xs", + { + userlistsmall: this.isUserDetailsVisible, + userlistextended: !this.isUserDetailsVisible + } + ]; + } + }, + methods: { + tween() {}, + nextPage() { + if (this.currentPage < this.pages) { + document.querySelector("#datatable").classList.add("fadeOut"); + setTimeout(() => { + document.querySelector("#datatable").classList.remove("fadeOut"); + this.currentPage += 1; + }, 10); + } + return; + }, + prevPage() { + if (this.currentPage > 0) { + document.querySelector("#datatable").classList.add("fadeOut"); + setTimeout(() => { + document.querySelector("#datatable").classList.remove("fadeOut"); + this.currentPage -= 1; + }, 10); + } + return; + }, + sortBy(criterion) { + this.sortCriterion = criterion; + }, + deleteUser(name) { + this.$store + .dispatch("usermanagement/deleteUser", { name: name }) + .then(() => { + this.submitted = false; + this.$store.dispatch("usermanagement/loadUsers").catch(error => { + const { status, data } = error.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data.message || data}` + }); + }); + }) + .catch(error => { + const { status, data } = error.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data.message || data}` + }); + }); + }, + addUser() { + this.$store.commit("usermanagement/clearCurrentUser"); + this.$store.commit("usermanagement/setUserDetailsVisible"); + }, + selectUser(name) { + const user = this.$store.getters["usermanagement/getUserByName"](name); + this.$store.commit("usermanagement/setCurrentUser", user); + }, + roleIcon(role) { + if (role === "sys_admin") return "star"; + if (role === "waterway_admin") return ["fab", "adn"]; + return "user"; + } + }, + beforeRouteEnter(to, from, next) { + store + .dispatch("usermanagement/loadUsers") + .then(next) + .catch(error => { + const { status, data } = error.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data}` + }); + }); + }, + beforeRouteLeave(to, from, next) { + store.commit("usermanagement/clearCurrentUser"); + store.commit("usermanagement/setUserDetailsInvisible"); + next(); + } +}; +</script>