mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-15 23:47:33 +08:00
add asset trends in statistics & analysis (#314)
This commit is contained in:
@@ -10,6 +10,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import type { WeekDayValue } from '@/core/datetime.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
import { StatisticsAnalysisType } from '@/core/statistics.ts';
|
||||
import { KnownFileType } from '@/core/file.ts';
|
||||
import type { Account } from '@/models/account.ts';
|
||||
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
||||
@@ -55,7 +56,7 @@ export function useReconciliationStatementPageBase() {
|
||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||
|
||||
const allChartTypes = computed<TypeAndDisplayName[]>(() => getAllAccountBalanceTrendChartTypes());
|
||||
const allDateAggregationTypes = computed<TypeAndDisplayName[]>(() => getAllStatisticsDateAggregationTypesWithShortName());
|
||||
const allDateAggregationTypes = computed<TypeAndDisplayName[]>(() => getAllStatisticsDateAggregationTypesWithShortName(StatisticsAnalysisType.AssetTrends));
|
||||
|
||||
const currentAccount = computed(() => allAccountsMap.value[accountId.value]);
|
||||
const currentAccountCurrency = computed<string>(() => currentAccount.value?.currency ?? defaultCurrency.value);
|
||||
|
||||
@@ -88,6 +88,14 @@ export const ALL_APPLICATION_CLOUD_SETTINGS: CategorizedApplicationCloudSettingI
|
||||
{ settingKey: 'statistics.defaultTrendChartType', settingName: 'Default Chart Type', mobile: false, desktop: true },
|
||||
{ settingKey: 'statistics.defaultTrendChartDataRangeType', settingName: 'Default Date Range', mobile: true, desktop: true }
|
||||
]
|
||||
},
|
||||
{
|
||||
categoryName: 'Statistics Settings',
|
||||
categorySubName: 'Asset Trends Settings',
|
||||
items: [
|
||||
{ settingKey: 'statistics.defaultAssetTrendsChartType', settingName: 'Default Chart Type', mobile: false, desktop: true },
|
||||
{ settingKey: 'statistics.defaultAssetTrendsChartDataRangeType', settingName: 'Default Date Range', mobile: true, desktop: true }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ export function useStatisticsSettingPageBase() {
|
||||
const allCategoricalChartDateRanges = computed<LocalizedDateRange[]>(() => getAllDateRanges(DateRangeScene.Normal, false));
|
||||
const allTrendChartTypes = computed<TypeAndDisplayName[]>(() => getAllTrendChartTypes());
|
||||
const allTrendChartDateRanges = computed<LocalizedDateRange[]>(() => getAllDateRanges(DateRangeScene.TrendAnalysis, false));
|
||||
const allAssetTrendsChartDateRanges = computed<LocalizedDateRange[]>(() => getAllDateRanges(DateRangeScene.AssetTrends, false));
|
||||
|
||||
const defaultChartDataType = computed<number>({
|
||||
get: () => settingsStore.appSettings.statistics.defaultChartDataType,
|
||||
@@ -63,6 +64,16 @@ export function useStatisticsSettingPageBase() {
|
||||
set: (value: number) => settingsStore.setStatisticsDefaultTrendChartDateRange(value)
|
||||
});
|
||||
|
||||
const defaultAssetTrendsChartType = computed<number>({
|
||||
get: () => settingsStore.appSettings.statistics.defaultAssetTrendsChartType,
|
||||
set: (value: number) => settingsStore.setStatisticsDefaultAssetTrendsChartType(value)
|
||||
});
|
||||
|
||||
const defaultAssetTrendsChartDateRange = computed<number>({
|
||||
get: () => settingsStore.appSettings.statistics.defaultAssetTrendsChartDataRangeType,
|
||||
set: (value: number) => settingsStore.setStatisticsDefaultAssetTrendsChartDateRange(value)
|
||||
});
|
||||
|
||||
return {
|
||||
// computed states
|
||||
allChartDataTypes,
|
||||
@@ -72,12 +83,15 @@ export function useStatisticsSettingPageBase() {
|
||||
allCategoricalChartDateRanges,
|
||||
allTrendChartTypes,
|
||||
allTrendChartDateRanges,
|
||||
allAssetTrendsChartDateRanges,
|
||||
defaultChartDataType,
|
||||
defaultTimezoneType,
|
||||
defaultSortingType,
|
||||
defaultCategoricalChartType,
|
||||
defaultCategoricalChartDateRange,
|
||||
defaultTrendChartType,
|
||||
defaultTrendChartDateRange
|
||||
defaultTrendChartDateRange,
|
||||
defaultAssetTrendsChartType,
|
||||
defaultAssetTrendsChartDateRange
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ import type {
|
||||
TransactionCategoricalOverviewAnalysisData,
|
||||
TransactionCategoricalAnalysisData,
|
||||
TransactionCategoricalAnalysisDataItem,
|
||||
TransactionTrendsAnalysisData
|
||||
TransactionTrendsAnalysisData,
|
||||
TransactionAssetTrendsAnalysisData
|
||||
} from '@/models/transaction.ts';
|
||||
|
||||
import { limitText, findNameByType, findDisplayNameByType } from '@/lib/common.ts';
|
||||
@@ -49,6 +50,7 @@ export function useStatisticsTransactionPageBase() {
|
||||
const loading = ref<boolean>(true);
|
||||
const analysisType = ref<StatisticsAnalysisType>(StatisticsAnalysisType.CategoricalAnalysis);
|
||||
const trendDateAggregationType = ref<number>(ChartDateAggregationType.Default.type);
|
||||
const assetTrendsDateAggregationType = ref<number>(ChartDateAggregationType.Default.type);
|
||||
|
||||
const showAccountBalance = computed<boolean>(() => settingsStore.appSettings.showAccountBalance);
|
||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||
@@ -60,12 +62,15 @@ export function useStatisticsTransactionPageBase() {
|
||||
return getAllDateRanges(DateRangeScene.Normal, true);
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return getAllDateRanges(DateRangeScene.TrendAnalysis, true);
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return getAllDateRanges(DateRangeScene.AssetTrends, true);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
const allSortingTypes = computed<TypeAndDisplayName[]>(() => getAllStatisticsSortingTypes());
|
||||
const allDateAggregationTypes = computed<TypeAndDisplayName[]>(() => getAllStatisticsDateAggregationTypes());
|
||||
const allTrendAnalysisDateAggregationTypes = computed<TypeAndDisplayName[]>(() => getAllStatisticsDateAggregationTypes(StatisticsAnalysisType.TrendAnalysis));
|
||||
const allAssetTrendsDateAggregationTypes = computed<TypeAndDisplayName[]>(() => getAllStatisticsDateAggregationTypes(StatisticsAnalysisType.AssetTrends));
|
||||
|
||||
const query = computed<TransactionStatisticsFilter>(() => statisticsStore.transactionStatisticsFilter);
|
||||
const queryChartDataCategory = computed<string>(() => statisticsStore.categoricalAnalysisChartDataCategory);
|
||||
@@ -74,6 +79,8 @@ export function useStatisticsTransactionPageBase() {
|
||||
return query.value.categoricalChartDateType;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return query.value.trendChartDateType;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return query.value.assetTrendsChartDateType;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -84,6 +91,8 @@ export function useStatisticsTransactionPageBase() {
|
||||
return formatUnixTimeToLongDateTime(query.value.categoricalChartStartTime);
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return formatUnixTimeToGregorianLikeLongYearMonth(getYearMonthFirstUnixTime(query.value.trendChartStartYearMonth));
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return formatUnixTimeToLongDateTime(query.value.assetTrendsChartStartTime);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -94,21 +103,25 @@ export function useStatisticsTransactionPageBase() {
|
||||
return formatUnixTimeToLongDateTime(query.value.categoricalChartEndTime);
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return formatUnixTimeToGregorianLikeLongYearMonth(getYearMonthLastUnixTime(query.value.trendChartEndYearMonth));
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return formatUnixTimeToLongDateTime(query.value.assetTrendsChartEndTime);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
const queryDateRangeName = computed<string>(() => {
|
||||
if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type ||
|
||||
query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
return tt(DateRange.All.name);
|
||||
}
|
||||
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type ||
|
||||
query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
return tt(DateRange.All.name);
|
||||
}
|
||||
|
||||
return formatDateRange(query.value.categoricalChartDateType, query.value.categoricalChartStartTime, query.value.categoricalChartEndTime);
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return formatDateRange(query.value.trendChartDateType, getYearMonthFirstUnixTime(query.value.trendChartStartYearMonth), getYearMonthLastUnixTime(query.value.trendChartEndYearMonth));
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return formatDateRange(query.value.assetTrendsChartDateType, query.value.assetTrendsChartStartTime, query.value.assetTrendsChartEndTime);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -124,7 +137,8 @@ export function useStatisticsTransactionPageBase() {
|
||||
return tt(querySortingTypeName);
|
||||
});
|
||||
|
||||
const queryTrendDateAggregationTypeName = computed<string>(() => findDisplayNameByType(allDateAggregationTypes.value, trendDateAggregationType.value) || '');
|
||||
const queryTrendDateAggregationTypeName = computed<string>(() => findDisplayNameByType(allTrendAnalysisDateAggregationTypes.value, trendDateAggregationType.value) || '');
|
||||
const queryAssetTrendsDateAggregationTypeName = computed<string>(() => findDisplayNameByType(allAssetTrendsDateAggregationTypes.value, assetTrendsDateAggregationType.value) || '');
|
||||
|
||||
const isQueryDateRangeChanged = computed<boolean>(() => {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
@@ -144,13 +158,31 @@ export function useStatisticsTransactionPageBase() {
|
||||
}
|
||||
|
||||
return !!query.value.trendChartStartYearMonth || !!query.value.trendChartEndYearMonth;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
if (query.value.assetTrendsChartDateType === settingsStore.appSettings.statistics.defaultAssetTrendsChartDataRangeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!query.value.assetTrendsChartStartTime || !!query.value.assetTrendsChartEndTime;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
const canChangeDateRange = computed<boolean>(() => {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
const canShiftDateRange = computed<boolean>(() => {
|
||||
if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
if (!canChangeDateRange.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -158,13 +190,31 @@ export function useStatisticsTransactionPageBase() {
|
||||
return query.value.categoricalChartDateType !== DateRange.All.type;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return query.value.trendChartDateType !== DateRange.All.type;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return query.value.assetTrendsChartDateType !== DateRange.All.type;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
const canUseCategoryFilter = computed<boolean>(() => {
|
||||
if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
return false;
|
||||
}
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
const canUseServerCustomFilter = computed<boolean>(() => {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
return false;
|
||||
}
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -172,25 +222,19 @@ export function useStatisticsTransactionPageBase() {
|
||||
});
|
||||
|
||||
const canUseTagFilter = computed<boolean>(() => {
|
||||
if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return canUseServerCustomFilter.value;
|
||||
});
|
||||
|
||||
const canUseKeywordFilter = computed<boolean>(() => {
|
||||
if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return canUseServerCustomFilter.value;
|
||||
});
|
||||
|
||||
const showAmountInChart = computed<boolean>(() => {
|
||||
if (!showAccountBalance.value
|
||||
&& (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type)) {
|
||||
return false;
|
||||
if (!showAccountBalance.value) {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis
|
||||
&& (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -231,7 +275,8 @@ export function useStatisticsTransactionPageBase() {
|
||||
query.value.chartDataType !== ChartDataType.TotalInflows.type &&
|
||||
query.value.chartDataType !== ChartDataType.TotalIncome.type &&
|
||||
query.value.chartDataType !== ChartDataType.NetCashFlow.type &&
|
||||
query.value.chartDataType !== ChartDataType.NetIncome.type;
|
||||
query.value.chartDataType !== ChartDataType.NetIncome.type &&
|
||||
query.value.chartDataType !== ChartDataType.NetWorth.type;
|
||||
});
|
||||
|
||||
const showStackedInTrendsChart = computed<boolean>(() => {
|
||||
@@ -246,18 +291,22 @@ export function useStatisticsTransactionPageBase() {
|
||||
query.value.chartDataType === ChartDataType.TotalInflows.type ||
|
||||
query.value.chartDataType === ChartDataType.TotalIncome.type ||
|
||||
query.value.chartDataType === ChartDataType.NetCashFlow.type ||
|
||||
query.value.chartDataType === ChartDataType.NetIncome.type;
|
||||
query.value.chartDataType === ChartDataType.NetIncome.type ||
|
||||
query.value.chartDataType === ChartDataType.NetWorth.type;
|
||||
});
|
||||
|
||||
const categoricalOverviewAnalysisData = computed<TransactionCategoricalOverviewAnalysisData | null>(() => statisticsStore.categoricalOverviewAnalysisData);
|
||||
const categoricalAnalysisData = computed<TransactionCategoricalAnalysisData>(() => statisticsStore.categoricalAnalysisData);
|
||||
const trendsAnalysisData = computed<TransactionTrendsAnalysisData | null>(() => statisticsStore.trendsAnalysisData);
|
||||
const assetTrendsData = computed<TransactionAssetTrendsAnalysisData | null>(() => statisticsStore.assetTrendsData);
|
||||
|
||||
function canShowCustomDateRange(dateRangeType: number): boolean {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
return query.value.categoricalChartDateType === dateRangeType && !!query.value.categoricalChartStartTime && !!query.value.categoricalChartEndTime;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return query.value.trendChartDateType === dateRangeType && !!query.value.trendChartStartYearMonth && !!query.value.trendChartEndYearMonth;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return query.value.assetTrendsChartDateType === dateRangeType && !!query.value.assetTrendsChartStartTime && !!query.value.assetTrendsChartEndTime;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -276,11 +325,11 @@ export function useStatisticsTransactionPageBase() {
|
||||
function getDisplayAmount(amount: number, currency: string, textLimit?: number): string {
|
||||
const finalAmount = formatAmountToLocalizedNumeralsWithCurrency(amount, currency);
|
||||
|
||||
if (!showAccountBalance.value
|
||||
&& (query.value.chartDataType === ChartDataType.AccountTotalAssets.type
|
||||
|| query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type)
|
||||
) {
|
||||
return DISPLAY_HIDDEN_AMOUNT;
|
||||
if (!showAccountBalance.value) {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis
|
||||
&& (query.value.chartDataType === ChartDataType.AccountTotalAssets.type || query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type)) {
|
||||
return DISPLAY_HIDDEN_AMOUNT;
|
||||
}
|
||||
}
|
||||
|
||||
if (textLimit) {
|
||||
@@ -295,6 +344,7 @@ export function useStatisticsTransactionPageBase() {
|
||||
loading,
|
||||
analysisType,
|
||||
trendDateAggregationType,
|
||||
assetTrendsDateAggregationType,
|
||||
// computed states
|
||||
showAccountBalance,
|
||||
defaultCurrency,
|
||||
@@ -302,7 +352,8 @@ export function useStatisticsTransactionPageBase() {
|
||||
fiscalYearStart,
|
||||
allDateRanges,
|
||||
allSortingTypes,
|
||||
allDateAggregationTypes,
|
||||
allTrendAnalysisDateAggregationTypes,
|
||||
allAssetTrendsDateAggregationTypes,
|
||||
query,
|
||||
queryChartDataCategory,
|
||||
queryDateType,
|
||||
@@ -312,7 +363,9 @@ export function useStatisticsTransactionPageBase() {
|
||||
queryChartDataTypeName,
|
||||
querySortingTypeName,
|
||||
queryTrendDateAggregationTypeName,
|
||||
queryAssetTrendsDateAggregationTypeName,
|
||||
isQueryDateRangeChanged,
|
||||
canChangeDateRange,
|
||||
canShiftDateRange,
|
||||
canUseCategoryFilter,
|
||||
canUseTagFilter,
|
||||
@@ -326,6 +379,7 @@ export function useStatisticsTransactionPageBase() {
|
||||
categoricalOverviewAnalysisData,
|
||||
categoricalAnalysisData,
|
||||
trendsAnalysisData,
|
||||
assetTrendsData,
|
||||
// functions
|
||||
canShowCustomDateRange,
|
||||
getTransactionCategoricalAnalysisDataItemDisplayColor,
|
||||
|
||||
@@ -29,10 +29,6 @@
|
||||
v-for="type in allChartTypes"></v-list-item>
|
||||
<v-divider class="my-2"/>
|
||||
<v-list-subheader :title="tt('Time Granularity')"/>
|
||||
<v-list-item :prepend-icon="mdiCalendarTodayOutline"
|
||||
:append-icon="chartDataDateAggregationType === undefined ? mdiCheck : undefined"
|
||||
:title="tt('granularity.Daily')"
|
||||
@click="chartDataDateAggregationType = undefined"></v-list-item>
|
||||
<v-list-item :key="dateAggregationType.type"
|
||||
:prepend-icon="chartDataDateAggregationTypeIconMap[dateAggregationType.type]"
|
||||
:append-icon="chartDataDateAggregationType === dateAggregationType.type ? mdiCheck : undefined"
|
||||
@@ -360,6 +356,7 @@ const chartTypeIconMap = {
|
||||
};
|
||||
|
||||
const chartDataDateAggregationTypeIconMap = {
|
||||
[ChartDateAggregationType.Day.type]: mdiCalendarTodayOutline,
|
||||
[ChartDateAggregationType.Month.type]: mdiCalendarMonthOutline,
|
||||
[ChartDateAggregationType.Quarter.type]: mdiLayersTripleOutline,
|
||||
[ChartDateAggregationType.Year.type]: mdiLayersTripleOutline,
|
||||
@@ -376,7 +373,7 @@ const currentPage = ref<number>(1);
|
||||
const countPerPage = ref<number>(10);
|
||||
const showAccountBalanceTrendsCharts = ref<boolean>(false);
|
||||
const chartType = ref<number>(AccountBalanceTrendChartType.Default.type);
|
||||
const chartDataDateAggregationType = ref<number | undefined>(undefined);
|
||||
const chartDataDateAggregationType = ref<number>(ChartDateAggregationType.Day.type);
|
||||
|
||||
let rejectFunc: ((reason?: unknown) => void) | null = null;
|
||||
|
||||
@@ -453,7 +450,7 @@ function open(options: { accountId: string, startTime: number, endTime: number }
|
||||
countPerPage.value = 10;
|
||||
showAccountBalanceTrendsCharts.value = false;
|
||||
chartType.value = AccountBalanceTrendChartType.Default.type;
|
||||
chartDataDateAggregationType.value = undefined;
|
||||
chartDataDateAggregationType.value = ChartDateAggregationType.Day.type;
|
||||
showState.value = true;
|
||||
loading.value = true;
|
||||
|
||||
|
||||
@@ -114,6 +114,40 @@
|
||||
</v-card>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12">
|
||||
<v-card :title="tt('Asset Trends Settings')">
|
||||
<v-form>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
item-title="displayName"
|
||||
item-value="type"
|
||||
persistent-placeholder
|
||||
:label="tt('Default Chart Type')"
|
||||
:placeholder="tt('Default Chart Type')"
|
||||
:items="allTrendChartTypes"
|
||||
v-model="defaultAssetTrendsChartType"
|
||||
/>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
item-title="displayName"
|
||||
item-value="type"
|
||||
persistent-placeholder
|
||||
:label="tt('Default Date Range')"
|
||||
:placeholder="tt('Default Date Range')"
|
||||
:items="allAssetTrendsChartDateRanges"
|
||||
v-model="defaultAssetTrendsChartDateRange"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-form>
|
||||
</v-card>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12">
|
||||
<account-filter-settings-card type="statisticsDefault" :auto-save="true" />
|
||||
</v-col>
|
||||
@@ -140,13 +174,16 @@ const {
|
||||
allCategoricalChartDateRanges,
|
||||
allTrendChartTypes,
|
||||
allTrendChartDateRanges,
|
||||
allAssetTrendsChartDateRanges,
|
||||
defaultChartDataType,
|
||||
defaultTimezoneType,
|
||||
defaultSortingType,
|
||||
defaultCategoricalChartType,
|
||||
defaultCategoricalChartDateRange,
|
||||
defaultTrendChartType,
|
||||
defaultTrendChartDateRange
|
||||
defaultTrendChartDateRange,
|
||||
defaultAssetTrendsChartType,
|
||||
defaultAssetTrendsChartDateRange
|
||||
} = useStatisticsSettingPageBase();
|
||||
</script>
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
<div class="mx-6 my-4">
|
||||
<btn-vertical-group :disabled="loading" :buttons="[
|
||||
{ name: tt('Categorical Analysis'), value: StatisticsAnalysisType.CategoricalAnalysis },
|
||||
{ name: tt('Trend Analysis'), value: StatisticsAnalysisType.TrendAnalysis }
|
||||
{ name: tt('Trend Analysis'), value: StatisticsAnalysisType.TrendAnalysis },
|
||||
{ name: tt('Asset Trends'), value: StatisticsAnalysisType.AssetTrends }
|
||||
]" v-model="queryAnalysisType" />
|
||||
</div>
|
||||
<v-divider />
|
||||
@@ -59,7 +60,7 @@
|
||||
<v-main>
|
||||
<v-window class="d-flex flex-grow-1 disable-tab-transition w-100-window-container" v-model="activeTab">
|
||||
<v-window-item value="statisticsPage">
|
||||
<v-card variant="flat" :min-height="queryAnalysisType === StatisticsAnalysisType.TrendAnalysis ? '860' : '760'">
|
||||
<v-card variant="flat" :min-height="queryAnalysisType === StatisticsAnalysisType.TrendAnalysis || queryAnalysisType === StatisticsAnalysisType.AssetTrends ? '900' : '800'">
|
||||
<template #title>
|
||||
<div class="title-and-toolbar d-flex align-center">
|
||||
<v-btn class="me-3 d-md-none" density="compact" color="default" variant="plain"
|
||||
@@ -73,7 +74,7 @@
|
||||
@click="shiftDateRange(-1)"/>
|
||||
<v-menu location="bottom">
|
||||
<template #activator="{ props }">
|
||||
<v-btn :disabled="loading || queryChartDataType === ChartDataType.AccountTotalAssets.type || queryChartDataType === ChartDataType.AccountTotalLiabilities.type"
|
||||
<v-btn :disabled="loading || !canChangeDateRange"
|
||||
v-bind="props">{{ queryDateRangeName }}</v-btn>
|
||||
</template>
|
||||
<v-list :selected="[queryDateType]">
|
||||
@@ -110,12 +111,28 @@
|
||||
<v-list-item class="cursor-pointer" :key="aggregationType.type" :value="aggregationType.type"
|
||||
:append-icon="(trendDateAggregationType === aggregationType.type ? mdiCheck : undefined)"
|
||||
:title="aggregationType.displayName"
|
||||
v-for="aggregationType in allDateAggregationTypes"
|
||||
v-for="aggregationType in allTrendAnalysisDateAggregationTypes"
|
||||
@click="setTrendDateAggregationType(aggregationType.type)">
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
<v-menu location="bottom" v-if="queryAnalysisType === StatisticsAnalysisType.AssetTrends">
|
||||
<template #activator="{ props }">
|
||||
<v-btn class="ms-3" color="default" variant="outlined"
|
||||
:prepend-icon="mdiCalendarRangeOutline" :disabled="loading"
|
||||
v-bind="props">{{ queryAssetTrendsDateAggregationTypeName }}</v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-item class="cursor-pointer" :key="aggregationType.type" :value="aggregationType.type"
|
||||
:append-icon="(assetTrendsDateAggregationType === aggregationType.type ? mdiCheck : undefined)"
|
||||
:title="aggregationType.displayName"
|
||||
v-for="aggregationType in allAssetTrendsDateAggregationTypes"
|
||||
@click="setAssetTrendsDateAggregationType(aggregationType.type)">
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
<v-btn density="compact" color="default" variant="text" size="24"
|
||||
class="ms-2" :icon="true" :loading="loading" @click="reload(true)">
|
||||
<template #loader>
|
||||
@@ -205,10 +222,11 @@
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text class="statistics-overview-title pt-0"
|
||||
v-else-if="!initing && (
|
||||
v-else-if="!loading && (
|
||||
(queryAnalysisType === StatisticsAnalysisType.CategoricalAnalysis && isQuerySpecialChartType && queryChartDataType === ChartDataType.Overview.type && (!categoricalOverviewAnalysisData || !categoricalOverviewAnalysisData.items || !categoricalOverviewAnalysisData.items.length))
|
||||
|| (queryAnalysisType === StatisticsAnalysisType.CategoricalAnalysis && !isQuerySpecialChartType && (!categoricalAnalysisData || !categoricalAnalysisData.items || !categoricalAnalysisData.items.length))
|
||||
|| (queryAnalysisType === StatisticsAnalysisType.TrendAnalysis && (!trendsAnalysisData || !trendsAnalysisData.items || !trendsAnalysisData.items.length))
|
||||
|| (queryAnalysisType === StatisticsAnalysisType.AssetTrends && (!assetTrendsData || !assetTrendsData.items || !assetTrendsData.items.length))
|
||||
)">
|
||||
<span class="statistics-subtitle statistics-overview-empty-tip">{{ tt('No transaction data') }}</span>
|
||||
</v-card-text>
|
||||
@@ -345,11 +363,15 @@
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text :class="{ 'readonly': loading }" v-if="queryAnalysisType === StatisticsAnalysisType.TrendAnalysis">
|
||||
<monthly-trends-chart
|
||||
<trends-chart
|
||||
chart-mode="monthly"
|
||||
:type="queryChartType"
|
||||
:start-time="undefined"
|
||||
:end-time="undefined"
|
||||
:start-year-month="query.trendChartStartYearMonth"
|
||||
:end-year-month="query.trendChartEndYearMonth"
|
||||
:sorting-type="querySortingType"
|
||||
:data-aggregation-type="ChartDataAggregationType.Sum"
|
||||
:date-aggregation-type="trendDateAggregationType"
|
||||
:fiscal-year-start="fiscalYearStart"
|
||||
:items="[]"
|
||||
@@ -360,11 +382,15 @@
|
||||
color-field="color"
|
||||
v-if="initing"
|
||||
/>
|
||||
<monthly-trends-chart
|
||||
<trends-chart
|
||||
chart-mode="monthly"
|
||||
:type="queryChartType"
|
||||
:start-time="undefined"
|
||||
:end-time="undefined"
|
||||
:start-year-month="query.trendChartStartYearMonth"
|
||||
:end-year-month="query.trendChartEndYearMonth"
|
||||
:sorting-type="querySortingType"
|
||||
:data-aggregation-type="ChartDataAggregationType.Sum"
|
||||
:date-aggregation-type="trendDateAggregationType"
|
||||
:fiscal-year-start="fiscalYearStart"
|
||||
:items="trendsAnalysisData && trendsAnalysisData.items && trendsAnalysisData.items.length ? trendsAnalysisData.items : []"
|
||||
@@ -384,6 +410,55 @@
|
||||
@click="onClickTrendChartItem"
|
||||
/>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text :class="{ 'readonly': loading }" v-if="queryAnalysisType === StatisticsAnalysisType.AssetTrends">
|
||||
<trends-chart
|
||||
chart-mode="daily"
|
||||
:type="queryChartType"
|
||||
:start-time="query.assetTrendsChartStartTime"
|
||||
:end-time="query.assetTrendsChartEndTime"
|
||||
:start-year-month="undefined"
|
||||
:end-year-month="undefined"
|
||||
:sorting-type="querySortingType"
|
||||
:data-aggregation-type="ChartDataAggregationType.Last"
|
||||
:date-aggregation-type="assetTrendsDateAggregationType"
|
||||
:fiscal-year-start="fiscalYearStart"
|
||||
:items="[]"
|
||||
:skeleton="true"
|
||||
id-field="id"
|
||||
name-field="name"
|
||||
value-field="value"
|
||||
color-field="color"
|
||||
v-if="initing"
|
||||
/>
|
||||
<trends-chart
|
||||
chart-mode="daily"
|
||||
:type="queryChartType"
|
||||
:start-time="query.assetTrendsChartStartTime"
|
||||
:end-time="query.assetTrendsChartEndTime"
|
||||
:start-year-month="undefined"
|
||||
:end-year-month="undefined"
|
||||
:sorting-type="querySortingType"
|
||||
:data-aggregation-type="ChartDataAggregationType.Last"
|
||||
:date-aggregation-type="assetTrendsDateAggregationType"
|
||||
:fiscal-year-start="fiscalYearStart"
|
||||
:items="assetTrendsData && assetTrendsData.items && assetTrendsData.items.length ? assetTrendsData.items : []"
|
||||
:translate-name="translateNameInTrendsChart"
|
||||
:show-value="showAmountInChart"
|
||||
:enable-click-item="true"
|
||||
:default-currency="defaultCurrency"
|
||||
:stacked="showStackedInTrendsChart"
|
||||
:show-total-amount-in-tooltip="showTotalAmountInTrendsChart"
|
||||
ref="dailyTrendsChart"
|
||||
id-field="id"
|
||||
name-field="name"
|
||||
value-field="totalAmount"
|
||||
hidden-field="hidden"
|
||||
display-orders-field="displayOrders"
|
||||
v-else-if="!initing && assetTrendsData && assetTrendsData.items && assetTrendsData.items.length"
|
||||
@click="onClickTrendChartItem"
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
@@ -429,7 +504,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import SnackBar from '@/components/desktop/SnackBar.vue';
|
||||
import MonthlyTrendsChart from '@/components/desktop/MonthlyTrendsChart.vue';
|
||||
import TrendsChart from '@/components/desktop/TrendsChart.vue';
|
||||
import AccountFilterSettingsCard from '@/views/desktop/common/cards/AccountFilterSettingsCard.vue';
|
||||
import CategoryFilterSettingsCard from '@/views/desktop/common/cards/CategoryFilterSettingsCard.vue';
|
||||
import TransactionTagFilterSettingsCard from '@/views/desktop/common/cards/TransactionTagFilterSettingsCard.vue';
|
||||
@@ -450,6 +525,7 @@ import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { type TextualYearMonth, type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import {
|
||||
ChartDataAggregationType,
|
||||
StatisticsAnalysisType,
|
||||
CategoricalChartType,
|
||||
ChartDataType,
|
||||
@@ -488,7 +564,7 @@ import {
|
||||
} from '@mdi/js';
|
||||
|
||||
type SnackBarType = InstanceType<typeof SnackBar>;
|
||||
type MonthlyTrendsChartType = InstanceType<typeof MonthlyTrendsChart>;
|
||||
type TrendsChartType = InstanceType<typeof TrendsChart>;
|
||||
type ExportDialogType = InstanceType<typeof ExportDialog>;
|
||||
|
||||
interface TransactionStatisticsProps {
|
||||
@@ -505,6 +581,7 @@ interface TransactionStatisticsProps {
|
||||
initKeyword?: string;
|
||||
initSortingType?: string,
|
||||
initTrendDateAggregationType?: string
|
||||
initAssetTrendsDateAggregationType?: string
|
||||
}
|
||||
|
||||
const props = defineProps<TransactionStatisticsProps>();
|
||||
@@ -525,12 +602,14 @@ const {
|
||||
loading,
|
||||
analysisType,
|
||||
trendDateAggregationType,
|
||||
assetTrendsDateAggregationType,
|
||||
defaultCurrency,
|
||||
firstDayOfWeek,
|
||||
fiscalYearStart,
|
||||
allDateRanges,
|
||||
allSortingTypes,
|
||||
allDateAggregationTypes,
|
||||
allTrendAnalysisDateAggregationTypes,
|
||||
allAssetTrendsDateAggregationTypes,
|
||||
query,
|
||||
queryChartDataCategory,
|
||||
queryDateType,
|
||||
@@ -538,6 +617,8 @@ const {
|
||||
queryEndTime,
|
||||
queryDateRangeName,
|
||||
queryTrendDateAggregationTypeName,
|
||||
queryAssetTrendsDateAggregationTypeName,
|
||||
canChangeDateRange,
|
||||
canShiftDateRange,
|
||||
canUseCategoryFilter,
|
||||
canUseTagFilter,
|
||||
@@ -551,6 +632,7 @@ const {
|
||||
categoricalOverviewAnalysisData,
|
||||
categoricalAnalysisData,
|
||||
trendsAnalysisData,
|
||||
assetTrendsData,
|
||||
canShowCustomDateRange,
|
||||
getTransactionCategoricalAnalysisDataItemDisplayColor,
|
||||
getDisplayAmount
|
||||
@@ -561,7 +643,8 @@ const transactionCategoriesStore = useTransactionCategoriesStore();
|
||||
const statisticsStore = useStatisticsStore();
|
||||
|
||||
const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
||||
const monthlyTrendsChart = useTemplateRef<MonthlyTrendsChartType>('monthlyTrendsChart');
|
||||
const monthlyTrendsChart = useTemplateRef<TrendsChartType>('monthlyTrendsChart');
|
||||
const dailyTrendsChart = useTemplateRef<TrendsChartType>('dailyTrendsChart');
|
||||
const exportDialog = useTemplateRef<ExportDialogType>('exportDialog');
|
||||
|
||||
const activeTab = ref<string>('statisticsPage');
|
||||
@@ -582,6 +665,8 @@ const statisticsDataHasData = computed<boolean>(() => {
|
||||
return !!categoricalAnalysisData.value && !!categoricalAnalysisData.value.items && categoricalAnalysisData.value.items.length > 0;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return !!trendsAnalysisData.value && !!trendsAnalysisData.value.items && trendsAnalysisData.value.items.length > 0 && !!monthlyTrendsChart.value;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return !!assetTrendsData.value && !!assetTrendsData.value.items && assetTrendsData.value.items.length > 0 && !!dailyTrendsChart.value;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -592,6 +677,8 @@ const allChartTypes = computed<TypeAndDisplayName[]>(() => {
|
||||
return getAllCategoricalChartTypes(true);
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return getAllTrendChartTypes();
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return getAllTrendChartTypes();
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
@@ -610,6 +697,8 @@ const queryChartType = computed<number | undefined>({
|
||||
return query.value.categoricalChartType;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return query.value.trendChartType;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return query.value.assetTrendsChartType;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
@@ -654,7 +743,7 @@ const statisticsTextColor = computed<string>(() => {
|
||||
});
|
||||
|
||||
function getFilterLinkUrl(): string {
|
||||
return `/statistics/transaction?${statisticsStore.getTransactionStatisticsPageParams(analysisType.value, trendDateAggregationType.value)}`;
|
||||
return `/statistics/transaction?${statisticsStore.getTransactionStatisticsPageParams(analysisType.value, trendDateAggregationType.value, assetTrendsDateAggregationType.value)}`;
|
||||
}
|
||||
|
||||
function getTransactionItemLinkUrl(itemId: string, dateRange?: TimeRangeAndDateType): string {
|
||||
@@ -718,6 +807,29 @@ function init(initProps: TransactionStatisticsProps): void {
|
||||
if (initProps.initTrendDateAggregationType) {
|
||||
trendDateAggregationType.value = parseInt(initProps.initTrendDateAggregationType);
|
||||
}
|
||||
} else if (initProps.initAnalysisType === StatisticsAnalysisType.AssetTrends.toString()) {
|
||||
filter.assetTrendsChartType = initProps.initChartType ? parseInt(initProps.initChartType) : undefined;
|
||||
filter.assetTrendsChartDateType = initProps.initChartDateType ? parseInt(initProps.initChartDateType) : undefined;
|
||||
filter.assetTrendsChartStartTime = initProps.initStartTime ? parseInt(initProps.initStartTime) : undefined;
|
||||
filter.assetTrendsChartEndTime = initProps.initEndTime ? parseInt(initProps.initEndTime) : undefined;
|
||||
|
||||
if (filter.assetTrendsChartDateType !== query.value.assetTrendsChartDateType) {
|
||||
needReload = true;
|
||||
} else if (filter.assetTrendsChartDateType === DateRange.Custom.type) {
|
||||
if (filter.assetTrendsChartStartTime !== query.value.assetTrendsChartStartTime
|
||||
|| filter.assetTrendsChartEndTime !== query.value.assetTrendsChartEndTime) {
|
||||
needReload = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (initProps.initAnalysisType !== analysisType.value.toString()) {
|
||||
analysisType.value = StatisticsAnalysisType.AssetTrends;
|
||||
needReload = true;
|
||||
}
|
||||
|
||||
if (initProps.initAssetTrendsDateAggregationType) {
|
||||
assetTrendsDateAggregationType.value = parseInt(initProps.initAssetTrendsDateAggregationType);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDefined(initProps.initAnalysisType)) {
|
||||
@@ -745,6 +857,10 @@ function init(initProps: TransactionStatisticsProps): void {
|
||||
return statisticsStore.loadTrendAnalysis({
|
||||
force: false
|
||||
}) as Promise<unknown>;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return statisticsStore.loadAssetTrends({
|
||||
force: false
|
||||
}) as Promise<unknown>;
|
||||
} else {
|
||||
return Promise.reject('An error occurred');
|
||||
}
|
||||
@@ -780,7 +896,8 @@ function reload(force: boolean): Promise<unknown> | null {
|
||||
query.value.chartDataType === ChartDataType.TotalInflows.type ||
|
||||
query.value.chartDataType === ChartDataType.TotalIncome.type ||
|
||||
query.value.chartDataType === ChartDataType.NetCashFlow.type ||
|
||||
query.value.chartDataType === ChartDataType.NetIncome.type) {
|
||||
query.value.chartDataType === ChartDataType.NetIncome.type ||
|
||||
query.value.chartDataType === ChartDataType.NetWorth.type) {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
dispatchPromise = statisticsStore.loadCategoricalAnalysis({
|
||||
force: force
|
||||
@@ -789,12 +906,22 @@ function reload(force: boolean): Promise<unknown> | null {
|
||||
dispatchPromise = statisticsStore.loadTrendAnalysis({
|
||||
force: force
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
dispatchPromise = statisticsStore.loadAssetTrends({
|
||||
force: force
|
||||
});
|
||||
}
|
||||
} else if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type ||
|
||||
query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
dispatchPromise = accountsStore.loadAllAccounts({
|
||||
force: force
|
||||
});
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
dispatchPromise = accountsStore.loadAllAccounts({
|
||||
force: force
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
dispatchPromise = statisticsStore.loadAssetTrends({
|
||||
force: force
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (dispatchPromise) {
|
||||
@@ -822,13 +949,21 @@ function setAnalysisType(type: StatisticsAnalysisType): void {
|
||||
}
|
||||
|
||||
if (!ChartDataType.isAvailableForAnalysisType(query.value.chartDataType, type)) {
|
||||
let defaultChartDataType: ChartDataType = ChartDataType.Default;
|
||||
|
||||
if (type === StatisticsAnalysisType.AssetTrends) {
|
||||
defaultChartDataType = ChartDataType.DefaultForAssetTrends;
|
||||
}
|
||||
|
||||
statisticsStore.updateTransactionStatisticsFilter({
|
||||
chartDataType: ChartDataType.Default.type
|
||||
chartDataType: defaultChartDataType.type
|
||||
});
|
||||
}
|
||||
|
||||
if (analysisType.value !== StatisticsAnalysisType.TrendAnalysis) {
|
||||
trendDateAggregationType.value = ChartDateAggregationType.Month.type;
|
||||
if (analysisType.value !== StatisticsAnalysisType.TrendAnalysis && type === StatisticsAnalysisType.TrendAnalysis) {
|
||||
trendDateAggregationType.value = ChartDateAggregationType.Default.type;
|
||||
} else if (analysisType.value !== StatisticsAnalysisType.AssetTrends && type === StatisticsAnalysisType.AssetTrends) {
|
||||
assetTrendsDateAggregationType.value = ChartDateAggregationType.Default.type;
|
||||
}
|
||||
|
||||
analysisType.value = type;
|
||||
@@ -848,6 +983,10 @@ function setChartType(type?: number): void {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
trendChartType: type
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
assetTrendsChartType: type
|
||||
});
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@@ -888,6 +1027,15 @@ function setTrendDateAggregationType(type: number): void {
|
||||
}
|
||||
}
|
||||
|
||||
function setAssetTrendsDateAggregationType(type: number): void {
|
||||
const changed = assetTrendsDateAggregationType.value !== type;
|
||||
assetTrendsDateAggregationType.value = type;
|
||||
|
||||
if (changed) {
|
||||
router.push(getFilterLinkUrl());
|
||||
}
|
||||
}
|
||||
|
||||
function setDateFilter(dateType: number): void {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
if (dateType === DateRange.Custom.type) { // Custom
|
||||
@@ -903,6 +1051,13 @@ function setDateFilter(dateType: number): void {
|
||||
} else if (query.value.trendChartDateType === dateType) {
|
||||
return;
|
||||
}
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
if (dateType === DateRange.Custom.type) { // Custom
|
||||
showCustomDateRangeDialog.value = true;
|
||||
return;
|
||||
} else if (query.value.assetTrendsChartDateType === dateType) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const dateRange = getDateRangeByDateType(dateType, firstDayOfWeek.value, fiscalYearStart.value);
|
||||
@@ -925,6 +1080,12 @@ function setDateFilter(dateType: number): void {
|
||||
trendChartStartYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(dateRange.minTime),
|
||||
trendChartEndYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(dateRange.maxTime)
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
assetTrendsChartDateType: dateRange.dateType,
|
||||
assetTrendsChartStartTime: dateRange.minTime,
|
||||
assetTrendsChartEndTime: dateRange.maxTime
|
||||
});
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@@ -961,6 +1122,16 @@ function setCustomDateFilter(startTime: number | TextualYearMonth, endTime: numb
|
||||
});
|
||||
|
||||
showCustomMonthRangeDialog.value = false;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends && isNumber(startTime) && isNumber(endTime)) {
|
||||
const chartDateType = getDateTypeByDateRange(startTime, endTime, firstDayOfWeek.value, fiscalYearStart.value, DateRangeScene.AssetTrends);
|
||||
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
assetTrendsChartDateType: chartDateType,
|
||||
assetTrendsChartStartTime: startTime,
|
||||
assetTrendsChartEndTime: endTime
|
||||
});
|
||||
|
||||
showCustomDateRangeDialog.value = false;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@@ -993,6 +1164,18 @@ function shiftDateRange(scale: number): void {
|
||||
trendChartStartYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(newDateRange.minTime),
|
||||
trendChartEndYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(newDateRange.maxTime)
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
if (query.value.assetTrendsChartDateType === DateRange.All.type) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newDateRange = getShiftedDateRangeAndDateType(query.value.assetTrendsChartStartTime, query.value.assetTrendsChartEndTime, scale, firstDayOfWeek.value, fiscalYearStart.value, DateRangeScene.AssetTrends);
|
||||
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
assetTrendsChartDateType: newDateRange.dateType,
|
||||
assetTrendsChartStartTime: newDateRange.minTime,
|
||||
assetTrendsChartEndTime: newDateRange.maxTime
|
||||
});
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@@ -1033,6 +1216,10 @@ function setTagFilter(changed: boolean): void {
|
||||
}
|
||||
|
||||
function setKeywordFilter(keyword: string): void {
|
||||
if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (query.value.keyword === keyword) {
|
||||
return;
|
||||
}
|
||||
@@ -1078,6 +1265,12 @@ function exportResults(): void {
|
||||
headers: exportData.headers || [],
|
||||
data: exportData.data || []
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends && assetTrendsData.value && assetTrendsData.value.items && dailyTrendsChart.value) {
|
||||
const exportData = dailyTrendsChart.value.exportData();
|
||||
exportDialog.value?.open({
|
||||
headers: exportData.headers || [],
|
||||
data: exportData.data || []
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1125,7 +1318,8 @@ onBeforeRouteUpdate((to) => {
|
||||
initTagFilterType: (to.query['tagFilterType'] as string | null) || undefined,
|
||||
initKeyword: (to.query['keyword'] as string | null) || undefined,
|
||||
initSortingType: (to.query['sortingType'] as string | null) || undefined,
|
||||
initTrendDateAggregationType: (to.query['trendDateAggregationType'] as string | null) || undefined
|
||||
initTrendDateAggregationType: (to.query['trendDateAggregationType'] as string | null) || undefined,
|
||||
initAssetTrendsDateAggregationType: (to.query['assetTrendsDateAggregationType'] as string | null) || undefined
|
||||
});
|
||||
} else {
|
||||
init({});
|
||||
|
||||
@@ -1795,12 +1795,16 @@ init(props);
|
||||
|
||||
<style>
|
||||
.transaction-keyword-filter .v-input--density-compact {
|
||||
--v-input-control-height: 36px !important;
|
||||
--v-input-control-height: 38px !important;
|
||||
--v-input-padding-top: 5px !important;
|
||||
--v-input-padding-bottom: 5px !important;
|
||||
--v-input-chips-margin-top: 0px !important;
|
||||
--v-input-chips-margin-bottom: 0px !important;
|
||||
inline-size: 20rem;
|
||||
|
||||
.v-field__input {
|
||||
min-block-size: 38px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.transaction-list-datetime-range {
|
||||
|
||||
@@ -281,14 +281,6 @@
|
||||
<f7-popover class="chart-data-date-aggregation-type-popover-menu"
|
||||
v-model:opened="showChartDataDateAggregationTypePopover">
|
||||
<f7-list dividers>
|
||||
<f7-list-item :title="tt('granularity.Daily')"
|
||||
:class="{ 'list-item-selected': chartDataDateAggregationType === undefined }"
|
||||
key="daily"
|
||||
@click="setChartDataDateAggregationType(undefined)">
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="chartDataDateAggregationType === undefined"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
<f7-list-item :title="dateAggregationType.displayName"
|
||||
:class="{ 'list-item-selected': chartDataDateAggregationType === dateAggregationType.type }"
|
||||
:key="dateAggregationType.type"
|
||||
@@ -358,6 +350,7 @@ import { TextDirection } from '@/core/text.ts';
|
||||
import { type TimeRangeAndDateType, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
||||
import { AccountType } from '@/core/account.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
import { ChartDateAggregationType } from '@/core/statistics.ts';
|
||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||
import { type TransactionReconciliationStatementResponseItem } from '@/models/transaction.ts';
|
||||
|
||||
@@ -436,7 +429,7 @@ const loading = ref<boolean>(false);
|
||||
const loadingError = ref<unknown | null>(null);
|
||||
const queryDateRangeType = ref<number>(DateRange.ThisMonth.type);
|
||||
const showAccountBalanceTrendsCharts = ref<boolean>(false);
|
||||
const chartDataDateAggregationType = ref<number | undefined>(undefined);
|
||||
const chartDataDateAggregationType = ref<number>(ChartDateAggregationType.Day.type);
|
||||
const transactionToDelete = ref<TransactionReconciliationStatementResponseItem | null>(null);
|
||||
const newClosingBalance = ref<number>(0);
|
||||
const showDisplayModePopover = ref<boolean>(false);
|
||||
@@ -489,10 +482,6 @@ const allReconciliationStatementVirtualListItems = computed<ReconciliationStatem
|
||||
});
|
||||
|
||||
const chartDataDateAggregationTypeDisplayName = computed<string>(() => {
|
||||
if (chartDataDateAggregationType.value === undefined) {
|
||||
return tt('granularity.Daily');
|
||||
}
|
||||
|
||||
return findDisplayNameByType(allDateAggregationTypes.value, chartDataDateAggregationType.value) || tt('Unknown');
|
||||
});
|
||||
|
||||
@@ -681,7 +670,7 @@ function removeTransaction(transaction: TransactionReconciliationStatementRespon
|
||||
});
|
||||
}
|
||||
|
||||
function setChartDataDateAggregationType(type: number | undefined): void {
|
||||
function setChartDataDateAggregationType(type: number): void {
|
||||
chartDataDateAggregationType.value = type;
|
||||
showChartDataDateAggregationTypePopover.value = false;
|
||||
}
|
||||
|
||||
@@ -128,6 +128,28 @@
|
||||
</list-item-selection-popup>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
|
||||
<f7-block-title>{{ tt('Asset Trends Settings') }}</f7-block-title>
|
||||
<f7-list strong inset dividers>
|
||||
<f7-list-item
|
||||
link="#"
|
||||
:title="tt('Default Date Range')"
|
||||
:after="findDisplayNameByType(allAssetTrendsChartDateRanges, defaultAssetTrendsChartDateRange)"
|
||||
@click="showDefaultAssetTrendsChartDateRangePopup = true"
|
||||
>
|
||||
<list-item-selection-popup value-type="item"
|
||||
key-field="type" value-field="type"
|
||||
title-field="displayName"
|
||||
:title="tt('Default Date Range')"
|
||||
:enable-filter="true"
|
||||
:filter-placeholder="tt('Date Range')"
|
||||
:filter-no-items-text="tt('No results')"
|
||||
:items="allAssetTrendsChartDateRanges"
|
||||
v-model:show="showDefaultAssetTrendsChartDateRangePopup"
|
||||
v-model="defaultAssetTrendsChartDateRange">
|
||||
</list-item-selection-popup>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-page>
|
||||
</template>
|
||||
|
||||
@@ -145,12 +167,14 @@ const {
|
||||
allCategoricalChartTypes,
|
||||
allCategoricalChartDateRanges,
|
||||
allTrendChartDateRanges,
|
||||
allAssetTrendsChartDateRanges,
|
||||
defaultChartDataType,
|
||||
defaultTimezoneType,
|
||||
defaultSortingType,
|
||||
defaultCategoricalChartType,
|
||||
defaultCategoricalChartDateRange,
|
||||
defaultTrendChartDateRange
|
||||
defaultTrendChartDateRange,
|
||||
defaultAssetTrendsChartDateRange
|
||||
} = useStatisticsSettingPageBase();
|
||||
|
||||
import { findDisplayNameByType } from '@/lib/common.ts';
|
||||
@@ -161,4 +185,5 @@ const showDefaultSortingTypePopup = ref<boolean>(false);
|
||||
const showDefaultCategoricalChartTypePopup = ref<boolean>(false);
|
||||
const showDefaultCategoricalChartDateRangePopup = ref<boolean>(false);
|
||||
const showDefaultTrendChartDateRangePopup = ref<boolean>(false);
|
||||
const showDefaultAssetTrendsChartDateRangePopup = ref<boolean>(false);
|
||||
</script>
|
||||
|
||||
@@ -45,6 +45,20 @@
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list-group>
|
||||
<f7-list-group>
|
||||
<f7-list-item group-title>
|
||||
<small>{{ tt('Asset Trends') }}</small>
|
||||
</f7-list-item>
|
||||
<f7-list-item :title="tt(dataType.name)"
|
||||
:class="{ 'list-item-selected': analysisType === StatisticsAnalysisType.AssetTrends && query.chartDataType === dataType.type }"
|
||||
:key="dataType.type"
|
||||
v-for="dataType in ChartDataType.values(StatisticsAnalysisType.AssetTrends)"
|
||||
@click="setChartDataType(StatisticsAnalysisType.AssetTrends, dataType.type)">
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="analysisType === StatisticsAnalysisType.AssetTrends && query.chartDataType === dataType.type"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list-group>
|
||||
</f7-list>
|
||||
</f7-popover>
|
||||
|
||||
@@ -203,11 +217,15 @@
|
||||
</div>
|
||||
</f7-card-header>
|
||||
<f7-card-content style="margin-top: -14px" :padding="false">
|
||||
<monthly-trends-bar-chart
|
||||
<trends-bar-chart
|
||||
chart-mode="monthly"
|
||||
:loading="loading || reloading"
|
||||
:start-time="undefined"
|
||||
:end-time="undefined"
|
||||
:start-year-month="query.trendChartStartYearMonth"
|
||||
:end-year-month="query.trendChartEndYearMonth"
|
||||
:sorting-type="query.sortingType"
|
||||
:data-aggregation-type="ChartDataAggregationType.Sum"
|
||||
:date-aggregation-type="trendDateAggregationType"
|
||||
:fiscal-year-start="fiscalYearStart"
|
||||
:items="trendsAnalysisData && trendsAnalysisData.items && trendsAnalysisData.items.length ? trendsAnalysisData.items : []"
|
||||
@@ -224,6 +242,42 @@
|
||||
</f7-card-content>
|
||||
</f7-card>
|
||||
|
||||
<f7-card v-else-if="analysisType === StatisticsAnalysisType.AssetTrends">
|
||||
<f7-card-header class="no-border display-block">
|
||||
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
|
||||
<div></div>
|
||||
<div class="align-self-flex-end">
|
||||
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
|
||||
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
|
||||
</div>
|
||||
</div>
|
||||
</f7-card-header>
|
||||
<f7-card-content style="margin-top: -14px" :padding="false">
|
||||
<trends-bar-chart
|
||||
chart-mode="daily"
|
||||
:loading="loading || reloading"
|
||||
:start-time="query.assetTrendsChartStartTime"
|
||||
:end-time="query.assetTrendsChartEndTime"
|
||||
:start-year-month="undefined"
|
||||
:end-year-month="undefined"
|
||||
:sorting-type="query.sortingType"
|
||||
:data-aggregation-type="ChartDataAggregationType.Last"
|
||||
:date-aggregation-type="assetTrendsDateAggregationType"
|
||||
:fiscal-year-start="fiscalYearStart"
|
||||
:items="assetTrendsData && assetTrendsData.items && assetTrendsData.items.length ? assetTrendsData.items : []"
|
||||
:stacked="showStackedInTrendsChart"
|
||||
:translate-name="translateNameInTrendsChart"
|
||||
:default-currency="defaultCurrency"
|
||||
id-field="id"
|
||||
name-field="name"
|
||||
value-field="totalAmount"
|
||||
hidden-field="hidden"
|
||||
display-orders-field="displayOrders"
|
||||
@click="onClickTrendChartItem"
|
||||
/>
|
||||
</f7-card-content>
|
||||
</f7-card>
|
||||
|
||||
<f7-popover class="sorting-type-popover-menu"
|
||||
v-model:opened="showSortingTypePopover">
|
||||
<f7-list dividers>
|
||||
@@ -243,7 +297,7 @@
|
||||
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(-1)">
|
||||
<f7-icon class="icon-with-direction" f7="arrow_left_square"></f7-icon>
|
||||
</f7-link>
|
||||
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading || query.chartDataType === ChartDataType.AccountTotalAssets.type || query.chartDataType === ChartDataType.AccountTotalLiabilities.type }" popover-open=".date-popover-menu">
|
||||
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading || !canChangeDateRange }" popover-open=".date-popover-menu">
|
||||
<span :class="{ 'tabbar-item-changed': isQueryDateRangeChanged }">{{ queryDateRangeName }}</span>
|
||||
</f7-link>
|
||||
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(1)">
|
||||
@@ -253,6 +307,10 @@
|
||||
v-if="analysisType === StatisticsAnalysisType.TrendAnalysis">
|
||||
<span :class="{ 'tabbar-item-changed': trendDateAggregationType !== ChartDateAggregationType.Default.type }">{{ queryTrendDateAggregationTypeName }}</span>
|
||||
</f7-link>
|
||||
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading }" popover-open=".date-aggregation-popover-menu"
|
||||
v-if="analysisType === StatisticsAnalysisType.AssetTrends">
|
||||
<span :class="{ 'tabbar-item-changed': assetTrendsDateAggregationType !== ChartDateAggregationType.Default.type }">{{ queryAssetTrendsDateAggregationTypeName }}</span>
|
||||
</f7-link>
|
||||
<f7-link class="tabbar-text-with-ellipsis" :key="chartType.type"
|
||||
v-for="chartType in allChartTypes" @click="setChartType(chartType.type)">
|
||||
<span :class="{ 'tabbar-item-changed': queryChartType === chartType.type }">{{ chartType.displayName }}</span>
|
||||
@@ -286,17 +344,28 @@
|
||||
<f7-popover class="date-aggregation-popover-menu"
|
||||
v-model:opened="showDateAggregationPopover"
|
||||
@popover:open="scrollPopoverToSelectedItem">
|
||||
<f7-list dividers>
|
||||
<f7-list dividers v-if="analysisType === StatisticsAnalysisType.TrendAnalysis">
|
||||
<f7-list-item :title="aggregationType.displayName"
|
||||
:class="{ 'list-item-selected': trendDateAggregationType === aggregationType.type }"
|
||||
:key="aggregationType.type"
|
||||
v-for="aggregationType in allDateAggregationTypes"
|
||||
v-for="aggregationType in allTrendAnalysisDateAggregationTypes"
|
||||
@click="setTrendDateAggregationType(aggregationType.type)">
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="trendDateAggregationType === aggregationType.type"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
<f7-list dividers v-else-if="analysisType === StatisticsAnalysisType.AssetTrends">
|
||||
<f7-list-item :title="aggregationType.displayName"
|
||||
:class="{ 'list-item-selected': assetTrendsDateAggregationType === aggregationType.type }"
|
||||
:key="aggregationType.type"
|
||||
v-for="aggregationType in allAssetTrendsDateAggregationTypes"
|
||||
@click="setAssetTrendsDateAggregationType(aggregationType.type)">
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="assetTrendsDateAggregationType === aggregationType.type"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-popover>
|
||||
|
||||
<date-range-selection-sheet :title="tt('Custom Date Range')"
|
||||
@@ -348,6 +417,7 @@ import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { type TextualYearMonth, type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import {
|
||||
ChartDataAggregationType,
|
||||
StatisticsAnalysisType,
|
||||
CategoricalChartType,
|
||||
ChartDataType,
|
||||
@@ -383,12 +453,14 @@ const {
|
||||
loading,
|
||||
analysisType,
|
||||
trendDateAggregationType,
|
||||
assetTrendsDateAggregationType,
|
||||
defaultCurrency,
|
||||
firstDayOfWeek,
|
||||
fiscalYearStart,
|
||||
allDateRanges,
|
||||
allSortingTypes,
|
||||
allDateAggregationTypes,
|
||||
allTrendAnalysisDateAggregationTypes,
|
||||
allAssetTrendsDateAggregationTypes,
|
||||
query,
|
||||
queryChartDataCategory,
|
||||
queryDateType,
|
||||
@@ -398,7 +470,9 @@ const {
|
||||
queryChartDataTypeName,
|
||||
querySortingTypeName,
|
||||
queryTrendDateAggregationTypeName,
|
||||
queryAssetTrendsDateAggregationTypeName,
|
||||
isQueryDateRangeChanged,
|
||||
canChangeDateRange,
|
||||
canShiftDateRange,
|
||||
canUseCategoryFilter,
|
||||
canUseTagFilter,
|
||||
@@ -410,6 +484,7 @@ const {
|
||||
translateNameInTrendsChart,
|
||||
categoricalAnalysisData,
|
||||
trendsAnalysisData,
|
||||
assetTrendsData,
|
||||
canShowCustomDateRange,
|
||||
getTransactionCategoricalAnalysisDataItemDisplayColor,
|
||||
getDisplayAmount
|
||||
@@ -445,6 +520,8 @@ const queryChartType = computed<number | undefined>({
|
||||
return query.value.categoricalChartType;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
return query.value.trendChartType;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return query.value.assetTrendsChartType;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
@@ -473,6 +550,10 @@ function init(): void {
|
||||
return statisticsStore.loadTrendAnalysis({
|
||||
force: false
|
||||
}) as Promise<unknown>;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return statisticsStore.loadAssetTrends({
|
||||
force: false
|
||||
}) as Promise<unknown>;
|
||||
} else {
|
||||
return Promise.reject('An error occurred');
|
||||
}
|
||||
@@ -507,7 +588,8 @@ function reload(done?: () => void): void {
|
||||
query.value.chartDataType === ChartDataType.TotalInflows.type ||
|
||||
query.value.chartDataType === ChartDataType.TotalIncome.type ||
|
||||
query.value.chartDataType === ChartDataType.NetCashFlow.type ||
|
||||
query.value.chartDataType === ChartDataType.NetIncome.type) {
|
||||
query.value.chartDataType === ChartDataType.NetIncome.type ||
|
||||
query.value.chartDataType === ChartDataType.NetWorth.type) {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
dispatchPromise = statisticsStore.loadCategoricalAnalysis({
|
||||
force: force
|
||||
@@ -516,12 +598,22 @@ function reload(done?: () => void): void {
|
||||
dispatchPromise = statisticsStore.loadTrendAnalysis({
|
||||
force: force
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
dispatchPromise = statisticsStore.loadAssetTrends({
|
||||
force: force
|
||||
});
|
||||
}
|
||||
} else if (query.value.chartDataType === ChartDataType.AccountTotalAssets.type ||
|
||||
query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type) {
|
||||
dispatchPromise = accountsStore.loadAllAccounts({
|
||||
force: force
|
||||
});
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
dispatchPromise = accountsStore.loadAllAccounts({
|
||||
force: force
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
dispatchPromise = statisticsStore.loadAssetTrends({
|
||||
force: force
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (dispatchPromise) {
|
||||
@@ -556,6 +648,10 @@ function setChartType(type?: number): void {
|
||||
statisticsStore.updateTransactionStatisticsFilter({
|
||||
trendChartType: type
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
statisticsStore.updateTransactionStatisticsFilter({
|
||||
assetTrendsChartType: type
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,6 +699,11 @@ function setTrendDateAggregationType(type: number): void {
|
||||
showDateAggregationPopover.value = false;
|
||||
}
|
||||
|
||||
function setAssetTrendsDateAggregationType(type: number): void {
|
||||
assetTrendsDateAggregationType.value = type;
|
||||
showDateAggregationPopover.value = false;
|
||||
}
|
||||
|
||||
function setDateFilter(dateType: number): void {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
if (dateType === DateRange.Custom.type) { // Custom
|
||||
@@ -620,6 +721,14 @@ function setDateFilter(dateType: number): void {
|
||||
} else if (query.value.trendChartDateType === dateType) {
|
||||
return;
|
||||
}
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
if (dateType === DateRange.Custom.type) { // Custom
|
||||
showCustomDateRangeSheet.value = true;
|
||||
showDatePopover.value = false;
|
||||
return;
|
||||
} else if (query.value.assetTrendsChartDateType === dateType) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const dateRange = getDateRangeByDateType(dateType, firstDayOfWeek.value, fiscalYearStart.value);
|
||||
@@ -642,6 +751,12 @@ function setDateFilter(dateType: number): void {
|
||||
trendChartStartYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(dateRange.minTime),
|
||||
trendChartEndYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(dateRange.maxTime)
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
assetTrendsChartDateType: dateRange.dateType,
|
||||
assetTrendsChartStartTime: dateRange.minTime,
|
||||
assetTrendsChartEndTime: dateRange.maxTime
|
||||
});
|
||||
}
|
||||
|
||||
showDatePopover.value = false;
|
||||
@@ -678,6 +793,16 @@ function setCustomDateFilter(startTime: number | TextualYearMonth, endTime: numb
|
||||
});
|
||||
|
||||
showCustomMonthRangeSheet.value = false;
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends && isNumber(startTime) && isNumber(endTime)) {
|
||||
const chartDateType = getDateTypeByDateRange(startTime, endTime, firstDayOfWeek.value, fiscalYearStart.value, DateRangeScene.AssetTrends);
|
||||
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
assetTrendsChartDateType: chartDateType,
|
||||
assetTrendsChartStartTime: startTime,
|
||||
assetTrendsChartEndTime: endTime
|
||||
});
|
||||
|
||||
showCustomDateRangeSheet.value = false;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@@ -708,6 +833,18 @@ function shiftDateRange(scale: number): void {
|
||||
trendChartStartYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(newDateRange.minTime),
|
||||
trendChartEndYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(newDateRange.maxTime)
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
if (query.value.assetTrendsChartDateType === DateRange.All.type) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newDateRange = getShiftedDateRangeAndDateType(query.value.assetTrendsChartStartTime, query.value.assetTrendsChartEndTime, scale, firstDayOfWeek.value, fiscalYearStart.value, DateRangeScene.AssetTrends);
|
||||
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
assetTrendsChartDateType: newDateRange.dateType,
|
||||
assetTrendsChartStartTime: newDateRange.minTime,
|
||||
assetTrendsChartEndTime: newDateRange.maxTime
|
||||
});
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@@ -728,6 +865,10 @@ function filterTags(): void {
|
||||
}
|
||||
|
||||
function filterDescription(): void {
|
||||
if (analysisType.value === StatisticsAnalysisType.AssetTrends) {
|
||||
return;
|
||||
}
|
||||
|
||||
showPrompt('Filter transaction description', query.value.keyword, value => {
|
||||
if (query.value.keyword === value) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user