mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-14 15:07:33 +08:00
use for-of statements to replace for and for-in
This commit is contained in:
@@ -69,9 +69,7 @@ export function useAccountBalanceTrendsChartBase(props: CommonAccountBalanceTren
|
||||
let minUnixTimeClosingBalance = 0;
|
||||
let maxUnixTimeClosingBalance = 0;
|
||||
|
||||
for (let i = 0; i < props.items.length; i++) {
|
||||
const item = props.items[i];
|
||||
|
||||
for (const item of props.items) {
|
||||
if (item.time < minUnixTime) {
|
||||
minUnixTime = item.time;
|
||||
minUnixTimeOpeningBalance = item.accountOpeningBalance;
|
||||
@@ -120,8 +118,7 @@ export function useAccountBalanceTrendsChartBase(props: CommonAccountBalanceTren
|
||||
|
||||
const dayDataItemsMap: Record<number, TransactionReconciliationStatementResponseItem[]> = {};
|
||||
|
||||
for (let i = 0; i < props.items.length; i++) {
|
||||
const dateItem = props.items[i];
|
||||
for (const dateItem of props.items) {
|
||||
let dateRangeMinUnixTime = 0;
|
||||
|
||||
if (props.dateAggregationType === ChartDateAggregationType.Year.type) {
|
||||
@@ -149,8 +146,7 @@ export function useAccountBalanceTrendsChartBase(props: CommonAccountBalanceTren
|
||||
let lastMedianBalance = lastClosingBalance;
|
||||
let lastAverageBalance = lastClosingBalance;
|
||||
|
||||
for (let i = 0; i < allDateRanges.value.length; i++) {
|
||||
const dateRange = allDateRanges.value[i];
|
||||
for (const dateRange of allDateRanges.value) {
|
||||
const dataItems = dayDataItemsMap[dateRange.minUnixTime];
|
||||
|
||||
let displayDate = '';
|
||||
@@ -176,11 +172,11 @@ export function useAccountBalanceTrendsChartBase(props: CommonAccountBalanceTren
|
||||
return data1.time - data2.time;
|
||||
});
|
||||
|
||||
const openingBalance = dataItems[0].accountOpeningBalance;
|
||||
const closingBalance = dataItems[dataItems.length - 1].accountClosingBalance;
|
||||
const openingBalance = dataItems[0]!.accountOpeningBalance;
|
||||
const closingBalance = dataItems[dataItems.length - 1]!.accountClosingBalance;
|
||||
const minimumBalance = Math.min(...dataItems.map(item => item.accountClosingBalance));
|
||||
const maximumBalance = Math.max(...dataItems.map(item => item.accountClosingBalance));
|
||||
const medianBalance = dataItems[Math.floor(dataItems.length / 2)].accountClosingBalance;
|
||||
const medianBalance = dataItems[Math.floor(dataItems.length / 2)]!.accountClosingBalance;
|
||||
const averageBalance = Math.trunc(sumAmounts(dataItems.map(item => item.accountClosingBalance)) / dataItems.length);
|
||||
|
||||
if (props.account.isAsset) {
|
||||
|
||||
@@ -56,11 +56,11 @@ export function useDateRangeSelectionBase(props: CommonDateRangeSelectionProps)
|
||||
|
||||
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
|
||||
const beginDateTime = computed<string>(() => {
|
||||
const actualBeginUnixTime = getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(dateRange.value[0]), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes());
|
||||
const actualBeginUnixTime = getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(dateRange.value[0] as Date), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes());
|
||||
return formatUnixTimeToLongDateTime(actualBeginUnixTime);
|
||||
});
|
||||
const endDateTime = computed<string>(() => {
|
||||
const actualEndUnixTime = getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(dateRange.value[1]), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes());
|
||||
const actualEndUnixTime = getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(dateRange.value[1] as Date), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes());
|
||||
return formatUnixTimeToLongDateTime(actualEndUnixTime);
|
||||
});
|
||||
const presetRanges = computed<PresetDateRange[]>(() => {
|
||||
|
||||
@@ -42,11 +42,13 @@ export function useItemIconBase(props: CommonIconProps) {
|
||||
iconId = iconId.toString();
|
||||
}
|
||||
|
||||
if (!ALL_ACCOUNT_ICONS[iconId]) {
|
||||
const iconInfo = ALL_ACCOUNT_ICONS[iconId];
|
||||
|
||||
if (!iconInfo) {
|
||||
return DEFAULT_ACCOUNT_ICON.icon;
|
||||
}
|
||||
|
||||
return ALL_ACCOUNT_ICONS[iconId].icon;
|
||||
return iconInfo.icon;
|
||||
}
|
||||
|
||||
function getCategoryIcon(iconId: string | number): string {
|
||||
@@ -54,11 +56,13 @@ export function useItemIconBase(props: CommonIconProps) {
|
||||
iconId = iconId.toString();
|
||||
}
|
||||
|
||||
if (!ALL_CATEGORY_ICONS[iconId]) {
|
||||
const iconInfo = ALL_CATEGORY_ICONS[iconId];
|
||||
|
||||
if (!iconInfo) {
|
||||
return DEFAULT_CATEGORY_ICON.icon;
|
||||
}
|
||||
|
||||
return ALL_CATEGORY_ICONS[iconId].icon;
|
||||
return iconInfo.icon;
|
||||
}
|
||||
|
||||
function getAccountIconStyle(color?: ColorValue, defaultColor?: ColorStyleValue, additionalColorAttr?: string): Record<IconItemStyleName, IconItemStyleValue> {
|
||||
|
||||
@@ -57,8 +57,8 @@ export function useMonthRangeSelectionBase(props: CommonMonthRangeSelectionProps
|
||||
maxDate
|
||||
]);
|
||||
|
||||
const beginDateTime = computed<string>(() => formatUnixTimeToGregorianLikeLongYearMonth(getYearMonthFirstUnixTime(dateRange.value[0])));
|
||||
const endDateTime = computed<string>(() => formatUnixTimeToGregorianLikeLongYearMonth(getYearMonthLastUnixTime(dateRange.value[1])));
|
||||
const beginDateTime = computed<string>(() => formatUnixTimeToGregorianLikeLongYearMonth(getYearMonthFirstUnixTime(dateRange.value[0] as Year0BasedMonth)));
|
||||
const endDateTime = computed<string>(() => formatUnixTimeToGregorianLikeLongYearMonth(getYearMonthLastUnixTime(dateRange.value[1] as Year0BasedMonth)));
|
||||
|
||||
function getFinalMonthRange(): { minYearMonth: TextualYearMonth | '', maxYearMonth: TextualYearMonth | '' } | null {
|
||||
if (!dateRange.value[0] || !dateRange.value[1]) {
|
||||
@@ -69,8 +69,8 @@ export function useMonthRangeSelectionBase(props: CommonMonthRangeSelectionProps
|
||||
throw new Error('Date is too early');
|
||||
}
|
||||
|
||||
const minYearMonth = getYearMonthStringFromYear0BasedMonthObject(dateRange.value[0]);
|
||||
const maxYearMonth = getYearMonthStringFromYear0BasedMonthObject(dateRange.value[1]);
|
||||
const minYearMonth = getYearMonthStringFromYear0BasedMonthObject(dateRange.value[0] as Year0BasedMonth);
|
||||
const maxYearMonth = getYearMonthStringFromYear0BasedMonthObject(dateRange.value[1] as Year0BasedMonth);
|
||||
|
||||
return {
|
||||
minYearMonth,
|
||||
|
||||
@@ -146,7 +146,7 @@ function getDisplayYear(year: number): string {
|
||||
|
||||
function getDisplayMonth(month: number): string {
|
||||
if (isArray(dateTime.value)) {
|
||||
return getCalendarDisplayShortMonthFromUnixTime(getYearMonthDayDateTime(dateTime.value[0].getFullYear(), month + 1, 1).getUnixTime(), actualNumeralSystem.value);
|
||||
return getCalendarDisplayShortMonthFromUnixTime(getYearMonthDayDateTime(dateTime.value[0]!.getFullYear(), month + 1, 1).getUnixTime(), actualNumeralSystem.value);
|
||||
} else if (dateTime.value) {
|
||||
return getCalendarDisplayShortMonthFromUnixTime(getYearMonthDayDateTime(dateTime.value.getFullYear(), month + 1, 1).getUnixTime(), actualNumeralSystem.value);
|
||||
} else {
|
||||
|
||||
@@ -102,7 +102,7 @@ function getDisplayYear(year: number): string {
|
||||
|
||||
function getDisplayMonth(month: number): string {
|
||||
if (isArray(dateTime.value)) {
|
||||
return getCalendarDisplayShortMonthFromUnixTime(getYearMonthDayDateTime(dateTime.value[0].year, month + 1, 1).getUnixTime());
|
||||
return getCalendarDisplayShortMonthFromUnixTime(getYearMonthDayDateTime(dateTime.value[0]!.year, month + 1, 1).getUnixTime());
|
||||
} else {
|
||||
return getCalendarDisplayShortMonthFromUnixTime(getYearMonthDayDateTime(dateTime.value.year, month + 1, 1).getUnixTime());
|
||||
}
|
||||
|
||||
@@ -8,11 +8,15 @@ import { useTheme } from 'vuetify';
|
||||
import type { CallbackDataParams } from 'echarts/types/dist/shared';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
import { type CommonAccountBalanceTrendsChartProps, useAccountBalanceTrendsChartBase } from '@/components/base/AccountBalanceTrendsChartBase.ts'
|
||||
import {
|
||||
type AccountBalanceTrendsChartItem,
|
||||
type CommonAccountBalanceTrendsChartProps,
|
||||
useAccountBalanceTrendsChartBase
|
||||
} from '@/components/base/AccountBalanceTrendsChartBase.ts'
|
||||
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
|
||||
import type { NameValue } from '@/core/base.ts';
|
||||
import { type NameValue, itemAndIndex } from '@/core/base.ts';
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import type { ColorStyleValue } from '@/core/color.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
@@ -83,9 +87,7 @@ const allSeries = computed<AccountBalanceTrendsChartDataItem[]>(() => {
|
||||
series.itemStyle.borderColor0 = expenseIncomeAmountColor.expenseAmountColor;
|
||||
}
|
||||
|
||||
for (let i = 0; i < allDataItems.value.length; i++) {
|
||||
const item = allDataItems.value[i];
|
||||
|
||||
for (const item of allDataItems.value) {
|
||||
if (props.type === AccountBalanceTrendChartType.Candlestick.type) {
|
||||
series.data.push([
|
||||
item.openingBalance,
|
||||
@@ -110,13 +112,12 @@ const yAxisWidth = computed<number>(() => {
|
||||
return width;
|
||||
}
|
||||
|
||||
for (let i = 0; i < allSeries.value.length; i++) {
|
||||
for (let j = 0; j < allSeries.value[i].data.length; j++) {
|
||||
const data = allSeries.value[i].data[j];
|
||||
for (const series of allSeries.value) {
|
||||
for (const data of series.data) {
|
||||
let value: number;
|
||||
|
||||
if (isArray(data)) {
|
||||
value = data[1]; // for candlestick, use closing balance
|
||||
value = data[1] as number; // for candlestick, use closing balance
|
||||
} else {
|
||||
value = data as number; // for line or bar chart
|
||||
}
|
||||
@@ -172,8 +173,8 @@ const chartOptions = computed<object>(() => {
|
||||
},
|
||||
formatter: (params: CallbackDataParams[]) => {
|
||||
if (props.type === AccountBalanceTrendChartType.Candlestick.type) {
|
||||
const dataIndex = params[0].dataIndex;
|
||||
const dataItem = allDataItems.value[dataIndex];
|
||||
const dataIndex = params[0]!.dataIndex;
|
||||
const dataItem = allDataItems.value[dataIndex] as AccountBalanceTrendsChartItem;
|
||||
const displayItems: NameValue[] = [
|
||||
{
|
||||
name: tt('Opening Balance'),
|
||||
@@ -201,20 +202,20 @@ const chartOptions = computed<object>(() => {
|
||||
}
|
||||
];
|
||||
|
||||
let tooltip = `${params[0].name} ${props.legendName}<br/>`;
|
||||
let tooltip = `${params[0]!.name} ${props.legendName}<br/>`;
|
||||
|
||||
for (let i = 0; i < displayItems.length; i++) {
|
||||
tooltip += `<div><span class="chart-pointer" style="background-color: #${DEFAULT_CHART_COLORS[i]}"></span>`
|
||||
+ `<span>${displayItems[i].name}</span><span class="ms-5" style="float: inline-end">${displayItems[i].value}</span><br/>`
|
||||
for (const [displayItem, index] of itemAndIndex(displayItems)) {
|
||||
tooltip += `<div><span class="chart-pointer" style="background-color: #${DEFAULT_CHART_COLORS[index]}"></span>`
|
||||
+ `<span>${displayItem.name}</span><span class="ms-5" style="float: inline-end">${displayItem.value}</span><br/>`
|
||||
+ `</div>`;
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
} else {
|
||||
const amount = params[0].data as number;
|
||||
const amount = params[0]!.data as number;
|
||||
const value = formatAmountToLocalizedNumeralsWithCurrency(amount, props.account.currency);
|
||||
|
||||
return `${params[0].name}<br/>`
|
||||
return `${params[0]!.name}<br/>`
|
||||
+ '<div><span class="chart-pointer" style="background-color: #' + DEFAULT_CHART_COLORS[0] + '"></span>'
|
||||
+ `<span>${props.legendName}</span><span class="ms-5" style="float: inline-end">${value}</span><br/>`
|
||||
+ '</div>';
|
||||
|
||||
@@ -14,6 +14,7 @@ import { type CommonMonthlyTrendsChartProps, type MonthlyTrendsBarChartClickEven
|
||||
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
|
||||
import { itemAndIndex } from '@/core/base.ts';
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { type Year1BasedMonth, DateRangeScene } from '@/core/datetime.ts';
|
||||
import type { ColorStyleValue } from '@/core/color.ts';
|
||||
@@ -100,8 +101,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: string = '';
|
||||
|
||||
if (props.idField && item[props.idField]) {
|
||||
@@ -135,9 +135,7 @@ const itemsMap = computed<Record<string, Record<string, unknown>>>(() => {
|
||||
const allDisplayDateRanges = computed<string[]>(() => {
|
||||
const allDisplayDateRanges: string[] = [];
|
||||
|
||||
for (let i = 0; i < allDateRanges.value.length; i++) {
|
||||
const dateRange = allDateRanges.value[i];
|
||||
|
||||
for (const dateRange of allDateRanges.value) {
|
||||
if (props.dateAggregationType === ChartDateAggregationType.Year.type) {
|
||||
allDisplayDateRanges.push(formatUnixTimeToGregorianLikeShortYear(dateRange.minUnixTime));
|
||||
} else if (props.dateAggregationType === ChartDateAggregationType.FiscalYear.type && 'year' in dateRange) {
|
||||
@@ -155,9 +153,7 @@ const allDisplayDateRanges = computed<string[]>(() => {
|
||||
const allSeries = computed<MonthlyTrendsChartDataItem[]>(() => {
|
||||
const allSeries: MonthlyTrendsChartDataItem[] = [];
|
||||
|
||||
for (let i = 0; i < props.items.length; i++) {
|
||||
const item = props.items[i];
|
||||
|
||||
for (const [item, index] of itemAndIndex(props.items)) {
|
||||
if (props.hiddenField && item[props.hiddenField]) {
|
||||
continue;
|
||||
}
|
||||
@@ -165,8 +161,7 @@ const allSeries = computed<MonthlyTrendsChartDataItem[]>(() => {
|
||||
const allAmounts: number[] = [];
|
||||
const dateRangeAmountMap: Record<string, YearMonthDataItem[]> = {};
|
||||
|
||||
for (let j = 0; j < item.items.length; j++) {
|
||||
const dataItem = item.items[j];
|
||||
for (const dataItem of item.items) {
|
||||
let dateRangeKey = '';
|
||||
|
||||
if (props.dateAggregationType === ChartDateAggregationType.Year.type) {
|
||||
@@ -189,8 +184,7 @@ const allSeries = computed<MonthlyTrendsChartDataItem[]>(() => {
|
||||
dateRangeAmountMap[dateRangeKey] = dataItems;
|
||||
}
|
||||
|
||||
for (let j = 0; j < allDateRanges.value.length; j++) {
|
||||
const dateRange = allDateRanges.value[j];
|
||||
for (const dateRange of allDateRanges.value) {
|
||||
let dateRangeKey = '';
|
||||
|
||||
if (props.dateAggregationType === ChartDateAggregationType.Year.type) {
|
||||
@@ -207,9 +201,7 @@ const allSeries = computed<MonthlyTrendsChartDataItem[]>(() => {
|
||||
const dataItems = dateRangeAmountMap[dateRangeKey];
|
||||
|
||||
if (isArray(dataItems)) {
|
||||
for (let i = 0; i < dataItems.length; i++) {
|
||||
const dataItem = dataItems[i];
|
||||
|
||||
for (const dataItem of dataItems) {
|
||||
if (isNumber(dataItem[props.valueField])) {
|
||||
amount += dataItem[props.valueField] as number;
|
||||
}
|
||||
@@ -223,7 +215,7 @@ const allSeries = computed<MonthlyTrendsChartDataItem[]>(() => {
|
||||
id: (props.idField && item[props.idField]) ? item[props.idField] as string : getItemName(item[props.nameField] as string),
|
||||
name: (props.idField && item[props.idField]) ? item[props.idField] as string : getItemName(item[props.nameField] as string),
|
||||
itemStyle: {
|
||||
color: getDisplayColor(props.colorField && item[props.colorField] ? item[props.colorField] as string : DEFAULT_CHART_COLORS[i % DEFAULT_CHART_COLORS.length]),
|
||||
color: getDisplayColor(props.colorField && item[props.colorField] ? item[props.colorField] as string : DEFAULT_CHART_COLORS[index % DEFAULT_CHART_COLORS.length]),
|
||||
},
|
||||
selected: true,
|
||||
type: 'line',
|
||||
@@ -253,10 +245,9 @@ const yAxisWidth = computed<number>(() => {
|
||||
return width;
|
||||
}
|
||||
|
||||
for (let i = 0; i < allSeries.value.length; i++) {
|
||||
for (let j = 0; j < allSeries.value[i].data.length; j++) {
|
||||
const value = allSeries.value[i].data[j];
|
||||
|
||||
for (const series of allSeries.value) {
|
||||
for (const value of series.data) {
|
||||
if (value > maxValue) {
|
||||
maxValue = value;
|
||||
}
|
||||
@@ -311,12 +302,12 @@ const chartOptions = computed<object>(() => {
|
||||
let totalAmount = 0;
|
||||
const displayItems: MonthlyTrendsChartTooltipItem[] = [];
|
||||
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
const id = params[i].seriesId as string;
|
||||
for (const param of params) {
|
||||
const id = param.seriesId as string;
|
||||
const name = itemsMap.value[id] && props.nameField && itemsMap.value[id][props.nameField] ? getItemName(itemsMap.value[id][props.nameField] as string) : id;
|
||||
const color = params[i].color;
|
||||
const color = param.color;
|
||||
const displayOrders = itemsMap.value[id] && props.displayOrdersField && itemsMap.value[id][props.displayOrdersField] ? itemsMap.value[id][props.displayOrdersField] as number[] : [0];
|
||||
const amount = params[i].data as number;
|
||||
const amount = param.data as number;
|
||||
|
||||
displayItems.push({
|
||||
name: name,
|
||||
@@ -330,9 +321,7 @@ const chartOptions = computed<object>(() => {
|
||||
|
||||
sortStatisticsItems(displayItems, props.sortingType);
|
||||
|
||||
for (let i = 0; i < displayItems.length; i++) {
|
||||
const item = displayItems[i];
|
||||
|
||||
for (const item of displayItems) {
|
||||
if (displayItems.length === 1 || item.totalAmount !== 0) {
|
||||
const value = formatAmountToLocalizedNumeralsWithCurrency(item.totalAmount, props.defaultCurrency);
|
||||
tooltip += '<div><span class="chart-pointer" style="background-color: ' + item.color + '"></span>';
|
||||
@@ -349,7 +338,7 @@ const chartOptions = computed<object>(() => {
|
||||
+ '</div>' + tooltip;
|
||||
}
|
||||
|
||||
if (params.length && params[0].name) {
|
||||
if (params.length && params[0] && params[0].name) {
|
||||
tooltip = `${params[0].name}<br/>` + tooltip;
|
||||
}
|
||||
|
||||
@@ -410,9 +399,14 @@ function clickItem(e: ECElementEvent): void {
|
||||
}
|
||||
|
||||
const id = e.seriesId as string;
|
||||
const item = itemsMap.value[id];
|
||||
const item = itemsMap.value[id] as Record<string, unknown>;
|
||||
const itemId = props.idField ? item[props.idField] as string : '';
|
||||
const dateRange = allDateRanges.value[e.dataIndex];
|
||||
|
||||
if (!dateRange) {
|
||||
return;
|
||||
}
|
||||
|
||||
let minUnixTime = dateRange.minUnixTime;
|
||||
let maxUnixTime = dateRange.maxUnixTime;
|
||||
|
||||
@@ -450,16 +444,16 @@ function exportData(): { headers: string[], data: string[][] } {
|
||||
|
||||
headers.push(tt('Date'));
|
||||
|
||||
for (let i = 0; i < allSeries.value.length; i++) {
|
||||
const id = allSeries.value[i].id;
|
||||
for (const series of allSeries.value) {
|
||||
const id = series.id;
|
||||
const name = itemsMap.value[id] && props.nameField && itemsMap.value[id][props.nameField] ? getItemName(itemsMap.value[id][props.nameField] as string) : id;
|
||||
headers.push(name);
|
||||
}
|
||||
|
||||
for (let i = 0; i < allDisplayDateRanges.value.length; i++) {
|
||||
for (const [displayDateRange, index] of itemAndIndex(allDisplayDateRanges.value)) {
|
||||
const row: string[] = [];
|
||||
row.push(allDisplayDateRanges.value[i]);
|
||||
row.push(...allSeries.value.map(item => formatAmountToWesternArabicNumeralsWithoutDigitGrouping(item.data[i])));
|
||||
row.push(displayDateRange);
|
||||
row.push(...allSeries.value.map(item => formatAmountToWesternArabicNumeralsWithoutDigitGrouping(item.data[index] ?? 0)));
|
||||
data.push(row);
|
||||
}
|
||||
|
||||
|
||||
@@ -252,8 +252,8 @@ function getTimerPickerItemStyle(textualValue: string, textualCurrentValue: stri
|
||||
return '';
|
||||
}
|
||||
|
||||
const minValue = parseInt(values[0].value);
|
||||
const maxValue = parseInt(values[values.length - 1].value);
|
||||
const minValue = parseInt(values[0]!.value);
|
||||
const maxValue = parseInt(values[values.length - 1]!.value);
|
||||
const value = parseInt(textualValue, 10);
|
||||
const currentValue = parseInt(textualCurrentValue, 10);
|
||||
let valueDiff = value - currentValue;
|
||||
@@ -327,7 +327,7 @@ function scrollToSelectedItem(itemsClass: string, itemClass: string, value: stri
|
||||
}
|
||||
|
||||
for (let i = 0; i < itemElements.length; i++) {
|
||||
const itemElement = itemElements[i];
|
||||
const itemElement = itemElements[i] as HTMLElement;
|
||||
|
||||
if ('offsetHeight' in itemsElement && 'offsetTop' in itemElement && 'offsetHeight' in itemElement
|
||||
&& (!itemElement.hasAttribute('data-items-index') || itemElement.getAttribute('data-items-index') === '1')
|
||||
|
||||
@@ -95,6 +95,7 @@ import { type CommonMonthlyTrendsChartProps, type MonthlyTrendsBarChartClickEven
|
||||
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
|
||||
import { itemAndIndex } from '@/core/base.ts';
|
||||
import { type Year1BasedMonth, type UnixTimeRange, DateRangeScene } from '@/core/datetime.ts';
|
||||
import type { ColorStyleValue } from '@/core/color.ts';
|
||||
import { ChartDateAggregationType } from '@/core/statistics.ts';
|
||||
@@ -173,9 +174,7 @@ const allDisplayDataItems = computed<MonthlyTrendsBarChartData>(() => {
|
||||
const allDateRangeItemsMap: Record<string, MonthlyTrendsBarChartDataAmount[]> = {};
|
||||
const legends: TrendsBarChartLegend[] = [];
|
||||
|
||||
for (let i = 0; i < props.items.length; i++) {
|
||||
const item = props.items[i];
|
||||
|
||||
for (const [item, index] of itemAndIndex(props.items)) {
|
||||
if (props.hiddenField && item[props.hiddenField]) {
|
||||
continue;
|
||||
}
|
||||
@@ -185,7 +184,7 @@ const allDisplayDataItems = computed<MonthlyTrendsBarChartData>(() => {
|
||||
const legend: TrendsBarChartLegend = {
|
||||
id: id,
|
||||
name: (props.nameField && item[props.nameField]) ? getItemName(item[props.nameField] as string) : id,
|
||||
color: getDisplayColor(props.colorField && item[props.colorField] ? item[props.colorField] as string : DEFAULT_CHART_COLORS[i % DEFAULT_CHART_COLORS.length]),
|
||||
color: getDisplayColor(props.colorField && item[props.colorField] ? item[props.colorField] as string : DEFAULT_CHART_COLORS[index % DEFAULT_CHART_COLORS.length]),
|
||||
displayOrders: (props.displayOrdersField && item[props.displayOrdersField]) ? item[props.displayOrdersField] as number[] : [0]
|
||||
};
|
||||
|
||||
@@ -197,8 +196,7 @@ const allDisplayDataItems = computed<MonthlyTrendsBarChartData>(() => {
|
||||
|
||||
const dateRangeItemMap: Record<string, MonthlyTrendsBarChartDataAmount> = {};
|
||||
|
||||
for (let j = 0; j < item.items.length; j++) {
|
||||
const dataItem = item.items[j];
|
||||
for (const dataItem of item.items) {
|
||||
let dateRangeKey = '';
|
||||
|
||||
if (props.dateAggregationType === ChartDateAggregationType.Year.type) {
|
||||
@@ -216,7 +214,7 @@ const allDisplayDataItems = computed<MonthlyTrendsBarChartData>(() => {
|
||||
}
|
||||
|
||||
if (dateRangeItemMap[dateRangeKey]) {
|
||||
dateRangeItemMap[dateRangeKey].totalAmount += (props.valueField && isNumber(dataItem[props.valueField])) ? dataItem[props.valueField] as number : 0;
|
||||
dateRangeItemMap[dateRangeKey]!.totalAmount += (props.valueField && isNumber(dataItem[props.valueField])) ? dataItem[props.valueField] as number : 0;
|
||||
} else {
|
||||
const allDataItems: MonthlyTrendsBarChartDataAmount[] = allDateRangeItemsMap[dateRangeKey] || [];
|
||||
const finalDataItem: MonthlyTrendsBarChartDataAmount = Object.assign({}, legend, {
|
||||
@@ -233,8 +231,7 @@ const allDisplayDataItems = computed<MonthlyTrendsBarChartData>(() => {
|
||||
const finalDataItems: MonthlyTrendsBarChartDataItem[] = [];
|
||||
let maxTotalAmount = 0;
|
||||
|
||||
for (let i = 0; i < allDateRanges.value.length; i++) {
|
||||
const dateRange = allDateRanges.value[i];
|
||||
for (const dateRange of allDateRanges.value) {
|
||||
let dateRangeKey = '';
|
||||
|
||||
if (props.dateAggregationType === ChartDateAggregationType.Year.type) {
|
||||
@@ -265,12 +262,12 @@ const allDisplayDataItems = computed<MonthlyTrendsBarChartData>(() => {
|
||||
|
||||
sortStatisticsItems(dataItems, props.sortingType);
|
||||
|
||||
for (let j = 0; j < dataItems.length; j++) {
|
||||
if (dataItems[j].totalAmount > 0) {
|
||||
totalPositiveAmount += dataItems[j].totalAmount;
|
||||
for (const dataItem of dataItems) {
|
||||
if (dataItem.totalAmount > 0) {
|
||||
totalPositiveAmount += dataItem.totalAmount;
|
||||
}
|
||||
|
||||
totalAmount += dataItems[j].totalAmount;
|
||||
totalAmount += dataItem.totalAmount;
|
||||
}
|
||||
|
||||
if (totalAmount > maxTotalAmount) {
|
||||
@@ -289,11 +286,11 @@ const allDisplayDataItems = computed<MonthlyTrendsBarChartData>(() => {
|
||||
finalDataItems.push(finalDataItem);
|
||||
}
|
||||
|
||||
for (let i = 0; i < finalDataItems.length; i++) {
|
||||
if (maxTotalAmount > 0 && finalDataItems[i].totalAmount > 0) {
|
||||
finalDataItems[i].percent = 100.0 * finalDataItems[i].totalAmount / maxTotalAmount;
|
||||
for (const finalDataItem of finalDataItems) {
|
||||
if (maxTotalAmount > 0 && finalDataItem.totalAmount > 0) {
|
||||
finalDataItem.percent = 100.0 * finalDataItem.totalAmount / maxTotalAmount;
|
||||
} else {
|
||||
finalDataItems[i].percent = 0.0;
|
||||
finalDataItem.percent = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,9 +303,7 @@ const allDisplayDataItems = computed<MonthlyTrendsBarChartData>(() => {
|
||||
function clickItem(item: MonthlyTrendsBarChartDataItem): void {
|
||||
let itemId = '';
|
||||
|
||||
for (let i = 0; i < props.items.length; i++) {
|
||||
const item = props.items[i];
|
||||
|
||||
for (const item of props.items) {
|
||||
if (!props.hiddenField || item[props.hiddenField]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -143,8 +143,8 @@ const allTags = computed<TransactionTag[]>(() => {
|
||||
|
||||
const noAvailableTag = computed<boolean>(() => {
|
||||
if (transactionTagsStore.allTransactionTags) {
|
||||
for (let i = 0; i < transactionTagsStore.allTransactionTags.length; i++) {
|
||||
if (!transactionTagsStore.allTransactionTags[i].hidden) {
|
||||
for (const transactionTag of transactionTagsStore.allTransactionTags) {
|
||||
if (!transactionTag.hidden) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+37
-67
@@ -1,3 +1,4 @@
|
||||
import { itemAndIndex, keys, keysIfValueEquals, values } from '@/core/base.ts';
|
||||
import { AccountType, AccountCategory } from '@/core/account.ts';
|
||||
import { PARENT_ACCOUNT_CURRENCY_PLACEHOLDER } from '@/consts/currency.ts';
|
||||
import { type AccountBalance, type CategorizedAccount, type AccountCategoriesWithVisibleCount, Account } from '@/models/account.ts';
|
||||
@@ -5,9 +6,7 @@ import { type AccountBalance, type CategorizedAccount, type AccountCategoriesWit
|
||||
export function getCategorizedAccountsMap(allAccounts: Account[]): Record<number, CategorizedAccount> {
|
||||
const ret: Record<number, CategorizedAccount> = {};
|
||||
|
||||
for (let i = 0; i < allAccounts.length; i++) {
|
||||
const account = allAccounts[i];
|
||||
|
||||
for (const account of allAccounts) {
|
||||
if (!ret[account.category]) {
|
||||
const categoryInfo = AccountCategory.valueOf(account.category);
|
||||
|
||||
@@ -21,8 +20,10 @@ export function getCategorizedAccountsMap(allAccounts: Account[]): Record<number
|
||||
}
|
||||
}
|
||||
|
||||
if (ret[account.category]) {
|
||||
const accountList = ret[account.category].accounts;
|
||||
const categorizedAccount = ret[account.category];
|
||||
|
||||
if (categorizedAccount) {
|
||||
const accountList = categorizedAccount.accounts;
|
||||
accountList.push(account);
|
||||
}
|
||||
}
|
||||
@@ -35,15 +36,16 @@ export function getCategorizedAccounts(allAccounts: Account[]): CategorizedAccou
|
||||
const allCategories = AccountCategory.values();
|
||||
const categorizedAccounts = getCategorizedAccountsMap(allAccounts);
|
||||
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
const category = allCategories[i];
|
||||
|
||||
for (const category of allCategories) {
|
||||
if (!categorizedAccounts[category.type]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const accountCategory = categorizedAccounts[category.type];
|
||||
ret.push(accountCategory);
|
||||
|
||||
if (accountCategory) {
|
||||
ret.push(accountCategory);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -56,14 +58,11 @@ export function getAccountMapByName(allAccounts: Account[]): Record<string, Acco
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (let i = 0; i < allAccounts.length; i++) {
|
||||
const account = allAccounts[i];
|
||||
|
||||
for (const account of allAccounts) {
|
||||
if (account.type === AccountType.SingleAccount.type) {
|
||||
ret[account.name] = account;
|
||||
} else 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) {
|
||||
ret[subAccount.name] = subAccount;
|
||||
}
|
||||
}
|
||||
@@ -76,28 +75,26 @@ export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap: R
|
||||
const ret: AccountCategoriesWithVisibleCount[] = [];
|
||||
const allCategories = AccountCategory.values();
|
||||
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
const accountCategory = allCategories[i];
|
||||
for (const accountCategory of allCategories) {
|
||||
const categorizedAccount = categorizedAccountsMap[accountCategory.type];
|
||||
|
||||
if (!categorizedAccountsMap[accountCategory.type] || !categorizedAccountsMap[accountCategory.type].accounts) {
|
||||
if (!categorizedAccount || !categorizedAccount.accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const allAccounts = categorizedAccountsMap[accountCategory.type].accounts;
|
||||
const allAccounts = categorizedAccount.accounts;
|
||||
const allSubAccounts: Record<string, Account[]> = {};
|
||||
const allVisibleSubAccountCounts: Record<string, number> = {};
|
||||
const allFirstVisibleSubAccountIndexes: Record<string, number> = {};
|
||||
let allVisibleAccountCount = 0;
|
||||
let firstVisibleAccountIndex = -1;
|
||||
|
||||
for (let j = 0; j < allAccounts.length; j++) {
|
||||
const account = allAccounts[j];
|
||||
|
||||
for (const [account, accountIndex] of itemAndIndex(allAccounts)) {
|
||||
if (!account.hidden) {
|
||||
allVisibleAccountCount++;
|
||||
|
||||
if (firstVisibleAccountIndex === -1) {
|
||||
firstVisibleAccountIndex = j;
|
||||
firstVisibleAccountIndex = accountIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,14 +102,12 @@ export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap: R
|
||||
let visibleSubAccountCount = 0;
|
||||
let firstVisibleSubAccountIndex = -1;
|
||||
|
||||
for (let k = 0; k < account.subAccounts.length; k++) {
|
||||
const subAccount = account.subAccounts[k];
|
||||
|
||||
for (const [subAccount, subAccountIndex] of itemAndIndex(account.subAccounts)) {
|
||||
if (!subAccount.hidden) {
|
||||
visibleSubAccountCount++;
|
||||
|
||||
if (firstVisibleSubAccountIndex === -1) {
|
||||
firstVisibleSubAccountIndex = k;
|
||||
firstVisibleSubAccountIndex = subAccountIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,16 +142,14 @@ export function getAllFilteredAccountsBalance(categorizedAccounts: Record<number
|
||||
const allAccountCategories = AccountCategory.values();
|
||||
const ret: AccountBalance[] = [];
|
||||
|
||||
for (let categoryIdx = 0; categoryIdx < allAccountCategories.length; categoryIdx++) {
|
||||
const accountCategory = allAccountCategories[categoryIdx];
|
||||
for (const accountCategory of allAccountCategories) {
|
||||
const categorizedAccount = categorizedAccounts[accountCategory.type];
|
||||
|
||||
if (!categorizedAccounts[accountCategory.type] || !categorizedAccounts[accountCategory.type].accounts) {
|
||||
if (!categorizedAccount || !categorizedAccount.accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let accountIdx = 0; accountIdx < categorizedAccounts[accountCategory.type].accounts.length; accountIdx++) {
|
||||
const account = categorizedAccounts[accountCategory.type].accounts[accountIdx];
|
||||
|
||||
for (const account of categorizedAccount.accounts) {
|
||||
if (account.hidden || !accountFilter(account)) {
|
||||
continue;
|
||||
}
|
||||
@@ -169,9 +162,7 @@ export function getAllFilteredAccountsBalance(categorizedAccounts: Record<number
|
||||
currency: account.currency
|
||||
});
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) {
|
||||
for (let subAccountIdx = 0; subAccountIdx < account.subAccounts.length; subAccountIdx++) {
|
||||
const subAccount = account.subAccounts[subAccountIdx];
|
||||
|
||||
for (const subAccount of account.subAccounts) {
|
||||
if (subAccount.hidden || !accountFilter(subAccount)) {
|
||||
continue;
|
||||
}
|
||||
@@ -197,13 +188,7 @@ export function getFinalAccountIdsByFilteredAccountIds(allAccountsMap: Record<st
|
||||
return finalAccountIds;
|
||||
}
|
||||
|
||||
for (const accountId in allAccountsMap) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allAccountsMap, accountId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const account = allAccountsMap[accountId];
|
||||
|
||||
for (const account of values(allAccountsMap)) {
|
||||
if (filteredAccountIds && !isAccountOrSubAccountsAllChecked(account, filteredAccountIds)) {
|
||||
continue;
|
||||
}
|
||||
@@ -225,13 +210,13 @@ export function getUnifiedSelectedAccountsCurrencyOrDefaultCurrency(allAccountsM
|
||||
|
||||
let accountCurrency = '';
|
||||
|
||||
for (const accountId in selectedAccountIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(selectedAccountIds, accountId)) {
|
||||
for (const accountId of keysIfValueEquals(selectedAccountIds, true)) {
|
||||
const account = allAccountsMap[accountId];
|
||||
|
||||
if (!account) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const account = allAccountsMap[accountId];
|
||||
|
||||
if (account.currency === PARENT_ACCOUNT_CURRENCY_PLACEHOLDER) {
|
||||
continue;
|
||||
}
|
||||
@@ -258,19 +243,14 @@ export function selectAccountOrSubAccounts(filterAccountIds: Record<string, bool
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
for (const subAccount of account.subAccounts) {
|
||||
filterAccountIds[subAccount.id] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function selectAll(filterAccountIds: Record<string, boolean>, allAccountsMap: Record<string, Account>, skipHiddenAccount: boolean): void {
|
||||
for (const accountId in filterAccountIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(filterAccountIds, accountId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const accountId of keys(filterAccountIds)) {
|
||||
const account = allAccountsMap[accountId];
|
||||
|
||||
if (skipHiddenAccount && account && account.hidden) {
|
||||
@@ -284,11 +264,7 @@ export function selectAll(filterAccountIds: Record<string, boolean>, allAccounts
|
||||
}
|
||||
|
||||
export function selectNone(filterAccountIds: Record<string, boolean>, allAccountsMap: Record<string, Account>, skipHiddenAccount: boolean): void {
|
||||
for (const accountId in filterAccountIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(filterAccountIds, accountId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const accountId of keys(filterAccountIds)) {
|
||||
const account = allAccountsMap[accountId];
|
||||
|
||||
if (skipHiddenAccount && account && account.hidden) {
|
||||
@@ -302,11 +278,7 @@ export function selectNone(filterAccountIds: Record<string, boolean>, allAccount
|
||||
}
|
||||
|
||||
export function selectInvert(filterAccountIds: Record<string, boolean>, allAccountsMap: Record<string, Account>, skipHiddenAccount: boolean): void {
|
||||
for (const accountId in filterAccountIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(filterAccountIds, accountId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const accountId of keys(filterAccountIds)) {
|
||||
const account = allAccountsMap[accountId];
|
||||
|
||||
if (skipHiddenAccount && account && account.hidden) {
|
||||
@@ -324,8 +296,7 @@ export function isAccountOrSubAccountsAllChecked(account: Account, filterAccount
|
||||
return !filterAccountIds[account.id];
|
||||
}
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
for (const subAccount of account.subAccounts) {
|
||||
if (filterAccountIds[subAccount.id]) {
|
||||
return false;
|
||||
}
|
||||
@@ -341,8 +312,7 @@ export function isAccountOrSubAccountsHasButNotAllChecked(account: Account, filt
|
||||
|
||||
let checkedCount = 0;
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
for (const subAccount of account.subAccounts) {
|
||||
if (!filterAccountIds[subAccount.id]) {
|
||||
checkedCount++;
|
||||
}
|
||||
|
||||
+2
-2
@@ -20,8 +20,8 @@ export function getColorsInRows(allColorValues: ColorValue[], itemPerRow: number
|
||||
ret[++rowCount] = [];
|
||||
}
|
||||
|
||||
ret[rowCount].push({
|
||||
color: allColorValues[i]
|
||||
ret[rowCount]!.push({
|
||||
color: allColorValues[i] as ColorValue
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+13
-8
@@ -4,12 +4,15 @@ import { replaceAll } from './common.ts';
|
||||
|
||||
import logger from './logger.ts';
|
||||
|
||||
type Operator = '+' | '-' | '*' | '/';
|
||||
type OperatorAndParenthesis = Operator | '(' | ')';
|
||||
|
||||
const maxAllowedDecimalCount = 6;
|
||||
const normalizeFactor: number = 1000000;
|
||||
const normalizedDecimalsMaxZeroString: string = '000000';
|
||||
const normalizedNumberToAmountFactor: number = 10000; // 1000000 / 100
|
||||
|
||||
const operatorPriority: Record<string, number> = {
|
||||
const operatorPriority: Record<Operator, number> = {
|
||||
'+': 1,
|
||||
'-': 1,
|
||||
'*': 2,
|
||||
@@ -48,20 +51,20 @@ function checkNumberRange(num: number): void {
|
||||
|
||||
function toPostfixExprTokens(expr: string): string[] | null {
|
||||
const finalTokens: string[] = [];
|
||||
const operatorStack: string[] = [];
|
||||
const operatorStack: OperatorAndParenthesis[] = [];
|
||||
let currentNumberBuilder = '';
|
||||
let isLastTokenOperator = true;
|
||||
|
||||
expr = replaceAll(expr, ' ', '');
|
||||
|
||||
for (let i = 0; i < expr.length; i++) {
|
||||
const ch = expr[i];
|
||||
const ch = expr[i] as string;
|
||||
|
||||
// number
|
||||
if ('0' <= ch && ch <= '9' || ch === '.') {
|
||||
currentNumberBuilder += ch;
|
||||
continue
|
||||
} else if (ch === '-' && i + 1 < expr.length && '0' <= expr[i + 1] && expr[i + 1] <= '9' && currentNumberBuilder.length === 0 && isLastTokenOperator) {
|
||||
} else if (ch === '-' && i + 1 < expr.length && '0' <= (expr[i + 1] as string) && (expr[i + 1] as string) <= '9' && currentNumberBuilder.length === 0 && isLastTokenOperator) {
|
||||
currentNumberBuilder += ch;
|
||||
continue
|
||||
}
|
||||
@@ -84,13 +87,15 @@ function toPostfixExprTokens(expr: string): string[] | null {
|
||||
}
|
||||
|
||||
while (operatorStack.length > 0) {
|
||||
const topOperator = operatorStack[operatorStack.length - 1];
|
||||
const topOperator = operatorStack[operatorStack.length - 1] as OperatorAndParenthesis;
|
||||
|
||||
if (topOperator === '(') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (operatorPriority[topOperator] >= operatorPriority[ch]) {
|
||||
const isCurrentOperator = topOperator === '+' || topOperator === '-' || topOperator === '*' || topOperator === '/';
|
||||
|
||||
if (isCurrentOperator && operatorPriority[topOperator] >= operatorPriority[ch]) {
|
||||
finalTokens.push(topOperator);
|
||||
operatorStack.pop();
|
||||
} else {
|
||||
@@ -154,7 +159,7 @@ function evaluatePostfixExpr(tokens: string[]): number | null {
|
||||
const stack: number[] = [];
|
||||
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i];
|
||||
const token = tokens[i] as string;
|
||||
|
||||
switch (token) {
|
||||
case '+':
|
||||
@@ -211,7 +216,7 @@ function evaluatePostfixExpr(tokens: string[]): number | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
return stack[0];
|
||||
return stack[0] as number;
|
||||
}
|
||||
export function evaluateExpressionToAmount(expr: string): number | undefined {
|
||||
if (!expr) {
|
||||
|
||||
+3
-3
@@ -13,8 +13,8 @@ import { isDefined, isString, isNumber, replaceAll, removeAll } from './common.t
|
||||
export function sumAmounts(amounts: number[]): number {
|
||||
let sum = 0;
|
||||
|
||||
for (let i = 0; i < amounts.length; i++) {
|
||||
sum += amounts[i];
|
||||
for (const amount of amounts) {
|
||||
sum += amount;
|
||||
}
|
||||
|
||||
return sum;
|
||||
@@ -292,7 +292,7 @@ export function formatExchangeRateAmount(exchangeRateAmount: number, options: Nu
|
||||
}
|
||||
}
|
||||
|
||||
export function getAdaptiveDisplayAmountRate(amount1: number, amount2: number, fromExchangeRate: { rate: string }, toExchangeRate: { rate: string }, options: NumberFormatOptions): string | null {
|
||||
export function getAdaptiveDisplayAmountRate(amount1: number, amount2: number, options: NumberFormatOptions, fromExchangeRate?: { rate: string }, toExchangeRate?: { rate: string }): string | null {
|
||||
const numeralSystem = options.numeralSystem || NumeralSystem.Default;
|
||||
|
||||
if (!amount1 || !amount2 || amount1 === amount2) {
|
||||
|
||||
+3
-5
@@ -1,3 +1,5 @@
|
||||
import { keys } from '@/core/base.ts';
|
||||
|
||||
import type {
|
||||
ApplicationSettingKey,
|
||||
ApplicationSettingValue,
|
||||
@@ -28,11 +30,7 @@ function getStoredApplicationSettings(): BaseApplicationSetting {
|
||||
export function getApplicationSettings(): ApplicationSettings {
|
||||
const storedApplicationSettings = getStoredApplicationSettings();
|
||||
|
||||
for (const key in storedApplicationSettings) {
|
||||
if (!Object.prototype.hasOwnProperty.call(storedApplicationSettings, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const key of keys(storedApplicationSettings)) {
|
||||
if (typeof(DEFAULT_APPLICATION_SETTINGS[key]) === 'object') {
|
||||
storedApplicationSettings[key] = Object.assign({}, DEFAULT_APPLICATION_SETTINGS[key], storedApplicationSettings[key]);
|
||||
}
|
||||
|
||||
+11
-10
@@ -1,8 +1,9 @@
|
||||
import { reversed } from '@/core/base.ts';
|
||||
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||
|
||||
export function isNoAvailableTag(tags: TransactionTag[], showHidden: boolean): boolean {
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
if (showHidden || !tags[i].hidden) {
|
||||
for (const tag of tags) {
|
||||
if (showHidden || !tag.hidden) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -13,8 +14,8 @@ export function isNoAvailableTag(tags: TransactionTag[], showHidden: boolean): b
|
||||
export function getAvailableTagCount(tags: TransactionTag[], showHidden: boolean): number {
|
||||
let count = 0;
|
||||
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
if (showHidden || !tags[i].hidden) {
|
||||
for (const tag of tags) {
|
||||
if (showHidden || !tag.hidden) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -23,9 +24,9 @@ export function getAvailableTagCount(tags: TransactionTag[], showHidden: boolean
|
||||
}
|
||||
|
||||
export function getFirstShowingId(tags: TransactionTag[], showHidden: boolean): string | null {
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
if (showHidden || !tags[i].hidden) {
|
||||
return tags[i].id;
|
||||
for (const tag of tags) {
|
||||
if (showHidden || !tag.hidden) {
|
||||
return tag.id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +34,9 @@ export function getFirstShowingId(tags: TransactionTag[], showHidden: boolean):
|
||||
}
|
||||
|
||||
export function getLastShowingId(tags: TransactionTag[], showHidden: boolean): string | null {
|
||||
for (let i = tags.length - 1; i >= 0; i--) {
|
||||
if (showHidden || !tags[i].hidden) {
|
||||
return tags[i].id;
|
||||
for (const tag of reversed(tags)) {
|
||||
if (showHidden || !tag.hidden) {
|
||||
return tag.id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-10
@@ -1,8 +1,9 @@
|
||||
import { reversed } from '@/core/base.ts';
|
||||
import { TransactionTemplate } from '@/models/transaction_template.ts';
|
||||
|
||||
export function isNoAvailableTemplate(templates: TransactionTemplate[], showHidden: boolean): boolean {
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
if (showHidden || !templates[i].hidden) {
|
||||
for (const template of templates) {
|
||||
if (showHidden || !template.hidden) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -13,8 +14,8 @@ export function isNoAvailableTemplate(templates: TransactionTemplate[], showHidd
|
||||
export function getAvailableTemplateCount(templates: TransactionTemplate[], showHidden: boolean): number {
|
||||
let count = 0;
|
||||
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
if (showHidden || !templates[i].hidden) {
|
||||
for (const template of templates) {
|
||||
if (showHidden || !template.hidden) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -23,9 +24,9 @@ export function getAvailableTemplateCount(templates: TransactionTemplate[], show
|
||||
}
|
||||
|
||||
export function getFirstShowingId(templates: TransactionTemplate[], showHidden: boolean): string | null {
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
if (showHidden || !templates[i].hidden) {
|
||||
return templates[i].id;
|
||||
for (const template of templates) {
|
||||
if (showHidden || !template.hidden) {
|
||||
return template.id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +34,9 @@ export function getFirstShowingId(templates: TransactionTemplate[], showHidden:
|
||||
}
|
||||
|
||||
export function getLastShowingId(templates: TransactionTemplate[], showHidden: boolean): string | null {
|
||||
for (let i = templates.length - 1; i >= 0; i--) {
|
||||
if (showHidden || !templates[i].hidden) {
|
||||
return templates[i].id;
|
||||
for (const template of reversed(templates)) {
|
||||
if (showHidden || !template.hidden) {
|
||||
return template.id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
|
||||
}
|
||||
|
||||
if (!options.type && options.categoryId && options.categoryId !== '0' && allCategoriesMap[options.categoryId]) {
|
||||
const category = allCategoriesMap[options.categoryId];
|
||||
const category = allCategoriesMap[options.categoryId] as TransactionCategory;
|
||||
const type = categoryTypeToTransactionType(category.type);
|
||||
|
||||
if (isNumber(type)) {
|
||||
@@ -102,8 +102,8 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
|
||||
|
||||
if (allVisibleAccounts.length) {
|
||||
if (options.accountId && options.accountId !== '0') {
|
||||
for (let i = 0; i < allVisibleAccounts.length; i++) {
|
||||
if (allVisibleAccounts[i].id === options.accountId) {
|
||||
for (const account of allVisibleAccounts) {
|
||||
if (account.id === options.accountId) {
|
||||
transaction.sourceAccountId = options.accountId;
|
||||
transaction.destinationAccountId = options.accountId;
|
||||
break;
|
||||
@@ -115,7 +115,7 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
|
||||
if (defaultAccountId && allAccountsMap[defaultAccountId] && !allAccountsMap[defaultAccountId].hidden) {
|
||||
transaction.sourceAccountId = defaultAccountId;
|
||||
} else {
|
||||
transaction.sourceAccountId = allVisibleAccounts[0].id;
|
||||
transaction.sourceAccountId = allVisibleAccounts[0]!.id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
|
||||
if (defaultAccountId && allAccountsMap[defaultAccountId] && !allAccountsMap[defaultAccountId].hidden) {
|
||||
transaction.destinationAccountId = defaultAccountId;
|
||||
} else {
|
||||
transaction.destinationAccountId = allVisibleAccounts[0].id;
|
||||
transaction.destinationAccountId = allVisibleAccounts[0]!.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,8 +132,7 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
|
||||
const tagIds = options.tagIds.split(',');
|
||||
const finalTagIds = [];
|
||||
|
||||
for (let i = 0; i < tagIds.length; i++) {
|
||||
const tagId = tagIds[i];
|
||||
for (const tagId of tagIds) {
|
||||
const tag = allTagsMap[tagId];
|
||||
|
||||
if (tag && !tag.hidden) {
|
||||
|
||||
+87
-163
@@ -21,6 +21,11 @@ import {
|
||||
DEFAULT_CONTENT as PERSIAN_CALENDAR_DEFAULT_CONTENT
|
||||
} from '@/locales/calendar/persian/index.ts';
|
||||
|
||||
import {
|
||||
entries,
|
||||
keys
|
||||
} from '@/core/base.ts';
|
||||
|
||||
import {
|
||||
TextDirection
|
||||
} from '@/core/text.ts';
|
||||
@@ -257,12 +262,7 @@ export function getI18nOptions(): object {
|
||||
messages: (function () {
|
||||
const messages: Record<string, object> = {};
|
||||
|
||||
for (const languageKey in ALL_LANGUAGES) {
|
||||
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const languageInfo = ALL_LANGUAGES[languageKey];
|
||||
for (const [languageKey, languageInfo] of entries(ALL_LANGUAGES)) {
|
||||
messages[languageKey] = languageInfo.content;
|
||||
}
|
||||
|
||||
@@ -274,13 +274,7 @@ export function getI18nOptions(): object {
|
||||
export function getRtlLocales(): Record<string, boolean> {
|
||||
const rtlLocales: Record<string, boolean> = {};
|
||||
|
||||
for (const languageKey in ALL_LANGUAGES) {
|
||||
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const languageInfo = ALL_LANGUAGES[languageKey];
|
||||
|
||||
for (const [languageKey, languageInfo] of entries(ALL_LANGUAGES)) {
|
||||
if (languageInfo.textDirection === 'rtl') {
|
||||
rtlLocales[languageKey] = true;
|
||||
}
|
||||
@@ -346,7 +340,7 @@ export function useI18n() {
|
||||
|
||||
// fallback to use marco language tag
|
||||
if (languageTagParts.length > 1) {
|
||||
browserLanguage = languageTagParts[0];
|
||||
browserLanguage = languageTagParts[0] as string;
|
||||
|
||||
// try to match marco language tag with full language tag in i18n file
|
||||
if (ALL_LANGUAGES[browserLanguage]) {
|
||||
@@ -373,24 +367,19 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
function getLanguageKeyFromLanguageAlias(alias: string): string | null {
|
||||
for (const languageKey in ALL_LANGUAGES) {
|
||||
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const [languageKey, languageInfo] of entries(ALL_LANGUAGES)) {
|
||||
if (languageKey.toLowerCase() === alias.toLowerCase()) {
|
||||
return languageKey;
|
||||
}
|
||||
|
||||
const langInfo = ALL_LANGUAGES[languageKey];
|
||||
const aliases = langInfo.aliases;
|
||||
const aliases = languageInfo.aliases;
|
||||
|
||||
if (!aliases || aliases.length < 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let i = 0; i < aliases.length; i++) {
|
||||
if (aliases[i].toLowerCase() === alias.toLowerCase()) {
|
||||
for (const aliasName of aliases) {
|
||||
if (aliasName.toLowerCase() === alias.toLowerCase()) {
|
||||
return languageKey;
|
||||
}
|
||||
}
|
||||
@@ -400,16 +389,12 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
function getLanguageKeyFromMarcoLanguageTag(languageTag: string): string | null {
|
||||
for (const languageKey in ALL_LANGUAGES) {
|
||||
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const languageKey of keys(ALL_LANGUAGES)) {
|
||||
if (languageKey.indexOf('-') < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const marcoLanguageTag = languageKey.split('-')[0];
|
||||
const marcoLanguageTag = languageKey.split('-')[0] as string;
|
||||
|
||||
if (marcoLanguageTag.toLowerCase() === languageTag.toLowerCase()) {
|
||||
return languageKey;
|
||||
@@ -422,7 +407,7 @@ export function useI18n() {
|
||||
function getLocalizedError(error: ErrorResponse): LocalizedError {
|
||||
if (error.errorCode === KnownErrorCode.ApiNotFound && SPECIFIED_API_NOT_FOUND_ERRORS[error.path]) {
|
||||
return {
|
||||
message: `${SPECIFIED_API_NOT_FOUND_ERRORS[error.path].message}`
|
||||
message: `${SPECIFIED_API_NOT_FOUND_ERRORS[error.path]!.message}`
|
||||
};
|
||||
}
|
||||
|
||||
@@ -432,8 +417,7 @@ export function useI18n() {
|
||||
};
|
||||
}
|
||||
|
||||
for (let i = 0; i < PARAMETERIZED_ERRORS.length; i++) {
|
||||
const errorInfo = PARAMETERIZED_ERRORS[i];
|
||||
for (const errorInfo of PARAMETERIZED_ERRORS) {
|
||||
const matches = error.errorMessage.match(errorInfo.regex);
|
||||
|
||||
if (matches && matches.length === errorInfo.parameters.length + 1) {
|
||||
@@ -443,7 +427,7 @@ export function useI18n() {
|
||||
return {
|
||||
key: param.field,
|
||||
localized: param.localized,
|
||||
value: matches[index + 1]
|
||||
value: matches[index + 1] as string
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -459,9 +443,7 @@ export function useI18n() {
|
||||
const localizedParameters: Record<string, string> = {};
|
||||
|
||||
if (parameters) {
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
const parameter = parameters[i];
|
||||
|
||||
for (const parameter of parameters) {
|
||||
if (parameter.localized) {
|
||||
localizedParameters[parameter.key] = t(`parameter.${parameter.value}`);
|
||||
} else {
|
||||
@@ -520,8 +502,7 @@ export function useI18n() {
|
||||
|
||||
const allCurrencyDisplayTypes = CurrencyDisplayType.values();
|
||||
|
||||
for (let i = 0; i < allCurrencyDisplayTypes.length; i++) {
|
||||
const type = allCurrencyDisplayTypes[i];
|
||||
for (const type of allCurrencyDisplayTypes) {
|
||||
const sampleValue = getFormattedAmountWithCurrency(12345, defaultCurrency, type, numeralSystem, decimalSeparator);
|
||||
const displayName = `${t(type.name)} (${sampleValue})`
|
||||
|
||||
@@ -534,7 +515,7 @@ export function useI18n() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getAllLocalizedCalendarTypes(allTypeAndNameArray: CalendarDisplayType[] | DateDisplayType[], localeDefaultType: CalendarDisplayType | DateDisplayType | undefined, systemDefaultType: CalendarDisplayType | DateDisplayType, languageDefaultValue: number): TypeAndDisplayName[] {
|
||||
function getAllLocalizedCalendarTypes(allCalendarDisplayTypeArray: CalendarDisplayType[] | DateDisplayType[], localeDefaultType: CalendarDisplayType | DateDisplayType | undefined, systemDefaultType: CalendarDisplayType | DateDisplayType, languageDefaultValue: number): TypeAndDisplayName[] {
|
||||
let defaultType: TypeAndName | undefined = localeDefaultType;
|
||||
|
||||
if (!defaultType) {
|
||||
@@ -548,12 +529,10 @@ export function useI18n() {
|
||||
displayName: `${t('Language Default')} (${t('calendar.' + defaultType.name)})`
|
||||
});
|
||||
|
||||
for (let i = 0; i < allTypeAndNameArray.length; i++) {
|
||||
const type = allTypeAndNameArray[i];
|
||||
|
||||
for (const calendarDisplayType of allCalendarDisplayTypeArray) {
|
||||
ret.push({
|
||||
type: type.type,
|
||||
displayName: t('calendar.' + type.name)
|
||||
type: calendarDisplayType.type,
|
||||
displayName: t('calendar.' + calendarDisplayType.name)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -563,12 +542,10 @@ export function useI18n() {
|
||||
function getLocalizedDisplayNameAndType(typeAndNames: TypeAndName[]): TypeAndDisplayName[] {
|
||||
const ret: TypeAndDisplayName[] = [];
|
||||
|
||||
for (let i = 0; i < typeAndNames.length; i++) {
|
||||
const nameAndType = typeAndNames[i];
|
||||
|
||||
for (const typeAndName of typeAndNames) {
|
||||
ret.push({
|
||||
type: nameAndType.type,
|
||||
displayName: t(nameAndType.name)
|
||||
type: typeAndName.type,
|
||||
displayName: t(typeAndName.name)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -583,12 +560,10 @@ export function useI18n() {
|
||||
displayName: t('System Default') + (defaultType.name ? ` (${t(defaultType.name)})` : '')
|
||||
});
|
||||
|
||||
for (let i = 0; i < typeAndNames.length; i++) {
|
||||
const nameAndType = typeAndNames[i];
|
||||
|
||||
for (const typeAndName of typeAndNames) {
|
||||
ret.push({
|
||||
type: nameAndType.type,
|
||||
displayName: t(nameAndType.name)
|
||||
type: typeAndName.type,
|
||||
displayName: t(typeAndName.name)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -610,13 +585,11 @@ export function useI18n() {
|
||||
displayName: `${t('Language Default')} (${defaultSeparatorType.symbol})`
|
||||
});
|
||||
|
||||
for (let i = 0; i < allSeparatorArray.length; i++) {
|
||||
const type = allSeparatorArray[i];
|
||||
|
||||
for (const separator of allSeparatorArray) {
|
||||
ret.push({
|
||||
type: type.type,
|
||||
symbol: type.symbol,
|
||||
displayName: `${t('numeral.' + type.name)} (${type.symbol})`
|
||||
type: separator.type,
|
||||
symbol: separator.symbol,
|
||||
displayName: `${t('numeral.' + separator.name)} (${separator.symbol})`
|
||||
});
|
||||
}
|
||||
|
||||
@@ -627,9 +600,7 @@ export function useI18n() {
|
||||
const ret: TypeAndDisplayName[] = [];
|
||||
const allTypes: ChartDateAggregationType[] = ChartDateAggregationType.values();
|
||||
|
||||
for (let i = 0; i < allTypes.length; i++) {
|
||||
const type = allTypes[i];
|
||||
|
||||
for (const type of allTypes) {
|
||||
ret.push({
|
||||
type: type.type,
|
||||
displayName: t(fullName ? type.fullName : `granularity.${type.shortName}`)
|
||||
@@ -643,8 +614,7 @@ export function useI18n() {
|
||||
const ret = [];
|
||||
const allMonths = Month.values();
|
||||
|
||||
for (let i = 0; i < allMonths.length; i++) {
|
||||
const month = allMonths[i];
|
||||
for (const month of allMonths) {
|
||||
ret.push(t(`datetime.${month.name}.${type}`));
|
||||
}
|
||||
|
||||
@@ -655,8 +625,7 @@ export function useI18n() {
|
||||
const ret = [];
|
||||
const allWeekDays = WeekDay.values();
|
||||
|
||||
for (let i = 0; i < allWeekDays.length; i++) {
|
||||
const weekDay = allWeekDays[i];
|
||||
for (const weekDay of allWeekDays) {
|
||||
ret.push(t(`datetime.${weekDay.name}.${type}`));
|
||||
}
|
||||
|
||||
@@ -952,17 +921,12 @@ export function useI18n() {
|
||||
function getAllLanguageOptions(includeSystemDefault: boolean): LanguageOption[] {
|
||||
const ret: LanguageOption[] = [];
|
||||
|
||||
for (const languageTag in ALL_LANGUAGES) {
|
||||
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageTag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const languageInfo = ALL_LANGUAGES[languageTag];
|
||||
for (const [languageKey, languageInfo] of entries(ALL_LANGUAGES)) {
|
||||
const displayName = languageInfo.displayName;
|
||||
const languageNameInCurrentLanguage = getLanguageDisplayName(languageInfo.name);
|
||||
|
||||
ret.push({
|
||||
languageTag: languageTag,
|
||||
languageTag: languageKey,
|
||||
displayName: languageNameInCurrentLanguage,
|
||||
nativeDisplayName: displayName
|
||||
});
|
||||
@@ -996,11 +960,7 @@ export function useI18n() {
|
||||
function getAllCurrencies(): LocalizedCurrencyInfo[] {
|
||||
const allCurrencies: LocalizedCurrencyInfo[] = [];
|
||||
|
||||
for (const currencyCode in ALL_CURRENCIES) {
|
||||
if (!Object.prototype.hasOwnProperty.call(ALL_CURRENCIES, currencyCode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const currencyCode of keys(ALL_CURRENCIES)) {
|
||||
const localizedCurrencyInfo: LocalizedCurrencyInfo = {
|
||||
currencyCode: currencyCode,
|
||||
displayName: getCurrencyName(currencyCode)
|
||||
@@ -1020,9 +980,7 @@ export function useI18n() {
|
||||
const allMeridiemIndicators = MeridiemIndicator.values();
|
||||
const localizedMeridiemIndicatorNames = [];
|
||||
|
||||
for (let i = 0; i < allMeridiemIndicators.length; i++) {
|
||||
const indicator = allMeridiemIndicators[i];
|
||||
|
||||
for (const indicator of allMeridiemIndicators) {
|
||||
localizedMeridiemIndicatorNames.push({
|
||||
name: t(`datetime.${indicator.name}.content`),
|
||||
value: indicator.name
|
||||
@@ -1061,7 +1019,7 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
for (let i = firstDayOfWeek; i < allWeekDays.length; i++) {
|
||||
const weekDay = allWeekDays[i];
|
||||
const weekDay = allWeekDays[i] as WeekDay;
|
||||
|
||||
ret.push({
|
||||
type: weekDay.type,
|
||||
@@ -1070,7 +1028,7 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
for (let i = 0; i < firstDayOfWeek; i++) {
|
||||
const weekDay = allWeekDays[i];
|
||||
const weekDay = allWeekDays[i] as WeekDay;
|
||||
|
||||
ret.push({
|
||||
type: weekDay.type,
|
||||
@@ -1092,8 +1050,7 @@ export function useI18n() {
|
||||
displayName: `${t('Language Default')} (${formatCurrentTime(defaultFormat, dateTimeFormatOptions)})`
|
||||
});
|
||||
|
||||
for (let i = 0; i < allFormatArray.length; i++) {
|
||||
const formatType = allFormatArray[i];
|
||||
for (const formatType of allFormatArray) {
|
||||
const format = t(`format.${type}.${formatType.key}`);
|
||||
|
||||
ret.push({
|
||||
@@ -1110,9 +1067,7 @@ export function useI18n() {
|
||||
const ret: LocalizedDateRange[] = [];
|
||||
const allDateRanges = DateRange.values();
|
||||
|
||||
for (let i = 0; i < allDateRanges.length; i++) {
|
||||
const dateRange = allDateRanges[i];
|
||||
|
||||
for (const dateRange of allDateRanges) {
|
||||
if (!dateRange.isAvailableForScene(scene)) {
|
||||
continue;
|
||||
}
|
||||
@@ -1158,9 +1113,7 @@ export function useI18n() {
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < recentDateRanges.length; i++) {
|
||||
const recentDateRange = recentDateRanges[i];
|
||||
|
||||
for (const recentDateRange of recentDateRanges) {
|
||||
allRecentMonthDateRanges.push({
|
||||
dateType: recentDateRange.dateType,
|
||||
minTime: recentDateRange.minTime,
|
||||
@@ -1190,14 +1143,14 @@ export function useI18n() {
|
||||
const defaultTimezoneOffsetMinutes = getBrowserTimezoneOffsetMinutes();
|
||||
const allTimezoneInfos: LocalizedTimezoneInfo[] = [];
|
||||
|
||||
for (let i = 0; i < ALL_TIMEZONES.length; i++) {
|
||||
const utcOffset = (ALL_TIMEZONES[i].timezoneName !== UTC_TIMEZONE.timezoneName ? numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(getTimezoneOffset(ALL_TIMEZONES[i].timezoneName)) : '');
|
||||
const displayName = t(`timezone.${ALL_TIMEZONES[i].displayName}`);
|
||||
for (const timezoneInfo of ALL_TIMEZONES) {
|
||||
const utcOffset = (timezoneInfo.timezoneName !== UTC_TIMEZONE.timezoneName ? numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(getTimezoneOffset(timezoneInfo.timezoneName)) : '');
|
||||
const displayName = t(`timezone.${timezoneInfo.displayName}`);
|
||||
|
||||
allTimezoneInfos.push({
|
||||
name: ALL_TIMEZONES[i].timezoneName,
|
||||
name: timezoneInfo.timezoneName,
|
||||
utcOffset: utcOffset,
|
||||
utcOffsetMinutes: getTimezoneOffsetMinutes(ALL_TIMEZONES[i].timezoneName),
|
||||
utcOffsetMinutes: getTimezoneOffsetMinutes(timezoneInfo.timezoneName),
|
||||
displayName: displayName,
|
||||
displayNameWithUtcOffset: `(UTC${utcOffset}) ${displayName}`
|
||||
});
|
||||
@@ -1269,9 +1222,7 @@ export function useI18n() {
|
||||
|
||||
const allFiscalYearFormats = FiscalYearFormat.values();
|
||||
|
||||
for (let i = 0; i < allFiscalYearFormats.length; i++) {
|
||||
const fiscalYearFormat = allFiscalYearFormats[i];
|
||||
|
||||
for (const fiscalYearFormat of allFiscalYearFormats) {
|
||||
ret.push({
|
||||
type: fiscalYearFormat.type,
|
||||
displayName: formatTimeRangeToGregorianLikeFiscalYearFormat(fiscalYearFormat, currentFiscalYearRange, numeralSystem, calendarType),
|
||||
@@ -1298,9 +1249,7 @@ export function useI18n() {
|
||||
|
||||
const allNumeralSystemTypes = NumeralSystem.values();
|
||||
|
||||
for (let i = 0; i < allNumeralSystemTypes.length; i++) {
|
||||
const type = allNumeralSystemTypes[i];
|
||||
|
||||
for (const type of allNumeralSystemTypes) {
|
||||
ret.push({
|
||||
type: type.type,
|
||||
displayName: `${t('numeral.' + type.name)} (${type.textualAllDigits})`
|
||||
@@ -1329,8 +1278,7 @@ export function useI18n() {
|
||||
const allDigitGroupingTypes = DigitGroupingType.values();
|
||||
const numberCharacters = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits('123456789').split('');
|
||||
|
||||
for (let i = 0; i < allDigitGroupingTypes.length; i++) {
|
||||
const type = allDigitGroupingTypes[i];
|
||||
for (const type of allDigitGroupingTypes) {
|
||||
const sampleValue = type.format(numberCharacters, digitGroupingSymbol);
|
||||
|
||||
ret.push({
|
||||
@@ -1364,9 +1312,7 @@ export function useI18n() {
|
||||
|
||||
const allPresetAmountColors = PresetAmountColor.values();
|
||||
|
||||
for (let i = 0; i < allPresetAmountColors.length; i++) {
|
||||
const amountColor = allPresetAmountColors[i];
|
||||
|
||||
for (const amountColor of allPresetAmountColors) {
|
||||
ret.push({
|
||||
type: amountColor.type,
|
||||
displayName: t('color.amount.' + amountColor.name)
|
||||
@@ -1380,9 +1326,7 @@ export function useI18n() {
|
||||
const ret: LocalizedAccountCategory[] = [];
|
||||
const allCategories = AccountCategory.values();
|
||||
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
const accountCategory = allCategories[i];
|
||||
|
||||
for (const accountCategory of allCategories) {
|
||||
ret.push({
|
||||
type: accountCategory.type,
|
||||
displayName: t(accountCategory.name),
|
||||
@@ -1403,9 +1347,8 @@ export function useI18n() {
|
||||
categoryTypes.push(categoryType);
|
||||
}
|
||||
|
||||
for (let i = 0; i < categoryTypes.length; i++) {
|
||||
for (const categoryType of categoryTypes) {
|
||||
const categories: LocalizedPresetCategory[] = [];
|
||||
const categoryType = categoryTypes[i];
|
||||
let defaultCategories: PresetCategory[] = [];
|
||||
|
||||
if (categoryType === CategoryType.Income) {
|
||||
@@ -1416,9 +1359,7 @@ export function useI18n() {
|
||||
defaultCategories = DEFAULT_TRANSFER_CATEGORIES;
|
||||
}
|
||||
|
||||
for (let j = 0; j < defaultCategories.length; j++) {
|
||||
const category = defaultCategories[j];
|
||||
|
||||
for (const category of defaultCategories) {
|
||||
const submitCategory: LocalizedPresetCategory = {
|
||||
name: t('category.' + category.name, {}, { locale: locale }),
|
||||
type: categoryType,
|
||||
@@ -1427,8 +1368,7 @@ export function useI18n() {
|
||||
subCategories: []
|
||||
};
|
||||
|
||||
for (let k = 0; k < category.subCategories.length; k++) {
|
||||
const subCategory = category.subCategories[k];
|
||||
for (const subCategory of category.subCategories) {
|
||||
const submitSubCategory: LocalizedPresetSubCategory = {
|
||||
name: t('category.' + subCategory.name, {}, { locale: locale }),
|
||||
type: categoryType,
|
||||
@@ -1455,9 +1395,7 @@ export function useI18n() {
|
||||
return availableExchangeRates;
|
||||
}
|
||||
|
||||
for (let i = 0; i < exchangeRatesData.exchangeRates.length; i++) {
|
||||
const exchangeRate = exchangeRatesData.exchangeRates[i];
|
||||
|
||||
for (const exchangeRate of exchangeRatesData.exchangeRates) {
|
||||
availableExchangeRates.push({
|
||||
currencyCode: exchangeRate.currency,
|
||||
currencyDisplayName: getCurrencyName(exchangeRate.currency),
|
||||
@@ -1494,16 +1432,13 @@ export function useI18n() {
|
||||
function getAllSupportedImportFileCagtegoryAndTypes(): LocalizedImportFileCategoryAndTypes[] {
|
||||
const allSupportedImportFileCategoryAndTypes: LocalizedImportFileCategoryAndTypes[] = [];
|
||||
|
||||
for (let i = 0; i < SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES.length; i++) {
|
||||
const categoryAndTypes = SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES[i];
|
||||
|
||||
for (const categoryAndTypes of SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES) {
|
||||
const localizedCategoryAndTypes: LocalizedImportFileCategoryAndTypes = {
|
||||
displayCategoryName: t(categoryAndTypes.categoryName),
|
||||
fileTypes: []
|
||||
};
|
||||
|
||||
for (let j = 0; j < categoryAndTypes.fileTypes.length; j++) {
|
||||
const fileType = categoryAndTypes.fileTypes[j];
|
||||
for (const fileType of categoryAndTypes.fileTypes) {
|
||||
let document: LocalizedImportFileDocument | undefined;
|
||||
|
||||
if (fileType.document) {
|
||||
@@ -1517,7 +1452,7 @@ export function useI18n() {
|
||||
if (SUPPORTED_DOCUMENT_LANGUAGES_FOR_IMPORT_FILE[documentLanguage] === documentLanguage) {
|
||||
documentAnchor = t(`document.anchor.export_and_import.${fileType.document.anchor}`);
|
||||
} else if (SUPPORTED_DOCUMENT_LANGUAGES_FOR_IMPORT_FILE[documentLanguage]) {
|
||||
documentLanguage = SUPPORTED_DOCUMENT_LANGUAGES_FOR_IMPORT_FILE[documentLanguage];
|
||||
documentLanguage = SUPPORTED_DOCUMENT_LANGUAGES_FOR_IMPORT_FILE[documentLanguage] as string;
|
||||
documentAnchor = t(`document.anchor.export_and_import.${fileType.document.anchor}`, {}, { locale: documentLanguage });
|
||||
} else {
|
||||
documentLanguage = DEFAULT_DOCUMENT_LANGUAGE_FOR_IMPORT_FILE;
|
||||
@@ -1528,8 +1463,8 @@ export function useI18n() {
|
||||
documentAnchor = fileType.document.anchor;
|
||||
}
|
||||
|
||||
if (documentLanguage && documentLanguage !== getCurrentLanguageTag()) {
|
||||
documentDisplayLanguageName = getLanguageDisplayName(ALL_LANGUAGES[documentLanguage].name);
|
||||
if (documentLanguage && documentLanguage !== getCurrentLanguageTag() && ALL_LANGUAGES[documentLanguage]) {
|
||||
documentDisplayLanguageName = getLanguageDisplayName((ALL_LANGUAGES[documentLanguage] as LanguageInfo).name);
|
||||
}
|
||||
|
||||
if (documentLanguage) {
|
||||
@@ -1556,8 +1491,7 @@ export function useI18n() {
|
||||
const subTypes: LocalizedImportFileTypeSubType[] = [];
|
||||
|
||||
if (fileType.subTypes) {
|
||||
for (let k = 0; k < fileType.subTypes.length; k++) {
|
||||
const subType = fileType.subTypes[k];
|
||||
for (const subType of fileType.subTypes) {
|
||||
const localizedSubType: LocalizedImportFileTypeSubType = {
|
||||
type: subType.type,
|
||||
displayName: t(subType.name),
|
||||
@@ -1571,8 +1505,7 @@ export function useI18n() {
|
||||
const supportedEncodings: LocalizedImportFileTypeSupportedEncodings[] = [];
|
||||
|
||||
if (fileType.supportedEncodings) {
|
||||
for (let k = 0; k < fileType.supportedEncodings.length; k++) {
|
||||
const encoding = fileType.supportedEncodings[k];
|
||||
for (const encoding of fileType.supportedEncodings) {
|
||||
const localizedEncoding: LocalizedImportFileTypeSupportedEncodings = {
|
||||
encoding: encoding,
|
||||
displayName: t(`encoding.${encoding}`)
|
||||
@@ -1638,7 +1571,7 @@ export function useI18n() {
|
||||
|
||||
if (monthDays.length === 1) {
|
||||
return t('format.misc.monthDay', {
|
||||
ordinal: getMonthdayOrdinal(monthDays[0])
|
||||
ordinal: getMonthdayOrdinal(monthDays[0] as number)
|
||||
});
|
||||
} else {
|
||||
return t('format.misc.monthDays', {
|
||||
@@ -1657,16 +1590,14 @@ export function useI18n() {
|
||||
firstDayOfWeek = WeekDay.DefaultFirstDay.type;
|
||||
}
|
||||
|
||||
for (let i = 0; i < weekdayTypes.length; i++) {
|
||||
weekdayTypesMap[weekdayTypes[i]] = true;
|
||||
for (const weekdayType of weekdayTypes) {
|
||||
weekdayTypesMap[weekdayType] = true;
|
||||
}
|
||||
|
||||
const allWeekDays = getAllWeekDays(firstDayOfWeek);
|
||||
const finalWeekdayNames = [];
|
||||
|
||||
for (let i = 0; i < allWeekDays.length; i++) {
|
||||
const weekDay = allWeekDays[i];
|
||||
|
||||
for (const weekDay of allWeekDays) {
|
||||
if (weekdayTypesMap[weekDay.type]) {
|
||||
finalWeekdayNames.push(weekDay.displayName);
|
||||
}
|
||||
@@ -1894,9 +1825,7 @@ export function useI18n() {
|
||||
const dateTimeFormatOptions = getDateTimeFormatOptions();
|
||||
const gregorianLikeDateTimeFormatOptions = getDateTimeFormatOptions({ calendarType: gregorianLikeCalendarType });
|
||||
|
||||
for (let i = 0; i < allDateRanges.length; i++) {
|
||||
const dateRange = allDateRanges[i];
|
||||
|
||||
for (const dateRange of allDateRanges) {
|
||||
if (dateRange && dateRange.type !== DateRange.Custom.type && dateRange.type === dateType && dateRange.name) {
|
||||
return t(dateRange.name);
|
||||
}
|
||||
@@ -1984,8 +1913,7 @@ export function useI18n() {
|
||||
|
||||
const ret: CalendarAlternateDate[] = [];
|
||||
|
||||
for (let i = 0; i < chineseDates.length; i++) {
|
||||
const chineseDate = chineseDates[i];
|
||||
for (const chineseDate of chineseDates) {
|
||||
const alternateDate = getChineseCalendarAlternateDisplayDate(chineseDate);
|
||||
ret.push(alternateDate);
|
||||
}
|
||||
@@ -2117,11 +2045,9 @@ export function useI18n() {
|
||||
return formatExchangeRateAmount(value, numberFormatOptions);
|
||||
}
|
||||
|
||||
function getAdaptiveAmountRate(amount1: number, amount2: number, fromExchangeRate: {
|
||||
rate: string
|
||||
}, toExchangeRate: { rate: string }): string | null {
|
||||
function getAdaptiveAmountRate(amount1: number, amount2: number, fromExchangeRate?: { rate: string }, toExchangeRate?: { rate: string }): string | null {
|
||||
const numberFormatOptions = getNumberFormatOptions({});
|
||||
return getAdaptiveDisplayAmountRate(amount1, amount2, fromExchangeRate, toExchangeRate, numberFormatOptions);
|
||||
return getAdaptiveDisplayAmountRate(amount1, amount2, numberFormatOptions, fromExchangeRate, toExchangeRate);
|
||||
}
|
||||
|
||||
function getAmountPrependAndAppendText(currencyCode: string, isPlural: boolean): CurrencyPrependAndAppendText | null {
|
||||
@@ -2137,19 +2063,17 @@ export function useI18n() {
|
||||
const allCategories = AccountCategory.values();
|
||||
const categorizedAccounts: Record<number, CategorizedAccount> = getCategorizedAccountsMap(Account.cloneAccounts(allVisibleAccounts));
|
||||
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
const category = allCategories[i];
|
||||
for (const category of allCategories) {
|
||||
const accountCategory = categorizedAccounts[category.type];
|
||||
|
||||
if (!categorizedAccounts[category.type]) {
|
||||
if (!accountCategory) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const accountCategory = categorizedAccounts[category.type];
|
||||
const accountsWithDisplayBalance: AccountWithDisplayBalance[] = [];
|
||||
|
||||
if (accountCategory.accounts) {
|
||||
for (let i = 0; i < accountCategory.accounts.length; i++) {
|
||||
const account = accountCategory.accounts[i];
|
||||
for (const account of accountCategory.accounts) {
|
||||
let accountWithDisplaceBalance: AccountWithDisplayBalance;
|
||||
|
||||
if (showAccountBalance && account.isAsset) {
|
||||
@@ -2171,24 +2095,24 @@ export function useI18n() {
|
||||
let totalBalance = 0;
|
||||
let hasUnCalculatedAmount = false;
|
||||
|
||||
for (let i = 0; i < accountsBalance.length; i++) {
|
||||
if (accountsBalance[i].currency === defaultCurrency) {
|
||||
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 === defaultCurrency) {
|
||||
if (accountBalance.isAsset) {
|
||||
totalBalance += accountBalance.balance;
|
||||
} else if (accountBalance.isLiability) {
|
||||
totalBalance -= accountBalance.balance;
|
||||
}
|
||||
} else {
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, defaultCurrency);
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountBalance.balance, accountBalance.currency, defaultCurrency);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
+15
-27
@@ -108,7 +108,7 @@ export class Account implements AccountInfoResponse {
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||
if (!this.subAccounts[i].equals(other.subAccounts[i])) {
|
||||
if (!(this.subAccounts[i] as Account).equals(other.subAccounts[i] as Account)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -137,9 +137,9 @@ export class Account implements AccountInfoResponse {
|
||||
public setSuitableIcon(oldCategory: number, newCategory: number): void {
|
||||
const allCategories = AccountCategory.values();
|
||||
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
if (allCategories[i].type === oldCategory) {
|
||||
if (this.icon !== allCategories[i].defaultAccountIconId) {
|
||||
for (const category of allCategories) {
|
||||
if (category.type === oldCategory) {
|
||||
if (this.icon !== category.defaultAccountIconId) {
|
||||
return;
|
||||
} else {
|
||||
break;
|
||||
@@ -147,9 +147,9 @@ export class Account implements AccountInfoResponse {
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
if (allCategories[i].type === newCategory) {
|
||||
this.icon = allCategories[i].defaultAccountIconId;
|
||||
for (const category of allCategories) {
|
||||
if (category.type === newCategory) {
|
||||
this.icon = category.defaultAccountIconId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,9 +231,7 @@ export class Account implements AccountInfoResponse {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||
const subAccount = this.subAccounts[i];
|
||||
|
||||
for (const subAccount of this.subAccounts) {
|
||||
if (subAccountId && subAccountId === subAccount.id) {
|
||||
return subAccount.id;
|
||||
}
|
||||
@@ -255,9 +253,7 @@ export class Account implements AccountInfoResponse {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||
const subAccount = this.subAccounts[i];
|
||||
|
||||
for (const subAccount of this.subAccounts) {
|
||||
if (subAccountId && subAccountId === subAccount.id) {
|
||||
return subAccount.hidden;
|
||||
}
|
||||
@@ -279,9 +275,7 @@ export class Account implements AccountInfoResponse {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||
const subAccount = this.subAccounts[i];
|
||||
|
||||
for (const subAccount of this.subAccounts) {
|
||||
if (subAccountId && subAccountId === subAccount.id) {
|
||||
return subAccount.comment;
|
||||
}
|
||||
@@ -303,9 +297,7 @@ export class Account implements AccountInfoResponse {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||
const subAccount = this.subAccounts[i];
|
||||
|
||||
for (const subAccount of this.subAccounts) {
|
||||
if (subAccountId && subAccountId === subAccount.id) {
|
||||
return subAccount;
|
||||
}
|
||||
@@ -322,9 +314,7 @@ export class Account implements AccountInfoResponse {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||
const subAccount = this.subAccounts[i];
|
||||
|
||||
for (const subAccount of this.subAccounts) {
|
||||
if (subAccountId && subAccountId === subAccount.id) {
|
||||
return subAccount;
|
||||
}
|
||||
@@ -341,9 +331,7 @@ export class Account implements AccountInfoResponse {
|
||||
const subAccountCurrenciesMap: Record<string, boolean> = {};
|
||||
const subAccountCurrencies: string[] = [];
|
||||
|
||||
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||
const subAccount = this.subAccounts[i];
|
||||
|
||||
for (const subAccount of this.subAccounts) {
|
||||
if (!showHidden && subAccount.hidden) {
|
||||
continue;
|
||||
}
|
||||
@@ -508,7 +496,7 @@ export class Account implements AccountInfoResponse {
|
||||
|
||||
if (account1.parentId && account1.parentId !== '0') {
|
||||
if (allAccountsMap && allAccountsMap[account1.parentId]) {
|
||||
account1DisplayOrder = allAccountsMap[account1.parentId].displayOrder;
|
||||
account1DisplayOrder = (allAccountsMap[account1.parentId] as Account).displayOrder;
|
||||
} else {
|
||||
account1DisplayOrder = null;
|
||||
}
|
||||
@@ -516,7 +504,7 @@ export class Account implements AccountInfoResponse {
|
||||
|
||||
if (account2.parentId && account2.parentId !== '0') {
|
||||
if (allAccountsMap && allAccountsMap[account2.parentId]) {
|
||||
account2DisplayOrder = allAccountsMap[account2.parentId].displayOrder;
|
||||
account2DisplayOrder = (allAccountsMap[account2.parentId] as Account).displayOrder;
|
||||
} else {
|
||||
account2DisplayOrder = null;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { PartialRecord } from '@/core/base.ts';
|
||||
import { type PartialRecord, itemAndIndex } from '@/core/base.ts';
|
||||
import type { Year1BasedMonth, TextualYearMonthDay, StartEndTime, WeekDay } from '@/core/datetime.ts';
|
||||
import { type Coordinate, getNormalizedCoordinate } from '@/core/coordinate.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
@@ -185,9 +185,9 @@ export class Transaction implements TransactionInfoResponse {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._pictures.length; i++) {
|
||||
if (this._pictures[i].pictureId === pictureInfo.pictureId) {
|
||||
this._pictures.splice(i, 1);
|
||||
for (const [picture, index] of itemAndIndex(this._pictures)) {
|
||||
if (picture.pictureId === pictureInfo.pictureId) {
|
||||
this._pictures.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { entries } from '@/core/base.ts';
|
||||
import type { ColorValue } from '@/core/color.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import { DEFAULT_CATEGORY_ICON_ID } from '@/consts/icon.ts';
|
||||
@@ -58,7 +59,7 @@ export class TransactionCategory implements TransactionCategoryInfoResponse {
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.subCategories.length; i++) {
|
||||
if (!this.subCategories[i].equals(other.subCategories[i])) {
|
||||
if (!(this.subCategories[i] as TransactionCategory).equals(other.subCategories[i] as TransactionCategory)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -132,12 +133,8 @@ export class TransactionCategory implements TransactionCategoryInfoResponse {
|
||||
public static ofMap(categoriesByType: Record<number, TransactionCategoryInfoResponse[]>): Record<number, TransactionCategory[]> {
|
||||
const ret: Record<number, TransactionCategory[]> = {};
|
||||
|
||||
for (const categoryType in categoriesByType) {
|
||||
if (!Object.prototype.hasOwnProperty.call(categoriesByType, categoryType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ret[categoryType] = TransactionCategory.ofMulti(categoriesByType[categoryType]);
|
||||
for (const [categoryType, categories] of entries(categoriesByType)) {
|
||||
ret[parseInt(categoryType)] = TransactionCategory.ofMulti(categories);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
+11
-13
@@ -1,7 +1,7 @@
|
||||
import { ref, computed } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import type { BeforeResolveFunction } from '@/core/base.ts';
|
||||
import { type BeforeResolveFunction, itemAndIndex } from '@/core/base.ts';
|
||||
|
||||
import type {
|
||||
UserCustomExchangeRateUpdateResponse,
|
||||
@@ -65,15 +65,14 @@ export const useExchangeRatesStore = defineStore('exchangeRates', () => {
|
||||
return exchangeRateMap;
|
||||
}
|
||||
|
||||
for (let i = 0; i < latestExchangeRates.value.data.exchangeRates.length; i++) {
|
||||
const exchangeRate = latestExchangeRates.value.data.exchangeRates[i];
|
||||
for (const exchangeRate of latestExchangeRates.value.data.exchangeRates) {
|
||||
exchangeRateMap[exchangeRate.currency] = exchangeRate;
|
||||
}
|
||||
|
||||
return exchangeRateMap;
|
||||
});
|
||||
|
||||
function updateExchangeRateToLatestExchangeRateList(exchangeRate: LatestExchangeRate, updateTime: number): void {
|
||||
function updateExchangeRateToLatestExchangeRateList(latestExchangeRate: LatestExchangeRate, updateTime: number): void {
|
||||
if (!latestExchangeRates.value || !latestExchangeRates.value.data || !latestExchangeRates.value.data.exchangeRates) {
|
||||
return;
|
||||
}
|
||||
@@ -81,16 +80,16 @@ export const useExchangeRatesStore = defineStore('exchangeRates', () => {
|
||||
const exchangeRates = latestExchangeRates.value.data.exchangeRates;
|
||||
let changed = false;
|
||||
|
||||
for (let i = 0; i < exchangeRates.length; i++) {
|
||||
if (exchangeRates[i].currency === exchangeRate.currency) {
|
||||
exchangeRates.splice(i, 1, exchangeRate);
|
||||
for (const [exchangeRate, index] of itemAndIndex(exchangeRates)) {
|
||||
if (exchangeRate.currency === latestExchangeRate.currency) {
|
||||
exchangeRates.splice(index, 1, latestExchangeRate);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
exchangeRates.push(exchangeRate);
|
||||
exchangeRates.push(latestExchangeRate);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@@ -109,9 +108,9 @@ export const useExchangeRatesStore = defineStore('exchangeRates', () => {
|
||||
const exchangeRates = latestExchangeRates.value.data.exchangeRates;
|
||||
let changed = false;
|
||||
|
||||
for (let i = 0; i < exchangeRates.length; i++) {
|
||||
if (exchangeRates[i].currency === currency) {
|
||||
exchangeRates.splice(i, 1);
|
||||
for (const [exchangeRate, index] of itemAndIndex(exchangeRates)) {
|
||||
if (exchangeRate.currency === currency) {
|
||||
exchangeRates.splice(index, 1);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
@@ -262,8 +261,7 @@ export const useExchangeRatesStore = defineStore('exchangeRates', () => {
|
||||
const exchangeRates = latestExchangeRates.value.data.exchangeRates;
|
||||
const exchangeRateMap: Record<string, LatestExchangeRate> = {};
|
||||
|
||||
for (let i = 0; i < exchangeRates.length; i++) {
|
||||
const exchangeRate = exchangeRates[i];
|
||||
for (const exchangeRate of exchangeRates) {
|
||||
exchangeRateMap[exchangeRate.currency] = exchangeRate;
|
||||
}
|
||||
|
||||
|
||||
+17
-18
@@ -1,6 +1,10 @@
|
||||
import { ref, computed } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import {
|
||||
values
|
||||
} from '@/core/base.ts';
|
||||
|
||||
import {
|
||||
type ApplicationSettingValue,
|
||||
type ApplicationSettingSubValue,
|
||||
@@ -39,13 +43,15 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
|
||||
function updateApplicationSettingsValueAndAppSettingsFromCloudSetting(key: string, value: string | number | boolean | Record<string, boolean>): void {
|
||||
const keyItems = key.split('.');
|
||||
const keyFirstPart = keyItems[0] as string;
|
||||
|
||||
if (keyItems.length === 1) {
|
||||
updateApplicationSettingsValue(keyItems[0], value);
|
||||
appSettings.value[keyItems[0]] = value;
|
||||
updateApplicationSettingsValue(keyFirstPart, value);
|
||||
appSettings.value[keyFirstPart] = value;
|
||||
} else if (keyItems.length === 2) {
|
||||
updateApplicationSettingsSubValue(keyItems[0], keyItems[1], value);
|
||||
(appSettings.value[keyItems[0]] as Record<string, ApplicationSettingSubValue>)[keyItems[1]] = value;
|
||||
const subKey = keyItems[1] as string;
|
||||
updateApplicationSettingsSubValue(keyFirstPart, subKey, value);
|
||||
(appSettings.value[keyFirstPart] as Record<string, ApplicationSettingSubValue>)[subKey] = value;
|
||||
} else {
|
||||
logger.warn(`cannot load application cloud setting "${key}", because it has invalid key format`);
|
||||
}
|
||||
@@ -60,10 +66,12 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
}
|
||||
|
||||
const keyItems = key.split('.');
|
||||
let value: ApplicationSettingValue | ApplicationSettingSubValue = appSettings.value[key];
|
||||
let value: ApplicationSettingValue | ApplicationSettingSubValue = appSettings.value[key] as (ApplicationSettingValue | ApplicationSettingSubValue);
|
||||
|
||||
if (keyItems.length === 2) {
|
||||
value = (appSettings.value[keyItems[0]] as Record<string, ApplicationSettingSubValue>)[keyItems[1]];
|
||||
const primaryKey = keyItems[0] as string;
|
||||
const subKey = keyItems[1] as string;
|
||||
value = (appSettings.value[primaryKey] as Record<string, ApplicationSettingSubValue>)[subKey] as ApplicationSettingSubValue;
|
||||
} else if (keyItems.length > 2) {
|
||||
logger.warn(`cannot get application cloud setting "${key}", because it has invalid key format`);
|
||||
return null;
|
||||
@@ -313,8 +321,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
|
||||
const settings: ApplicationCloudSetting[] = [];
|
||||
|
||||
for (let i = 0; i < applicationSettingKeys.length; i++) {
|
||||
const settingKey = applicationSettingKeys[i];
|
||||
for (const settingKey of applicationSettingKeys) {
|
||||
const cloudSetting = createUserApplicationCloudSetting(settingKey);
|
||||
|
||||
if (cloudSetting) {
|
||||
@@ -333,9 +340,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
|
||||
syncedAppSettings.value = arrayItemToObjectField(cloudSettings.map(item => item.settingKey), true);
|
||||
|
||||
for (let i = 0; i < cloudSettings.length; i++) {
|
||||
const setting = cloudSettings[i];
|
||||
|
||||
for (const setting of cloudSettings) {
|
||||
if (!setting || !setting.settingKey) {
|
||||
continue;
|
||||
}
|
||||
@@ -371,13 +376,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
let isValid = isObject(map);
|
||||
|
||||
if (isValid) {
|
||||
for (const key in map) {
|
||||
if (!Object.prototype.hasOwnProperty.call(map, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = map[key];
|
||||
|
||||
for (const value of values(map)) {
|
||||
if (!isBoolean(value)) {
|
||||
isValid = false;
|
||||
break;
|
||||
|
||||
@@ -140,11 +140,9 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
const allFilterTagIdsCount = computed<number>(() => countSplitItems(transactionsFilter.value.tagIds, ','));
|
||||
|
||||
const noTransaction = computed<boolean>(() => {
|
||||
for (let i = 0; i < transactions.value.length; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
|
||||
for (let j = 0; j < transactionMonthList.items.length; j++) {
|
||||
if (transactionMonthList.items[j]) {
|
||||
for (const transactionMonthList of transactions.value) {
|
||||
for (const transaction of transactionMonthList.items) {
|
||||
if (transaction) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ref, computed } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import type { BeforeResolveFunction } from '@/core/base.ts';
|
||||
import { type BeforeResolveFunction, itemAndIndex } from '@/core/base.ts';
|
||||
|
||||
import {
|
||||
type TransactionTagCreateBatchRequest,
|
||||
@@ -49,37 +49,37 @@ export const useTransactionTagsStore = defineStore('transactionTags', () => {
|
||||
allTransactionTagsMap.value[tag.id] = tag;
|
||||
}
|
||||
|
||||
function updateTagInTransactionTagList(tag: TransactionTag): void {
|
||||
for (let i = 0; i < allTransactionTags.value.length; i++) {
|
||||
if (allTransactionTags.value[i].id === tag.id) {
|
||||
allTransactionTags.value.splice(i, 1, tag);
|
||||
function updateTagInTransactionTagList(currentTag: TransactionTag): void {
|
||||
for (const [transactionTag, index] of itemAndIndex(allTransactionTags.value)) {
|
||||
if (transactionTag.id === currentTag.id) {
|
||||
allTransactionTags.value.splice(index, 1, currentTag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
allTransactionTagsMap.value[tag.id] = tag;
|
||||
allTransactionTagsMap.value[currentTag.id] = currentTag;
|
||||
}
|
||||
|
||||
function updateTagDisplayOrderInTransactionTagList({ from, to }: { from: number, to: number }): void {
|
||||
allTransactionTags.value.splice(to, 0, allTransactionTags.value.splice(from, 1)[0]);
|
||||
allTransactionTags.value.splice(to, 0, allTransactionTags.value.splice(from, 1)[0] as TransactionTag);
|
||||
}
|
||||
|
||||
function updateTagVisibilityInTransactionTagList({ tag, hidden }: { tag: TransactionTag, hidden: boolean }): void {
|
||||
if (allTransactionTagsMap.value[tag.id]) {
|
||||
allTransactionTagsMap.value[tag.id].hidden = hidden;
|
||||
allTransactionTagsMap.value[tag.id]!.hidden = hidden;
|
||||
}
|
||||
}
|
||||
|
||||
function removeTagFromTransactionTagList(tag: TransactionTag): void {
|
||||
for (let i = 0; i < allTransactionTags.value.length; i++) {
|
||||
if (allTransactionTags.value[i].id === tag.id) {
|
||||
allTransactionTags.value.splice(i, 1);
|
||||
function removeTagFromTransactionTagList(currentTag: TransactionTag): void {
|
||||
for (const [transactionTag, index] of itemAndIndex(allTransactionTags.value)) {
|
||||
if (transactionTag.id === currentTag.id) {
|
||||
allTransactionTags.value.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allTransactionTagsMap.value[tag.id]) {
|
||||
delete allTransactionTagsMap.value[tag.id];
|
||||
if (allTransactionTagsMap.value[currentTag.id]) {
|
||||
delete allTransactionTagsMap.value[currentTag.id];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,16 +223,16 @@ export const useTransactionTagsStore = defineStore('transactionTags', () => {
|
||||
|
||||
function changeTagDisplayOrder({ tagId, from, to }: { tagId: string, from: number, to: number }): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let tag: TransactionTag | null = null;
|
||||
let currentTag: TransactionTag | null = null;
|
||||
|
||||
for (let i = 0; i < allTransactionTags.value.length; i++) {
|
||||
if (allTransactionTags.value[i].id === tagId) {
|
||||
tag = allTransactionTags.value[i];
|
||||
for (const transactionTag of allTransactionTags.value) {
|
||||
if (transactionTag.id === tagId) {
|
||||
currentTag = transactionTag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tag || !allTransactionTags.value[to]) {
|
||||
if (!currentTag || !allTransactionTags.value[to]) {
|
||||
reject({ message: 'Unable to move tag' });
|
||||
return;
|
||||
}
|
||||
@@ -250,10 +250,10 @@ export const useTransactionTagsStore = defineStore('transactionTags', () => {
|
||||
function updateTagDisplayOrders(): Promise<boolean> {
|
||||
const newDisplayOrders: TransactionTagNewDisplayOrderRequest[] = [];
|
||||
|
||||
for (let i = 0; i < allTransactionTags.value.length; i++) {
|
||||
for (const [transactionTag, index] of itemAndIndex(allTransactionTags.value)) {
|
||||
newDisplayOrders.push({
|
||||
id: allTransactionTags.value[i].id,
|
||||
displayOrder: i + 1
|
||||
id: transactionTag.id,
|
||||
displayOrder: index + 1
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,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 type { Account, AccountCategoriesWithVisibleCount } from '@/models/account.ts';
|
||||
|
||||
import {
|
||||
@@ -65,13 +66,7 @@ export function useAccountFilterSettingPageBase(type?: AccountFilterType) {
|
||||
function loadFilterAccountIds(): boolean {
|
||||
const allAccountIds: Record<string, boolean> = {};
|
||||
|
||||
for (const accountId in accountsStore.allAccountsMap) {
|
||||
if (!Object.prototype.hasOwnProperty.call(accountsStore.allAccountsMap, accountId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const account = accountsStore.allAccountsMap[accountId];
|
||||
|
||||
for (const account of values(accountsStore.allAccountsMap)) {
|
||||
if (!allowHiddenAccount.value && account.hidden) {
|
||||
continue;
|
||||
}
|
||||
@@ -93,11 +88,7 @@ export function useAccountFilterSettingPageBase(type?: AccountFilterType) {
|
||||
filterAccountIds.value = Object.assign(allAccountIds, settingsStore.appSettings.overviewAccountFilterInHomePage);
|
||||
return true;
|
||||
} else if (type === 'transactionListCurrent') {
|
||||
for (const accountId in transactionsStore.allFilterAccountIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionsStore.allFilterAccountIds, accountId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const accountId of keysIfValueEquals(transactionsStore.allFilterAccountIds, true)) {
|
||||
const account = accountsStore.allAccountsMap[accountId];
|
||||
|
||||
if (account) {
|
||||
@@ -120,11 +111,7 @@ export function useAccountFilterSettingPageBase(type?: AccountFilterType) {
|
||||
let finalAccountIds = '';
|
||||
let changed = true;
|
||||
|
||||
for (const accountId in filterAccountIds.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(filterAccountIds.value, accountId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const accountId of keys(filterAccountIds.value)) {
|
||||
const account = accountsStore.allAccountsMap[accountId];
|
||||
|
||||
if (!account) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ref, computed } from 'vue';
|
||||
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
|
||||
import { keysIfValueEquals } from '@/core/base.ts';
|
||||
import type { ApplicationCloudSetting } from '@/core/setting.ts';
|
||||
|
||||
export interface CategorizedApplicationCloudSettingItems {
|
||||
@@ -101,14 +102,8 @@ export function useAppCloudSyncBase() {
|
||||
const isEnableCloudSync = computed<boolean>(() => settingsStore.enableApplicationCloudSync);
|
||||
|
||||
const hasEnabledApplicationCloudSettings = computed<boolean>(() => {
|
||||
for (const key in enabledApplicationCloudSettings.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(enabledApplicationCloudSettings.value, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (enabledApplicationCloudSettings.value[key]) {
|
||||
return true;
|
||||
}
|
||||
for (const _ of keysIfValueEquals(enabledApplicationCloudSettings.value, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -117,22 +112,15 @@ export function useAppCloudSyncBase() {
|
||||
const enabledApplicationCloudSettingKeys = computed<string[]>(() => {
|
||||
const keys: string[] = [];
|
||||
|
||||
for (const key in enabledApplicationCloudSettings.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(enabledApplicationCloudSettings.value, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (enabledApplicationCloudSettings.value[key]) {
|
||||
keys.push(key);
|
||||
}
|
||||
for (const key of keysIfValueEquals(enabledApplicationCloudSettings.value, true)) {
|
||||
keys.push(key);
|
||||
}
|
||||
|
||||
return keys;
|
||||
});
|
||||
|
||||
function isAllSettingsSelected(categorizedItems: CategorizedApplicationCloudSettingItems): boolean {
|
||||
for (let i = 0; i < categorizedItems.items.length; i++) {
|
||||
const item = categorizedItems.items[i];
|
||||
for (const item of categorizedItems.items) {
|
||||
if (!enabledApplicationCloudSettings.value[item.settingKey]) {
|
||||
return false;
|
||||
}
|
||||
@@ -144,8 +132,7 @@ export function useAppCloudSyncBase() {
|
||||
function hasSettingSelectedButNotAllChecked(categorizedItems: CategorizedApplicationCloudSettingItems): boolean {
|
||||
let checkedCount = 0;
|
||||
|
||||
for (let i = 0; i < categorizedItems.items.length; i++) {
|
||||
const item = categorizedItems.items[i];
|
||||
for (const item of categorizedItems.items) {
|
||||
if (!enabledApplicationCloudSettings.value[item.settingKey]) {
|
||||
checkedCount++;
|
||||
}
|
||||
@@ -155,40 +142,30 @@ export function useAppCloudSyncBase() {
|
||||
}
|
||||
|
||||
function updateSettingsSelected(categorizedItems: CategorizedApplicationCloudSettingItems, value: boolean): void {
|
||||
for (let i = 0; i < categorizedItems.items.length; i++) {
|
||||
const item = categorizedItems.items[i];
|
||||
for (const item of categorizedItems.items) {
|
||||
enabledApplicationCloudSettings.value[item.settingKey] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function selectAllSettings(): void {
|
||||
for (let i = 0; i < ALL_APPLICATION_CLOUD_SETTINGS.length; i++) {
|
||||
const categorizedItems = ALL_APPLICATION_CLOUD_SETTINGS[i];
|
||||
|
||||
for (let j = 0; j < categorizedItems.items.length; j++) {
|
||||
const item = categorizedItems.items[j];
|
||||
for (const categorizedItems of ALL_APPLICATION_CLOUD_SETTINGS) {
|
||||
for (const item of categorizedItems.items) {
|
||||
enabledApplicationCloudSettings.value[item.settingKey] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectNoneSettings(): void {
|
||||
for (let i = 0; i < ALL_APPLICATION_CLOUD_SETTINGS.length; i++) {
|
||||
const categorizedItems = ALL_APPLICATION_CLOUD_SETTINGS[i];
|
||||
|
||||
for (let j = 0; j < categorizedItems.items.length; j++) {
|
||||
const item = categorizedItems.items[j];
|
||||
for (const categorizedItems of ALL_APPLICATION_CLOUD_SETTINGS) {
|
||||
for (const item of categorizedItems.items) {
|
||||
enabledApplicationCloudSettings.value[item.settingKey] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectInvertSettings(): void {
|
||||
for (let i = 0; i < ALL_APPLICATION_CLOUD_SETTINGS.length; i++) {
|
||||
const categorizedItems = ALL_APPLICATION_CLOUD_SETTINGS[i];
|
||||
|
||||
for (let j = 0; j < categorizedItems.items.length; j++) {
|
||||
const item = categorizedItems.items[j];
|
||||
for (const categorizedItems of ALL_APPLICATION_CLOUD_SETTINGS) {
|
||||
for (const item of categorizedItems.items) {
|
||||
enabledApplicationCloudSettings.value[item.settingKey] = !enabledApplicationCloudSettings.value[item.settingKey];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useOverviewStore } from '@/stores/overview.ts';
|
||||
import { useStatisticsStore } from '@/stores/statistics.ts';
|
||||
|
||||
import type { NameValue, TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { type NameValue, type TypeAndDisplayName, keysIfValueEquals, values } from '@/core/base.ts';
|
||||
import type { LocalizedTimezoneInfo } from '@/core/timezone.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import type { Account } from '@/models/account.ts';
|
||||
@@ -145,12 +145,8 @@ export function useAppSettingPageBase() {
|
||||
|
||||
let hasExcludeAccount = false;
|
||||
|
||||
for (const accountId in excludeAccountIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(excludeAccountIds, accountId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (excludeAccountIds[accountId] && accountsStore.allAccountsMap[accountId]) {
|
||||
for (const accountId of keysIfValueEquals(excludeAccountIds, true)) {
|
||||
if (accountsStore.allAccountsMap[accountId]) {
|
||||
hasExcludeAccount = true;
|
||||
break;
|
||||
}
|
||||
@@ -162,9 +158,7 @@ export function useAppSettingPageBase() {
|
||||
|
||||
let allAccountExcluded = true;
|
||||
|
||||
for (let i = 0; i < allAccounts.length; i++) {
|
||||
const account = allAccounts[i];
|
||||
|
||||
for (const account of allAccounts) {
|
||||
if (!excludeAccountIds[account.id]) {
|
||||
allAccountExcluded = false;
|
||||
break;
|
||||
@@ -185,12 +179,8 @@ export function useAppSettingPageBase() {
|
||||
|
||||
let hasExcludeTransactionCategory = false;
|
||||
|
||||
for (const transactionCategoryId in excludeTransactionCategoryIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(excludeTransactionCategoryIds, transactionCategoryId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (excludeTransactionCategoryIds[transactionCategoryId] && transactionCategoriesStore.allTransactionCategoriesMap[transactionCategoryId]) {
|
||||
for (const transactionCategoryId of keysIfValueEquals(excludeTransactionCategoryIds, true)) {
|
||||
if (transactionCategoriesStore.allTransactionCategoriesMap[transactionCategoryId]) {
|
||||
hasExcludeTransactionCategory = true;
|
||||
break;
|
||||
}
|
||||
@@ -202,13 +192,7 @@ export function useAppSettingPageBase() {
|
||||
|
||||
let allTransactionCategoryExcluded = true;
|
||||
|
||||
for (const transactionCategoryId in transactionCategoriesStore.allTransactionCategoriesMap) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionCategoriesStore.allTransactionCategoriesMap, transactionCategoryId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const transactionCategory = transactionCategoriesStore.allTransactionCategoriesMap[transactionCategoryId];
|
||||
|
||||
for (const transactionCategory of values(transactionCategoriesStore.allTransactionCategoriesMap)) {
|
||||
if (transactionCategory.type !== CategoryType.Income && transactionCategory.type !== CategoryType.Expense) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
import { useStatisticsStore } from '@/stores/statistics.ts';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { type TypeAndDisplayName, keys, keysIfValueEquals, values } from '@/core/base.ts';
|
||||
import { TransactionTagFilterType } from '@/core/transaction.ts';
|
||||
import type { TransactionTag } from '@/models/transaction_tag.ts';
|
||||
|
||||
@@ -44,20 +44,14 @@ export function useTransactionTagFilterSettingPageBase(type?: string) {
|
||||
function loadFilterTagIds(): boolean {
|
||||
const allTransactionTagIds: Record<string, boolean> = {};
|
||||
|
||||
for (const transactionTagId in transactionTagsStore.allTransactionTagsMap) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionTagsStore.allTransactionTagsMap, transactionTagId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const transactionTag = transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
for (const transactionTag of values(transactionTagsStore.allTransactionTagsMap)) {
|
||||
allTransactionTagIds[transactionTag.id] = true;
|
||||
}
|
||||
|
||||
if (type === 'statisticsCurrent') {
|
||||
const transactionTagIds = statisticsStore.transactionStatisticsFilter.tagIds ? statisticsStore.transactionStatisticsFilter.tagIds.split(',') : [];
|
||||
|
||||
for (let i = 0; i < transactionTagIds.length; i++) {
|
||||
const transactionTagId = transactionTagIds[i];
|
||||
for (const transactionTagId of transactionTagIds) {
|
||||
const transactionTag = transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (transactionTag) {
|
||||
@@ -68,11 +62,7 @@ export function useTransactionTagFilterSettingPageBase(type?: string) {
|
||||
tagFilterType.value = statisticsStore.transactionStatisticsFilter.tagFilterType;
|
||||
return true;
|
||||
} else if (type === 'transactionListCurrent') {
|
||||
for (const transactionTagId in transactionsStore.allFilterTagIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionsStore.allFilterTagIds, transactionTagId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const transactionTagId of keysIfValueEquals(transactionsStore.allFilterTagIds, true)) {
|
||||
const transactionTag = transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (transactionTag) {
|
||||
@@ -91,11 +81,7 @@ export function useTransactionTagFilterSettingPageBase(type?: string) {
|
||||
let finalTagIds = '';
|
||||
let changed = true;
|
||||
|
||||
for (const transactionTagId in filterTagIds.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(filterTagIds.value, transactionTagId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const transactionTagId of keys(filterTagIds.value)) {
|
||||
const transactionTag = transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (!transactionTag) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { type TransactionListFilter, type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
|
||||
|
||||
import type { TypeAndName } from '@/core/base.ts';
|
||||
import { type TypeAndName, entries } from '@/core/base.ts';
|
||||
import type { NumeralSystem } from '@/core/numeral.ts';
|
||||
import { type TextualYearMonthDay, type Year0BasedMonth, type LocalizedDateRange, type WeekDayValue, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
||||
import { AccountType } from '@/core/account.ts';
|
||||
@@ -113,16 +113,12 @@ export function useTransactionListPageBase() {
|
||||
const allPrimaryCategories = computed<Record<string, TransactionCategory[]>>(() => {
|
||||
const primaryCategories: Record<string, TransactionCategory[]> = {};
|
||||
|
||||
for (const categoryType in transactionCategoriesStore.allTransactionCategories) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionCategoriesStore.allTransactionCategories, categoryType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const [categoryType, categories] of entries(transactionCategoriesStore.allTransactionCategories)) {
|
||||
if (query.value.type && categoryTypeToTransactionType(parseInt(categoryType)) !== query.value.type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
primaryCategories[categoryType] = transactionCategoriesStore.allTransactionCategories[categoryType];
|
||||
primaryCategories[categoryType] = categories;
|
||||
}
|
||||
|
||||
return primaryCategories;
|
||||
@@ -131,17 +127,13 @@ export function useTransactionListPageBase() {
|
||||
const allAvailableCategoriesCount = computed<number>(() => {
|
||||
let totalCount = 0;
|
||||
|
||||
for (const categoryType in transactionCategoriesStore.allTransactionCategories) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionCategoriesStore.allTransactionCategories, categoryType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const [categoryType, categories] of entries(transactionCategoriesStore.allTransactionCategories)) {
|
||||
if (query.value.type && categoryTypeToTransactionType(parseInt(categoryType)) !== query.value.type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (transactionCategoriesStore.allTransactionCategories[categoryType]) {
|
||||
totalCount += transactionCategoriesStore.allTransactionCategories[categoryType].length;
|
||||
if (categories) {
|
||||
totalCount += categories.length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +221,7 @@ export function useTransactionListPageBase() {
|
||||
const displayAmount: string[] = [];
|
||||
|
||||
for (let i = 1; i < amountFilterItems.length; i++) {
|
||||
displayAmount.push(formatAmountToLocalizedNumeralsWithCurrency(parseInt(amountFilterItems[i]), false));
|
||||
displayAmount.push(formatAmountToLocalizedNumeralsWithCurrency(parseInt(amountFilterItems[i] as string), false));
|
||||
}
|
||||
|
||||
return displayAmount.join(' ~ ');
|
||||
@@ -249,9 +241,9 @@ export function useTransactionListPageBase() {
|
||||
const currentYear = currentMonthMinDate.getGregorianCalendarYear();
|
||||
const currentMonth = currentMonthMinDate.getGregorianCalendarMonth();
|
||||
|
||||
for (let i = 0; i < allTransactions.length; i++) {
|
||||
if (allTransactions[i].year === currentYear && allTransactions[i].month === currentMonth) {
|
||||
return allTransactions[i];
|
||||
for (const transactionMonth of allTransactions) {
|
||||
if (transactionMonth.year === currentYear && transactionMonth.month === currentMonth) {
|
||||
return transactionMonth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
v-if="(showHidden || !account.hidden) && account.type === AccountType.MultiSubAccounts.type && ((showHidden && accountCategory.allSubAccounts[account.id]) || accountCategory.allVisibleSubAccountCounts[account.id])">
|
||||
<template :key="subAccount.id"
|
||||
v-for="(subAccount, subIdx) in accountCategory.allSubAccounts[account.id]">
|
||||
<v-divider v-if="showHidden ? subIdx > 0 : (!subAccount.hidden ? subIdx > accountCategory.allFirstVisibleSubAccountIndexes[account.id] : false)"/>
|
||||
<v-divider v-if="showHidden ? subIdx > 0 : (!subAccount.hidden ? subIdx > (accountCategory.allFirstVisibleSubAccountIndexes[account.id] as number) : false)"/>
|
||||
|
||||
<v-list-item v-if="showHidden || !subAccount.hidden">
|
||||
<template #prepend>
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
v-if="(showHidden || !category.hidden) && ((showHidden && transactionType.allSubCategories[category.id]) || transactionType.allVisibleSubCategoryCounts[category.id])">
|
||||
<template :key="subCategory.id"
|
||||
v-for="(subCategory, subIdx) in transactionType.allSubCategories[category.id]">
|
||||
<v-divider v-if="showHidden ? subIdx > 0 : (!subCategory.hidden ? subIdx > transactionType.allFirstVisibleSubCategoryIndexes[category.id] : false)"/>
|
||||
<v-divider v-if="showHidden ? subIdx > 0 : (!subCategory.hidden ? subIdx > (transactionType.allFirstVisibleSubCategoryIndexes[category.id] as number) : false)"/>
|
||||
|
||||
<v-list-item v-if="showHidden || !subCategory.hidden">
|
||||
<template #prepend>
|
||||
|
||||
@@ -227,8 +227,7 @@ function reload(force: boolean): void {
|
||||
const exchangeRates = exchangeRatesData.value.exchangeRates;
|
||||
let foundDefaultCurrency = false;
|
||||
|
||||
for (let i = 0; i < exchangeRates.length; i++) {
|
||||
const exchangeRate = exchangeRates[i];
|
||||
for (const exchangeRate of exchangeRates) {
|
||||
if (exchangeRate.currency === baseCurrency.value) {
|
||||
foundDefaultCurrency = true;
|
||||
break;
|
||||
|
||||
@@ -696,7 +696,7 @@ function close(completed: boolean): void {
|
||||
|
||||
watch(fileType, () => {
|
||||
if (allFileSubTypes.value && allFileSubTypes.value.length) {
|
||||
fileSubType.value = allFileSubTypes.value[0].type;
|
||||
fileSubType.value = allFileSubTypes.value[0]!.type;
|
||||
}
|
||||
|
||||
importFile.value = null;
|
||||
|
||||
@@ -145,6 +145,7 @@ import { useRootStore } from '@/stores/index.ts';
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
import { useTokensStore } from '@/stores/token.ts';
|
||||
|
||||
import { itemAndIndex, reversedItemAndIndex } from '@/core/base.ts';
|
||||
import { type TokenInfoResponse, SessionInfo } from '@/models/token.ts';
|
||||
|
||||
import { isEquals } from '@/lib/common.ts';
|
||||
@@ -203,8 +204,7 @@ const sessions = computed<DesktopPageSessionInfo[]>(() => {
|
||||
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 DesktopPageSessionInfo(sessionInfo));
|
||||
}
|
||||
@@ -336,9 +336,9 @@ function revokeSession(session: SessionInfo): void {
|
||||
}).then(() => {
|
||||
loadingSession.value = false;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
@@ -362,9 +362,9 @@ function revokeAllSessions(): void {
|
||||
tokensStore.revokeAllTokens().then(() => {
|
||||
loadingSession.value = false;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -309,8 +309,7 @@ exchangeRatesStore.getLatestExchangeRates({
|
||||
const exchangeRates = exchangeRatesData.value.exchangeRates;
|
||||
let hasBaseCurrency = false;
|
||||
|
||||
for (let i = 0; i < exchangeRates.length; i++) {
|
||||
const exchangeRate = exchangeRates[i];
|
||||
for (const exchangeRate of exchangeRates) {
|
||||
if (exchangeRate.currency === baseCurrency.value) {
|
||||
hasBaseCurrency = true;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user