mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-15 23:47:33 +08:00
use for-of statements to replace for and for-in
This commit is contained in:
@@ -175,8 +175,7 @@ export function useAppCloudSyncBase() {
|
||||
if (settings && settings.length > 0) {
|
||||
settingsStore.setApplicationSettingsFromCloudSettings(settings);
|
||||
|
||||
for (let i = 0; i < settings.length; i++) {
|
||||
const setting = settings[i];
|
||||
for (const setting of settings) {
|
||||
if (setting && setting.settingKey) {
|
||||
enabledApplicationCloudSettings.value[setting.settingKey] = true;
|
||||
}
|
||||
|
||||
@@ -150,8 +150,8 @@
|
||||
handle=".drag-handle"
|
||||
ghost-class="dragging-item"
|
||||
:disabled="activeAccountCategoryVisibleAccountCount <= 1"
|
||||
:list="allCategorizedAccountsMap[activeAccountCategory.type].accounts"
|
||||
v-if="activeAccountCategory && allCategorizedAccountsMap[activeAccountCategory.type] && allCategorizedAccountsMap[activeAccountCategory.type].accounts && allCategorizedAccountsMap[activeAccountCategory.type].accounts.length"
|
||||
:list="allCategorizedAccountsMap[activeAccountCategory.type]!.accounts"
|
||||
v-if="activeAccountCategory && allCategorizedAccountsMap[activeAccountCategory.type] && allCategorizedAccountsMap[activeAccountCategory.type]!.accounts && allCategorizedAccountsMap[activeAccountCategory.type]!.accounts.length"
|
||||
@change="onMove"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
@@ -376,20 +376,24 @@ const activeAccountCategory = computed<AccountCategory | undefined>(() => Accoun
|
||||
const activeAccountCategoryTotalBalance = computed<string>(() => accountCategoryTotalBalance(activeAccountCategory.value));
|
||||
|
||||
const activeAccountCategoryVisibleAccountCount = computed<number>(() => {
|
||||
if (!activeAccountCategory.value || !allCategorizedAccountsMap.value[activeAccountCategory.value.type] || !allCategorizedAccountsMap.value[activeAccountCategory.value.type].accounts) {
|
||||
if (!activeAccountCategory.value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const accounts = allCategorizedAccountsMap.value[activeAccountCategory.value.type].accounts;
|
||||
const categorizedAccounts = allCategorizedAccountsMap.value[activeAccountCategory.value.type];
|
||||
|
||||
if (!categorizedAccounts || !categorizedAccounts.accounts || !categorizedAccounts.accounts.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (showHidden.value) {
|
||||
return accounts.length;
|
||||
return categorizedAccounts.accounts.length;
|
||||
}
|
||||
|
||||
let visibleCount = 0;
|
||||
|
||||
for (let i = 0; i < accounts.length; i++) {
|
||||
if (!accounts[i].hidden) {
|
||||
for (const account of categorizedAccounts.accounts) {
|
||||
if (!account.hidden) {
|
||||
visibleCount++;
|
||||
}
|
||||
}
|
||||
@@ -407,9 +411,7 @@ function reload(force: boolean): void {
|
||||
displayOrderModified.value = false;
|
||||
|
||||
if (allAccounts.value) {
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
const account = allAccounts.value[i];
|
||||
|
||||
for (const account of allAccounts.value) {
|
||||
if (account.type === AccountType.MultiSubAccounts.type && !activeSubAccount.value[account.id]) {
|
||||
activeSubAccount.value[account.id] = '';
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ import { useAccountEditPageBaseBase } from '@/views/base/accounts/AccountEditPag
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
import { useAccountsStore } from '@/stores/account.ts';
|
||||
|
||||
import { itemAndIndex } from '@/core/base.ts';
|
||||
import { AccountType } from '@/core/account.ts';
|
||||
import { ALL_ACCOUNT_ICONS } from '@/consts/icon.ts';
|
||||
import { ALL_ACCOUNT_COLORS } from '@/consts/color.ts';
|
||||
@@ -365,11 +366,11 @@ function save(): void {
|
||||
});
|
||||
}
|
||||
|
||||
function removeSubAccount(subAccount: Account): void {
|
||||
function removeSubAccount(currentSubAccount: Account): void {
|
||||
confirmDialog.value?.open('Are you sure you want to remove this sub-account?').then(() => {
|
||||
for (let i = 0; i < subAccounts.value.length; i++) {
|
||||
if (subAccounts.value[i] === subAccount) {
|
||||
subAccounts.value.splice(i, 1);
|
||||
for (const [subAccount, index] of itemAndIndex(subAccounts.value)) {
|
||||
if (subAccount === currentSubAccount) {
|
||||
subAccounts.value.splice(index, 1);
|
||||
|
||||
if (currentAccountIndex.value >= subAccounts.value.length) {
|
||||
currentAccountIndex.value = subAccounts.value.length - 1;
|
||||
|
||||
@@ -162,15 +162,15 @@
|
||||
<template #item.categoryId="{ item }">
|
||||
<div class="d-flex align-center">
|
||||
<ItemIcon size="24px" icon-type="category"
|
||||
:icon-id="allCategoriesMap[item.categoryId].icon"
|
||||
:color="allCategoriesMap[item.categoryId].color"
|
||||
:icon-id="allCategoriesMap[item.categoryId]?.icon ?? ''"
|
||||
:color="allCategoriesMap[item.categoryId]?.color ?? ''"
|
||||
v-if="allCategoriesMap[item.categoryId] && allCategoriesMap[item.categoryId]?.color"></ItemIcon>
|
||||
<v-icon size="24" :icon="mdiPencilBoxOutline" v-else-if="!allCategoriesMap[item.categoryId] || !allCategoriesMap[item.categoryId]?.color" />
|
||||
<span class="ms-2" v-if="item.type === TransactionType.ModifyBalance">
|
||||
{{ tt('Modify Balance') }}
|
||||
</span>
|
||||
<span class="ms-2" v-else-if="item.type !== TransactionType.ModifyBalance && allCategoriesMap[item.categoryId]">
|
||||
{{ allCategoriesMap[item.categoryId].name }}
|
||||
{{ allCategoriesMap[item.categoryId]?.name }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -181,9 +181,9 @@
|
||||
</template>
|
||||
<template #item.sourceAccountId="{ item }">
|
||||
<div class="d-flex align-center">
|
||||
<span v-if="item.sourceAccountId && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId].name }}</span>
|
||||
<span v-if="item.sourceAccountId && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId]?.name }}</span>
|
||||
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer"></v-icon>
|
||||
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && allAccountsMap[item.destinationAccountId]">{{ allAccountsMap[item.destinationAccountId].name }}</span>
|
||||
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && allAccountsMap[item.destinationAccountId]">{{ allAccountsMap[item.destinationAccountId]?.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #item.accountBalance="{ item }">
|
||||
@@ -388,12 +388,7 @@ const totalPageCount = computed<number>(() => {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
|
||||
for (let i = 0; i < reconciliationStatements.value.transactions.length; i++) {
|
||||
count++;
|
||||
}
|
||||
|
||||
const count = reconciliationStatements.value.transactions.length;
|
||||
return Math.ceil(count / countPerPage.value);
|
||||
});
|
||||
|
||||
@@ -422,9 +417,7 @@ function getTablePageOptions(linesCount?: number): NameNumeralValue[] {
|
||||
|
||||
const availableCountPerPage = [ 5, 10, 15, 20, 25, 30, 50 ];
|
||||
|
||||
for (let i = 0; i < availableCountPerPage.length; i++) {
|
||||
const count = availableCountPerPage[i];
|
||||
|
||||
for (const count of availableCountPerPage) {
|
||||
if (linesCount < count) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ const primaryCategories = computed<TransactionCategory[]>(() => {
|
||||
return [];
|
||||
}
|
||||
|
||||
return transactionCategoriesStore.allTransactionCategories[activeCategoryType.value];
|
||||
return transactionCategoriesStore.allTransactionCategories[activeCategoryType.value] ?? [];
|
||||
});
|
||||
|
||||
const secondaryCategories = computed<TransactionCategory[]>(() => {
|
||||
@@ -267,7 +267,7 @@ const secondaryCategories = computed<TransactionCategory[]>(() => {
|
||||
return [];
|
||||
}
|
||||
|
||||
return transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value].subCategories || [];
|
||||
return transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value]?.subCategories ?? [];
|
||||
});
|
||||
|
||||
const hasSubCategories = computed<boolean>(() => {
|
||||
|
||||
@@ -78,9 +78,7 @@ const hasAnyData = computed<boolean>(() => {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < props.data.length; i++) {
|
||||
const item = props.data[i];
|
||||
|
||||
for (const item of props.data) {
|
||||
if (item.incomeAmount > 0 || item.incomeAmount < 0 || item.expenseAmount > 0 || item.expenseAmount < 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -99,8 +97,7 @@ const chartOptions = computed<object>(() => {
|
||||
const expenseIncomeAmountColor = getExpenseAndIncomeAmountColor(userStore.currentUserExpenseAmountColor, userStore.currentUserIncomeAmountColor, props.isDarkMode);
|
||||
|
||||
if (props.data) {
|
||||
for (let i = 0; i < props.data.length; i++) {
|
||||
const item = props.data[i];
|
||||
for (const item of props.data) {
|
||||
const monthShortName = formatUnixTimeToGregorianLikeShortMonth(item.monthStartTime);
|
||||
|
||||
monthNames.push(monthShortName);
|
||||
@@ -145,10 +142,9 @@ const chartOptions = computed<object>(() => {
|
||||
let incomeAmount: string | null = null;
|
||||
let expenseAmount: string | null = null;
|
||||
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
const param = params[i];
|
||||
for (const param of params) {
|
||||
const dataIndex = param.dataIndex;
|
||||
const data = props.data[dataIndex];
|
||||
const data = props.data[dataIndex] as TransactionMonthlyIncomeAndExpenseData;
|
||||
|
||||
if (param.seriesId === 'seriesIncome') {
|
||||
incomeAmount = getDisplayIncomeAmount(data);
|
||||
@@ -160,7 +156,7 @@ const chartOptions = computed<object>(() => {
|
||||
return `<table>` +
|
||||
`<thead>` +
|
||||
`<tr>` +
|
||||
`<td colspan="2" class="text-start">${params[0].name}</td>` +
|
||||
`<td colspan="2" class="text-start">${params[0]?.name}</td>` +
|
||||
`</tr>` +
|
||||
`</thead>` +
|
||||
`<tbody>` +
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
</v-list-item>
|
||||
|
||||
<v-list-group :key="category.id" v-for="category in categories">
|
||||
<template #activator="{ props }" v-if="!category.hidden || query.categoryIds === category.id || (allCategories[query.categoryIds] && allCategories[query.categoryIds].parentId === category.id)">
|
||||
<template #activator="{ props }" v-if="!category.hidden || query.categoryIds === category.id || (allCategories[query.categoryIds] && allCategories[query.categoryIds]!.parentId === category.id)">
|
||||
<v-divider />
|
||||
<v-list-item class="text-sm" density="compact"
|
||||
:class="getCategoryListItemCheckedClass(category, queryAllFilterCategoryIds)"
|
||||
@@ -402,12 +402,12 @@
|
||||
</v-list-item>
|
||||
<template :key="account.id"
|
||||
v-for="account in allAccounts">
|
||||
<v-divider v-if="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId].hidden)) || query.accountIds === account.id" />
|
||||
<v-divider v-if="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId]!.hidden)) || query.accountIds === account.id" />
|
||||
<v-list-item class="text-sm" density="compact"
|
||||
:value="account.id"
|
||||
:class="{ 'list-item-selected': query.accountIds === account.id, 'item-in-multiple-selection': queryAllFilterAccountIdsCount > 1 && queryAllFilterAccountIds[account.id] }"
|
||||
:append-icon="(query.accountIds === account.id ? mdiCheck : undefined)"
|
||||
v-if="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId].hidden)) || query.accountIds === account.id">
|
||||
v-if="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId]!.hidden)) || query.accountIds === account.id">
|
||||
<v-list-item-title class="cursor-pointer"
|
||||
@click="changeAccountFilter(account.id)">
|
||||
<div class="d-flex align-center">
|
||||
@@ -527,7 +527,7 @@
|
||||
:class="{ 'disabled': loading, 'has-bottom-border': idx < transactions.length - 1 }"
|
||||
v-for="(transaction, idx) in transactions">
|
||||
<tr class="transaction-list-row-date no-hover text-sm"
|
||||
v-if="pageType === TransactionListPageType.List.type && (idx === 0 || (idx > 0 && (transaction.gregorianCalendarYearDashMonthDashDay !== transactions[idx - 1].gregorianCalendarYearDashMonthDashDay)))">
|
||||
v-if="pageType === TransactionListPageType.List.type && (idx === 0 || (idx > 0 && (transaction.gregorianCalendarYearDashMonthDashDay !== transactions[idx - 1]!.gregorianCalendarYearDashMonthDashDay)))">
|
||||
<td :colspan="showTagInTransactionListPage ? 6 : 5" class="font-weight-bold">
|
||||
<div class="d-flex align-center">
|
||||
<span>{{ getDisplayLongDate(transaction) }}</span>
|
||||
@@ -579,7 +579,7 @@
|
||||
</td>
|
||||
<td class="transaction-table-column-tags" v-if="showTagInTransactionListPage">
|
||||
<v-chip class="transaction-tag" size="small" :prepend-icon="mdiPound"
|
||||
:text="allTransactionTags[tagId].name"
|
||||
:text="allTransactionTags[tagId]?.name"
|
||||
:key="tagId"
|
||||
v-for="tagId in transaction.tagIds"/>
|
||||
<v-chip class="transaction-tag" size="small"
|
||||
@@ -669,7 +669,11 @@ import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||
import { useDesktopPageStore } from '@/stores/desktopPage.ts';
|
||||
|
||||
import type { NameNumeralValue, TypeAndDisplayName } from '@/core/base.ts';
|
||||
import {
|
||||
type NameNumeralValue,
|
||||
type TypeAndDisplayName,
|
||||
keys
|
||||
} from '@/core/base.ts';
|
||||
import {
|
||||
type Year0BasedMonth,
|
||||
type LocalizedRecentMonthDateRange,
|
||||
@@ -884,8 +888,7 @@ const allPageCounts = computed<NameNumeralValue[]>(() => {
|
||||
const pageCounts: NameNumeralValue[] = [];
|
||||
const availableCountPerPage: number[] = [ 5, 10, 15, 20, 25, 30, 50 ];
|
||||
|
||||
for (let i = 0; i < availableCountPerPage.length; i++) {
|
||||
const count = availableCountPerPage[i];
|
||||
for (const count of availableCountPerPage) {
|
||||
pageCounts.push({ value: count, name: numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(count.toString()) });
|
||||
}
|
||||
|
||||
@@ -903,11 +906,11 @@ const allTransactionTagFilterTypes = computed<TransactionTemplateWithIcon[]>(()
|
||||
const allTagFilterTypes: TypeAndDisplayName[] = getAllTransactionTagFilterTypes();
|
||||
const allTagFilterTypesWithIcon: TransactionTemplateWithIcon[] = [];
|
||||
|
||||
for (let i = 0; i < allTagFilterTypes.length; i++) {
|
||||
for (const tagFilterType of allTagFilterTypes) {
|
||||
allTagFilterTypesWithIcon.push({
|
||||
type: allTagFilterTypes[i].type,
|
||||
displayName: allTagFilterTypes[i].displayName,
|
||||
icon: tagFilterIconMap[allTagFilterTypes[i].type]
|
||||
type: tagFilterType.type,
|
||||
displayName: tagFilterType.displayName,
|
||||
icon: tagFilterIconMap[tagFilterType.type] ?? ''
|
||||
});
|
||||
}
|
||||
|
||||
@@ -948,9 +951,7 @@ const transactions = computed<Transaction[]>(() => {
|
||||
|
||||
const transactions :Transaction[] = [];
|
||||
|
||||
for (let i = 0; i < transactionData.items.length; i++) {
|
||||
const transaction = transactionData.items[i];
|
||||
|
||||
for (const transaction of transactionData.items) {
|
||||
if (transaction.gregorianCalendarYearDashMonthDashDay === currentCalendarDate.value) {
|
||||
transactions.push(transaction);
|
||||
}
|
||||
@@ -972,7 +973,7 @@ const recentDateRangeIndex = computed<number>({
|
||||
value = 0;
|
||||
}
|
||||
|
||||
changeDateFilter(recentMonthDateRanges.value[value]);
|
||||
changeDateFilter(recentMonthDateRanges.value[value] as LocalizedRecentMonthDateRange);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1089,8 +1090,8 @@ function getCategoryListItemCheckedClass(category: TransactionCategory, queryCat
|
||||
}
|
||||
|
||||
if (category.subCategories) {
|
||||
for (let i = 0; i < category.subCategories.length; i++) {
|
||||
if (queryCategoryIds && queryCategoryIds[category.subCategories[i].id]) {
|
||||
for (const subCategory of category.subCategories) {
|
||||
if (queryCategoryIds && queryCategoryIds[subCategory.id]) {
|
||||
return {
|
||||
'list-item-selected': true,
|
||||
'has-children-item-selected': true
|
||||
@@ -1382,7 +1383,7 @@ function changeCustomMonthDateFilter(yearMonth: Year0BasedMonth): void {
|
||||
}
|
||||
|
||||
function shiftDateRange(startTime: number, endTime: number, scale: number): void {
|
||||
if (recentMonthDateRanges.value[recentDateRangeIndex.value].dateType === DateRange.All.type) {
|
||||
if (recentMonthDateRanges.value[recentDateRangeIndex.value]?.dateType === DateRange.All.type) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1421,11 +1422,7 @@ function changeTypeFilter(type: number): void {
|
||||
if (type && query.value.categoryIds) {
|
||||
newCategoryFilter = '';
|
||||
|
||||
for (const categoryId in queryAllFilterCategoryIds.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(queryAllFilterCategoryIds.value, categoryId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const categoryId of keys(queryAllFilterCategoryIds.value)) {
|
||||
const category = allCategories.value[categoryId];
|
||||
|
||||
if (category && category.type === transactionTypeToCategoryType(type)) {
|
||||
@@ -1680,13 +1677,13 @@ function scrollAmountMenuToSelectedItem(opened: boolean): void {
|
||||
if (isString(query.value.amountFilter)) {
|
||||
try {
|
||||
const filterItems = query.value.amountFilter.split(':');
|
||||
const amountCount = getAmountFilterParameterCount(filterItems[0]);
|
||||
const amountCount = getAmountFilterParameterCount(filterItems[0] as string);
|
||||
|
||||
if (filterItems.length === 2 && amountCount === 1) {
|
||||
amount1 = parseInt(filterItems[1]);
|
||||
amount1 = parseInt(filterItems[1] as string);
|
||||
} else if (filterItems.length === 3 && amountCount === 2) {
|
||||
amount1 = parseInt(filterItems[1]);
|
||||
amount2 = parseInt(filterItems[2]);
|
||||
amount1 = parseInt(filterItems[1] as string);
|
||||
amount2 = parseInt(filterItems[2] as string);
|
||||
}
|
||||
} catch (ex) {
|
||||
logger.warn('cannot parse amount from filter value, original value is ' + query.value.amountFilter, ex);
|
||||
|
||||
@@ -93,11 +93,11 @@
|
||||
<div class="d-flex align-center" v-if="editingTransaction !== item || item.type === TransactionType.ModifyBalance">
|
||||
<span v-if="item.type === TransactionType.ModifyBalance">-</span>
|
||||
<ItemIcon size="24px" icon-type="category"
|
||||
:icon-id="allCategoriesMap[item.categoryId].icon"
|
||||
:color="allCategoriesMap[item.categoryId].color"
|
||||
:icon-id="allCategoriesMap[item.categoryId]?.icon ?? ''"
|
||||
:color="allCategoriesMap[item.categoryId]?.color ?? ''"
|
||||
v-if="item.type !== TransactionType.ModifyBalance && item.categoryId && item.categoryId !== '0' && allCategoriesMap[item.categoryId]"></ItemIcon>
|
||||
<span class="ms-2" v-if="item.type !== TransactionType.ModifyBalance && item.categoryId && item.categoryId !== '0' && allCategoriesMap[item.categoryId]">
|
||||
{{ allCategoriesMap[item.categoryId].name }}
|
||||
{{ allCategoriesMap[item.categoryId]?.name }}
|
||||
</span>
|
||||
<div class="text-error font-italic" v-else-if="item.type !== TransactionType.ModifyBalance && (!item.categoryId || item.categoryId === '0' || !allCategoriesMap[item.categoryId])">
|
||||
<v-icon class="me-1" :icon="mdiAlertOutline"/>
|
||||
@@ -166,13 +166,13 @@
|
||||
</template>
|
||||
<template #item.actualSourceAccountName="{ item }">
|
||||
<div class="d-flex align-center" v-if="editingTransaction !== item">
|
||||
<span v-if="item.sourceAccountId && item.sourceAccountId !== '0' && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId].name }}</span>
|
||||
<span v-if="item.sourceAccountId && item.sourceAccountId !== '0' && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId]?.name }}</span>
|
||||
<div class="text-error font-italic" v-else>
|
||||
<v-icon class="me-1" :icon="mdiAlertOutline"/>
|
||||
<span>{{ item.originalSourceAccountName }}</span>
|
||||
</div>
|
||||
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer"></v-icon>
|
||||
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && item.destinationAccountId !== '0' && allAccountsMap[item.destinationAccountId]">{{allAccountsMap[item.destinationAccountId].name }}</span>
|
||||
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && item.destinationAccountId !== '0' && allAccountsMap[item.destinationAccountId]">{{allAccountsMap[item.destinationAccountId]?.name }}</span>
|
||||
<div class="text-error font-italic" v-else-if="item.type === TransactionType.Transfer && (!item.destinationAccountId || item.destinationAccountId === '0' || !allAccountsMap[item.destinationAccountId])">
|
||||
<v-icon class="me-1" :icon="mdiAlertOutline"/>
|
||||
<span>{{ item.originalDestinationAccountName }}</span>
|
||||
@@ -252,7 +252,7 @@
|
||||
<v-chip :class="{ 'font-italic': !isTagValid(editingTags, index) }"
|
||||
:prepend-icon="isTagValid(editingTags, index) ? mdiPound : mdiAlertOutline"
|
||||
:color="isTagValid(editingTags, index) ? 'default' : 'error'"
|
||||
:text="isTagValid(editingTags, index) ? allTagsMap[editingTags[index]].name : item.originalTagNames[index]"
|
||||
:text="isTagValid(editingTags, index) ? allTagsMap[editingTags[index] as string]?.name : item.originalTagNames[index]"
|
||||
v-bind="props"/>
|
||||
</template>
|
||||
|
||||
@@ -1153,7 +1153,7 @@ function getTransactionDisplayAmount(transaction: ImportTransaction): string {
|
||||
let currency = transaction.originalSourceAccountCurrency || defaultCurrency.value;
|
||||
|
||||
if (transaction.sourceAccountId && transaction.sourceAccountId !== '0' && allAccountsMap.value[transaction.sourceAccountId]) {
|
||||
currency = allAccountsMap.value[transaction.sourceAccountId].currency;
|
||||
currency = allAccountsMap.value[transaction.sourceAccountId]!.currency;
|
||||
}
|
||||
|
||||
return getDisplayCurrency(transaction.sourceAmount, currency);
|
||||
@@ -1167,7 +1167,7 @@ function getTransactionDisplayDestinationAmount(transaction: ImportTransaction):
|
||||
let currency = transaction.originalDestinationAccountCurrency || defaultCurrency.value;
|
||||
|
||||
if (transaction.destinationAccountId && transaction.destinationAccountId !== '0' && allAccountsMap.value[transaction.destinationAccountId]) {
|
||||
currency = allAccountsMap.value[transaction.destinationAccountId].currency;
|
||||
currency = allAccountsMap.value[transaction.destinationAccountId]!.currency;
|
||||
}
|
||||
|
||||
return getDisplayCurrency(transaction.destinationAmount, currency);
|
||||
@@ -1425,15 +1425,15 @@ function updateTransactionData(transaction: ImportTransaction): void {
|
||||
transaction.valid = transaction.isTransactionValid();
|
||||
|
||||
if (transaction.categoryId && allCategoriesMap.value[transaction.categoryId]) {
|
||||
transaction.actualCategoryName = allCategoriesMap.value[transaction.categoryId].name;
|
||||
transaction.actualCategoryName = allCategoriesMap.value[transaction.categoryId]!.name;
|
||||
}
|
||||
|
||||
if (transaction.sourceAccountId && allAccountsMap.value[transaction.sourceAccountId]) {
|
||||
transaction.actualSourceAccountName = allAccountsMap.value[transaction.sourceAccountId].name;
|
||||
transaction.actualSourceAccountName = allAccountsMap.value[transaction.sourceAccountId]!.name;
|
||||
}
|
||||
|
||||
if (transaction.destinationAccountId && allAccountsMap.value[transaction.destinationAccountId]) {
|
||||
transaction.actualDestinationAccountName = allAccountsMap.value[transaction.destinationAccountId].name;
|
||||
transaction.actualDestinationAccountName = allAccountsMap.value[transaction.destinationAccountId]!.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -358,15 +358,16 @@ const parsedFileLinesHeaders = computed<object[]>(() => {
|
||||
}
|
||||
}
|
||||
|
||||
const headers: object[] = [];
|
||||
const firstLine: string[] = props.parsedFileData && props.parsedFileData.length > 0 ? (props.parsedFileData[0] as string[]) : [];
|
||||
|
||||
const headers: object[] = [];
|
||||
headers.push({ key: 'index', value: 'index', title: '#', sortable: true, nowrap: true });
|
||||
|
||||
for (let i = 0; i < maxColumnCount; i++) {
|
||||
let title = `#${i + 1}`;
|
||||
|
||||
if (parsedFileDataColumnMapping.value.includeHeader && props.parsedFileData && props.parsedFileData[0][i]) {
|
||||
title = props.parsedFileData[0][i] as string;
|
||||
if (parsedFileDataColumnMapping.value.includeHeader && firstLine && firstLine[i]) {
|
||||
title = firstLine[i] as string;
|
||||
}
|
||||
|
||||
headers.push({ key: i.toString(), value: `column${i + 1}`, title: title, sortable: true, nowrap: true });
|
||||
|
||||
@@ -370,7 +370,7 @@
|
||||
<template #default>
|
||||
<div class="grid grid-cols-2">
|
||||
<div class="list-item-subitem no-chevron">
|
||||
<a class="item-link" href="#" @click="subAccountContexts[idx].showIconSelectionSheet = true">
|
||||
<a class="item-link" href="#" @click="subAccountContexts[idx]!.showIconSelectionSheet = true">
|
||||
<div class="item-content">
|
||||
<div class="item-inner">
|
||||
<div class="item-header">
|
||||
@@ -387,12 +387,12 @@
|
||||
|
||||
<icon-selection-sheet :all-icon-infos="ALL_ACCOUNT_ICONS"
|
||||
:color="subAccount.color"
|
||||
v-model:show="subAccountContexts[idx].showIconSelectionSheet"
|
||||
v-model:show="subAccountContexts[idx]!.showIconSelectionSheet"
|
||||
v-model="subAccount.icon"
|
||||
></icon-selection-sheet>
|
||||
</div>
|
||||
<div class="list-item-subitem no-chevron">
|
||||
<a class="item-link" href="#" @click="subAccountContexts[idx].showColorSelectionSheet = true">
|
||||
<a class="item-link" href="#" @click="subAccountContexts[idx]!.showColorSelectionSheet = true">
|
||||
<div class="item-content">
|
||||
<div class="item-inner">
|
||||
<div class="item-header">
|
||||
@@ -408,7 +408,7 @@
|
||||
</a>
|
||||
|
||||
<color-selection-sheet :all-color-infos="ALL_ACCOUNT_COLORS"
|
||||
v-model:show="subAccountContexts[idx].showColorSelectionSheet"
|
||||
v-model:show="subAccountContexts[idx]!.showColorSelectionSheet"
|
||||
v-model="subAccount.color"
|
||||
></color-selection-sheet>
|
||||
</div>
|
||||
@@ -422,7 +422,7 @@
|
||||
:class="{ 'disabled': editAccountId && !isNewAccount(subAccount) }"
|
||||
:header="tt('Currency')"
|
||||
:no-chevron="!!editAccountId && !isNewAccount(subAccount)"
|
||||
@click="subAccountContexts[idx].showCurrencyPopup = true"
|
||||
@click="subAccountContexts[idx]!.showCurrencyPopup = true"
|
||||
>
|
||||
<template #title>
|
||||
<div class="no-padding no-margin">
|
||||
@@ -438,7 +438,7 @@
|
||||
:filter-placeholder="tt('Currency')"
|
||||
:filter-no-items-text="tt('No results')"
|
||||
:items="allCurrencies"
|
||||
v-model:show="subAccountContexts[idx].showCurrencyPopup"
|
||||
v-model:show="subAccountContexts[idx]!.showCurrencyPopup"
|
||||
v-model="subAccount.currency">
|
||||
</list-item-selection-popup>
|
||||
</f7-list-item>
|
||||
@@ -449,13 +449,13 @@
|
||||
:class="{ 'disabled': editAccountId && !isNewAccount(subAccount) }"
|
||||
:header="account.isLiability ? tt('Sub-account Outstanding Balance') : tt('Sub-account Balance')"
|
||||
:title="formatAccountDisplayBalance(subAccount)"
|
||||
@click="subAccountContexts[idx].showBalanceSheet = true"
|
||||
@click="subAccountContexts[idx]!.showBalanceSheet = true"
|
||||
>
|
||||
<number-pad-sheet :min-value="TRANSACTION_MIN_AMOUNT"
|
||||
:max-value="TRANSACTION_MAX_AMOUNT"
|
||||
:currency="subAccount.currency"
|
||||
:flip-negative="account.isLiability"
|
||||
v-model:show="subAccountContexts[idx].showBalanceSheet"
|
||||
v-model:show="subAccountContexts[idx]!.showBalanceSheet"
|
||||
v-model="subAccount.balance"
|
||||
></number-pad-sheet>
|
||||
</f7-list-item>
|
||||
@@ -467,15 +467,15 @@
|
||||
v-if="!editAccountId || isNewAccount(subAccount)"
|
||||
>
|
||||
<template #header>
|
||||
<div class="account-edit-balancetime-header" @click="showDateTimeDialog(subAccountContexts[idx], 'time')">{{ tt('Sub-account Balance Time') }}</div>
|
||||
<div class="account-edit-balancetime-header" @click="showDateTimeDialog(subAccountContexts[idx] as AccountContext, 'time')">{{ tt('Sub-account Balance Time') }}</div>
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="account-edit-balancetime-title">
|
||||
<div @click="showDateTimeDialog(subAccountContexts[idx], 'date')">{{ formatAccountBalanceDate(subAccount) }}</div> <div class="account-edit-balancetime-time" @click="showDateTimeDialog(subAccountContexts[idx], 'time')">{{ formatAccountBalanceTime(subAccount) }}</div>
|
||||
<div @click="showDateTimeDialog(subAccountContexts[idx] as AccountContext, 'date')">{{ formatAccountBalanceDate(subAccount) }}</div> <div class="account-edit-balancetime-time" @click="showDateTimeDialog(subAccountContexts[idx] as AccountContext, 'time')">{{ formatAccountBalanceTime(subAccount) }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<date-time-selection-sheet :init-mode="subAccountContexts[idx].balanceDateTimeSheetMode"
|
||||
v-model:show="subAccountContexts[idx].showBalanceDateTimeSheet"
|
||||
<date-time-selection-sheet :init-mode="subAccountContexts[idx]!.balanceDateTimeSheetMode"
|
||||
v-model:show="subAccountContexts[idx]!.showBalanceDateTimeSheet"
|
||||
v-model="subAccount.balanceTime">
|
||||
</date-time-selection-sheet>
|
||||
</f7-list-item>
|
||||
@@ -526,6 +526,7 @@ import { useAccountEditPageBaseBase } from '@/views/base/accounts/AccountEditPag
|
||||
|
||||
import { useAccountsStore } from '@/stores/account.ts';
|
||||
|
||||
import { itemAndIndex } from '@/core/base.ts';
|
||||
import type { LocalizedCurrencyInfo } from '@/core/currency.ts';
|
||||
import { AccountType } from '@/core/account.ts';
|
||||
import { ALL_ACCOUNT_ICONS } from '@/consts/icon.ts';
|
||||
@@ -709,14 +710,14 @@ function addSubAccountAndContext(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function removeSubAccount(subAccount: Account | null, confirm: boolean): void {
|
||||
if (!subAccount) {
|
||||
function removeSubAccount(currentSubAccount: Account | null, confirm: boolean): void {
|
||||
if (!currentSubAccount) {
|
||||
showAlert('An error occurred');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm) {
|
||||
subAccountToDelete.value = subAccount;
|
||||
subAccountToDelete.value = currentSubAccount;
|
||||
showDeleteActionSheet.value = true;
|
||||
return;
|
||||
}
|
||||
@@ -724,10 +725,10 @@ function removeSubAccount(subAccount: Account | null, confirm: boolean): void {
|
||||
showDeleteActionSheet.value = false;
|
||||
subAccountToDelete.value = null;
|
||||
|
||||
for (let i = 0; i < subAccounts.value.length; i++) {
|
||||
if (subAccounts.value[i] === subAccount) {
|
||||
subAccounts.value.splice(i, 1);
|
||||
subAccountContexts.value.splice(i, 1);
|
||||
for (const [subAccount, index] of itemAndIndex(subAccounts.value)) {
|
||||
if (subAccount === currentSubAccount) {
|
||||
subAccounts.value.splice(index, 1);
|
||||
subAccountContexts.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,13 +140,13 @@ const categories = computed<TransactionCategory[]>(() => {
|
||||
return [];
|
||||
}
|
||||
|
||||
return transactionCategoriesStore.allTransactionCategories[categoryType.value];
|
||||
return transactionCategoriesStore.allTransactionCategories[categoryType.value] ?? [];
|
||||
} else if (primaryCategoryId.value && primaryCategoryId.value !== '' && primaryCategoryId.value !== '0') {
|
||||
if (!transactionCategoriesStore.allTransactionCategoriesMap || !transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value]) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value].subCategories || [];
|
||||
return transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value]?.subCategories ?? [];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -684,9 +684,9 @@ const transactionPictures = computed<Record<string, string | undefined>[]>(() =>
|
||||
return thumbs;
|
||||
}
|
||||
|
||||
for (let i = 0; i < transaction.value.pictures.length; i++) {
|
||||
for (const picture of transaction.value.pictures) {
|
||||
thumbs.push({
|
||||
url: getTransactionPictureUrl(transaction.value.pictures[i])
|
||||
url: getTransactionPictureUrl(picture)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -700,8 +700,8 @@ const transactionThumbs = computed<(string | undefined)[]>(() => {
|
||||
return thumbs;
|
||||
}
|
||||
|
||||
for (let i = 0; i < transaction.value.pictures.length; i++) {
|
||||
thumbs.push(getTransactionPictureUrl(transaction.value.pictures[i]));
|
||||
for (const picture of transaction.value.pictures) {
|
||||
thumbs.push(getTransactionPictureUrl(picture));
|
||||
}
|
||||
|
||||
return thumbs;
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
v-for="(transaction, idx) in transactionMonthList.items"
|
||||
>
|
||||
<template #media>
|
||||
<div class="display-flex flex-direction-column transaction-date" :style="getTransactionDateStyle(transaction, idx > 0 ? transactionMonthList.items[idx - 1] : null)">
|
||||
<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) }}
|
||||
</span>
|
||||
@@ -252,7 +252,7 @@
|
||||
<div class="item-footer">
|
||||
<div class="transaction-tags" v-if="showTagInTransactionListPage && transaction.tagIds && transaction.tagIds.length">
|
||||
<f7-chip media-text-color="var(--f7-chip-text-color)" class="transaction-tag"
|
||||
:text="allTransactionTags[tagId].name"
|
||||
:text="allTransactionTags[tagId]?.name"
|
||||
:key="tagId"
|
||||
v-for="tagId in transaction.tagIds">
|
||||
<template #media>
|
||||
@@ -373,7 +373,7 @@
|
||||
:class="getCategoryListItemCheckedClass(category, queryAllFilterCategoryIds)"
|
||||
:key="category.id"
|
||||
v-for="category in categories"
|
||||
v-show="!category.hidden || query.categoryIds === category.id || (allCategories[query.categoryIds] && allCategories[query.categoryIds].parentId === category.id)"
|
||||
v-show="!category.hidden || query.categoryIds === category.id || (allCategories[query.categoryIds] && allCategories[query.categoryIds]?.parentId === category.id)"
|
||||
>
|
||||
<template #media>
|
||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||
@@ -439,7 +439,7 @@
|
||||
:class="{ 'list-item-selected': query.accountIds === account.id, 'item-in-multiple-selection': queryAllFilterAccountIdsCount > 1 && queryAllFilterAccountIds[account.id] }"
|
||||
:key="account.id"
|
||||
v-for="account in allAccounts"
|
||||
v-show="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId].hidden)) || query.accountIds === account.id"
|
||||
v-show="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId]!.hidden)) || query.accountIds === account.id"
|
||||
@click="changeAccountFilter(account.id)"
|
||||
>
|
||||
<template #media>
|
||||
@@ -597,7 +597,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { type TypeAndDisplayName, keys } from '@/core/base.ts';
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import {
|
||||
type TextualYearMonth,
|
||||
@@ -742,9 +742,7 @@ const transactions = computed<TransactionMonthList[]>(() => {
|
||||
|
||||
const transactions :Transaction[] = [];
|
||||
|
||||
for (let i = 0; i < transactionData.items.length; i++) {
|
||||
const transaction = transactionData.items[i];
|
||||
|
||||
for (const transaction of transactionData.items) {
|
||||
if (transaction.gregorianCalendarYearDashMonthDashDay === currentCalendarDate.value) {
|
||||
transactions.push(transaction);
|
||||
}
|
||||
@@ -778,7 +776,7 @@ const noTransaction = computed<boolean>(() => {
|
||||
if (pageType.value === TransactionListPageType.List.type) {
|
||||
return transactionsStore.noTransaction;
|
||||
} else if (pageType.value === TransactionListPageType.Calendar.type) {
|
||||
return !transactions.value || !transactions.value.length || !transactions.value[0].items || !transactions.value[0].items.length;
|
||||
return !transactions.value || !transactions.value.length || !transactions.value[0]!.items || !transactions.value[0]!.items.length;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@@ -832,8 +830,7 @@ function setTransactionMonthListHeights(reset: boolean): Promise<unknown> {
|
||||
if (transactions.value && transactions.value.length) {
|
||||
const heights: Record<string, number> = getElementActualHeights('.transaction-month-list');
|
||||
|
||||
for (let i = 0; i < transactions.value.length - 1; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
for (const transactionMonthList of transactions.value) {
|
||||
const yearDashMonth = transactionMonthList.yearDashMonth;
|
||||
const domId = getTransactionMonthListDomId(yearDashMonth);
|
||||
const height = heights[domId];
|
||||
@@ -851,8 +848,7 @@ function setTransactionInvisibleYearMonthList(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < transactions.value.length - 1; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
for (const transactionMonthList of transactions.value) {
|
||||
const yearDashMonth = transactionMonthList.yearDashMonth;
|
||||
|
||||
const titleDomId = getTransactionMonthTitleDomId(yearDashMonth);
|
||||
@@ -875,7 +871,7 @@ function setTransactionInvisibleYearMonthList(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function getTransactionDateStyle(transaction: Transaction, previousTransaction: Transaction | null): Record<string, string> {
|
||||
function getTransactionDateStyle(transaction: Transaction, previousTransaction: Transaction | undefined): Record<string, string> {
|
||||
if (!previousTransaction || transaction.gregorianCalendarDayOfMonth !== previousTransaction.gregorianCalendarDayOfMonth) {
|
||||
return {};
|
||||
}
|
||||
@@ -893,8 +889,8 @@ function getCategoryListItemCheckedClass(category: TransactionCategory, queryCat
|
||||
}
|
||||
|
||||
if (category.subCategories) {
|
||||
for (let i = 0; i < category.subCategories.length; i++) {
|
||||
if (queryCategoryIds && queryCategoryIds[category.subCategories[i].id]) {
|
||||
for (const subCategory of category.subCategories) {
|
||||
if (queryCategoryIds && queryCategoryIds[subCategory.id]) {
|
||||
return {
|
||||
'list-item-checked': true
|
||||
};
|
||||
@@ -1208,11 +1204,7 @@ function changeTypeFilter(type: number): void {
|
||||
if (type && query.value.categoryIds) {
|
||||
newCategoryFilter = '';
|
||||
|
||||
for (const categoryId in queryAllFilterCategoryIds.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(queryAllFilterCategoryIds.value, categoryId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const categoryId of keys(queryAllFilterCategoryIds.value)) {
|
||||
const category = allCategories.value[categoryId];
|
||||
|
||||
if (category && category.type === transactionTypeToCategoryType(type)) {
|
||||
|
||||
Reference in New Issue
Block a user