refactor(frontend): migrate user settings to FormField component
Migrate ApiTokens, Caldav, DataExport, Deletion, EmailUpdate, PasswordUpdate, TOTP, and DataExportDownload views to use the new FormField component.
This commit is contained in:
parent
0c23714a79
commit
908c241ec7
|
|
@ -3,32 +3,17 @@
|
|||
<h1>{{ $t('user.export.downloadTitle') }}</h1>
|
||||
<template v-if="isLocalUser">
|
||||
<p>{{ $t('user.export.descriptionPasswordRequired') }}</p>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="currentPasswordDataExport"
|
||||
>
|
||||
{{ $t('user.settings.currentPassword') }}
|
||||
</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="currentPasswordDataExport"
|
||||
ref="passwordInput"
|
||||
v-model="password"
|
||||
class="input"
|
||||
:class="{'is-danger': errPasswordRequired}"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup="() => errPasswordRequired = password === ''"
|
||||
>
|
||||
</div>
|
||||
<p
|
||||
v-if="errPasswordRequired"
|
||||
class="help is-danger"
|
||||
>
|
||||
{{ $t('user.deletion.passwordRequired') }}
|
||||
</p>
|
||||
</div>
|
||||
<FormField
|
||||
id="currentPasswordDataExport"
|
||||
ref="passwordInput"
|
||||
v-model="password"
|
||||
:label="$t('user.settings.currentPassword')"
|
||||
:class="{'is-danger': errPasswordRequired}"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
:error="errPasswordRequired ? $t('user.deletion.passwordRequired') : null"
|
||||
@keyup="() => errPasswordRequired = password === ''"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<XButton
|
||||
|
|
@ -52,6 +37,7 @@
|
|||
<script setup lang="ts">
|
||||
import {ref, computed, reactive} from 'vue'
|
||||
import DataExportService from '@/services/dataExport'
|
||||
import FormField from '@/components/input/FormField.vue'
|
||||
import {useAuthStore} from '@/stores/auth'
|
||||
|
||||
const dataExportService = reactive(new DataExportService())
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import flatPickr from 'vue-flatpickr-component'
|
|||
import 'flatpickr/dist/flatpickr.css'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import Message from '@/components/misc/Message.vue'
|
||||
import FormField from '@/components/input/FormField.vue'
|
||||
import type {IApiToken} from '@/modelTypes/IApiToken'
|
||||
|
||||
const service = new ApiTokenService()
|
||||
|
|
@ -232,31 +233,18 @@ function toggleGroupPermissionsFromChild(group: string, checked: boolean) {
|
|||
@submit.prevent="createToken"
|
||||
>
|
||||
<!-- Title -->
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="apiTokenTitle"
|
||||
>{{ $t('user.settings.apiTokens.attributes.title') }}</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="apiTokenTitle"
|
||||
ref="apiTokenTitle"
|
||||
v-model="newToken.title"
|
||||
v-focus
|
||||
class="input"
|
||||
type="text"
|
||||
:placeholder="$t('user.settings.apiTokens.attributes.titlePlaceholder')"
|
||||
@keyup="() => newTokenTitleValid = newToken.title !== ''"
|
||||
@focusout="() => newTokenTitleValid = newToken.title !== ''"
|
||||
>
|
||||
</div>
|
||||
<p
|
||||
v-if="!newTokenTitleValid"
|
||||
class="help is-danger"
|
||||
>
|
||||
{{ $t('user.settings.apiTokens.titleRequired') }}
|
||||
</p>
|
||||
</div>
|
||||
<FormField
|
||||
id="apiTokenTitle"
|
||||
ref="apiTokenTitle"
|
||||
v-model="newToken.title"
|
||||
v-focus
|
||||
:label="$t('user.settings.apiTokens.attributes.title')"
|
||||
type="text"
|
||||
:placeholder="$t('user.settings.apiTokens.attributes.titlePlaceholder')"
|
||||
:error="newTokenTitleValid ? null : $t('user.settings.apiTokens.titleRequired')"
|
||||
@keyup="() => newTokenTitleValid = newToken.title !== ''"
|
||||
@focusout="() => newTokenTitleValid = newToken.title !== ''"
|
||||
/>
|
||||
|
||||
<!-- Expiry -->
|
||||
<div class="field">
|
||||
|
|
|
|||
|
|
@ -6,24 +6,20 @@
|
|||
<p>
|
||||
{{ $t('user.settings.caldav.howTo') }}
|
||||
</p>
|
||||
<div class="field has-addons no-input-mobile">
|
||||
<div class="control is-expanded">
|
||||
<input
|
||||
v-model="caldavUrl"
|
||||
type="text"
|
||||
class="input"
|
||||
readonly
|
||||
>
|
||||
</div>
|
||||
<div class="control">
|
||||
<FormField
|
||||
v-model="caldavUrl"
|
||||
type="text"
|
||||
readonly
|
||||
>
|
||||
<template #addon>
|
||||
<XButton
|
||||
v-tooltip="$t('misc.copy')"
|
||||
:shadow="false"
|
||||
icon="paste"
|
||||
@click="copy(caldavUrl)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</FormField>
|
||||
|
||||
<h5 class="mbs-5 mbe-4 has-text-weight-bold">
|
||||
{{ $t('user.settings.caldav.tokens') }}
|
||||
|
|
@ -108,6 +104,7 @@ import {useCopyToClipboard} from '@/composables/useCopyToClipboard'
|
|||
import {success} from '@/message'
|
||||
import BaseButton from '@/components/base/BaseButton.vue'
|
||||
import Message from '@/components/misc/Message.vue'
|
||||
import FormField from '@/components/input/FormField.vue'
|
||||
import CaldavTokenService from '@/services/caldavToken'
|
||||
import { formatDateShort } from '@/helpers/time/formatDate'
|
||||
import type {ICaldavToken} from '@/modelTypes/ICaldavToken'
|
||||
|
|
|
|||
|
|
@ -32,32 +32,17 @@
|
|||
<p>
|
||||
{{ $t('user.export.descriptionPasswordRequired') }}
|
||||
</p>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="currentPasswordDataExport"
|
||||
>
|
||||
{{ $t('user.settings.currentPassword') }}
|
||||
</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="currentPasswordDataExport"
|
||||
ref="passwordInput"
|
||||
v-model="password"
|
||||
class="input"
|
||||
:class="{'is-danger': errPasswordRequired}"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup="() => errPasswordRequired = password === ''"
|
||||
>
|
||||
</div>
|
||||
<p
|
||||
v-if="errPasswordRequired"
|
||||
class="help is-danger"
|
||||
>
|
||||
{{ $t('user.deletion.passwordRequired') }}
|
||||
</p>
|
||||
</div>
|
||||
<FormField
|
||||
id="currentPasswordDataExport"
|
||||
ref="passwordInput"
|
||||
v-model="password"
|
||||
:label="$t('user.settings.currentPassword')"
|
||||
:class="{'is-danger': errPasswordRequired}"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
:error="errPasswordRequired ? $t('user.deletion.passwordRequired') : null"
|
||||
@keyup="() => errPasswordRequired = password === ''"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<XButton
|
||||
|
|
@ -81,6 +66,7 @@ import {useAuthStore} from '@/stores/auth'
|
|||
import {formatISO, formatDateLong, formatDisplayDate} from '@/helpers/time/formatDate'
|
||||
|
||||
import Message from '@/components/misc/Message.vue'
|
||||
import FormField from '@/components/input/FormField.vue'
|
||||
|
||||
defineOptions({name: 'UserSettingsDataExport'})
|
||||
|
||||
|
|
|
|||
|
|
@ -17,32 +17,17 @@
|
|||
<p>
|
||||
{{ $t('user.deletion.scheduledCancelText') }}
|
||||
</p>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="currentPasswordAccountDelete"
|
||||
>
|
||||
{{ $t('user.settings.currentPassword') }}
|
||||
</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="currentPasswordAccountDelete"
|
||||
ref="passwordInput"
|
||||
v-model="password"
|
||||
class="input"
|
||||
:class="{'is-danger': errPasswordRequired}"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup="() => errPasswordRequired = password === ''"
|
||||
>
|
||||
</div>
|
||||
<p
|
||||
v-if="errPasswordRequired"
|
||||
class="help is-danger"
|
||||
>
|
||||
{{ $t('user.deletion.passwordRequired') }}
|
||||
</p>
|
||||
</div>
|
||||
<FormField
|
||||
id="currentPasswordAccountDelete"
|
||||
ref="passwordInput"
|
||||
v-model="password"
|
||||
:label="$t('user.settings.currentPassword')"
|
||||
:class="{'is-danger': errPasswordRequired}"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
:error="errPasswordRequired ? $t('user.deletion.passwordRequired') : null"
|
||||
@keyup="() => errPasswordRequired = password === ''"
|
||||
/>
|
||||
</template>
|
||||
<p v-else>
|
||||
{{ $t('user.deletion.scheduledCancelButton') }}
|
||||
|
|
@ -68,32 +53,17 @@
|
|||
<p>
|
||||
{{ $t('user.deletion.text2') }}
|
||||
</p>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="currentPasswordAccountDelete"
|
||||
>
|
||||
{{ $t('user.settings.currentPassword') }}
|
||||
</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="currentPasswordAccountDelete"
|
||||
ref="passwordInput"
|
||||
v-model="password"
|
||||
class="input"
|
||||
:class="{'is-danger': errPasswordRequired}"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup="() => errPasswordRequired = password === ''"
|
||||
>
|
||||
</div>
|
||||
<p
|
||||
v-if="errPasswordRequired"
|
||||
class="help is-danger"
|
||||
>
|
||||
{{ $t('user.deletion.passwordRequired') }}
|
||||
</p>
|
||||
</div>
|
||||
<FormField
|
||||
id="currentPasswordAccountDelete"
|
||||
ref="passwordInput"
|
||||
v-model="password"
|
||||
:label="$t('user.settings.currentPassword')"
|
||||
:class="{'is-danger': errPasswordRequired}"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
:error="errPasswordRequired ? $t('user.deletion.passwordRequired') : null"
|
||||
@keyup="() => errPasswordRequired = password === ''"
|
||||
/>
|
||||
</form>
|
||||
<p v-else>
|
||||
{{ $t('user.deletion.text3') }}
|
||||
|
|
@ -121,6 +91,7 @@ import {useTitle} from '@/composables/useTitle'
|
|||
import {success} from '@/message'
|
||||
import {useAuthStore} from '@/stores/auth'
|
||||
import {useConfigStore} from '@/stores/config'
|
||||
import FormField from '@/components/input/FormField.vue'
|
||||
|
||||
defineOptions({name: 'UserSettingsDeletion'})
|
||||
|
||||
|
|
|
|||
|
|
@ -4,38 +4,22 @@
|
|||
:title="$t('user.settings.updateEmailTitle')"
|
||||
>
|
||||
<form @submit.prevent="updateEmail">
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="newEmail"
|
||||
>{{ $t('user.settings.updateEmailNew') }}</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="newEmail"
|
||||
v-model="emailUpdate.newEmail"
|
||||
class="input"
|
||||
:placeholder="$t('user.auth.emailPlaceholder')"
|
||||
type="email"
|
||||
@keyup.enter="updateEmail"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="currentPasswordEmail"
|
||||
>{{ $t('user.settings.currentPassword') }}</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="currentPasswordEmail"
|
||||
v-model="emailUpdate.password"
|
||||
class="input"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="updateEmail"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<FormField
|
||||
id="newEmail"
|
||||
v-model="emailUpdate.newEmail"
|
||||
:label="$t('user.settings.updateEmailNew')"
|
||||
:placeholder="$t('user.auth.emailPlaceholder')"
|
||||
type="email"
|
||||
@keyup.enter="updateEmail"
|
||||
/>
|
||||
<FormField
|
||||
id="currentPasswordEmail"
|
||||
v-model="emailUpdate.password"
|
||||
:label="$t('user.settings.currentPassword')"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="updateEmail"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<XButton
|
||||
|
|
@ -55,6 +39,7 @@ import {useI18n} from 'vue-i18n'
|
|||
|
||||
import EmailUpdateService from '@/services/emailUpdate'
|
||||
import EmailUpdateModel from '@/models/emailUpdate'
|
||||
import FormField from '@/components/input/FormField.vue'
|
||||
import {success} from '@/message'
|
||||
import {useTitle} from '@/composables/useTitle'
|
||||
import {useAuthStore} from '@/stores/auth'
|
||||
|
|
|
|||
|
|
@ -5,57 +5,33 @@
|
|||
:loading="passwordUpdateService.loading"
|
||||
>
|
||||
<form @submit.prevent="updatePassword">
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="newPassword"
|
||||
>{{ $t('user.settings.newPassword') }}</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="newPassword"
|
||||
v-model="passwordUpdate.newPassword"
|
||||
autocomplete="new-password"
|
||||
class="input"
|
||||
:placeholder="$t('user.auth.passwordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="updatePassword"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="newPasswordConfirm"
|
||||
>{{ $t('user.settings.newPasswordConfirm') }}</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="newPasswordConfirm"
|
||||
v-model="passwordConfirm"
|
||||
autocomplete="new-password"
|
||||
class="input"
|
||||
:placeholder="$t('user.auth.passwordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="updatePassword"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="currentPassword"
|
||||
>{{ $t('user.settings.currentPassword') }}</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="currentPassword"
|
||||
v-model="passwordUpdate.oldPassword"
|
||||
autocomplete="current-password"
|
||||
class="input"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="updatePassword"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<FormField
|
||||
id="newPassword"
|
||||
v-model="passwordUpdate.newPassword"
|
||||
:label="$t('user.settings.newPassword')"
|
||||
autocomplete="new-password"
|
||||
:placeholder="$t('user.auth.passwordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="updatePassword"
|
||||
/>
|
||||
<FormField
|
||||
id="newPasswordConfirm"
|
||||
v-model="passwordConfirm"
|
||||
:label="$t('user.settings.newPasswordConfirm')"
|
||||
autocomplete="new-password"
|
||||
:placeholder="$t('user.auth.passwordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="updatePassword"
|
||||
/>
|
||||
<FormField
|
||||
id="currentPassword"
|
||||
v-model="passwordUpdate.oldPassword"
|
||||
:label="$t('user.settings.currentPassword')"
|
||||
autocomplete="current-password"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="updatePassword"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<XButton
|
||||
|
|
@ -75,6 +51,7 @@ import {useI18n} from 'vue-i18n'
|
|||
|
||||
import PasswordUpdateService from '@/services/passwordUpdateService'
|
||||
import PasswordUpdateModel from '@/models/passwordUpdate'
|
||||
import FormField from '@/components/input/FormField.vue'
|
||||
|
||||
import {useTitle} from '@/composables/useTitle'
|
||||
import {success, error} from '@/message'
|
||||
|
|
|
|||
|
|
@ -23,24 +23,16 @@
|
|||
alt=""
|
||||
>
|
||||
</p>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="totpConfirmPasscode"
|
||||
>{{ $t('user.settings.totp.passcode') }}</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="totpConfirmPasscode"
|
||||
v-model="totpConfirmPasscode"
|
||||
autocomplete="one-time-code"
|
||||
class="input"
|
||||
:placeholder="$t('user.settings.totp.passcodePlaceholder')"
|
||||
type="text"
|
||||
inputmode="numeric"
|
||||
@keyup.enter="totpConfirm"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<FormField
|
||||
id="totpConfirmPasscode"
|
||||
v-model="totpConfirmPasscode"
|
||||
:label="$t('user.settings.totp.passcode')"
|
||||
autocomplete="one-time-code"
|
||||
:placeholder="$t('user.settings.totp.passcodePlaceholder')"
|
||||
type="text"
|
||||
inputmode="numeric"
|
||||
@keyup.enter="totpConfirm"
|
||||
/>
|
||||
<XButton @click="totpConfirm">
|
||||
{{ $t('misc.confirm') }}
|
||||
</XButton>
|
||||
|
|
@ -58,23 +50,15 @@
|
|||
</XButton>
|
||||
</p>
|
||||
<div v-if="totpDisableForm">
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="currentPassword"
|
||||
>{{ $t('user.settings.totp.enterPassword') }}</label>
|
||||
<div class="control">
|
||||
<input
|
||||
id="currentPassword"
|
||||
v-model="totpDisablePassword"
|
||||
v-focus
|
||||
class="input"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="totpDisable"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<FormField
|
||||
id="currentPassword"
|
||||
v-model="totpDisablePassword"
|
||||
v-focus
|
||||
:label="$t('user.settings.totp.enterPassword')"
|
||||
:placeholder="$t('user.settings.currentPasswordPlaceholder')"
|
||||
type="password"
|
||||
@keyup.enter="totpDisable"
|
||||
/>
|
||||
<XButton
|
||||
danger
|
||||
@click="totpDisable"
|
||||
|
|
@ -100,6 +84,7 @@ import {useI18n} from 'vue-i18n'
|
|||
|
||||
import TotpService from '@/services/totp'
|
||||
import TotpModel from '@/models/totp'
|
||||
import FormField from '@/components/input/FormField.vue'
|
||||
|
||||
import {success} from '@/message'
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue