filter transaction description keywords in statistics & analysis page
This commit is contained in:
@@ -316,7 +316,7 @@ func (a *TransactionsApi) TransactionStatisticsHandler(c *core.WebContext) (any,
|
||||
}
|
||||
|
||||
uid := c.GetCurrentUid()
|
||||
totalAmounts, err := a.transactions.GetAccountsAndCategoriesTotalIncomeAndExpense(c, uid, statisticReq.StartTime, statisticReq.EndTime, allTagIds, noTags, statisticReq.TagFilterType, utcOffset, statisticReq.UseTransactionTimezone)
|
||||
totalAmounts, err := a.transactions.GetAccountsAndCategoriesTotalIncomeAndExpense(c, uid, statisticReq.StartTime, statisticReq.EndTime, allTagIds, noTags, statisticReq.TagFilterType, statisticReq.Keyword, utcOffset, statisticReq.UseTransactionTimezone)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[transactions.TransactionStatisticsHandler] failed to get accounts and categories total income and expense for user \"uid:%d\", because %s", uid, err.Error())
|
||||
@@ -379,7 +379,7 @@ func (a *TransactionsApi) TransactionStatisticsTrendsHandler(c *core.WebContext)
|
||||
}
|
||||
|
||||
uid := c.GetCurrentUid()
|
||||
allMonthlyTotalAmounts, err := a.transactions.GetAccountsAndCategoriesMonthlyIncomeAndExpense(c, uid, startYear, startMonth, endYear, endMonth, allTagIds, noTags, statisticTrendsReq.TagFilterType, utcOffset, statisticTrendsReq.UseTransactionTimezone)
|
||||
allMonthlyTotalAmounts, err := a.transactions.GetAccountsAndCategoriesMonthlyIncomeAndExpense(c, uid, startYear, startMonth, endYear, endMonth, allTagIds, noTags, statisticTrendsReq.TagFilterType, statisticTrendsReq.Keyword, utcOffset, statisticTrendsReq.UseTransactionTimezone)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[transactions.TransactionStatisticsTrendsHandler] failed to get accounts and categories total income and expense for user \"uid:%d\", because %s", uid, err.Error())
|
||||
|
||||
@@ -228,6 +228,7 @@ type TransactionStatisticRequest struct {
|
||||
EndTime int64 `form:"end_time" binding:"min=0"`
|
||||
TagIds string `form:"tag_ids"`
|
||||
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
|
||||
Keyword string `form:"keyword"`
|
||||
UseTransactionTimezone bool `form:"use_transaction_timezone"`
|
||||
}
|
||||
|
||||
@@ -236,6 +237,7 @@ type TransactionStatisticTrendsRequest struct {
|
||||
YearMonthRangeRequest
|
||||
TagIds string `form:"tag_ids"`
|
||||
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
|
||||
Keyword string `form:"keyword"`
|
||||
UseTransactionTimezone bool `form:"use_transaction_timezone"`
|
||||
}
|
||||
|
||||
|
||||
@@ -1421,7 +1421,7 @@ func (s *TransactionService) GetAccountsTotalIncomeAndExpense(c core.Context, ui
|
||||
}
|
||||
|
||||
// GetAccountsAndCategoriesTotalIncomeAndExpense returns the every accounts and categories total income and expense amount by specific date range
|
||||
func (s *TransactionService) GetAccountsAndCategoriesTotalIncomeAndExpense(c core.Context, uid int64, startUnixTime int64, endUnixTime int64, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, utcOffset int16, useTransactionTimezone bool) ([]*models.Transaction, error) {
|
||||
func (s *TransactionService) GetAccountsAndCategoriesTotalIncomeAndExpense(c core.Context, uid int64, startUnixTime int64, endUnixTime int64, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, keyword string, utcOffset int16, useTransactionTimezone bool) ([]*models.Transaction, error) {
|
||||
if uid <= 0 {
|
||||
return nil, errs.ErrUserIdInvalid
|
||||
}
|
||||
@@ -1469,6 +1469,11 @@ func (s *TransactionService) GetAccountsAndCategoriesTotalIncomeAndExpense(c cor
|
||||
finalConditionParams = append(finalConditionParams, maxTransactionTime)
|
||||
}
|
||||
|
||||
if keyword != "" {
|
||||
finalCondition = finalCondition + " AND comment LIKE ?"
|
||||
finalConditionParams = append(finalConditionParams, "%%"+keyword+"%%")
|
||||
}
|
||||
|
||||
sess := s.UserDataDB(uid).NewSession(c).Select("category_id, account_id, transaction_time, timezone_utc_offset, amount").Where(finalCondition, finalConditionParams...)
|
||||
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagIds, noTags, tagFilterType)
|
||||
|
||||
@@ -1530,7 +1535,7 @@ func (s *TransactionService) GetAccountsAndCategoriesTotalIncomeAndExpense(c cor
|
||||
}
|
||||
|
||||
// GetAccountsAndCategoriesMonthlyIncomeAndExpense returns the every accounts monthly income and expense amount by specific date range
|
||||
func (s *TransactionService) GetAccountsAndCategoriesMonthlyIncomeAndExpense(c core.Context, uid int64, startYear int32, startMonth int32, endYear int32, endMonth int32, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, utcOffset int16, useTransactionTimezone bool) (map[int32][]*models.Transaction, error) {
|
||||
func (s *TransactionService) GetAccountsAndCategoriesMonthlyIncomeAndExpense(c core.Context, uid int64, startYear int32, startMonth int32, endYear int32, endMonth int32, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, keyword string, utcOffset int16, useTransactionTimezone bool) (map[int32][]*models.Transaction, error) {
|
||||
if uid <= 0 {
|
||||
return nil, errs.ErrUserIdInvalid
|
||||
}
|
||||
@@ -1583,6 +1588,11 @@ func (s *TransactionService) GetAccountsAndCategoriesMonthlyIncomeAndExpense(c c
|
||||
finalConditionParams = append(finalConditionParams, maxTransactionTime)
|
||||
}
|
||||
|
||||
if keyword != "" {
|
||||
finalCondition = finalCondition + " AND comment LIKE ?"
|
||||
finalConditionParams = append(finalConditionParams, "%%"+keyword+"%%")
|
||||
}
|
||||
|
||||
sess := s.UserDataDB(uid).NewSession(c).Select("category_id, account_id, transaction_time, timezone_utc_offset, amount").Where(finalCondition, finalConditionParams...)
|
||||
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagIds, noTags, tagFilterType)
|
||||
|
||||
|
||||
@@ -432,6 +432,10 @@ export default {
|
||||
queryParams.push(`tag_filter_type=${req.tagFilterType}`);
|
||||
}
|
||||
|
||||
if (req.keyword) {
|
||||
queryParams.push(`keyword=${encodeURIComponent(req.keyword)}`);
|
||||
}
|
||||
|
||||
return axios.get<ApiResponse<TransactionStatisticResponse>>(`v1/transactions/statistics.json?use_transaction_timezone=${req.useTransactionTimezone}` + (queryParams.length ? '&' + queryParams.join('&') : ''));
|
||||
},
|
||||
getTransactionStatisticsTrends: (req: TransactionStatisticTrendsRequest): ApiResponsePromise<TransactionStatisticTrendsResponseItem[]> => {
|
||||
@@ -453,6 +457,10 @@ export default {
|
||||
queryParams.push(`tag_filter_type=${req.tagFilterType}`);
|
||||
}
|
||||
|
||||
if (req.keyword) {
|
||||
queryParams.push(`keyword=${encodeURIComponent(req.keyword)}`);
|
||||
}
|
||||
|
||||
return axios.get<ApiResponse<TransactionStatisticTrendsResponseItem[]>>(`v1/transactions/statistics/trends.json?use_transaction_timezone=${req.useTransactionTimezone}` + (queryParams.length ? '&' + queryParams.join('&') : ''));
|
||||
},
|
||||
getTransactionAmounts: (params: TransactionAmountsRequestParams): ApiResponsePromise<TransactionAmountsResponse> => {
|
||||
|
||||
@@ -249,6 +249,37 @@ export function useI18nUIComponents() {
|
||||
});
|
||||
}
|
||||
|
||||
function showPrompt(message: string, currentValue?: string, confirmCallback?: (value: string, dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: (value: string, dialog: Dialog.Dialog, e: Event) => void): void {
|
||||
f7ready((f7) => {
|
||||
f7.dialog.create({
|
||||
title: tt('global.app.title'),
|
||||
text: tt(message),
|
||||
content: `<div class="dialog-input-field input"><input type="text" class="dialog-input" value="${currentValue || ''}"></div>`,
|
||||
animate: isEnableAnimate(),
|
||||
buttons: [
|
||||
{
|
||||
text: tt('Cancel'),
|
||||
onClick: (dialog, event) => {
|
||||
if (cancelCallback) {
|
||||
const inputValue = dialog.$el.find('.dialog-input').val();
|
||||
cancelCallback(inputValue, dialog, event);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
text: tt('OK'),
|
||||
onClick: (dialog, event) => {
|
||||
if (confirmCallback) {
|
||||
const inputValue = dialog.$el.find('.dialog-input').val();
|
||||
confirmCallback(inputValue, dialog, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}).open();
|
||||
});
|
||||
}
|
||||
|
||||
function showToast(message: string, timeout?: number): void {
|
||||
f7ready((f7) => {
|
||||
f7.toast.create({
|
||||
@@ -262,6 +293,7 @@ export function useI18nUIComponents() {
|
||||
return {
|
||||
showAlert: showAlert,
|
||||
showConfirm: showConfirm,
|
||||
showPrompt: showPrompt,
|
||||
showToast: showToast,
|
||||
routeBackOnError
|
||||
}
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "Konten filtern",
|
||||
"Filter Transaction Categories": "Transaktionskategorien filtern",
|
||||
"Filter Transaction Tags": "Transaktions-Tags filtern",
|
||||
"Filter transaction description": "Filter transaction description",
|
||||
"User Settings": "Benutzereinstellungen",
|
||||
"User Profile": "Benutzerprofil",
|
||||
"Language": "Sprache",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "Filter Accounts",
|
||||
"Filter Transaction Categories": "Filter Transaction Categories",
|
||||
"Filter Transaction Tags": "Filter Transaction Tags",
|
||||
"Filter transaction description": "Filter transaction description",
|
||||
"User Settings": "User Settings",
|
||||
"User Profile": "User Profile",
|
||||
"Language": "Language",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "Filtrar cuentas",
|
||||
"Filter Transaction Categories": "Filtrar categorías de transacciones",
|
||||
"Filter Transaction Tags": "Filtrar etiquetas de transacciones",
|
||||
"Filter transaction description": "Filter transaction description",
|
||||
"User Settings": "Configuración de usuario",
|
||||
"User Profile": "Perfil de usuario",
|
||||
"Language": "Idioma",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "Filtra conti",
|
||||
"Filter Transaction Categories": "Filtra categorie transazione",
|
||||
"Filter Transaction Tags": "Filtra tag transazione",
|
||||
"Filter transaction description": "Filter transaction description",
|
||||
"User Settings": "Impostazioni utente",
|
||||
"User Profile": "Profilo utente",
|
||||
"Language": "Lingua",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "口座で絞り込み",
|
||||
"Filter Transaction Categories": "取引カテゴリで絞り込み",
|
||||
"Filter Transaction Tags": "取引タグで絞り込み",
|
||||
"Filter transaction description": "Filter transaction description",
|
||||
"User Settings": "ユーザー設定",
|
||||
"User Profile": "ユーザープロフィール",
|
||||
"Language": "言語",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "Filtrar Contas",
|
||||
"Filter Transaction Categories": "Filtrar Categorias de Transações",
|
||||
"Filter Transaction Tags": "Filtrar Tags de Transações",
|
||||
"Filter transaction description": "Filter transaction description",
|
||||
"User Settings": "Configurações do Usuário",
|
||||
"User Profile": "Perfil do Usuário",
|
||||
"Language": "Idioma",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "Фильтровать счета",
|
||||
"Filter Transaction Categories": "Фильтровать категории транзакций",
|
||||
"Filter Transaction Tags": "Фильтровать теги транзакций",
|
||||
"Filter transaction description": "Filter transaction description",
|
||||
"User Settings": "Настройки пользователя",
|
||||
"User Profile": "Профиль пользователя",
|
||||
"Language": "Язык",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "Фільтрувати рахунки",
|
||||
"Filter Transaction Categories": "Фільтрувати категорії транзакцій",
|
||||
"Filter Transaction Tags": "Фільтрувати теги транзакцій",
|
||||
"Filter transaction description": "Filter transaction description",
|
||||
"User Settings": "Налаштування користувача",
|
||||
"User Profile": "Профіль користувача",
|
||||
"Language": "Мова",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "Lọc tài khoản",
|
||||
"Filter Transaction Categories": "Lọc danh mục giao dịch",
|
||||
"Filter Transaction Tags": "Lọc thẻ giao dịch",
|
||||
"Filter transaction description": "Filter transaction description",
|
||||
"User Settings": "Cài đặt người dùng",
|
||||
"User Profile": "Hồ sơ người dùng",
|
||||
"Language": "Ngôn ngữ",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "过滤账户",
|
||||
"Filter Transaction Categories": "过滤交易类型",
|
||||
"Filter Transaction Tags": "过滤交易标签",
|
||||
"Filter transaction description": "过滤交易描述",
|
||||
"User Settings": "用户设置",
|
||||
"User Profile": "用户信息",
|
||||
"Language": "语言",
|
||||
|
||||
@@ -1851,6 +1851,7 @@
|
||||
"Filter Accounts": "篩選帳戶",
|
||||
"Filter Transaction Categories": "篩選交易類型",
|
||||
"Filter Transaction Tags": "篩選交易標籤",
|
||||
"Filter transaction description": "篩選交易描述",
|
||||
"User Settings": "使用者設定",
|
||||
"User Profile": "使用者資料",
|
||||
"Language": "語言",
|
||||
|
||||
@@ -548,6 +548,7 @@ export interface TransactionStatisticRequest {
|
||||
readonly endTime: number;
|
||||
readonly tagIds: string;
|
||||
readonly tagFilterType: number;
|
||||
readonly keyword: string;
|
||||
readonly useTransactionTimezone: boolean;
|
||||
}
|
||||
|
||||
@@ -559,6 +560,7 @@ export interface YearMonthRangeRequest {
|
||||
export interface TransactionStatisticTrendsRequest extends YearMonthRangeRequest {
|
||||
readonly tagIds: string;
|
||||
readonly tagFilterType: number;
|
||||
readonly keyword: string;
|
||||
readonly useTransactionTimezone: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,6 +131,7 @@ const router = createRouter({
|
||||
initFilterCategoryIds: route.query['filterCategoryIds'],
|
||||
initTagIds: route.query['tagIds'],
|
||||
initTagFilterType: route.query['tagFilterType'],
|
||||
initKeyword: route.query['keyword'],
|
||||
initSortingType: route.query['sortingType'],
|
||||
initTrendDateAggregationType: route.query['trendDateAggregationType']
|
||||
})
|
||||
|
||||
@@ -124,6 +124,7 @@ export interface TransactionStatisticsPartialFilter {
|
||||
filterCategoryIds?: Record<string, boolean>;
|
||||
tagIds?: string;
|
||||
tagFilterType?: number;
|
||||
keyword?: string;
|
||||
sortingType?: number;
|
||||
}
|
||||
|
||||
@@ -141,6 +142,7 @@ export interface TransactionStatisticsFilter extends TransactionStatisticsPartia
|
||||
filterCategoryIds: Record<string, boolean>;
|
||||
tagIds: string;
|
||||
tagFilterType: number;
|
||||
keyword: string;
|
||||
sortingType: number;
|
||||
}
|
||||
|
||||
@@ -165,6 +167,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
filterCategoryIds: {},
|
||||
tagIds: '',
|
||||
tagFilterType: TransactionTagFilterType.Default.type,
|
||||
keyword: '',
|
||||
sortingType: ChartSortingType.Default.type
|
||||
});
|
||||
|
||||
@@ -693,6 +696,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
transactionStatisticsFilter.value.filterCategoryIds = {};
|
||||
transactionStatisticsFilter.value.tagIds = '';
|
||||
transactionStatisticsFilter.value.tagFilterType = TransactionTagFilterType.Default.type;
|
||||
transactionStatisticsFilter.value.keyword = '';
|
||||
transactionCategoryStatisticsData.value = null;
|
||||
transactionCategoryTrendsData.value = [];
|
||||
transactionStatisticsStateInvalid.value = true;
|
||||
@@ -825,6 +829,12 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
transactionStatisticsFilter.value.tagFilterType = TransactionTagFilterType.Default.type;
|
||||
}
|
||||
|
||||
if (filter && isString(filter.keyword)) {
|
||||
transactionStatisticsFilter.value.keyword = filter.keyword;
|
||||
} else {
|
||||
transactionStatisticsFilter.value.keyword = '';
|
||||
}
|
||||
|
||||
if (filter && isInteger(filter.sortingType)) {
|
||||
transactionStatisticsFilter.value.sortingType = filter.sortingType;
|
||||
} else {
|
||||
@@ -904,6 +914,11 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (filter && isString(filter.keyword) && transactionStatisticsFilter.value.keyword !== filter.keyword) {
|
||||
transactionStatisticsFilter.value.keyword = filter.keyword;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (filter && isInteger(filter.sortingType) && transactionStatisticsFilter.value.sortingType !== filter.sortingType) {
|
||||
transactionStatisticsFilter.value.sortingType = filter.sortingType;
|
||||
changed = true;
|
||||
@@ -964,6 +979,10 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
querys.push('tagFilterType=' + transactionStatisticsFilter.value.tagFilterType);
|
||||
}
|
||||
|
||||
if (transactionStatisticsFilter.value.keyword) {
|
||||
querys.push('keyword=' + encodeURIComponent(transactionStatisticsFilter.value.keyword));
|
||||
}
|
||||
|
||||
querys.push('sortingType=' + transactionStatisticsFilter.value.sortingType);
|
||||
|
||||
return querys.join('&');
|
||||
@@ -1020,6 +1039,10 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
querys.push('tagFilterType=' + transactionStatisticsFilter.value.tagFilterType);
|
||||
}
|
||||
|
||||
if (transactionStatisticsFilter.value.keyword) {
|
||||
querys.push('keyword=' + encodeURIComponent(transactionStatisticsFilter.value.keyword));
|
||||
}
|
||||
|
||||
if (analysisType === StatisticsAnalysisType.CategoricalAnalysis
|
||||
&& transactionStatisticsFilter.value.chartDataType !== ChartDataType.AccountTotalAssets.type
|
||||
&& transactionStatisticsFilter.value.chartDataType !== ChartDataType.AccountTotalLiabilities.type) {
|
||||
@@ -1045,6 +1068,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
endTime: transactionStatisticsFilter.value.categoricalChartEndTime,
|
||||
tagIds: transactionStatisticsFilter.value.tagIds,
|
||||
tagFilterType: transactionStatisticsFilter.value.tagFilterType,
|
||||
keyword: transactionStatisticsFilter.value.keyword,
|
||||
useTransactionTimezone: settingsStore.appSettings.statistics.defaultTimezoneType === TimezoneTypeForStatistics.TransactionTimezone.type
|
||||
}).then(response => {
|
||||
const data = response.data;
|
||||
@@ -1087,6 +1111,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
endYearMonth: transactionStatisticsFilter.value.trendChartEndYearMonth,
|
||||
tagIds: transactionStatisticsFilter.value.tagIds,
|
||||
tagFilterType: transactionStatisticsFilter.value.tagFilterType,
|
||||
keyword: transactionStatisticsFilter.value.keyword,
|
||||
useTransactionTimezone: settingsStore.appSettings.statistics.defaultTimezoneType === TimezoneTypeForStatistics.TransactionTimezone.type
|
||||
}).then(response => {
|
||||
const data = response.data;
|
||||
|
||||
@@ -113,6 +113,16 @@
|
||||
<v-tooltip activator="parent">{{ tt('Refresh') }}</v-tooltip>
|
||||
</v-btn>
|
||||
<v-spacer/>
|
||||
<div class="transaction-keyword-filter ml-2">
|
||||
<v-text-field density="compact" :disabled="loading"
|
||||
:prepend-inner-icon="mdiMagnify"
|
||||
:append-inner-icon="filterKeyword !== query.keyword ? mdiCheck : undefined"
|
||||
:placeholder="tt('Filter transaction description')"
|
||||
v-model="filterKeyword"
|
||||
@click:append-inner="setKeywordFilter(filterKeyword)"
|
||||
@keyup.enter="setKeywordFilter(filterKeyword)"
|
||||
/>
|
||||
</div>
|
||||
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
|
||||
:disabled="loading" :icon="true">
|
||||
<v-icon :icon="mdiDotsVertical" />
|
||||
@@ -383,6 +393,7 @@ import {
|
||||
mdiCalendarRangeOutline,
|
||||
mdiRefresh,
|
||||
mdiSquareRounded,
|
||||
mdiMagnify,
|
||||
mdiMenu,
|
||||
mdiFilterOutline,
|
||||
mdiFilterCogOutline,
|
||||
@@ -405,6 +416,7 @@ interface TransactionStatisticsProps {
|
||||
initFilterCategoryIds?: string,
|
||||
initTagIds?: string,
|
||||
initTagFilterType?: string,
|
||||
initKeyword?: string;
|
||||
initSortingType?: string,
|
||||
initTrendDateAggregationType?: string
|
||||
}
|
||||
@@ -454,6 +466,7 @@ const exportDialog = useTemplateRef<ExportDialogType>('exportDialog');
|
||||
|
||||
const activeTab = ref<string>('statisticsPage');
|
||||
const initing = ref<boolean>(true);
|
||||
const filterKeyword = ref<string>('');
|
||||
const alwaysShowNav = ref<boolean>(display.mdAndUp.value);
|
||||
const showNav = ref<boolean>(display.mdAndUp.value);
|
||||
const showCustomDateRangeDialog = ref<boolean>(false);
|
||||
@@ -551,9 +564,12 @@ function init(initProps: TransactionStatisticsProps): void {
|
||||
filterCategoryIds: initProps.initFilterCategoryIds ? arrayItemToObjectField(initProps.initFilterCategoryIds.split(','), true) : {},
|
||||
tagIds: initProps.initTagIds,
|
||||
tagFilterType: initProps.initTagFilterType && parseInt(initProps.initTagFilterType) >= 0 ? parseInt(initProps.initTagFilterType) : undefined,
|
||||
keyword: initProps.initKeyword,
|
||||
sortingType: initProps.initSortingType ? parseInt(initProps.initSortingType) : undefined
|
||||
};
|
||||
|
||||
filterKeyword.value = filter.keyword || '';
|
||||
|
||||
if (initProps.initAnalysisType === StatisticsAnalysisType.CategoricalAnalysis.toString()) {
|
||||
filter.categoricalChartType = initProps.initChartType ? parseInt(initProps.initChartType) : undefined;
|
||||
filter.categoricalChartDateType = initProps.initChartDateType ? parseInt(initProps.initChartDateType) : undefined;
|
||||
@@ -904,6 +920,30 @@ function setTagFilter(changed: boolean): void {
|
||||
}
|
||||
}
|
||||
|
||||
function setKeywordFilter(keyword: string): void {
|
||||
if (query.value.keyword === keyword) {
|
||||
return;
|
||||
}
|
||||
|
||||
let changed = false;
|
||||
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
keyword: keyword
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
keyword: keyword
|
||||
});
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
loading.value = true;
|
||||
statisticsStore.updateTransactionStatisticsInvalidState(true);
|
||||
router.push(getFilterLinkUrl());
|
||||
}
|
||||
}
|
||||
|
||||
function exportResults(): void {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis && categoricalAnalysisData.value && categoricalAnalysisData.value.items) {
|
||||
exportDialog.value?.open({
|
||||
@@ -954,6 +994,7 @@ onBeforeRouteUpdate((to) => {
|
||||
initFilterCategoryIds: (to.query['filterCategoryIds'] as string | null) || undefined,
|
||||
initTagIds: (to.query['tagIds'] as string | null) || undefined,
|
||||
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
|
||||
});
|
||||
|
||||
@@ -313,6 +313,10 @@
|
||||
<f7-actions-button @click="filterCategories">{{ tt('Filter Transaction Categories') }}</f7-actions-button>
|
||||
<f7-actions-button @click="filterTags">{{ tt('Filter Transaction Tags') }}</f7-actions-button>
|
||||
</f7-actions-group>
|
||||
<f7-actions-group>
|
||||
<f7-actions-label v-if="query.keyword">{{ query.keyword }}</f7-actions-label>
|
||||
<f7-actions-button @click="filterDescription">{{ tt('Filter transaction description') }}</f7-actions-button>
|
||||
</f7-actions-group>
|
||||
<f7-actions-group>
|
||||
<f7-actions-button @click="settings">{{ tt('Settings') }}</f7-actions-button>
|
||||
</f7-actions-group>
|
||||
@@ -360,7 +364,7 @@ const props = defineProps<{
|
||||
}>();
|
||||
|
||||
const { tt, getAllCategoricalChartTypes, formatPercent } = useI18n();
|
||||
const { showToast, routeBackOnError } = useI18nUIComponents();
|
||||
const { showPrompt, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const {
|
||||
loading,
|
||||
@@ -697,6 +701,30 @@ function filterTags(): void {
|
||||
props.f7router.navigate('/settings/filter/tag?type=statisticsCurrent');
|
||||
}
|
||||
|
||||
function filterDescription(): void {
|
||||
showPrompt('Filter transaction description', query.value.keyword, value => {
|
||||
if (query.value.keyword === value) {
|
||||
return;
|
||||
}
|
||||
|
||||
let changed = false;
|
||||
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
keyword: value
|
||||
});
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
keyword: value
|
||||
});
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function settings(): void {
|
||||
props.f7router.navigate('/statistic/settings');
|
||||
}
|
||||
|
||||
@@ -941,7 +941,8 @@ function init(): void {
|
||||
categoryIds: initQuery['categoryIds'],
|
||||
accountIds: initQuery['accountIds'],
|
||||
tagIds: initQuery['tagIds'],
|
||||
tagFilterType: initQuery['tagFilterType'] && parseInt(initQuery['tagFilterType']) >= 0 ? parseInt(initQuery['tagFilterType']) : undefined
|
||||
tagFilterType: initQuery['tagFilterType'] && parseInt(initQuery['tagFilterType']) >= 0 ? parseInt(initQuery['tagFilterType']) : undefined,
|
||||
keyword: initQuery['keyword']
|
||||
});
|
||||
|
||||
reload();
|
||||
|
||||
Reference in New Issue
Block a user