mirror of
https://github.com/gotson/komga.git
synced 2026-05-09 05:10:19 +02:00
delete user
This commit is contained in:
parent
84d25f1cb1
commit
b5b4562b1d
5 changed files with 144 additions and 4 deletions
|
|
@ -33,3 +33,19 @@ export const useUpdateUserPassword = defineMutation(() => {
|
|||
},
|
||||
})
|
||||
})
|
||||
|
||||
export const useDeleteUser = defineMutation(() => {
|
||||
const queryCache = useQueryCache()
|
||||
return useMutation({
|
||||
mutation: (userId: string) =>
|
||||
komgaClient.DELETE('/api/v2/users/{id}', {
|
||||
params: {path: {id: userId}},
|
||||
}),
|
||||
onSuccess: () => {
|
||||
void queryCache.invalidateQueries({key: ['users']})
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log('delete user error', error)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
|
|
|||
1
next-ui/src/components.d.ts
vendored
1
next-ui/src/components.d.ts
vendored
|
|
@ -21,6 +21,7 @@ declare module 'vue' {
|
|||
AppFooter: typeof import('./components/AppFooter.vue')['default']
|
||||
BuildCommit: typeof import('./components/BuildCommit.vue')['default']
|
||||
BuildVersion: typeof import('./components/BuildVersion.vue')['default']
|
||||
DialogConfirm: typeof import('./components/dialogs/DialogConfirm.vue')['default']
|
||||
DialogConfirmEdit: typeof import('./components/dialogs/DialogConfirmEdit.vue')['default']
|
||||
FormUserChangePassword: typeof import('./components/forms/user/FormUserChangePassword.vue')['default']
|
||||
FormUserRoles: typeof import('./components/forms/user/FormUserRoles.vue')['default']
|
||||
|
|
|
|||
89
next-ui/src/components/dialogs/DialogConfirm.vue
Normal file
89
next-ui/src/components/dialogs/DialogConfirm.vue
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
<template>
|
||||
<v-dialog
|
||||
v-model="showDialog"
|
||||
:activator="activator"
|
||||
:max-width="maxWidth"
|
||||
>
|
||||
<v-form
|
||||
v-model="formValid"
|
||||
@submit.prevent="submitForm()"
|
||||
>
|
||||
<v-card
|
||||
:title="title"
|
||||
:subtitle="subtitle"
|
||||
>
|
||||
<template #text>
|
||||
<slot name="warning" />
|
||||
<slot name="text">
|
||||
Please type <span class="font-weight-bold">{{ validateText }}</span> to confirm.
|
||||
</slot>
|
||||
|
||||
<v-text-field
|
||||
:rules="[rules.sameAs(validateText)]"
|
||||
hide-details
|
||||
class="mt-2"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
text="Cancel"
|
||||
@click="close()"
|
||||
/>
|
||||
<v-btn
|
||||
:disabled="!formValid"
|
||||
:text="okText"
|
||||
type="submit"
|
||||
variant="elevated"
|
||||
rounded="xs"
|
||||
color="error"
|
||||
/>
|
||||
</template>
|
||||
</v-card>
|
||||
</v-form>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {useRules} from 'vuetify/labs/rules'
|
||||
|
||||
const showDialog = defineModel<boolean>('dialog', {required: false})
|
||||
const emit = defineEmits<{
|
||||
confirm: []
|
||||
}>()
|
||||
|
||||
const formValid = ref<boolean>(false)
|
||||
|
||||
const rules = useRules()
|
||||
|
||||
function submitForm() {
|
||||
if(formValid.value) {
|
||||
emit('confirm')
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
title?: string,
|
||||
subtitle?: string,
|
||||
okText?: string,
|
||||
validateText?: string,
|
||||
maxWidth?: string | number,
|
||||
activator?: Element | string,
|
||||
}
|
||||
|
||||
const {
|
||||
title = undefined,
|
||||
subtitle = undefined,
|
||||
okText = 'Confirm',
|
||||
validateText = 'confirm',
|
||||
maxWidth = undefined,
|
||||
activator = undefined,
|
||||
} = defineProps<Props>()
|
||||
|
||||
function close() {
|
||||
showDialog.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -47,6 +47,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
/** Dialog super component de la race*/
|
||||
const showDialog = defineModel<boolean>('dialog', {required: false})
|
||||
const record = defineModel<unknown>('record', {required: true})
|
||||
|
||||
|
|
@ -56,7 +57,11 @@ function submitForm(callback: () => void) {
|
|||
if(formValid.value) callback()
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
interface Props {
|
||||
/**
|
||||
* Dialog title
|
||||
* @type string
|
||||
*/
|
||||
title?: string,
|
||||
subtitle?: string,
|
||||
maxWidth?: string | number,
|
||||
|
|
@ -74,4 +79,3 @@ function close() {
|
|||
showDialog.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
icon="mdi-delete"
|
||||
:disabled="me?.id == user.id"
|
||||
@click="showDialog(ACTION.DELETE, user)"
|
||||
@mouseenter="activator = $event.currentTarget"
|
||||
@mouseenter="activatorDelete = $event.currentTarget"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -75,6 +75,33 @@
|
|||
/>
|
||||
</template>
|
||||
</DialogConfirmEdit>
|
||||
|
||||
<DialogConfirm
|
||||
:activator="activatorDelete"
|
||||
:title="dialogTitle"
|
||||
:subtitle="userRecord?.email"
|
||||
ok-text="Delete"
|
||||
:validate-text="userRecord?.email"
|
||||
max-width="600"
|
||||
@confirm="handleDialogConfirmation()"
|
||||
>
|
||||
<template #warning>
|
||||
<v-alert
|
||||
type="warning"
|
||||
variant="tonal"
|
||||
class="mb-4"
|
||||
>
|
||||
<div>The user account will be deleted from this server.</div>
|
||||
<ul class="ps-8">
|
||||
<li>The read progress for this user account will be permanently deleted.</li>
|
||||
<li>Authentication activity for this user will be permanently deleted.</li>
|
||||
</ul>
|
||||
<div class="font-weight-bold mt-4">
|
||||
This action cannot be undone.
|
||||
</div>
|
||||
</v-alert>
|
||||
</template>
|
||||
</DialogConfirm>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
|
@ -84,7 +111,7 @@ import {komgaClient} from '@/api/komga-client.ts'
|
|||
import type {components} from '@/generated/openapi/komga'
|
||||
import {useCurrentUser} from '@/colada/queries/current-user.ts'
|
||||
import {UserRoles} from '@/types/UserRoles.ts'
|
||||
import {useUpdateUser, useUpdateUserPassword} from '@/colada/mutations/update-user.ts'
|
||||
import {useDeleteUser, useUpdateUser, useUpdateUserPassword} from '@/colada/mutations/update-user.ts'
|
||||
import FormUserChangePassword from '@/components/forms/user/FormUserChangePassword.vue'
|
||||
import FormUserRoles from '@/components/forms/user/FormUserRoles.vue'
|
||||
import type {Component} from 'vue'
|
||||
|
|
@ -140,12 +167,14 @@ const currentAction = ref<ACTION>()
|
|||
// the record passed to the dialog's form's model
|
||||
const dialogRecord = ref<unknown>()
|
||||
const activator = ref<Element>()
|
||||
const activatorDelete = ref<Element>()
|
||||
const dialogTitle = ref<string>()
|
||||
// dynamic component for the dialog's inner form
|
||||
const dialogComponent = shallowRef<Component>()
|
||||
|
||||
const {mutate: mutateUser} = useUpdateUser()
|
||||
const {mutate: mutateUserPassword} = useUpdateUserPassword()
|
||||
const {mutate: mutateDeleteUser} = useDeleteUser()
|
||||
|
||||
enum ACTION {
|
||||
EDIT, DELETE, RESTRICTIONS, PASSWORD
|
||||
|
|
@ -184,6 +213,7 @@ function handleDialogConfirmation() {
|
|||
mutateUser(dialogRecord.value as components["schemas"]["UserDto"])
|
||||
break;
|
||||
case ACTION.DELETE:
|
||||
mutateDeleteUser(userRecord.value!.id)
|
||||
break;
|
||||
case ACTION.RESTRICTIONS:
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in a new issue