feat: delete a user
This commit is contained in:
parent
3b347f262c
commit
f09f1f4f1e
@ -57,7 +57,8 @@
|
|||||||
prepend-icon='mdi-account-group'
|
prepend-icon='mdi-account-group'
|
||||||
v-model='group'
|
v-model='group'
|
||||||
label='Assign to Group(s)...'
|
label='Assign to Group(s)...'
|
||||||
dense
|
hint='Note that you cannot assign users to the Administrators or Guests groups from this dialog.'
|
||||||
|
persistent-hint
|
||||||
clearable
|
clearable
|
||||||
multiple
|
multiple
|
||||||
)
|
)
|
||||||
|
@ -23,23 +23,30 @@
|
|||||||
v-spacer
|
v-spacer
|
||||||
i18next.caption.grey--text.animated.fadeInRight.wait-p5s(path='admin:users.id', tag='div')
|
i18next.caption.grey--text.animated.fadeInRight.wait-p5s(path='admin:users.id', tag='div')
|
||||||
strong(place='id') {{user.id}}
|
strong(place='id') {{user.id}}
|
||||||
v-divider.animated.fadeInRight.wait-p3s.ml-3(vertical)
|
v-divider.animated.fadeInRight.wait-p4s.ml-3(vertical)
|
||||||
v-btn.ml-3.animated.fadeInDown.wait-p2s(color='grey', large, outlined, to='/users')
|
v-btn.ml-3.animated.fadeInDown.wait-p3s(color='grey', large, outlined, to='/users')
|
||||||
v-icon mdi-arrow-left
|
v-icon mdi-arrow-left
|
||||||
v-dialog(v-model='deleteUserDialog', max-width='500', v-if='user.id !== currentUserId && !user.isSystem')
|
v-menu(offset-y, origin='top right')
|
||||||
template(v-slot:activator='{ on }')
|
template(v-slot:activator='{ on }')
|
||||||
v-btn.ml-3.animated.fadeInDown.wait-p1s(color='red', large, outlined, v-on='on', disabled)
|
v-btn.ml-3.animated.fadeInDown.wait-p2s(color='indigo', v-on='on', large, depressed, dark)
|
||||||
v-icon(color='red') mdi-trash-can-outline
|
span Actions
|
||||||
v-card
|
v-icon(right) mdi-chevron-down
|
||||||
.dialog-header.is-red Delete User?
|
v-list(dense, nav)
|
||||||
v-card-text Are you sure you want to delete user #[strong {{ user.name }}]?
|
v-list-item(v-if='!user.isActive', @click='activateUser')
|
||||||
v-card-actions
|
v-list-item-icon
|
||||||
v-spacer
|
v-icon(color='purple') mdi-steering
|
||||||
v-btn(text, @click='deleteUserDialog = false') Cancel
|
v-list-item-title Activate
|
||||||
v-btn(color='red', dark, @click='deleteUser') Delete
|
v-list-item(v-else, @click='deactivateUser', :disabled='user.id == currentUserId || user.isSystem')
|
||||||
|
v-list-item-icon
|
||||||
|
v-icon(color='purple') mdi-cancel
|
||||||
|
v-list-item-title Deactivate
|
||||||
|
v-list-item(@click='deleteUserDialog = true', :disabled='user.id == currentUserId || user.isSystem')
|
||||||
|
v-list-item-icon
|
||||||
|
v-icon(color='red') mdi-trash-can-outline
|
||||||
|
v-list-item-title Delete
|
||||||
v-btn.ml-3.animated.fadeInDown(color='primary', large, depressed, @click='updateUser')
|
v-btn.ml-3.animated.fadeInDown(color='primary', large, depressed, @click='updateUser')
|
||||||
v-icon(left) mdi-check
|
v-icon(left) mdi-check
|
||||||
span Update User
|
span {{$t('admin:users.updateUser')}}
|
||||||
v-flex(xs6)
|
v-flex(xs6)
|
||||||
v-card.animated.fadeInUp
|
v-card.animated.fadeInUp
|
||||||
v-toolbar(color='primary', dense, dark, flat)
|
v-toolbar(color='primary', dense, dark, flat)
|
||||||
@ -208,7 +215,6 @@
|
|||||||
item-disabled='isSystem'
|
item-disabled='isSystem'
|
||||||
solo
|
solo
|
||||||
flat
|
flat
|
||||||
dense
|
|
||||||
hide-details
|
hide-details
|
||||||
@keydown.esc='editPop.assignGroup = false'
|
@keydown.esc='editPop.assignGroup = false'
|
||||||
style='max-width: 300px;'
|
style='max-width: 300px;'
|
||||||
@ -216,6 +222,10 @@
|
|||||||
v-btn.ml-2.px-4(depressed, color='primary', height='48', @click='assignGroup', :disabled='newGroup === 0')
|
v-btn.ml-2.px-4(depressed, color='primary', height='48', @click='assignGroup', :disabled='newGroup === 0')
|
||||||
v-icon(left) mdi-clipboard-account-outline
|
v-icon(left) mdi-clipboard-account-outline
|
||||||
span {{$t('admin:users.groupAssign')}}
|
span {{$t('admin:users.groupAssign')}}
|
||||||
|
v-system-bar(window, :color='$vuetify.theme.dark ? `grey darken-4-l3` : `grey lighten-3`')
|
||||||
|
v-spacer
|
||||||
|
.caption {{$t('admin:users.groupAssignNotice')}}
|
||||||
|
|
||||||
v-flex(xs6)
|
v-flex(xs6)
|
||||||
v-card.animated.fadeInUp.wait-p2s
|
v-card.animated.fadeInUp.wait-p2s
|
||||||
v-toolbar(color='primary', dense, dark, flat)
|
v-toolbar(color='primary', dense, dark, flat)
|
||||||
@ -317,6 +327,18 @@
|
|||||||
v-card-text
|
v-card-text
|
||||||
em.caption.grey--text Coming soon
|
em.caption.grey--text Coming soon
|
||||||
|
|
||||||
|
v-dialog(v-model='deleteUserDialog', max-width='500')
|
||||||
|
v-card
|
||||||
|
.dialog-header.is-red {{$t('admin:users.deleteConfirmTitle')}}
|
||||||
|
v-card-text.pt-5
|
||||||
|
i18next(path='admin:users.deleteConfirmText', tag='span')
|
||||||
|
strong(place='username') {{ user.email }}
|
||||||
|
.caption.mt-3 {{$t('admin:users.deleteConfirmForeignNotice')}}
|
||||||
|
v-card-actions
|
||||||
|
v-spacer
|
||||||
|
v-btn(text, @click='deleteUserDialog = false') {{$t('common:actions.cancel')}}
|
||||||
|
v-btn(color='red', dark, @click='deleteUser') {{$t('common:actions.delete')}}
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
@ -327,6 +349,7 @@ import { StatusIndicator } from 'vue-status-indicator'
|
|||||||
import userQuery from 'gql/admin/users/users-query-single.gql'
|
import userQuery from 'gql/admin/users/users-query-single.gql'
|
||||||
import groupsQuery from 'gql/admin/users/users-query-groups.gql'
|
import groupsQuery from 'gql/admin/users/users-query-groups.gql'
|
||||||
import updateUserMutation from 'gql/admin/users/users-mutation-update.gql'
|
import updateUserMutation from 'gql/admin/users/users-mutation-update.gql'
|
||||||
|
import deleteUserMutation from 'gql/admin/users/users-mutation-delete.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -615,7 +638,41 @@ export default {
|
|||||||
currentUserId: get('user/id')
|
currentUserId: get('user/id')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
deleteUser() {},
|
async activateUser () {
|
||||||
|
|
||||||
|
},
|
||||||
|
async deactivateUser () {
|
||||||
|
this.$store.commit('showNotification', {
|
||||||
|
style: 'indigo',
|
||||||
|
message: `Coming soon...`,
|
||||||
|
icon: 'directions_boat'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async deleteUser () {
|
||||||
|
this.$store.commit(`loadingStart`, 'admin-users-delete')
|
||||||
|
const resp = await this.$apollo.mutate({
|
||||||
|
mutation: deleteUserMutation,
|
||||||
|
variables: {
|
||||||
|
id: this.user.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (_.get(resp, 'data.users.delete.responseResult.succeeded', false)) {
|
||||||
|
this.$store.commit('showNotification', {
|
||||||
|
style: 'success',
|
||||||
|
message: this.$t('admin:users.userDeleteSuccess'),
|
||||||
|
icon: 'check'
|
||||||
|
})
|
||||||
|
this.$router.push('/users')
|
||||||
|
} else {
|
||||||
|
this.$store.commit('showNotification', {
|
||||||
|
style: 'red',
|
||||||
|
message: _.get(resp, 'data.users.delete.responseResult.message', 'An unexpected error occured.'),
|
||||||
|
icon: 'warning'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.deleteUserDialog = false
|
||||||
|
this.$store.commit(`loadingStop`, 'admin-users-delete')
|
||||||
|
},
|
||||||
async updateUser() {
|
async updateUser() {
|
||||||
this.$store.commit(`loadingStart`, 'admin-users-update')
|
this.$store.commit(`loadingStart`, 'admin-users-update')
|
||||||
const resp = await this.$apollo.mutate({
|
const resp = await this.$apollo.mutate({
|
||||||
|
12
client/graph/admin/users/users-mutation-delete.gql
Normal file
12
client/graph/admin/users/users-mutation-delete.gql
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
mutation ($id: Int!) {
|
||||||
|
users {
|
||||||
|
delete(id: $id) {
|
||||||
|
responseResult {
|
||||||
|
succeeded
|
||||||
|
errorCode
|
||||||
|
slug
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
UserMutation: {
|
UserMutation: {
|
||||||
async create(obj, args) {
|
async create (obj, args) {
|
||||||
try {
|
try {
|
||||||
await WIKI.models.users.createNewUser(args)
|
await WIKI.models.users.createNewUser(args)
|
||||||
|
|
||||||
@ -40,10 +40,24 @@ module.exports = {
|
|||||||
return graphHelper.generateError(err)
|
return graphHelper.generateError(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
delete(obj, args) {
|
async delete (obj, args) {
|
||||||
return WIKI.models.users.query().deleteById(args.id)
|
try {
|
||||||
|
if (args.id <= 2) {
|
||||||
|
throw new WIKI.Error.UserDeleteProtected()
|
||||||
|
}
|
||||||
|
await WIKI.models.users.query().deleteById(args.id)
|
||||||
|
return {
|
||||||
|
responseResult: graphHelper.generateSuccess('User deleted successfully')
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.message.indexOf('foreign') >= 0) {
|
||||||
|
return graphHelper.generateError(new WIKI.Error.UserDeleteForeignConstraint())
|
||||||
|
} else {
|
||||||
|
return graphHelper.generateError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async update(obj, args) {
|
async update (obj, args) {
|
||||||
try {
|
try {
|
||||||
await WIKI.models.users.updateUser(args)
|
await WIKI.models.users.updateUser(args)
|
||||||
|
|
||||||
@ -54,7 +68,7 @@ module.exports = {
|
|||||||
return graphHelper.generateError(err)
|
return graphHelper.generateError(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resetPassword(obj, args) {
|
resetPassword (obj, args) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -169,6 +169,14 @@ module.exports = {
|
|||||||
message: 'An unexpected error occured during user creation.',
|
message: 'An unexpected error occured during user creation.',
|
||||||
code: 1009
|
code: 1009
|
||||||
}),
|
}),
|
||||||
|
UserDeleteForeignConstraint: CustomError('UserCreationFailed', {
|
||||||
|
message: 'Cannot delete user because of content relational constraints.',
|
||||||
|
code: 1017
|
||||||
|
}),
|
||||||
|
UserDeleteProtected: CustomError('UserDeleteProtected', {
|
||||||
|
message: 'Cannot delete a protected system account.',
|
||||||
|
code: 1018
|
||||||
|
}),
|
||||||
UserNotFound: CustomError('UserNotFound', {
|
UserNotFound: CustomError('UserNotFound', {
|
||||||
message: 'This user does not exist.',
|
message: 'This user does not exist.',
|
||||||
code: 1016
|
code: 1016
|
||||||
|
8
server/modules/rendering/openapi-core/definition.yml
Normal file
8
server/modules/rendering/openapi-core/definition.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
key: openapiCore
|
||||||
|
title: Core
|
||||||
|
description: Basic OpenAPI Parser
|
||||||
|
author: requarks.io
|
||||||
|
input: openapi
|
||||||
|
output: html
|
||||||
|
icon: mdi-api
|
||||||
|
props: {}
|
14
server/modules/rendering/openapi-core/renderer.js
Normal file
14
server/modules/rendering/openapi-core/renderer.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
const _ = require('lodash')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async render() {
|
||||||
|
let output = this.input
|
||||||
|
|
||||||
|
for (let child of this.children) {
|
||||||
|
const renderer = require(`../${_.kebabCase(child.key)}/renderer.js`)
|
||||||
|
output = await renderer.init(output, child.config)
|
||||||
|
}
|
||||||
|
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user