Mercurial > gemma
view client/src/components/usermanagement/Usermanagement.vue @ 2624:9dbaf69c7a66
Improve geoserver config to better calculate bounding boxes
* Disable the use of estimated extents for the postgis storage
configuration for geoserver, which is set via the gemma middleware.
This way we are able to get better bounding boxes for many layers
where the postgis function `ST_EstimatedExtent()` would be far off.
author | Bernhard Reiter <bernhard@intevation.de> |
---|---|
date | Wed, 13 Mar 2019 16:18:39 +0100 |
parents | dda4cec8e67b |
children | 4bcb26542767 |
line wrap: on
line source
<template> <div class="main d-flex flex-row" style="position: relative;"> <Spacer></Spacer> <div class="d-flex content py-2"> <div :class="userlistStyle"> <div class="card shadow-xs"> <UIBoxHeader icon="users-cog" title="Users" /> <UITableHeader :columns="[ { id: 'role', title: 'Role', class: 'col-1' }, { id: 'user', title: 'Username', class: 'col-3' }, { id: 'country', title: 'Country', class: 'col-2' }, { id: 'email', title: 'Email', class: 'col-3' } ]" @sortingChanged="sortBy" /> <UITableBody :data="sortedUsers" maxHeight="47rem" :active="currentUser" v-slot="{ item: user }" > <div class="py-2 col-1" @click="selectUser(user.user)"> <font-awesome-icon v-tooltip="roleLabel(user.role)" :icon="roleIcon(user.role)" class="fa-lg" ></font-awesome-icon> </div> <div class="py-2 col-3" @click="selectUser(user.user)"> {{ user.user }} </div> <div class="py-2 col-2" @click="selectUser(user.user)"> {{ user.country }} </div> <div class="py-2 col-3" @click="selectUser(user.user)"> {{ user.email }} </div> <div class="py-2 col text-right"> <button @click="sendTestMail(user.user)" class="btn btn-sm btn-dark mr-1" v-tooltip="sendMailLabel" v-if="user.email" > <font-awesome-icon icon="paper-plane"></font-awesome-icon> </button> <button @click="deleteUser(user.user)" class="btn btn-sm btn-dark" v-tooltip="deleteUserLabel" > <font-awesome-icon icon="trash" /> </button> </div> </UITableBody> <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 py-3 text-right"> <button @click="addUser" class="btn btn-info addbutton shadow-sm"> <translate>Add User</translate> </button> </div> </div> </div> <Userdetail v-if="isUserDetailsVisible"></Userdetail> </div> </div> </template> <style lang="sass" scoped> .addbutton position: absolute bottom: $offset right: $offset .content width: 100% .userdetails width: 50% .main height: 100% .icon font-size: large .userlist min-width: 520px height: 100% .userlistsmall width: 100% .userlistextended width: 100% .table-body .row > div transition: background-color 0.3s, color 0.3s &.active > div background-color: $color-info color: #fff a color: #fff !important </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 store from "@/store"; import { mapGetters, mapState } from "vuex"; import { displayError, displayInfo } from "@/lib/errors.js"; import { HTTP } from "@/lib/http"; import Vue from "vue"; import { VTooltip, VPopover, VClosePopover } from "v-tooltip"; Vue.directive("tooltip", VTooltip); Vue.directive("close-popover", VClosePopover); Vue.component("v-popover", VPopover); export default { name: "userview", data() { return { sortColumn: "user", sortDirection: "ASC", pageSize: 15, currentPage: 1 }; }, components: { Userdetail: () => import("./Userdetail"), Spacer: () => import("@/components/Spacer") }, computed: { ...mapGetters("usermanagement", [ "isUserDetailsVisible", "users", "currentUser" ]), ...mapState("application", ["showSidebar"]), sendMailLabel() { return this.$gettext("Send testmail"); }, deleteUserLabel() { return this.$gettext("Delete user"); }, sortedUsers() { const start = (this.currentPage - 1) * this.pageSize; return this.users .filter(u => u) // to clone the array and leave the original store value intact .sort((a, b) => { if ( a[this.sortColumn].toLowerCase() < b[this.sortColumn].toLowerCase() ) return this.sortDirection === "ASC" ? -1 : 1; if ( a[this.sortColumn].toLowerCase() > b[this.sortColumn].toLowerCase() ) return this.sortDirection === "ASC" ? 1 : -1; return 0; }) .slice(start, start + this.pageSize); }, pages() { return Math.ceil(this.users.length / this.pageSize); }, tableStyle() { return { table: true, "table-hover": true, "table-sm": this.isUserDetailsVisible, fadeIn: true, animated: true }; }, userlistStyle() { return [ "userlist mr-2", { userlistsmall: this.isUserDetailsVisible, userlistextended: !this.isUserDetailsVisible } ]; } }, methods: { sendTestMail(user) { HTTP.get("/testmail/" + user, { headers: { "X-Gemma-Auth": localStorage.getItem("token"), "Content-type": "text/xml; charset=UTF-8" } }) .then(() => { displayInfo({ message: this.$gettext("Testmail sent") }); }) .catch(error => { this.loginFailed = true; const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); }, nextPage() { if (this.currentPage < this.pages) { this.currentPage += 1; } }, prevPage() { if (this.currentPage > 0) { this.currentPage -= 1; } }, sortBy(sorting) { this.sortColumn = sorting.sortColumn; this.sortDirection = sorting.sortDirection; }, deleteUser(name) { this.$store.commit("application/popup", { icon: "trash", title: this.$gettext("Delete User"), content: this.$gettext( "Do you really want to delete the following user account:" ) + `<br> <b>${name}</b>`, confirm: { label: this.$gettext("Delete"), icon: "trash", callback: () => { this.$store .dispatch("usermanagement/deleteUser", { name }) .then(() => { 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}` }); }); } }, cancel: { label: this.$gettext("Cancel"), icon: "times" } }); }, 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"; }, roleLabel(role) { const labels = { sys_admin: this.$gettext("System-Administrator"), waterway_admin: this.$gettext("Waterway Admin"), waterway_user: this.$gettext("Waterway User") }; return labels[role]; } }, 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>