2021-10-26 20:58:02 +00:00
|
|
|
<template>
|
2021-12-30 20:20:45 +00:00
|
|
|
<card :title="$t('user.settings.general.title')" class="general-settings" :loading="loading">
|
2021-10-26 20:58:02 +00:00
|
|
|
<div class="field">
|
|
|
|
<label class="label" :for="`newName${id}`">{{ $t('user.settings.general.name') }}</label>
|
|
|
|
<div class="control">
|
|
|
|
<input
|
|
|
|
@keyup.enter="updateSettings"
|
|
|
|
class="input"
|
|
|
|
:id="`newName${id}`"
|
|
|
|
:placeholder="$t('user.settings.general.newName')"
|
|
|
|
type="text"
|
|
|
|
v-model="settings.name"/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="field">
|
|
|
|
<label class="label">
|
|
|
|
{{ $t('user.settings.general.defaultList') }}
|
|
|
|
</label>
|
|
|
|
<list-search v-model="defaultList"/>
|
|
|
|
</div>
|
|
|
|
<div class="field">
|
|
|
|
<label class="checkbox">
|
2022-06-16 14:52:25 +00:00
|
|
|
<input type="checkbox" v-model="settings.overdueTasksRemindersEnabled"/>
|
|
|
|
{{ $t('user.settings.general.overdueReminders') }}
|
2021-10-26 20:58:02 +00:00
|
|
|
</label>
|
|
|
|
</div>
|
2022-06-16 14:52:25 +00:00
|
|
|
<div class="field" v-if="settings.overdueTasksRemindersEnabled">
|
|
|
|
<label class="label" for="overdueTasksReminderTime">
|
|
|
|
{{ $t('user.settings.general.overdueTasksRemindersTime') }}
|
|
|
|
</label>
|
|
|
|
<div class="control">
|
|
|
|
<input
|
|
|
|
@keyup.enter="updateSettings"
|
|
|
|
class="input"
|
|
|
|
id="overdueTasksReminderTime"
|
|
|
|
type="time"
|
|
|
|
v-model="settings.overdueTasksRemindersTime"/>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-10-26 20:58:02 +00:00
|
|
|
<div class="field">
|
|
|
|
<label class="checkbox">
|
2022-06-16 14:52:25 +00:00
|
|
|
<input type="checkbox" v-model="settings.emailRemindersEnabled"/>
|
|
|
|
{{ $t('user.settings.general.emailReminders') }}
|
2021-10-26 20:58:02 +00:00
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
<div class="field">
|
|
|
|
<label class="checkbox">
|
|
|
|
<input type="checkbox" v-model="settings.discoverableByName"/>
|
|
|
|
{{ $t('user.settings.general.discoverableByName') }}
|
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
<div class="field">
|
|
|
|
<label class="checkbox">
|
|
|
|
<input type="checkbox" v-model="settings.discoverableByEmail"/>
|
|
|
|
{{ $t('user.settings.general.discoverableByEmail') }}
|
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
<div class="field">
|
|
|
|
<label class="checkbox">
|
|
|
|
<input type="checkbox" v-model="playSoundWhenDone"/>
|
|
|
|
{{ $t('user.settings.general.playSoundWhenDone') }}
|
|
|
|
</label>
|
|
|
|
</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>
|
|
|
|
</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">
|
2021-12-30 20:20:45 +00:00
|
|
|
<select v-model="settings.language">
|
2022-05-20 05:36:08 +00:00
|
|
|
<option
|
|
|
|
v-for="lang in availableLanguageOptions"
|
|
|
|
:key="lang.code"
|
|
|
|
:value="lang.code"
|
|
|
|
>{{ lang.title }}</option>
|
2021-10-26 20:58:02 +00:00
|
|
|
</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="quickAddMagicMode">
|
2022-05-20 05:36:08 +00:00
|
|
|
<option v-for="set in PrefixMode" :key="set" :value="set">
|
2021-10-26 20:58:02 +00:00
|
|
|
{{ $t(`user.settings.quickAddMagic.${set}`) }}
|
|
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</label>
|
|
|
|
</div>
|
2021-11-22 21:12:54 +00:00
|
|
|
<div class="field">
|
|
|
|
<label class="is-flex is-align-items-center">
|
2022-01-14 21:02:45 +00:00
|
|
|
<span>
|
|
|
|
{{ $t('user.settings.appearance.title') }}
|
|
|
|
</span>
|
2021-11-22 21:12:54 +00:00
|
|
|
<div class="select ml-2">
|
|
|
|
<select v-model="activeColorSchemeSetting">
|
|
|
|
<!-- 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>
|
2022-01-14 21:02:45 +00:00
|
|
|
<div class="field">
|
|
|
|
<label class="is-flex is-align-items-center">
|
|
|
|
<span>
|
|
|
|
{{ $t('user.settings.general.timezone') }}
|
|
|
|
</span>
|
|
|
|
<div class="select ml-2">
|
|
|
|
<select v-model="settings.timezone">
|
|
|
|
<option v-for="tz in availableTimezones" :key="tz">
|
|
|
|
{{ tz }}
|
|
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</label>
|
|
|
|
</div>
|
2021-10-26 20:58:02 +00:00
|
|
|
|
|
|
|
<x-button
|
2021-12-30 20:20:45 +00:00
|
|
|
:loading="loading"
|
2021-10-26 20:58:02 +00:00
|
|
|
@click="updateSettings()"
|
|
|
|
class="is-fullwidth mt-4"
|
2022-01-04 18:58:06 +00:00
|
|
|
v-cy="'saveGeneralSettings'"
|
2021-10-26 20:58:02 +00:00
|
|
|
>
|
|
|
|
{{ $t('misc.save') }}
|
|
|
|
</x-button>
|
|
|
|
</card>
|
|
|
|
</template>
|
|
|
|
|
2022-02-15 12:07:34 +00:00
|
|
|
<script lang="ts">
|
2022-05-20 05:36:08 +00:00
|
|
|
import {defineComponent} from 'vue'
|
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
name: 'user-settings-general',
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
import {computed, watch, ref, reactive} from 'vue'
|
2021-11-22 21:12:54 +00:00
|
|
|
import {useI18n} from 'vue-i18n'
|
2022-05-20 05:36:08 +00:00
|
|
|
import {useStore} from 'vuex'
|
|
|
|
|
|
|
|
import {PrefixMode} from '@/modules/parseTaskText'
|
|
|
|
|
|
|
|
import ListSearch from '@/components/tasks/partials/listSearch.vue'
|
2021-11-22 21:12:54 +00:00
|
|
|
|
2021-12-30 20:20:45 +00:00
|
|
|
import {availableLanguages} from '@/i18n'
|
2022-05-20 05:36:08 +00:00
|
|
|
import {playSoundWhenDoneKey, playPopSound} from '@/helpers/playPop'
|
2021-10-26 20:58:02 +00:00
|
|
|
import {getQuickAddMagicMode, setQuickAddMagicMode} from '@/helpers/quickAddMagicMode'
|
|
|
|
import {createRandomID} from '@/helpers/randomId'
|
2021-11-22 21:12:54 +00:00
|
|
|
import {success} from '@/message'
|
2022-01-14 21:02:45 +00:00
|
|
|
import {AuthenticatedHTTPFactory} from '@/http-common'
|
2021-11-22 21:12:54 +00:00
|
|
|
|
2022-05-20 05:36:08 +00:00
|
|
|
import {useColorScheme} from '@/composables/useColorScheme'
|
|
|
|
import { useTitle } from '@/composables/useTitle'
|
|
|
|
|
2022-05-23 05:23:59 +00:00
|
|
|
const {t} = useI18n({useScope: 'global'})
|
2022-05-20 05:36:08 +00:00
|
|
|
useTitle(() => `${t('user.settings.general.title')} - ${t('user.settings.title')}`)
|
|
|
|
|
2021-12-13 22:20:45 +00:00
|
|
|
const DEFAULT_LIST_ID = 0
|
|
|
|
|
2021-11-22 21:12:54 +00:00
|
|
|
function useColorSchemeSetting() {
|
2022-05-23 05:23:59 +00:00
|
|
|
const {t} = useI18n({useScope: 'global'})
|
2021-11-22 21:12:54 +00:00
|
|
|
const colorSchemeSettings = computed(() => ({
|
|
|
|
light: t('user.settings.appearance.colorScheme.light'),
|
|
|
|
auto: t('user.settings.appearance.colorScheme.system'),
|
|
|
|
dark: t('user.settings.appearance.colorScheme.dark'),
|
|
|
|
}))
|
|
|
|
|
|
|
|
const {store} = useColorScheme()
|
|
|
|
watch(store, (schemeId) => {
|
2021-12-13 22:20:45 +00:00
|
|
|
success({
|
|
|
|
message: t('user.settings.appearance.setSuccess', {
|
|
|
|
colorScheme: colorSchemeSettings.value[schemeId],
|
|
|
|
}),
|
|
|
|
})
|
2021-11-22 21:12:54 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
return {
|
|
|
|
colorSchemeSettings,
|
|
|
|
activeColorSchemeSetting: store,
|
|
|
|
}
|
|
|
|
}
|
2021-10-26 20:58:02 +00:00
|
|
|
|
2022-05-20 05:36:08 +00:00
|
|
|
const {colorSchemeSettings, activeColorSchemeSetting} = useColorSchemeSetting()
|
|
|
|
|
2022-01-14 21:02:45 +00:00
|
|
|
function useAvailableTimezones() {
|
|
|
|
const availableTimezones = ref([])
|
|
|
|
|
|
|
|
const HTTP = AuthenticatedHTTPFactory()
|
|
|
|
HTTP.get('user/timezones')
|
|
|
|
.then(r => {
|
|
|
|
availableTimezones.value = r.data.sort()
|
|
|
|
})
|
|
|
|
|
|
|
|
return availableTimezones
|
|
|
|
}
|
2022-05-20 05:36:08 +00:00
|
|
|
const availableTimezones = useAvailableTimezones()
|
2022-01-14 21:02:45 +00:00
|
|
|
|
2021-10-26 20:58:02 +00:00
|
|
|
function getPlaySoundWhenDoneSetting() {
|
|
|
|
return localStorage.getItem(playSoundWhenDoneKey) === 'true' || localStorage.getItem(playSoundWhenDoneKey) === null
|
|
|
|
}
|
|
|
|
|
2022-05-20 05:36:08 +00:00
|
|
|
const playSoundWhenDone = ref(getPlaySoundWhenDoneSetting())
|
|
|
|
const quickAddMagicMode = ref(getQuickAddMagicMode())
|
2021-11-22 21:12:54 +00:00
|
|
|
|
2022-05-20 05:36:08 +00:00
|
|
|
const store = useStore()
|
|
|
|
const settings = reactive({...store.state.auth.settings})
|
|
|
|
const id = ref(createRandomID())
|
|
|
|
const availableLanguageOptions = ref(
|
|
|
|
Object.entries(availableLanguages)
|
|
|
|
.map(l => ({code: l[0], title: l[1]}))
|
|
|
|
.sort((a, b) => a.title.localeCompare(b.title)),
|
|
|
|
)
|
|
|
|
|
|
|
|
const defaultList = computed({
|
|
|
|
get: () => store.getters['lists/getListById'](settings.defaultListId),
|
|
|
|
set(l) {
|
|
|
|
settings.defaultListId = l ? l.id : DEFAULT_LIST_ID
|
2021-10-26 20:58:02 +00:00
|
|
|
},
|
2022-02-15 12:07:59 +00:00
|
|
|
})
|
2022-05-20 05:36:08 +00:00
|
|
|
const loading = computed(() => store.state.loading && store.state.loadingModule === 'general-settings')
|
|
|
|
|
|
|
|
watch(
|
|
|
|
playSoundWhenDone,
|
|
|
|
(play) => play && playPopSound(),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
async function updateSettings() {
|
|
|
|
localStorage.setItem(playSoundWhenDoneKey, playSoundWhenDone.value ? 'true' : 'false')
|
|
|
|
setQuickAddMagicMode(quickAddMagicMode.value)
|
|
|
|
|
|
|
|
await store.dispatch('auth/saveUserSettings', {
|
|
|
|
settings: {...settings},
|
|
|
|
})
|
|
|
|
}
|
2021-10-26 20:58:02 +00:00
|
|
|
</script>
|