diff --git a/cms/src/extensions/users-permissions/strapi-server.js b/cms/src/extensions/users-permissions/strapi-server.js index 4fd052cc6c8439768efac0bde52fabd58d7ba149..b8a11449627de1e36b1c48105400fa5b4e324ff9 100644 --- a/cms/src/extensions/users-permissions/strapi-server.js +++ b/cms/src/extensions/users-permissions/strapi-server.js @@ -25,5 +25,15 @@ module.exports = (plugin) => { ctx.body = data; }; + plugin.controllers.user.find = async (ctx) => { + let data = await getService('user').fetchAll({}, ['role']); + + if (data) { + data = await sanitizeOutput(data, ctx); + } + + ctx.body = data; + }; + return plugin; }; diff --git a/web/src/components/UserTable.vue b/web/src/components/UserTable.vue index 8943b6359dd4d23c9fdaa6bd35b34c3e1f6630fc..8b6afef1bd5d9ff0c974f5a8852cd8f4bae436cf 100644 --- a/web/src/components/UserTable.vue +++ b/web/src/components/UserTable.vue @@ -60,28 +60,44 @@ export default { data: 'current_affiliation', }, { - title: 'Profile Link', - data: 'profile_link', - }, - { - title: 'Current Role', + title: 'Current Role/Link', data: 'current_role', + fnCreatedCell: (nTd, sData, oData) => { + $(nTd).html(`${oData.current_role}<br><a class="extern-link" href="${oData.profile_link}">${oData.profile_link}</a>`); + }, }, { - title: 'Motivation', - data: 'motivation_text', + title: 'Role', + data: 'role.name', }, { - title: 'Joined', + title: 'Joined/Updated', data: 'createdAt', + fnCreatedCell: (nTd, sData, oData) => { + $(nTd).html(`${oData.createdAt.split('T')[0]} (J)<br>${oData.updatedAt.split('T')[0]} (U)`); + }, }, { - title: 'Updated', - data: 'updatedAt', - }, - { - title: 'Status', + title: 'Confirmed', data: 'confirmed', + fnCreatedCell: (nTd, sData, oData) => { + if(sData && oData.role.name === 'Authenticated') { + $(nTd).html(`<button class="rounded-md bg-transparent hover:bg-blue-500 text-blue-700 + hover:text-white + border border-blue-500 + hover:border-transparent + focus:ring-2 focus:ring-blue-300 + items-center + px-4 + py-2 + text-center + edit-link"> + Approve + </button>`); + } else { + $(nTd).html(`${sData}`); + } + }, }, ]; @@ -120,12 +136,22 @@ export default { const row = table.row(tr); vm.editUser(row.data().id); }); + + $(tableBody).on('click', 'tr td button.edit-link', (e) => { + e.preventDefault(); + + const tr = $(e.target).parent().parent(); + const row = table.row(tr); + const dat = row.data(); + + vm.$emit('approve', dat) + }); }, }, }; </script> -<style scoped> +<style> @import url("~@/assets/datatable.css"); select.form-control { @@ -148,6 +174,11 @@ ul.pagination { color: #549bb0; } +.extern-link { + font-weight: bold; + color: #395384; +} + .pagination { font-size: 1.2rem; } diff --git a/web/src/components/js/const.js b/web/src/components/js/const.js index 7c333b3a672180089c300f4f6975a3415cfc60a9..2a5e6c44e0936451b5ece7c5746cfded09f359eb 100644 --- a/web/src/components/js/const.js +++ b/web/src/components/js/const.js @@ -8,5 +8,8 @@ export const devApiHost = '/cms'; // export const apiHost = 'http://localhost:1337'; // export const devApiHost = 'http://localhost:1337'; -// apikey should be give here: +// apikey should be given here: export const apikey = process.env.VUE_APP_API_KEY; + +// wiki apikey should be given here: +export const wikiApikey = process.env.VUE_APP_WIKI_KEY; diff --git a/web/src/views/Profile.vue b/web/src/views/Profile.vue index e5f47de45a4d22cfcbe84b08450a57c5c1be2e1e..536b83287c628af0840f9b2c535a8313017ee17c 100644 --- a/web/src/views/Profile.vue +++ b/web/src/views/Profile.vue @@ -14,7 +14,7 @@ size="lg" /> - <h4>Profile update successful!</h4> + <h4>{{toasterMessage}}</h4> <button class="btn btn-outline" @click="hideDialog" @@ -452,7 +452,7 @@ </template> </fetch-profile> - <fetch-users v-if="getRole === 'Administrator'"> + <fetch-users v-if="getRole === 'Administrator'" :key="'users-' + updatedUsersKey"> <template slot-scope="{ response, loading }"> <slot :response="response" @@ -466,6 +466,7 @@ <user-table id="usersTable" :data="response" + @approve="approve" /> </div> </slot> @@ -512,6 +513,7 @@ export default { isDev: process.env.NODE_ENV === 'development', editMode: false, toasterIsOpen: false, + toasterMessage: 'Profile update successful!', error: false, scientificDisciplineOptions: [ { id: '1', discipline: 'Physics' }, @@ -530,6 +532,7 @@ export default { passwordErrMsg: '', errorMsg: '', updatedKey: 0, + updatedUsersKey: 0, }; }, computed: { @@ -590,6 +593,7 @@ export default { this.showChangePassword = true; }, showDialog() { + this.toasterMessage = 'Profile update successful!'; this.toasterIsOpen = true; }, hideDialog() { @@ -698,6 +702,7 @@ export default { // console.log(res.data); this.error = false; + this.toasterMessage = 'Profile update successful!'; this.toasterIsOpen = true; this.editMode = false; this.isOpen = false; @@ -715,6 +720,77 @@ export default { this.errorMsg = error; } }, + async approve(e) { + const vm = this + + try { + vm.user = e.id; + + if (vm.isDev) { + host = require('@/components/js/const').devApiHost; + } + + let jwt = vm.jwt; + if (jwt === null) { + vm.loaded = false; + return; + } + + const dat = { + id: vm.user, + role: 3, // Make the user contributor + }; + + let res = await this.axios.put(`${host}/api/users/${vm.user}`, dat, { + headers: { + Authorization: `Bearer ${jwt}`, + }, + }); + + jwt = require('@/components/js/const').wikiApikey; + + const query = `mutation User { + users { + create (email: "${e.email}", + name: "${e.full_name}", + passwordRaw: "welcome2cdcode", + providerKey: "local", + groups: 3, + mustChangePassword: true, + sendWelcomeEmail: true) { + responseResult { + succeeded, + errorCode, + slug, + message + }, + user { + email, + name + } + } + } + }` + + res = await this.axios.post(`https://wiki.cd-code.org/graphql`, { query }, { + headers: { + Authorization: `Bearer ${jwt}`, + }, + }); + + vm.error = false; + vm.toasterMessage = 'Approved and a welcome email sent!'; + vm.toasterIsOpen = true; + setTimeout(() => { + vm.toasterIsOpen = false; + }, 2000); + + vm.updatedUsersKey += 1; + } catch (error) { + this.error = true; + this.errorMsg = error; + } + } }, }; </script>