mirror of
https://github.com/gotson/komga.git
synced 2025-12-12 03:24:45 +01:00
user password change form
This commit is contained in:
parent
cffc4fdb20
commit
e79c2ca88b
4 changed files with 85 additions and 35 deletions
|
|
@ -18,3 +18,18 @@ export const useUpdateUser = defineMutation(() => {
|
|||
},
|
||||
})
|
||||
})
|
||||
|
||||
export const useUpdateUserPassword = defineMutation(() => {
|
||||
return useMutation({
|
||||
mutation: ({userId, newPassword}: { userId: string, newPassword: string }) =>
|
||||
komgaClient.PATCH('/api/v2/users/{id}/password', {
|
||||
params: {path: {id: userId}},
|
||||
body: {
|
||||
password: newPassword,
|
||||
},
|
||||
}),
|
||||
onError: (error) => {
|
||||
console.log('update user password error', error)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -10,12 +10,15 @@
|
|||
@save="close()"
|
||||
>
|
||||
<template #default="{ model: proxyModel, cancel, save, isPristine }">
|
||||
<v-card
|
||||
:title="title"
|
||||
:subtitle="subtitle"
|
||||
<v-form
|
||||
v-model="formValid"
|
||||
@submit.prevent="submitForm(save)"
|
||||
>
|
||||
<template #text>
|
||||
<v-form v-model="formValid">
|
||||
<v-card
|
||||
:title="title"
|
||||
:subtitle="subtitle"
|
||||
>
|
||||
<template #text>
|
||||
<slot
|
||||
name="text"
|
||||
:proxy-model="proxyModel"
|
||||
|
|
@ -23,22 +26,21 @@
|
|||
:save="save"
|
||||
:is-pristine="isPristine"
|
||||
/>
|
||||
</v-form>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
text="Cancel"
|
||||
@click="close()"
|
||||
/>
|
||||
<v-btn
|
||||
:disabled="!formValid"
|
||||
text="Save"
|
||||
@click="save"
|
||||
/>
|
||||
</template>
|
||||
</v-card>
|
||||
<template #actions>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
text="Cancel"
|
||||
@click="close()"
|
||||
/>
|
||||
<v-btn
|
||||
text="Save"
|
||||
type="submit"
|
||||
/>
|
||||
</template>
|
||||
</v-card>
|
||||
</v-form>
|
||||
</template>
|
||||
</v-confirm-edit>
|
||||
</v-dialog>
|
||||
|
|
@ -50,6 +52,10 @@ const record = defineModel<unknown>('record', {required: true})
|
|||
|
||||
const formValid = ref<boolean>(false)
|
||||
|
||||
function submitForm(callback: () => void) {
|
||||
if(formValid.value) callback()
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
title?: string,
|
||||
subtitle?: string,
|
||||
|
|
|
|||
|
|
@ -1,17 +1,31 @@
|
|||
<template>
|
||||
<v-text-field :rules="rules" />
|
||||
<v-text-field />
|
||||
<v-text-field
|
||||
v-model="newPassword"
|
||||
:rules="[rules.required()]"
|
||||
label="New password"
|
||||
autocomplete="off"
|
||||
:type="showPassword ? 'text' : 'password'"
|
||||
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
|
||||
@click:append="showPassword = !showPassword"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="confirmPassword"
|
||||
:rules="[rules.sameAs(newPassword)]"
|
||||
label="Confirm password"
|
||||
autocomplete="off"
|
||||
:type="showPassword ? 'text' : 'password'"
|
||||
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
|
||||
@click:append="showPassword = !showPassword"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {components} from '@/generated/openapi/komga'
|
||||
import { useRules } from 'vuetify/labs/rules'
|
||||
|
||||
const user = defineModel<components["schemas"]["UserDto"] | undefined>({required: true})
|
||||
const rules = useRules()
|
||||
|
||||
const rules = [
|
||||
value => {
|
||||
if (value) return true
|
||||
return 'You must enter a first name.'
|
||||
},
|
||||
]
|
||||
const newPassword = defineModel<string>({required: true})
|
||||
|
||||
const confirmPassword = ref<string>()
|
||||
const showPassword = ref<boolean>(false)
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -61,12 +61,12 @@
|
|||
</v-data-table>
|
||||
|
||||
<DialogConfirmEdit
|
||||
v-model:record="userRecord"
|
||||
v-model:record="dialogRecord"
|
||||
:activator="activator"
|
||||
:title="dialogTitle"
|
||||
:subtitle="userRecord?.email"
|
||||
max-width="400"
|
||||
@update:record="handleConfirmation()"
|
||||
@update:record="handleDialogConfirmation()"
|
||||
>
|
||||
<template #text="{proxyModel}">
|
||||
<component
|
||||
|
|
@ -84,7 +84,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} from '@/colada/mutations/update-user.ts'
|
||||
import {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'
|
||||
|
|
@ -133,13 +133,19 @@ onMounted(() => refetchUsers())
|
|||
|
||||
|
||||
// Dialogs handling
|
||||
// stores the user being actioned upon
|
||||
const userRecord = ref<components["schemas"]["UserDto"]>()
|
||||
// stores the ongoing action, so we can handle the action when the dialog is closed with changes
|
||||
const currentAction = ref<ACTION>()
|
||||
// the record passed to the dialog's form's model
|
||||
const dialogRecord = ref<unknown>()
|
||||
const activator = 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()
|
||||
|
||||
enum ACTION {
|
||||
EDIT, DELETE, RESTRICTIONS, PASSWORD
|
||||
|
|
@ -151,32 +157,41 @@ function showDialog(action: ACTION, user: components["schemas"]["UserDto"]) {
|
|||
case ACTION.EDIT:
|
||||
dialogTitle.value = 'Edit Roles'
|
||||
dialogComponent.value = FormUserRoles
|
||||
dialogRecord.value = user
|
||||
break;
|
||||
case ACTION.DELETE:
|
||||
dialogTitle.value = 'Delete User'
|
||||
dialogComponent.value = FormUserRoles
|
||||
dialogRecord.value = user
|
||||
break;
|
||||
case ACTION.RESTRICTIONS:
|
||||
dialogTitle.value = 'Edit Restrictions'
|
||||
dialogComponent.value = FormUserRoles
|
||||
dialogRecord.value = user
|
||||
break;
|
||||
case ACTION.PASSWORD:
|
||||
dialogTitle.value = 'Change Password'
|
||||
dialogComponent.value = FormUserChangePassword
|
||||
// password change initiated with an empty string
|
||||
dialogRecord.value = ''
|
||||
}
|
||||
userRecord.value = user
|
||||
}
|
||||
|
||||
function handleConfirmation() {
|
||||
function handleDialogConfirmation() {
|
||||
switch (currentAction.value) {
|
||||
case ACTION.EDIT:
|
||||
mutateUser(userRecord.value!)
|
||||
mutateUser(dialogRecord.value as components["schemas"]["UserDto"])
|
||||
break;
|
||||
case ACTION.DELETE:
|
||||
break;
|
||||
case ACTION.RESTRICTIONS:
|
||||
break;
|
||||
case ACTION.PASSWORD:
|
||||
mutateUserPassword({
|
||||
userId: userRecord.value!.id,
|
||||
newPassword: dialogRecord.value as string,
|
||||
})
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue