From beb5a9d68d822471a7859571dc7c09b31ae6f276 Mon Sep 17 00:00:00 2001 From: HongKee Moon <moon@mpi-cbg.de> Date: Wed, 9 Feb 2022 12:04:27 +0100 Subject: [PATCH] Close #50: Add EditUser component --- web/src/components/UserTable.vue | 10 +- web/src/router/index.js | 5 + web/src/views/UpdateUser.vue | 292 +++++++++++++++++++++++++++++++ 3 files changed, 304 insertions(+), 3 deletions(-) create mode 100644 web/src/views/UpdateUser.vue diff --git a/web/src/components/UserTable.vue b/web/src/components/UserTable.vue index d8deebe..8bdfd2a 100644 --- a/web/src/components/UserTable.vue +++ b/web/src/components/UserTable.vue @@ -1,6 +1,6 @@ <template> <div class="flex items-center justify-center panel-table w-full md:w-auto pt-10"> - <table :id=id class="table table-striped table-bordered table-hover" width="100%"></table> + <table :id=id class="table table-striped table-bordered table-hover"></table> </div> </template> @@ -14,7 +14,11 @@ export default { name: 'user-table', props: ['id', 'data'], methods:{ - createTable(id, data) { + editUser(id) { + // eslint-disable-next-line + this.$router.push('/updateuser/' + id) + }, + createTable(id, data) { const vm = this; @@ -92,7 +96,7 @@ export default { e.preventDefault() const tr = $(e.target).parent().parent(); const row = table.row(tr); - // vm.editUpdateItem(row.data().id); + vm.editUser(row.data().id); }); }, }, diff --git a/web/src/router/index.js b/web/src/router/index.js index c185c33..fd5608f 100644 --- a/web/src/router/index.js +++ b/web/src/router/index.js @@ -101,6 +101,11 @@ export default new Router({ name: 'updateItem', component: () => import('@/views/UpdateItem'), }, + { + path: '/updateuser/:user', + name: 'updateUser', + component: () => import('@/views/UpdateUser'), + }, // { path: '/user/:id', component: User }, // { // path: '*', diff --git a/web/src/views/UpdateUser.vue b/web/src/views/UpdateUser.vue new file mode 100644 index 0000000..6520bf2 --- /dev/null +++ b/web/src/views/UpdateUser.vue @@ -0,0 +1,292 @@ +<template> + <div> + <h3 v-show="error" class="flex items-center justify-center text-2xl text-red-500">{{ errorMsg }}</h3> + <div class="flex items-center justify-center"> + <div v-if="loaded" class="md:flex card p-2 mt-5"> + <div class="p-5 mx-auto text-left font-raleway container max-w-screen-md"> + <h1 class="font-bold text-left font-montserrat text-3xl sm:text-5xl mb-7"> + {{ user }} + </h1> + <form @submit="update" class="w-full md:w-auto"> + <div class="md:flex md:items-center mx-3 mb-6"> + <div class="md:w-1/3"> + <label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-entity-type"> + Username + </label> + </div> + <div class="md:w-2/3"> + <p class="mt-3"> + {{username}} + </p> + </div> + </div> + + <div class="md:flex md:items-center mx-3 mb-6"> + <div class="md:w-1/3"> + <label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-entity-id"> + Email + </label> + </div> + <div class="md:w-2/3"> + <p class="mt-3"> + {{email}} + </p> + </div> + </div> + + <div class="md:flex md:items-center mx-3 mb-6"> + <div class="md:w-1/3"> + <label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-change-operation"> + Role + </label> + </div> + <div class="md:w-2/3"> + <select v-model="role" class="bg-white w-full py-2 text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 focus:bg-gray-200 focus:border-blue-700" id="inline-change-operation" > + <option v-for="option in roles" v-bind:key="option.id" :selected="role.name === option.name" :disabled="option.name === 'Administrator' || option.name === 'Public'" v-bind:value="{ id: option.id, name: option.name }"> + {{ option.name }} + </option> + </select> + </div> + </div> + + <div class="md:flex md:items-center mx-3 mb-6"> + <div class="md:w-1/3"> + <label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-status"> + Affiliation + </label> + </div> + <div class="md:w-2/3"> + <p class="mt-3"> + {{Affiliation}} + </p> + </div> + </div> + + <div class="md:flex md:items-center mx-3 mb-6"> + <div class="md:w-1/3"> + <label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-status"> + Profile Link + </label> + </div> + <div class="md:w-2/3"> + <p class="mt-3"> + {{ProfileLink}} + </p> + </div> + </div> + + <div class="md:flex md:items-center mx-3 mb-6"> + <div class="md:w-1/3"> + <label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-status"> + Status + </label> + </div> + <div class="md:w-2/3"> + <p class="mt-3"> + <input type="checkbox" id="confirmed_checkbox" v-model="confirmed" disabled> + <label class="ml-3" for="confirmed_checkbox">Authenticated</label> + </p> + <p class="mt-3"> + <input type="checkbox" id="blocked_checkbox" v-model="blocked"> + <label class="ml-3" for="blocked_checkbox">Blocked</label> + </p> + </div> + </div> + + <button type="submit" :disabled="role.length < 3" class="bg-green-400 p-5 text-white"> + {{ 'Update' }} <span class="fa fa-arrow-right"/> + </button> + + </form> + </div> + </div> + </div> + </div> +</template> +<script> +const _ = require('lodash'); +let host = require('@/components/js/const').apiHost; + +export default { + name: 'UpdateUser', + props: ['userId'], + data() { + return { + user: this.$route.params.user ? this.$route.params.user : this.userId, + username: '', + email: '', + preRole: '', + role: {}, + roles: [], + confirmed: false, + blocked: true, + Affiliation: '', + ProfileLink: '', + createdAt: '', // datetime + updatedAt: '', // datetime + loaded: false, + error: false, + errorMsg: `An error occurred, please try again`, + isDev: process.env.NODE_ENV === 'development', + } + }, + computed: { + jwt: function () { + return this.$store.getters['User/jwt'] + }, + userData: function () { + return this.$store.getters['User/userData'] + }, + userRole: function () { + return this.$store.getters['User/userRole'] + }, + }, + methods: { + async update(e) { + e.preventDefault() + + const vm = this; + + if(vm.isDev) { + host = require('@/components/js/const').devApiHost; + } + + const jwt = vm.jwt; + if(jwt === null) { + vm.loaded = false; + return + } + + // Prevent to update the Administrator status + if(vm.preRole === 'Administrator') { + this.error = true + this.errorMsg = `Cannot change the administrator's attributes.` + setTimeout(() => vm.$router.go(-1), 2000); + return + } + + // console.log(vm.role) + + let dat = { + id: vm.user, + role: vm.role.id, + blocked: vm.blocked, + }; + + try { + const res = await this.axios.put(`${host}/api/users/${vm.user}`, dat, { + headers: { + Authorization: `Bearer ${jwt}` + } + }); + + // console.log(res.data) + + vm.$router.push('/profile') + } catch(error) { + // console.log(error.response.data.error.message) + // console.log(error.response) + this.error = true + this.errorMsg = error + } + }, + async preload() { + const vm = this; + + if(vm.isDev) { + host = require('@/components/js/const').devApiHost; + } + + const jwt = vm.jwt; + if(jwt === null) { + vm.loaded = false; + return + } + + // console.log(vm.userData) + + try { + const res = await this.axios.get(`${host}/api/users-permissions/roles`, { + headers: { + Authorization: `Bearer ${jwt}` + } + }); + + if(res.data) { + vm.roles = _.sortBy(_.filter(res.data.roles, o => o.name !== 'Public'), ['name']); + } + } catch(error) { + // console.error(error) + this.error = true + this.errorMsg = "You are not authorized to access this item." + setTimeout(() => vm.$router.go(-1), 2000); + } + }, + async load(id) { + const vm = this; + + if(vm.isDev) { + host = require('@/components/js/const').devApiHost; + } + + const jwt = vm.jwt; + if(jwt === null) { + vm.loaded = false; + return + } + + // console.log(vm.userData) + + try { + const res = await this.axios.get(`${host}/api/users/` + id, { + headers: { + Authorization: `Bearer ${jwt}` + } + }); + + // console.log(res) + + if(res.data) { + const d = res.data; + vm.username = d.username; + vm.email = d.email; + vm.preRole = d.role.name; + vm.role.name = d.role.name; + vm.role.id = d.role.id; + vm.confirmed = d.confirmed; + vm.blocked = d.blocked; + vm.Affiliation = d.Affiliation; + vm.ProfileLink = d.ProfileLink; + vm.createdAt = d.createdAt; + vm.updatedAt = d.updatedAt; + } + + vm.loaded = true; + } catch(error) { + // console.error(error) + this.error = true + this.errorMsg = "You are not authorized to access this item." + setTimeout(() => vm.$router.go(-1), 2000); + } + } + }, + mounted: function () { + const vm = this; + + const jwt = vm.jwt; + if(jwt === null) { + vm.$router.push('/login') + } else { + vm.preload(); + vm.load(vm.user) + } + } +} +</script> +<style> +@import url('~@/assets/bootstrap.css'); + +a { + color: #42b983; +} +</style> \ No newline at end of file -- GitLab