mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-18 00:34:28 +08:00
use the daylight saving time zone as default time zone rather than the current standard time zone during the DST
This commit is contained in:
@@ -9,6 +9,7 @@ import type { VersionInfo } from '@/core/version.ts';
|
||||
|
||||
import type { LatestExchangeRateResponse } from '@/models/exchange_rate.ts';
|
||||
|
||||
import { parseDateTimeFromUnixTime } from '@/lib/datetime.ts';
|
||||
import { getMapProvider } from '@/lib/server_settings.ts';
|
||||
import { getMapWebsite } from '@/lib/map/index.ts';
|
||||
import { getLicense, getThirdPartyLicenses } from '@/lib/licenses.ts';
|
||||
@@ -16,7 +17,7 @@ import { formatDisplayVersion, getClientDisplayVersion, getClientBuildTime } fro
|
||||
import { clearBrowserCaches } from '@/lib/ui/common.ts';
|
||||
|
||||
export function useAboutPageBase() {
|
||||
const { tt, formatUnixTimeToLongDateTime } = useI18n();
|
||||
const { tt, formatDateTimeToLongDateTime } = useI18n();
|
||||
|
||||
const systemsStore = useSystemsStore();
|
||||
const exchangeRatesStore = useExchangeRatesStore();
|
||||
@@ -41,7 +42,8 @@ export function useAboutPageBase() {
|
||||
return time;
|
||||
}
|
||||
|
||||
return formatUnixTimeToLongDateTime(parseInt(time));
|
||||
const buildDateTime = parseDateTimeFromUnixTime(parseInt(time));
|
||||
return formatDateTimeToLongDateTime(buildDateTime);
|
||||
});
|
||||
|
||||
const exchangeRatesData = computed<LatestExchangeRateResponse | undefined>(() => exchangeRatesStore.latestExchangeRates.data);
|
||||
|
||||
@@ -12,9 +12,10 @@ import type {
|
||||
} from '@/models/exchange_rate.ts';
|
||||
|
||||
import { getExchangedAmountByRate } from '@/lib/numeral.ts';
|
||||
import { parseDateTimeFromUnixTime } from '@/lib/datetime.ts';
|
||||
|
||||
export function useExchangeRatesPageBase() {
|
||||
const { getAllDisplayExchangeRates, formatUnixTimeToLongDate, parseAmountFromWesternArabicNumerals } = useI18n();
|
||||
const { getAllDisplayExchangeRates, formatDateTimeToLongDate, parseAmountFromWesternArabicNumerals } = useI18n();
|
||||
|
||||
const userStore = useUserStore();
|
||||
const exchangeRatesStore = useExchangeRatesStore();
|
||||
@@ -27,8 +28,12 @@ export function useExchangeRatesPageBase() {
|
||||
const isUserCustomExchangeRates = computed<boolean>(() => exchangeRatesStore.isUserCustomExchangeRates);
|
||||
|
||||
const exchangeRatesDataUpdateTime = computed<string>(() => {
|
||||
const exchangeRatesLastUpdateTime = exchangeRatesStore.exchangeRatesLastUpdateTime;
|
||||
return exchangeRatesLastUpdateTime ? formatUnixTimeToLongDate(exchangeRatesLastUpdateTime) : '';
|
||||
if (!exchangeRatesStore.exchangeRatesLastUpdateTime) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const exchangeRatesLastUpdateTime = parseDateTimeFromUnixTime(exchangeRatesStore.exchangeRatesLastUpdateTime);
|
||||
return formatDateTimeToLongDate(exchangeRatesLastUpdateTime);
|
||||
});
|
||||
|
||||
const availableExchangeRates = computed<LocalizedLatestExchangeRate[]>(() => {
|
||||
|
||||
@@ -17,12 +17,14 @@ import type {
|
||||
TransactionOverviewResponseItem
|
||||
} from '@/models/transaction.ts';
|
||||
|
||||
import { parseDateTimeFromUnixTime } from '@/lib/datetime.ts';
|
||||
|
||||
export function useHomePageBase() {
|
||||
const {
|
||||
formatUnixTimeToLongDate,
|
||||
formatUnixTimeToLongMonthDay,
|
||||
formatUnixTimeToGregorianLikeLongYear,
|
||||
formatUnixTimeToGregorianLikeLongMonth,
|
||||
formatDateTimeToLongDate,
|
||||
formatDateTimeToLongMonthDay,
|
||||
formatDateTimeToGregorianLikeLongYear,
|
||||
formatDateTimeToGregorianLikeLongMonth,
|
||||
formatAmountToLocalizedNumeralsWithCurrency
|
||||
} = useI18n();
|
||||
|
||||
@@ -57,19 +59,19 @@ export function useHomePageBase() {
|
||||
const displayDateRange = computed<TransactionOverviewDisplayTime>(() => {
|
||||
return {
|
||||
today: {
|
||||
displayTime: formatUnixTimeToLongDate(overviewStore.transactionDataRange.today.startTime),
|
||||
displayTime: formatDateTimeToLongDate(parseDateTimeFromUnixTime(overviewStore.transactionDataRange.today.startTime)),
|
||||
},
|
||||
thisWeek: {
|
||||
startTime: formatUnixTimeToLongMonthDay(overviewStore.transactionDataRange.thisWeek.startTime),
|
||||
endTime: formatUnixTimeToLongMonthDay(overviewStore.transactionDataRange.thisWeek.endTime)
|
||||
startTime: formatDateTimeToLongMonthDay(parseDateTimeFromUnixTime(overviewStore.transactionDataRange.thisWeek.startTime)),
|
||||
endTime: formatDateTimeToLongMonthDay(parseDateTimeFromUnixTime(overviewStore.transactionDataRange.thisWeek.endTime))
|
||||
},
|
||||
thisMonth: {
|
||||
displayTime: formatUnixTimeToGregorianLikeLongMonth(overviewStore.transactionDataRange.thisMonth.startTime),
|
||||
startTime: formatUnixTimeToLongMonthDay(overviewStore.transactionDataRange.thisMonth.startTime),
|
||||
endTime: formatUnixTimeToLongMonthDay(overviewStore.transactionDataRange.thisMonth.endTime)
|
||||
displayTime: formatDateTimeToGregorianLikeLongMonth(parseDateTimeFromUnixTime(overviewStore.transactionDataRange.thisMonth.startTime)),
|
||||
startTime: formatDateTimeToLongMonthDay(parseDateTimeFromUnixTime(overviewStore.transactionDataRange.thisMonth.startTime)),
|
||||
endTime: formatDateTimeToLongMonthDay(parseDateTimeFromUnixTime(overviewStore.transactionDataRange.thisMonth.endTime))
|
||||
},
|
||||
thisYear: {
|
||||
displayTime: formatUnixTimeToGregorianLikeLongYear(overviewStore.transactionDataRange.thisYear.startTime)
|
||||
displayTime: formatDateTimeToGregorianLikeLongYear(parseDateTimeFromUnixTime(overviewStore.transactionDataRange.thisYear.startTime))
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -9,7 +9,13 @@ import { AccountCategory, AccountType } from '@/core/account.ts';
|
||||
import type { LocalizedAccountCategory } from '@/core/account.ts';
|
||||
import { Account } from '@/models/account.ts';
|
||||
|
||||
import { getCurrentUnixTime } from '@/lib/datetime.ts';
|
||||
import { isDefined } from '@/lib/common.ts';
|
||||
import {
|
||||
getTimezoneOffsetMinutes,
|
||||
getSameDateTimeWithCurrentTimezone,
|
||||
parseDateTimeFromUnixTimeWithBrowserTimezone,
|
||||
getCurrentUnixTime
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
export interface DayAndDisplayName {
|
||||
readonly day: number;
|
||||
@@ -25,7 +31,7 @@ export function useAccountEditPageBase() {
|
||||
const clientSessionId = ref<string>('');
|
||||
const loading = ref<boolean>(false);
|
||||
const submitting = ref<boolean>(false);
|
||||
const account = ref<Account>(Account.createNewAccount(userStore.currentUserDefaultCurrency, getCurrentUnixTime()));
|
||||
const account = ref<Account>(Account.createNewAccount(userStore.currentUserDefaultCurrency, getCurrentUnixTimeForNewAccount()));
|
||||
const subAccounts = ref<Account[]>([]);
|
||||
|
||||
const title = computed<string>(() => {
|
||||
@@ -89,6 +95,18 @@ export function useAccountEditPageBase() {
|
||||
|
||||
const isAccountSupportCreditCardStatementDate = computed<boolean>(() => account.value && account.value.category === AccountCategory.CreditCard.type);
|
||||
|
||||
function getCurrentUnixTimeForNewAccount(): number {
|
||||
return getSameDateTimeWithCurrentTimezone(parseDateTimeFromUnixTimeWithBrowserTimezone(getCurrentUnixTime())).getUnixTime();
|
||||
}
|
||||
|
||||
function getDefaultTimezoneOffsetMinutes(account: Account): number {
|
||||
if (!account.balanceTime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return getTimezoneOffsetMinutes(account.balanceTime);
|
||||
}
|
||||
|
||||
function getAccountCreditCardStatementDate(statementDate?: number): string | null {
|
||||
for (const item of allAvailableMonthDays.value) {
|
||||
if (item.day === statementDate) {
|
||||
@@ -99,6 +117,23 @@ export function useAccountEditPageBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function updateAccountBalanceTime(account: Account, balanceTime: number): void {
|
||||
if (!isDefined(account.balanceTime)) {
|
||||
account.balanceTime = balanceTime;
|
||||
return;
|
||||
}
|
||||
|
||||
const oldUtcOffset = getTimezoneOffsetMinutes(account.balanceTime);
|
||||
const newUtcOffset = getTimezoneOffsetMinutes(balanceTime);
|
||||
|
||||
if (oldUtcOffset === newUtcOffset) {
|
||||
account.balanceTime = balanceTime;
|
||||
return;
|
||||
}
|
||||
|
||||
account.balanceTime = balanceTime - (newUtcOffset - oldUtcOffset) * 60;
|
||||
}
|
||||
|
||||
function getInputEmptyProblemMessage(account: Account, isSubAccount: boolean): string | null {
|
||||
if (!isSubAccount && !account.category) {
|
||||
return 'Account category cannot be blank';
|
||||
@@ -122,7 +157,7 @@ export function useAccountEditPageBase() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const subAccount = account.value.createNewSubAccount(userStore.currentUserDefaultCurrency, getCurrentUnixTime());
|
||||
const subAccount = account.value.createNewSubAccount(userStore.currentUserDefaultCurrency, getCurrentUnixTimeForNewAccount());
|
||||
subAccounts.value.push(subAccount);
|
||||
return true;
|
||||
}
|
||||
@@ -133,7 +168,7 @@ export function useAccountEditPageBase() {
|
||||
|
||||
if (newAccount.subAccounts && newAccount.subAccounts.length > 0) {
|
||||
for (const oldSubAccount of newAccount.subAccounts) {
|
||||
const subAccount: Account = account.value.createNewSubAccount(userStore.currentUserDefaultCurrency, getCurrentUnixTime());
|
||||
const subAccount: Account = account.value.createNewSubAccount(userStore.currentUserDefaultCurrency, getCurrentUnixTimeForNewAccount());
|
||||
subAccount.fillFrom(oldSubAccount);
|
||||
|
||||
subAccounts.value.push(subAccount);
|
||||
@@ -163,7 +198,10 @@ export function useAccountEditPageBase() {
|
||||
allAvailableMonthDays,
|
||||
isAccountSupportCreditCardStatementDate,
|
||||
// functions
|
||||
getCurrentUnixTimeForNewAccount,
|
||||
getDefaultTimezoneOffsetMinutes,
|
||||
getAccountCreditCardStatementDate,
|
||||
updateAccountBalanceTime,
|
||||
isNewAccount,
|
||||
addSubAccount,
|
||||
setAccount
|
||||
|
||||
@@ -2,7 +2,6 @@ import { ref, computed } from 'vue';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
import { useAccountsStore } from '@/stores/account.ts';
|
||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
@@ -25,7 +24,8 @@ import { replaceAll } from '@/lib/common.ts';
|
||||
import {
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffsetMinutes,
|
||||
parseDateTimeFromUnixTime
|
||||
parseDateTimeFromUnixTime,
|
||||
parseDateTimeFromUnixTimeWithTimezoneOffset
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
export function useReconciliationStatementPageBase() {
|
||||
@@ -33,15 +33,14 @@ export function useReconciliationStatementPageBase() {
|
||||
tt,
|
||||
getAllAccountBalanceTrendChartTypes,
|
||||
getAllStatisticsDateAggregationTypesWithShortName,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatUnixTimeToLongDate,
|
||||
formatUnixTimeToShortTime,
|
||||
formatUnixTimeToGregorianDefaultDateTime,
|
||||
formatDateTimeToLongDateTime,
|
||||
formatDateTimeToLongDate,
|
||||
formatDateTimeToShortTime,
|
||||
formatDateTimeToGregorianDefaultDateTime,
|
||||
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
||||
formatAmountToLocalizedNumeralsWithCurrency
|
||||
} = useI18n();
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const userStore = useUserStore();
|
||||
const accountsStore = useAccountsStore();
|
||||
const transactionCategoriesStore = useTransactionCategoriesStore();
|
||||
@@ -53,7 +52,6 @@ export function useReconciliationStatementPageBase() {
|
||||
|
||||
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
|
||||
const fiscalYearStart = computed<number>(() => userStore.currentUserFiscalYearStart);
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||
|
||||
const allChartTypes = computed<TypeAndDisplayName[]>(() => getAllAccountBalanceTrendChartTypes());
|
||||
@@ -79,11 +77,13 @@ export function useReconciliationStatementPageBase() {
|
||||
const allCategoriesMap = computed<Record<string, TransactionCategory>>(() => transactionCategoriesStore.allTransactionCategoriesMap);
|
||||
|
||||
const displayStartDateTime = computed<string>(() => {
|
||||
return formatUnixTimeToLongDateTime(startTime.value);
|
||||
const dateTime = parseDateTimeFromUnixTime(startTime.value);
|
||||
return formatDateTimeToLongDateTime(dateTime);
|
||||
});
|
||||
|
||||
const displayEndDateTime = computed<string>(() => {
|
||||
return formatUnixTimeToLongDateTime(endTime.value);
|
||||
const dateTime = parseDateTimeFromUnixTime(endTime.value);
|
||||
return formatDateTimeToLongDateTime(dateTime);
|
||||
});
|
||||
|
||||
const displayTotalInflows = computed<string>(() => {
|
||||
@@ -160,15 +160,22 @@ export function useReconciliationStatementPageBase() {
|
||||
}
|
||||
|
||||
function getDisplayDateTime(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
|
||||
return formatUnixTimeToLongDateTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset);
|
||||
return formatDateTimeToLongDateTime(dateTime);
|
||||
}
|
||||
|
||||
function getDisplayDate(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
|
||||
return formatUnixTimeToLongDate(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset);
|
||||
return formatDateTimeToLongDate(dateTime);
|
||||
}
|
||||
|
||||
function getDisplayTime(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
|
||||
return formatUnixTimeToShortTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset);
|
||||
return formatDateTimeToShortTime(dateTime);
|
||||
}
|
||||
|
||||
function isSameAsDefaultTimezoneOffsetMinutes(transaction: TransactionReconciliationStatementResponseItemWithInfo): boolean {
|
||||
return transaction.utcOffset === getTimezoneOffsetMinutes(transaction.time);
|
||||
}
|
||||
|
||||
function getDisplayTimezone(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
|
||||
@@ -227,7 +234,7 @@ export function useReconciliationStatementPageBase() {
|
||||
|
||||
const transactions = reconciliationStatements.value?.transactions ?? [];
|
||||
const rows = transactions.map(transaction => {
|
||||
const transactionTime = parseDateTimeFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value).getUnixTime();
|
||||
const transactionTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset);
|
||||
const type = getDisplayTransactionType(transaction);
|
||||
let categoryName = transaction.categoryName;
|
||||
let displayAmount = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(transaction.sourceAmount);
|
||||
@@ -260,7 +267,7 @@ export function useReconciliationStatementPageBase() {
|
||||
}
|
||||
|
||||
return [
|
||||
formatUnixTimeToGregorianDefaultDateTime(transactionTime),
|
||||
formatDateTimeToGregorianDefaultDateTime(transactionTime),
|
||||
type,
|
||||
categoryName,
|
||||
displayAmount,
|
||||
@@ -282,7 +289,6 @@ export function useReconciliationStatementPageBase() {
|
||||
// computed states
|
||||
firstDayOfWeek,
|
||||
fiscalYearStart,
|
||||
currentTimezoneOffsetMinutes,
|
||||
defaultCurrency,
|
||||
allChartTypes,
|
||||
allDateAggregationTypes,
|
||||
@@ -303,6 +309,7 @@ export function useReconciliationStatementPageBase() {
|
||||
getDisplayDateTime,
|
||||
getDisplayDate,
|
||||
getDisplayTime,
|
||||
isSameAsDefaultTimezoneOffsetMinutes,
|
||||
getDisplayTimezone,
|
||||
getDisplaySourceAmount,
|
||||
getDisplayDestinationAmount,
|
||||
|
||||
@@ -15,6 +15,7 @@ import { CategoryType } from '@/core/category.ts';
|
||||
import type { Account } from '@/models/account.ts';
|
||||
|
||||
import { isObjectEmpty } from '@/lib/common.ts';
|
||||
import { getCurrentUnixTime } from '@/lib/datetime.ts';
|
||||
|
||||
export function useAppSettingPageBase() {
|
||||
const { tt, getAllTimezones, getAllTimezoneTypesUsedForStatistics, getAllCurrencySortingTypes, setTimeZone } = useI18n();
|
||||
@@ -37,7 +38,7 @@ export function useAppSettingPageBase() {
|
||||
];
|
||||
});
|
||||
|
||||
const allTimezones = computed<LocalizedTimezoneInfo[]>(() => getAllTimezones(true));
|
||||
const allTimezones = computed<LocalizedTimezoneInfo[]>(() => getAllTimezones(getCurrentUnixTime(), true));
|
||||
const allTimezoneTypesUsedForStatistics = computed<TypeAndDisplayName[]>(() => getAllTimezoneTypesUsedForStatistics());
|
||||
const allCurrencySortingTypes = computed<TypeAndDisplayName[]>(() => getAllCurrencySortingTypes());
|
||||
|
||||
|
||||
@@ -28,7 +28,11 @@ import type {
|
||||
} from '@/models/transaction.ts';
|
||||
|
||||
import { limitText, findNameByType, findDisplayNameByType } from '@/lib/common.ts';
|
||||
import { getYearMonthFirstUnixTime, getYearMonthLastUnixTime } from '@/lib/datetime.ts';
|
||||
import {
|
||||
parseDateTimeFromUnixTime,
|
||||
getYearMonthFirstUnixTime,
|
||||
getYearMonthLastUnixTime
|
||||
} from '@/lib/datetime.ts';
|
||||
import { getDisplayColor, getCategoryDisplayColor, getAccountDisplayColor } from '@/lib/color.ts';
|
||||
|
||||
export function useStatisticsTransactionPageBase() {
|
||||
@@ -37,8 +41,8 @@ export function useStatisticsTransactionPageBase() {
|
||||
getAllDateRanges,
|
||||
getAllStatisticsSortingTypes,
|
||||
getAllStatisticsDateAggregationTypes,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatUnixTimeToGregorianLikeLongYearMonth,
|
||||
formatDateTimeToLongDateTime,
|
||||
formatDateTimeToGregorianLikeLongYearMonth,
|
||||
formatDateRange,
|
||||
formatAmountToLocalizedNumeralsWithCurrency
|
||||
} = useI18n();
|
||||
@@ -88,11 +92,11 @@ export function useStatisticsTransactionPageBase() {
|
||||
|
||||
const queryStartTime = computed<string>(() => {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
return formatUnixTimeToLongDateTime(query.value.categoricalChartStartTime);
|
||||
return formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(query.value.categoricalChartStartTime));
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return formatUnixTimeToGregorianLikeLongYearMonth(getYearMonthFirstUnixTime(query.value.trendChartStartYearMonth));
|
||||
return formatDateTimeToGregorianLikeLongYearMonth(parseDateTimeFromUnixTime(getYearMonthFirstUnixTime(query.value.trendChartStartYearMonth)));
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return formatUnixTimeToLongDateTime(query.value.assetTrendsChartStartTime);
|
||||
return formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(query.value.assetTrendsChartStartTime));
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -100,11 +104,11 @@ export function useStatisticsTransactionPageBase() {
|
||||
|
||||
const queryEndTime = computed<string>(() => {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
return formatUnixTimeToLongDateTime(query.value.categoricalChartEndTime);
|
||||
return formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(query.value.categoricalChartEndTime));
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return formatUnixTimeToGregorianLikeLongYearMonth(getYearMonthLastUnixTime(query.value.trendChartEndYearMonth));
|
||||
return formatDateTimeToGregorianLikeLongYearMonth(parseDateTimeFromUnixTime(getYearMonthLastUnixTime(query.value.trendChartEndYearMonth)));
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return formatUnixTimeToLongDateTime(query.value.assetTrendsChartEndTime);
|
||||
return formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(query.value.assetTrendsChartEndTime));
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ import {
|
||||
import {
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffsetMinutes,
|
||||
getSameDateTimeWithCurrentTimezone,
|
||||
parseDateTimeFromUnixTimeWithBrowserTimezone,
|
||||
getCurrentUnixTime
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
@@ -92,14 +94,14 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
const transaction = ref<Transaction | TransactionTemplate>(createNewTransactionModel(transactionDefaultType));
|
||||
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(transaction.value.time));
|
||||
const showAccountBalance = computed<boolean>(() => settingsStore.appSettings.showAccountBalance);
|
||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||
const defaultAccountId = computed<string>(() => userStore.currentUserDefaultAccountId);
|
||||
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
|
||||
const coordinateDisplayType = computed<number>(() => userStore.currentUserCoordinateDisplayType);
|
||||
|
||||
const allTimezones = computed<LocalizedTimezoneInfo[]>(() => getAllTimezones(true));
|
||||
const allTimezones = computed<LocalizedTimezoneInfo[]>(() => getAllTimezones(transaction.value.time, true));
|
||||
const allAccounts = computed<Account[]>(() => accountsStore.allPlainAccounts);
|
||||
const allVisibleAccounts = computed<Account[]>(() => accountsStore.allVisiblePlainAccounts);
|
||||
const allAccountsMap = computed<Record<string, Account>>(() => accountsStore.allAccountsMap);
|
||||
@@ -274,7 +276,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
});
|
||||
|
||||
const transactionTimezoneTimeDifference = computed<string>(() => {
|
||||
return getTimezoneDifferenceDisplayText(transaction.value.utcOffset);
|
||||
return getTimezoneDifferenceDisplayText(transaction.value.time, transaction.value.utcOffset);
|
||||
});
|
||||
|
||||
const geoLocationStatusInfo = computed<string>(() => {
|
||||
@@ -331,8 +333,12 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
return !!inputEmptyProblemMessage.value;
|
||||
});
|
||||
|
||||
function getCurrentUnixTimeForNewTransaction(): number {
|
||||
return getSameDateTimeWithCurrentTimezone(parseDateTimeFromUnixTimeWithBrowserTimezone(getCurrentUnixTime())).getUnixTime();
|
||||
}
|
||||
|
||||
function createNewTransactionModel(transactionType?: number): Transaction | TransactionTemplate {
|
||||
const now: number = getCurrentUnixTime();
|
||||
const now: number = getCurrentUnixTimeForNewTransaction();
|
||||
const currentTimezone: string = settingsStore.appSettings.timeZone;
|
||||
|
||||
let defaultType: TransactionType = TransactionType.Expense;
|
||||
@@ -343,7 +349,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
defaultType = TransactionType.Transfer;
|
||||
}
|
||||
|
||||
let newTransaction: Transaction | TransactionTemplate = Transaction.createNewTransaction(defaultType, now, currentTimezone, getTimezoneOffsetMinutes(currentTimezone));
|
||||
let newTransaction: Transaction | TransactionTemplate = Transaction.createNewTransaction(defaultType, now, currentTimezone, getTimezoneOffsetMinutes(now, currentTimezone));
|
||||
|
||||
if (type === TransactionEditPageType.Template) {
|
||||
newTransaction = TransactionTemplate.createNewTransactionTemplate(newTransaction);
|
||||
@@ -352,6 +358,25 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
return newTransaction;
|
||||
}
|
||||
|
||||
function updateTransactionTime(newTime: number): void {
|
||||
transaction.value.time = newTime;
|
||||
updateTransactionTimezone(transaction.value.timeZone ?? '');
|
||||
}
|
||||
|
||||
function updateTransactionTimezone(timezoneName: string): void {
|
||||
const oldUtcOffset = transaction.value.utcOffset;
|
||||
|
||||
for (const timezone of allTimezones.value) {
|
||||
if (timezone.name === timezoneName) {
|
||||
transaction.value.timeZone = timezone.name;
|
||||
transaction.value.utcOffset = timezone.utcOffsetMinutes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
transaction.value.time = transaction.value.time - (transaction.value.utcOffset - oldUtcOffset) * 60;
|
||||
}
|
||||
|
||||
function swapTransactionData(swapAccount: boolean, swapAmount: boolean): void {
|
||||
if (swapAccount) {
|
||||
const oldSourceAccountId = transaction.value.sourceAccountId;
|
||||
@@ -396,15 +421,6 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
}
|
||||
});
|
||||
|
||||
watch(() => transaction.value.timeZone, (newValue) => {
|
||||
for (const timezone of allTimezones.value) {
|
||||
if (timezone.name === newValue) {
|
||||
transaction.value.utcOffset = timezone.utcOffsetMinutes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
// constants
|
||||
isSupportGeoLocation,
|
||||
@@ -460,6 +476,8 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
inputIsEmpty,
|
||||
// functions
|
||||
createNewTransactionModel,
|
||||
updateTransactionTime,
|
||||
updateTransactionTimezone,
|
||||
swapTransactionData,
|
||||
getDisplayAmount,
|
||||
getTransactionPictureUrl
|
||||
|
||||
@@ -23,13 +23,12 @@ import { type Transaction, TransactionTagFilter } from '@/models/transaction.ts'
|
||||
|
||||
import {
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffset,
|
||||
getTimezoneOffsetMinutes,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getLocalDatetimeFromUnixTime,
|
||||
getDummyUnixTimeForLocalUsage,
|
||||
getSameDateTimeWithBrowserTimezone,
|
||||
getCurrentDateTime,
|
||||
parseDateTimeFromUnixTime,
|
||||
parseDateTimeFromUnixTimeWithTimezoneOffset,
|
||||
getYearMonthFirstUnixTime,
|
||||
isDateRangeMatchOneMonth
|
||||
} from '@/lib/datetime.ts';
|
||||
@@ -76,10 +75,10 @@ export function useTransactionListPageBase() {
|
||||
tt,
|
||||
getAllDateRanges,
|
||||
getCurrentNumeralSystemType,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatUnixTimeToLongDate,
|
||||
formatUnixTimeToShortTime,
|
||||
formatUnixTimeToGregorianLikeLongYearMonth,
|
||||
formatDateTimeToLongDateTime,
|
||||
formatDateTimeToLongDate,
|
||||
formatDateTimeToShortTime,
|
||||
formatDateTimeToGregorianLikeLongYearMonth,
|
||||
formatDateRange,
|
||||
formatAmountToLocalizedNumeralsWithCurrency
|
||||
} = useI18n();
|
||||
@@ -98,7 +97,6 @@ export function useTransactionListPageBase() {
|
||||
const currentCalendarDate = ref<TextualYearMonthDay | ''>('');
|
||||
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
|
||||
const fiscalYearStart = computed<number>(() => userStore.currentUserFiscalYearStart);
|
||||
const defaultCurrency = computed<string>(() => getUnifiedSelectedAccountsCurrencyOrDefaultCurrency(allAccountsMap.value, queryAllFilterAccountIds.value, userStore.currentUserDefaultCurrency));
|
||||
@@ -161,8 +159,8 @@ export function useTransactionListPageBase() {
|
||||
|
||||
return formatDateRange(query.value.dateType, query.value.minTime, query.value.maxTime);
|
||||
});
|
||||
const queryMinTime = computed<string>(() => formatUnixTimeToLongDateTime(query.value.minTime));
|
||||
const queryMaxTime = computed<string>(() => formatUnixTimeToLongDateTime(query.value.maxTime));
|
||||
const queryMinTime = computed<string>(() => formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(query.value.minTime)));
|
||||
const queryMaxTime = computed<string>(() => formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(query.value.maxTime)));
|
||||
const queryMonthlyData = computed<boolean>(() => isDateRangeMatchOneMonth(query.value.minTime, query.value.maxTime));
|
||||
const queryMonth = computed<Year0BasedMonth>(() => {
|
||||
if (!query.value.minTime || !query.value.maxTime) {
|
||||
@@ -235,8 +233,8 @@ export function useTransactionListPageBase() {
|
||||
return displayAmount.join(' ~ ');
|
||||
});
|
||||
|
||||
const transactionCalendarMinDate = computed<Date>(() => getLocalDatetimeFromUnixTime(getDummyUnixTimeForLocalUsage(query.value.minTime, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())));
|
||||
const transactionCalendarMaxDate = computed<Date>(() => getLocalDatetimeFromUnixTime(getDummyUnixTimeForLocalUsage(query.value.maxTime, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())));
|
||||
const transactionCalendarMinDate = computed<Date>(() => getLocalDatetimeFromUnixTime(getSameDateTimeWithBrowserTimezone(parseDateTimeFromUnixTime(query.value.minTime)).getUnixTime()));
|
||||
const transactionCalendarMaxDate = computed<Date>(() => getLocalDatetimeFromUnixTime(getSameDateTimeWithBrowserTimezone(parseDateTimeFromUnixTime(query.value.maxTime)).getUnixTime()));
|
||||
|
||||
const currentMonthTransactionData = computed<TransactionMonthList | null>(() => {
|
||||
const allTransactions = transactionsStore.transactions;
|
||||
@@ -284,6 +282,10 @@ export function useTransactionListPageBase() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isSameAsDefaultTimezoneOffsetMinutes(transaction: Transaction): boolean {
|
||||
return transaction.utcOffset === getTimezoneOffsetMinutes(transaction.time);
|
||||
}
|
||||
|
||||
function formatAmount(amount: number, hideAmount: boolean, currencyCode: string): string {
|
||||
if (hideAmount) {
|
||||
return formatAmountToLocalizedNumeralsWithCurrency(DISPLAY_HIDDEN_AMOUNT, currencyCode);
|
||||
@@ -293,15 +295,18 @@ export function useTransactionListPageBase() {
|
||||
}
|
||||
|
||||
function getDisplayTime(transaction: Transaction): string {
|
||||
return formatUnixTimeToShortTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset);
|
||||
return formatDateTimeToShortTime(dateTime);
|
||||
}
|
||||
|
||||
function getDisplayLongDate(transaction: Transaction): string {
|
||||
return formatUnixTimeToLongDate(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset);
|
||||
return formatDateTimeToLongDate(dateTime);
|
||||
}
|
||||
|
||||
function getDisplayLongYearMonth(transactionMonthList: TransactionMonthList): string {
|
||||
return formatUnixTimeToGregorianLikeLongYearMonth(getYearMonthFirstUnixTime(transactionMonthList.yearDashMonth));
|
||||
const yearMonthDateTime = parseDateTimeFromUnixTime(getYearMonthFirstUnixTime(transactionMonthList.yearDashMonth));
|
||||
return formatDateTimeToGregorianLikeLongYearMonth(yearMonthDateTime);
|
||||
}
|
||||
|
||||
function getDisplayTimezone(transaction: Transaction): string {
|
||||
@@ -310,8 +315,10 @@ export function useTransactionListPageBase() {
|
||||
}
|
||||
|
||||
function getDisplayTimeInDefaultTimezone(transaction: Transaction): string {
|
||||
const utcOffset = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(getTimezoneOffset(settingsStore.appSettings.timeZone));
|
||||
return `${formatUnixTimeToLongDateTime(transaction.time)} (UTC${utcOffset})`;
|
||||
const timezoneOffsetMinutes = getTimezoneOffsetMinutes(transaction.time);
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, timezoneOffsetMinutes);
|
||||
const utcOffset = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(getUtcOffsetByUtcOffsetMinutes(timezoneOffsetMinutes));
|
||||
return `${formatDateTimeToLongDateTime(dateTime)} (UTC${utcOffset})`;
|
||||
}
|
||||
|
||||
function getDisplayAmount(transaction: Transaction): string {
|
||||
@@ -372,7 +379,6 @@ export function useTransactionListPageBase() {
|
||||
customMaxDatetime,
|
||||
currentCalendarDate,
|
||||
// computed states
|
||||
currentTimezoneOffsetMinutes,
|
||||
firstDayOfWeek,
|
||||
fiscalYearStart,
|
||||
defaultCurrency,
|
||||
@@ -410,6 +416,7 @@ export function useTransactionListPageBase() {
|
||||
canAddTransaction,
|
||||
// functions
|
||||
hasSubCategoryInQuery,
|
||||
isSameAsDefaultTimezoneOffsetMinutes,
|
||||
getDisplayTime,
|
||||
getDisplayLongDate,
|
||||
getDisplayLongYearMonth,
|
||||
|
||||
@@ -202,12 +202,10 @@ import { useAccountsStore } from '@/stores/account.ts';
|
||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useOverviewStore } from '@/stores/overview.ts';
|
||||
|
||||
import { entries } from '@/core/base.ts';
|
||||
import { type NumeralSystem } from '@/core/numeral.ts';
|
||||
import { DateRange } from '@/core/datetime.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import {
|
||||
type TransactionAmountsRequestType,
|
||||
type TransactionMonthlyIncomeAndExpenseData,
|
||||
LATEST_12MONTHS_TRANSACTION_AMOUNTS_REQUEST_TYPES
|
||||
} from '@/models/transaction.ts';
|
||||
@@ -280,8 +278,7 @@ const monthlyIncomeAndExpenseData = computed<TransactionMonthlyIncomeAndExpenseD
|
||||
return data;
|
||||
}
|
||||
|
||||
for (const [type, monthDiff] of entries(LATEST_12MONTHS_TRANSACTION_AMOUNTS_REQUEST_TYPES)) {
|
||||
const amountRequestType = type as TransactionAmountsRequestType;
|
||||
for (const amountRequestType of LATEST_12MONTHS_TRANSACTION_AMOUNTS_REQUEST_TYPES) {
|
||||
const dateRange = overviewStore.transactionDataRange[amountRequestType];
|
||||
|
||||
if (!dateRange) {
|
||||
@@ -292,7 +289,6 @@ const monthlyIncomeAndExpenseData = computed<TransactionMonthlyIncomeAndExpenseD
|
||||
|
||||
data.push({
|
||||
monthStartTime: dateRange.startTime,
|
||||
monthsBeforeCurrentMonth: monthDiff,
|
||||
incomeAmount: item?.incomeAmount || 0,
|
||||
expenseAmount: item?.expenseAmount || 0,
|
||||
incompleteIncomeAmount: item ? item.incompleteIncomeAmount : true,
|
||||
|
||||
@@ -145,7 +145,9 @@
|
||||
<date-time-select
|
||||
:disabled="loading || submitting"
|
||||
:label="tt('Balance Time')"
|
||||
v-model="selectedAccount.balanceTime"
|
||||
:timezone-utc-offset="getDefaultTimezoneOffsetMinutes(selectedAccount)"
|
||||
:model-value="selectedAccount.balanceTime"
|
||||
@update:model-value="updateAccountBalanceTime(selectedAccount, $event)"
|
||||
@error="onShowDateTimeError" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="12">
|
||||
@@ -210,7 +212,6 @@ import { ALL_ACCOUNT_COLORS } from '@/consts/color.ts';
|
||||
import { Account } from '@/models/account.ts';
|
||||
|
||||
import { isNumber } from '@/lib/common.ts';
|
||||
import { getCurrentUnixTime } from '@/lib/datetime.ts';
|
||||
import { generateRandomUUID } from '@/lib/misc.ts';
|
||||
|
||||
import {
|
||||
@@ -242,6 +243,9 @@ const {
|
||||
allAccountTypes,
|
||||
allAvailableMonthDays,
|
||||
isAccountSupportCreditCardStatementDate,
|
||||
getCurrentUnixTimeForNewAccount,
|
||||
getDefaultTimezoneOffsetMinutes,
|
||||
updateAccountBalanceTime,
|
||||
isNewAccount,
|
||||
addSubAccount,
|
||||
setAccount
|
||||
@@ -275,7 +279,7 @@ const accountAmountTitle = computed<string>(() => {
|
||||
|
||||
const isAccountModified = computed<boolean>(() => {
|
||||
if (!editAccountId.value) {
|
||||
return !account.value.equals(Account.createNewAccount(userStore.currentUserDefaultCurrency, account.value.balanceTime ?? getCurrentUnixTime()));
|
||||
return !account.value.equals(Account.createNewAccount(userStore.currentUserDefaultCurrency, account.value.balanceTime ?? getCurrentUnixTimeForNewAccount()));
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@@ -289,7 +293,7 @@ function open(options?: { id?: string, currentAccount?: Account, category?: numb
|
||||
loading.value = true;
|
||||
submitting.value = false;
|
||||
|
||||
const newAccount = Account.createNewAccount(userStore.currentUserDefaultCurrency, getCurrentUnixTime());
|
||||
const newAccount = Account.createNewAccount(userStore.currentUserDefaultCurrency, getCurrentUnixTimeForNewAccount());
|
||||
account.value.fillFrom(newAccount);
|
||||
subAccounts.value = [];
|
||||
currentAccountIndex.value = -1;
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
<template #item.time="{ item }">
|
||||
<span>{{ getDisplayDateTime(item) }}</span>
|
||||
<v-chip class="ms-1" variant="flat" color="secondary" size="x-small"
|
||||
v-if="item.utcOffset !== currentTimezoneOffsetMinutes">{{ getDisplayTimezone(item) }}</v-chip>
|
||||
v-if="!isSameAsDefaultTimezoneOffsetMinutes(item)">{{ getDisplayTimezone(item) }}</v-chip>
|
||||
</template>
|
||||
<template #item.type="{ item }">
|
||||
<v-chip label variant="outlined" size="x-small"
|
||||
@@ -323,7 +323,6 @@ const {
|
||||
startTime,
|
||||
endTime,
|
||||
reconciliationStatements,
|
||||
currentTimezoneOffsetMinutes,
|
||||
fiscalYearStart,
|
||||
allChartTypes,
|
||||
allDateAggregationTypes,
|
||||
@@ -341,6 +340,7 @@ const {
|
||||
setReconciliationStatements,
|
||||
getDisplayTransactionType,
|
||||
getDisplayDateTime,
|
||||
isSameAsDefaultTimezoneOffsetMinutes,
|
||||
getDisplayTimezone,
|
||||
getDisplaySourceAmount,
|
||||
getDisplayDestinationAmount,
|
||||
|
||||
@@ -151,9 +151,10 @@ import {
|
||||
} from '@/models/transaction.ts';
|
||||
|
||||
import {
|
||||
parseDateTimeFromUnixTime,
|
||||
getShiftedDateRangeAndDateType,
|
||||
getDateTypeByDateRange,
|
||||
getDateRangeByDateType,
|
||||
getDateRangeByDateType
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
import {
|
||||
@@ -188,7 +189,7 @@ const {
|
||||
tt,
|
||||
getAllDateRanges,
|
||||
getCurrentNumeralSystemType,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatDateTimeToLongDateTime,
|
||||
formatDateRange
|
||||
} = useI18n();
|
||||
|
||||
@@ -221,8 +222,8 @@ const filteredTransactions = computed<TransactionInsightDataItem[]>(() => explor
|
||||
const allDateRanges = computed<LocalizedDateRange[]>(() => getAllDateRanges(DateRangeScene.InsightsExplore, true));
|
||||
const canShiftDateRange = computed<boolean>(() => query.value.dateRangeType !== DateRange.All.type);
|
||||
const displayQueryDateRangeName = computed<string>(() => formatDateRange(query.value.dateRangeType, query.value.startTime, query.value.endTime));
|
||||
const displayQueryStartTime = computed<string>(() => formatUnixTimeToLongDateTime(query.value.startTime));
|
||||
const displayQueryEndTime = computed<string>(() => formatUnixTimeToLongDateTime(query.value.endTime));
|
||||
const displayQueryStartTime = computed<string>(() => formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(query.value.startTime)));
|
||||
const displayQueryEndTime = computed<string>(() => formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(query.value.endTime)));
|
||||
|
||||
const allTabs = computed<{ name: string, value: ExplorePageTabType }[]>(() => {
|
||||
return [
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<template #item.time="{ item }">
|
||||
<span>{{ getDisplayDateTime(item) }}</span>
|
||||
<v-chip class="ms-1" variant="flat" color="secondary" size="x-small"
|
||||
v-if="item.utcOffset !== currentTimezoneOffsetMinutes">{{ getDisplayTimezone(item) }}</v-chip>
|
||||
v-if="!isSameAsDefaultTimezoneOffsetMinutes(item)">{{ getDisplayTimezone(item) }}</v-chip>
|
||||
</template>
|
||||
<template #item.type="{ item }">
|
||||
<v-chip label variant="outlined" size="x-small"
|
||||
@@ -76,7 +76,6 @@ import { ref, computed } from 'vue';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
import { useExploresStore } from '@/stores/explore.ts';
|
||||
|
||||
@@ -89,7 +88,7 @@ import {
|
||||
import {
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffsetMinutes,
|
||||
parseDateTimeFromUnixTime
|
||||
parseDateTimeFromUnixTimeWithTimezoneOffset
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
import {
|
||||
@@ -109,19 +108,17 @@ const emit = defineEmits<{
|
||||
|
||||
const {
|
||||
tt,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatUnixTimeToGregorianDefaultDateTime,
|
||||
formatDateTimeToLongDateTime,
|
||||
formatDateTimeToGregorianDefaultDateTime,
|
||||
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
||||
formatAmountToLocalizedNumeralsWithCurrency
|
||||
} = useI18n();
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const userStore = useUserStore();
|
||||
const exploresStore = useExploresStore();
|
||||
|
||||
const currentPage = ref<number>(1);
|
||||
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||
|
||||
const filteredTransactions = computed<TransactionInsightDataItem[]>(() => exploresStore.filteredTransactions);
|
||||
@@ -163,7 +160,12 @@ const dataTableHeaders = computed<object[]>(() => {
|
||||
});
|
||||
|
||||
function getDisplayDateTime(transaction: TransactionInsightDataItem): string {
|
||||
return formatUnixTimeToLongDateTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset);
|
||||
return formatDateTimeToLongDateTime(dateTime);
|
||||
}
|
||||
|
||||
function isSameAsDefaultTimezoneOffsetMinutes(transaction: TransactionInsightDataItem): boolean {
|
||||
return transaction.utcOffset === getTimezoneOffsetMinutes(transaction.time);
|
||||
}
|
||||
|
||||
function getDisplayTimezone(transaction: TransactionInsightDataItem): string {
|
||||
@@ -234,7 +236,7 @@ function buildExportResults(): { headers: string[], data: string[][] } | undefin
|
||||
],
|
||||
data: filteredTransactions.value
|
||||
.map(transaction => {
|
||||
const transactionTime = parseDateTimeFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value).getUnixTime();
|
||||
const transactionTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset);
|
||||
const type = getDisplayTransactionType(transaction);
|
||||
|
||||
let categoryName = transaction.secondaryCategoryName;
|
||||
@@ -254,7 +256,7 @@ function buildExportResults(): { headers: string[], data: string[][] } | undefin
|
||||
const description = transaction.comment || '';
|
||||
|
||||
return [
|
||||
formatUnixTimeToGregorianDefaultDateTime(transactionTime),
|
||||
formatDateTimeToGregorianDefaultDateTime(transactionTime),
|
||||
type,
|
||||
categoryName,
|
||||
displayAmount,
|
||||
|
||||
@@ -41,7 +41,7 @@ import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numera
|
||||
|
||||
import { type TransactionMonthlyIncomeAndExpenseData } from '@/models/transaction.ts';
|
||||
|
||||
import { getUnixTimeBeforeUnixTime, getThisMonthFirstUnixTime } from '@/lib/datetime.ts';
|
||||
import { parseDateTimeFromUnixTime } from '@/lib/datetime.ts';
|
||||
import { getExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
|
||||
|
||||
export interface MonthlyIncomeAndExpenseCardClickEvent {
|
||||
@@ -64,7 +64,7 @@ const emit = defineEmits<{
|
||||
const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
formatUnixTimeToGregorianLikeShortMonth,
|
||||
formatDateTimeToGregorianLikeShortMonth,
|
||||
formatAmountToLocalizedNumeralsWithCurrency
|
||||
} = useI18n();
|
||||
|
||||
@@ -98,11 +98,9 @@ const chartOptions = computed<object>(() => {
|
||||
const expenseIncomeAmountColor = getExpenseAndIncomeAmountColor(userStore.currentUserExpenseAmountColor, userStore.currentUserIncomeAmountColor, props.isDarkMode);
|
||||
|
||||
if (props.data) {
|
||||
const currentMonthFirstUnixTime = getThisMonthFirstUnixTime();
|
||||
|
||||
for (const item of props.data) {
|
||||
const monthFirstUnixTime = getUnixTimeBeforeUnixTime(currentMonthFirstUnixTime, item.monthsBeforeCurrentMonth, 'months');
|
||||
const monthShortName = formatUnixTimeToGregorianLikeShortMonth(monthFirstUnixTime);
|
||||
const monthStartDateTime = parseDateTimeFromUnixTime(item.monthStartTime);
|
||||
const monthShortName = formatDateTimeToGregorianLikeShortMonth(monthStartDateTime);
|
||||
|
||||
monthNames.push(monthShortName);
|
||||
incomeAmounts.push(item.incomeAmount);
|
||||
|
||||
@@ -534,8 +534,8 @@
|
||||
<td class="transaction-table-column-time">
|
||||
<div class="d-flex flex-column">
|
||||
<span>{{ getDisplayTime(transaction) }}</span>
|
||||
<span class="text-caption" v-if="transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ getDisplayTimezone(transaction) }}</span>
|
||||
<v-tooltip activator="parent" v-if="transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ getDisplayTimeInDefaultTimezone(transaction) }}</v-tooltip>
|
||||
<span class="text-caption" v-if="!isSameAsDefaultTimezoneOffsetMinutes(transaction)">{{ getDisplayTimezone(transaction) }}</span>
|
||||
<v-tooltip activator="parent" v-if="!isSameAsDefaultTimezoneOffsetMinutes(transaction)">{{ getDisplayTimeInDefaultTimezone(transaction) }}</v-tooltip>
|
||||
</div>
|
||||
</td>
|
||||
<td class="transaction-table-column-category">
|
||||
@@ -691,8 +691,6 @@ import {
|
||||
import {
|
||||
getCurrentUnixTime,
|
||||
parseDateTimeFromUnixTime,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getActualUnixTimeForStore,
|
||||
getDayFirstUnixTimeBySpecifiedUnixTime,
|
||||
getYearMonthFirstUnixTime,
|
||||
getYearMonthLastUnixTime,
|
||||
@@ -775,7 +773,6 @@ const {
|
||||
customMinDatetime,
|
||||
customMaxDatetime,
|
||||
currentCalendarDate,
|
||||
currentTimezoneOffsetMinutes,
|
||||
firstDayOfWeek,
|
||||
fiscalYearStart,
|
||||
defaultCurrency,
|
||||
@@ -809,6 +806,7 @@ const {
|
||||
transactionCalendarMaxDate,
|
||||
currentMonthTransactionData,
|
||||
hasSubCategoryInQuery,
|
||||
isSameAsDefaultTimezoneOffsetMinutes,
|
||||
canAddTransaction,
|
||||
getDisplayTime,
|
||||
getDisplayLongDate,
|
||||
@@ -1234,7 +1232,7 @@ function changePageType(type: number): void {
|
||||
function changeDateFilter(dateRange: TimeRangeAndDateType | number | null): void {
|
||||
if (dateRange === DateRange.Custom.type || (isObject(dateRange) && dateRange.dateType === DateRange.Custom.type && !dateRange.minTime && !dateRange.maxTime)) { // Custom
|
||||
if (!query.value.minTime || !query.value.maxTime) {
|
||||
customMaxDatetime.value = getActualUnixTimeForStore(getCurrentUnixTime(), currentTimezoneOffsetMinutes.value, getBrowserTimezoneOffsetMinutes());
|
||||
customMaxDatetime.value = getCurrentUnixTime();
|
||||
customMinDatetime.value = getDayFirstUnixTimeBySpecifiedUnixTime(customMaxDatetime.value);
|
||||
} else {
|
||||
customMaxDatetime.value = query.value.maxTime;
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
<template #item.time="{ item }">
|
||||
<span>{{ getDisplayDateTime(item) }}</span>
|
||||
<v-chip class="ms-1" variant="flat" color="grey" size="x-small"
|
||||
v-if="item.utcOffset !== currentTimezoneOffsetMinutes">{{ getDisplayTimezone(item) }}</v-chip>
|
||||
v-if="!isSameAsDefaultTimezoneOffsetMinutes(item)">{{ getDisplayTimezone(item) }}</v-chip>
|
||||
</template>
|
||||
<template #item.type="{ value }">
|
||||
<v-chip label color="secondary" variant="outlined" size="x-small" v-if="value === TransactionType.ModifyBalance">{{ tt('Modify Balance') }}</v-chip>
|
||||
@@ -427,7 +427,9 @@ import {
|
||||
} from '@/lib/common.ts';
|
||||
import {
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffsetMinutes
|
||||
getTimezoneOffsetMinutes,
|
||||
parseDateTimeFromUnixTime,
|
||||
parseDateTimeFromUnixTimeWithTimezoneOffset
|
||||
} from '@/lib/datetime.ts';
|
||||
import { formatCoordinate } from '@/lib/coordinate.ts';
|
||||
import {
|
||||
@@ -495,7 +497,7 @@ const props = defineProps<{
|
||||
const {
|
||||
tt,
|
||||
getCurrentNumeralSystemType,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatDateTimeToLongDateTime,
|
||||
formatAmountToLocalizedNumeralsWithCurrency,
|
||||
getCategorizedAccountsWithDisplayBalance
|
||||
} = useI18n();
|
||||
@@ -536,7 +538,6 @@ const currentDescriptionFilterValue = ref<string | null>(null);
|
||||
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const showAccountBalance = computed<boolean>(() => settingsStore.appSettings.showAccountBalance);
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||
|
||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||
const coordinateDisplayType = computed<number>(() => userStore.currentUserCoordinateDisplayType);
|
||||
@@ -1129,8 +1130,8 @@ const displayFilterCustomDateRange = computed<string>(() => {
|
||||
return '';
|
||||
}
|
||||
|
||||
const minDisplayTime = formatUnixTimeToLongDateTime(filters.value.minDatetime);
|
||||
const maxDisplayTime = formatUnixTimeToLongDateTime(filters.value.maxDatetime);
|
||||
const minDisplayTime = formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(filters.value.minDatetime));
|
||||
const maxDisplayTime = formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(filters.value.maxDatetime));
|
||||
|
||||
return `${minDisplayTime} - ${maxDisplayTime}`
|
||||
});
|
||||
@@ -1272,7 +1273,12 @@ function isTagValid(tagIds: string[], tagIndex: number): boolean {
|
||||
}
|
||||
|
||||
function getDisplayDateTime(transaction: ImportTransaction): string {
|
||||
return formatUnixTimeToLongDateTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset)
|
||||
return formatDateTimeToLongDateTime(dateTime);
|
||||
}
|
||||
|
||||
function isSameAsDefaultTimezoneOffsetMinutes(transaction: ImportTransaction): boolean {
|
||||
return transaction.utcOffset === getTimezoneOffsetMinutes(transaction.time);
|
||||
}
|
||||
|
||||
function getDisplayTimezone(transaction: ImportTransaction): string {
|
||||
|
||||
+5
-2
@@ -54,7 +54,10 @@ import { KnownFileType } from '@/core/file.ts';
|
||||
import type { ImportTransactionRequest, ImportTransactionRequestItem } from '@/models/imported_transaction.ts';
|
||||
|
||||
import { isDefined } from '@/lib/common.ts';
|
||||
import { getBrowserTimezoneOffsetMinutes } from '@/lib/datetime.ts';
|
||||
import {
|
||||
getTimezoneOffsetMinutes,
|
||||
getCurrentUnixTime
|
||||
} from '@/lib/datetime.ts';
|
||||
import {
|
||||
openTextFileContent,
|
||||
startDownloadFile
|
||||
@@ -121,7 +124,7 @@ function parse(row, index) {
|
||||
|
||||
return {
|
||||
time: row[0], // ${tt('sample.importTransactionCustomScript.fieldTimeDescription')}
|
||||
utcOffset: '${getBrowserTimezoneOffsetMinutes()}', // ${tt('sample.importTransactionCustomScript.fieldUtcOffsetDescription')}
|
||||
utcOffset: '${getTimezoneOffsetMinutes(getCurrentUnixTime())}', // ${tt('sample.importTransactionCustomScript.fieldUtcOffsetDescription')}
|
||||
type: TransactionType.Expense, // ${tt('sample.importTransactionCustomScript.fieldTypeDescription')}
|
||||
categoryName: row[4], // ${tt('sample.importTransactionCustomScript.fieldCategoryNameDescription')}
|
||||
sourceAccountName: row[5], // ${tt('sample.importTransactionCustomScript.fieldSourceAccountNameDescription')}
|
||||
|
||||
@@ -250,7 +250,9 @@
|
||||
:readonly="mode === TransactionEditPageMode.View"
|
||||
:disabled="loading || submitting || (mode === TransactionEditPageMode.Edit && transaction.type === TransactionType.ModifyBalance)"
|
||||
:label="tt('Transaction Time')"
|
||||
v-model="transaction.time"
|
||||
:timezone-utc-offset="transaction.utcOffset"
|
||||
:model-value="transaction.time"
|
||||
@update:model-value="updateTransactionTime"
|
||||
@error="onShowDateTimeError" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="6" v-if="type === TransactionEditPageType.Template && transaction instanceof TransactionTemplate && transaction.templateType === TemplateType.Schedule.type">
|
||||
@@ -274,7 +276,8 @@
|
||||
:placeholder="!transaction.timeZone && transaction.timeZone !== '' ? `(${transactionDisplayTimezone}) ${transactionTimezoneTimeDifference}` : tt('Timezone')"
|
||||
:items="allTimezones"
|
||||
:no-data-text="tt('No results')"
|
||||
v-model="transaction.timeZone"
|
||||
:model-value="transaction.timeZone"
|
||||
@update:model-value="updateTransactionTimezone"
|
||||
>
|
||||
<template #selection="{ item }">
|
||||
<span class="text-truncate" v-if="transaction.timeZone || transaction.timeZone === ''">
|
||||
@@ -642,6 +645,8 @@ const {
|
||||
inputEmptyProblemMessage,
|
||||
inputIsEmpty,
|
||||
createNewTransactionModel,
|
||||
updateTransactionTime,
|
||||
updateTransactionTimezone,
|
||||
swapTransactionData,
|
||||
getTransactionPictureUrl
|
||||
} = useTransactionEditPageBase(props.type);
|
||||
@@ -714,7 +719,7 @@ const isTransactionModified = computed<boolean>(() => {
|
||||
}
|
||||
});
|
||||
|
||||
function setTransaction(newTransaction: Transaction | null, options: SetTransactionOptions, setContextData: boolean, convertContextTime: boolean): void {
|
||||
function setTransaction(newTransaction: Transaction | null, options: SetTransactionOptions, setContextData: boolean): void {
|
||||
setTransactionModelByTransaction(
|
||||
transaction.value,
|
||||
newTransaction,
|
||||
@@ -735,8 +740,7 @@ function setTransaction(newTransaction: Transaction | null, options: SetTransact
|
||||
tagIds: options.tagIds,
|
||||
comment: options.comment
|
||||
},
|
||||
setContextData,
|
||||
convertContextTime
|
||||
setContextData
|
||||
);
|
||||
}
|
||||
|
||||
@@ -758,7 +762,7 @@ function open(options: TransactionEditOptions): Promise<TransactionEditResponse
|
||||
initTagIds.value = options.tagIds;
|
||||
|
||||
const newTransaction = createNewTransactionModel(options.type);
|
||||
setTransaction(newTransaction, options, true, false);
|
||||
setTransaction(newTransaction, options, true);
|
||||
|
||||
const promises: Promise<unknown>[] = [
|
||||
accountsStore.loadAllAccounts({ force: false }),
|
||||
@@ -769,7 +773,7 @@ function open(options: TransactionEditOptions): Promise<TransactionEditResponse
|
||||
if (props.type === TransactionEditPageType.Transaction) {
|
||||
if (options && options.id) {
|
||||
if (options.currentTransaction) {
|
||||
setTransaction(options.currentTransaction, options, true, true);
|
||||
setTransaction(options.currentTransaction, options, true);
|
||||
}
|
||||
|
||||
mode.value = TransactionEditPageMode.View;
|
||||
@@ -781,10 +785,10 @@ function open(options: TransactionEditOptions): Promise<TransactionEditResponse
|
||||
editId.value = null;
|
||||
|
||||
if (options.template) {
|
||||
setTransaction(options.template, options, false, false);
|
||||
setTransaction(options.template, options, false);
|
||||
addByTemplateId.value = options.template.id;
|
||||
} else if (!options.noTransactionDraft && (settingsStore.appSettings.autoSaveTransactionDraft === 'enabled' || settingsStore.appSettings.autoSaveTransactionDraft === 'confirmation') && transactionsStore.transactionDraft) {
|
||||
setTransaction(Transaction.ofDraft(transactionsStore.transactionDraft), options, false, false);
|
||||
setTransaction(Transaction.ofDraft(transactionsStore.transactionDraft), options, false);
|
||||
}
|
||||
|
||||
if (settingsStore.appSettings.autoGetCurrentGeoLocation
|
||||
@@ -809,7 +813,7 @@ function open(options: TransactionEditOptions): Promise<TransactionEditResponse
|
||||
|
||||
if (options && options.id) {
|
||||
if (options.currentTemplate) {
|
||||
setTransaction(options.currentTemplate, options, false, false);
|
||||
setTransaction(options.currentTemplate, options, false);
|
||||
(transaction.value as TransactionTemplate).fillFrom(options.currentTemplate);
|
||||
}
|
||||
|
||||
@@ -850,11 +854,11 @@ function open(options: TransactionEditOptions): Promise<TransactionEditResponse
|
||||
|
||||
if (props.type === TransactionEditPageType.Transaction && options && options.id && responses[3] && responses[3] instanceof Transaction) {
|
||||
const transaction: Transaction = responses[3];
|
||||
setTransaction(transaction, options, true, true);
|
||||
setTransaction(transaction, options, true);
|
||||
originalTransactionEditable.value = transaction.editable;
|
||||
} else if (props.type === TransactionEditPageType.Template && options && options.id && responses[3] && responses[3] instanceof TransactionTemplate) {
|
||||
const template: TransactionTemplate = responses[3];
|
||||
setTransaction(template, options, false, false);
|
||||
setTransaction(template, options, false);
|
||||
|
||||
if (!(transaction.value instanceof TransactionTemplate)) {
|
||||
transaction.value = TransactionTemplate.createNewTransactionTemplate(transaction.value);
|
||||
@@ -862,7 +866,7 @@ function open(options: TransactionEditOptions): Promise<TransactionEditResponse
|
||||
|
||||
(transaction.value as TransactionTemplate).fillFrom(template);
|
||||
} else {
|
||||
setTransaction(null, options, true, true);
|
||||
setTransaction(null, options, true);
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
@@ -1003,7 +1007,7 @@ function duplicate(withTime?: boolean, withGeoLocation?: boolean): void {
|
||||
if (!withTime) {
|
||||
transaction.value.time = getCurrentUnixTime();
|
||||
transaction.value.timeZone = settingsStore.appSettings.timeZone;
|
||||
transaction.value.utcOffset = getTimezoneOffsetMinutes(transaction.value.timeZone);
|
||||
transaction.value.utcOffset = getTimezoneOffsetMinutes(transaction.value.time, transaction.value.timeZone);
|
||||
}
|
||||
|
||||
if (!withGeoLocation) {
|
||||
|
||||
@@ -218,6 +218,7 @@ import { type UserExternalAuthInfoResponse } from '@/models/user_external_auth.t
|
||||
import { type TokenInfoResponse, SessionDeviceType, SessionInfo } from '@/models/token.ts';
|
||||
|
||||
import { isEquals } from '@/lib/common.ts';
|
||||
import { parseDateTimeFromUnixTime } from '@/lib/datetime.ts';
|
||||
import { parseSessionInfo } from '@/lib/session.ts';
|
||||
import {
|
||||
isAPITokenEnabled,
|
||||
@@ -253,7 +254,7 @@ class DesktopPageLinkedThirdPartyLogin {
|
||||
this.externalAuthType = externalAuthInfoResponse.externalAuthType;
|
||||
this.linked = externalAuthInfoResponse.linked;
|
||||
this.externalUsername = externalAuthInfoResponse.externalUsername ? externalAuthInfoResponse.externalUsername : '-';
|
||||
this.createdAt = externalAuthInfoResponse.createdAt ? formatUnixTimeToLongDateTime(externalAuthInfoResponse.createdAt) : '-';
|
||||
this.createdAt = externalAuthInfoResponse.createdAt ? formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(externalAuthInfoResponse.createdAt)) : '-';
|
||||
|
||||
if (externalAuthInfoResponse.externalAuthCategory === 'oauth2') {
|
||||
this.displayName = getLocalizedOAuth2ProviderName(externalAuthInfoResponse.externalAuthType, getOIDCCustomDisplayNames());
|
||||
@@ -277,7 +278,7 @@ class DesktopPageSessionInfo extends SessionInfo {
|
||||
public constructor(sessionInfo: SessionInfo) {
|
||||
super(sessionInfo.tokenId, sessionInfo.isCurrent, sessionInfo.deviceType, sessionInfo.deviceInfo, sessionInfo.deviceName, sessionInfo.lastSeen);
|
||||
this.icon = this.getTokenIcon(sessionInfo.deviceType);
|
||||
this.lastSeenDateTime = sessionInfo.lastSeen ? formatUnixTimeToLongDateTime(sessionInfo.lastSeen) : '-';
|
||||
this.lastSeenDateTime = sessionInfo.lastSeen ? formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(sessionInfo.lastSeen)) : '-';
|
||||
}
|
||||
|
||||
private getTokenIcon(deviceType: SessionDeviceType): string {
|
||||
@@ -306,7 +307,7 @@ type SnackBarType = InstanceType<typeof SnackBar>;
|
||||
|
||||
const {
|
||||
tt,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatDateTimeToLongDateTime,
|
||||
getLocalizedOAuth2ProviderName,
|
||||
setLanguage
|
||||
} = useI18n();
|
||||
|
||||
@@ -129,6 +129,7 @@ import { useUserStore } from '@/stores/user.ts';
|
||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||
|
||||
import { findNameByValue } from '@/lib/common.ts';
|
||||
import { parseDateTimeFromUnixTime } from '@/lib/datetime.ts';
|
||||
import { getClientDisplayVersion, getDesktopVersionPath } from '@/lib/version.ts';
|
||||
import { isUserScheduledTransactionEnabled } from '@/lib/server_settings.ts';
|
||||
import { setExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
|
||||
@@ -137,7 +138,7 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt, formatUnixTimeToLongDate, initLocale } = useI18n();
|
||||
const { tt, formatDateTimeToLongDate, initLocale } = useI18n();
|
||||
const { showToast, showConfirm } = useI18nUIComponents();
|
||||
const { allThemes, allTimezones, timeZone, isAutoUpdateExchangeRatesData, showAccountBalance } = useAppSettingPageBase();
|
||||
|
||||
@@ -197,8 +198,12 @@ const isEnableAnimate = computed<boolean>({
|
||||
const isEnableApplicationLock = computed<boolean>(() => settingsStore.appSettings.applicationLock);
|
||||
|
||||
const exchangeRatesLastUpdateDate = computed<string>(() => {
|
||||
const exchangeRatesLastUpdateTime = exchangeRatesStore.exchangeRatesLastUpdateTime;
|
||||
return exchangeRatesLastUpdateTime ? formatUnixTimeToLongDate(exchangeRatesLastUpdateTime) : '';
|
||||
if (!exchangeRatesStore.exchangeRatesLastUpdateTime) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const exchangeRatesLastUpdateTime = parseDateTimeFromUnixTime(exchangeRatesStore.exchangeRatesLastUpdateTime);
|
||||
return formatDateTimeToLongDate(exchangeRatesLastUpdateTime);
|
||||
});
|
||||
|
||||
function switchToDesktopVersion(): void {
|
||||
|
||||
@@ -233,8 +233,10 @@
|
||||
</div>
|
||||
</template>
|
||||
<date-time-selection-sheet :init-mode="accountContext.balanceDateTimeSheetMode"
|
||||
:timezone-utc-offset="getDefaultTimezoneOffsetMinutes(account)"
|
||||
:model-value="account.balanceTime"
|
||||
v-model:show="accountContext.showBalanceDateTimeSheet"
|
||||
v-model="account.balanceTime">
|
||||
@update:model-value="updateAccountBalanceTime(account, $event)">
|
||||
</date-time-selection-sheet>
|
||||
</f7-list-item>
|
||||
|
||||
@@ -475,8 +477,10 @@
|
||||
</div>
|
||||
</template>
|
||||
<date-time-selection-sheet :init-mode="subAccountContexts[idx]!.balanceDateTimeSheetMode"
|
||||
:timezone-utc-offset="getDefaultTimezoneOffsetMinutes(subAccount)"
|
||||
:model-value="subAccount.balanceTime"
|
||||
v-model:show="subAccountContexts[idx]!.showBalanceDateTimeSheet"
|
||||
v-model="subAccount.balanceTime">
|
||||
@update:model-value="updateAccountBalanceTime(subAccount, $event)">
|
||||
</date-time-selection-sheet>
|
||||
</f7-list-item>
|
||||
|
||||
@@ -538,8 +542,7 @@ import { isDefined, findDisplayNameByType } from '@/lib/common.ts';
|
||||
import { generateRandomUUID } from '@/lib/misc.ts';
|
||||
import {
|
||||
getTimezoneOffsetMinutes,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getActualUnixTimeForStore
|
||||
parseDateTimeFromUnixTimeWithTimezoneOffset
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
interface AccountContext {
|
||||
@@ -561,8 +564,8 @@ const {
|
||||
tt,
|
||||
getAllCurrencies,
|
||||
getCurrencyName,
|
||||
formatUnixTimeToLongDate,
|
||||
formatUnixTimeToLongTime,
|
||||
formatDateTimeToLongDate,
|
||||
formatDateTimeToLongTime,
|
||||
formatAmountToLocalizedNumeralsWithCurrency
|
||||
} = useI18n();
|
||||
|
||||
@@ -582,7 +585,9 @@ const {
|
||||
allAccountTypes,
|
||||
allAvailableMonthDays,
|
||||
isAccountSupportCreditCardStatementDate,
|
||||
getDefaultTimezoneOffsetMinutes,
|
||||
getAccountCreditCardStatementDate,
|
||||
updateAccountBalanceTime,
|
||||
isNewAccount,
|
||||
addSubAccount,
|
||||
setAccount
|
||||
@@ -621,7 +626,8 @@ function formatAccountBalanceDate(account: Account): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
return formatUnixTimeToLongDate(getActualUnixTimeForStore(account.balanceTime, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes()));
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(account.balanceTime, getTimezoneOffsetMinutes(account.balanceTime));
|
||||
return formatDateTimeToLongDate(dateTime);
|
||||
}
|
||||
|
||||
function formatAccountBalanceTime(account: Account): string {
|
||||
@@ -629,7 +635,8 @@ function formatAccountBalanceTime(account: Account): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
return formatUnixTimeToLongTime(getActualUnixTimeForStore(account.balanceTime, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes()));
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(account.balanceTime, getTimezoneOffsetMinutes(account.balanceTime));
|
||||
return formatDateTimeToLongTime(dateTime);
|
||||
}
|
||||
|
||||
function init(): void {
|
||||
|
||||
@@ -51,10 +51,10 @@
|
||||
</template>
|
||||
<template #footer>
|
||||
<div v-if="dateRange.isUserCustomRange && queryDateRangeType === dateRange.type && startTime && endTime">
|
||||
<span>{{ displayStartTime }}</span>
|
||||
<span>{{ displayStartDateTime }}</span>
|
||||
<span> - </span>
|
||||
<br/>
|
||||
<span>{{ displayEndTime }}</span>
|
||||
<span>{{ displayEndDateTime }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
@@ -227,7 +227,7 @@
|
||||
<div class="transaction-footer display-flex justify-content-space-between">
|
||||
<div class="flex-shrink-0">
|
||||
<span>{{ getDisplayTime(item.transaction) }}</span>
|
||||
<span v-if="item.transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ `(${getDisplayTimezone(item.transaction)})` }}</span>
|
||||
<span style="margin-inline-start: 4px" v-if="!isSameAsDefaultTimezoneOffsetMinutes(item.transaction)">{{ `(${getDisplayTimezone(item.transaction)})` }}</span>
|
||||
</div>
|
||||
<div class="account-balance flex-shrink-1">
|
||||
<span>{{ isCurrentLiabilityAccount ? tt('Outstanding Balance') : tt('Balance') }}</span>
|
||||
@@ -388,7 +388,6 @@ const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
getAllDateRanges,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatNumberToLocalizedNumerals
|
||||
} = useI18n();
|
||||
|
||||
@@ -402,7 +401,6 @@ const {
|
||||
firstDayOfWeek,
|
||||
fiscalYearStart,
|
||||
allDateAggregationTypes,
|
||||
currentTimezoneOffsetMinutes,
|
||||
isCurrentLiabilityAccount,
|
||||
currentAccount,
|
||||
currentAccountCurrency,
|
||||
@@ -416,6 +414,7 @@ const {
|
||||
setReconciliationStatements,
|
||||
getDisplayDate,
|
||||
getDisplayTime,
|
||||
isSameAsDefaultTimezoneOffsetMinutes,
|
||||
getDisplayTimezone,
|
||||
getDisplaySourceAmount,
|
||||
getDisplayDestinationAmount,
|
||||
@@ -446,8 +445,6 @@ const virtualDataItems = ref<ReconciliationStatementVirtualListData>({
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
const validQuery = computed(() => currentAccount.value && currentAccount.value.type === AccountType.SingleAccount.type);
|
||||
const allAvailableDateRanges = computed(() => getAllDateRanges(DateRangeScene.Normal, true, !!accountsStore.getAccountStatementDate(accountId.value)));
|
||||
const displayStartTime = computed<string>(() => formatUnixTimeToLongDateTime(startTime.value));
|
||||
const displayEndTime = computed<string>(() => formatUnixTimeToLongDateTime(endTime.value));
|
||||
|
||||
const allReconciliationStatementVirtualListItems = computed<ReconciliationStatementVirtualListItem[]>(() => {
|
||||
const ret: ReconciliationStatementVirtualListItem[] = [];
|
||||
|
||||
@@ -124,8 +124,9 @@ import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { type DateTime } from '@/core/datetime.ts';
|
||||
import { FontSize } from '@/core/font.ts';
|
||||
import { parseDateTimeFromUnixTime, getCurrentUnixTime } from '@/lib/datetime.ts';
|
||||
import { getCurrentDateTime } from '@/lib/datetime.ts';
|
||||
import { setAppFontSize, getFontSizePreviewClassName } from '@/lib/ui/mobile.ts';
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -136,23 +137,23 @@ const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
getWeekdayShortName,
|
||||
getCalendarDisplayDayOfMonthFromUnixTime,
|
||||
formatUnixTimeToShortTime,
|
||||
formatUnixTimeToGregorianLikeLongYearMonth,
|
||||
getCalendarDisplayDayOfMonthFromDateTime,
|
||||
formatDateTimeToShortTime,
|
||||
formatDateTimeToGregorianLikeLongYearMonth,
|
||||
formatAmountToLocalizedNumeralsWithCurrency
|
||||
} = useI18n();
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const currentUnixTime = ref<number>(getCurrentUnixTime());
|
||||
const currentDateTime = ref<DateTime>(getCurrentDateTime());
|
||||
const fontSize = ref<number>(settingsStore.appSettings.fontSize);
|
||||
|
||||
const textDirection = computed<string>(() => getCurrentLanguageTextDirection());
|
||||
const fontSizePreviewClassName = computed<string>(() => getFontSizePreviewClassName(fontSize.value));
|
||||
const currentLongYearMonth = computed<string>(() => formatUnixTimeToGregorianLikeLongYearMonth(currentUnixTime.value));
|
||||
const currentDayOfMonth = computed<string>(() => getCalendarDisplayDayOfMonthFromUnixTime(currentUnixTime.value));
|
||||
const currentDayOfWeek = computed<string>(() => getWeekdayShortName(parseDateTimeFromUnixTime(currentUnixTime.value).getWeekDay()));
|
||||
const currentShortTime = computed<string>(() => formatUnixTimeToShortTime(currentUnixTime.value));
|
||||
const currentLongYearMonth = computed<string>(() => formatDateTimeToGregorianLikeLongYearMonth(currentDateTime.value));
|
||||
const currentDayOfMonth = computed<string>(() => getCalendarDisplayDayOfMonthFromDateTime(currentDateTime.value));
|
||||
const currentDayOfWeek = computed<string>(() => getWeekdayShortName(currentDateTime.value.getWeekDay()));
|
||||
const currentShortTime = computed<string>(() => formatDateTimeToShortTime(currentDateTime.value));
|
||||
|
||||
function getFontSizeName(): string {
|
||||
return '';
|
||||
|
||||
@@ -251,8 +251,10 @@
|
||||
</div>
|
||||
</template>
|
||||
<date-time-selection-sheet :init-mode="transactionDateTimeSheetMode"
|
||||
:timezone-utc-offset="transaction.utcOffset"
|
||||
:model-value="transaction.time"
|
||||
v-model:show="showTransactionDateTimeSheet"
|
||||
v-model="transaction.time">
|
||||
@update:model-value="updateTransactionTime">
|
||||
</date-time-selection-sheet>
|
||||
</f7-list-item>
|
||||
|
||||
@@ -323,8 +325,9 @@
|
||||
:filter-placeholder="tt('Timezone')"
|
||||
:filter-no-items-text="tt('No results')"
|
||||
:items="allTimezones"
|
||||
:model-value="transaction.timeZone"
|
||||
v-model:show="showTimezonePopup"
|
||||
v-model="transaction.timeZone">
|
||||
@update:model-value="updateTransactionTimezone">
|
||||
</list-item-selection-popup>
|
||||
</f7-list-item>
|
||||
|
||||
@@ -512,10 +515,9 @@ import type { TransactionPictureInfoBasicResponse } from '@/models/transaction_p
|
||||
import { Transaction } from '@/models/transaction.ts';
|
||||
|
||||
import {
|
||||
getActualUnixTimeForStore,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getTimezoneOffset,
|
||||
getTimezoneOffsetMinutes
|
||||
getTimezoneOffsetMinutes,
|
||||
parseDateTimeFromUnixTimeWithTimezoneOffset
|
||||
} from '@/lib/datetime.ts';
|
||||
import { formatCoordinate } from '@/lib/coordinate.ts';
|
||||
import { generateRandomUUID } from '@/lib/misc.ts';
|
||||
@@ -536,8 +538,8 @@ const {
|
||||
tt,
|
||||
getMultiMonthdayShortNames,
|
||||
getMultiWeekdayLongNames,
|
||||
formatUnixTimeToLongDate,
|
||||
formatUnixTimeToLongTime,
|
||||
formatDateTimeToLongDate,
|
||||
formatDateTimeToLongTime,
|
||||
formatGregorianTextualYearMonthDayToLongDate,
|
||||
parseAmountFromLocalizedNumerals
|
||||
} = useI18n();
|
||||
@@ -589,6 +591,8 @@ const {
|
||||
geoLocationStatusInfo,
|
||||
inputEmptyProblemMessage,
|
||||
inputIsEmpty,
|
||||
updateTransactionTime,
|
||||
updateTransactionTimezone,
|
||||
swapTransactionData,
|
||||
getDisplayAmount,
|
||||
getTransactionPictureUrl
|
||||
@@ -655,19 +659,23 @@ const destinationAmountClass = computed<Record<string, boolean>>(() => {
|
||||
|
||||
const transactionDisplayDate = computed<string>(() => {
|
||||
if (mode.value !== TransactionEditPageMode.View || !showTimeInDefaultTimezone.value) {
|
||||
return formatUnixTimeToLongDate(getActualUnixTimeForStore(transaction.value.time, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes()));
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.value.time, transaction.value.utcOffset);
|
||||
return formatDateTimeToLongDate(dateTime);
|
||||
}
|
||||
|
||||
return formatUnixTimeToLongDate(getActualUnixTimeForStore(transaction.value.time, transaction.value.utcOffset, getBrowserTimezoneOffsetMinutes()));
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.value.time, getTimezoneOffsetMinutes(transaction.value.time));
|
||||
return formatDateTimeToLongDate(dateTime);
|
||||
});
|
||||
|
||||
const transactionDisplayTime = computed<string>(() => {
|
||||
if (mode.value !== TransactionEditPageMode.View || !showTimeInDefaultTimezone.value) {
|
||||
return formatUnixTimeToLongTime(getActualUnixTimeForStore(transaction.value.time, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes()));
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.value.time, transaction.value.utcOffset);
|
||||
return formatDateTimeToLongTime(dateTime);
|
||||
}
|
||||
|
||||
const utcOffset = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(getTimezoneOffset(settingsStore.appSettings.timeZone));
|
||||
return `${formatUnixTimeToLongTime(getActualUnixTimeForStore(transaction.value.time, transaction.value.utcOffset, getBrowserTimezoneOffsetMinutes()))} (UTC${utcOffset})`;
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.value.time, getTimezoneOffsetMinutes(transaction.value.time));
|
||||
const utcOffset = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(getTimezoneOffset(transaction.value.time));
|
||||
return `${formatDateTimeToLongTime(dateTime)} (UTC${utcOffset})`;
|
||||
});
|
||||
|
||||
const transactionDisplayTimezoneName = computed<string>(() => {
|
||||
@@ -949,7 +957,6 @@ function init(): void {
|
||||
tagIds: query['tagIds'],
|
||||
comment: query['comment']
|
||||
},
|
||||
pageTypeAndMode.type === TransactionEditPageType.Transaction && (mode.value === TransactionEditPageMode.Edit || mode.value === TransactionEditPageMode.View),
|
||||
pageTypeAndMode.type === TransactionEditPageType.Transaction && (mode.value === TransactionEditPageMode.Edit || mode.value === TransactionEditPageMode.View)
|
||||
);
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
<template #media>
|
||||
<div class="display-flex flex-direction-column transaction-date" :style="getTransactionDateStyle(transaction, idx > 0 ? transactionMonthList.items[idx - 1] : undefined)">
|
||||
<span class="transaction-day full-line flex-direction-column">
|
||||
{{ getCalendarDisplayDayOfMonthFromUnixTime(transaction.time) }}
|
||||
{{ transaction.gregorianCalendarDayOfMonth ? numeralSystem.formatNumber(transaction.gregorianCalendarDayOfMonth) : '' }}
|
||||
</span>
|
||||
<span class="transaction-day-of-week full-line flex-direction-column" v-if="transaction.displayDayOfWeek">
|
||||
{{ getWeekdayShortName(transaction.displayDayOfWeek) }}
|
||||
@@ -265,7 +265,7 @@
|
||||
</div>
|
||||
<div class="transaction-footer">
|
||||
<span>{{ getDisplayTime(transaction) }}</span>
|
||||
<span v-if="transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ `(${getDisplayTimezone(transaction)})` }}</span>
|
||||
<span v-if="!isSameAsDefaultTimezoneOffsetMinutes(transaction)">{{ `(${getDisplayTimezone(transaction)})` }}</span>
|
||||
<span v-if="transaction.sourceAccount">·</span>
|
||||
<span v-if="transaction.sourceAccount">{{ transaction.sourceAccount.name }}</span>
|
||||
<f7-icon class="transaction-account-arrow icon-with-direction" f7="arrow_right" v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id"></f7-icon>
|
||||
@@ -624,7 +624,7 @@ import {
|
||||
DateRangeScene,
|
||||
DateRange
|
||||
} from '@/core/datetime.ts';
|
||||
import { AmountFilterType } from '@/core/numeral.ts';
|
||||
import { type NumeralSystem, AmountFilterType } from '@/core/numeral.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
||||
import { type Transaction, TransactionTagFilter } from '@/models/transaction.ts';
|
||||
@@ -637,8 +637,6 @@ import {
|
||||
import {
|
||||
getCurrentUnixTime,
|
||||
parseDateTimeFromUnixTime,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getActualUnixTimeForStore,
|
||||
getDayFirstUnixTimeBySpecifiedUnixTime,
|
||||
getYearMonthFirstUnixTime,
|
||||
getYearMonthLastUnixTime,
|
||||
@@ -664,8 +662,8 @@ const props = defineProps<{
|
||||
const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
getWeekdayShortName,
|
||||
getCalendarDisplayDayOfMonthFromUnixTime
|
||||
getCurrentNumeralSystemType,
|
||||
getWeekdayShortName
|
||||
} = useI18n();
|
||||
|
||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
@@ -676,7 +674,6 @@ const {
|
||||
customMinDatetime,
|
||||
customMaxDatetime,
|
||||
currentCalendarDate,
|
||||
currentTimezoneOffsetMinutes,
|
||||
firstDayOfWeek,
|
||||
fiscalYearStart,
|
||||
defaultCurrency,
|
||||
@@ -711,6 +708,7 @@ const {
|
||||
transactionCalendarMaxDate,
|
||||
currentMonthTransactionData,
|
||||
hasSubCategoryInQuery,
|
||||
isSameAsDefaultTimezoneOffsetMinutes,
|
||||
canAddTransaction,
|
||||
getDisplayTime,
|
||||
getDisplayLongYearMonth,
|
||||
@@ -737,6 +735,7 @@ const showCustomMonthSheet = ref<boolean>(false);
|
||||
const showDeleteActionSheet = ref<boolean>(false);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode || false);
|
||||
|
||||
const transactions = computed<TransactionMonthList[]>(() => {
|
||||
@@ -1057,7 +1056,7 @@ function changePageType(type: number): void {
|
||||
function changeDateFilter(dateType: number): void {
|
||||
if (dateType === DateRange.Custom.type) { // Custom
|
||||
if (!query.value.minTime || !query.value.maxTime) {
|
||||
customMaxDatetime.value = getActualUnixTimeForStore(getCurrentUnixTime(), currentTimezoneOffsetMinutes.value, getBrowserTimezoneOffsetMinutes());
|
||||
customMaxDatetime.value = getCurrentUnixTime();
|
||||
customMinDatetime.value = getDayFirstUnixTimeBySpecifiedUnixTime(customMaxDatetime.value);
|
||||
} else {
|
||||
customMaxDatetime.value = query.value.maxTime;
|
||||
|
||||
@@ -58,6 +58,7 @@ import { TextDirection } from '@/core/text.ts';
|
||||
import { type TokenInfoResponse, SessionDeviceType, SessionInfo } from '@/models/token.ts';
|
||||
|
||||
import { isEquals } from '@/lib/common.ts';
|
||||
import { parseDateTimeFromUnixTime } from '@/lib/datetime.ts';
|
||||
import { parseSessionInfo } from '@/lib/session.ts';
|
||||
|
||||
class MobilePageSessionInfo extends SessionInfo {
|
||||
@@ -69,7 +70,7 @@ class MobilePageSessionInfo extends SessionInfo {
|
||||
super(sessionInfo.tokenId, sessionInfo.isCurrent, sessionInfo.deviceType, sessionInfo.deviceInfo, sessionInfo.deviceName, sessionInfo.lastSeen);
|
||||
this.domId = getTokenDomId(sessionInfo.tokenId);
|
||||
this.icon = getTokenIcon(sessionInfo.deviceType);
|
||||
this.lastSeenDateTime = sessionInfo.lastSeen ? formatUnixTimeToLongDateTime(sessionInfo.lastSeen) : '-';
|
||||
this.lastSeenDateTime = sessionInfo.lastSeen ? formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(sessionInfo.lastSeen)) : '-';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +78,12 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt, getCurrentLanguageTextDirection, formatUnixTimeToLongDateTime } = useI18n();
|
||||
const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
formatDateTimeToLongDateTime
|
||||
} = useI18n();
|
||||
|
||||
const { showConfirm, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const tokensStore = useTokensStore();
|
||||
|
||||
Reference in New Issue
Block a user