feat(settings): restructure general settings view
This commit is contained in:
parent
e608f987f6
commit
715c28736f
|
|
@ -43,3 +43,4 @@ devenv.local.nix
|
|||
# AI Tools
|
||||
/.claude/
|
||||
PLAN.md
|
||||
/.crush/
|
||||
|
|
|
|||
|
|
@ -115,6 +115,13 @@
|
|||
},
|
||||
"externalUserNameChange": "Your name is managed by your login provider ({provider}). To change it, please update it there instead."
|
||||
},
|
||||
"sections": {
|
||||
"personalInformation": "Personal Information",
|
||||
"taskAndNotifications": "Projects & Tasks",
|
||||
"privacy": "Privacy",
|
||||
"localization": "Localization",
|
||||
"appearance": "Appearance & Behavior"
|
||||
},
|
||||
"totp": {
|
||||
"title": "Two Factor Authentication",
|
||||
"enroll": "Enroll",
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
<template>
|
||||
<Card
|
||||
:title="$t('user.settings.general.title')"
|
||||
:title="$t('user.settings.sections.personalInformation')"
|
||||
class="general-settings"
|
||||
:loading="loading"
|
||||
>
|
||||
<div class="field-group">
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
:for="`newName${id}`"
|
||||
>
|
||||
<label :for="`newName${id}`">
|
||||
<span>
|
||||
{{ $t('user.settings.general.name') }}
|
||||
</label>
|
||||
<div class="control">
|
||||
</span>
|
||||
<div class="ml-auto two-col">
|
||||
<input
|
||||
:id="`newName${id}`"
|
||||
v-model="settings.name"
|
||||
|
|
@ -22,6 +21,7 @@
|
|||
@keyup.enter="updateSettings"
|
||||
>
|
||||
</div>
|
||||
</label>
|
||||
<p
|
||||
v-if="isExternalUser"
|
||||
class="help"
|
||||
|
|
@ -30,16 +30,30 @@
|
|||
</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.general.defaultProject') }}
|
||||
</label>
|
||||
</span>
|
||||
<div class="ml-auto two-col">
|
||||
<ProjectSearch v-model="defaultProject" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">
|
||||
{{ $t('user.settings.general.defaultView') }}
|
||||
</label>
|
||||
<div class="select">
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
:title="$t('user.settings.sections.taskAndNotifications')"
|
||||
class="general-settings section-block"
|
||||
:loading="loading"
|
||||
>
|
||||
<div class="field-group">
|
||||
<div class="field">
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.general.defaultView') }}
|
||||
</span>
|
||||
<div class="select ml-auto two-col">
|
||||
<select v-model="settings.frontendSettings.defaultView">
|
||||
<option
|
||||
v-for="view in DEFAULT_PROJECT_VIEW_SETTINGS"
|
||||
|
|
@ -50,12 +64,14 @@
|
|||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.general.minimumPriority') }}
|
||||
</label>
|
||||
<div class="select">
|
||||
</span>
|
||||
<div class="select ml-auto two-col">
|
||||
<select v-model="settings.frontendSettings.minimumPriority">
|
||||
<option :value="PRIORITIES.LOW">
|
||||
{{ $t('task.priority.low') }}
|
||||
|
|
@ -74,19 +90,24 @@
|
|||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
v-if="hasFilters"
|
||||
class="field"
|
||||
>
|
||||
<label class="label">
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.general.filterUsedOnOverview') }}
|
||||
</label>
|
||||
</span>
|
||||
<div class="ml-auto two-col">
|
||||
<ProjectSearch
|
||||
v-model="filterUsedInOverview"
|
||||
:saved-filters-only="true"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input
|
||||
|
|
@ -99,19 +120,147 @@
|
|||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input
|
||||
v-model="settings.discoverableByName"
|
||||
v-model="settings.overdueTasksRemindersEnabled"
|
||||
type="checkbox"
|
||||
>
|
||||
{{ $t('user.settings.general.discoverableByName') }}
|
||||
{{ $t('user.settings.general.overdueReminders') }}
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
v-if="settings.overdueTasksRemindersEnabled"
|
||||
class="field"
|
||||
>
|
||||
<label for="overdueTasksReminderTime">
|
||||
<span>
|
||||
{{ $t('user.settings.general.overdueTasksRemindersTime') }}
|
||||
</span>
|
||||
<div class="ml-auto two-col">
|
||||
<input
|
||||
id="overdueTasksReminderTime"
|
||||
v-model="settings.overdueTasksRemindersTime"
|
||||
class="input"
|
||||
type="time"
|
||||
@keyup.enter="updateSettings"
|
||||
>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
:title="$t('user.settings.sections.localization')"
|
||||
class="general-settings section-block"
|
||||
:loading="loading"
|
||||
>
|
||||
<div class="field-group">
|
||||
<div class="field">
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.general.language') }}
|
||||
</span>
|
||||
<div class="select ml-auto two-col">
|
||||
<select v-model="settings.language">
|
||||
<option
|
||||
v-for="lang in availableLanguageOptions"
|
||||
:key="lang.code"
|
||||
:value="lang.code"
|
||||
>{{ lang.title }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input
|
||||
v-model="settings.discoverableByEmail"
|
||||
type="checkbox"
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.general.timezone') }}
|
||||
</span>
|
||||
<div class="ml-auto two-col">
|
||||
<Multiselect
|
||||
v-model="timezoneObject"
|
||||
:placeholder="$t('user.settings.general.timezone')"
|
||||
:search-results="timezoneSearchResults"
|
||||
:show-empty="true"
|
||||
class="timezone-select"
|
||||
label="label"
|
||||
@search="searchTimezones"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.general.weekStart') }}
|
||||
</span>
|
||||
<div class="select ml-auto two-col">
|
||||
<select v-model.number="settings.weekStart">
|
||||
<option value="0">{{ $t('user.settings.general.weekStartSunday') }}</option>
|
||||
<option value="1">{{ $t('user.settings.general.weekStartMonday') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.general.dateDisplay') }}
|
||||
</span>
|
||||
<div class="select ml-auto two-col">
|
||||
<select v-model="settings.frontendSettings.dateDisplay">
|
||||
<option
|
||||
v-for="(label, value) in dateDisplaySettings"
|
||||
:key="value"
|
||||
:value="value"
|
||||
>{{ label }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
:title="$t('user.settings.sections.appearance')"
|
||||
class="general-settings section-block"
|
||||
:loading="loading"
|
||||
>
|
||||
{{ $t('user.settings.general.discoverableByEmail') }}
|
||||
<div class="field-group">
|
||||
<div class="field">
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.appearance.title') }}
|
||||
</span>
|
||||
<div class="select ml-auto two-col">
|
||||
<select v-model="settings.frontendSettings.colorSchema">
|
||||
<option
|
||||
v-for="(title, schemeId) in colorSchemeSettings"
|
||||
:key="schemeId"
|
||||
:value="schemeId"
|
||||
>
|
||||
{{ title }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>
|
||||
<span>
|
||||
{{ $t('user.settings.quickAddMagic.title') }}
|
||||
</span>
|
||||
<div class="select ml-auto two-col">
|
||||
<select v-model="settings.frontendSettings.quickAddMagicMode">
|
||||
<option
|
||||
v-for="set in PrefixMode"
|
||||
:key="set"
|
||||
:value="set"
|
||||
>
|
||||
{{ $t(`user.settings.quickAddMagic.${set}`) }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
|
|
@ -132,144 +281,46 @@
|
|||
{{ $t('user.settings.general.allowIconChanges') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
:title="$t('user.settings.sections.privacy')"
|
||||
class="general-settings section-block"
|
||||
:loading="loading"
|
||||
>
|
||||
<div class="field-group">
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input
|
||||
v-model="settings.overdueTasksRemindersEnabled"
|
||||
v-model="settings.discoverableByName"
|
||||
type="checkbox"
|
||||
>
|
||||
{{ $t('user.settings.general.overdueReminders') }}
|
||||
{{ $t('user.settings.general.discoverableByName') }}
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
v-if="settings.overdueTasksRemindersEnabled"
|
||||
class="field"
|
||||
>
|
||||
<label
|
||||
class="label"
|
||||
for="overdueTasksReminderTime"
|
||||
>
|
||||
{{ $t('user.settings.general.overdueTasksRemindersTime') }}
|
||||
</label>
|
||||
<div class="control">
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input
|
||||
id="overdueTasksReminderTime"
|
||||
v-model="settings.overdueTasksRemindersTime"
|
||||
class="input"
|
||||
type="time"
|
||||
@keyup.enter="updateSettings"
|
||||
v-model="settings.discoverableByEmail"
|
||||
type="checkbox"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="is-flex is-align-items-center">
|
||||
<span>
|
||||
{{ $t('user.settings.general.weekStart') }}
|
||||
</span>
|
||||
<div class="select ml-2">
|
||||
<select v-model.number="settings.weekStart">
|
||||
<option value="0">{{ $t('user.settings.general.weekStartSunday') }}</option>
|
||||
<option value="1">{{ $t('user.settings.general.weekStartMonday') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ $t('user.settings.general.discoverableByEmail') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="is-flex is-align-items-center">
|
||||
<span>
|
||||
{{ $t('user.settings.general.language') }}
|
||||
</span>
|
||||
<div class="select ml-2">
|
||||
<select v-model="settings.language">
|
||||
<option
|
||||
v-for="lang in availableLanguageOptions"
|
||||
:key="lang.code"
|
||||
:value="lang.code"
|
||||
>{{ lang.title }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="is-flex is-align-items-center">
|
||||
<span>
|
||||
{{ $t('user.settings.quickAddMagic.title') }}
|
||||
</span>
|
||||
<div class="select ml-2">
|
||||
<select v-model="settings.frontendSettings.quickAddMagicMode">
|
||||
<option
|
||||
v-for="set in PrefixMode"
|
||||
:key="set"
|
||||
:value="set"
|
||||
>
|
||||
{{ $t(`user.settings.quickAddMagic.${set}`) }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="is-flex is-align-items-center">
|
||||
<span>
|
||||
{{ $t('user.settings.appearance.title') }}
|
||||
</span>
|
||||
<div class="select ml-2">
|
||||
<select v-model="settings.frontendSettings.colorSchema">
|
||||
<!-- TODO: use the Vikunja logo in color scheme as option buttons -->
|
||||
<option
|
||||
v-for="(title, schemeId) in colorSchemeSettings"
|
||||
:key="schemeId"
|
||||
:value="schemeId"
|
||||
>
|
||||
{{ title }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="is-flex is-align-items-center">
|
||||
<span>
|
||||
{{ $t('user.settings.general.dateDisplay') }}
|
||||
</span>
|
||||
<div class="select ml-2">
|
||||
<select v-model="settings.frontendSettings.dateDisplay">
|
||||
<option
|
||||
v-for="(label, value) in dateDisplaySettings"
|
||||
:key="value"
|
||||
:value="value"
|
||||
>{{ label }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="is-flex is-align-items-center">
|
||||
<span>
|
||||
{{ $t('user.settings.general.timezone') }}
|
||||
</span>
|
||||
<Multiselect
|
||||
v-model="timezoneObject"
|
||||
:placeholder="$t('user.settings.general.timezone')"
|
||||
:search-results="timezoneSearchResults"
|
||||
:show-empty="true"
|
||||
class="ml-2 timezone-select"
|
||||
label="label"
|
||||
@search="searchTimezones"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<div class="sticky-save">
|
||||
<XButton
|
||||
v-cy="'saveGeneralSettings'"
|
||||
:loading="loading"
|
||||
class="is-fullwidth mt-4"
|
||||
class="is-fullwidth"
|
||||
@click="updateSettings()"
|
||||
>
|
||||
{{ $t('misc.save') }}
|
||||
</XButton>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
|
@ -456,4 +507,31 @@ async function updateSettings() {
|
|||
min-width: 200px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.section-block + .section-block {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.field-group {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.field > label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.two-col {
|
||||
flex: 0 0 50%;
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
.sticky-save {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
padding: .25rem 1rem 1rem;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue