[WIP]refactor(front): new components for user settings
This commit is contained in:
parent
1576890933
commit
6ecb344b73
|
@ -16,7 +16,11 @@ import useLogger from '~/composables/useLogger'
|
|||
import SubsonicTokenForm from '~/components/auth/SubsonicTokenForm.vue'
|
||||
import AttachmentInput from '~/components/common/AttachmentInput.vue'
|
||||
import PasswordInput from '~/components/forms/PasswordInput.vue'
|
||||
import Input from '~/components/ui/Input.vue'
|
||||
import Layout from '~/components/ui/Layout.vue'
|
||||
import Header from '~/components/ui/Header.vue'
|
||||
import Button from '~/components/ui/Button.vue'
|
||||
import Link from '~/components/ui/Link.vue'
|
||||
|
||||
const SETTINGS_ORDER: FieldId[] = ['summary', 'privacy_level']
|
||||
|
||||
|
@ -266,91 +270,82 @@ fetchOwnedApps()
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<main
|
||||
<Layout main stack
|
||||
v-title="labels.title"
|
||||
class="main"
|
||||
>
|
||||
<div class="ui vertical stripe segment">
|
||||
<section class="ui text container">
|
||||
<h2 class="ui header">
|
||||
{{ t('components.auth.Settings.header.accountSettings') }}
|
||||
</h2>
|
||||
<form
|
||||
class="ui form"
|
||||
@submit.prevent="submitSettings()"
|
||||
<Header :h1="t('components.auth.Settings.header.accountSettings')">
|
||||
</Header>
|
||||
<Layout form
|
||||
@submit.prevent="submitSettings()"
|
||||
>
|
||||
<Alert green
|
||||
v-if="settings.success"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ t('components.auth.Settings.header.settingsUpdated') }}
|
||||
</h4>
|
||||
</Alert>
|
||||
<Alert red
|
||||
v-if="settings.errors.length > 0"
|
||||
role="alert"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ t('components.auth.Settings.header.updateFailure') }}
|
||||
</h4>
|
||||
<ul class="list">
|
||||
<li
|
||||
v-for="(error, key) in settings.errors"
|
||||
:key="key"
|
||||
>
|
||||
{{ error }}
|
||||
</li>
|
||||
</ul>
|
||||
</Alert>
|
||||
<div
|
||||
v-for="f in orderedSettingsFields"
|
||||
:key="f.id"
|
||||
class="field"
|
||||
>
|
||||
<label :for="f.id">{{ sharedLabels.fields[f.id].label }}</label>
|
||||
<p v-if="sharedLabels.fields[f.id].help">
|
||||
{{ sharedLabels.fields[f.id].help }}
|
||||
</p>
|
||||
<select
|
||||
v-if="f.type === 'dropdown'"
|
||||
:id="f.id"
|
||||
v-model="f.value"
|
||||
class="ui dropdown"
|
||||
>
|
||||
<div
|
||||
v-if="settings.success"
|
||||
class="ui positive message"
|
||||
<option
|
||||
v-for="(c, key) in f.choices"
|
||||
:key="key"
|
||||
:value="c"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ t('components.auth.Settings.header.settingsUpdated') }}
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
v-if="settings.errors.length > 0"
|
||||
role="alert"
|
||||
class="ui negative message"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ t('components.auth.Settings.header.updateFailure') }}
|
||||
</h4>
|
||||
<ul class="list">
|
||||
<li
|
||||
v-for="(error, key) in settings.errors"
|
||||
:key="key"
|
||||
>
|
||||
{{ error }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
v-for="f in orderedSettingsFields"
|
||||
:key="f.id"
|
||||
class="field"
|
||||
>
|
||||
<label :for="f.id">{{ sharedLabels.fields[f.id].label }}</label>
|
||||
<p v-if="sharedLabels.fields[f.id].help">
|
||||
{{ sharedLabels.fields[f.id].help }}
|
||||
</p>
|
||||
<select
|
||||
v-if="f.type === 'dropdown'"
|
||||
:id="f.id"
|
||||
v-model="f.value"
|
||||
class="ui dropdown"
|
||||
>
|
||||
<option
|
||||
v-for="(c, key) in f.choices"
|
||||
:key="key"
|
||||
:value="c"
|
||||
>
|
||||
{{ sharedLabels.fields[f.id].choices?.[c] }}
|
||||
</option>
|
||||
</select>
|
||||
<content-form
|
||||
v-if="f.type === 'content'"
|
||||
v-model="f.value.text"
|
||||
:field-id="f.id"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
:is-loading="isLoading"
|
||||
type="submit"
|
||||
>
|
||||
{{ t('components.auth.Settings.button.updateSettings') }}
|
||||
</Button>
|
||||
</form>
|
||||
</section>
|
||||
{{ sharedLabels.fields[f.id].choices?.[c] }}
|
||||
</option>
|
||||
</select>
|
||||
<content-form
|
||||
v-if="f.type === 'content'"
|
||||
v-model="f.value.text"
|
||||
:field-id="f.id"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
primary
|
||||
:is-loading="isLoading"
|
||||
type="submit"
|
||||
>
|
||||
{{ t('components.auth.Settings.button.updateSettings') }}
|
||||
</Button>
|
||||
</Layout>
|
||||
<section class="ui text container">
|
||||
<div class="ui hidden divider" />
|
||||
<h2 class="ui header">
|
||||
{{ t('components.auth.Settings.header.avatar') }}
|
||||
</h2>
|
||||
<div class="ui form">
|
||||
<div
|
||||
<Layout form>
|
||||
<Alert red
|
||||
v-if="avatarErrors.length > 0"
|
||||
role="alert"
|
||||
class="ui negative message"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ t('components.auth.Settings.header.avatarFailure') }}
|
||||
|
@ -363,7 +358,7 @@ fetchOwnedApps()
|
|||
{{ error }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Alert>
|
||||
<attachment-input
|
||||
v-model="avatar.uuid"
|
||||
:initial-value="initialAvatar"
|
||||
|
@ -372,25 +367,22 @@ fetchOwnedApps()
|
|||
>
|
||||
{{ t('components.auth.Settings.label.avatar') }}
|
||||
</attachment-input>
|
||||
</div>
|
||||
</Layout>
|
||||
</section>
|
||||
|
||||
<section class="ui text container">
|
||||
<div class="ui hidden divider" />
|
||||
<h2 class="ui header">
|
||||
{{ t('components.auth.Settings.header.changePassword') }}
|
||||
</h2>
|
||||
<div class="ui message">
|
||||
{{ t('components.auth.Settings.description.changePassword.paragraph1') }} {{ t('components.auth.Settings.description.changePassword.paragraph2') }}
|
||||
</div>
|
||||
<form
|
||||
class="ui form"
|
||||
<Layout form
|
||||
@submit.prevent="submitPassword()"
|
||||
>
|
||||
<div
|
||||
<Alert
|
||||
v-if="passwordError"
|
||||
role="alert"
|
||||
class="ui negative message"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ t('components.auth.Settings.header.passwordFailure') }}
|
||||
|
@ -400,7 +392,7 @@ fetchOwnedApps()
|
|||
{{ t('components.auth.Settings.help.changePassword') }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Alert>
|
||||
<div class="field">
|
||||
<label for="old-password-field">{{ t('components.auth.Settings.label.currentPassword') }}</label>
|
||||
<password-input
|
||||
|
@ -448,7 +440,7 @@ fetchOwnedApps()
|
|||
</div>
|
||||
</template>
|
||||
</dangerous-button>
|
||||
</form>
|
||||
</Layout>
|
||||
<div class="ui hidden divider" />
|
||||
<subsonic-token-form />
|
||||
</section>
|
||||
|
@ -457,9 +449,8 @@ fetchOwnedApps()
|
|||
id="content-filters"
|
||||
class="ui text container"
|
||||
>
|
||||
<div class="ui hidden divider" />
|
||||
<h2 class="ui header">
|
||||
<i class="eye slash outline icon" />
|
||||
<i class="bi bi-eye-slash" />
|
||||
<div class="content">
|
||||
{{ t('components.auth.Settings.header.contentFilters') }}
|
||||
</div>
|
||||
|
@ -469,6 +460,7 @@ fetchOwnedApps()
|
|||
</p>
|
||||
|
||||
<Button
|
||||
primary
|
||||
icon="bi-arrow-clockwise"
|
||||
@click="store.dispatch('moderation/fetchContentFilters')"
|
||||
>
|
||||
|
@ -504,6 +496,7 @@ fetchOwnedApps()
|
|||
</td>
|
||||
<td>
|
||||
<Button
|
||||
secondary
|
||||
@click="store.dispatch('moderation/deleteContentFilter', filter.uuid)"
|
||||
>
|
||||
{{ t('components.auth.Settings.button.delete') }}
|
||||
|
@ -519,7 +512,7 @@ fetchOwnedApps()
|
|||
>
|
||||
<div class="ui hidden divider" />
|
||||
<h2 class="ui header">
|
||||
<i class="open lock icon" />
|
||||
<i class="bi bi-unlock-fill" />
|
||||
<div class="content">
|
||||
{{ t('components.auth.Settings.header.authorizedApps') }}
|
||||
</div>
|
||||
|
@ -528,6 +521,7 @@ fetchOwnedApps()
|
|||
{{ t('components.auth.Settings.description.authorizedApps') }}
|
||||
</p>
|
||||
<Button
|
||||
primary
|
||||
icon="bi-arrow-clockwise"
|
||||
:is-loading="isLoadingApps"
|
||||
@click="fetchApps()"
|
||||
|
@ -599,7 +593,7 @@ fetchOwnedApps()
|
|||
>
|
||||
<div class="ui hidden divider" />
|
||||
<h2 class="ui header">
|
||||
<i class="code icon" />
|
||||
<i class="bi bi-code-slash" />
|
||||
<div class="content">
|
||||
{{ t('components.auth.Settings.header.yourApps') }}
|
||||
</div>
|
||||
|
@ -607,12 +601,12 @@ fetchOwnedApps()
|
|||
<p>
|
||||
{{ t('components.auth.Settings.description.yourApps') }}
|
||||
</p>
|
||||
<router-link
|
||||
<Link
|
||||
class="ui success button"
|
||||
:to="{name: 'settings.applications.new'}"
|
||||
>
|
||||
{{ t('components.auth.Settings.link.newApp') }}
|
||||
</router-link>
|
||||
</Link>
|
||||
<table
|
||||
v-if="ownedApps.length > 0"
|
||||
class="ui compact very basic unstackable table"
|
||||
|
@ -648,12 +642,12 @@ fetchOwnedApps()
|
|||
<human-date :date="app.created" />
|
||||
</td>
|
||||
<td>
|
||||
<router-link
|
||||
<Link
|
||||
class="ui tiny success button"
|
||||
:to="{name: 'settings.applications.edit', params: {id: app.client_id}}"
|
||||
>
|
||||
{{ t('components.auth.Settings.button.edit') }}
|
||||
</router-link>
|
||||
</Link>
|
||||
<Button
|
||||
color="destructive"
|
||||
:is-loading="isDeleting.has(app.client_id)"
|
||||
|
@ -695,7 +689,7 @@ fetchOwnedApps()
|
|||
>
|
||||
<div class="ui hidden divider" />
|
||||
<h2 class="ui header">
|
||||
<i class="code icon" />
|
||||
<i class="bi bi-code" />
|
||||
<div class="content">
|
||||
{{ t('components.auth.Settings.header.plugins') }}
|
||||
</div>
|
||||
|
@ -703,17 +697,17 @@ fetchOwnedApps()
|
|||
<p>
|
||||
{{ t('components.auth.Settings.description.plugins') }}
|
||||
</p>
|
||||
<router-link
|
||||
class="ui success button"
|
||||
<Button
|
||||
primary
|
||||
:to="{name: 'settings.plugins'}"
|
||||
>
|
||||
{{ t('components.auth.Settings.link.managePlugins') }}
|
||||
</router-link>
|
||||
</Button>
|
||||
</section>
|
||||
<section class="ui text container">
|
||||
<div class="ui hidden divider" />
|
||||
<h2 class="ui header">
|
||||
<i class="comment icon" />
|
||||
<i class="bi bi-envelope-at" />
|
||||
<div class="content">
|
||||
{{ t('components.auth.Settings.header.changeEmail') }}
|
||||
</div>
|
||||
|
@ -724,14 +718,12 @@ fetchOwnedApps()
|
|||
<p>
|
||||
{{ t('components.auth.Settings.message.currentEmail', { email: store.state.auth.profile?.email }) }}
|
||||
</p>
|
||||
<form
|
||||
class="ui form"
|
||||
<Layout form
|
||||
@submit.prevent="changeEmail"
|
||||
>
|
||||
<div
|
||||
<Alert red
|
||||
v-if="changeEmailErrors.length > 0"
|
||||
role="alert"
|
||||
class="ui negative message"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ t('components.auth.Settings.header.emailFailure') }}
|
||||
|
@ -744,15 +736,15 @@ fetchOwnedApps()
|
|||
{{ error }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Alert>
|
||||
<div class="field">
|
||||
<label for="new-email">{{ t('components.auth.Settings.label.newEmail') }}</label>
|
||||
<input
|
||||
<Input
|
||||
id="new-email"
|
||||
v-model="newEmail"
|
||||
required
|
||||
type="email"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="current-password-field-email">{{ t('components.auth.Settings.label.password') }}</label>
|
||||
|
@ -763,16 +755,17 @@ fetchOwnedApps()
|
|||
/>
|
||||
</div>
|
||||
<Button
|
||||
primary
|
||||
type="submit"
|
||||
>
|
||||
{{ t('components.auth.Settings.button.update') }}
|
||||
</Button>
|
||||
</form>
|
||||
</Layout>
|
||||
</section>
|
||||
<section class="ui text container">
|
||||
<div class="ui hidden divider" />
|
||||
<h2 class="ui header">
|
||||
<i class="trash icon" />
|
||||
<i class="bi bi-trash" />
|
||||
<div class="content">
|
||||
{{ t('components.auth.Settings.header.deleteAccount') }}
|
||||
</div>
|
||||
|
@ -780,17 +773,15 @@ fetchOwnedApps()
|
|||
<p>
|
||||
{{ t('components.auth.Settings.description.deleteAccount') }}
|
||||
</p>
|
||||
<div
|
||||
<Alert yellow
|
||||
role="alert"
|
||||
class="ui warning message"
|
||||
>
|
||||
{{ t('components.auth.Settings.warning.deleteAccount') }}
|
||||
</div>
|
||||
<div class="ui form">
|
||||
<div
|
||||
</Alert>
|
||||
<Layout form>
|
||||
<Alert red
|
||||
v-if="accountDeleteErrors.length > 0"
|
||||
role="alert"
|
||||
class="ui negative message"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ t('components.auth.Settings.header.accountFailure') }}
|
||||
|
@ -803,7 +794,7 @@ fetchOwnedApps()
|
|||
{{ error }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Alert>
|
||||
<div class="field">
|
||||
<label for="current-password-field">{{ t('components.auth.Settings.label.currentPassword') }}</label>
|
||||
<password-input
|
||||
|
@ -835,8 +826,7 @@ fetchOwnedApps()
|
|||
</div>
|
||||
</template>
|
||||
</dangerous-button>
|
||||
</div>
|
||||
</Layout>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
</template>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { useStore } from '~/store'
|
|||
import axios from 'axios'
|
||||
|
||||
import PasswordInput from '~/components/forms/PasswordInput.vue'
|
||||
import Alert from '~/components/ui/Alert.vue'
|
||||
import Button from '~/components/ui/Button.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
@ -105,18 +106,16 @@ fetchToken()
|
|||
{{ t('components.auth.SubsonicTokenForm.link.apps') }}
|
||||
</a>
|
||||
</p>
|
||||
<div
|
||||
<Alert green
|
||||
v-if="success"
|
||||
class="ui positive message"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ successMessage }}
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
</Alert>
|
||||
<Alert red
|
||||
v-if="subsonicEnabled && errors.length > 0"
|
||||
role="alert"
|
||||
class="ui negative message"
|
||||
>
|
||||
<h4 class="header">
|
||||
{{ t('components.auth.SubsonicTokenForm.header.error') }}
|
||||
|
@ -129,7 +128,7 @@ fetchToken()
|
|||
{{ error }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Alert>
|
||||
<template v-if="subsonicEnabled">
|
||||
<div
|
||||
v-if="token"
|
||||
|
@ -150,7 +149,7 @@ fetchToken()
|
|||
</div>
|
||||
<Button
|
||||
v-if="token"
|
||||
color="destructive"
|
||||
destructive
|
||||
:is-loading="isLoading"
|
||||
:action="requestNewToken"
|
||||
>
|
||||
|
@ -172,6 +171,7 @@ fetchToken()
|
|||
</template>
|
||||
</Button>
|
||||
<Button
|
||||
primary
|
||||
v-else
|
||||
:is-loading="isLoading"
|
||||
@click="requestNewToken"
|
||||
|
@ -179,6 +179,7 @@ fetchToken()
|
|||
{{ t('components.auth.SubsonicTokenForm.button.confirmNewPassword') }}
|
||||
</Button>
|
||||
<Button
|
||||
primary
|
||||
v-if="token"
|
||||
:is-loading="isLoading"
|
||||
color="destructive"
|
||||
|
|
Loading…
Reference in New Issue