From 1a8ce7d58df0e47d423fceb51286a1e1c1a5b409 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sun, 14 Sep 2025 17:18:01 +0800 Subject: [PATCH] use for-of statements to replace for and for-in --- .../desktop/ScheduleFrequencySelect.vue | 10 +- .../mobile/AccountBalanceTrendsBarChart.vue | 17 +- .../mobile/ScheduleFrequencySheet.vue | 15 +- .../mobile/TreeViewSelectionSheet.vue | 4 +- src/core/import_transaction.ts | 76 +++-- .../calendar/__tests__/chinese_calendar.ts | 13 +- src/lib/category.ts | 4 +- src/lib/common.ts | 26 +- src/lib/map/leaflet.ts | 4 +- src/models/account.ts | 12 +- src/models/transaction.ts | 6 +- src/stores/account.ts | 312 ++++++++---------- src/stores/statistics.ts | 39 +-- src/stores/transaction.ts | 100 +++--- src/stores/transactionCategory.ts | 84 +++-- src/stores/transactionTemplate.ts | 72 ++-- .../base/settings/AppCloudSyncPageBase.ts | 3 +- src/views/desktop/accounts/ListPage.vue | 22 +- .../accounts/list/dialogs/EditDialog.vue | 9 +- .../dialogs/ReconciliationStatementDialog.vue | 21 +- src/views/desktop/categories/ListPage.vue | 4 +- .../cards/MonthlyIncomeAndExpenseCard.vue | 14 +- src/views/desktop/transactions/ListPage.vue | 53 ++- .../tabs/ImportTransactionCheckDataTab.vue | 22 +- .../tabs/ImportTransactionDefineColumnTab.vue | 7 +- src/views/mobile/accounts/EditPage.vue | 39 +-- src/views/mobile/categories/ListPage.vue | 4 +- src/views/mobile/transactions/EditPage.vue | 8 +- src/views/mobile/transactions/ListPage.vue | 34 +- 29 files changed, 455 insertions(+), 579 deletions(-) diff --git a/src/components/desktop/ScheduleFrequencySelect.vue b/src/components/desktop/ScheduleFrequencySelect.vue index 65df22d1..2c5b8fb6 100644 --- a/src/components/desktop/ScheduleFrequencySelect.vue +++ b/src/components/desktop/ScheduleFrequencySelect.vue @@ -151,14 +151,8 @@ function updateFrequencyValue(value: number, selected: boolean | null): void { frequencyValue.value = sortNumbersArray(newFrequencyValues); } -function isFrequencyValueSelected(value: number): boolean { - for (let i = 0; i < frequencyValue.value.length; i++) { - if (frequencyValue.value[i] === value) { - return true; - } - } - - return false; +function isFrequencyValueSelected(currentValue: number): boolean { + return frequencyValue.value.indexOf(currentValue) >= 0; } function onMenuStateChanged(state: boolean): void { diff --git a/src/components/mobile/AccountBalanceTrendsBarChart.vue b/src/components/mobile/AccountBalanceTrendsBarChart.vue index c7a8300a..962e8372 100644 --- a/src/components/mobile/AccountBalanceTrendsBarChart.vue +++ b/src/components/mobile/AccountBalanceTrendsBarChart.vue @@ -56,6 +56,7 @@ import { useAccountBalanceTrendsChartBase } from '@/components/base/AccountBalanceTrendsChartBase.ts' +import { itemAndIndex } from '@/core/base.ts'; import type { ColorStyleValue } from '@/core/color.ts'; import { DEFAULT_CHART_COLORS } from '@/consts/color.ts'; @@ -88,15 +89,13 @@ const allVirtualListItems = computed(() = const ret: MobileAccountBalanceTrendsChartItem[] = []; let maxClosingBalance = 0; - for (let i = 0; i < allDataItems.value.length; i++) { - const dataItem = allDataItems.value[i]; - + for (const [dataItem, index] of itemAndIndex(allDataItems.value)) { if (dataItem.closingBalance > maxClosingBalance) { maxClosingBalance = dataItem.closingBalance; } const finalDataItem: MobileAccountBalanceTrendsChartItem = { - index: i, + index: index, displayDate: dataItem.displayDate, openingBalance: dataItem.openingBalance, closingBalance: dataItem.closingBalance, @@ -104,18 +103,18 @@ const allVirtualListItems = computed(() = averageBalance: dataItem.averageBalance, minimumBalance: dataItem.minimumBalance, maximumBalance: dataItem.maximumBalance, - color: `#${DEFAULT_CHART_COLORS[0]}`, + color: `#${DEFAULT_CHART_COLORS[0] as string}`, percent: 0.0 }; ret.push(finalDataItem); } - for (let i = 0; i < ret.length; i++) { - if (maxClosingBalance > 0 && ret[i].closingBalance > 0) { - ret[i].percent = 100.0 * ret[i].closingBalance / maxClosingBalance; + for (const item of ret) { + if (maxClosingBalance > 0 && item.closingBalance > 0) { + item.percent = 100.0 * item.closingBalance / maxClosingBalance; } else { - ret[i].percent = 0.0; + item.percent = 0.0; } } diff --git a/src/components/mobile/ScheduleFrequencySheet.vue b/src/components/mobile/ScheduleFrequencySheet.vue index 08b62060..f758684f 100644 --- a/src/components/mobile/ScheduleFrequencySheet.vue +++ b/src/components/mobile/ScheduleFrequencySheet.vue @@ -72,6 +72,7 @@ import { type CommonScheduleFrequencySelectionProps, useScheduleFrequencySelecti import { useUserStore } from '@/stores/user.ts'; +import { itemAndIndex } from '@/core/base.ts'; import { type WeekDayValue } from '@/core/datetime.ts'; import { ScheduledTemplateFrequencyType } from '@/core/template.ts'; import { sortNumbersArray } from '@/lib/common.ts'; @@ -117,20 +118,20 @@ function changeFrequencyType(value: number): void { } function changeFrequencyValue(e: Event): void { - const value = parseInt((e.target as HTMLInputElement).value); + const currentValue = parseInt((e.target as HTMLInputElement).value); if ((e.target as HTMLInputElement).checked) { - for (let i = 0; i < currentFrequencyValue.value.length; i++) { - if (currentFrequencyValue.value[i] === value) { + for (const value of currentFrequencyValue.value) { + if (value === currentValue) { return; } } - currentFrequencyValue.value.push(value); + currentFrequencyValue.value.push(currentValue); } else { - for (let i = 0; i < currentFrequencyValue.value.length; i++) { - if (currentFrequencyValue.value[i] === value) { - currentFrequencyValue.value.splice(i, 1); + for (const [value, index] of itemAndIndex(currentFrequencyValue.value)) { + if (value === currentValue) { + currentFrequencyValue.value.splice(index, 1); break; } } diff --git a/src/components/mobile/TreeViewSelectionSheet.vue b/src/components/mobile/TreeViewSelectionSheet.vue index f5efd5c5..0225fb97 100644 --- a/src/components/mobile/TreeViewSelectionSheet.vue +++ b/src/components/mobile/TreeViewSelectionSheet.vue @@ -103,9 +103,7 @@ function isPrimaryItemHasSecondaryValue(primaryItem: Record): b const lowerCaseFilterContent = filterContent.value?.toLowerCase() ?? ''; - for (let i = 0; i < subItems.length; i++) { - const secondaryItem = subItems[i]; - + for (const secondaryItem of subItems) { if (props.secondaryHiddenField && (secondaryItem as Record)[props.secondaryHiddenField]) { continue; } diff --git a/src/core/import_transaction.ts b/src/core/import_transaction.ts index a7674949..95c6482a 100644 --- a/src/core/import_transaction.ts +++ b/src/core/import_transaction.ts @@ -1,4 +1,4 @@ -import type { TypeAndName, TypeAndDisplayName } from './base.ts'; +import { type TypeAndName, type TypeAndDisplayName, entries, keys } from './base.ts'; import { KnownAmountFormat } from './numeral.ts'; import { KnownDateTimeFormat } from './datetime.ts'; import { KnownDateTimezoneFormat } from './timezone.ts'; @@ -92,9 +92,9 @@ export class ImportTransactionDataMapping { this.dataColumnMapping[columnType] = columnIndex; } - for (const otherColumnType in this.dataColumnMapping) { - if (otherColumnType !== columnType.toString() && this.dataColumnMapping[otherColumnType] === columnIndex) { - delete this.dataColumnMapping[otherColumnType]; + for (const otherColumnType of keys(this.dataColumnMapping)) { + if (otherColumnType !== columnType.toString() && this.dataColumnMapping[parseInt(otherColumnType)] === columnIndex) { + delete this.dataColumnMapping[parseInt(otherColumnType)]; } } } @@ -119,16 +119,22 @@ export class ImportTransactionDataMapping { const allTypeMap: Record = {}; const allTypes: string[] = []; - const typeColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionType.type]; + const typeColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionType.type] as number; const startIndex = this.includeHeader ? 1 : 0; for (let i = startIndex; i < fileData.length; i++) { - if (fileData[i].length <= typeColumnIndex) { + const items = fileData[i]; + + if (!items) { continue; } - const type = fileData[i][typeColumnIndex]; + if (items.length <= typeColumnIndex) { + continue; + } + + const type = items[typeColumnIndex]; if (type && !allTypeMap[type]) { allTypes.push(type); @@ -150,13 +156,7 @@ export class ImportTransactionDataMapping { return result; } - for (const name in this.transactionTypeMapping) { - if (!Object.prototype.hasOwnProperty.call(this.transactionTypeMapping, name)) { - continue; - } - - const type = this.transactionTypeMapping[name]; - + for (const [name, type] of entries(this.transactionTypeMapping)) { if (TransactionType.ModifyBalance <= type && type <= TransactionType.Transfer) { result[name] = type; } @@ -171,16 +171,22 @@ export class ImportTransactionDataMapping { } const allDateTimes: string[] = []; - const dateTimeColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionTime.type]; + const dateTimeColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionTime.type] as number; const startIndex = this.includeHeader ? 1 : 0; for (let i = startIndex; i < fileData.length; i++) { - if (fileData[i].length <= dateTimeColumnIndex) { + const items = fileData[i]; + + if (!items) { continue; } - const dateTime = fileData[i][dateTimeColumnIndex]; + if (items.length <= dateTimeColumnIndex) { + continue; + } + + const dateTime = items[dateTimeColumnIndex]; if (dateTime) { allDateTimes.push(dateTime); @@ -193,7 +199,7 @@ export class ImportTransactionDataMapping { return undefined; } - return detectedFormats[0].format; + return detectedFormats[0]!.format; } public parseFileAutoDetectedTimezoneFormat(fileData: string[][] | undefined): string | undefined { @@ -202,16 +208,22 @@ export class ImportTransactionDataMapping { } const allTimezones: string[] = []; - const timezoneColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionTimezone.type]; + const timezoneColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionTimezone.type] as number; const startIndex = this.includeHeader ? 1 : 0; for (let i = startIndex; i < fileData.length; i++) { - if (fileData[i].length <= timezoneColumnIndex) { + const items = fileData[i]; + + if (!items) { continue; } - const timezone = fileData[i][timezoneColumnIndex]; + if (items.length <= timezoneColumnIndex) { + continue; + } + + const timezone = items[timezoneColumnIndex]; if (timezone) { allTimezones.push(timezone); @@ -224,7 +236,7 @@ export class ImportTransactionDataMapping { return undefined; } - return detectedFormats[0].value; + return detectedFormats[0]!.value; } public parseFileAutoDetectedAmountFormat(fileData: string[][] | undefined): string | undefined { @@ -233,16 +245,22 @@ export class ImportTransactionDataMapping { } const allAmounts: string[] = []; - const amountColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.Amount.type]; + const amountColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.Amount.type] as number; const startIndex = this.includeHeader ? 1 : 0; for (let i = startIndex; i < fileData.length; i++) { - if (fileData[i].length <= amountColumnIndex) { + const items = fileData[i]; + + if (!items) { continue; } - const amount = fileData[i][amountColumnIndex]; + if (items.length <= amountColumnIndex) { + continue; + } + + const amount = items[amountColumnIndex]; if (amount) { allAmounts.push(amount); @@ -255,7 +273,7 @@ export class ImportTransactionDataMapping { return undefined; } - return detectedFormats[0].type; + return detectedFormats[0]!.type; } public reset(): void { @@ -382,8 +400,7 @@ export class ImportTransactionReplaceRules { public toJson(): string { const result: unknown[] = []; - for (let i = 0; i < this.rules.length; i++) { - const rule = this.rules[i]; + for (const rule of this.rules) { result.push(rule.toJsonObject()); } @@ -407,8 +424,7 @@ export class ImportTransactionReplaceRules { const result = new ImportTransactionReplaceRules([]); - for (let i = 0; i < root.length; i++) { - const rule = root[i]; + for (const rule of root) { const replaceRule = ImportTransactionReplaceRule.parse(rule); if (replaceRule) { diff --git a/src/lib/calendar/__tests__/chinese_calendar.ts b/src/lib/calendar/__tests__/chinese_calendar.ts index a377ba57..d74d1cc7 100644 --- a/src/lib/calendar/__tests__/chinese_calendar.ts +++ b/src/lib/calendar/__tests__/chinese_calendar.ts @@ -3,6 +3,8 @@ import path from 'path'; import { describe, expect, test } from '@jest/globals'; import { DEFAULT_CONTENT } from '@/locales/calendar/chinese/index.ts'; + +import { itemAndIndex, entries } from '@/core/base.ts'; import type { ChineseCalendarLocaleData } from '@/core/calendar.ts'; import { type ChineseYearMonthDayInfo, @@ -90,12 +92,12 @@ describe('getChineseYearMonthAllDayInfos', () => { allMonthChineseDays[`${currentYear}-${currentMonth}`] = currentMonthChineseDays; allMonthSolarTermNames[`${currentYear}-${currentMonth}`] = currentMonthSolarTermNames; - for (const yearMonth in allMonthChineseDays) { + for (const [yearMonth, monthChineseDays] of entries(allMonthChineseDays)) { test(`returns correct chinese all dates in month for ${yearMonth}`, () => { const [yearStr, monthStr] = yearMonth.split('-'); const year = parseInt(yearStr as string); const month = parseInt(monthStr as string); - const expectedChineseMonthOrDays = allMonthChineseDays[yearMonth] as string[]; + const expectedChineseMonthOrDays = monthChineseDays; const expectedSolarTermNames = allMonthSolarTermNames[yearMonth] as string[]; const actualChineseDates: ChineseYearMonthDayInfo[] | undefined = getChineseYearMonthAllDayInfos({ @@ -106,13 +108,12 @@ describe('getChineseYearMonthAllDayInfos', () => { expect(actualChineseDates).toBeDefined(); if (actualChineseDates) { - for (let i = 0; i < actualChineseDates.length; i++) { - const actualChineseDate = actualChineseDates[i]; + for (const [actualChineseDate, index] of itemAndIndex(actualChineseDates)) { const chineseMonthOrDay: string | undefined = actualChineseDate?.day === 1 ? `${actualChineseDate?.month}${ordinalSuffix[actualChineseDate?.month - 1] ?? 'th'} Lunar Month`.toLowerCase() : actualChineseDate?.day.toString(); expect(actualChineseDate).toBeDefined(); - expect(chineseMonthOrDay).toBe(expectedChineseMonthOrDays[i]); - expect(actualChineseDate?.solarTermName).toBe(expectedSolarTermNames[i]); + expect(chineseMonthOrDay).toBe(expectedChineseMonthOrDays[index]); + expect(actualChineseDate?.solarTermName).toBe(expectedSolarTermNames[index]); } } }); diff --git a/src/lib/category.ts b/src/lib/category.ts index 6049dee9..f4f2b3b3 100644 --- a/src/lib/category.ts +++ b/src/lib/category.ts @@ -71,7 +71,7 @@ export function localizedPresetCategoriesToTransactionCategoryCreateWithSubCateg return categories; } -export function getSecondaryTransactionMapByName(allCategories: TransactionCategory[]): Record { +export function getSecondaryTransactionMapByName(allCategories?: TransactionCategory[]): Record { const ret: Record = {}; if (!allCategories) { @@ -274,7 +274,7 @@ export function isSubCategoryIdAvailable(categories: TransactionCategory[], cate return false; } -export function getFirstAvailableCategoryId(categories: TransactionCategory[]): string { +export function getFirstAvailableCategoryId(categories?: TransactionCategory[]): string { if (!categories || !categories.length) { return ''; } diff --git a/src/lib/common.ts b/src/lib/common.ts index 52b619fe..02033d61 100644 --- a/src/lib/common.ts +++ b/src/lib/common.ts @@ -431,8 +431,8 @@ export function countSplitItems(str: string | undefined | null, separator: strin const items = str.split(separator); let count = 0; - for (let i = 0; i < items.length; i++) { - if (items[i]) { + for (const item of items) { + if (item) { count++; } } @@ -483,9 +483,13 @@ export function selectInvert(filterItemIds: Record, allItemsMap } export function isPrimaryItemHasSecondaryValue(primaryItem: Record[]>, primarySubItemsField: string, secondaryValueField: string | undefined, secondaryHiddenField: string | undefined, secondaryValue: unknown): boolean { - for (let i = 0; i < primaryItem[primarySubItemsField].length; i++) { - const secondaryItem = primaryItem[primarySubItemsField][i]; + const secondaryItems = primaryItem[primarySubItemsField]; + if (!secondaryItems || secondaryItems.length < 1) { + return false; + } + + for (const secondaryItem of secondaryItems) { if (secondaryHiddenField && secondaryItem[secondaryHiddenField]) { continue; } @@ -500,14 +504,12 @@ export function isPrimaryItemHasSecondaryValue(primaryItem: Record(items: Record[]>[] | Record[]>>, primarySubItemsField: string | undefined, primaryValueField: string | undefined, primaryHiddenField: string | undefined, secondaryValueField: string | undefined, secondaryHiddenField: string | undefined, secondaryValue: T): Record[] | Record[]> | null { +export function getPrimaryValueBySecondaryValue(items: Record[]>[] | Record[]>>, primarySubItemsField: string | undefined, primaryValueField: string | undefined, primaryHiddenField: string | undefined, secondaryValueField: string | undefined, secondaryHiddenField: string | undefined, secondaryValue: T): Record[] | Record[]> | null | undefined { if (primarySubItemsField) { if (isArray(items)) { const arr = items as Record[]>[]; - for (let i = 0; i < arr.length; i++) { - const primaryItem = arr[i]; - + for (const primaryItem of arr) { if (primaryHiddenField && primaryItem[primaryHiddenField]) { continue; } @@ -523,13 +525,7 @@ export function getPrimaryValueBySecondaryValue(items: Record[]>>; - for (const field in obj) { - if (!Object.prototype.hasOwnProperty.call(obj, field)) { - continue; - } - - const primaryItem = obj[field]; - + for (const primaryItem of values(obj)) { if (primaryHiddenField && primaryItem[primaryHiddenField]) { continue; } diff --git a/src/lib/map/leaflet.ts b/src/lib/map/leaflet.ts index cb3c1169..ea316826 100644 --- a/src/lib/map/leaflet.ts +++ b/src/lib/map/leaflet.ts @@ -224,9 +224,7 @@ export class LeafletMapInstance implements MapInstance { private getFinalUrlFormat(urlFormat: string, urlExtraParams: LeafletTileSourceExtraParam[], options: MapInstanceInitOptions) { const params: string[] = []; - for (let i = 0; i < urlExtraParams.length; i++) { - const param = urlExtraParams[i]; - + for (const param of urlExtraParams) { if (param.paramValueType === 'tomtom_key') { params.push(param.paramName + '=' + getTomTomMapAPIKey()); } else if (param.paramValueType === 'tianditu_key') { diff --git a/src/models/account.ts b/src/models/account.ts index 8d94b0bb..a5427104 100644 --- a/src/models/account.ts +++ b/src/models/account.ts @@ -221,7 +221,7 @@ export class Account implements AccountInfoResponse { }; } - public getAccountOrSubAccountId(subAccountId: string): string | null { + public getAccountOrSubAccountId(subAccountId?: string): string | null { if (this.type === AccountType.SingleAccount.type) { return this.id; } else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) { @@ -243,7 +243,7 @@ export class Account implements AccountInfoResponse { } } - public isAccountOrSubAccountHidden(subAccountId: string): boolean { + public isAccountOrSubAccountHidden(subAccountId?: string): boolean { if (this.type === AccountType.SingleAccount.type) { return this.hidden; } else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) { @@ -265,7 +265,7 @@ export class Account implements AccountInfoResponse { } } - public getAccountOrSubAccountComment(subAccountId: string): string | null { + public getAccountOrSubAccountComment(subAccountId?: string): string | null { if (this.type === AccountType.SingleAccount.type) { return this.comment; } else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) { @@ -287,7 +287,7 @@ export class Account implements AccountInfoResponse { } } - public getAccountOrSubAccount(subAccountId: string): Account | null { + public getAccountOrSubAccount(subAccountId?: string): Account | null { if (this.type === AccountType.SingleAccount.type) { return this; } else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) { @@ -309,7 +309,7 @@ export class Account implements AccountInfoResponse { } } - public getSubAccount(subAccountId: string): Account | null { + public getSubAccount(subAccountId?: string): Account | null { if (!this.subAccounts || !this.subAccounts.length) { return null; } @@ -323,7 +323,7 @@ export class Account implements AccountInfoResponse { return null; } - public getSubAccountCurrencies(showHidden: boolean, subAccountId: string): string[] { + public getSubAccountCurrencies(showHidden: boolean, subAccountId?: string): string[] { if (!this.subAccounts || !this.subAccounts.length) { return []; } diff --git a/src/models/transaction.ts b/src/models/transaction.ts index f0847e5b..1adc9576 100644 --- a/src/models/transaction.ts +++ b/src/models/transaction.ts @@ -140,15 +140,15 @@ export class Transaction implements TransactionInfoResponse { } } - public setCategory(category: TransactionCategory): void { + public setCategory(category?: TransactionCategory): void { this._category = category; } - public setSourceAccount(sourceAccount: Account): void { + public setSourceAccount(sourceAccount?: Account): void { this._sourceAccount = sourceAccount; } - public setDestinationAccount(destinationAccount: Account): void { + public setDestinationAccount(destinationAccount?: Account): void { this._destinationAccount = destinationAccount; } diff --git a/src/stores/account.ts b/src/stores/account.ts index 06b66866..2843bb7d 100644 --- a/src/stores/account.ts +++ b/src/stores/account.ts @@ -5,7 +5,7 @@ import { useSettingsStore } from './setting.ts'; import { useUserStore } from './user.ts'; import { useExchangeRatesStore } from './exchangeRates.ts'; -import type { BeforeResolveFunction } from '@/core/base.ts'; +import { type BeforeResolveFunction, itemAndIndex, reversed, entries, values } from '@/core/base.ts'; import type { HiddenAmount, NumberWithSuffix } from '@/core/numeral.ts'; import { AccountType, AccountCategory } from '@/core/account.ts'; import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts'; @@ -36,15 +36,12 @@ export const useAccountsStore = defineStore('accounts', () => { const allPlainAccounts = computed(() => { const allAccountsList: Account[] = []; - for (let i = 0; i < allAccounts.value.length; i++) { - const account = allAccounts.value[i]; - + for (const account of allAccounts.value) { if (account.type === AccountType.SingleAccount.type) { allAccountsList.push(account); } else if (account.type === AccountType.MultiSubAccounts.type) { if (account.subAccounts) { - for (let j = 0; j < account.subAccounts.length; j++) { - const subAccount = account.subAccounts[j]; + for (const subAccount of account.subAccounts) { allAccountsList.push(subAccount); } } @@ -57,17 +54,14 @@ export const useAccountsStore = defineStore('accounts', () => { const allMixedPlainAccounts = computed(() => { const allAccountsList: Account[] = []; - for (let i = 0; i < allAccounts.value.length; i++) { - const account = allAccounts.value[i]; - + for (const account of allAccounts.value) { if (account.type === AccountType.SingleAccount.type) { allAccountsList.push(account); } else if (account.type === AccountType.MultiSubAccounts.type) { allAccountsList.push(account); if (account.subAccounts) { - for (let j = 0; j < account.subAccounts.length; j++) { - const subAccount = account.subAccounts[j]; + for (const subAccount of account.subAccounts) { allAccountsList.push(subAccount); } } @@ -80,9 +74,7 @@ export const useAccountsStore = defineStore('accounts', () => { const allVisiblePlainAccounts = computed(() => { const allVisibleAccounts: Account[] = []; - for (let i = 0; i < allAccounts.value.length; i++) { - const account = allAccounts.value[i]; - + for (const account of allAccounts.value) { if (account.hidden) { continue; } @@ -91,8 +83,7 @@ export const useAccountsStore = defineStore('accounts', () => { allVisibleAccounts.push(account); } else if (account.type === AccountType.MultiSubAccounts.type) { if (account.subAccounts) { - for (let j = 0; j < account.subAccounts.length; j++) { - const subAccount = account.subAccounts[j]; + for (const subAccount of account.subAccounts) { if (subAccount.hidden) { continue; @@ -110,12 +101,8 @@ export const useAccountsStore = defineStore('accounts', () => { const allAvailableAccountsCount = computed(() => { let allAccountCount = 0; - for (const category in allCategorizedAccountsMap.value) { - if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) { - continue; - } - - allAccountCount += allCategorizedAccountsMap.value[category].accounts.length; + for (const categorizedAccounts of values(allCategorizedAccountsMap.value)) { + allAccountCount += categorizedAccounts.accounts.length; } return allAccountCount; @@ -124,15 +111,11 @@ export const useAccountsStore = defineStore('accounts', () => { const allVisibleAccountsCount = computed(() => { let shownAccountCount = 0; - for (const category in allCategorizedAccountsMap.value) { - if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) { - continue; - } + for (const categorizedAccounts of values(allCategorizedAccountsMap.value)) { + const accountList = categorizedAccounts.accounts; - const accountList = allCategorizedAccountsMap.value[category].accounts; - - for (let i = 0; i < accountList.length; i++) { - if (!accountList[i].hidden) { + for (const account of accountList) { + if (!account.hidden) { shownAccountCount++; } } @@ -145,13 +128,11 @@ export const useAccountsStore = defineStore('accounts', () => { allAccounts.value = accounts; allAccountsMap.value = {}; - for (let i = 0; i < accounts.length; i++) { - const account = accounts[i]; + for (const account of accounts) { allAccountsMap.value[account.id] = account; if (account.subAccounts) { - for (let j = 0; j < account.subAccounts.length; j++) { - const subAccount = account.subAccounts[j]; + for (const subAccount of account.subAccounts) { allAccountsMap.value[subAccount.id] = subAccount; } } @@ -160,51 +141,49 @@ export const useAccountsStore = defineStore('accounts', () => { allCategorizedAccountsMap.value = getCategorizedAccountsMap(accounts); } - function addAccountToAccountList(account: Account): void { - const newAccountCategory = AccountCategory.valueOf(account.category); + function addAccountToAccountList(currentAccount: Account): void { + const newAccountCategory = AccountCategory.valueOf(currentAccount.category); let insertIndexToAllList = allAccounts.value.length; if (newAccountCategory) { - for (let i = 0; i < allAccounts.value.length; i++) { - const accountCategory = AccountCategory.valueOf(allAccounts.value[i].category); + for (const [account, index] of itemAndIndex(allAccounts.value)) { + const accountCategory = AccountCategory.valueOf(account.category); if (accountCategory && accountCategory.displayOrder > newAccountCategory.displayOrder) { - insertIndexToAllList = i; + insertIndexToAllList = index; break; } } } - allAccounts.value.splice(insertIndexToAllList, 0, account); + allAccounts.value.splice(insertIndexToAllList, 0, currentAccount); - allAccountsMap.value[account.id] = account; + allAccountsMap.value[currentAccount.id] = currentAccount; - if (account.subAccounts) { - for (let i = 0; i < account.subAccounts.length; i++) { - const subAccount = account.subAccounts[i]; + if (currentAccount.subAccounts) { + for (const subAccount of currentAccount.subAccounts) { allAccountsMap.value[subAccount.id] = subAccount; } } - if (allCategorizedAccountsMap.value[account.category]) { - const accountList = allCategorizedAccountsMap.value[account.category].accounts; - accountList.push(account); + if (allCategorizedAccountsMap.value[currentAccount.category]) { + const accountList = allCategorizedAccountsMap.value[currentAccount.category]!.accounts; + accountList.push(currentAccount); } else { allCategorizedAccountsMap.value = getCategorizedAccountsMap(allAccounts.value); } } function updateAccountToAccountList(oldAccount: Account, newAccount: Account): void { - for (let i = 0; i < allAccounts.value.length; i++) { - if (allAccounts.value[i].id === newAccount.id) { - allAccounts.value.splice(i, 1, newAccount); + for (const [account, index] of itemAndIndex(allAccounts.value)) { + if (account.id === newAccount.id) { + allAccounts.value.splice(index, 1, newAccount); break; } } if (oldAccount.subAccounts) { - for (let i = 0; i < oldAccount.subAccounts.length; i++) { - const subAccount = oldAccount.subAccounts[i]; + for (const subAccount of oldAccount.subAccounts) { if (allAccountsMap.value[subAccount.id]) { delete allAccountsMap.value[subAccount.id]; } @@ -214,18 +193,17 @@ export const useAccountsStore = defineStore('accounts', () => { allAccountsMap.value[newAccount.id] = newAccount; if (newAccount.subAccounts) { - for (let i = 0; i < newAccount.subAccounts.length; i++) { - const subAccount = newAccount.subAccounts[i]; + for (const subAccount of newAccount.subAccounts) { allAccountsMap.value[subAccount.id] = subAccount; } } if (allCategorizedAccountsMap.value[newAccount.category]) { - const accountList = allCategorizedAccountsMap.value[newAccount.category].accounts; + const accountList = allCategorizedAccountsMap.value[newAccount.category]!.accounts; - for (let i = 0; i < accountList.length; i++) { - if (accountList[i].id === newAccount.id) { - accountList.splice(i, 1, newAccount); + for (const [account, index] of itemAndIndex(accountList)) { + if (account.id === newAccount.id) { + accountList.splice(index, 1, newAccount); break; } } @@ -237,12 +215,12 @@ export const useAccountsStore = defineStore('accounts', () => { let toAccount = null; if (allCategorizedAccountsMap.value[account.category]) { - const accountList = allCategorizedAccountsMap.value[account.category].accounts; + const accountList = allCategorizedAccountsMap.value[account.category]!.accounts; if (updateListOrder) { fromAccount = accountList[from]; toAccount = accountList[to]; - accountList.splice(to, 0, accountList.splice(from, 1)[0]); + accountList.splice(to, 0, accountList.splice(from, 1)[0] as Account); } else { fromAccount = accountList[to]; @@ -258,94 +236,93 @@ export const useAccountsStore = defineStore('accounts', () => { let globalFromIndex = -1; let globalToIndex = -1; - for (let i = 0; i < allAccounts.value.length; i++) { - if (allAccounts.value[i].id === fromAccount.id) { - globalFromIndex = i; - } else if (allAccounts.value[i].id === toAccount.id) { - globalToIndex = i; + for (const [account, index] of itemAndIndex(allAccounts.value)) { + if (account.id === fromAccount.id) { + globalFromIndex = index; + } else if (account.id === toAccount.id) { + globalToIndex = index; } } if (globalFromIndex >= 0 && globalToIndex >= 0) { - allAccounts.value.splice(globalToIndex, 0, allAccounts.value.splice(globalFromIndex, 1)[0]); + allAccounts.value.splice(globalToIndex, 0, allAccounts.value.splice(globalFromIndex, 1)[0] as Account); } } } function updateAccountVisibilityInAccountList({ account, hidden }: { account: Account, hidden: boolean }): void { if (allAccountsMap.value[account.id]) { - allAccountsMap.value[account.id].visible = !hidden; + allAccountsMap.value[account.id]!.visible = !hidden; } } - function removeAccountFromAccountList(account: Account): void { - for (let i = 0; i < allAccounts.value.length; i++) { - if (allAccounts.value[i].id === account.id) { - allAccounts.value.splice(i, 1); + function removeAccountFromAccountList(currentAccount: Account): void { + for (const [account, index] of itemAndIndex(allAccounts.value)) { + if (account.id === currentAccount.id) { + allAccounts.value.splice(index, 1); break; } } - if (allAccountsMap.value[account.id] && allAccountsMap.value[account.id].subAccounts) { - const subAccounts = allAccountsMap.value[account.id].subAccounts as Account[]; + if (allAccountsMap.value[currentAccount.id] && allAccountsMap.value[currentAccount.id]!.subAccounts) { + const subAccounts = allAccountsMap.value[currentAccount.id]!.subAccounts as Account[]; - for (let i = 0; i < subAccounts.length; i++) { - const subAccount = subAccounts[i]; + for (const subAccount of subAccounts) { if (allAccountsMap.value[subAccount.id]) { delete allAccountsMap.value[subAccount.id]; } } } - if (allAccountsMap.value[account.id]) { - delete allAccountsMap.value[account.id]; + if (allAccountsMap.value[currentAccount.id]) { + delete allAccountsMap.value[currentAccount.id]; } - if (allCategorizedAccountsMap.value[account.category]) { - const accountList = allCategorizedAccountsMap.value[account.category].accounts; + if (allCategorizedAccountsMap.value[currentAccount.category]) { + const accountList = allCategorizedAccountsMap.value[currentAccount.category]!.accounts; - for (let i = 0; i < accountList.length; i++) { - if (accountList[i].id === account.id) { - accountList.splice(i, 1); + for (const [account, index] of itemAndIndex(accountList)) { + if (account.id === currentAccount.id) { + accountList.splice(index, 1); break; } } } } - function removeSubAccountFromAccountList(subAccount: Account): void { - for (let i = 0; i < allAccounts.value.length; i++) { - if (allAccounts.value[i].type !== AccountType.MultiSubAccounts.type || !allAccounts.value[i].subAccounts) { + function removeSubAccountFromAccountList(currentSubAccount: Account): void { + for (const account of allAccounts.value) { + if (account.type !== AccountType.MultiSubAccounts.type || !account.subAccounts) { continue; } - const subAccounts = allAccounts.value[i].subAccounts as Account[]; + const subAccounts = account.subAccounts as Account[]; - for (let j = 0; j < subAccounts.length; j++) { - if (subAccounts[j].id === subAccount.id) { - subAccounts.splice(j, 1); + for (const [subAccount, index] of itemAndIndex(subAccounts)) { + if (subAccount.id === currentSubAccount.id) { + subAccounts.splice(index, 1); break; } } } - if (allAccountsMap.value[subAccount.id]) { - delete allAccountsMap.value[subAccount.id]; + if (allAccountsMap.value[currentSubAccount.id]) { + delete allAccountsMap.value[currentSubAccount.id]; } - if (allCategorizedAccountsMap.value[subAccount.category]) { - const accountList = allCategorizedAccountsMap.value[subAccount.category].accounts; + if (allCategorizedAccountsMap.value[currentSubAccount.category]) { + const accountList = allCategorizedAccountsMap.value[currentSubAccount.category]!.accounts; - for (let i = 0; i < accountList.length; i++) { - if (accountList[i].type !== AccountType.MultiSubAccounts.type || !accountList[i].subAccounts) { + for (const account of accountList) { + if (account.type !== AccountType.MultiSubAccounts.type || !account.subAccounts) { continue; } - const subAccounts = accountList[i].subAccounts as Account[]; + const subAccounts = account.subAccounts as Account[]; - for (let j = 0; j < subAccounts.length; j++) { - if (subAccounts[j].id === subAccount.id) { - subAccounts.splice(j, 1); + for (const [subAccount, index] of itemAndIndex(subAccounts)) { + if (subAccount.id === currentSubAccount.id) { + subAccounts.splice(index, 1); break; } } @@ -370,24 +347,16 @@ export const useAccountsStore = defineStore('accounts', () => { subAccounts: {} }; - for (const category in allCategorizedAccountsMap.value) { - if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) { + for (const [category, categorizedAccounts] of entries(allCategorizedAccountsMap.value)) { + if (!categorizedAccounts || !categorizedAccounts.accounts) { continue; } - if (!allCategorizedAccountsMap.value[category] || !allCategorizedAccountsMap.value[category].accounts) { - continue; - } - - const accounts = allCategorizedAccountsMap.value[category].accounts; - - for (let i = 0; i < accounts.length; i++) { - const account = accounts[i]; + const accounts = categorizedAccounts.accounts; + for (const account of accounts) { if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) { - for (let j = 0; j < account.subAccounts.length; j++) { - const subAccount = account.subAccounts[j]; - + for (const subAccount of account.subAccounts) { if (showHidden || !subAccount.hidden) { ret.subAccounts[account.id] = subAccount.id; break; @@ -396,7 +365,7 @@ export const useAccountsStore = defineStore('accounts', () => { } if (showHidden || !account.hidden) { - ret.accounts[category] = account.id; + ret.accounts[parseInt(category)] = account.id; break; } } @@ -411,24 +380,16 @@ export const useAccountsStore = defineStore('accounts', () => { subAccounts: {} }; - for (const category in allCategorizedAccountsMap.value) { - if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) { + for (const [category, categorizedAccounts] of entries(allCategorizedAccountsMap.value)) { + if (!categorizedAccounts || !categorizedAccounts.accounts) { continue; } - if (!allCategorizedAccountsMap.value[category] || !allCategorizedAccountsMap.value[category].accounts) { - continue; - } - - const accounts = allCategorizedAccountsMap.value[category].accounts; - - for (let i = accounts.length - 1; i >= 0; i--) { - const account = accounts[i]; + const accounts = categorizedAccounts.accounts; + for (const account of reversed(accounts)) { if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) { - for (let j = account.subAccounts.length - 1; j >= 0; j--) { - const subAccount = account.subAccounts[j]; - + for (const subAccount of reversed(account.subAccounts)) { if (showHidden || !subAccount.hidden) { ret.subAccounts[account.id] = subAccount.id; break; @@ -437,7 +398,7 @@ export const useAccountsStore = defineStore('accounts', () => { } if (showHidden || !account.hidden) { - ret.accounts[category] = account.id; + ret.accounts[parseInt(category)] = account.id; break; } } @@ -454,9 +415,8 @@ export const useAccountsStore = defineStore('accounts', () => { const accountIds = accountId.split(','); let mainAccount = null; - for (let i = 0; i < accountIds.length; i++) { - const id = accountIds[i]; - let account = allAccountsMap.value[id]; + for (const accountId of accountIds) { + let account = allAccountsMap.value[accountId]; if (!account) { return null; @@ -466,7 +426,11 @@ export const useAccountsStore = defineStore('accounts', () => { account = allAccountsMap.value[account.parentId]; } - if (mainAccount !== null) { + if (!account) { + return null; + } + + if (mainAccount) { if (mainAccount.id !== account.id) { return null; } else { @@ -499,11 +463,11 @@ export const useAccountsStore = defineStore('accounts', () => { let netAssets = 0; let hasUnCalculatedAmount = false; - for (let i = 0; i < accountsBalance.length; i++) { - if (accountsBalance[i].currency === userStore.currentUserDefaultCurrency) { - netAssets += accountsBalance[i].balance; + for (const accountBalance of accountsBalance) { + if (accountBalance.currency === userStore.currentUserDefaultCurrency) { + netAssets += accountBalance.balance; } else { - const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, userStore.currentUserDefaultCurrency); + const balance = exchangeRatesStore.getExchangedAmount(accountBalance.balance, accountBalance.currency, userStore.currentUserDefaultCurrency); if (!isNumber(balance)) { hasUnCalculatedAmount = true; @@ -535,11 +499,11 @@ export const useAccountsStore = defineStore('accounts', () => { let totalAssets = 0; let hasUnCalculatedAmount = false; - for (let i = 0; i < accountsBalance.length; i++) { - if (accountsBalance[i].currency === userStore.currentUserDefaultCurrency) { - totalAssets += accountsBalance[i].balance; + for (const accountBalance of accountsBalance) { + if (accountBalance.currency === userStore.currentUserDefaultCurrency) { + totalAssets += accountBalance.balance; } else { - const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, userStore.currentUserDefaultCurrency); + const balance = exchangeRatesStore.getExchangedAmount(accountBalance.balance, accountBalance.currency, userStore.currentUserDefaultCurrency); if (!isNumber(balance)) { hasUnCalculatedAmount = true; @@ -571,11 +535,11 @@ export const useAccountsStore = defineStore('accounts', () => { let totalLiabilities = 0; let hasUnCalculatedAmount = false; - for (let i = 0; i < accountsBalance.length; i++) { - if (accountsBalance[i].currency === userStore.currentUserDefaultCurrency) { - totalLiabilities -= accountsBalance[i].balance; + for (const accountBalance of accountsBalance) { + if (accountBalance.currency === userStore.currentUserDefaultCurrency) { + totalLiabilities -= accountBalance.balance; } else { - const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, userStore.currentUserDefaultCurrency); + const balance = exchangeRatesStore.getExchangedAmount(accountBalance.balance, accountBalance.currency, userStore.currentUserDefaultCurrency); if (!isNumber(balance)) { hasUnCalculatedAmount = true; @@ -605,26 +569,26 @@ export const useAccountsStore = defineStore('accounts', () => { let totalBalance = 0; let hasUnCalculatedAmount = false; - for (let i = 0; i < accountsBalance.length; i++) { - if (accountsBalance[i].currency === userStore.currentUserDefaultCurrency) { - if (accountsBalance[i].isAsset) { - totalBalance += accountsBalance[i].balance; - } else if (accountsBalance[i].isLiability) { - totalBalance -= accountsBalance[i].balance; + for (const accountBalance of accountsBalance) { + if (accountBalance.currency === userStore.currentUserDefaultCurrency) { + if (accountBalance.isAsset) { + totalBalance += accountBalance.balance; + } else if (accountBalance.isLiability) { + totalBalance -= accountBalance.balance; } else { - totalBalance += accountsBalance[i].balance; + totalBalance += accountBalance.balance; } } else { - const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, userStore.currentUserDefaultCurrency); + const balance = exchangeRatesStore.getExchangedAmount(accountBalance.balance, accountBalance.currency, userStore.currentUserDefaultCurrency); if (!isNumber(balance)) { hasUnCalculatedAmount = true; continue; } - if (accountsBalance[i].isAsset) { + if (accountBalance.isAsset) { totalBalance += Math.trunc(balance); - } else if (accountsBalance[i].isLiability) { + } else if (accountBalance.isLiability) { totalBalance -= Math.trunc(balance); } else { totalBalance += Math.trunc(balance); @@ -678,9 +642,7 @@ export const useAccountsStore = defineStore('accounts', () => { const allSubAccountCurrencies: string[] = []; let totalBalance = 0; - for (let i = 0; i < account.subAccounts.length; i++) { - const subAccount = account.subAccounts[i]; - + for (const subAccount of account.subAccounts) { if (!showHidden && subAccount.hidden) { continue; } @@ -699,14 +661,12 @@ export const useAccountsStore = defineStore('accounts', () => { } if (allSubAccountCurrencies.length === 1) { - resultCurrency = allSubAccountCurrencies[0]; + resultCurrency = allSubAccountCurrencies[0] as string; } let hasUnCalculatedAmount = false; - for (let i = 0; i < account.subAccounts.length; i++) { - const subAccount = account.subAccounts[i]; - + for (const subAccount of account.subAccounts) { if (!showHidden && subAccount.hidden) { continue; } @@ -762,17 +722,15 @@ export const useAccountsStore = defineStore('accounts', () => { } function hasAccount(accountCategory: AccountCategory, visibleOnly: boolean): boolean { - if (!allCategorizedAccountsMap.value[accountCategory.type] || - !allCategorizedAccountsMap.value[accountCategory.type].accounts || - !allCategorizedAccountsMap.value[accountCategory.type].accounts.length) { + const categorizedAccounts = allCategorizedAccountsMap.value[accountCategory.type]; + + if (!categorizedAccounts || !categorizedAccounts.accounts || !categorizedAccounts.accounts.length) { return false; } let shownCount = 0; - for (let i = 0; i < allCategorizedAccountsMap.value[accountCategory.type].accounts.length; i++) { - const account = allCategorizedAccountsMap.value[accountCategory.type].accounts[i]; - + for (const account of categorizedAccounts.accounts) { if (!visibleOnly || !account.hidden) { shownCount++; } @@ -786,8 +744,8 @@ export const useAccountsStore = defineStore('accounts', () => { return false; } - for (let i = 0; i < account.subAccounts.length; i++) { - if (showHidden || !account.subAccounts[i].hidden) { + for (const subAccount of account.subAccounts) { + if (showHidden || !subAccount.hidden) { return true; } } @@ -934,8 +892,8 @@ export const useAccountsStore = defineStore('accounts', () => { return new Promise((resolve, reject) => { if (!account || !allCategorizedAccountsMap.value[account.category] || - !allCategorizedAccountsMap.value[account.category].accounts || - !allCategorizedAccountsMap.value[account.category].accounts[to]) { + !allCategorizedAccountsMap.value[account.category]!.accounts || + !allCategorizedAccountsMap.value[account.category]!.accounts[to]) { reject({ message: 'Unable to move account' }); return; } @@ -953,17 +911,11 @@ export const useAccountsStore = defineStore('accounts', () => { function updateAccountDisplayOrders(): Promise { const newDisplayOrders: AccountNewDisplayOrderRequest[] = []; - for (const category in allCategorizedAccountsMap.value) { - if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) { - continue; - } - - const accountList = allCategorizedAccountsMap.value[category].accounts; - - for (let i = 0; i < accountList.length; i++) { + for (const categorizedAccounts of values(allCategorizedAccountsMap.value)) { + for (const [account, index] of itemAndIndex(categorizedAccounts.accounts)) { newDisplayOrders.push({ - id: accountList[i].id, - displayOrder: i + 1 + id: account.id, + displayOrder: index + 1 }); } } diff --git a/src/stores/statistics.ts b/src/stores/statistics.ts index 5394e3b3..d4fe5e44 100644 --- a/src/stores/statistics.ts +++ b/src/stores/statistics.ts @@ -7,6 +7,7 @@ import { useAccountsStore } from './account.ts'; import { useTransactionCategoriesStore } from './transactionCategory.ts'; import { useExchangeRatesStore } from './exchangeRates.ts'; +import { entries, values } from '@/core/base.ts'; import { type TextualYearMonth, type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts'; import { TimezoneTypeForStatistics } from '@/core/timezone.ts'; import { CategoryType } from '@/core/category.ts'; @@ -228,9 +229,7 @@ export const useStatisticsStore = defineStore('statistics', () => { let totalAmount = 0; let totalNonNegativeAmount = 0; - for (let i = 0; i < accountsStore.allPlainAccounts.length; i++) { - const account = accountsStore.allPlainAccounts[i]; - + for (const account of accountsStore.allPlainAccounts) { if (transactionStatisticsFilter.value.chartDataType === ChartDataType.AccountTotalAssets.type) { if (!account.isAsset) { continue; @@ -312,12 +311,7 @@ export const useStatisticsStore = defineStore('statistics', () => { const allStatisticsItems: TransactionCategoricalAnalysisDataItem[] = []; if (combinedData && combinedData.items) { - for (const id in combinedData.items) { - if (!Object.prototype.hasOwnProperty.call(combinedData.items, id)) { - continue; - } - - const dataItem = combinedData.items[id]; + for (const dataItem of values(combinedData.items)) { let percent = 0; if (dataItem.totalAmount > 0) { @@ -361,8 +355,7 @@ export const useStatisticsStore = defineStore('statistics', () => { const finalTrendsData: TransactionStatisticTrendsResponseItemWithInfo[] = []; if (trendsData && trendsData.length) { - for (let i = 0; i < trendsData.length; i++) { - const trendItem = trendsData[i]; + for (const trendItem of trendsData) { const finalTrendItem: TransactionStatisticTrendsResponseItemWithInfo = { year: trendItem.year, month: trendItem.month, @@ -387,16 +380,10 @@ export const useStatisticsStore = defineStore('statistics', () => { const combinedDataMap: Record = {}; - for (let i = 0; i < transactionCategoryTrendsDataWithCategoryAndAccountInfo.value.length; i++) { - const trendItem = transactionCategoryTrendsDataWithCategoryAndAccountInfo.value[i]; + for (const trendItem of transactionCategoryTrendsDataWithCategoryAndAccountInfo.value) { const totalAmountItems = getCategoryTotalAmountItems(trendItem.items, transactionStatisticsFilter.value); - for (const id in totalAmountItems.items) { - if (!Object.prototype.hasOwnProperty.call(totalAmountItems.items, id)) { - continue; - } - - const item = totalAmountItems.items[id]; + for (const [id, item] of entries(totalAmountItems.items)) { let combinedData = combinedDataMap[id]; if (!combinedData) { @@ -426,12 +413,7 @@ export const useStatisticsStore = defineStore('statistics', () => { const totalAmountsTrends: TransactionTrendsAnalysisDataItem[] = []; - for (const id in combinedDataMap) { - if (!Object.prototype.hasOwnProperty.call(combinedDataMap, id)) { - continue; - } - - const trendData = combinedDataMap[id]; + for (const trendData of values(combinedDataMap)) { totalAmountsTrends.push(trendData); } @@ -448,8 +430,7 @@ export const useStatisticsStore = defineStore('statistics', () => { const finalItems: TransactionStatisticResponseItemWithInfo[] = []; const defaultCurrency = userStore.currentUserDefaultCurrency; - for (let i = 0; i < items.length; i++) { - const dataItem = items[i]; + for (const dataItem of items) { const item: TransactionStatisticResponseItemWithInfo = { categoryId: dataItem.categoryId, accountId: dataItem.accountId, @@ -500,9 +481,7 @@ export const useStatisticsStore = defineStore('statistics', () => { let totalAmount = 0; let totalNonNegativeAmount = 0; - for (let i = 0; i < items.length; i++) { - const item = items[i]; - + for (const item of items) { if (!item.primaryAccount || !item.account || !item.primaryCategory || !item.category) { continue; } diff --git a/src/stores/transaction.ts b/src/stores/transaction.ts index ea6d78c7..462ee04c 100644 --- a/src/stores/transaction.ts +++ b/src/stores/transaction.ts @@ -9,7 +9,7 @@ import { useOverviewStore } from './overview.ts'; import { useStatisticsStore } from './statistics.ts'; import { useExchangeRatesStore } from './exchangeRates.ts'; -import type { BeforeResolveFunction } from '@/core/base.ts'; +import { type BeforeResolveFunction, itemAndIndex, entries, keys } from '@/core/base.ts'; import { type TextualYearMonth, DateRange } from '@/core/datetime.ts'; import { CategoryType } from '@/core/category.ts'; import { TransactionType, TransactionTagFilterType } from '@/core/transaction.ts'; @@ -165,8 +165,7 @@ export const useTransactionsStore = defineStore('transactions', () => { let currentMonthListIndex = -1; let currentMonthList: TransactionMonthList | null = null; - for (let i = 0; i < transactionPageWrapper.items.length; i++) { - const item = transactionPageWrapper.items[i]; + for (const [item, index] of itemAndIndex(transactionPageWrapper.items)) { fillTransactionObject(item, currentUtcOffset); const transactionTime = parseDateTimeFromUnixTime(item.time, item.utcOffset, currentUtcOffset); @@ -174,8 +173,8 @@ export const useTransactionsStore = defineStore('transactions', () => { const transactionMonth = transactionTime.getGregorianCalendarMonth(); const transactionYearDashMonth = transactionTime.getGregorianCalendarYearDashMonth(); - if (i === 0 && transactions.value.length > 0) { - const lastMonthList = transactions.value[transactions.value.length - 1]; + if (index === 0 && transactions.value.length > 0) { + const lastMonthList = transactions.value[transactions.value.length - 1] as TransactionMonthList; if (lastMonthList.totalAmount.incompleteExpense || lastMonthList.totalAmount.incompleteIncome) { // calculate the total amount of last month which has incomplete total amount before starting to process a new request @@ -186,7 +185,7 @@ export const useTransactionsStore = defineStore('transactions', () => { if (currentMonthList && currentMonthList.year === transactionYear && currentMonthList.month === transactionMonth) { currentMonthList.items.push(Object.freeze(item)); - if (i === transactionPageWrapper.items.length - 1) { + if (index === transactionPageWrapper.items.length - 1) { // calculate the total amount of current month when processing the last transaction item of this request calculateMonthTotalAmount(currentMonthList, defaultCurrency, transactionsFilter.value.accountIds, true); } @@ -194,9 +193,9 @@ export const useTransactionsStore = defineStore('transactions', () => { } for (let j = currentMonthListIndex + 1; j < transactions.value.length; j++) { - if (transactions.value[j].year === transactionYear && transactions.value[j].month === transactionMonth) { + if (transactions.value[j]!.year === transactionYear && transactions.value[j]!.month === transactionMonth) { currentMonthListIndex = j; - currentMonthList = transactions.value[j]; + currentMonthList = transactions.value[j] as TransactionMonthList; break; } } @@ -223,7 +222,7 @@ export const useTransactionsStore = defineStore('transactions', () => { transactions.value.push(monthList); currentMonthListIndex = transactions.value.length - 1; - currentMonthList = transactions.value[transactions.value.length - 1]; + currentMonthList = transactions.value[transactions.value.length - 1] as TransactionMonthList; } currentMonthList.items.push(Object.freeze(item)); @@ -235,50 +234,48 @@ export const useTransactionsStore = defineStore('transactions', () => { if (nextTimeSequenceId) { transactionsNextTimeId.value = nextTimeSequenceId; } else { - calculateMonthTotalAmount(transactions.value[transactions.value.length - 1], defaultCurrency, transactionsFilter.value.accountIds, false); + calculateMonthTotalAmount(transactions.value[transactions.value.length - 1] as TransactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, false); transactionsNextTimeId.value = -1; } } - function updateTransactionInTransactionList({ transaction, defaultCurrency }: { transaction: Transaction, defaultCurrency: string }): void { + function updateTransactionInTransactionList({ currentTransaction, defaultCurrency }: { currentTransaction: Transaction, defaultCurrency: string }): void { const currentUtcOffset = getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone); - const transactionTime = parseDateTimeFromUnixTime(transaction.time, transaction.utcOffset, currentUtcOffset); + const transactionTime = parseDateTimeFromUnixTime(currentTransaction.time, currentTransaction.utcOffset, currentUtcOffset); const transactionYear = transactionTime.getGregorianCalendarYear(); const transactionMonth = transactionTime.getGregorianCalendarMonth(); - for (let i = 0; i < transactions.value.length; i++) { - const transactionMonthList = transactions.value[i]; - + for (const [transactionMonthList, monthIndex] of itemAndIndex(transactions.value)) { if (!transactionMonthList.items) { continue; } - for (let j = 0; j < transactionMonthList.items.length; j++) { - if (transactionMonthList.items[j].id === transaction.id) { - fillTransactionObject(transaction, currentUtcOffset); + for (const [transaction, transactionIndex] of itemAndIndex(transactionMonthList.items)) { + if (transaction.id === currentTransaction.id) { + fillTransactionObject(currentTransaction, currentUtcOffset); if (transactionYear !== transactionMonthList.year || transactionMonth !== transactionMonthList.month || - transaction.gregorianCalendarDayOfMonth !== transactionMonthList.items[j].gregorianCalendarDayOfMonth) { + currentTransaction.gregorianCalendarDayOfMonth !== transaction.gregorianCalendarDayOfMonth) { transactionListStateInvalid.value = true; return; } - if ((transactionsFilter.value.categoryIds && !allFilterCategoryIds.value[transaction.categoryId]) || - (transactionsFilter.value.accountIds && !allFilterAccountIds.value[transaction.sourceAccountId] && !allFilterAccountIds.value[transaction.destinationAccountId] && - (!transaction.sourceAccount || !allFilterAccountIds.value[transaction.sourceAccount.parentId]) && - (!transaction.destinationAccount || !allFilterAccountIds.value[transaction.destinationAccount.parentId]) + if ((transactionsFilter.value.categoryIds && !allFilterCategoryIds.value[currentTransaction.categoryId]) || + (transactionsFilter.value.accountIds && !allFilterAccountIds.value[currentTransaction.sourceAccountId] && !allFilterAccountIds.value[currentTransaction.destinationAccountId] && + (!currentTransaction.sourceAccount || !allFilterAccountIds.value[currentTransaction.sourceAccount.parentId]) && + (!currentTransaction.destinationAccount || !allFilterAccountIds.value[currentTransaction.destinationAccount.parentId]) ) ) { - transactionMonthList.items.splice(j, 1); + transactionMonthList.items.splice(transactionIndex, 1); } else { - transactionMonthList.items.splice(j, 1, transaction); + transactionMonthList.items.splice(transactionIndex, 1, currentTransaction); } if (transactionMonthList.items.length < 1) { - transactions.value.splice(i, 1); + transactions.value.splice(monthIndex, 1); } else { - calculateMonthTotalAmount(transactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, i >= transactions.value.length - 1 && transactionsNextTimeId.value > 0); + calculateMonthTotalAmount(transactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, monthIndex >= transactions.value.length - 1 && transactionsNextTimeId.value > 0); } return; @@ -287,26 +284,24 @@ export const useTransactionsStore = defineStore('transactions', () => { } } - function removeTransactionFromTransactionList({ transaction, defaultCurrency }: { transaction: TransactionInfoResponse, defaultCurrency: string }): void { - for (let i = 0; i transaction.time) { + transactionMonthList.items[0]!.time < currentTransaction.time || + transactionMonthList.items[transactionMonthList.items.length - 1]!.time > currentTransaction.time) { continue; } - for (let j = 0; j < transactionMonthList.items.length; j++) { - if (transactionMonthList.items[j].id === transaction.id) { - transactionMonthList.items.splice(j, 1); + for (const [transaction, transactionIndex] of itemAndIndex(transactionMonthList.items)) { + if (transaction.id === currentTransaction.id) { + transactionMonthList.items.splice(transactionIndex, 1); } } if (transactionMonthList.items.length < 1) { - transactions.value.splice(i, 1); + transactions.value.splice(monthIndex, 1); } else { - calculateMonthTotalAmount(transactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, i >= transactions.value.length - 1 && transactionsNextTimeId.value > 0); + calculateMonthTotalAmount(transactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, monthIndex >= transactions.value.length - 1 && transactionsNextTimeId.value > 0); } } } @@ -328,16 +323,15 @@ export const useTransactionsStore = defineStore('transactions', () => { if (accountIds && accountIds !== '0') { const allAccountIdsArray = accountIds.split(','); - for (let i = 0; i < allAccountIdsArray.length; i++) { - if (allAccountIdsArray[i]) { - allAccountIdsMap[allAccountIdsArray[i]] = true; + for (const accountId of allAccountIdsArray) { + if (accountId) { + allAccountIdsMap[accountId] = true; totalAccountIdsCount++; } } } - for (let i = 0; i < transactionMonthList.items.length; i++) { - const transaction = transactionMonthList.items[i]; + for (const transaction of transactionMonthList.items) { const transactionDay = isNumber(transaction.gregorianCalendarDayOfMonth) ? transaction.gregorianCalendarDayOfMonth.toString() : '0'; let dailyTotalAmount = dailyTotalAmounts[transactionDay]; @@ -413,21 +407,11 @@ export const useTransactionsStore = defineStore('transactions', () => { transactionMonthList.totalAmount.income = Math.trunc(totalIncome); transactionMonthList.totalAmount.incompleteIncome = incomplete || hasUnCalculatedTotalIncome; - for (const day in transactionMonthList.dailyTotalAmounts) { - if (!Object.prototype.hasOwnProperty.call(transactionMonthList.dailyTotalAmounts, day)) { - continue; - } - + for (const day of keys(transactionMonthList.dailyTotalAmounts)) { delete transactionMonthList.dailyTotalAmounts[day]; } - for (const day in dailyTotalAmounts) { - if (!Object.prototype.hasOwnProperty.call(dailyTotalAmounts, day)) { - continue; - } - - const dailyTotalAmount = dailyTotalAmounts[day]; - + for (const [day, dailyTotalAmount] of entries(dailyTotalAmounts)) { transactionMonthList.dailyTotalAmounts[day] = { expense: Math.trunc(dailyTotalAmount.expense), incompleteExpense: incomplete || dailyTotalAmount.incompleteExpense, @@ -1076,7 +1060,7 @@ export const useTransactionsStore = defineStore('transactions', () => { } } else { updateTransactionInTransactionList({ - transaction: transaction, + currentTransaction: transaction, defaultCurrency: defaultCurrency }); } @@ -1131,13 +1115,13 @@ export const useTransactionsStore = defineStore('transactions', () => { if (beforeResolve) { beforeResolve(() => { removeTransactionFromTransactionList({ - transaction: transaction, + currentTransaction: transaction, defaultCurrency: defaultCurrency }); }); } else { removeTransactionFromTransactionList({ - transaction: transaction, + currentTransaction: transaction, defaultCurrency: defaultCurrency }); } diff --git a/src/stores/transactionCategory.ts b/src/stores/transactionCategory.ts index bf50e864..f7e9cfb1 100644 --- a/src/stores/transactionCategory.ts +++ b/src/stores/transactionCategory.ts @@ -3,6 +3,7 @@ import { defineStore } from 'pinia'; import type { BeforeResolveFunction } from '@/core/base.ts'; +import { itemAndIndex, values } from '@/core/base.ts'; import { CategoryType } from '@/core/category.ts'; import { @@ -53,23 +54,15 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories' allTransactionCategories.value = allCategories; allTransactionCategoriesMap.value = {}; - for (const categoryType in allCategories) { - if (!Object.prototype.hasOwnProperty.call(allCategories, categoryType)) { - continue; - } - - const categories = allCategories[categoryType]; - - for (let i = 0; i < categories.length; i++) { - const category = categories[i]; + for (const categories of values(allCategories)) { + for (const category of categories) { allTransactionCategoriesMap.value[category.id] = category; if (!category.subCategories) { continue; } - for (let j = 0; j < category.subCategories.length; j++) { - const subCategory = category.subCategories[j]; + for (const subCategory of category.subCategories) { allTransactionCategoriesMap.value[subCategory.id] = subCategory; } } @@ -82,7 +75,7 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories' if (!category.parentId || category.parentId === '0') { categoryList = allTransactionCategories.value[category.type]; } else if (allTransactionCategoriesMap.value[category.parentId]) { - categoryList = allTransactionCategoriesMap.value[category.parentId].subCategories; + categoryList = allTransactionCategoriesMap.value[category.parentId]!.subCategories; } if (categoryList) { @@ -92,33 +85,33 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories' allTransactionCategoriesMap.value[category.id] = category; } - function updateCategoryInTransactionCategoryList(category: TransactionCategory, oldCategory: TransactionCategory): boolean { - if (oldCategory && category.parentId !== oldCategory.parentId) { + function updateCategoryInTransactionCategoryList(currentCategory: TransactionCategory, oldCategory?: TransactionCategory): boolean { + if (oldCategory && currentCategory.parentId !== oldCategory.parentId) { return false; } let categoryList: TransactionCategory[] | undefined = undefined; - if (!category.parentId || category.parentId === '0') { - categoryList = allTransactionCategories.value[category.type]; - } else if (allTransactionCategoriesMap.value[category.parentId]) { - categoryList = allTransactionCategoriesMap.value[category.parentId].subCategories; + if (!currentCategory.parentId || currentCategory.parentId === '0') { + categoryList = allTransactionCategories.value[currentCategory.type]; + } else if (allTransactionCategoriesMap.value[currentCategory.parentId]) { + categoryList = allTransactionCategoriesMap.value[currentCategory.parentId]!.subCategories; } if (categoryList) { - for (let i = 0; i < categoryList.length; i++) { - if (categoryList[i].id === category.id) { - if (!category.parentId || category.parentId === '0') { - category.subCategories = categoryList[i].subCategories; + for (const [category, index] of itemAndIndex(categoryList)) { + if (category.id === currentCategory.id) { + if (!currentCategory.parentId || currentCategory.parentId === '0') { + currentCategory.subCategories = category.subCategories; } - categoryList.splice(i, 1, category); + categoryList.splice(index, 1, currentCategory); break; } } } - allTransactionCategoriesMap.value[category.id] = category; + allTransactionCategoriesMap.value[currentCategory.id] = currentCategory; return true; } @@ -128,44 +121,43 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories' if (!category.parentId || category.parentId === '0') { categoryList = allTransactionCategories.value[category.type]; } else if (allTransactionCategoriesMap.value[category.parentId]) { - categoryList = allTransactionCategoriesMap.value[category.parentId].subCategories; + categoryList = allTransactionCategoriesMap.value[category.parentId]!.subCategories; } if (categoryList) { - categoryList.splice(to, 0, categoryList.splice(from, 1)[0]); + categoryList.splice(to, 0, categoryList.splice(from, 1)[0] as TransactionCategory); } } function updateCategoryVisibilityInTransactionCategoryList({ category, hidden }: { category: TransactionCategory, hidden: boolean }): void { if (allTransactionCategoriesMap.value[category.id]) { - allTransactionCategoriesMap.value[category.id].visible = !hidden; + allTransactionCategoriesMap.value[category.id]!.visible = !hidden; } } - function removeCategoryFromTransactionCategoryList(category: TransactionCategory): void { + function removeCategoryFromTransactionCategoryList(currentCategory: TransactionCategory): void { let categoryList: TransactionCategory[] | undefined = undefined; - if (!category.parentId || category.parentId === '0') { - categoryList = allTransactionCategories.value[category.type]; - } else if (allTransactionCategoriesMap.value[category.parentId]) { - categoryList = allTransactionCategoriesMap.value[category.parentId].subCategories; + if (!currentCategory.parentId || currentCategory.parentId === '0') { + categoryList = allTransactionCategories.value[currentCategory.type]; + } else if (allTransactionCategoriesMap.value[currentCategory.parentId]) { + categoryList = allTransactionCategoriesMap.value[currentCategory.parentId]!.subCategories; } if (categoryList) { - for (let i = 0; i < categoryList.length; i++) { - if (categoryList[i].id === category.id) { - categoryList.splice(i, 1); + for (const [category, index] of itemAndIndex(categoryList)) { + if (category.id === currentCategory.id) { + categoryList.splice(index, 1); break; } } } - if (allTransactionCategoriesMap.value[category.id] && allTransactionCategoriesMap.value[category.id].subCategories) { - const subCategoryList = allTransactionCategoriesMap.value[category.id].subCategories; + if (allTransactionCategoriesMap.value[currentCategory.id] && allTransactionCategoriesMap.value[currentCategory.id]!.subCategories) { + const subCategoryList = allTransactionCategoriesMap.value[currentCategory.id]!.subCategories; if (subCategoryList) { - for (let i = 0; i < subCategoryList.length; i++) { - const subCategory = subCategoryList[i]; + for (const subCategory of subCategoryList) { if (allTransactionCategoriesMap.value[subCategory.id]) { delete allTransactionCategoriesMap.value[subCategory.id]; } @@ -173,8 +165,8 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories' } } - if (allTransactionCategoriesMap.value[category.id]) { - delete allTransactionCategoriesMap.value[category.id]; + if (allTransactionCategoriesMap.value[currentCategory.id]) { + delete allTransactionCategoriesMap.value[currentCategory.id]; } } @@ -403,12 +395,12 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories' if (!category.parentId || category.parentId === '0') { if (!allTransactionCategories.value[category.type] || - !allTransactionCategories.value[category.type][to]) { + !allTransactionCategories.value[category.type]![to]) { reject({ message: 'Unable to move category' }); return; } } else { - const subCategoryList = allTransactionCategoriesMap.value[category.parentId].subCategories; + const subCategoryList = allTransactionCategoriesMap.value[category.parentId]?.subCategories; if (!subCategoryList || !subCategoryList[to]) { reject({ message: 'Unable to move category' }); @@ -438,10 +430,10 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories' } if (categoryList) { - for (let i = 0; i < categoryList.length; i++) { + for (const [category, index] of itemAndIndex(categoryList)) { newDisplayOrders.push({ - id: categoryList[i].id, - displayOrder: i + 1 + id: category.id, + displayOrder: index + 1 }); } } diff --git a/src/stores/transactionTemplate.ts b/src/stores/transactionTemplate.ts index d89f46d3..e7a9ae9e 100644 --- a/src/stores/transactionTemplate.ts +++ b/src/stores/transactionTemplate.ts @@ -1,7 +1,7 @@ import { ref, computed } from 'vue'; import { defineStore } from 'pinia'; -import type { BeforeResolveFunction } from '@/core/base.ts'; +import { type BeforeResolveFunction, itemAndIndex, entries } from '@/core/base.ts'; import { TransactionType } from '@/core/transaction.ts'; @@ -24,23 +24,16 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates', const allVisibleTemplates = computed>(() => { const allVisibleTemplates: Record = {}; - for (const templateType in allTransactionTemplates.value) { - if (!Object.prototype.hasOwnProperty.call(allTransactionTemplates.value, templateType)) { - continue; - } - - const allTemplates = allTransactionTemplates.value[templateType]; + for (const [templateType, allTemplates] of entries(allTransactionTemplates.value)) { const visibleTemplates: TransactionTemplate[] = []; - for (let i = 0; i < allTemplates.length; i++) { - const template = allTemplates[i]; - + for (const template of allTemplates) { if (!template.hidden) { visibleTemplates.push(template); } } - allVisibleTemplates[templateType] = visibleTemplates; + allVisibleTemplates[parseInt(templateType)] = visibleTemplates; } return allVisibleTemplates; @@ -49,12 +42,8 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates', const allAvailableTemplatesCount = computed>(() => { const allAvailableTemplateCounts: Record = {}; - for (const templateType in allTransactionTemplates.value) { - if (!Object.prototype.hasOwnProperty.call(allTransactionTemplates.value, templateType)) { - continue; - } - - allAvailableTemplateCounts[templateType] = allTransactionTemplates.value[templateType].length; + for (const [templateType, allTemplates] of entries(allTransactionTemplates.value)) { + allAvailableTemplateCounts[parseInt(templateType)] = allTemplates.length; } return allAvailableTemplateCounts; @@ -63,12 +52,8 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates', const allVisibleTemplatesCount = computed>(() => { const allVisibleTemplateCounts: Record = {}; - for (const templateType in allVisibleTemplates.value) { - if (!Object.prototype.hasOwnProperty.call(allVisibleTemplates.value, templateType)) { - continue; - } - - allVisibleTemplateCounts[templateType] = allVisibleTemplates.value[templateType].length; + for (const [templateType, allTemplates] of entries(allVisibleTemplates.value)) { + allVisibleTemplateCounts[parseInt(templateType)] = allTemplates.length; } return allVisibleTemplateCounts; @@ -78,8 +63,7 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates', allTransactionTemplates.value[templateType] = templates; allTransactionTemplatesMap.value[templateType] = {}; - for (let i = 0; i < templates.length; i++) { - const template = templates[i]; + for (const template of templates) { allTransactionTemplatesMap.value[templateType][template.id] = template; } } @@ -102,9 +86,9 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates', const templateMap = allTransactionTemplatesMap.value[templateType]; if (isArray(templates)) { - for (let i = 0; i < templates.length; i++) { - if (templates[i].id === template.id) { - templates.splice(i, 1, template); + for (const [template, index] of itemAndIndex(templates)) { + if (template.id === template.id) { + templates.splice(index, 1, template); break; } } @@ -119,7 +103,7 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates', const templates = allTransactionTemplates.value[templateType]; if (isArray(templates)) { - templates.splice(to, 0, templates.splice(from, 1)[0]); + templates.splice(to, 0, templates.splice(from, 1)[0] as TransactionTemplate); } } @@ -128,27 +112,27 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates', if (isObject(templateMap)) { if (templateMap[template.id]) { - templateMap[template.id].hidden = hidden; + templateMap[template.id]!.hidden = hidden; } } } - function removeTemplateFromTransactionTemplateList(templateType: number, template: TransactionTemplate): void { + function removeTemplateFromTransactionTemplateList(templateType: number, currentTemplate: TransactionTemplate): void { const templates = allTransactionTemplates.value[templateType]; const templateMap = allTransactionTemplatesMap.value[templateType]; if (isArray(templates)) { - for (let i = 0; i < templates.length; i++) { - if (templates[i].id === template.id) { - templates.splice(i, 1); + for (const [template, index] of itemAndIndex(templates)) { + if (template.id === currentTemplate.id) { + templates.splice(index, 1); break; } } } if (isObject(templateMap)) { - if (templateMap[template.id]) { - delete templateMap[template.id]; + if (templateMap[currentTemplate.id]) { + delete templateMap[currentTemplate.id]; } } } @@ -298,21 +282,21 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates', function changeTemplateDisplayOrder({ templateType, templateId, from, to }: { templateType: number, templateId: string, from: number, to: number }): Promise { return new Promise((resolve, reject) => { - let template: TransactionTemplate | null = null; + let currentTemplate: TransactionTemplate | null = null; if (!isArray(allTransactionTemplates.value[templateType])) { reject({ message: 'Unable to move template' }); return; } - for (let i = 0; i < allTransactionTemplates.value[templateType].length; i++) { - if (allTransactionTemplates.value[templateType][i].id === templateId) { - template = allTransactionTemplates.value[templateType][i]; + for (const template of allTransactionTemplates.value[templateType]) { + if (template.id === templateId) { + currentTemplate = template; break; } } - if (!template || !allTransactionTemplates.value[templateType][to]) { + if (!currentTemplate || !allTransactionTemplates.value[templateType][to]) { reject({ message: 'Unable to move template' }); return; } @@ -331,10 +315,10 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates', const newDisplayOrders: TransactionTemplateNewDisplayOrderRequest[] = []; if (isArray(allTransactionTemplates.value[templateType])) { - for (let i = 0; i < allTransactionTemplates.value[templateType].length; i++) { + for (const [template, index] of itemAndIndex(allTransactionTemplates.value[templateType])) { newDisplayOrders.push({ - id: allTransactionTemplates.value[templateType][i].id, - displayOrder: i + 1 + id: template.id, + displayOrder: index + 1 }); } } diff --git a/src/views/base/settings/AppCloudSyncPageBase.ts b/src/views/base/settings/AppCloudSyncPageBase.ts index 02469b3f..49f59023 100644 --- a/src/views/base/settings/AppCloudSyncPageBase.ts +++ b/src/views/base/settings/AppCloudSyncPageBase.ts @@ -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; } diff --git a/src/views/desktop/accounts/ListPage.vue b/src/views/desktop/accounts/ListPage.vue index c3416363..ef216153 100644 --- a/src/views/desktop/accounts/ListPage.vue +++ b/src/views/desktop/accounts/ListPage.vue @@ -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" >