Mercurial > gemma
changeset 2463:8cc3cd1b27f2
client: usermanagement: implemented new table component
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Mon, 04 Mar 2019 15:59:02 +0100 |
parents | 9ae2a2f758bb |
children | bc0f1771497a 9d9c6425db82 |
files | client/src/components/usermanagement/Usermanagement.vue |
diffstat | 1 files changed, 108 insertions(+), 171 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/components/usermanagement/Usermanagement.vue Mon Mar 04 14:50:23 2019 +0100 +++ b/client/src/components/usermanagement/Usermanagement.vue Mon Mar 04 15:59:02 2019 +0100 @@ -5,82 +5,55 @@ <div :class="userlistStyle"> <div class="card shadow-xs"> <UIBoxHeader icon="users-cog" title="Users" /> - <div class="card-body"> - <table id="datatable" :class="tableStyle"> - <thead> - <tr> - <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" @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"></th> - </tr> - </thead> - <transition-group name="fade" tag="tbody"> - <tr v-for="user in users" :key="user.user"> - <td @click="selectUser(user.user)"> - <font-awesome-icon - v-tooltip="roleLabel(user.role)" - :icon="roleIcon(user.role)" - class="fa-lg" - ></font-awesome-icon> - </td> - <td @click="selectUser(user.user)">{{ user.user }}</td> - <td @click="selectUser(user.user)">{{ user.country }}</td> - <td @click="selectUser(user.user)">{{ user.email }}</td> - <td class="text-right"> - <button - @click="sendTestMail(user.user)" - class="btn btn-sm btn-dark mr-1" - v-tooltip="$gettext('Send testmail')" - 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="$gettext('Delete user')" - > - <font-awesome-icon icon="trash" /> - </button> - </td> - </tr> - </transition-group> - </table> - </div> + <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="$gettext('Send testmail')" + 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="$gettext('Delete user')" + > + <font-awesome-icon icon="trash" /> + </button> + </div> + </UITableBody> <div class="d-flex mx-auto align-items-center"> <button @click="prevPage" @@ -110,70 +83,44 @@ </div> </template> -<style lang="scss" scoped> -.addbutton { - position: absolute; - bottom: $offset; - right: $offset; -} +<style lang="sass" scoped> +.addbutton + position: absolute + bottom: $offset + right: $offset -.content { - width: 100%; -} - -.userdetails { - width: 50%; -} +.content + width: 100% -.main { - height: 100%; -} - -.icon { - font-size: large; -} +.userdetails + width: 50% -.userlist { - min-width: 520px; - height: 100%; -} +.main + height: 100% -.userlistsmall { - width: 100%; -} +.icon + font-size: large -.userlistextended { - width: 100%; -} - -.table { - margin: auto; -} +.userlist + min-width: 520px + height: 100% -.table th { - cursor: pointer; -} +.userlistsmall + width: 100% -.table th:first-child { - width: 50px; -} +.userlistextended + width: 100% -.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; -} +.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> @@ -205,11 +152,10 @@ name: "userview", data() { return { - sortCriterion: "user", - pageSize: 20, - currentPage: 1, - userToDelete: "", - showDeleteUserPrompt: false + sortColumn: "user", + sortDirection: "ASC", + pageSize: 15, + currentPage: 1 }; }, components: { @@ -217,29 +163,30 @@ Spacer: () => import("@/components/Spacer") }, computed: { - ...mapGetters("usermanagement", ["isUserDetailsVisible"]), + ...mapGetters("usermanagement", [ + "isUserDetailsVisible", + "users", + "currentUser" + ]), ...mapState("application", ["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; - }); + sortedUsers() { const start = (this.currentPage - 1) * this.pageSize; - return users.slice(start, start + this.pageSize); + return this.users + .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() { - let users = [...this.$store.getters["usermanagement/users"]]; - return Math.ceil(users.length / this.pageSize); + return Math.ceil(this.users.length / this.pageSize); }, tableStyle() { return { @@ -282,29 +229,19 @@ }); }); }, - tween() {}, nextPage() { if (this.currentPage < this.pages) { - document.querySelector("#datatable").classList.add("fadeOut"); - setTimeout(() => { - document.querySelector("#datatable").classList.remove("fadeOut"); - this.currentPage += 1; - }, 10); + this.currentPage += 1; } - return; }, prevPage() { if (this.currentPage > 0) { - document.querySelector("#datatable").classList.add("fadeOut"); - setTimeout(() => { - document.querySelector("#datatable").classList.remove("fadeOut"); - this.currentPage -= 1; - }, 10); + this.currentPage -= 1; } - return; }, - sortBy(criterion) { - this.sortCriterion = criterion; + sortBy(sorting) { + this.sortColumn = sorting.sortColumn; + this.sortDirection = sorting.sortDirection; }, deleteUser(name) { this.$store.commit("application/popup", {