use for-of statements to replace for and for-in

This commit is contained in:
MaysWind
2025-09-14 17:18:01 +08:00
parent 4700446ca0
commit 1a8ce7d58d
29 changed files with 455 additions and 579 deletions
+25 -28
View File
@@ -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 });