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