migrate app settings page to composition API and typescript
This commit is contained in:
@@ -1,7 +1,4 @@
|
||||
export interface TimezoneInfo {
|
||||
readonly displayName: string;
|
||||
readonly timezoneName: string;
|
||||
}
|
||||
import type { TimezoneInfo } from '@/core/timezone.ts';
|
||||
|
||||
export const UTC_TIMEZONE: TimezoneInfo = {
|
||||
displayName: 'Coordinated Universal Time',
|
||||
|
||||
@@ -13,4 +13,9 @@ export interface TypeAndDisplayName {
|
||||
readonly displayName: string;
|
||||
}
|
||||
|
||||
export interface LocalizedSwitchOption {
|
||||
readonly value: boolean;
|
||||
readonly displayName: string;
|
||||
}
|
||||
|
||||
export type BeforeResolveFunction = (callback: () => void) => void;
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
import type { TypeAndName } from './base.ts';
|
||||
|
||||
export interface TimezoneInfo {
|
||||
readonly displayName: string;
|
||||
readonly timezoneName: string;
|
||||
}
|
||||
|
||||
export interface LocalizedTimezoneInfo {
|
||||
readonly name: string;
|
||||
readonly utcOffset: string;
|
||||
readonly utcOffsetMinutes: number;
|
||||
readonly displayName: string;
|
||||
readonly displayNameWithUtcOffset: string;
|
||||
}
|
||||
|
||||
export class TimezoneTypeForStatistics implements TypeAndName {
|
||||
public static readonly ApplicationTimezone = new TimezoneTypeForStatistics(0, 'Application Timezone');
|
||||
public static readonly TransactionTimezone = new TimezoneTypeForStatistics(1, 'Transaction Timezone');
|
||||
|
||||
@@ -37,7 +37,7 @@ export function showAlert(message: string, confirmCallback: (dialog: Dialog.Dial
|
||||
});
|
||||
}
|
||||
|
||||
export function showConfirm(message: string, confirmCallback: (dialog: Dialog.Dialog, e: Event) => void, cancelCallback: (dialog: Dialog.Dialog, e: Event) => void, translateFn: TranslateFunction): void {
|
||||
export function showConfirm(message: string, confirmCallback: (dialog: Dialog.Dialog, e: Event) => void, cancelCallback: ((dialog: Dialog.Dialog, e: Event) => void) | undefined, translateFn: TranslateFunction): void {
|
||||
f7ready((f7) => {
|
||||
f7.dialog.create({
|
||||
title: translateFn('global.app.title'),
|
||||
@@ -230,7 +230,7 @@ export function useI18nUIComponents() {
|
||||
|
||||
return {
|
||||
showAlert: (message: string, confirmCallback: (dialog: Dialog.Dialog, e: Event) => void) => showAlert(message, confirmCallback, i18nGlobal.t),
|
||||
showConfirm: (message: string, confirmCallback: (dialog: Dialog.Dialog, e: Event) => void, cancelCallback: (dialog: Dialog.Dialog, e: Event) => void): void => showConfirm(message, confirmCallback, cancelCallback, i18nGlobal.t),
|
||||
showConfirm: (message: string, confirmCallback: (dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: (dialog: Dialog.Dialog, e: Event) => void): void => showConfirm(message, confirmCallback, cancelCallback, i18nGlobal.t),
|
||||
showToast: (message: string, timeout?: number): void => showToast(message, timeout, i18nGlobal.t),
|
||||
routeBackOnError
|
||||
}
|
||||
|
||||
@@ -1216,16 +1216,6 @@ function getAllSupportedImportFileTypes(i18nGlobal, translateFn) {
|
||||
return allSupportedImportFileTypes;
|
||||
}
|
||||
|
||||
function getEnableDisableOptions(translateFn) {
|
||||
return [{
|
||||
value: true,
|
||||
displayName: translateFn('Enable')
|
||||
},{
|
||||
value: false,
|
||||
displayName: translateFn('Disable')
|
||||
}];
|
||||
}
|
||||
|
||||
function getCategorizedAccountsWithDisplayBalance(allVisibleAccounts, showAccountBalance, defaultCurrency, userStore, settingsStore, exchangeRatesStore, translateFn) {
|
||||
const ret = [];
|
||||
const allCategories = AccountCategory.values();
|
||||
@@ -1546,7 +1536,6 @@ export function i18nFunctions(i18nGlobal) {
|
||||
getAllTransactionDefaultCategories: (categoryType, locale) => getAllTransactionDefaultCategories(categoryType, locale, i18nGlobal.t),
|
||||
getAllDisplayExchangeRates: (settingsStore, exchangeRatesData) => getAllDisplayExchangeRates(settingsStore, exchangeRatesData, i18nGlobal.t),
|
||||
getAllSupportedImportFileTypes: () => getAllSupportedImportFileTypes(i18nGlobal, i18nGlobal.t),
|
||||
getEnableDisableOptions: () => getEnableDisableOptions(i18nGlobal.t),
|
||||
getCategorizedAccountsWithDisplayBalance: (allVisibleAccounts, showAccountBalance, defaultCurrency, settingsStore, userStore, exchangeRatesStore) => getCategorizedAccountsWithDisplayBalance(allVisibleAccounts, showAccountBalance, defaultCurrency, userStore, settingsStore, exchangeRatesStore, i18nGlobal.t),
|
||||
getServerTipContent: (tipConfig) => getServerTipContent(tipConfig, i18nGlobal),
|
||||
joinMultiText: (textArray) => joinMultiText(textArray, i18nGlobal.t),
|
||||
|
||||
+95
-1
@@ -1,7 +1,7 @@
|
||||
import { useI18n as useVueI18n } from 'vue-i18n';
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
import type { TypeAndName, TypeAndDisplayName } from '@/core/base.ts';
|
||||
import type {TypeAndName, TypeAndDisplayName, LocalizedSwitchOption } from '@/core/base.ts';
|
||||
|
||||
import { type LanguageInfo, allLanguages, DEFAULT_LANGUAGE } from '@/locales/index.ts';
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
} from '@/core/datetime.ts';
|
||||
|
||||
import {
|
||||
type LocalizedTimezoneInfo,
|
||||
TimezoneTypeForStatistics
|
||||
} from '@/core/timezone.ts';
|
||||
|
||||
@@ -69,6 +70,7 @@ import {
|
||||
import type { LocaleDefaultSettings } from '@/core/setting.ts';
|
||||
import type { ErrorResponse } from '@/core/api.ts';
|
||||
|
||||
import { UTC_TIMEZONE, ALL_TIMEZONES } from '@/consts/timezone.ts';
|
||||
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
||||
import { KnownErrorCode, SPECIFIED_API_NOT_FOUND_ERRORS, PARAMETERIZED_ERRORS } from '@/consts/api.ts';
|
||||
|
||||
@@ -85,6 +87,10 @@ import {
|
||||
isPM,
|
||||
formatUnixTime,
|
||||
getTimezoneOffset,
|
||||
getTimezoneOffsetMinutes,
|
||||
getBrowserTimezoneOffset,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getTimeDifferenceHoursAndMinutes,
|
||||
getDateTimeFormatType,
|
||||
getRecentMonthDateRanges
|
||||
} from '@/lib/datetime.ts';
|
||||
@@ -534,6 +540,16 @@ export function useI18n() {
|
||||
return t('default.firstDayOfWeek');
|
||||
}
|
||||
|
||||
function getAllEnableDisableOptions(): LocalizedSwitchOption[] {
|
||||
return [{
|
||||
value: true,
|
||||
displayName: t('Enable')
|
||||
},{
|
||||
value: false,
|
||||
displayName: t('Disable')
|
||||
}];
|
||||
}
|
||||
|
||||
function getAllMeridiemIndicators(): LocalizedMeridiemIndicator {
|
||||
const allMeridiemIndicators = MeridiemIndicator.values();
|
||||
const meridiemIndicatorNames = [];
|
||||
@@ -674,6 +690,50 @@ export function useI18n() {
|
||||
return allRecentMonthDateRanges;
|
||||
}
|
||||
|
||||
function getAllTimezones(includeSystemDefault?: boolean): LocalizedTimezoneInfo[] {
|
||||
const defaultTimezoneOffset = getBrowserTimezoneOffset();
|
||||
const defaultTimezoneOffsetMinutes = getBrowserTimezoneOffsetMinutes();
|
||||
const allTimezoneInfos: LocalizedTimezoneInfo[] = [];
|
||||
|
||||
for (let i = 0; i < ALL_TIMEZONES.length; i++) {
|
||||
const utcOffset = (ALL_TIMEZONES[i].timezoneName !== UTC_TIMEZONE.timezoneName ? getTimezoneOffset(ALL_TIMEZONES[i].timezoneName) : '');
|
||||
const displayName = t(`timezone.${ALL_TIMEZONES[i].displayName}`);
|
||||
|
||||
allTimezoneInfos.push({
|
||||
name: ALL_TIMEZONES[i].timezoneName,
|
||||
utcOffset: utcOffset,
|
||||
utcOffsetMinutes: getTimezoneOffsetMinutes(ALL_TIMEZONES[i].timezoneName),
|
||||
displayName: displayName,
|
||||
displayNameWithUtcOffset: `(UTC${utcOffset}) ${displayName}`
|
||||
});
|
||||
}
|
||||
|
||||
if (includeSystemDefault) {
|
||||
const defaultDisplayName = t('System Default');
|
||||
|
||||
allTimezoneInfos.push({
|
||||
name: '',
|
||||
utcOffset: defaultTimezoneOffset,
|
||||
utcOffsetMinutes: defaultTimezoneOffsetMinutes,
|
||||
displayName: defaultDisplayName,
|
||||
displayNameWithUtcOffset: `(UTC${defaultTimezoneOffset}) ${defaultDisplayName}`
|
||||
});
|
||||
}
|
||||
|
||||
allTimezoneInfos.sort(function(c1, c2) {
|
||||
const utcOffset1 = parseInt(c1.utcOffset.replace(':', ''));
|
||||
const utcOffset2 = parseInt(c2.utcOffset.replace(':', ''));
|
||||
|
||||
if (utcOffset1 !== utcOffset2) {
|
||||
return utcOffset1 - utcOffset2;
|
||||
}
|
||||
|
||||
return c1.displayName.localeCompare(c2.displayName);
|
||||
})
|
||||
|
||||
return allTimezoneInfos;
|
||||
}
|
||||
|
||||
function getAllTimezoneTypesUsedForStatistics(currentTimezone?: string): TypeAndDisplayName[] {
|
||||
const currentTimezoneOffset = getTimezoneOffset(currentTimezone);
|
||||
|
||||
@@ -934,6 +994,37 @@ export function useI18n() {
|
||||
}
|
||||
}
|
||||
|
||||
function getTimezoneDifferenceDisplayText(utcOffset: number): string {
|
||||
const defaultTimezoneOffset = getTimezoneOffsetMinutes();
|
||||
const offsetTime = getTimeDifferenceHoursAndMinutes(utcOffset - defaultTimezoneOffset);
|
||||
|
||||
if (utcOffset > defaultTimezoneOffset) {
|
||||
if (offsetTime.offsetMinutes) {
|
||||
return t('format.misc.hoursMinutesAheadOfDefaultTimezone', {
|
||||
hours: offsetTime.offsetHours,
|
||||
minutes: offsetTime.offsetMinutes
|
||||
});
|
||||
} else {
|
||||
return t('format.misc.hoursAheadOfDefaultTimezone', {
|
||||
hours: offsetTime.offsetHours
|
||||
});
|
||||
}
|
||||
} else if (utcOffset < defaultTimezoneOffset) {
|
||||
if (offsetTime.offsetMinutes) {
|
||||
return t('format.misc.hoursMinutesBehindDefaultTimezone', {
|
||||
hours: offsetTime.offsetHours,
|
||||
minutes: offsetTime.offsetMinutes
|
||||
});
|
||||
} else {
|
||||
return t('format.misc.hoursBehindDefaultTimezone', {
|
||||
hours: offsetTime.offsetHours
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return t('Same time as default timezone');
|
||||
}
|
||||
}
|
||||
|
||||
function getNumberWithDigitGroupingSymbol(value: number | string): string {
|
||||
const numberFormatOptions = getNumberFormatOptions();
|
||||
return appendDigitGroupingSymbol(value, numberFormatOptions);
|
||||
@@ -1105,6 +1196,7 @@ export function useI18n() {
|
||||
getDefaultCurrency,
|
||||
getDefaultFirstDayOfWeek,
|
||||
// get all localized info of specified type
|
||||
getAllEnableDisableOptions,
|
||||
getAllMeridiemIndicators,
|
||||
getAllLongMonthNames,
|
||||
getAllShortMonthNames,
|
||||
@@ -1114,6 +1206,7 @@ export function useI18n() {
|
||||
getAllWeekDays,
|
||||
getAllDateRanges,
|
||||
getAllRecentMonthDateRanges,
|
||||
getAllTimezones,
|
||||
getAllTimezoneTypesUsedForStatistics,
|
||||
getAllDecimalSeparators: () => getLocalizedNumeralSeparatorFormats(DecimalSeparator.values(), DecimalSeparator.parse(t('default.decimalSeparator')), DecimalSeparator.Default, DecimalSeparator.LanguageDefaultType),
|
||||
getAllDigitGroupingSymbols: () => getLocalizedNumeralSeparatorFormats(DigitGroupingSymbol.values(), DigitGroupingSymbol.parse(t('default.digitGroupingSymbol')), DigitGroupingSymbol.Default, DigitGroupingSymbol.LanguageDefaultType),
|
||||
@@ -1164,6 +1257,7 @@ export function useI18n() {
|
||||
formatUnixTimeToLongTime: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedLongTimeFormat(), utcOffset, currentUtcOffset),
|
||||
formatUnixTimeToShortTime: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortTimeFormat(), utcOffset, currentUtcOffset),
|
||||
formatYearQuarter,
|
||||
getTimezoneDifferenceDisplayText,
|
||||
appendDigitGroupingSymbol: getNumberWithDigitGroupingSymbol,
|
||||
parseAmount: getParsedAmountNumber,
|
||||
formatAmount: getFormattedAmount,
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
// @ts-expect-error the above file is migrating to ts
|
||||
import { useTransactionsStore } from '@/stores/transaction.js';
|
||||
import { useOverviewStore } from '@/stores/overview.ts';
|
||||
// @ts-expect-error the above file is migrating to ts
|
||||
import { useStatisticsStore } from '@/stores/statistics.js';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import type { LocalizedTimezoneInfo } from '@/core/timezone.ts';
|
||||
|
||||
export function useAppSettingPageBase() {
|
||||
const { getAllTimezones, getAllTimezoneTypesUsedForStatistics, getAllCurrencySortingTypes, setTimeZone } = useI18n();
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const transactionsStore = useTransactionsStore();
|
||||
const overviewStore = useOverviewStore();
|
||||
const statisticsStore = useStatisticsStore();
|
||||
|
||||
const allTimezones = computed<LocalizedTimezoneInfo[]>(() => getAllTimezones(true));
|
||||
const allTimezoneTypesUsedForStatistics = computed<TypeAndDisplayName[]>(() => getAllTimezoneTypesUsedForStatistics());
|
||||
const allCurrencySortingTypes = computed<TypeAndDisplayName[]>(() => getAllCurrencySortingTypes());
|
||||
|
||||
const timeZone = computed<string>({
|
||||
get: () => settingsStore.appSettings.timeZone,
|
||||
set: (value) => {
|
||||
settingsStore.setTimeZone(value);
|
||||
setTimeZone(value);
|
||||
transactionsStore.updateTransactionListInvalidState(true);
|
||||
overviewStore.updateTransactionOverviewInvalidState(true);
|
||||
statisticsStore.updateTransactionStatisticsInvalidState(true);
|
||||
}
|
||||
});
|
||||
|
||||
const isAutoUpdateExchangeRatesData = computed<boolean>({
|
||||
get: () => settingsStore.appSettings.autoUpdateExchangeRatesData,
|
||||
set: (value) => settingsStore.setAutoUpdateExchangeRatesData(value)
|
||||
});
|
||||
|
||||
const showAccountBalance = computed<boolean>({
|
||||
get: () => settingsStore.appSettings.showAccountBalance,
|
||||
set: (value) => settingsStore.setShowAccountBalance(value)
|
||||
});
|
||||
|
||||
const showAmountInHomePage = computed<boolean>({
|
||||
get: () => settingsStore.appSettings.showAmountInHomePage,
|
||||
set: (value) => settingsStore.setShowAmountInHomePage(value)
|
||||
});
|
||||
|
||||
const timezoneUsedForStatisticsInHomePage = computed<number>({
|
||||
get: () => settingsStore.appSettings.timezoneUsedForStatisticsInHomePage,
|
||||
set: (value: number) => {
|
||||
settingsStore.setTimezoneUsedForStatisticsInHomePage(value);
|
||||
overviewStore.updateTransactionOverviewInvalidState(true);
|
||||
}
|
||||
});
|
||||
|
||||
const showTotalAmountInTransactionListPage = computed<boolean>({
|
||||
get: () => settingsStore.appSettings.showTotalAmountInTransactionListPage,
|
||||
set: (value) => settingsStore.setShowTotalAmountInTransactionListPage(value)
|
||||
});
|
||||
|
||||
const showTagInTransactionListPage = computed<boolean>({
|
||||
get: () => settingsStore.appSettings.showTagInTransactionListPage,
|
||||
set: (value) => settingsStore.setShowTagInTransactionListPage(value)
|
||||
});
|
||||
|
||||
const itemsCountInTransactionListPage = computed<number>({
|
||||
get: () => settingsStore.appSettings.itemsCountInTransactionListPage,
|
||||
set: (value) => settingsStore.setItemsCountInTransactionListPage(value)
|
||||
});
|
||||
|
||||
const autoSaveTransactionDraft = computed<string>({
|
||||
get: () => settingsStore.appSettings.autoSaveTransactionDraft,
|
||||
set: (value: string) => {
|
||||
settingsStore.setAutoSaveTransactionDraft(value);
|
||||
|
||||
if (value === 'disabled') {
|
||||
transactionsStore.clearTransactionDraft();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const isAutoGetCurrentGeoLocation = computed<boolean>({
|
||||
get: () => settingsStore.appSettings.autoGetCurrentGeoLocation,
|
||||
set: (value) => settingsStore.setAutoGetCurrentGeoLocation(value)
|
||||
});
|
||||
|
||||
const currencySortByInExchangeRatesPage = computed<number>({
|
||||
get: () => settingsStore.appSettings.currencySortByInExchangeRatesPage,
|
||||
set: (value: number) => settingsStore.setCurrencySortByInExchangeRatesPage(value)
|
||||
});
|
||||
|
||||
return {
|
||||
// computed states
|
||||
allTimezones,
|
||||
allTimezoneTypesUsedForStatistics,
|
||||
allCurrencySortingTypes,
|
||||
timeZone,
|
||||
isAutoUpdateExchangeRatesData,
|
||||
showAccountBalance,
|
||||
showAmountInHomePage,
|
||||
itemsCountInTransactionListPage,
|
||||
timezoneUsedForStatisticsInHomePage,
|
||||
showTotalAmountInTransactionListPage,
|
||||
showTagInTransactionListPage,
|
||||
autoSaveTransactionDraft,
|
||||
isAutoGetCurrentGeoLocation,
|
||||
currencySortByInExchangeRatesPage
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-card :title="$t('Basic Settings')">
|
||||
<v-card :title="tt('Basic Settings')">
|
||||
<v-form>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
@@ -10,14 +10,14 @@
|
||||
item-title="displayName"
|
||||
item-value="value"
|
||||
persistent-placeholder
|
||||
:label="$t('Theme')"
|
||||
:placeholder="$t('Theme')"
|
||||
:label="tt('Theme')"
|
||||
:placeholder="tt('Theme')"
|
||||
:items="[
|
||||
{ value: 'auto', displayName: $t('System Default') },
|
||||
{ value: 'light', displayName: $t('Light') },
|
||||
{ value: 'dark', displayName: $t('Dark') }
|
||||
{ value: 'auto', displayName: tt('System Default') },
|
||||
{ value: 'light', displayName: tt('Light') },
|
||||
{ value: 'dark', displayName: tt('Dark') }
|
||||
]"
|
||||
v-model="theme"
|
||||
v-model="currentTheme"
|
||||
/>
|
||||
</v-col>
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
item-value="name"
|
||||
auto-select-first
|
||||
persistent-placeholder
|
||||
:label="$t('Timezone')"
|
||||
:placeholder="$t('Timezone')"
|
||||
:label="tt('Timezone')"
|
||||
:placeholder="tt('Timezone')"
|
||||
:items="allTimezones"
|
||||
:no-data-text="$t('No results')"
|
||||
:no-data-text="tt('No results')"
|
||||
v-model="timeZone"
|
||||
/>
|
||||
</v-col>
|
||||
@@ -40,8 +40,8 @@
|
||||
item-title="displayName"
|
||||
item-value="value"
|
||||
persistent-placeholder
|
||||
:label="$t('Auto-update Exchange Rates Data')"
|
||||
:placeholder="$t('Auto-update Exchange Rates Data')"
|
||||
:label="tt('Auto-update Exchange Rates Data')"
|
||||
:placeholder="tt('Auto-update Exchange Rates Data')"
|
||||
:items="enableDisableOptions"
|
||||
v-model="isAutoUpdateExchangeRatesData"
|
||||
/>
|
||||
@@ -52,8 +52,8 @@
|
||||
item-title="displayName"
|
||||
item-value="value"
|
||||
persistent-placeholder
|
||||
:label="$t('Show Account Balance')"
|
||||
:placeholder="$t('Show Account Balance')"
|
||||
:label="tt('Show Account Balance')"
|
||||
:placeholder="tt('Show Account Balance')"
|
||||
:items="enableDisableOptions"
|
||||
v-model="showAccountBalance"
|
||||
/>
|
||||
@@ -65,7 +65,7 @@
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12">
|
||||
<v-card :title="$t('Overview Page')">
|
||||
<v-card :title="tt('Overview Page')">
|
||||
<v-form>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
@@ -74,8 +74,8 @@
|
||||
item-title="displayName"
|
||||
item-value="value"
|
||||
persistent-placeholder
|
||||
:label="$t('Show Amount')"
|
||||
:placeholder="$t('Show Amount')"
|
||||
:label="tt('Show Amount')"
|
||||
:placeholder="tt('Show Amount')"
|
||||
:items="enableDisableOptions"
|
||||
v-model="showAmountInHomePage"
|
||||
/>
|
||||
@@ -86,8 +86,8 @@
|
||||
item-title="displayName"
|
||||
item-value="type"
|
||||
persistent-placeholder
|
||||
:label="$t('Timezone Used for Statistics')"
|
||||
:placeholder="$t('Timezone Used for Statistics')"
|
||||
:label="tt('Timezone Used for Statistics')"
|
||||
:placeholder="tt('Timezone Used for Statistics')"
|
||||
:items="allTimezoneTypesUsedForStatistics"
|
||||
v-model="timezoneUsedForStatisticsInHomePage"
|
||||
/>
|
||||
@@ -99,15 +99,15 @@
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12">
|
||||
<v-card :title="$t('Transaction List Page')">
|
||||
<v-card :title="tt('Transaction List Page')">
|
||||
<v-form>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
persistent-placeholder
|
||||
:label="$t('Transactions Per Page')"
|
||||
:placeholder="$t('Transactions Per Page')"
|
||||
:label="tt('Transactions Per Page')"
|
||||
:placeholder="tt('Transactions Per Page')"
|
||||
:items="[ 5, 10, 15, 20, 25, 30, 50 ]"
|
||||
v-model="itemsCountInTransactionListPage"
|
||||
/>
|
||||
@@ -117,8 +117,8 @@
|
||||
item-title="displayName"
|
||||
item-value="value"
|
||||
persistent-placeholder
|
||||
:label="$t('Show Monthly Total Amount')"
|
||||
:placeholder="$t('Show Monthly Total Amount')"
|
||||
:label="tt('Show Monthly Total Amount')"
|
||||
:placeholder="tt('Show Monthly Total Amount')"
|
||||
:items="enableDisableOptions"
|
||||
v-model="showTotalAmountInTransactionListPage"
|
||||
/>
|
||||
@@ -128,8 +128,8 @@
|
||||
item-title="displayName"
|
||||
item-value="value"
|
||||
persistent-placeholder
|
||||
:label="$t('Show Transaction Tag')"
|
||||
:placeholder="$t('Show Transaction Tag')"
|
||||
:label="tt('Show Transaction Tag')"
|
||||
:placeholder="tt('Show Transaction Tag')"
|
||||
:items="enableDisableOptions"
|
||||
v-model="showTagInTransactionListPage"
|
||||
/>
|
||||
@@ -141,7 +141,7 @@
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12">
|
||||
<v-card :title="$t('Transaction Edit Page')">
|
||||
<v-card :title="tt('Transaction Edit Page')">
|
||||
<v-form>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
@@ -150,12 +150,12 @@
|
||||
item-title="displayName"
|
||||
item-value="value"
|
||||
persistent-placeholder
|
||||
:label="$t('Automatically Save Draft')"
|
||||
:placeholder="$t('Automatically Save Draft')"
|
||||
:label="tt('Automatically Save Draft')"
|
||||
:placeholder="tt('Automatically Save Draft')"
|
||||
:items="[
|
||||
{ value: 'disabled', displayName: $t('Disabled') },
|
||||
{ value: 'enabled', displayName: $t('Enabled') },
|
||||
{ value: 'confirmation', displayName: $t('Show Confirmation Every Time') }
|
||||
{ value: 'disabled', displayName: tt('Disabled') },
|
||||
{ value: 'enabled', displayName: tt('Enabled') },
|
||||
{ value: 'confirmation', displayName: tt('Show Confirmation Every Time') }
|
||||
]"
|
||||
v-model="autoSaveTransactionDraft"
|
||||
/>
|
||||
@@ -166,8 +166,8 @@
|
||||
item-title="displayName"
|
||||
item-value="value"
|
||||
persistent-placeholder
|
||||
:label="$t('Automatically Add Geolocation')"
|
||||
:placeholder="$t('Automatically Add Geolocation')"
|
||||
:label="tt('Automatically Add Geolocation')"
|
||||
:placeholder="tt('Automatically Add Geolocation')"
|
||||
:items="enableDisableOptions"
|
||||
v-model="isAutoGetCurrentGeoLocation"
|
||||
/>
|
||||
@@ -179,7 +179,7 @@
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12">
|
||||
<v-card :title="$t('Exchange Rates Data Page')">
|
||||
<v-card :title="tt('Exchange Rates Data Page')">
|
||||
<v-form>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
@@ -188,8 +188,8 @@
|
||||
item-title="displayName"
|
||||
item-value="type"
|
||||
persistent-placeholder
|
||||
:label="$t('Sort by')"
|
||||
:placeholder="$t('Sort by')"
|
||||
:label="tt('Sort by')"
|
||||
:placeholder="tt('Sort by')"
|
||||
:items="allCurrencySortingTypes"
|
||||
v-model="currencySortByInExchangeRatesPage"
|
||||
/>
|
||||
@@ -202,156 +202,54 @@
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useTheme } from 'vuetify';
|
||||
|
||||
import { mapStores } from 'pinia';
|
||||
import { useRootStore } from '@/stores/index.js';
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useAppSettingPageBase } from '@/views/base/settings/AppSettingsPageBase.ts';
|
||||
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
import { useTransactionsStore } from '@/stores/transaction.js';
|
||||
import { useOverviewStore } from '@/stores/overview.ts';
|
||||
import { useStatisticsStore } from '@/stores/statistics.js';
|
||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { getSystemTheme } from '@/lib/ui/common.ts';
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapStores(useRootStore, useSettingsStore, useUserStore, useTransactionsStore, useOverviewStore, useStatisticsStore, useExchangeRatesStore),
|
||||
enableDisableOptions() {
|
||||
return this.$locale.getEnableDisableOptions();
|
||||
},
|
||||
allTimezones() {
|
||||
return this.$locale.getAllTimezones(true);
|
||||
},
|
||||
allTimezoneTypesUsedForStatistics() {
|
||||
return this.$locale.getAllTimezoneTypesUsedForStatistics(this.timeZone);
|
||||
},
|
||||
allCurrencySortingTypes() {
|
||||
return this.$locale.getAllCurrencySortingTypes();
|
||||
},
|
||||
theme: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.theme;
|
||||
},
|
||||
set: function (value) {
|
||||
if (value !== this.settingsStore.appSettings.theme) {
|
||||
this.settingsStore.setTheme(value);
|
||||
const theme = useTheme();
|
||||
|
||||
if (value === ThemeType.Light || value === ThemeType.Dark) {
|
||||
this.globalTheme.global.name.value = value;
|
||||
} else {
|
||||
this.globalTheme.global.name.value = getSystemTheme();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
timeZone: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.timeZone;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setTimeZone(value);
|
||||
this.$locale.setTimeZone(value);
|
||||
this.transactionsStore.updateTransactionListInvalidState(true);
|
||||
this.overviewStore.updateTransactionOverviewInvalidState(true);
|
||||
this.statisticsStore.updateTransactionStatisticsInvalidState(true);
|
||||
}
|
||||
},
|
||||
isAutoUpdateExchangeRatesData: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.autoUpdateExchangeRatesData;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setAutoUpdateExchangeRatesData(value);
|
||||
}
|
||||
},
|
||||
showAccountBalance: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.showAccountBalance;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setShowAccountBalance(value);
|
||||
}
|
||||
},
|
||||
showAmountInHomePage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.showAmountInHomePage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setShowAmountInHomePage(value);
|
||||
}
|
||||
},
|
||||
timezoneUsedForStatisticsInHomePage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.timezoneUsedForStatisticsInHomePage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setTimezoneUsedForStatisticsInHomePage(value);
|
||||
this.overviewStore.updateTransactionOverviewInvalidState(true);
|
||||
}
|
||||
},
|
||||
showTotalAmountInTransactionListPage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.showTotalAmountInTransactionListPage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setShowTotalAmountInTransactionListPage(value);
|
||||
}
|
||||
},
|
||||
showTagInTransactionListPage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.showTagInTransactionListPage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setShowTagInTransactionListPage(value);
|
||||
}
|
||||
},
|
||||
itemsCountInTransactionListPage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.itemsCountInTransactionListPage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setItemsCountInTransactionListPage(value);
|
||||
}
|
||||
},
|
||||
autoSaveTransactionDraft: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.autoSaveTransactionDraft;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setAutoSaveTransactionDraft(value);
|
||||
const { tt, getAllEnableDisableOptions } = useI18n();
|
||||
const {
|
||||
allTimezones,
|
||||
allTimezoneTypesUsedForStatistics,
|
||||
allCurrencySortingTypes,
|
||||
timeZone,
|
||||
isAutoUpdateExchangeRatesData,
|
||||
showAccountBalance,
|
||||
showAmountInHomePage,
|
||||
itemsCountInTransactionListPage,
|
||||
timezoneUsedForStatisticsInHomePage,
|
||||
showTotalAmountInTransactionListPage,
|
||||
showTagInTransactionListPage,
|
||||
autoSaveTransactionDraft,
|
||||
isAutoGetCurrentGeoLocation,
|
||||
currencySortByInExchangeRatesPage
|
||||
} = useAppSettingPageBase();
|
||||
|
||||
if (value === 'disabled') {
|
||||
this.transactionsStore.clearTransactionDraft();
|
||||
}
|
||||
}
|
||||
},
|
||||
isAutoGetCurrentGeoLocation: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.autoGetCurrentGeoLocation;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setAutoGetCurrentGeoLocation(value);
|
||||
}
|
||||
},
|
||||
currencySortByInExchangeRatesPage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.currencySortByInExchangeRatesPage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setCurrencySortByInExchangeRatesPage(value);
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const enableDisableOptions = computed(() => getAllEnableDisableOptions());
|
||||
|
||||
const currentTheme = computed<string>({
|
||||
get: () => settingsStore.appSettings.theme,
|
||||
set: (value: string) => {
|
||||
if (value !== settingsStore.appSettings.theme) {
|
||||
settingsStore.setTheme(value);
|
||||
|
||||
if (value === ThemeType.Light || value === ThemeType.Dark) {
|
||||
theme.global.name.value = value;
|
||||
} else {
|
||||
theme.global.name.value = getSystemTheme();
|
||||
}
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const theme = useTheme();
|
||||
|
||||
return {
|
||||
globalTheme: theme
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
+114
-152
@@ -1,212 +1,174 @@
|
||||
<template>
|
||||
<f7-page @page:afterin="onPageAfterIn">
|
||||
<f7-navbar :title="$t('Settings')" :back-link="$t('Back')"></f7-navbar>
|
||||
<f7-navbar :title="tt('Settings')" :back-link="tt('Back')"></f7-navbar>
|
||||
|
||||
<f7-block-title class="margin-top">{{ currentNickName }}</f7-block-title>
|
||||
<f7-list strong inset dividers>
|
||||
<f7-list-item :title="$t('User Profile')" link="/user/profile"></f7-list-item>
|
||||
<f7-list-item :title="$t('Transaction Categories')" link="/category/all"></f7-list-item>
|
||||
<f7-list-item :title="$t('Transaction Tags')" link="/tag/list"></f7-list-item>
|
||||
<f7-list-item :title="$t('Transaction Templates')" link="/template/list"></f7-list-item>
|
||||
<f7-list-item :title="$t('Scheduled Transactions')" link="/schedule/list" v-if="isUserScheduledTransactionEnabled"></f7-list-item>
|
||||
<f7-list-item :title="$t('Data Management')" link="/user/data/management"></f7-list-item>
|
||||
<f7-list-item :title="$t('Two-Factor Authentication')" link="/user/2fa"></f7-list-item>
|
||||
<f7-list-item :title="$t('Device & Sessions')" link="/user/sessions"></f7-list-item>
|
||||
<f7-list-button :class="{ 'disabled': logouting }" @click="logout">{{ $t('Log Out') }}</f7-list-button>
|
||||
<f7-list-item :title="tt('User Profile')" link="/user/profile"></f7-list-item>
|
||||
<f7-list-item :title="tt('Transaction Categories')" link="/category/all"></f7-list-item>
|
||||
<f7-list-item :title="tt('Transaction Tags')" link="/tag/list"></f7-list-item>
|
||||
<f7-list-item :title="tt('Transaction Templates')" link="/template/list"></f7-list-item>
|
||||
<f7-list-item :title="tt('Scheduled Transactions')" link="/schedule/list" v-if="isUserScheduledTransactionEnabled()"></f7-list-item>
|
||||
<f7-list-item :title="tt('Data Management')" link="/user/data/management"></f7-list-item>
|
||||
<f7-list-item :title="tt('Two-Factor Authentication')" link="/user/2fa"></f7-list-item>
|
||||
<f7-list-item :title="tt('Device & Sessions')" link="/user/sessions"></f7-list-item>
|
||||
<f7-list-button :class="{ 'disabled': logouting }" @click="logout">{{ tt('Log Out') }}</f7-list-button>
|
||||
</f7-list>
|
||||
|
||||
<f7-block-title>{{ $t('Application') }}</f7-block-title>
|
||||
<f7-block-title>{{ tt('Application') }}</f7-block-title>
|
||||
<f7-list strong inset dividers>
|
||||
<f7-list-item
|
||||
:key="currentLocale + '_theme'"
|
||||
:title="$t('Theme')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Theme'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
|
||||
<select v-model="theme">
|
||||
<option value="auto">{{ $t('System Default') }}</option>
|
||||
<option value="light">{{ $t('Light') }}</option>
|
||||
<option value="dark">{{ $t('Dark') }}</option>
|
||||
:title="tt('Theme')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: tt('Theme'), searchbarDisableText: tt('Cancel'), appendSearchbarNotFound: tt('No results'), popupCloseLinkText: tt('Done') }">
|
||||
<select v-model="currentTheme">
|
||||
<option value="auto">{{ tt('System Default') }}</option>
|
||||
<option value="light">{{ tt('Light') }}</option>
|
||||
<option value="dark">{{ tt('Dark') }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Text Size')" link="/settings/textsize"></f7-list-item>
|
||||
<f7-list-item :title="tt('Text Size')" link="/settings/textsize"></f7-list-item>
|
||||
|
||||
<f7-list-item
|
||||
:key="currentLocale + '_timezone'"
|
||||
:title="$t('Timezone')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Timezone'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
|
||||
:title="tt('Timezone')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: tt('Timezone'), searchbarDisableText: tt('Cancel'), appendSearchbarNotFound: tt('No results'), popupCloseLinkText: tt('Done') }">
|
||||
<select v-model="timeZone">
|
||||
<option :value="tz.name" :key="tz.name"
|
||||
v-for="tz in allTimezones">{{ tz.displayNameWithUtcOffset }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Application Lock')" :after="isEnableApplicationLock ? $t('Enabled') : $t('Disabled')" link="/app_lock"></f7-list-item>
|
||||
<f7-list-item :title="tt('Application Lock')" :after="isEnableApplicationLock ? tt('Enabled') : tt('Disabled')" link="/app_lock"></f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Exchange Rates Data')" :after="exchangeRatesLastUpdateDate" link="/exchange_rates"></f7-list-item>
|
||||
<f7-list-item :title="tt('Exchange Rates Data')" :after="exchangeRatesLastUpdateDate" link="/exchange_rates"></f7-list-item>
|
||||
|
||||
<f7-list-item>
|
||||
<span>{{ $t('Auto-update Exchange Rates Data') }}</span>
|
||||
<span>{{ tt('Auto-update Exchange Rates Data') }}</span>
|
||||
<f7-toggle :checked="isAutoUpdateExchangeRatesData" @toggle:change="isAutoUpdateExchangeRatesData = $event"></f7-toggle>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item>
|
||||
<span>{{ $t('Show Account Balance') }}</span>
|
||||
<span>{{ tt('Show Account Balance') }}</span>
|
||||
<f7-toggle :checked="showAccountBalance" @toggle:change="showAccountBalance = $event"></f7-toggle>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Page Settings')" link="/settings/page"></f7-list-item>
|
||||
<f7-list-item :title="tt('Page Settings')" link="/settings/page"></f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Statistics Settings')" link="/statistic/settings"></f7-list-item>
|
||||
<f7-list-item :title="tt('Statistics Settings')" link="/statistic/settings"></f7-list-item>
|
||||
|
||||
<f7-list-item>
|
||||
<span>{{ $t('Enable Animation') }}</span>
|
||||
<span>{{ tt('Enable Animation') }}</span>
|
||||
<f7-toggle :checked="isEnableAnimate" @toggle:change="isEnableAnimate = $event"></f7-toggle>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Switch to Desktop Version')" @click="switchToDesktopVersion"></f7-list-item>
|
||||
<f7-list-item :title="tt('Switch to Desktop Version')" @click="switchToDesktopVersion"></f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('About')" link="/about" :after="version"></f7-list-item>
|
||||
<f7-list-item :title="tt('About')" link="/about" :after="version"></f7-list-item>
|
||||
</f7-list>
|
||||
</f7-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapStores } from 'pinia';
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import type { Router } from 'framework7/types';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useI18nUIComponents, showLoading, hideLoading } from '@/lib/ui/mobile.ts';
|
||||
import { useAppSettingPageBase } from '@/views/base/settings/AppSettingsPageBase.ts';
|
||||
|
||||
import { useRootStore } from '@/stores/index.js';
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
import { useTransactionsStore } from '@/stores/transaction.js';
|
||||
import { useOverviewStore } from '@/stores/overview.ts';
|
||||
import { useStatisticsStore } from '@/stores/statistics.js';
|
||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||
|
||||
import { getDesktopVersionPath } from '@/lib/version.ts';
|
||||
import { getVersion, getDesktopVersionPath } from '@/lib/version.ts';
|
||||
import { isUserScheduledTransactionEnabled } from '@/lib/server_settings.ts';
|
||||
import { setExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
'f7router'
|
||||
],
|
||||
data() {
|
||||
const self = this;
|
||||
const { tt, getCurrentLanguageTag, formatUnixTimeToLongDate, initLocale } = useI18n();
|
||||
const { showToast, showConfirm } = useI18nUIComponents();
|
||||
const { allTimezones, timeZone, isAutoUpdateExchangeRatesData, showAccountBalance } = useAppSettingPageBase();
|
||||
|
||||
return {
|
||||
currentLocale: self.$locale.getCurrentLanguageTag(),
|
||||
logouting: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useRootStore, useSettingsStore, useUserStore, useTransactionsStore, useOverviewStore, useStatisticsStore, useExchangeRatesStore),
|
||||
version() {
|
||||
return 'v' + this.$version;
|
||||
},
|
||||
allTimezones() {
|
||||
return this.$locale.getAllTimezones(true);
|
||||
},
|
||||
currentNickName() {
|
||||
return this.userStore.currentUserNickname || this.$t('User');
|
||||
},
|
||||
isUserScheduledTransactionEnabled() {
|
||||
return isUserScheduledTransactionEnabled();
|
||||
},
|
||||
theme: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.theme;
|
||||
},
|
||||
set: function (value) {
|
||||
if (value !== this.settingsStore.appSettings.theme) {
|
||||
this.settingsStore.setTheme(value);
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
},
|
||||
timeZone: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.timeZone;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setTimeZone(value);
|
||||
this.$locale.setTimeZone(value);
|
||||
this.transactionsStore.updateTransactionListInvalidState(true);
|
||||
this.overviewStore.updateTransactionOverviewInvalidState(true);
|
||||
this.statisticsStore.updateTransactionStatisticsInvalidState(true);
|
||||
}
|
||||
},
|
||||
exchangeRatesLastUpdateDate() {
|
||||
const exchangeRatesLastUpdateTime = this.exchangeRatesStore.exchangeRatesLastUpdateTime;
|
||||
return exchangeRatesLastUpdateTime ? this.$locale.formatUnixTimeToLongDate(this.userStore, exchangeRatesLastUpdateTime) : '';
|
||||
},
|
||||
isAutoUpdateExchangeRatesData: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.autoUpdateExchangeRatesData;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setAutoUpdateExchangeRatesData(value);
|
||||
}
|
||||
},
|
||||
isEnableApplicationLock() {
|
||||
return this.settingsStore.appSettings.applicationLock;
|
||||
},
|
||||
showAccountBalance: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.showAccountBalance;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setShowAccountBalance(value);
|
||||
}
|
||||
},
|
||||
isEnableAnimate: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.animate;
|
||||
},
|
||||
set: function (value) {
|
||||
if (value !== this.settingsStore.appSettings.animate) {
|
||||
this.settingsStore.setEnableAnimate(value);
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onPageAfterIn() {
|
||||
this.currentLocale = this.$locale.getCurrentLanguageTag();
|
||||
},
|
||||
logout() {
|
||||
const self = this;
|
||||
const router = self.f7router;
|
||||
const rootStore = useRootStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const userStore = useUserStore();
|
||||
const exchangeRatesStore = useExchangeRatesStore();
|
||||
|
||||
self.$confirm('Are you sure you want to log out?', () => {
|
||||
self.logouting = true;
|
||||
self.$showLoading(() => self.logouting);
|
||||
const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
self.rootStore.logout().then(() => {
|
||||
self.logouting = false;
|
||||
self.$hideLoading();
|
||||
const version = `v${getVersion()}`;
|
||||
|
||||
self.settingsStore.clearAppSettings();
|
||||
const currentLocale = ref<string>(getCurrentLanguageTag());
|
||||
const logouting = ref<boolean>(false);
|
||||
|
||||
const localeDefaultSettings = self.$locale.initLocale(self.userStore.currentUserLanguage, self.settingsStore.appSettings.timeZone);
|
||||
self.settingsStore.updateLocalizedDefaultSettings(localeDefaultSettings);
|
||||
const currentNickName = computed<string>(() => userStore.currentUserNickname || tt('User'));
|
||||
|
||||
setExpenseAndIncomeAmountColor(self.userStore.currentUserExpenseAmountColor, self.userStore.currentUserIncomeAmountColor);
|
||||
|
||||
router.navigate('/');
|
||||
}).catch(error => {
|
||||
self.logouting = false;
|
||||
self.$hideLoading();
|
||||
|
||||
if (!error.processed) {
|
||||
self.$toast(error.message || error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
switchToDesktopVersion() {
|
||||
this.$confirm('Are you sure you want to switch to desktop version?', () => {
|
||||
window.location.replace(getDesktopVersionPath());
|
||||
});
|
||||
const currentTheme = computed<string>({
|
||||
get: () => settingsStore.appSettings.theme,
|
||||
set: value => {
|
||||
if (value !== settingsStore.appSettings.theme) {
|
||||
settingsStore.setTheme(value);
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const isEnableAnimate = computed<boolean>({
|
||||
get: () => settingsStore.appSettings.animate,
|
||||
set: value => {
|
||||
if (value !== settingsStore.appSettings.animate) {
|
||||
settingsStore.setEnableAnimate(value);
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const isEnableApplicationLock = computed<boolean>(() => settingsStore.appSettings.applicationLock);
|
||||
|
||||
const exchangeRatesLastUpdateDate = computed<string>(() => {
|
||||
const exchangeRatesLastUpdateTime = exchangeRatesStore.exchangeRatesLastUpdateTime;
|
||||
return exchangeRatesLastUpdateTime ? formatUnixTimeToLongDate(exchangeRatesLastUpdateTime) : '';
|
||||
});
|
||||
|
||||
function switchToDesktopVersion() {
|
||||
showConfirm('Are you sure you want to switch to desktop version?', () => {
|
||||
window.location.replace(getDesktopVersionPath());
|
||||
});
|
||||
}
|
||||
|
||||
function logout() {
|
||||
showConfirm('Are you sure you want to log out?', () => {
|
||||
logouting.value = true;
|
||||
showLoading(() => logouting.value);
|
||||
|
||||
rootStore.logout().then(() => {
|
||||
logouting.value = false;
|
||||
hideLoading();
|
||||
|
||||
settingsStore.clearAppSettings();
|
||||
|
||||
const localeDefaultSettings = initLocale(userStore.currentUserLanguage, settingsStore.appSettings.timeZone);
|
||||
settingsStore.updateLocalizedDefaultSettings(localeDefaultSettings);
|
||||
|
||||
setExpenseAndIncomeAmountColor(userStore.currentUserExpenseAmountColor, userStore.currentUserIncomeAmountColor);
|
||||
|
||||
props.f7router.navigate('/');
|
||||
}).catch(error => {
|
||||
logouting.value = false;
|
||||
hideLoading();
|
||||
|
||||
if (!error.processed) {
|
||||
showToast(error.message || error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onPageAfterIn() {
|
||||
currentLocale.value = getCurrentLanguageTag();
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<f7-page>
|
||||
<f7-navbar :title="$t('Page Settings')" :back-link="$t('Back')"></f7-navbar>
|
||||
<f7-navbar :title="tt('Page Settings')" :back-link="tt('Back')"></f7-navbar>
|
||||
|
||||
<f7-block-title class="margin-top">{{ $t('Overview Page') }}</f7-block-title>
|
||||
<f7-block-title class="margin-top">{{ tt('Overview Page') }}</f7-block-title>
|
||||
<f7-list strong inset dividers>
|
||||
<f7-list-item>
|
||||
<span>{{ $t('Show Amount') }}</span>
|
||||
<span>{{ tt('Show Amount') }}</span>
|
||||
<f7-toggle :checked="showAmountInHomePage" @toggle:change="showAmountInHomePage = $event"></f7-toggle>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item
|
||||
:title="$t('Timezone Used for Statistics')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Timezone Type'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
|
||||
:title="tt('Timezone Used for Statistics')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: tt('Timezone Type'), searchbarDisableText: tt('Cancel'), appendSearchbarNotFound: tt('No results'), popupCloseLinkText: tt('Done') }">
|
||||
<select v-model="timezoneUsedForStatisticsInHomePage">
|
||||
<option :value="timezoneType.type"
|
||||
:key="timezoneType.type"
|
||||
@@ -20,40 +20,40 @@
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
|
||||
<f7-block-title>{{ $t('Transaction List Page') }}</f7-block-title>
|
||||
<f7-block-title>{{ tt('Transaction List Page') }}</f7-block-title>
|
||||
<f7-list strong inset dividers>
|
||||
<f7-list-item>
|
||||
<span>{{ $t('Show Monthly Total Amount') }}</span>
|
||||
<span>{{ tt('Show Monthly Total Amount') }}</span>
|
||||
<f7-toggle :checked="showTotalAmountInTransactionListPage" @toggle:change="showTotalAmountInTransactionListPage = $event"></f7-toggle>
|
||||
</f7-list-item>
|
||||
<f7-list-item>
|
||||
<span>{{ $t('Show Transaction Tag') }}</span>
|
||||
<span>{{ tt('Show Transaction Tag') }}</span>
|
||||
<f7-toggle :checked="showTagInTransactionListPage" @toggle:change="showTagInTransactionListPage = $event"></f7-toggle>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
|
||||
<f7-block-title>{{ $t('Transaction Edit Page') }}</f7-block-title>
|
||||
<f7-block-title>{{ tt('Transaction Edit Page') }}</f7-block-title>
|
||||
<f7-list strong inset dividers>
|
||||
<f7-list-item
|
||||
:title="$t('Automatically Save Draft')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Automatically Save Draft'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
|
||||
:title="tt('Automatically Save Draft')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: tt('Automatically Save Draft'), searchbarDisableText: tt('Cancel'), appendSearchbarNotFound: tt('No results'), popupCloseLinkText: tt('Done') }">
|
||||
<select v-model="autoSaveTransactionDraft">
|
||||
<option value="disabled">{{ $t('Disabled') }}</option>
|
||||
<option value="enabled">{{ $t('Enabled') }}</option>
|
||||
<option value="confirmation">{{ $t('Show Confirmation Every Time') }}</option>
|
||||
<option value="disabled">{{ tt('Disabled') }}</option>
|
||||
<option value="enabled">{{ tt('Enabled') }}</option>
|
||||
<option value="confirmation">{{ tt('Show Confirmation Every Time') }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
<f7-list-item>
|
||||
<span>{{ $t('Automatically Add Geolocation') }}</span>
|
||||
<span>{{ tt('Automatically Add Geolocation') }}</span>
|
||||
<f7-toggle :checked="isAutoGetCurrentGeoLocation" @toggle:change="isAutoGetCurrentGeoLocation = $event"></f7-toggle>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
|
||||
<f7-block-title>{{ $t('Exchange Rates Data Page') }}</f7-block-title>
|
||||
<f7-block-title>{{ tt('Exchange Rates Data Page') }}</f7-block-title>
|
||||
<f7-list strong inset dividers>
|
||||
<f7-list-item
|
||||
:title="$t('Sort by')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Sort by'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
|
||||
:title="tt('Sort by')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: tt('Sort by'), searchbarDisableText: tt('Cancel'), appendSearchbarNotFound: tt('No results'), popupCloseLinkText: tt('Done') }">
|
||||
<select v-model="currencySortByInExchangeRatesPage">
|
||||
<option :value="sortingType.type"
|
||||
:key="sortingType.type"
|
||||
@@ -64,82 +64,20 @@
|
||||
</f7-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
import { useTransactionsStore } from '@/stores/transaction.js';
|
||||
import { useOverviewStore } from '@/stores/overview.ts';
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useAppSettingPageBase } from '@/views/base/settings/AppSettingsPageBase.ts';
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapStores(useSettingsStore, useTransactionsStore, useOverviewStore),
|
||||
allTimezoneTypesUsedForStatistics() {
|
||||
return this.$locale.getAllTimezoneTypesUsedForStatistics();
|
||||
},
|
||||
allCurrencySortingTypes() {
|
||||
return this.$locale.getAllCurrencySortingTypes();
|
||||
},
|
||||
showAmountInHomePage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.showAmountInHomePage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setShowAmountInHomePage(value);
|
||||
}
|
||||
},
|
||||
timezoneUsedForStatisticsInHomePage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.timezoneUsedForStatisticsInHomePage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setTimezoneUsedForStatisticsInHomePage(value);
|
||||
this.overviewStore.updateTransactionOverviewInvalidState(true);
|
||||
}
|
||||
},
|
||||
showTotalAmountInTransactionListPage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.showTotalAmountInTransactionListPage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setShowTotalAmountInTransactionListPage(value);
|
||||
}
|
||||
},
|
||||
showTagInTransactionListPage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.showTagInTransactionListPage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setShowTagInTransactionListPage(value);
|
||||
}
|
||||
},
|
||||
autoSaveTransactionDraft: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.autoSaveTransactionDraft;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setAutoSaveTransactionDraft(value);
|
||||
|
||||
if (value === 'disabled') {
|
||||
this.transactionsStore.clearTransactionDraft();
|
||||
}
|
||||
}
|
||||
},
|
||||
isAutoGetCurrentGeoLocation: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.autoGetCurrentGeoLocation;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setAutoGetCurrentGeoLocation(value);
|
||||
}
|
||||
},
|
||||
currencySortByInExchangeRatesPage: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.currencySortByInExchangeRatesPage;
|
||||
},
|
||||
set: function (value) {
|
||||
this.settingsStore.setCurrencySortByInExchangeRatesPage(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const { tt } = useI18n();
|
||||
const {
|
||||
allTimezoneTypesUsedForStatistics,
|
||||
allCurrencySortingTypes,
|
||||
showAmountInHomePage,
|
||||
timezoneUsedForStatisticsInHomePage,
|
||||
showTotalAmountInTransactionListPage,
|
||||
showTagInTransactionListPage,
|
||||
autoSaveTransactionDraft,
|
||||
isAutoGetCurrentGeoLocation,
|
||||
currencySortByInExchangeRatesPage
|
||||
} = useAppSettingPageBase();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user