migrate transaction list page to composition API and typescript

This commit is contained in:
MaysWind
2025-02-09 15:07:06 +08:00
parent bb3a0c4444
commit 596787b998
12 changed files with 1875 additions and 2453 deletions

View File

@@ -23,17 +23,9 @@ export default [
'**/*.{vue,ts,tsx,mts,js,jsx,cjs,mjs}'
],
rules: {
'@typescript-eslint/no-this-alias': ['error', {
allowedNames: ['self']
}],
'vue/valid-v-slot': ['error', {
allowModifiers: true
}],
'vue/block-lang': ['error', {
script: {
lang: ['ts', 'js']
}
}],
}]
}
},
];

View File

@@ -74,7 +74,7 @@ export interface LocalizedDateRange extends TypeAndDisplayName {
readonly isBillingCycle?: boolean;
}
export interface LocalizedRecentMonthDateRange {
export interface LocalizedRecentMonthDateRange extends TimeRangeAndDateType {
readonly dateType: number;
readonly minTime: number;
readonly maxTime: number;
@@ -420,60 +420,48 @@ export enum DateRangeScene {
TrendAnalysis = 1
}
export type DateRangeTypeName = 'All' |
'Today' | 'Yesterday' |
'LastSevenDays' | 'LastThirtyDays' |
'ThisWeek' | 'LastWeek' |
'ThisMonth' | 'LastMonth' |
'ThisYear' | 'LastYear' |
'PreviousBillingCycle' | 'CurrentBillingCycle' |
'RecentTwelveMonths' | 'RecentTwentyFourMonths' | 'RecentThirtySixMonths' |
'RecentTwoYears' | 'RecentThreeYears' | 'RecentFiveYears' |
'Custom';
export class DateRange implements TypeAndName {
private static readonly allInstances: DateRange[] = [];
private static readonly allInstancesByType: Record<number, DateRange> = {};
private static readonly allInstancesByTypeName: Record<string, DateRange> = {};
// All date range
public static readonly All = new DateRange(0, 'All', 'All', false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis);
public static readonly All = new DateRange(0, 'All', false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis);
// Date ranges for normal scene only
public static readonly Today = new DateRange(1, 'Today', 'Today', false, DateRangeScene.Normal);
public static readonly Yesterday = new DateRange(2, 'Yesterday', 'Yesterday', false, DateRangeScene.Normal);
public static readonly LastSevenDays = new DateRange(3, 'LastSevenDays', 'Recent 7 days', false, DateRangeScene.Normal);
public static readonly LastThirtyDays = new DateRange(4, 'LastThirtyDays', 'Recent 30 days', false, DateRangeScene.Normal);
public static readonly ThisWeek = new DateRange(5, 'ThisWeek', 'This week', false, DateRangeScene.Normal);
public static readonly LastWeek = new DateRange(6, 'LastWeek', 'Last week', false, DateRangeScene.Normal);
public static readonly ThisMonth = new DateRange(7, 'ThisMonth', 'This month', false, DateRangeScene.Normal);
public static readonly LastMonth = new DateRange(8, 'LastMonth', 'Last month', false, DateRangeScene.Normal);
public static readonly Today = new DateRange(1, 'Today', false, DateRangeScene.Normal);
public static readonly Yesterday = new DateRange(2, 'Yesterday', false, DateRangeScene.Normal);
public static readonly LastSevenDays = new DateRange(3, 'Recent 7 days', false, DateRangeScene.Normal);
public static readonly LastThirtyDays = new DateRange(4, 'Recent 30 days', false, DateRangeScene.Normal);
public static readonly ThisWeek = new DateRange(5, 'This week', false, DateRangeScene.Normal);
public static readonly LastWeek = new DateRange(6, 'Last week', false, DateRangeScene.Normal);
public static readonly ThisMonth = new DateRange(7, 'This month', false, DateRangeScene.Normal);
public static readonly LastMonth = new DateRange(8, 'Last month', false, DateRangeScene.Normal);
// Date ranges for normal and trend analysis scene
public static readonly ThisYear = new DateRange(9, 'ThisYear', 'This year', false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis);
public static readonly LastYear = new DateRange(10, 'LastYear', 'Last year', false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis);
public static readonly ThisYear = new DateRange(9, 'This year', false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis);
public static readonly LastYear = new DateRange(10, 'Last year', false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis);
// Billing cycle date ranges for normal scene only
public static readonly PreviousBillingCycle = new DateRange(51, 'PreviousBillingCycle', 'Previous Billing Cycle', true, DateRangeScene.Normal);
public static readonly CurrentBillingCycle = new DateRange(52, 'CurrentBillingCycle', 'Current Billing Cycle', true, DateRangeScene.Normal);
public static readonly PreviousBillingCycle = new DateRange(51, 'Previous Billing Cycle', true, DateRangeScene.Normal);
public static readonly CurrentBillingCycle = new DateRange(52, 'Current Billing Cycle', true, DateRangeScene.Normal);
// Date ranges for trend analysis scene only
public static readonly RecentTwelveMonths = new DateRange(101, 'RecentTwelveMonths', 'Recent 12 months', false, DateRangeScene.TrendAnalysis);
public static readonly RecentTwentyFourMonths = new DateRange(102, 'RecentTwentyFourMonths', 'Recent 24 months', false, DateRangeScene.TrendAnalysis);
public static readonly RecentThirtySixMonths = new DateRange(103, 'RecentThirtySixMonths', 'Recent 36 months', false, DateRangeScene.TrendAnalysis);
public static readonly RecentTwoYears = new DateRange(104, 'RecentTwoYears', 'Recent 2 years', false, DateRangeScene.TrendAnalysis);
public static readonly RecentThreeYears = new DateRange(105, 'RecentThreeYears', 'Recent 3 years', false, DateRangeScene.TrendAnalysis);
public static readonly RecentFiveYears = new DateRange(106, 'RecentFiveYears', 'Recent 5 years', false, DateRangeScene.TrendAnalysis);
public static readonly RecentTwelveMonths = new DateRange(101, 'Recent 12 months', false, DateRangeScene.TrendAnalysis);
public static readonly RecentTwentyFourMonths = new DateRange(102, 'Recent 24 months', false, DateRangeScene.TrendAnalysis);
public static readonly RecentThirtySixMonths = new DateRange(103, 'Recent 36 months', false, DateRangeScene.TrendAnalysis);
public static readonly RecentTwoYears = new DateRange(104, 'Recent 2 years', false, DateRangeScene.TrendAnalysis);
public static readonly RecentThreeYears = new DateRange(105, 'Recent 3 years', false, DateRangeScene.TrendAnalysis);
public static readonly RecentFiveYears = new DateRange(106, 'Recent 5 years', false, DateRangeScene.TrendAnalysis);
// Custom date range
public static readonly Custom = new DateRange(255, 'Custom', 'Custom Date', false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis);
public static readonly Custom = new DateRange(255, 'Custom Date', false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis);
public readonly type: number;
public readonly name: string;
public readonly isBillingCycle: boolean;
private readonly availableScenes: Record<number, boolean>;
private constructor(type: number, typeName: DateRangeTypeName, name: string, isBillingCycle: boolean, ...availableScenes: DateRangeScene[]) {
private constructor(type: number, name: string, isBillingCycle: boolean, ...availableScenes: DateRangeScene[]) {
this.type = type;
this.name = name;
this.isBillingCycle = isBillingCycle;
@@ -487,7 +475,6 @@ export class DateRange implements TypeAndName {
DateRange.allInstances.push(this);
DateRange.allInstancesByType[type] = this;
DateRange.allInstancesByTypeName[typeName] = this;
}
public isAvailableForScene(scene: DateRangeScene): boolean {
@@ -498,10 +485,6 @@ export class DateRange implements TypeAndName {
return DateRange.allInstances;
}
public static all(): Record<DateRangeTypeName, DateRange> {
return DateRange.allInstancesByTypeName;
}
public static valueOf(type: number): DateRange | undefined {
return DateRange.allInstancesByType[type];
}

View File

@@ -71,8 +71,6 @@ import draggable from 'vuedraggable';
import router from '@/router/desktop.ts';
import { getI18nOptions } from '@/locales/helpers.ts';
// @ts-expect-error the above file is migrating to ts
import { i18nFunctions } from '@/locales/helper.js';
import PinCodeInput from '@/components/common/PinCodeInput.vue';
import MapView from '@/components/common/MapView.vue';
@@ -465,6 +463,4 @@ app.component('DateRangeSelectionDialog', DateRangeSelectionDialog);
app.component('MonthRangeSelectionDialog', MonthRangeSelectionDialog);
app.component('SwitchToMobileDialog', SwitchToMobileDialog);
app.config.globalProperties['$locale'] = i18nFunctions(i18n.global);
app.mount('#app');

View File

@@ -545,7 +545,7 @@ export function getShiftedDateRangeAndDateType(minTime: number, maxTime: number,
};
}
export function getShiftedDateRangeAndDateTypeForBillingCycle(minTime: number, maxTime: number, scale: number, firstDayOfWeek: number, scene: number, statementDate: number): TimeRangeAndDateType | null {
export function getShiftedDateRangeAndDateTypeForBillingCycle(minTime: number, maxTime: number, scale: number, firstDayOfWeek: number, scene: number, statementDate: number | undefined | null): TimeRangeAndDateType | null {
if (!statementDate || !DateRange.PreviousBillingCycle.isAvailableForScene(scene) || !DateRange.CurrentBillingCycle.isAvailableForScene(scene)) {
return null;
}
@@ -588,7 +588,7 @@ export function getDateTypeByDateRange(minTime: number, maxTime: number, firstDa
return newDateType;
}
export function getDateTypeByBillingCycleDateRange(minTime: number, maxTime: number, firstDayOfWeek: number, scene: DateRangeScene, statementDate: number): number | null {
export function getDateTypeByBillingCycleDateRange(minTime: number, maxTime: number, firstDayOfWeek: number, scene: DateRangeScene, statementDate: number | undefined | null): number | null {
if (!statementDate || !DateRange.PreviousBillingCycle.isAvailableForScene(scene) || !DateRange.CurrentBillingCycle.isAvailableForScene(scene)) {
return null;
}
@@ -605,7 +605,7 @@ export function getDateTypeByBillingCycleDateRange(minTime: number, maxTime: num
return null;
}
export function getDateRangeByDateType(dateType: number, firstDayOfWeek: number): TimeRangeAndDateType | null {
export function getDateRangeByDateType(dateType: number | undefined, firstDayOfWeek: number): TimeRangeAndDateType | null {
let maxTime = 0;
let minTime = 0;
@@ -671,7 +671,7 @@ export function getDateRangeByDateType(dateType: number, firstDayOfWeek: number)
};
}
export function getDateRangeByBillingCycleDateType(dateType: number, firstDayOfWeek: number, statementDate: number): TimeRangeAndDateType | null {
export function getDateRangeByBillingCycleDateType(dateType: number, firstDayOfWeek: number, statementDate: number | undefined | null): TimeRangeAndDateType | null {
let maxTime = 0;
let minTime = 0;

View File

@@ -3,7 +3,7 @@ import { TransactionType } from '@/core/transaction.ts';
import { Account } from '@/models/account.ts';
import { TransactionCategory } from '@/models/transaction_category.ts';
import { TransactionTag } from '@/models/transaction_tag.ts';
import {Transaction, TransactionPicture} from '@/models/transaction.ts';
import { Transaction, TransactionPicture } from '@/models/transaction.ts';
import {
isNumber
@@ -30,14 +30,6 @@ export interface SetTransactionOptions {
comment?: string;
}
function getDisplayAmount(amount: number, currency: string, hideAmount: boolean, formatAmountWithCurrencyFunc: (value: number | string, currencyCode?: string) => string): string {
if (hideAmount) {
return formatAmountWithCurrencyFunc('***', currency);
}
return formatAmountWithCurrencyFunc(amount, currency);
}
export function setTransactionModelByTransaction(transaction: Transaction, transaction2: Transaction | null | undefined, allCategories: Record<number, TransactionCategory[]>, allCategoriesMap: Record<string, TransactionCategory>, allVisibleAccounts: Account[], allAccountsMap: Record<string, Account>, allTagsMap: Record<string, TransactionTag>, defaultAccountId: string, options: SetTransactionOptions, setContextData: boolean, convertContextTime: boolean): void {
if (!options.type && options.categoryId && options.categoryId !== '0' && allCategoriesMap[options.categoryId]) {
const category = allCategoriesMap[options.categoryId];
@@ -190,33 +182,3 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
}
}
}
export function getTransactionDisplayAmount(transaction: Transaction, allFilterAccountIdsCount: number, allFilterAccountIds: Record<string, boolean>, formatAmountWithCurrencyFunc: (value: number | string, currencyCode?: string) => string): string {
if (allFilterAccountIdsCount < 1) {
if (transaction.sourceAccount) {
return getDisplayAmount(transaction.sourceAmount, transaction.sourceAccount.currency, transaction.hideAmount, formatAmountWithCurrencyFunc);
}
} else if (allFilterAccountIdsCount === 1) {
if (transaction.sourceAccount && (allFilterAccountIds[transaction.sourceAccount.id] || allFilterAccountIds[transaction.sourceAccount.parentId])) {
return getDisplayAmount(transaction.sourceAmount, transaction.sourceAccount.currency, transaction.hideAmount , formatAmountWithCurrencyFunc);
} else if (transaction.destinationAccount && (allFilterAccountIds[transaction.destinationAccount.id] || allFilterAccountIds[transaction.destinationAccount.parentId])) {
return getDisplayAmount(transaction.destinationAmount, transaction.destinationAccount.currency, transaction.hideAmount , formatAmountWithCurrencyFunc);
}
} else { // allFilterAccountIdsCount > 1
if (transaction.sourceAccount && transaction.destinationAccount) {
if ((allFilterAccountIds[transaction.sourceAccount.id] || allFilterAccountIds[transaction.sourceAccount.parentId])
&& !allFilterAccountIds[transaction.destinationAccount.id] && !allFilterAccountIds[transaction.destinationAccount.parentId]) {
return getDisplayAmount(transaction.sourceAmount, transaction.sourceAccount.currency, transaction.hideAmount , formatAmountWithCurrencyFunc);
} else if ((allFilterAccountIds[transaction.destinationAccount.id] || allFilterAccountIds[transaction.destinationAccount.parentId])
&& !allFilterAccountIds[transaction.sourceAccount.id] && !allFilterAccountIds[transaction.sourceAccount.parentId]) {
return getDisplayAmount(transaction.destinationAmount, transaction.destinationAccount.currency, transaction.hideAmount , formatAmountWithCurrencyFunc);
}
}
}
if (transaction.sourceAccount) {
return getDisplayAmount(transaction.sourceAmount, transaction.sourceAccount.currency, transaction.hideAmount, formatAmountWithCurrencyFunc);
}
return '';
}

View File

@@ -45,7 +45,7 @@ export function getCssValue(element: HTMLElement | null, name: string): string {
return computedStyle.getPropertyValue(name);
}
export function scrollToSelectedItem(parentEl: HTMLElement | null, containerSelector: string | null, selectedItemSelector: string): void {
export function scrollToSelectedItem(parentEl: HTMLElement | null | undefined, containerSelector: string | null, selectedItemSelector: string): void {
if (!parentEl) {
return;
}

View File

@@ -1,13 +1,12 @@
import { type Ref, watch } from 'vue';
import { useI18n as useVueI18n } from 'vue-i18n';
import { f7, f7ready } from 'framework7-vue';
import type { Dialog, Picker, Router } from 'framework7/types';
import { useI18n } from '@/locales/helpers.ts';
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
import { getNumberValue } from '../common.ts';
import { isEnableAnimate } from '../settings.ts';
// @ts-expect-error the above file is migrating to ts
import { translateError } from '@/locales/helper.js';
export interface Framework7Dom {
length: number;
@@ -19,34 +18,6 @@ export interface Framework7Dom {
css(property: string): string | number;
}
type TranslateFunction = (message: string) => string;
export function showAlert(message: string, confirmCallback: ((dialog: Dialog.Dialog, e: Event) => void) | undefined, translateFn: TranslateFunction): void {
f7ready((f7) => {
f7.dialog.create({
title: translateFn('global.app.title'),
text: translateError(message, translateFn),
animate: isEnableAnimate(),
buttons: [
{
text: translateFn('OK'),
onClick: confirmCallback
}
]
}).open();
});
}
export function showToast(message: string, timeout: number | undefined, translateFn: TranslateFunction): void {
f7ready((f7) => {
f7.toast.create({
text: translateError(message, translateFn),
position: 'center',
closeTimeout: timeout || 1500
}).open();
});
}
export function showLoading(delayConditionFunc?: () => boolean, delayMills?: number): void {
if (!delayConditionFunc) {
f7ready((f7) => {
@@ -82,26 +53,6 @@ export function createInlinePicker(containerEl: string, inputEl: string, cols: P
});
}
export function routeBackOnError(f7router: Router.Router, errorPropertyName: string): void {
// @ts-expect-error vue SFC would be migrated to composition API and this function would be removed in the future
const self = this;
const router = f7router;
const unwatch = self.$watch(errorPropertyName, () => {
if (self[errorPropertyName]) {
setTimeout(() => {
if (unwatch) {
unwatch();
}
router.back();
}, 200);
}
}, {
immediate: true
});
}
export function isModalShowing(): number {
return f7.$('.modal-in').length;
}
@@ -190,7 +141,7 @@ export function scrollToSelectedItem(parentEl: Framework7Dom, containerSelector:
}
export function useI18nUIComponents() {
const { t } = useVueI18n();
const { tt, te } = useI18n();
function routeBackOnError<T>(f7router: Router.Router, errorRef: Ref<T>): void {
const unwatch = watch(errorRef, (newValue) => {
@@ -208,19 +159,15 @@ export function useI18nUIComponents() {
});
}
function showConfirm(message: string, confirmCallback?: (dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: ((dialog: Dialog.Dialog, e: Event) => void) | undefined): void {
function showAlert(message: string, confirmCallback?: (dialog: Dialog.Dialog, e: Event) => void): void {
f7ready((f7) => {
f7.dialog.create({
title: t('global.app.title'),
text: t(message),
title: tt('global.app.title'),
text: te(message),
animate: isEnableAnimate(),
buttons: [
{
text: t('Cancel'),
onClick: cancelCallback
},
{
text: t('OK'),
text: tt('OK'),
onClick: confirmCallback
}
]
@@ -228,10 +175,40 @@ export function useI18nUIComponents() {
});
}
function showConfirm(message: string, confirmCallback?: (dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: (dialog: Dialog.Dialog, e: Event) => void): void {
f7ready((f7) => {
f7.dialog.create({
title: tt('global.app.title'),
text: tt(message),
animate: isEnableAnimate(),
buttons: [
{
text: tt('Cancel'),
onClick: cancelCallback
},
{
text: tt('OK'),
onClick: confirmCallback
}
]
}).open();
});
}
function showToast(message: string, timeout?: number): void {
f7ready((f7) => {
f7.toast.create({
text: te(message),
position: 'center',
closeTimeout: timeout || 1500
}).open();
});
}
return {
showAlert: (message: string, confirmCallback?: (dialog: Dialog.Dialog, e: Event) => void) => showAlert(message, confirmCallback, t),
showAlert: showAlert,
showConfirm: showConfirm,
showToast: (message: string, timeout?: number): void => showToast(message, timeout, t),
showToast: showToast,
routeBackOnError
}
}

View File

@@ -1,442 +0,0 @@
import { LongDateFormat, ShortDateFormat, LongTimeFormat, ShortTimeFormat, DateRange } from '@/core/datetime.ts';
import { DecimalSeparator, DigitGroupingSymbol, DigitGroupingType } from '@/core/numeral.ts';
import { CurrencyDisplayType } from '@/core/currency.ts'
import { TransactionTagFilterType } from '@/core/transaction.ts';
import { ALL_CURRENCIES } from '@/consts/currency.ts';
import { KnownErrorCode, SPECIFIED_API_NOT_FOUND_ERRORS, PARAMETERIZED_ERRORS } from '@/consts/api.ts';
import {
isString,
isNumber,
isBoolean
} from '@/lib/common.ts';
import {
parseDateFromUnixTime,
formatUnixTime,
getYear,
getDateTimeFormatType,
getRecentMonthDateRanges,
isDateRangeMatchFullYears,
isDateRangeMatchFullMonths
} from '@/lib/datetime.ts';
import {
formatAmount
} from '@/lib/numeral.ts';
import {
getCurrencyFraction,
appendCurrencySymbol
} from '@/lib/currency.ts';
function getLocalizedDisplayNameAndType(typeAndNames, translateFn) {
const ret = [];
for (let i = 0; i < typeAndNames.length; i++) {
const nameAndType = typeAndNames[i];
ret.push({
type: nameAndType.type,
displayName: translateFn(nameAndType.name)
});
}
return ret;
}
function getCurrencyName(currencyCode, translateFn) {
return translateFn(`currency.name.${currencyCode}`);
}
function getCurrencyUnitName(currencyCode, isPlural, translateFn) {
const currencyInfo = ALL_CURRENCIES[currencyCode];
if (currencyInfo && currencyInfo.unit) {
if (isPlural) {
return translateFn(`currency.unit.${currencyInfo.unit}.plural`);
} else {
return translateFn(`currency.unit.${currencyInfo.unit}.normal`);
}
}
return '';
}
function getWeekdayShortName(weekDayName, translateFn) {
return translateFn(`datetime.${weekDayName}.short`);
}
function getWeekdayLongName(weekDayName, translateFn) {
return translateFn(`datetime.${weekDayName}.long`);
}
function getI18nLongDateFormat(translateFn, formatTypeValue) {
const defaultLongDateFormatTypeName = translateFn('default.longDateFormat');
return getDateTimeFormat(translateFn, LongDateFormat.all(), LongDateFormat.values(), 'format.longDate', defaultLongDateFormatTypeName, LongDateFormat.Default, formatTypeValue);
}
function getI18nShortDateFormat(translateFn, formatTypeValue) {
const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat');
return getDateTimeFormat(translateFn, ShortDateFormat.all(), ShortDateFormat.values(), 'format.shortDate', defaultShortDateFormatTypeName, ShortDateFormat.Default, formatTypeValue);
}
function getI18nLongYearFormat(translateFn, formatTypeValue) {
const defaultLongDateFormatTypeName = translateFn('default.longDateFormat');
return getDateTimeFormat(translateFn, LongDateFormat.all(), LongDateFormat.values(), 'format.longYear', defaultLongDateFormatTypeName, LongDateFormat.Default, formatTypeValue);
}
function getI18nShortYearFormat(translateFn, formatTypeValue) {
const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat');
return getDateTimeFormat(translateFn, ShortDateFormat.all(), ShortDateFormat.values(), 'format.shortYear', defaultShortDateFormatTypeName, ShortDateFormat.Default, formatTypeValue);
}
function getI18nLongYearMonthFormat(translateFn, formatTypeValue) {
const defaultLongDateFormatTypeName = translateFn('default.longDateFormat');
return getDateTimeFormat(translateFn, LongDateFormat.all(), LongDateFormat.values(), 'format.longYearMonth', defaultLongDateFormatTypeName, LongDateFormat.Default, formatTypeValue);
}
function getI18nShortYearMonthFormat(translateFn, formatTypeValue) {
const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat');
return getDateTimeFormat(translateFn, ShortDateFormat.all(), ShortDateFormat.values(), 'format.shortYearMonth', defaultShortDateFormatTypeName, ShortDateFormat.Default, formatTypeValue);
}
function getI18nShortMonthDayFormat(translateFn, formatTypeValue) {
const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat');
return getDateTimeFormat(translateFn, ShortDateFormat.all(), ShortDateFormat.values(), 'format.shortMonthDay', defaultShortDateFormatTypeName, ShortDateFormat.Default, formatTypeValue);
}
function getI18nLongTimeFormat(translateFn, formatTypeValue) {
const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat');
return getDateTimeFormat(translateFn, LongTimeFormat.all(), LongTimeFormat.values(), 'format.longTime', defaultLongTimeFormatTypeName, LongTimeFormat.Default, formatTypeValue);
}
function getI18nShortTimeFormat(translateFn, formatTypeValue) {
const defaultShortTimeFormatTypeName = translateFn('default.shortTimeFormat');
return getDateTimeFormat(translateFn, ShortTimeFormat.all(), ShortTimeFormat.values(), 'format.shortTime', defaultShortTimeFormatTypeName, ShortTimeFormat.Default, formatTypeValue);
}
function getDateTimeFormat(translateFn, allFormatMap, allFormatArray, localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue) {
const type = getDateTimeFormatType(allFormatMap, allFormatArray, formatTypeValue, localeDefaultFormatTypeName, systemDefaultFormatType);
return translateFn(`${localeFormatPathPrefix}.${type.key}`);
}
function getAllDateRanges(scene, includeCustom, includeBillingCycle, translateFn) {
const ret = [];
const allDateRanges = DateRange.values();
for (let i = 0; i < allDateRanges.length; i++) {
const dateRange = allDateRanges[i];
if (!dateRange.isAvailableForScene(scene)) {
continue;
}
if (dateRange.isBillingCycle) {
if (includeBillingCycle) {
ret.push({
type: dateRange.type,
displayName: translateFn(dateRange.name),
isBillingCycle: dateRange.isBillingCycle
});
}
continue;
}
if (includeCustom || dateRange.type !== DateRange.Custom.type) {
ret.push({
type: dateRange.type,
displayName: translateFn(dateRange.name)
});
}
}
return ret;
}
function getAllRecentMonthDateRanges(userStore, includeAll, includeCustom, translateFn) {
const allRecentMonthDateRanges = [];
const recentDateRanges = getRecentMonthDateRanges(12);
if (includeAll) {
allRecentMonthDateRanges.push({
dateType: DateRange.All.type,
minTime: 0,
maxTime: 0,
displayName: translateFn('All')
});
}
for (let i = 0; i < recentDateRanges.length; i++) {
const recentDateRange = recentDateRanges[i];
allRecentMonthDateRanges.push({
dateType: recentDateRange.dateType,
minTime: recentDateRange.minTime,
maxTime: recentDateRange.maxTime,
year: recentDateRange.year,
month: recentDateRange.month,
isPreset: true,
displayName: formatUnixTime(recentDateRange.minTime, getI18nLongYearMonthFormat(translateFn, userStore.currentUserLongDateFormat))
});
}
if (includeCustom) {
allRecentMonthDateRanges.push({
dateType: DateRange.Custom.type,
minTime: 0,
maxTime: 0,
displayName: translateFn('Custom Date')
});
}
return allRecentMonthDateRanges;
}
function getDateRangeDisplayName(userStore, dateType, startTime, endTime, translateFn) {
if (dateType === DateRange.All.type) {
return translateFn(DateRange.All.name);
}
const allDateRanges = DateRange.values();
for (let i = 0; i < allDateRanges.length; i++) {
const dateRange = allDateRanges[i];
if (dateRange && dateRange.type !== DateRange.Custom.type && dateRange.type === dateType && dateRange.name) {
return translateFn(dateRange.name);
}
}
if (isDateRangeMatchFullYears(startTime, endTime)) {
const displayStartTime = formatUnixTime(startTime, getI18nShortYearFormat(translateFn, userStore.currentUserShortDateFormat));
const displayEndTime = formatUnixTime(endTime, getI18nShortYearFormat(translateFn, userStore.currentUserShortDateFormat));
return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime;
}
if (isDateRangeMatchFullMonths(startTime, endTime)) {
const displayStartTime = formatUnixTime(startTime, getI18nShortYearMonthFormat(translateFn, userStore.currentUserShortDateFormat));
const displayEndTime = formatUnixTime(endTime, getI18nShortYearMonthFormat(translateFn, userStore.currentUserShortDateFormat));
return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime;
}
const startTimeYear = getYear(parseDateFromUnixTime(startTime));
const endTimeYear = getYear(parseDateFromUnixTime(endTime));
const displayStartTime = formatUnixTime(startTime, getI18nShortDateFormat(translateFn, userStore.currentUserShortDateFormat));
const displayEndTime = formatUnixTime(endTime, getI18nShortDateFormat(translateFn, userStore.currentUserShortDateFormat));
if (displayStartTime === displayEndTime) {
return displayStartTime;
} else if (startTimeYear === endTimeYear) {
const displayShortEndTime = formatUnixTime(endTime, getI18nShortMonthDayFormat(translateFn, userStore.currentUserShortDateFormat));
return `${displayStartTime} ~ ${displayShortEndTime}`;
}
return `${displayStartTime} ~ ${displayEndTime}`;
}
function getCurrentDecimalSeparator(translateFn, decimalSeparator) {
let decimalSeparatorType = DecimalSeparator.valueOf(decimalSeparator);
if (!decimalSeparatorType) {
const defaultDecimalSeparatorTypeName = translateFn('default.decimalSeparator');
decimalSeparatorType = DecimalSeparator.parse(defaultDecimalSeparatorTypeName);
if (!decimalSeparatorType) {
decimalSeparatorType = DecimalSeparator.Default;
}
}
return decimalSeparatorType.symbol;
}
function getCurrentDigitGroupingSymbol(translateFn, digitGroupingSymbol) {
let digitGroupingSymbolType = DigitGroupingSymbol.valueOf(digitGroupingSymbol);
if (!digitGroupingSymbolType) {
const defaultDigitGroupingSymbolTypeName = translateFn('default.digitGroupingSymbol');
digitGroupingSymbolType = DigitGroupingSymbol.parse(defaultDigitGroupingSymbolTypeName);
if (!digitGroupingSymbolType) {
digitGroupingSymbolType = DigitGroupingSymbol.Default;
}
}
return digitGroupingSymbolType.symbol;
}
function getCurrentDigitGroupingType(translateFn, digitGrouping) {
let digitGroupingType = DigitGroupingType.valueOf(digitGrouping);
if (!digitGroupingType) {
const defaultDigitGroupingTypeName = translateFn('default.digitGrouping');
digitGroupingType = DigitGroupingType.parse(defaultDigitGroupingTypeName);
if (!digitGroupingType) {
digitGroupingType = DigitGroupingType.Default;
}
}
return digitGroupingType.type;
}
function getNumberFormatOptions(translateFn, userStore, currencyCode) {
return {
decimalSeparator: getCurrentDecimalSeparator(translateFn, userStore.currentUserDecimalSeparator),
decimalNumberCount: getCurrencyFraction(currencyCode),
digitGroupingSymbol: getCurrentDigitGroupingSymbol(translateFn, userStore.currentUserDigitGroupingSymbol),
digitGrouping: getCurrentDigitGroupingType(translateFn, userStore.currentUserDigitGrouping),
};
}
function getCurrentCurrencyDisplayType(translateFn, userStore) {
let currencyDisplayType = CurrencyDisplayType.valueOf(userStore.currentUserCurrencyDisplayType);
if (!currencyDisplayType) {
const defaultCurrencyDisplayTypeName = translateFn('default.currencyDisplayType');
currencyDisplayType = CurrencyDisplayType.parse(defaultCurrencyDisplayTypeName);
}
if (!currencyDisplayType) {
currencyDisplayType = CurrencyDisplayType.Default;
}
return currencyDisplayType;
}
function getFormattedAmountWithCurrency(value, currencyCode, translateFn, userStore, settingsStore, notConvertValue, currencyDisplayType) {
if (!isNumber(value) && !isString(value)) {
return value;
}
if (isNumber(value)) {
value = value.toString();
}
const isPlural = value !== '100' && value !== '-100';
if (!notConvertValue) {
const numberFormatOptions = getNumberFormatOptions(translateFn, userStore, currencyCode);
const hasIncompleteFlag = isString(value) && value.charAt(value.length - 1) === '+';
if (hasIncompleteFlag) {
value = value.substring(0, value.length - 1);
}
value = formatAmount(value, numberFormatOptions);
if (hasIncompleteFlag) {
value = value + '+';
}
}
if (!isBoolean(currencyCode) && !currencyCode) {
currencyCode = userStore.currentUserDefaultCurrency;
} else if (isBoolean(currencyCode) && !currencyCode) {
currencyCode = '';
}
if (!currencyCode) {
return value;
}
if (!currencyDisplayType) {
currencyDisplayType = getCurrentCurrencyDisplayType(translateFn, userStore);
}
const currencyUnit = getCurrencyUnitName(currencyCode, isPlural, translateFn);
const currencyName = getCurrencyName(currencyCode, translateFn);
return appendCurrencySymbol(value, currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural);
}
function getAllTransactionTagFilterTypes(translateFn) {
return getLocalizedDisplayNameAndType(TransactionTagFilterType.values(), translateFn);
}
function getLocalizedError(error) {
if (error.errorCode === KnownErrorCode.ApiNotFound && SPECIFIED_API_NOT_FOUND_ERRORS[error.path]) {
return {
message: `${SPECIFIED_API_NOT_FOUND_ERRORS[error.path].message}`
};
}
if (error.errorCode !== KnownErrorCode.ValidatorError) {
return {
message: `error.${error.errorMessage}`
};
}
for (let i = 0; i < PARAMETERIZED_ERRORS.length; i++) {
const errorInfo = PARAMETERIZED_ERRORS[i];
const matches = error.errorMessage.match(errorInfo.regex);
if (matches && matches.length === errorInfo.parameters.length + 1) {
return {
message: `parameterizedError.${errorInfo.localeKey}`,
parameters: errorInfo.parameters.map((param, index) => {
return {
key: param.field,
localized: param.localized,
value: matches[index + 1]
}
})
};
}
}
return {
message: `error.${error.errorMessage}`
};
}
function getLocalizedErrorParameters(parameters, i18nFunc) {
let localizedParameters = {};
if (parameters) {
for (let i = 0; i < parameters.length; i++) {
const parameter = parameters[i];
if (parameter.localized) {
localizedParameters[parameter.key] = i18nFunc(`parameter.${parameter.value}`);
} else {
localizedParameters[parameter.key] = parameter.value;
}
}
}
return localizedParameters;
}
export function translateError(message, translateFn) {
let parameters = {};
if (message && message.error) {
const localizedError = getLocalizedError(message.error);
message = localizedError.message;
parameters = getLocalizedErrorParameters(localizedError.parameters, translateFn);
}
return translateFn(message, parameters);
}
export function i18nFunctions(i18nGlobal) {
return {
getWeekdayShortName: (weekDay) => getWeekdayShortName(weekDay, i18nGlobal.t),
getWeekdayLongName: (weekDay) => getWeekdayLongName(weekDay, i18nGlobal.t),
formatUnixTimeToLongDateTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongDateFormat(i18nGlobal.t, userStore.currentUserLongDateFormat) + ' ' + getI18nLongTimeFormat(i18nGlobal.t, userStore.currentUserLongTimeFormat), utcOffset, currentUtcOffset),
formatUnixTimeToLongDate: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongDateFormat(i18nGlobal.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset),
formatUnixTimeToLongYear: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongYearFormat(i18nGlobal.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset),
formatUnixTimeToLongYearMonth: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongYearMonthFormat(i18nGlobal.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset),
formatUnixTimeToShortTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortTimeFormat(i18nGlobal.t, userStore.currentUserShortTimeFormat), utcOffset, currentUtcOffset),
getAllDateRanges: (scene, includeCustom, includeBillingCycle) => getAllDateRanges(scene, includeCustom, includeBillingCycle, i18nGlobal.t),
getAllRecentMonthDateRanges: (userStore, includeAll, includeCustom) => getAllRecentMonthDateRanges(userStore, includeAll, includeCustom, i18nGlobal.t),
getDateRangeDisplayName: (userStore, dateType, startTime, endTime) => getDateRangeDisplayName(userStore, dateType, startTime, endTime, i18nGlobal.t),
formatAmountWithCurrency: (settingsStore, userStore, value, currencyCode) => getFormattedAmountWithCurrency(value, currencyCode, i18nGlobal.t, userStore, settingsStore),
getAllTransactionTagFilterTypes: () => getAllTransactionTagFilterTypes(i18nGlobal.t)
};
}

View File

@@ -38,7 +38,6 @@ import Framework7Swiper from 'framework7/components/swiper';
import Framework7PhotoBrowser from 'framework7/components/photo-browser';
// @ts-expect-error there is a function called "registerComponents" in the framework7-vue package, but it is not declared in the type definition file
import Framework7Vue, { registerComponents } from 'framework7-vue/bundle';
import type { Dialog } from 'framework7/types';
import 'framework7/css';
import 'framework7/components/dialog/css';
@@ -82,15 +81,6 @@ import VueDatePicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css';
import { getI18nOptions } from '@/locales/helpers.ts';
// @ts-expect-error the above file is migrating to ts
import { i18nFunctions } from '@/locales/helper.js';
import {
showAlert,
showToast,
showLoading,
hideLoading,
routeBackOnError
} from '@/lib/ui/mobile.ts';
import PinCodeInput from '@/components/common/PinCodeInput.vue';
import MapView from '@/components/common/MapView.vue';
@@ -200,12 +190,4 @@ app.component('ScheduleFrequencySheet', ScheduleFrequencySheet);
app.directive('TextareaAutoSize', TextareaAutoSize);
app.config.globalProperties['$locale'] = i18nFunctions(i18n.global);
app.config.globalProperties['$alert'] = (message: string, confirmCallback: ((dialog: Dialog.Dialog, e: Event) => void) | undefined) => showAlert(message, confirmCallback, i18n.global.t);
app.config.globalProperties['$toast'] = (message: string, timeout: number | undefined) => showToast(message, timeout, i18n.global.t);
app.config.globalProperties['$showLoading'] = showLoading;
app.config.globalProperties['$hideLoading'] = hideLoading;
app.config.globalProperties['$routeBackOnError'] = routeBackOnError;
app.mount('#app');

View File

@@ -0,0 +1,312 @@
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';
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
import { type TransactionListFilter, type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
import { type LocalizedDateRange, DateRange, DateRangeScene } from '@/core/datetime.ts';
import { AccountType } from '@/core/account.ts';
import { TransactionType } from '@/core/transaction.ts';
import type { Account } from '@/models/account.ts';
import type { TransactionCategory } from '@/models/transaction_category.ts';
import type { TransactionTag } from '@/models/transaction_tag.ts';
import type { Transaction } from '@/models/transaction.ts';
import {
getUtcOffsetByUtcOffsetMinutes,
getTimezoneOffset,
getTimezoneOffsetMinutes,
parseDateFromUnixTime,
getUnixTime,
getYearMonthFirstUnixTime
} from '@/lib/datetime.ts';
import {
getUnifiedSelectedAccountsCurrencyOrDefaultCurrency
} from '@/lib/account.ts';
import {
categoryTypeToTransactionType
} from '@/lib/category.ts';
export function useTransactionListPageBase() {
const {
tt,
getAllDateRanges,
formatUnixTimeToLongDateTime,
formatUnixTimeToLongDate,
formatUnixTimeToLongYearMonth,
formatUnixTimeToShortTime,
formatDateRange,
formatAmountWithCurrency
} = useI18n();
const settingsStore = useSettingsStore();
const userStore = useUserStore();
const accountsStore = useAccountsStore();
const transactionCategoriesStore = useTransactionCategoriesStore();
const transactionTagsStore = useTransactionTagsStore();
const transactionsStore = useTransactionsStore();
const loading = ref<boolean>(true);
const customMinDatetime = ref<number>(0);
const customMaxDatetime = ref<number>(0);
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
const firstDayOfWeek = computed<number>(() => userStore.currentUserFirstDayOfWeek);
const defaultCurrency = computed<string>(() => getUnifiedSelectedAccountsCurrencyOrDefaultCurrency(allAccounts.value, queryAllFilterAccountIds.value, userStore.currentUserDefaultCurrency));
const showTotalAmountInTransactionListPage = computed<boolean>(() => settingsStore.appSettings.showTotalAmountInTransactionListPage);
const showTagInTransactionListPage = computed<boolean>(() => settingsStore.appSettings.showTagInTransactionListPage);
const allDateRanges = computed<LocalizedDateRange[]>(() => getAllDateRanges(DateRangeScene.Normal, true, !!accountsStore.getAccountStatementDate(query.value.accountIds)));
const allAccounts = computed<Record<string, Account>>(() => accountsStore.allAccountsMap);
const allAvailableAccountsCount = computed<number>(() => accountsStore.allAvailableAccountsCount);
const allPrimaryCategories = computed<Record<number, TransactionCategory[]>>(() => {
const primaryCategories: Record<number, TransactionCategory[]> = {};
for (const categoryType in transactionCategoriesStore.allTransactionCategories) {
if (!Object.prototype.hasOwnProperty.call(transactionCategoriesStore.allTransactionCategories, categoryType)) {
continue;
}
if (query.value.type && categoryTypeToTransactionType(parseInt(categoryType)) !== query.value.type) {
continue;
}
primaryCategories[categoryType] = transactionCategoriesStore.allTransactionCategories[categoryType];
}
return primaryCategories;
});
const allCategories = computed<Record<string, TransactionCategory>>(() => transactionCategoriesStore.allTransactionCategoriesMap);
const allAvailableCategoriesCount = computed<number>(() => {
let totalCount = 0;
for (const categoryType in transactionCategoriesStore.allTransactionCategories) {
if (!Object.prototype.hasOwnProperty.call(transactionCategoriesStore.allTransactionCategories, categoryType)) {
continue;
}
if (query.value.type && categoryTypeToTransactionType(parseInt(categoryType)) !== query.value.type) {
continue;
}
if (transactionCategoriesStore.allTransactionCategories[categoryType]) {
totalCount += transactionCategoriesStore.allTransactionCategories[categoryType].length;
}
}
return totalCount;
});
const allTransactionTags = computed<Record<string, TransactionTag>>(() => transactionTagsStore.allTransactionTagsMap);
const allAvailableTagsCount = computed<number>(() => transactionTagsStore.allAvailableTagsCount);
const query = computed<TransactionListFilter>(() => transactionsStore.transactionsFilter);
const queryDateRangeName = computed<string>(() => {
if (query.value.dateType === DateRange.All.type) {
return tt('Date');
}
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 queryAllFilterCategoryIds = computed<Record<string, boolean>>(() => transactionsStore.allFilterCategoryIds);
const queryAllFilterAccountIds = computed<Record<string, boolean>>(() => transactionsStore.allFilterAccountIds);
const queryAllFilterTagIds = computed<Record<string, boolean>>(() => transactionsStore.allFilterTagIds);
const queryAllFilterCategoryIdsCount = computed<number>(() => transactionsStore.allFilterCategoryIdsCount);
const queryAllFilterAccountIdsCount = computed<number>(() => transactionsStore.allFilterAccountIdsCount);
const queryAllFilterTagIdsCount = computed<number>(() => transactionsStore.allFilterTagIdsCount);
const queryAccountName = computed<string>(() => {
if (queryAllFilterAccountIdsCount.value > 1) {
return tt('Multiple Accounts');
}
return allAccounts.value[query.value.accountIds]?.name || tt('Account');
});
const queryCategoryName = computed<string>(() => {
if (queryAllFilterCategoryIdsCount.value > 1) {
return tt('Multiple Categories');
}
return allCategories.value[query.value.categoryIds]?.name || tt('Category');
});
const queryTagName = computed<string>(() => {
if (query.value.tagIds === 'none') {
return tt('Without Tags');
}
if (queryAllFilterTagIdsCount.value > 1) {
return tt('Multiple Tags');
}
return allTransactionTags.value[query.value.tagIds]?.name || tt('Tags');
});
const queryAmount = computed<string>(() => {
if (!query.value.amountFilter) {
return '';
}
const amountFilterItems = query.value.amountFilter.split(':');
if (amountFilterItems.length < 2) {
return '';
}
const displayAmount: string[] = [];
for (let i = 1; i < amountFilterItems.length; i++) {
displayAmount.push(formatAmountWithCurrency(amountFilterItems[i], false));
}
return displayAmount.join(' ~ ');
});
const canAddTransaction = computed<boolean>(() => {
if (query.value.accountIds && queryAllFilterAccountIdsCount.value === 1) {
const account = allAccounts.value[query.value.accountIds];
if (account && account.type === AccountType.MultiSubAccounts.type) {
return false;
}
}
return true;
});
function formatAmount(amount: number, hideAmount: boolean, currencyCode: string): string {
if (hideAmount) {
return formatAmountWithCurrency('***', currencyCode);
}
return formatAmountWithCurrency(amount, currencyCode);
}
function getDisplayTime(transaction: Transaction): string {
return formatUnixTimeToShortTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
}
function getDisplayLongDate(transaction: Transaction): string {
const transactionTime = getUnixTime(parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value));
return formatUnixTimeToLongDate(transactionTime);
}
function getDisplayLongYearMonth(transactionMonthList: TransactionMonthList): string {
return formatUnixTimeToLongYearMonth(getYearMonthFirstUnixTime(transactionMonthList.yearMonth));
}
function getDisplayTimezone(transaction: Transaction): string {
return `UTC${getUtcOffsetByUtcOffsetMinutes(transaction.utcOffset)}`;
}
function getDisplayTimeInDefaultTimezone(transaction: Transaction): string {
return `${formatUnixTimeToLongDateTime(transaction.time)} (UTC${getTimezoneOffset(settingsStore.appSettings.timeZone)})`;
}
function getDisplayAmount(transaction: Transaction): string {
if (queryAllFilterAccountIdsCount.value < 1) {
if (transaction.sourceAccount) {
return formatAmount(transaction.sourceAmount, transaction.hideAmount, transaction.sourceAccount.currency);
}
} else if (queryAllFilterAccountIdsCount.value === 1) {
if (transaction.sourceAccount && (queryAllFilterAccountIds.value[transaction.sourceAccount.id] || queryAllFilterAccountIds.value[transaction.sourceAccount.parentId])) {
return formatAmount(transaction.sourceAmount, transaction.hideAmount, transaction.sourceAccount.currency);
} else if (transaction.destinationAccount && (queryAllFilterAccountIds.value[transaction.destinationAccount.id] || queryAllFilterAccountIds.value[transaction.destinationAccount.parentId])) {
return formatAmount(transaction.destinationAmount, transaction.hideAmount, transaction.destinationAccount.currency);
}
} else { // queryAllFilterAccountIdsCount.value > 1
if (transaction.sourceAccount && transaction.destinationAccount) {
if ((queryAllFilterAccountIds.value[transaction.sourceAccount.id] || queryAllFilterAccountIds.value[transaction.sourceAccount.parentId])
&& !queryAllFilterAccountIds.value[transaction.destinationAccount.id] && !queryAllFilterAccountIds.value[transaction.destinationAccount.parentId]) {
return formatAmount(transaction.sourceAmount, transaction.hideAmount, transaction.sourceAccount.currency);
} else if ((queryAllFilterAccountIds.value[transaction.destinationAccount.id] || queryAllFilterAccountIds.value[transaction.destinationAccount.parentId])
&& !queryAllFilterAccountIds.value[transaction.sourceAccount.id] && !queryAllFilterAccountIds.value[transaction.sourceAccount.parentId]) {
return formatAmount(transaction.destinationAmount, transaction.hideAmount, transaction.destinationAccount.currency);
}
}
}
if (transaction.sourceAccount) {
return formatAmount(transaction.sourceAmount, transaction.hideAmount, transaction.sourceAccount.currency);
}
return '';
}
function getDisplayMonthTotalAmount(amount: number, currency: string, symbol: string, incomplete: boolean): string {
const displayAmount = formatAmountWithCurrency(amount, currency);
return symbol + displayAmount + (incomplete ? '+' : '');
}
function getTransactionTypeName(type: number | null, defaultName: string): string {
switch (type){
case TransactionType.ModifyBalance:
return tt('Modify Balance');
case TransactionType.Income:
return tt('Income');
case TransactionType.Expense:
return tt('Expense');
case TransactionType.Transfer:
return tt('Transfer');
default:
return tt(defaultName);
}
}
return {
// states
loading,
customMinDatetime,
customMaxDatetime,
// computed states
currentTimezoneOffsetMinutes,
firstDayOfWeek,
defaultCurrency,
showTotalAmountInTransactionListPage,
showTagInTransactionListPage,
allDateRanges,
allAccounts,
allAvailableAccountsCount,
allCategories,
allPrimaryCategories,
allAvailableCategoriesCount,
allTransactionTags,
allAvailableTagsCount,
query,
queryDateRangeName,
queryMinTime,
queryMaxTime,
queryAllFilterCategoryIds,
queryAllFilterAccountIds,
queryAllFilterTagIds,
queryAllFilterCategoryIdsCount,
queryAllFilterAccountIdsCount,
queryAllFilterTagIdsCount,
queryAccountName,
queryCategoryName,
queryTagName,
queryAmount,
canAddTransaction,
// functions
getDisplayTime,
getDisplayLongDate,
getDisplayLongYearMonth,
getDisplayTimezone,
getDisplayTimeInDefaultTimezone,
getDisplayAmount,
getDisplayMonthTotalAmount,
getTransactionTypeName,
};
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff