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

This commit is contained in:
MaysWind
2025-09-09 23:48:42 +08:00
parent c75a902d84
commit 34c5a1750e
50 changed files with 368 additions and 460 deletions
+9 -5
View File
@@ -40,11 +40,13 @@ export function useNumberInputBase(props: NumberInputProps, emit: NumberInputEmi
let finalValue = '';
for (let i = 0; i < value.length; i++) {
if (!NumeralSystem.WesternArabicNumerals.isDigit(value[i]) && !numeralSystem.value.isDigit(value[i]) && value[i] !== '-' && value[i] !== decimalSeparator) {
const ch = value.charAt(i);
if (!NumeralSystem.WesternArabicNumerals.isDigit(ch) && !numeralSystem.value.isDigit(ch) && ch !== '-' && ch !== decimalSeparator) {
break;
}
finalValue += value[i];
finalValue += ch;
}
finalValue = numeralSystem.value.replaceLocalizedDigitsToWesternArabicDigits(finalValue);
@@ -104,14 +106,16 @@ export function useNumberInputBase(props: NumberInputProps, emit: NumberInputEmi
const decimalSeparator = getCurrentDecimalSeparator();
if (newValue[0] === '-' || newValue[0] === decimalSeparator) {
actualNumeralSystem = NumeralSystem.detect(newValue[1]);
actualNumeralSystem = NumeralSystem.detect(newValue.charAt(1));
} else {
actualNumeralSystem = NumeralSystem.detect(newValue[0]);
actualNumeralSystem = NumeralSystem.detect(newValue.charAt(0));
}
if (actualNumeralSystem && (actualNumeralSystem.type === NumeralSystem.WesternArabicNumerals.type || actualNumeralSystem.type === numeralSystem.value.type)) {
for (let i = 0; i < newValue.length; i++) {
if (!NumeralSystem.WesternArabicNumerals.isDigit(newValue[i]) && !numeralSystem.value.isDigit(newValue[i]) && newValue[i] !== '-' && newValue[i] !== decimalSeparator) {
const ch = newValue.charAt(i);
if (!NumeralSystem.WesternArabicNumerals.isDigit(ch) && !numeralSystem.value.isDigit(ch) && ch !== '-' && ch !== decimalSeparator) {
break;
}
+2 -4
View File
@@ -44,8 +44,7 @@ export function usePieChartBase(props: CommonPieChartProps) {
const validItems = computed<CommonPieChartDataItem[]>(() => {
let totalValidValue = 0;
for (let i = 0; i < props.items.length; i++) {
const item = props.items[i];
for (const item of props.items) {
const value = item[props.valueField];
if (isNumber(value) && value > 0 && (!props.hiddenField || !item[props.hiddenField])) {
@@ -55,8 +54,7 @@ export function usePieChartBase(props: CommonPieChartProps) {
const validItems: CommonPieChartDataItem[] = [];
for (let i = 0; i < props.items.length; i++) {
const item = props.items[i];
for (const item of props.items) {
const value = item[props.valueField];
const percent = props.percentField ? item[props.percentField] : -1;
@@ -44,9 +44,9 @@ export function useScheduleFrequencySelectionBase() {
const values = value.split(',');
const ret: number[] = [];
for (let i = 0; i < values.length; i++) {
if (values[i]) {
ret.push(parseInt(values[i]));
for (const value of values) {
if (value) {
ret.push(parseInt(value));
}
}
+30 -22
View File
@@ -1,15 +1,15 @@
<template>
<div class="pin-codes-input" :style="`grid-template-columns: repeat(${length}, minmax(0, 1fr))`">
<div class="pin-code-input pin-code-input-outline"
:class="{ 'pin-code-input-focued': codes[index].focused }" :key="index"
:class="{ 'pin-code-input-focued': codes[index]!.focused }" :key="index"
v-for="(_, index) in codes">
<input ref="pin-code-input" min="0" maxlength="1" pattern="[0-9]*"
:value="codes[index].value"
:type="codes[index].inputType"
:value="codes[index]!.value"
:type="codes[index]!.inputType"
:disabled="disabled ? true : undefined"
:autofocus="autofocus && index === 0 ? true : undefined"
@focus="codes[index].focused = true"
@blur="codes[index].focused = false"
@focus="codes[index]!.focused = true"
@blur="codes[index]!.focused = false"
@keydown="onKeydown(index, $event)"
@paste="onPaste(index, $event)"
@change="onInput(index, $event)"
@@ -57,9 +57,9 @@ const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType(
const finalPinCode = computed<string>(() => {
let ret = '';
for (let i = 0; i < codes.value.length; i++) {
if (codes.value[i].value) {
ret += codes.value[i].value;
for (const code of codes.value) {
if (code.value) {
ret += code.value;
} else {
break;
}
@@ -80,7 +80,7 @@ function init(length: number, value: string): void {
};
if (value && value[i]) {
code.value = value[i];
code.value = value.charAt(i);
if (props.secure) {
code.inputType = 'password';
@@ -95,12 +95,14 @@ function autoFillText(index: number, text: string): void {
let lastIndex = index;
for (let i = index, j = 0; i < codes.value.length && j < text.length; i++, j++) {
if (text[j] < '0' || text[j] > '9') {
codes.value[i].value = '';
const ch = text.charAt(j);
if (ch < '0' || ch > '9') {
codes.value[i]!.value = '';
break;
}
codes.value[i].value = text[j];
codes.value[i]!.value = ch;
setInputType(i);
lastIndex = i;
}
@@ -117,23 +119,29 @@ function setInputType(index: number): void {
return;
}
if (!codes.value[index].value) {
codes.value[index].inputType = 'tel';
const code = codes.value[index];
if (!code) {
return;
}
if (codes.value[index].inputTimer) {
if (!code.value) {
code.inputType = 'tel';
return;
}
codes.value[index].inputTimer = setTimeout(() => {
if (codes.value[index].value) {
codes.value[index].inputType = 'password';
if (code.inputTimer) {
return;
}
code.inputTimer = setTimeout(() => {
if (code.value) {
code.inputType = 'password';
} else {
codes.value[index].inputType = 'tel';
code.inputType = 'tel';
}
codes.value[index].inputTimer = null;
code.inputTimer = null;
}, 300);
}
@@ -205,7 +213,7 @@ function onKeydown(index: number, event: KeyboardEvent): void {
if (event.key === 'Backspace' || event.key === 'Delete' || event.key === 'Del') {
for (let i = index; i < codes.value.length; i++) {
codes.value[i].value = '';
codes.value[i]!.value = '';
setInputType(i);
}
@@ -227,7 +235,7 @@ function onKeydown(index: number, event: KeyboardEvent): void {
}
if (digit) {
codes.value[index].value = digit;
codes.value[index]!.value = digit;
setInputType(index);
setNextFocus(index);
@@ -91,7 +91,7 @@ const alternateDates = computed<Record<TextualYearMonthDay, string> | undefined>
return undefined;
}
const allDates: CalendarAlternateDate[] | undefined = getCalendarAlternateDates({ year: parseInt(yearMonthDay[0]), month1base: parseInt(yearMonthDay[1]) })
const allDates: CalendarAlternateDate[] | undefined = getCalendarAlternateDates({ year: parseInt(yearMonthDay[0] as string), month1base: parseInt(yearMonthDay[1] as string) })
if (!allDates) {
return undefined;
+6 -4
View File
@@ -338,18 +338,20 @@ watch(currentValue, (newValue) => {
const decimalSeparator = getCurrentDecimalSeparator();
if (newValue[0] === '-' || newValue[0] === decimalSeparator) {
actualNumeralSystem = NumeralSystem.detect(newValue[1]);
actualNumeralSystem = NumeralSystem.detect(newValue.charAt(1));
} else {
actualNumeralSystem = NumeralSystem.detect(newValue[0]);
actualNumeralSystem = NumeralSystem.detect(newValue.charAt(0));
}
if (actualNumeralSystem && (actualNumeralSystem.type === NumeralSystem.WesternArabicNumerals.type || actualNumeralSystem.type === numeralSystem.value.type)) {
for (let i = 0; i < newValue.length; i++) {
if (!NumeralSystem.WesternArabicNumerals.isDigit(newValue[i]) && !numeralSystem.value.isDigit(newValue[i]) && newValue[i] !== '-' && newValue[i] !== decimalSeparator) {
const ch = newValue.charAt(i);
if (!NumeralSystem.WesternArabicNumerals.isDigit(ch) && !numeralSystem.value.isDigit(ch) && ch !== '-' && ch !== decimalSeparator) {
break;
}
finalValue += newValue[i];
finalValue += ch;
}
finalValue = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(finalValue);
+2 -6
View File
@@ -52,7 +52,7 @@ import { ref, computed } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import type { NameNumeralValue } from '@/core/base.ts';
import { type NameNumeralValue, keys } from '@/core/base.ts';
import type { NumeralSystem } from '@/core/numeral.ts';
import type { ComponentDensity } from '@/lib/ui/desktop.ts';
@@ -94,11 +94,7 @@ const currentPage = computed<number>({
if (value && value >= 1 && value <= props.totalPageCount) {
emit('update:modelValue', value);
for (const key in showMenus.value) {
if (!Object.prototype.hasOwnProperty.call(showMenus.value, key)) {
continue;
}
for (const key of keys(showMenus.value)) {
showMenus.value[key] = false;
}
}
+9 -16
View File
@@ -13,6 +13,7 @@ import type { CallbackDataParams } from 'echarts/types/dist/shared';
import { useI18n } from '@/locales/helpers.ts';
import { type CommonPieChartDataItem, type CommonPieChartProps, usePieChartBase } from '@/components/base/PieChartBase.ts'
import { itemAndIndex } from '@/core/base.ts';
import type { ColorStyleValue } from '@/core/color.ts';
import { ThemeType } from '@/core/theme.ts';
@@ -41,8 +42,7 @@ const isDarkMode = computed<boolean>(() => theme.global.name.value === ThemeType
const itemsMap = computed<Record<string, Record<string, unknown>>>(() => {
const map: Record<string, Record<string, unknown>> = {};
for (let i = 0; i < props.items.length; i++) {
const item = props.items[i];
for (const item of props.items) {
let id = '';
if (props.idField && item[props.idField]) {
@@ -60,8 +60,7 @@ const itemsMap = computed<Record<string, Record<string, unknown>>>(() => {
const seriesData = computed<DesktopPieChartDataItem[]>(() => {
const ret: DesktopPieChartDataItem[] = [];
for (let i = 0; i < validItems.value.length; i++) {
const item = validItems.value[i];
for (const item of validItems.value) {
ret.push({
...item,
itemStyle: {
@@ -75,9 +74,7 @@ const seriesData = computed<DesktopPieChartDataItem[]>(() => {
});
const hasUnselectedItem = computed<boolean>(() => {
for (let i = 0; i < validItems.value.length; i++) {
const item = validItems.value[i];
for (const item of validItems.value) {
if (selectedLegends.value && !selectedLegends.value[item.id]) {
return true;
}
@@ -91,9 +88,7 @@ const firstItemAndHalfCurrentItemTotalPercent = computed<number>(() => {
let firstValue = null;
let firstToCurrentTotalValue = 0;
for (let i = 0; i < validItems.value.length; i++) {
const item = validItems.value[i];
for (const [item, index] of itemAndIndex(validItems.value)) {
if (selectedLegends.value && !selectedLegends.value[item.id]) {
continue;
}
@@ -103,9 +98,9 @@ const firstItemAndHalfCurrentItemTotalPercent = computed<number>(() => {
}
if (firstValue !== null) {
if (i < selectedIndex.value) {
if (index < selectedIndex.value) {
firstToCurrentTotalValue += item.value;
} else if (i === selectedIndex.value) {
} else if (index === selectedIndex.value) {
firstToCurrentTotalValue += item.value / 2;
}
}
@@ -241,11 +236,9 @@ function onLegendSelectChanged(e: { selected: Record<string, boolean> }): void {
if (!selectedItem || !selectedLegends.value[selectedItem.id]) {
let newSelectedIndex = 0;
for (let i = 0; i < validItems.value.length; i++) {
const item = validItems.value[i];
for (const [item, index] of itemAndIndex(validItems.value)) {
if (selectedLegends.value[item.id]) {
newSelectedIndex = i;
newSelectedIndex = index;
break;
}
}
@@ -138,9 +138,9 @@ function updateFrequencyValue(value: number, selected: boolean | null): void {
const currentFrequencyValues = frequencyValue.value;
const newFrequencyValues: number[] = [];
for (let i = 0; i < currentFrequencyValues.length; i++) {
if (currentFrequencyValues[i] !== value || selected) {
newFrequencyValues.push(currentFrequencyValues[i]);
for (const currentFrequencyValue of currentFrequencyValues) {
if (currentFrequencyValue !== value || selected) {
newFrequencyValues.push(currentFrequencyValue);
}
}
+4 -3
View File
@@ -48,6 +48,7 @@ import { computed } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { itemAndIndex } from '@/core/base.ts';
import { NumeralSystem } from '@/core/numeral.ts';
export interface StepBarItem {
@@ -87,9 +88,9 @@ function isStepActive(step: StepBarItem): boolean {
}
function isStepCompleted(stepIndex: number): boolean {
for (let i = 0; i < props.steps.length; i++) {
if (props.steps[i].name === props.currentStep) {
return stepIndex < i;
for (const [step, index] of itemAndIndex(props.steps)) {
if (step.name === props.currentStep) {
return stepIndex < index;
}
}
+3 -3
View File
@@ -50,7 +50,7 @@
<span class="numpad-button-text numpad-button-text-normal">{{ decimalSeparator }}</span>
</f7-button>
<f7-button class="numpad-button numpad-button-num" v-if="!supportDecimalSeparator" @click="inputDoubleNum(0)">
<span class="numpad-button-text numpad-button-text-normal">{{ digits[0] + digits[0] }}</span>
<span class="numpad-button-text numpad-button-text-normal">{{ `${digits[0]}${digits[0]}` }}</span>
</f7-button>
<f7-button class="numpad-button numpad-button-num" @click="inputNum(0)">
<span class="numpad-button-text numpad-button-text-normal">{{ digits[0] }}</span>
@@ -114,11 +114,11 @@ const digits = computed<string[]>(() => getAllLocalizedDigits());
const decimalSeparator = computed<string>(() => getCurrentDecimalSeparator());
const supportDecimalSeparator = computed<boolean>(() => {
if (!props.currency || !ALL_CURRENCIES[props.currency] || !isNumber(ALL_CURRENCIES[props.currency].fraction)) {
if (!props.currency || !ALL_CURRENCIES[props.currency] || !isNumber(ALL_CURRENCIES[props.currency]!.fraction)) {
return true;
}
return (ALL_CURRENCIES[props.currency].fraction as number) > 0;
return (ALL_CURRENCIES[props.currency]!.fraction as number) > 0;
});
const currentDisplay = computed<string>(() => {
+5 -7
View File
@@ -105,8 +105,8 @@ const circumference: number = diameter * Math.PI;
const totalValidValue = computed<number>(() => {
let totalValidValue = 0;
for (let i = 0; i < validItems.value.length; i++) {
totalValidValue += validItems.value[i].value;
for (const item of validItems.value) {
totalValidValue += item.value;
}
return totalValidValue;
@@ -120,7 +120,7 @@ const itemCommonDashOffset = computed<number>(() => {
let offset = 0;
for (let i = 0; i < Math.min(selectedIndex.value + 1, validItems.value.length); i++) {
const item = validItems.value[i];
const item = validItems.value[i] as CommonPieChartDataItem;
if (item.actualPercent > 0) {
if (i === selectedIndex.value) {
@@ -154,9 +154,7 @@ function getItemStrokeDash(item: CommonPieChartDataItem): string {
function getItemDashOffset(item: CommonPieChartDataItem, items: CommonPieChartDataItem[], offset?: number): number {
let allPreviousPercent = 0;
for (let i = 0; i < items.length; i++) {
const curItem = items[i];
for (const curItem of items) {
if (curItem === item) {
break;
}
@@ -189,7 +187,7 @@ const selectedItem = computed<CommonPieChartDataItem | null>(() => {
index = 0;
}
return validItems.value[index];
return validItems.value[index] ?? null;
});
function switchSelectedIndex(index: number): void {
+1 -1
View File
@@ -1284,5 +1284,5 @@ export const ALL_CURRENCIES: Record<string, CurrencyInfo> = {
};
export const DEFAULT_CURRENCY_SYMBOL: string = '¤';
export const DEFAULT_CURRENCY_CODE: string = ALL_CURRENCIES['USD'].code;
export const DEFAULT_CURRENCY_CODE: string = (ALL_CURRENCIES['USD'] as CurrencyInfo).code;
export const PARENT_ACCOUNT_CURRENCY_PLACEHOLDER: string = '---';
+2 -2
View File
@@ -161,7 +161,7 @@ export const ALL_ACCOUNT_ICONS: Record<string, IconInfo> = {
}
};
export const DEFAULT_ACCOUNT_ICON = ALL_ACCOUNT_ICONS[DEFAULT_ACCOUNT_ICON_ID];
export const DEFAULT_ACCOUNT_ICON: IconInfo = ALL_ACCOUNT_ICONS[DEFAULT_ACCOUNT_ICON_ID] as IconInfo;
export const DEFAULT_CATEGORY_ICON_ID = '1';
export const AUTOMATICALLY_CREATED_CATEGORY_ICON_ID = '561';
@@ -837,4 +837,4 @@ export const ALL_CATEGORY_ICONS: Record<string, IconInfo> = {
}
};
export const DEFAULT_CATEGORY_ICON = ALL_CATEGORY_ICONS[DEFAULT_CATEGORY_ICON_ID];
export const DEFAULT_CATEGORY_ICON: IconInfo = ALL_CATEGORY_ICONS[DEFAULT_CATEGORY_ICON_ID] as IconInfo;
+62
View File
@@ -3,6 +3,68 @@ export type PartialRecord<K extends keyof any, T> = {
[P in K]?: T;
}
export function* itemAndIndex<T>(arr: T[]): Iterable<[T, number]> {
for (let i = 0; i < arr.length; i++) {
yield [arr[i], i] as [T, number];
}
}
export function* reversed<T>(arr: T[]): Iterable<T> {
for (let i = arr.length - 1; i >= 0; i--) {
yield arr[i] as T;
}
}
export function* reversedItemAndIndex<T>(arr: T[]): Iterable<[T, number]> {
for (let i = arr.length - 1; i >= 0; i--) {
yield [arr[i], i] as [T, number];
}
}
export function* entries<K extends string | number | symbol, V>(obj: Record<K, V>): Iterable<[K, V]> {
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
}
yield [key, obj[key]] as [K, V];
}
}
export function* keys<K extends string | number | symbol, V>(obj: Record<K, V>): Iterable<K> {
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
}
yield key as K;
}
}
export function* keysIfValueEquals<K extends string | number | symbol, V>(obj: Record<K, V>, value: V): Iterable<K> {
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
}
if (obj[key] !== value) {
continue;
}
yield key as K;
}
}
export function* values<K extends string | number | symbol, V>(obj: Record<K, V>): Iterable<V> {
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
}
yield obj[key] as V;
}
}
export interface NameValue {
readonly name: string;
readonly value: string;
+3 -3
View File
@@ -69,8 +69,8 @@ export class FiscalYearStart {
return undefined;
}
const month = parseInt(parts[0], 10);
const day = parseInt(parts[1], 10);
const month = parseInt(parts[0] as string, 10);
const day = parseInt(parts[1] as string, 10);
return FiscalYearStart.of(month, day);
}
@@ -87,7 +87,7 @@ export class FiscalYearStart {
}
private static isValidFiscalYearMonthDay(month: number, day: number): boolean {
return 1 <= month && month <= 12 && 1 <= day && day <= FiscalYearStart.MONTH_MAX_DAYS[month - 1];
return 1 <= month && month <= 12 && 1 <= day && day <= (FiscalYearStart.MONTH_MAX_DAYS[month - 1] as number);
}
}
+7 -7
View File
@@ -96,7 +96,7 @@ export class NumeralSystem implements TypeAndName {
return '';
}
return this.allDigits[digit];
return this.allDigits[digit] as string;
}
public parseInt(value: string): number {
@@ -136,11 +136,11 @@ export class NumeralSystem implements TypeAndName {
let result = '';
for (let i = 0; i < value.length; i++) {
const ch = value[i];
const ch = value.charAt(i);
if (NumeralSystem.WesternArabicNumerals.isDigit(ch)) {
const digit = NumeralSystem.WesternArabicNumerals.digitsToWesternArabic[ch];
result += this.allDigits[digit];
const digit = NumeralSystem.WesternArabicNumerals.digitsToWesternArabic[ch] as number;
result += this.allDigits[digit] as string;
} else {
result += ch;
}
@@ -157,11 +157,11 @@ export class NumeralSystem implements TypeAndName {
let result = '';
for (let i = 0; i < value.length; i++) {
const ch = value[i];
const ch = value.charAt(i);
if (this.isDigit(ch)) {
const digit = this.digitsToWesternArabic[ch];
result += NumeralSystem.WesternArabicNumerals.allDigits[digit];
const digit = this.digitsToWesternArabic[ch] as number;
result += NumeralSystem.WesternArabicNumerals.allDigits[digit] as string;
} else {
result += ch;
}
+2 -2
View File
@@ -168,7 +168,7 @@ describe('getFiscalYearStartUnixTime', () => {
const expected = testCase.expected[testFiscalYearStart.id];
const unixTimeISO = formatUnixTimeISO(startUnixTime);
expect({ unixTime: startUnixTime, ISO: unixTimeISO }).toStrictEqual({ unixTime: expected.unixTime, ISO: expected.unixTimeISO });
expect({ unixTime: startUnixTime, ISO: unixTimeISO }).toStrictEqual({ unixTime: expected!.unixTime, ISO: expected!.unixTimeISO });
});
});
});
@@ -198,7 +198,7 @@ describe('getFiscalYearEndUnixTime', () => {
const expected = testCase.expected[testFiscalYearStart.id];
const unixTimeISO = formatUnixTimeISO(endUnixTime);
expect({ unixTime: endUnixTime, ISO: unixTimeISO }).toStrictEqual({ unixTime: expected.unixTime, ISO: expected.unixTimeISO });
expect({ unixTime: endUnixTime, ISO: unixTimeISO }).toStrictEqual({ unixTime: expected!.unixTime, ISO: expected!.unixTimeISO });
});
});
+15 -15
View File
@@ -60,12 +60,12 @@ describe('getChineseYearMonthAllDayInfos', () => {
}
const items = line.split('\t');
const gregorianDate = items[0];
const gregorianDate = items[0] as string;
const gregorianDateItems = gregorianDate.split('/');
const gregorianYear = parseInt(gregorianDateItems[0], 10);
const gregorianMonth = parseInt(gregorianDateItems[1], 10);
const chineseDay = items[1];
const solarTermName = items.length > 3 ? items[3] : '';
const gregorianYear = parseInt(gregorianDateItems[0] as string, 10);
const gregorianMonth = parseInt(gregorianDateItems[1] as string, 10);
const chineseDay = items[1] as string;
const solarTermName = items.length > 3 ? items[3] as string : '';
if (currentYear > 0 && currentMonth > 0 && (gregorianYear !== currentYear || gregorianMonth !== currentMonth)) {
allMonthChineseDays[`${currentYear}-${currentMonth}`] = currentMonthChineseDays;
@@ -93,10 +93,10 @@ describe('getChineseYearMonthAllDayInfos', () => {
for (const yearMonth in allMonthChineseDays) {
test(`returns correct chinese all dates in month for ${yearMonth}`, () => {
const [yearStr, monthStr] = yearMonth.split('-');
const year = parseInt(yearStr);
const month = parseInt(monthStr);
const expectedChineseMonthOrDays = allMonthChineseDays[yearMonth];
const expectedSolarTermNames = allMonthSolarTermNames[yearMonth];
const year = parseInt(yearStr as string);
const month = parseInt(monthStr as string);
const expectedChineseMonthOrDays = allMonthChineseDays[yearMonth] as string[];
const expectedSolarTermNames = allMonthSolarTermNames[yearMonth] as string[];
const actualChineseDates: ChineseYearMonthDayInfo[] | undefined = getChineseYearMonthAllDayInfos({
year: year,
@@ -128,13 +128,13 @@ describe('getChineseYearMonthDayInfo', () => {
}
const items = line.split('\t');
const gregorianDate = items[0];
const gregorianDate = items[0] as string;
const gregorianDateItems = gregorianDate.split('/');
const gregorianYear = parseInt(gregorianDateItems[0]);
const gregorianMonth = parseInt(gregorianDateItems[1]);
const gregorianDay = parseInt(gregorianDateItems[2]);
const expectedChineseMonthOrDay = items[1];
const expectedSolarTermName = items.length > 3 ? items[3] : '';
const gregorianYear = parseInt(gregorianDateItems[0] as string);
const gregorianMonth = parseInt(gregorianDateItems[1] as string);
const gregorianDay = parseInt(gregorianDateItems[2] as string);
const expectedChineseMonthOrDay = items[1] as string;
const expectedSolarTermName = items.length > 3 ? items[3] as string : '';
test(`returns correct chinese date for ${gregorianDate}`, () => {
const actualChineseDate: ChineseYearMonthDayInfo | undefined = getChineseYearMonthDayInfo({
+3 -3
View File
@@ -177,9 +177,9 @@ function getSolarTermName(gregorianDate: YearMonthDay, localeData: ChineseCalend
const [firstTermDay, firstTermIndex, secondTermDay, secondTermIndex] = getSolarTermDays(gregorianDate.year, gregorianDate.month);
if (firstTermDay > 0 && firstTermDay === gregorianDate.day) {
return localeData.solarTermNames[firstTermIndex];
return localeData.solarTermNames[firstTermIndex] ?? '';
} else if (secondTermDay > 0 && secondTermDay === gregorianDate.day) {
return localeData.solarTermNames[secondTermIndex];
return localeData.solarTermNames[secondTermIndex] ?? '';
} else {
return '';
}
@@ -317,7 +317,7 @@ function buildChineseYearMonthDayInfo(gregorianDate: YearMonthDay, chineseDate:
day: chineseDate.day,
displayYear: getChineseNumber(chineseDate.year, localeData),
displayMonth: (chineseDate.isLeapMonth ? localeData.leapMonthPrefix : '') + localeData.monthNames[chineseDate.month - 1],
displayDay: localeData.dayNames[chineseDate.day - 1],
displayDay: localeData.dayNames[chineseDate.day - 1] ?? '',
isLeapMonth: chineseDate.isLeapMonth,
solarTermName: getSolarTermName(gregorianDate, localeData)
};
+47 -107
View File
@@ -1,3 +1,4 @@
import { itemAndIndex, reversed, entries, keys, values } from '@/core/base.ts';
import { type LocalizedPresetCategory, CategoryType } from '@/core/category.ts';
import { TransactionType } from '@/core/transaction.ts';
import {
@@ -34,8 +35,7 @@ export function categoryTypeToTransactionType(categoryType: CategoryType): Trans
export function localizedPresetCategoryToTransactionCategoryCreateWithSubCategorys(presetCategory: LocalizedPresetCategory): TransactionCategoryCreateWithSubCategories {
const subCategories: TransactionCategoryCreateRequest[] = [];
for (let i = 0; i < presetCategory.subCategories.length; i++) {
const subPresetCategory = presetCategory.subCategories[i];
for (const subPresetCategory of presetCategory.subCategories) {
const subCategory: TransactionCategoryCreateRequest = {
name: subPresetCategory.name,
type: subPresetCategory.type,
@@ -63,8 +63,7 @@ export function localizedPresetCategoryToTransactionCategoryCreateWithSubCategor
export function localizedPresetCategoriesToTransactionCategoryCreateWithSubCategories(presetCategories: LocalizedPresetCategory[]): TransactionCategoryCreateWithSubCategories[] {
const categories: TransactionCategoryCreateWithSubCategories[] = [];
for (let i = 0; i < presetCategories.length; i++) {
const presetCategory = presetCategories[i];
for (const presetCategory of presetCategories) {
const categoryWithSubCategories = localizedPresetCategoryToTransactionCategoryCreateWithSubCategorys(presetCategory);
categories.push(categoryWithSubCategories);
}
@@ -79,12 +78,9 @@ export function getSecondaryTransactionMapByName(allCategories: TransactionCateg
return ret;
}
for (let i = 0; i < allCategories.length; i++) {
const category = allCategories[i];
for (const category of allCategories) {
if (category.subCategories) {
for (let j = 0; j < category.subCategories.length; j++) {
const subCategory = category.subCategories[j];
for (const subCategory of category.subCategories) {
ret[subCategory.name] = subCategory;
}
}
@@ -93,22 +89,21 @@ export function getSecondaryTransactionMapByName(allCategories: TransactionCateg
return ret;
}
export function getTransactionPrimaryCategoryName(categoryId: string | null | undefined, allCategories: TransactionCategory[]): string {
export function getTransactionPrimaryCategoryName(categoryId: string | null | undefined, allCategories?: TransactionCategory[]): string {
if (!allCategories) {
return '';
}
for (let i = 0; i < allCategories.length; i++) {
const subCategoryList = allCategories[i].subCategories;
for (const category of allCategories) {
const subCategoryList = category.subCategories;
if (!subCategoryList) {
continue;
}
for (let j = 0; j < subCategoryList.length; j++) {
const subCategory = subCategoryList[j];
for (const subCategory of subCategoryList) {
if (subCategory.id === categoryId) {
return allCategories[i].name;
return category.name;
}
}
}
@@ -116,20 +111,19 @@ export function getTransactionPrimaryCategoryName(categoryId: string | null | un
return '';
}
export function getTransactionSecondaryCategoryName(categoryId: string | null | undefined, allCategories: TransactionCategory[]): string {
export function getTransactionSecondaryCategoryName(categoryId: string | null | undefined, allCategories?: TransactionCategory[]): string {
if (!allCategories) {
return '';
}
for (let i = 0; i < allCategories.length; i++) {
const subCategoryList = allCategories[i].subCategories;
for (const category of allCategories) {
const subCategoryList = category.subCategories;
if (!subCategoryList) {
continue;
}
for (let j = 0; j < subCategoryList.length; j++) {
const subCategory = subCategoryList[j];
for (const subCategory of subCategoryList) {
if (subCategory.id === categoryId) {
return subCategory.name;
}
@@ -148,9 +142,7 @@ export function allTransactionCategoriesWithVisibleCount(allTransactionCategorie
const allCategoryTypes = [ CategoryType.Income, CategoryType.Expense, CategoryType.Transfer ];
for (let i = 0; i < allCategoryTypes.length; i++) {
const categoryType = allCategoryTypes[i];
for (const categoryType of allCategoryTypes) {
if (!allTransactionCategories[categoryType]) {
continue;
}
@@ -166,14 +158,12 @@ export function allTransactionCategoriesWithVisibleCount(allTransactionCategorie
let allVisibleCategoryCount = 0;
let firstVisibleCategoryIndex = -1;
for (let j = 0; j < allCategories.length; j++) {
const category = allCategories[j];
for (const [category, cagtegoryIndex] of itemAndIndex(allCategories)) {
if (!category.hidden) {
allVisibleCategoryCount++;
if (firstVisibleCategoryIndex === -1) {
firstVisibleCategoryIndex = j;
firstVisibleCategoryIndex = cagtegoryIndex;
}
}
@@ -181,14 +171,12 @@ export function allTransactionCategoriesWithVisibleCount(allTransactionCategorie
let visibleSubCategoryCount = 0;
let firstVisibleSubCategoryIndex = -1;
for (let k = 0; k < category.subCategories.length; k++) {
const subCategory = category.subCategories[k];
for (const [subCategory, subCategoryIndex] of itemAndIndex(category.subCategories)) {
if (!subCategory.hidden) {
visibleSubCategoryCount++;
if (firstVisibleSubCategoryIndex === -1) {
firstVisibleSubCategoryIndex = k;
firstVisibleSubCategoryIndex = subCategoryIndex;
}
}
}
@@ -223,9 +211,7 @@ export function allVisiblePrimaryTransactionCategoriesByType(allTransactionCateg
return visibleCategories;
}
for (let i = 0; i < allCategories.length; i++) {
const category = allCategories[i];
for (const category of allCategories) {
if (category.hidden) {
continue;
}
@@ -243,13 +229,7 @@ export function getFinalCategoryIdsByFilteredCategoryIds(allTransactionCategorie
return finalCategoryIds;
}
for (const categoryId in allTransactionCategoriesMap) {
if (!Object.prototype.hasOwnProperty.call(allTransactionCategoriesMap, categoryId)) {
continue;
}
const category = allTransactionCategoriesMap[categoryId];
for (const category of values(allTransactionCategoriesMap)) {
if (filteredCategoryIds && !isCategoryOrSubCategoriesAllChecked(category, filteredCategoryIds)) {
continue;
}
@@ -269,9 +249,7 @@ export function isSubCategoryIdAvailable(categories: TransactionCategory[], cate
return false;
}
for (let i = 0; i < categories.length; i++) {
const primaryCategory = categories[i];
for (const primaryCategory of categories) {
if (primaryCategory.hidden) {
continue;
}
@@ -282,9 +260,7 @@ export function isSubCategoryIdAvailable(categories: TransactionCategory[], cate
continue;
}
for (let j = 0; j < subCategoryList.length; j++) {
const secondaryCategory = subCategoryList[j];
for (const secondaryCategory of subCategoryList) {
if (secondaryCategory.hidden) {
continue;
}
@@ -303,9 +279,7 @@ export function getFirstAvailableCategoryId(categories: TransactionCategory[]):
return '';
}
for (let i = 0; i < categories.length; i++) {
const primaryCategory = categories[i];
for (const primaryCategory of categories) {
if (primaryCategory.hidden) {
continue;
}
@@ -316,9 +290,7 @@ export function getFirstAvailableCategoryId(categories: TransactionCategory[]):
continue;
}
for (let j = 0; j < subCategoryList.length; j++) {
const secondaryCategory = subCategoryList[j];
for (const secondaryCategory of subCategoryList) {
if (secondaryCategory.hidden) {
continue;
}
@@ -335,9 +307,7 @@ export function getFirstAvailableSubCategoryId(categories: TransactionCategory[]
return '';
}
for (let i = 0; i < categories.length; i++) {
const primaryCategory = categories[i];
for (const primaryCategory of categories) {
if (primaryCategory.hidden || primaryCategory.id !== categoryId) {
continue;
}
@@ -348,9 +318,7 @@ export function getFirstAvailableSubCategoryId(categories: TransactionCategory[]
return '';
}
for (let j = 0; j < subCategoryList.length; j++) {
const secondaryCategory = subCategoryList[j];
for (const secondaryCategory of subCategoryList) {
if (secondaryCategory.hidden) {
continue;
}
@@ -365,8 +333,8 @@ export function getFirstAvailableSubCategoryId(categories: TransactionCategory[]
}
export function isNoAvailableCategory(categories: TransactionCategory[], showHidden: boolean): boolean {
for (let i = 0; i < categories.length; i++) {
if (showHidden || !categories[i].hidden) {
for (const category of categories) {
if (showHidden || !category.hidden) {
return false;
}
}
@@ -377,8 +345,8 @@ export function isNoAvailableCategory(categories: TransactionCategory[], showHid
export function getAvailableCategoryCount(categories: TransactionCategory[], showHidden: boolean): number {
let count = 0;
for (let i = 0; i < categories.length; i++) {
if (showHidden || !categories[i].hidden) {
for (const category of categories) {
if (showHidden || !category.hidden) {
count++;
}
}
@@ -387,9 +355,9 @@ export function getAvailableCategoryCount(categories: TransactionCategory[], sho
}
export function getFirstShowingId(categories: TransactionCategory[], showHidden: boolean): string | null {
for (let i = 0; i < categories.length; i++) {
if (showHidden || !categories[i].hidden) {
return categories[i].id;
for (const category of categories) {
if (showHidden || !category.hidden) {
return category.id;
}
}
@@ -397,9 +365,9 @@ export function getFirstShowingId(categories: TransactionCategory[], showHidden:
}
export function getLastShowingId(categories: TransactionCategory[], showHidden: boolean): string | null {
for (let i = categories.length - 1; i >= 0; i--) {
if (showHidden || !categories[i].hidden) {
return categories[i].id;
for (const category of reversed(categories)) {
if (showHidden || !category.hidden) {
return category.id;
}
}
@@ -407,13 +375,7 @@ export function getLastShowingId(categories: TransactionCategory[], showHidden:
}
export function containsAnyAvailableCategory(allTransactionCategories: Record<number, TransactionCategoriesWithVisibleCount>, showHidden: boolean): boolean {
for (const type in allTransactionCategories) {
if (!Object.prototype.hasOwnProperty.call(allTransactionCategories, type)) {
continue;
}
const categoryType = allTransactionCategories[type];
for (const categoryType of values(allTransactionCategories)) {
if (showHidden) {
if (categoryType.allCategories && categoryType.allCategories.length > 0) {
return true;
@@ -431,13 +393,7 @@ export function containsAnyAvailableCategory(allTransactionCategories: Record<nu
export function containsAvailableCategory(allTransactionCategories: Record<number, TransactionCategoriesWithVisibleCount>, showHidden: boolean): Record<number, boolean> {
const result: Record<number, boolean> = {};
for (const type in allTransactionCategories) {
if (!Object.prototype.hasOwnProperty.call(allTransactionCategories, type)) {
continue;
}
const categoryType = allTransactionCategories[type];
for (const [type, categoryType] of entries(allTransactionCategories)) {
if (showHidden) {
result[type] = categoryType.allCategories && categoryType.allCategories.length > 0;
} else {
@@ -448,23 +404,18 @@ export function containsAvailableCategory(allTransactionCategories: Record<numbe
return result;
}
export function selectAllSubCategories(filterCategoryIds: Record<string, boolean>, category: TransactionCategory, value: boolean): void {
export function selectAllSubCategories(filterCategoryIds: Record<string, boolean>, value: boolean, category?: TransactionCategory): void {
if (!category || !category.subCategories || !category.subCategories.length) {
return;
}
for (let i = 0; i < category.subCategories.length; i++) {
const subCategory = category.subCategories[i];
for (const subCategory of category.subCategories) {
filterCategoryIds[subCategory.id] = value;
}
}
export function selectAll(filterCategoryIds: Record<string, boolean>, allTransactionCategoriesMap: Record<string, TransactionCategory>): void {
for (const categoryId in filterCategoryIds) {
if (!Object.prototype.hasOwnProperty.call(filterCategoryIds, categoryId)) {
continue;
}
for (const categoryId of keys(filterCategoryIds)) {
const category = allTransactionCategoriesMap[categoryId];
if (category) {
@@ -474,11 +425,7 @@ export function selectAll(filterCategoryIds: Record<string, boolean>, allTransac
}
export function selectNone(filterCategoryIds: Record<string, boolean>, allTransactionCategoriesMap: Record<string, TransactionCategory>): void {
for (const categoryId in filterCategoryIds) {
if (!Object.prototype.hasOwnProperty.call(filterCategoryIds, categoryId)) {
continue;
}
for (const categoryId of keys(filterCategoryIds)) {
const category = allTransactionCategoriesMap[categoryId];
if (category) {
@@ -488,11 +435,7 @@ export function selectNone(filterCategoryIds: Record<string, boolean>, allTransa
}
export function selectInvert(filterCategoryIds: Record<string, boolean>, allTransactionCategoriesMap: Record<string, TransactionCategory>): void {
for (const categoryId in filterCategoryIds) {
if (!Object.prototype.hasOwnProperty.call(filterCategoryIds, categoryId)) {
continue;
}
for (const categoryId of keys(filterCategoryIds)) {
const category = allTransactionCategoriesMap[categoryId];
if (category) {
@@ -506,8 +449,7 @@ export function isCategoryOrSubCategoriesAllChecked(category: TransactionCategor
return !filterCategoryIds[category.id];
}
for (let i = 0; i < category.subCategories.length; i++) {
const subCategory = category.subCategories[i];
for (const subCategory of category.subCategories) {
if (filterCategoryIds[subCategory.id]) {
return false;
}
@@ -521,8 +463,7 @@ export function isSubCategoriesAllChecked(category: TransactionCategory, filterC
return false;
}
for (let i = 0; i < category.subCategories.length; i++) {
const subCategory = category.subCategories[i];
for (const subCategory of category.subCategories) {
if (filterCategoryIds[subCategory.id]) {
return false;
}
@@ -538,8 +479,7 @@ export function isSubCategoriesHasButNotAllChecked(category: TransactionCategory
return false;
}
for (let i = 0; i < category.subCategories.length; i++) {
const subCategory = category.subCategories[i];
for (const subCategory of category.subCategories) {
if (!filterCategoryIds[subCategory.id]) {
checkedCount++;
}
+38 -92
View File
@@ -1,3 +1,4 @@
import { keys, keysIfValueEquals, values } from '@/core/base.ts';
import type { NameValue, TypeAndName, TypeAndDisplayName} from '@/core/base.ts';
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
@@ -48,7 +49,7 @@ export function isYearMonth(val: unknown): val is string {
return false;
}
return !!parseInt(items[0]) && !!parseInt(items[1]);
return !!parseInt(items[0] as string) && !!parseInt(items[1] as string);
}
export function isEquals(obj1: unknown, obj2: unknown): boolean {
@@ -82,13 +83,13 @@ export function isEquals(obj1: unknown, obj2: unknown): boolean {
const keyExistsMap2 = new Map<string, boolean>();
for (let i = 0; i < keys2.length; i++) {
const key = keys2[i];
const key = keys2[i] as string;
keyExistsMap2.set(key, true);
}
for (let i = 0; i < keys1.length; i++) {
const key = keys1[i];
const key = keys1[i] as string;
if (!keyExistsMap2.get(key)) {
return false;
@@ -117,7 +118,7 @@ export function isYearMonthEquals(val1: unknown, val2: unknown): boolean {
return false;
}
return (!!parseInt(items1[0]) && !!parseInt(items1[1])) && (parseInt(items1[0]) === parseInt(items2[0])) && (parseInt(items1[1]) === parseInt(items2[1]));
return (!!parseInt(items1[0] as string) && !!parseInt(items1[1] as string)) && (parseInt(items1[0] as string) === parseInt(items2[0] as string)) && (parseInt(items1[1] as string) === parseInt(items2[1] as string));
}
export function isArray1SubsetOfArray2<T>(array1: T[], array2: T[]): boolean {
@@ -128,11 +129,11 @@ export function isArray1SubsetOfArray2<T>(array1: T[], array2: T[]): boolean {
const array2ValuesMap: Map<T, boolean> = new Map<T, boolean>();
for (let i = 0; i < array2.length; i++) {
array2ValuesMap.set(array2[i], true);
array2ValuesMap.set(array2[i] as T, true);
}
for (let i = 0; i < array1.length; i++) {
if (!array2ValuesMap.get(array1[i])) {
if (!array2ValuesMap.get(array1[i] as T)) {
return false;
}
}
@@ -145,11 +146,7 @@ export function isObjectEmpty(obj: object): boolean {
return true;
}
for (const field in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, field)) {
continue;
}
for (const _ of keys(obj)) {
return false;
}
@@ -183,11 +180,8 @@ export function getObjectOwnFieldCount(object: object): number {
return count;
}
for (const field in object) {
if (!Object.prototype.hasOwnProperty.call(object, field)) {
continue;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const _ of keys(object)) {
count++;
}
@@ -251,26 +245,22 @@ export function getFirstVisibleItem<T>(items: Record<string, T>[] | Record<strin
if (isArray(items) && items.length > 0) {
const arr = items as Record<string, T>[];
for (let i = 0; i < arr.length; i++) {
if (hiddenField && arr[i][hiddenField]) {
for (const item of arr) {
if (hiddenField && item[hiddenField]) {
continue;
}
return arr[i];
return item;
}
} else if (isObject(items)) {
const obj = items as Record<string, Record<string, T>>;
for (const field in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, field)) {
for (const item of values(obj)) {
if (hiddenField && item[hiddenField]) {
continue;
}
if (hiddenField && obj[field][hiddenField]) {
continue;
}
return obj[field];
return item;
}
}
@@ -281,9 +271,7 @@ export function getItemByKeyValue<T>(src: Record<string, T>[] | Record<string, R
if (isArray(src)) {
const arr = src as Record<string, T>[];
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
for (const item of arr) {
if (item[keyField] === value) {
return item;
}
@@ -291,13 +279,7 @@ export function getItemByKeyValue<T>(src: Record<string, T>[] | Record<string, R
} else if (isObject(src)) {
const obj = src as Record<string, Record<string, T>>;
for (const field in obj) {
if (!Object.prototype.hasOwnProperty.call(src, field)) {
continue;
}
const item = obj[field];
for (const item of values(obj)) {
if (item[keyField] === value) {
return item;
}
@@ -342,9 +324,7 @@ export function getNameByKeyValue<V, N>(src: Record<string, N | V>[] | Record<st
const arr = src as Record<string, N | V>[];
if (keyField) {
for (let i = 0; i < arr.length; i++) {
const option = arr[i];
for (const option of arr) {
if (option[keyField] === value) {
return option[nameField] as N;
}
@@ -362,13 +342,7 @@ export function getNameByKeyValue<V, N>(src: Record<string, N | V>[] | Record<st
const obj = src as Record<string, Record<string, N | V>>;
if (keyField) {
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(src, key)) {
continue;
}
const option = obj[key];
for (const option of values(obj)) {
if (option[keyField] === value) {
return option[nameField] as N;
}
@@ -392,8 +366,8 @@ export function arrayContainsFieldValue<T>(array: Record<string, T>[], fieldName
return false;
}
for (let i = 0; i < array.length; i++) {
if (array[i][fieldName] === value) {
for (const item of array) {
if (item[fieldName] === value) {
return true;
}
}
@@ -404,11 +378,7 @@ export function arrayContainsFieldValue<T>(array: Record<string, T>[], fieldName
export function objectFieldToArrayItem(object: object): string[] {
const ret: string[] = [];
for (const field in object) {
if (!Object.prototype.hasOwnProperty.call(object, field)) {
continue;
}
for (const field of keys(object)) {
ret.push(field);
}
@@ -418,14 +388,8 @@ export function objectFieldToArrayItem(object: object): string[] {
export function objectFieldWithValueToArrayItem<T>(object: Record<string, T>, value: T): string[] {
const ret: string[] = [];
for (const field in object) {
if (!Object.prototype.hasOwnProperty.call(object, field)) {
continue;
}
if (object[field] === value) {
ret.push(field);
}
for (const field of keysIfValueEquals(object, value)) {
ret.push(field);
}
return ret;
@@ -434,8 +398,8 @@ export function objectFieldWithValueToArrayItem<T>(object: Record<string, T>, va
export function arrayItemToObjectField<T>(array: string[], value: T): Record<string, T> {
const ret: Record<string, T> = {};
for (let i = 0; i < array.length; i++) {
ret[array[i]] = value;
for (const item of array) {
ret[item] = value;
}
return ret;
@@ -450,9 +414,9 @@ export function splitItemsToMap(str: string | undefined | null, separator: strin
const items = str.split(separator);
for (let i = 0; i < items.length; i++) {
if (items[i]) {
ret[items[i]] = true;
for (const item of items) {
if (item) {
ret[item] = true;
}
}
@@ -479,15 +443,9 @@ export function countSplitItems(str: string | undefined | null, separator: strin
export function categorizedArrayToPlainArray<T>(object: Record<string, T[]>): T[] {
const ret: T[] = [];
for (const field in object) {
if (!Object.prototype.hasOwnProperty.call(object, field)) {
continue;
}
const array = object[field];
for (let i = 0; i < array.length; i++) {
ret.push(array[i]);
for (const array of values(object)) {
for (const item of array) {
ret.push(item);
}
}
@@ -495,11 +453,7 @@ export function categorizedArrayToPlainArray<T>(object: Record<string, T[]>): T[
}
export function selectAll(filterItemIds: Record<string, boolean>, allItemsMap: { [key: string]: { id: string } }): void {
for (const itemId in filterItemIds) {
if (!Object.prototype.hasOwnProperty.call(filterItemIds, itemId)) {
continue;
}
for (const itemId of keys(filterItemIds)) {
const item = allItemsMap[itemId];
if (item) {
@@ -509,11 +463,7 @@ export function selectAll(filterItemIds: Record<string, boolean>, allItemsMap: {
}
export function selectNone(filterItemIds: Record<string, boolean>, allItemsMap: { [key: string]: { id: string } }): void {
for (const itemId in filterItemIds) {
if (!Object.prototype.hasOwnProperty.call(filterItemIds, itemId)) {
continue;
}
for (const itemId of keys(filterItemIds)) {
const item = allItemsMap[itemId];
if (item) {
@@ -523,11 +473,7 @@ export function selectNone(filterItemIds: Record<string, boolean>, allItemsMap:
}
export function selectInvert(filterItemIds: Record<string, boolean>, allItemsMap: { [key: string]: { id: string } }): void {
for (const itemId in filterItemIds) {
if (!Object.prototype.hasOwnProperty.call(filterItemIds, itemId)) {
continue;
}
for (const itemId of keys(filterItemIds)) {
const item = allItemsMap[itemId];
if (item) {
@@ -610,11 +556,11 @@ export function arrangeArrayWithNewStartIndex<T>(array: T[], startIndex: number)
const newArray: T[] = [];
for (let i = startIndex; i < array.length; i++) {
newArray.push(array[i]);
newArray.push(array[i] as T);
}
for (let i = 0; i < startIndex; i++) {
newArray.push(array[i]);
newArray.push(array[i] as T);
}
return newArray;
+17 -18
View File
@@ -3,6 +3,9 @@ import { type unitOfTime } from 'moment/moment';
import jalaali, { type JalaaliDateObject } from 'jalaali-js';
import {
itemAndIndex
} from '@/core/base.ts';
import {
type ChineseCalendarLocaleData,
CalendarType
@@ -426,8 +429,8 @@ export function getYear0BasedMonthObjectFromString(yearMonth: TextualYearMonth |
return null;
}
const year = parseInt(items[0]);
const month0base = parseInt(items[1]) - 1;
const year = parseInt(items[0] as string);
const month0base = parseInt(items[1] as string) - 1;
if (!isYear0BasedMonthValid(year, month0base)) {
return null;
@@ -581,9 +584,9 @@ export function getLocalDateFromYearDashMonthDashDay(date: TextualYearMonthDay):
return null;
}
const year = parseInt(items[0]);
const month = parseInt(items[1]);
const day = parseInt(items[2]);
const year = parseInt(items[0] as string);
const month = parseInt(items[1] as string);
const day = parseInt(items[2] as string);
if (!isNumber(year) || !isNumber(month) || !isNumber(day)) {
return null;
@@ -983,8 +986,8 @@ export function getAllDaysStartAndEndUnixTimes(startUnixTime: number, endUnixTim
}
export function getDateTimeFormatType<T extends DateFormat | TimeFormat>(allFormatMap: Record<string, T>, allFormatArray: T[], formatTypeValue: number, languageDefaultTypeName: string, systemDefaultFormatType: T): T {
if (formatTypeValue > LANGUAGE_DEFAULT_DATE_TIME_FORMAT_VALUE && allFormatArray[formatTypeValue - 1] && allFormatArray[formatTypeValue - 1].key) {
return allFormatArray[formatTypeValue - 1];
if (formatTypeValue > LANGUAGE_DEFAULT_DATE_TIME_FORMAT_VALUE && allFormatArray[formatTypeValue - 1] && allFormatArray[formatTypeValue - 1]!.key) {
return allFormatArray[formatTypeValue - 1] as T;
} else if (formatTypeValue === LANGUAGE_DEFAULT_DATE_TIME_FORMAT_VALUE && allFormatMap[languageDefaultTypeName] && allFormatMap[languageDefaultTypeName].key) {
return allFormatMap[languageDefaultTypeName];
} else {
@@ -1079,9 +1082,7 @@ export function getDateTypeByDateRange(minTime: number, maxTime: number, firstDa
const allDateRanges = DateRange.values();
let newDateType = DateRange.Custom.type;
for (let i = 0; i < allDateRanges.length; i++) {
const dateRange = allDateRanges[i];
for (const dateRange of allDateRanges) {
if (!dateRange.isAvailableForScene(scene)) {
continue;
}
@@ -1264,9 +1265,9 @@ export function getRecentMonthDateRanges(monthCount: number): RecentMonthDateRan
}
export function getRecentDateRangeIndexByDateType(allRecentMonthDateRanges: LocalizedRecentMonthDateRange[], dateType: number): number {
for (let i = 0; i < allRecentMonthDateRanges.length; i++) {
if (!allRecentMonthDateRanges[i].isPreset && allRecentMonthDateRanges[i].dateType === dateType) {
return i;
for (const [recentDateRange, index] of itemAndIndex(allRecentMonthDateRanges)) {
if (!recentDateRange.isPreset && recentDateRange.dateType === dateType) {
return index;
}
}
@@ -1292,11 +1293,9 @@ export function getRecentDateRangeIndex(allRecentMonthDateRanges: LocalizedRecen
};
}
for (let i = 0; i < allRecentMonthDateRanges.length; i++) {
const recentDateRange = allRecentMonthDateRanges[i];
for (const [recentDateRange, index] of itemAndIndex(allRecentMonthDateRanges)) {
if (recentDateRange.isPreset && recentDateRange.minTime === dateRange.minTime && recentDateRange.maxTime === dateRange.maxTime) {
return i;
return index;
}
}
@@ -1356,7 +1355,7 @@ export function getValidMonthDayOrCurrentDayShortDate(unixTime: number, currentS
const yearMonthDay = currentShortDate.split('-');
if (yearMonthDay.length === 3) {
const currentDay = parseInt(yearMonthDay[2]);
const currentDay = parseInt(yearMonthDay[2] as string);
if (currentDay < monthLastTime.date()) {
return MomentDateTime.of(monthLastTime.set({ date: currentDay })).getGregorianCalendarYearDashMonthDashDay();
+3 -5
View File
@@ -8,7 +8,7 @@ export function getFileExtension(filename: string): string {
}
const parts = filename.split('.');
return parts[parts.length - 1];
return parts[parts.length - 1] as string;
}
export function findExtensionByType(items: ImportFileTypeAndExtensions[] | undefined, type: string): string | undefined {
@@ -33,10 +33,8 @@ export function isFileExtensionSupported(filename: string, supportedExtensions:
const supportedExtensionsArray = supportedExtensions.split(',');
const fileExtension = getFileExtension(filename).toLowerCase();
for (let i = 0; i < supportedExtensionsArray.length; i++) {
const supportedExtension = getFileExtension(supportedExtensionsArray[i]).toLowerCase();
if (supportedExtension === fileExtension) {
for (const supportedExtension of supportedExtensionsArray) {
if (getFileExtension(supportedExtension).toLowerCase() === fileExtension) {
return true;
}
}
+4 -9
View File
@@ -1,24 +1,19 @@
import { entries } from '@/core/base.ts';
import type { IconInfo, IconInfoWithId } from '@/core/icon.ts';
export function getIconsInRows(allIconInfos: Record<string, IconInfo>, itemPerRow: number): IconInfoWithId[][] {
const ret: IconInfoWithId[][] = [];
let rowCount = 0;
for (const iconInfoId in allIconInfos) {
if (!Object.prototype.hasOwnProperty.call(allIconInfos, iconInfoId)) {
continue;
}
const iconInfo = allIconInfos[iconInfoId];
for (const [iconInfoId, iconInfo] of entries(allIconInfos)) {
if (!ret[rowCount]) {
ret[rowCount] = [];
} else if (ret[rowCount] && ret[rowCount].length >= itemPerRow) {
} else if (ret[rowCount] && ret[rowCount]!.length >= itemPerRow) {
rowCount++;
ret[rowCount] = [];
}
ret[rowCount].push({
ret[rowCount]!.push({
id: iconInfoId,
icon: iconInfo.icon
});
+3 -7
View File
@@ -18,7 +18,7 @@ export function sortStatisticsItems<T extends SortableTransactionStatisticDataIt
items.sort(function (data1, data2) {
for (let i = 0; i < Math.min(data1.displayOrders.length, data2.displayOrders.length); i++) {
if (data1.displayOrders[i] !== data2.displayOrders[i]) {
return data1.displayOrders[i] - data2.displayOrders[i]; // asc
return (data1.displayOrders[i] as number) - (data2.displayOrders[i] as number); // asc
}
}
@@ -52,12 +52,8 @@ export function getAllDateRangesFromItems<T extends Year1BasedMonth>(items: Year
if ((!startYearMonth || !endYearMonth) && items && items.length) {
let minYear = Number.MAX_SAFE_INTEGER, minMonth = Number.MAX_SAFE_INTEGER, maxYear = 0, maxMonth = 0;
for (let i = 0; i < items.length; i++) {
const item = items[i];
for (let j = 0; j < item.items.length; j++) {
const dataItem = item.items[j];
for (const item of items) {
for (const dataItem of item.items) {
if (dataItem.year < minYear || (dataItem.year === minYear && dataItem.month1base < minMonth)) {
minYear = dataItem.year;
minMonth = dataItem.month1base;
+4 -7
View File
@@ -59,9 +59,7 @@ export function setExpenseAndIncomeAmountColor(expenseAmountColorType: number, i
const allPresetAmountColors = PresetAmountColor.values();
for (let i = 0; i < allPresetAmountColors.length; i++) {
const amountColor = allPresetAmountColors[i];
for (const amountColor of allPresetAmountColors) {
if (amountColor.type === expenseAmountColor.type) {
if (!htmlElement.classList.contains(amountColor.expenseClassName)) {
htmlElement.classList.add(amountColor.expenseClassName);
@@ -97,8 +95,8 @@ export function openTextFileContent({ allowedExtensions }: { allowedExtensions:
fileInput.onchange = (event) => {
const el = event.target as HTMLInputElement;
if (el.files && el.files.length > 0) {
const file = el.files[0];
if (el.files && el.files.length > 0 && el.files[0]) {
const file = el.files[0] as File;
const reader = new FileReader();
reader.onload = (e) => {
@@ -146,8 +144,7 @@ export function clearBrowserCaches(): Promise<void> {
window.caches.keys().then(cacheNames => {
const promises = [];
for (let i = 0; i < cacheNames.length; i++) {
const cacheName = cacheNames[i];
for (const cacheName of cacheNames) {
promises.push(window.caches.delete(cacheName).then(success => {
if (success) {
logger.info(`cache "${cacheName}" cleared successfully`);
+3 -8
View File
@@ -74,9 +74,7 @@ export function setAppFontSize(type: number): void {
const htmlElement = f7.$('html');
const allFontSizes = FontSize.values();
for (let i = 0; i < allFontSizes.length; i++) {
const fontSizeType = allFontSizes[i];
for (const fontSizeType of allFontSizes) {
if (fontSizeType.type === type) {
if (!htmlElement.hasClass(fontSizeType.className)) {
htmlElement.addClass(fontSizeType.className);
@@ -90,9 +88,7 @@ export function setAppFontSize(type: number): void {
export function getFontSizePreviewClassName(type: number): string {
const allFontSizes = FontSize.values();
for (let i = 0; i < allFontSizes.length; i++) {
const fontSizeType = allFontSizes[i];
for (const fontSizeType of allFontSizes) {
if (fontSizeType.type === type) {
return FONT_SIZE_PREVIEW_CLASSNAME_PREFIX + fontSizeType.className;
}
@@ -109,8 +105,7 @@ export function getElementActualHeights(selector: string): Record<string, number
return heights;
}
for (let i = 0; i < elements.length; i++) {
const el = elements[i];
for (const el of elements) {
const rect = el.getBoundingClientRect();
heights[el.id] = rect.height;
}
+3 -3
View File
@@ -180,7 +180,7 @@ export function verifyWebAuthnCredential(userInfo: UserBasicInfo, credentialId:
}) as PublicKeyCredentialRequestOptions;
if (publicKeyCredentialRequestOptions.allowCredentials && publicKeyCredentialRequestOptions.allowCredentials.length > 0) {
publicKeyCredentialRequestOptions.allowCredentials[0].id = stringToArrayBuffer(base64decode(credentialId));
publicKeyCredentialRequestOptions.allowCredentials[0]!.id = stringToArrayBuffer(base64decode(credentialId));
}
logger.debug('webauthn get options', publicKeyCredentialRequestOptions);
@@ -199,8 +199,8 @@ export function verifyWebAuthnCredential(userInfo: UserBasicInfo, credentialId:
userIdParts && userIdParts.length === 2 && userIdParts[0] === userInfo.username) {
const ret: WebAuthnVerifyResponse = {
id: base64encode(rawCredential.rawId),
userName: userIdParts[0],
userSecret: userIdParts[1],
userName: userIdParts[0] as string,
userSecret: userIdParts[1] as string,
clientData: clientData,
rawCredential: rawCredential
};
+1 -3
View File
@@ -156,9 +156,7 @@ export const useOverviewStore = defineStore('overview', () => {
let hasUnCalculatedTotalExpense = false;
if (item.amounts) {
for (let i = 0; i < item.amounts.length; i++) {
const amount = item.amounts[i];
for (const amount of item.amounts) {
if (amount.currency !== defaultCurrency) {
const incomeAmount = exchangeRatesStore.getExchangedAmount(amount.incomeAmount, amount.currency, defaultCurrency);
const expenseAmount = exchangeRatesStore.getExchangedAmount(amount.expenseAmount, amount.currency, defaultCurrency);
+1 -1
View File
@@ -35,7 +35,7 @@ export function useExchangeRatesPageBase() {
return getAllDisplayExchangeRates(exchangeRatesData.value);
});
function getConvertedAmount(baseAmount: number | '', fromExchangeRate: LatestExchangeRate | LocalizedLatestExchangeRate, toExchangeRate: LatestExchangeRate | LocalizedLatestExchangeRate): number | '' | null {
function getConvertedAmount(baseAmount: number | '', fromExchangeRate?: LatestExchangeRate | LocalizedLatestExchangeRate, toExchangeRate?: LatestExchangeRate | LocalizedLatestExchangeRate): number | '' | null {
if (!fromExchangeRate || !toExchangeRate) {
return '';
}
@@ -52,8 +52,8 @@ export function useAccountEditPageBaseBase() {
}
if (account.value.type === AccountType.MultiSubAccounts.type) {
for (let i = 0; i < subAccounts.value.length; i++) {
problemMessage = getInputEmptyProblemMessage(subAccounts.value[i], true);
for (const subAccount of subAccounts.value) {
problemMessage = getInputEmptyProblemMessage(subAccount, true);
if (problemMessage) {
return problemMessage;
@@ -132,9 +132,9 @@ export function useAccountEditPageBaseBase() {
subAccounts.value = [];
if (newAccount.subAccounts && newAccount.subAccounts.length > 0) {
for (let i = 0; i < newAccount.subAccounts.length; i++) {
for (const oldSubAccount of newAccount.subAccounts) {
const subAccount: Account = account.value.createNewSubAccount(userStore.currentUserDefaultCurrency, getCurrentUnixTime());
subAccount.fillFrom(newAccount.subAccounts[i]);
subAccount.fillFrom(oldSubAccount);
subAccounts.value.push(subAccount);
}
@@ -150,7 +150,7 @@ export function useReconciliationStatementPageBase() {
let currency = defaultCurrency.value;
if (allAccountsMap.value[transaction.sourceAccountId]) {
currency = allAccountsMap.value[transaction.sourceAccountId].currency;
currency = allAccountsMap.value[transaction.sourceAccountId]!.currency;
}
return formatAmountToLocalizedNumeralsWithCurrency(transaction.sourceAmount, currency);
@@ -160,7 +160,7 @@ export function useReconciliationStatementPageBase() {
let currency = defaultCurrency.value;
if (allAccountsMap.value[transaction.destinationAccountId]) {
currency = allAccountsMap.value[transaction.destinationAccountId].currency;
currency = allAccountsMap.value[transaction.destinationAccountId]!.currency;
}
return formatAmountToLocalizedNumeralsWithCurrency(transaction.destinationAmount, currency);
@@ -172,12 +172,12 @@ export function useReconciliationStatementPageBase() {
if (transaction.type === TransactionType.Transfer && transaction.destinationAccountId === accountId.value) {
if (allAccountsMap.value[transaction.destinationAccountId]) {
currency = allAccountsMap.value[transaction.destinationAccountId].currency;
isLiabilityAccount = allAccountsMap.value[transaction.destinationAccountId].isLiability;
currency = allAccountsMap.value[transaction.destinationAccountId]!.currency;
isLiabilityAccount = allAccountsMap.value[transaction.destinationAccountId]!.isLiability;
}
} else if (allAccountsMap.value[transaction.sourceAccountId]) {
currency = allAccountsMap.value[transaction.sourceAccountId].currency;
isLiabilityAccount = allAccountsMap.value[transaction.sourceAccountId].isLiability;
currency = allAccountsMap.value[transaction.sourceAccountId]!.currency;
isLiabilityAccount = allAccountsMap.value[transaction.sourceAccountId]!.isLiability;
}
if (isLiabilityAccount) {
@@ -8,6 +8,7 @@ import { useTransactionsStore } from '@/stores/transaction.ts';
import { useStatisticsStore } from '@/stores/statistics.ts';
import { useOverviewStore } from '@/stores/overview.ts';
import { keys, keysIfValueEquals, values } from '@/core/base.ts';
import { CategoryType } from '@/core/category.ts';
import type { TransactionCategory, TransactionCategoriesWithVisibleCount } from '@/models/transaction_category.ts';
@@ -80,13 +81,7 @@ export function useCategoryFilterSettingPageBase(type?: CategoryFilterType, allo
function loadFilterCategoryIds(): boolean {
const allCategoryIds: Record<string, boolean> = {};
for (const categoryId in transactionCategoriesStore.allTransactionCategoriesMap) {
if (!Object.prototype.hasOwnProperty.call(transactionCategoriesStore.allTransactionCategoriesMap, categoryId)) {
continue;
}
const category = transactionCategoriesStore.allTransactionCategoriesMap[categoryId];
for (const category of values(transactionCategoriesStore.allTransactionCategoriesMap)) {
if (allowCategoryTypes && !allowCategoryTypes[category.type]) {
continue;
}
@@ -108,17 +103,13 @@ export function useCategoryFilterSettingPageBase(type?: CategoryFilterType, allo
filterCategoryIds.value = Object.assign(allCategoryIds, settingsStore.appSettings.overviewTransactionCategoryFilterInHomePage);
return true;
} else if (type === 'transactionListCurrent') {
for (const categoryId in transactionsStore.allFilterCategoryIds) {
if (!Object.prototype.hasOwnProperty.call(transactionsStore.allFilterCategoryIds, categoryId)) {
continue;
}
for (const categoryId of keysIfValueEquals(transactionsStore.allFilterCategoryIds, true)) {
const category = transactionCategoriesStore.allTransactionCategoriesMap[categoryId];
if (category && (!category.subCategories || !category.subCategories.length)) {
allCategoryIds[category.id] = false;
} else if (category) {
selectAllSubCategories(allCategoryIds, category, false);
selectAllSubCategories(allCategoryIds, false, category);
}
}
@@ -135,11 +126,7 @@ export function useCategoryFilterSettingPageBase(type?: CategoryFilterType, allo
let finalCategoryIds = '';
let changed = true;
for (const categoryId in filterCategoryIds.value) {
if (!Object.prototype.hasOwnProperty.call(filterCategoryIds.value, categoryId)) {
continue;
}
for (const categoryId of keys(filterCategoryIds.value)) {
const category = transactionCategoriesStore.allTransactionCategoriesMap[categoryId];
if (!category) {
@@ -396,9 +396,9 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
});
watch(() => transaction.value.timeZone, (newValue) => {
for (let i = 0; i < allTimezones.value.length; i++) {
if (allTimezones.value[i].name === newValue) {
transaction.value.utcOffset = allTimezones.value[i].utcOffsetMinutes;
for (const timezone of allTimezones.value) {
if (timezone.name === newValue) {
transaction.value.utcOffset = timezone.utcOffsetMinutes;
break;
}
}
@@ -260,7 +260,7 @@ const selectedAccount = computed<Account>(() => {
return account.value;
}
return subAccounts.value[currentAccountIndex.value];
return subAccounts.value[currentAccountIndex.value] as Account;
});
const accountAmountTitle = computed<string>(() => {
@@ -248,7 +248,7 @@ function updateCategorySelected(category: TransactionCategory, value: boolean |
}
function updateAllSubCategoriesSelected(category: TransactionCategory, value: boolean | null): void {
selectAllSubCategories(filterCategoryIds.value, category, !value);
selectAllSubCategories(filterCategoryIds.value, !value, category);
if (props.autoSave) {
save();
@@ -1888,11 +1888,11 @@ function setImportFile(event: Event): void {
const el = event.target as HTMLInputElement;
if (!el.files || !el.files.length) {
if (!el.files || !el.files.length || !el.files[0]) {
return;
}
importFile.value = el.files[0];
importFile.value = el.files[0] as File;
el.value = '';
}
@@ -75,7 +75,7 @@ import { useI18n } from '@/locales/helpers.ts';
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
import type { NameValue } from '@/core/base.ts';
import { type NameValue, values } from '@/core/base.ts';
import { CategoryType } from '@/core/category.ts';
import { AUTOMATICALLY_CREATED_CATEGORY_ICON_ID } from '@/consts/icon.ts';
import { DEFAULT_CATEGORY_COLOR } from '@/consts/color.ts';
@@ -140,9 +140,7 @@ function buildBatchCreateCategoryResponse(createdCategories: Record<number, Tran
displayNameSourceItemMap[item.name] = item.value;
}
for (const categoryType in createdCategories) {
const categories = createdCategories[categoryType];
for (const categories of values(createdCategories)) {
for (const category of categories) {
if (!category.subCategories || category.subCategories.length < 1) {
continue;
@@ -1168,11 +1168,11 @@ function uploadPicture(event: Event): void {
const el = event.target as HTMLInputElement;
if (!el.files || !el.files.length) {
if (!el.files || !el.files.length || !el.files[0]) {
return;
}
const pictureFile = el.files[0];
const pictureFile = el.files[0] as File;
el.value = '';
@@ -536,11 +536,11 @@ function updateAvatar(event: Event): void {
const el = event.target as HTMLInputElement;
if (!el.files || !el.files.length) {
if (!el.files || !el.files.length || !el.files[0]) {
return;
}
const avatarFile = el.files[0];
const avatarFile = el.files[0] as File;
el.value = '';
+1 -1
View File
@@ -87,7 +87,7 @@
:after="account.type === AccountType.SingleAccount.type ? accountBalance(account) : ''"
:link="!sortable ? '/transaction/list?accountIds=' + account.id : null"
:key="account.id"
v-for="account in allCategorizedAccountsMap[accountCategory.type].accounts"
v-for="account in allCategorizedAccountsMap[accountCategory.type]!.accounts"
v-show="showHidden || !account.hidden"
@taphold="setSortable()"
>
@@ -166,7 +166,7 @@
<f7-list-item chevron-center
:key="item.index"
:id="item.transaction ? getTransactionDomId(item.transaction) : undefined"
:class="{ 'transaction-info': item.type == 'transaction', 'last-transaction-of-day': allReconciliationStatementVirtualListItems[item.index + 1] && allReconciliationStatementVirtualListItems[item.index + 1].type === 'date', 'reconciliation-statement-transaction-date': item.type == 'date' }"
:class="{ 'transaction-info': item.type == 'transaction', 'last-transaction-of-day': allReconciliationStatementVirtualListItems[item.index + 1] && allReconciliationStatementVirtualListItems[item.index + 1]!.type === 'date', 'reconciliation-statement-transaction-date': item.type == 'date' }"
:style="`top: ${virtualDataItems.topPosition}px`"
:virtual-list-index="item.index"
:swipeout="item.type === 'transaction' && !!item.transaction"
@@ -204,7 +204,7 @@
{{ tt('Modify Balance') }}
</span>
<span v-else-if="item.transaction.type !== TransactionType.ModifyBalance && allCategoriesMap[item.transaction.categoryId]">
{{ allCategoriesMap[item.transaction.categoryId].name }}
{{ allCategoriesMap[item.transaction.categoryId]!.name }}
</span>
</div>
</div>
@@ -466,8 +466,7 @@ const allReconciliationStatementVirtualListItems = computed<ReconciliationStatem
let index = 0;
let lastDisplayDate: string | null = null;
for (let i = 0; i < reconciliationStatements.value.transactions.length; i++) {
const transaction = reconciliationStatements.value.transactions[i];
for (const transaction of reconciliationStatements.value.transactions) {
const displayDate = getDisplayDate(transaction);
if (lastDisplayDate !== displayDate) {
@@ -47,22 +47,22 @@
:key="accountCategory.category"
v-for="accountCategory in allCategorizedAccounts"
v-show="showHidden || accountCategory.allVisibleAccountCount > 0">
<f7-accordion-item :opened="collapseStates[accountCategory.category].opened"
@accordion:open="collapseStates[accountCategory.category].opened = true"
@accordion:close="collapseStates[accountCategory.category].opened = false">
<f7-accordion-item :opened="collapseStates[accountCategory.category]!.opened"
@accordion:open="collapseStates[accountCategory.category]!.opened = true"
@accordion:close="collapseStates[accountCategory.category]!.opened = false">
<f7-block-title>
<f7-accordion-toggle>
<f7-list strong inset dividers
class="combination-list-header"
:class="collapseStates[accountCategory.category].opened ? 'combination-list-opened' : 'combination-list-closed'">
:class="collapseStates[accountCategory.category]!.opened ? 'combination-list-opened' : 'combination-list-closed'">
<f7-list-item group-title>
<small>{{ tt(accountCategory.name) }}</small>
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates[accountCategory.category].opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates[accountCategory.category]!.opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
</f7-list-item>
</f7-list>
</f7-accordion-toggle>
</f7-block-title>
<f7-accordion-content :style="{ height: collapseStates[accountCategory.category].opened ? 'auto' : '' }">
<f7-accordion-content :style="{ height: collapseStates[accountCategory.category]!.opened ? 'auto' : '' }">
<f7-list strong inset dividers accordion-list class="combination-list-content">
<f7-list-item checkbox
:class="{ 'has-child-list-item': account.type === AccountType.MultiSubAccounts.type && ((showHidden && accountCategory.allSubAccounts[account.id]) || accountCategory.allVisibleSubAccountCounts[account.id]) }"
@@ -189,9 +189,7 @@ function getCollapseStates(): Record<number, CollapseState> {
const collapseStates: Record<number, CollapseState> = {};
const allCategories = AccountCategory.values();
for (let i = 0; i < allCategories.length; i++) {
const accountCategory = allCategories[i];
for (const accountCategory of allCategories) {
collapseStates[accountCategory.type] = {
opened: true
};
@@ -52,22 +52,22 @@
:key="categoryType.type"
v-for="categoryType in allTransactionCategories"
v-else-if="!loading">
<f7-accordion-item :opened="collapseStates[categoryType.type].opened"
@accordion:open="collapseStates[categoryType.type].opened = true"
@accordion:close="collapseStates[categoryType.type].opened = false">
<f7-accordion-item :opened="collapseStates[categoryType.type]!.opened"
@accordion:open="collapseStates[categoryType.type]!.opened = true"
@accordion:close="collapseStates[categoryType.type]!.opened = false">
<f7-block-title>
<f7-accordion-toggle>
<f7-list strong inset dividers
class="combination-list-header"
:class="collapseStates[categoryType.type].opened ? 'combination-list-opened' : 'combination-list-closed'">
:class="collapseStates[categoryType.type]!.opened ? 'combination-list-opened' : 'combination-list-closed'">
<f7-list-item group-title>
<small>{{ getCategoryTypeName(categoryType.type) }}</small>
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates[categoryType.type].opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates[categoryType.type]!.opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
</f7-list-item>
</f7-list>
</f7-accordion-toggle>
</f7-block-title>
<f7-accordion-content :style="{ height: collapseStates[categoryType.type].opened ? 'auto' : '' }">
<f7-accordion-content :style="{ height: collapseStates[categoryType.type]!.opened ? 'auto' : '' }">
<f7-list strong inset dividers accordion-list class="combination-list-content" v-if="!hasAvailableCategory[categoryType.type]">
<f7-list-item :title="tt('No available category')"></f7-list-item>
</f7-list>
@@ -242,7 +242,7 @@ function updateAllSubCategoriesSelected(e: Event): void {
const categoryId = target.value;
const category = transactionCategoriesStore.allTransactionCategoriesMap[categoryId];
selectAllSubCategories(filterCategoryIds.value, category, !target.checked);
selectAllSubCategories(filterCategoryIds.value, !target.checked, category);
}
function selectAllCategories(): void {
@@ -51,22 +51,22 @@
</f7-list-item>
</f7-list>
<f7-accordion-item :opened="collapseStates['default'].opened"
@accordion:open="collapseStates['default'].opened = true"
@accordion:close="collapseStates['default'].opened = false">
<f7-accordion-item :opened="collapseStates['default']!.opened"
@accordion:open="collapseStates['default']!.opened = true"
@accordion:close="collapseStates['default']!.opened = false">
<f7-block-title>
<f7-accordion-toggle>
<f7-list strong inset dividers
class="combination-list-header"
:class="collapseStates['default'].opened ? 'combination-list-opened' : 'combination-list-closed'">
:class="collapseStates['default']!.opened ? 'combination-list-opened' : 'combination-list-closed'">
<f7-list-item group-title>
<small>{{ tt('Tags') }}</small>
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates['default'].opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates['default']!.opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
</f7-list-item>
</f7-list>
</f7-accordion-toggle>
</f7-block-title>
<f7-accordion-content :style="{ height: collapseStates['default'].opened ? 'auto' : '' }">
<f7-accordion-content :style="{ height: collapseStates['default']!.opened ? 'auto' : '' }">
<f7-list strong inset dividers accordion-list class="combination-list-content">
<f7-list-item checkbox
:title="transactionTag.name"
@@ -119,13 +119,13 @@ function init(): void {
if (isString(query['value'])) {
try {
const filterItems = query['value'].split(':');
const amountCount = getAmountFilterParameterCount(filterItems[0]);
const amountCount = getAmountFilterParameterCount(filterItems[0] as string);
if (filterItems.length === 2 && amountCount === 1) {
queryAmount1 = parseInt(filterItems[1]);
queryAmount1 = parseInt(filterItems[1] as string);
} else if (filterItems.length === 3 && amountCount === 2) {
queryAmount1 = parseInt(filterItems[1]);
queryAmount2 = parseInt(filterItems[2]);
queryAmount1 = parseInt(filterItems[1] as string);
queryAmount2 = parseInt(filterItems[2] as string);
}
} catch (ex) {
logger.warn('cannot parse amount from filter value, original value is ' + query['value'], ex);
+5 -5
View File
@@ -721,9 +721,9 @@ const transactionDisplayScheduledFrequency = computed<string>(() => {
const items = (template.scheduledFrequency || '').split(',');
const scheduledFrequencyValues: number[] = [];
for (let i = 0; i < items.length; i++) {
if (items[i]) {
scheduledFrequencyValues.push(parseInt(items[i]));
for (const item of items) {
if (item) {
scheduledFrequencyValues.push(parseInt(item));
}
}
@@ -912,7 +912,7 @@ function init(): void {
if (query['id'] && responses[4] instanceof Transaction) {
fromTransaction = responses[4];
} else if (query['templateId'] && transactionTemplatesStore.allTransactionTemplatesMap && transactionTemplatesStore.allTransactionTemplatesMap[TemplateType.Normal.type]) {
fromTransaction = transactionTemplatesStore.allTransactionTemplatesMap[TemplateType.Normal.type][query['templateId']];
fromTransaction = (transactionTemplatesStore.allTransactionTemplatesMap[TemplateType.Normal.type] as Record<string, TransactionTemplate>)[query['templateId']] ?? null;
if (fromTransaction) {
addByTemplateId.value = fromTransaction.id;
@@ -1163,7 +1163,7 @@ function uploadPicture(event: Event): void {
return;
}
const pictureFile = el.files[0];
const pictureFile = el.files[0] as File;
el.value = '';
+8 -8
View File
@@ -53,6 +53,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
import { useTokensStore } from '@/stores/token.ts';
import { itemAndIndex, reversedItemAndIndex } from '@/core/base.ts';
import { TextDirection } from '@/core/text.ts';
import { type TokenInfoResponse, SessionInfo } from '@/models/token.ts';
@@ -94,8 +95,7 @@ const sessions = computed<MobilePageSessionInfo[]>(() => {
return sessions;
}
for (let i = 0; i < tokens.value.length; i++) {
const token = tokens.value[i];
for (const token of tokens.value) {
const sessionInfo = parseSessionInfo(token);
sessions.push(new MobilePageSessionInfo(sessionInfo));
}
@@ -171,9 +171,9 @@ function revoke(session: SessionInfo): void {
hideLoading();
onSwipeoutDeleted(getTokenDomId(session.tokenId), () => {
for (let i = 0; i < tokens.value.length; i++) {
if (tokens.value[i].tokenId === session.tokenId) {
tokens.value.splice(i, 1);
for (const [ token, index ] of itemAndIndex(tokens.value)) {
if (token.tokenId === session.tokenId) {
tokens.value.splice(index, 1);
}
}
});
@@ -198,9 +198,9 @@ function revokeAll(): void {
tokensStore.revokeAllTokens().then(() => {
hideLoading();
for (let i = tokens.value.length - 1; i >= 0; i--) {
if (!tokens.value[i].isCurrent) {
tokens.value.splice(i, 1);
for (const [ token, index ] of reversedItemAndIndex(tokens.value)) {
if (!token.isCurrent) {
tokens.value.splice(index, 1);
}
}
+3 -3
View File
@@ -666,9 +666,9 @@ const allLanguages = computed<LanguageOption[]>(() => getAllLanguageOptions(true
const allCurrencies = computed<LocalizedCurrencyInfo[]>(() => getAllCurrencies());
const currentLanguageName = computed<string>(() => {
for (let i = 0; i < allLanguages.value.length; i++) {
if (allLanguages.value[i].languageTag === newProfile.value.language) {
return allLanguages.value[i].nativeDisplayName;
for (const lang of allLanguages.value) {
if (lang.languageTag === newProfile.value.language) {
return lang.nativeDisplayName;
}
}