diff --git a/pkg/api/transactions.go b/pkg/api/transactions.go index d32e2afa..195db567 100644 --- a/pkg/api/transactions.go +++ b/pkg/api/transactions.go @@ -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()) diff --git a/pkg/models/transaction.go b/pkg/models/transaction.go index 9d925db3..b9189713 100644 --- a/pkg/models/transaction.go +++ b/pkg/models/transaction.go @@ -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"` } diff --git a/pkg/services/transactions.go b/pkg/services/transactions.go index 04a0ab22..d828da9b 100644 --- a/pkg/services/transactions.go +++ b/pkg/services/transactions.go @@ -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) diff --git a/src/lib/services.ts b/src/lib/services.ts index 132c582e..166a9741 100644 --- a/src/lib/services.ts +++ b/src/lib/services.ts @@ -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>(`v1/transactions/statistics.json?use_transaction_timezone=${req.useTransactionTimezone}` + (queryParams.length ? '&' + queryParams.join('&') : '')); }, getTransactionStatisticsTrends: (req: TransactionStatisticTrendsRequest): ApiResponsePromise => { @@ -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>(`v1/transactions/statistics/trends.json?use_transaction_timezone=${req.useTransactionTimezone}` + (queryParams.length ? '&' + queryParams.join('&') : '')); }, getTransactionAmounts: (params: TransactionAmountsRequestParams): ApiResponsePromise => { diff --git a/src/lib/ui/mobile.ts b/src/lib/ui/mobile.ts index 13b1c149..bcb7b707 100644 --- a/src/lib/ui/mobile.ts +++ b/src/lib/ui/mobile.ts @@ -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: `
`, + 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 } diff --git a/src/locales/de.json b/src/locales/de.json index 754d7277..9ad1933e 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -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", diff --git a/src/locales/en.json b/src/locales/en.json index 87836420..72942ef0 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -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", diff --git a/src/locales/es.json b/src/locales/es.json index 1f2511d7..7997efb1 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -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", diff --git a/src/locales/it.json b/src/locales/it.json index f66b2f3c..112c9402 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -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", diff --git a/src/locales/ja.json b/src/locales/ja.json index cc972138..bb2bde3e 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1851,6 +1851,7 @@ "Filter Accounts": "口座で絞り込み", "Filter Transaction Categories": "取引カテゴリで絞り込み", "Filter Transaction Tags": "取引タグで絞り込み", + "Filter transaction description": "Filter transaction description", "User Settings": "ユーザー設定", "User Profile": "ユーザープロフィール", "Language": "言語", diff --git a/src/locales/pt_BR.json b/src/locales/pt_BR.json index 6132e758..171049e9 100644 --- a/src/locales/pt_BR.json +++ b/src/locales/pt_BR.json @@ -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", diff --git a/src/locales/ru.json b/src/locales/ru.json index 701f5a3c..7d5beca7 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -1851,6 +1851,7 @@ "Filter Accounts": "Фильтровать счета", "Filter Transaction Categories": "Фильтровать категории транзакций", "Filter Transaction Tags": "Фильтровать теги транзакций", + "Filter transaction description": "Filter transaction description", "User Settings": "Настройки пользователя", "User Profile": "Профиль пользователя", "Language": "Язык", diff --git a/src/locales/uk.json b/src/locales/uk.json index 039ef2b7..acaa0714 100644 --- a/src/locales/uk.json +++ b/src/locales/uk.json @@ -1851,6 +1851,7 @@ "Filter Accounts": "Фільтрувати рахунки", "Filter Transaction Categories": "Фільтрувати категорії транзакцій", "Filter Transaction Tags": "Фільтрувати теги транзакцій", + "Filter transaction description": "Filter transaction description", "User Settings": "Налаштування користувача", "User Profile": "Профіль користувача", "Language": "Мова", diff --git a/src/locales/vi.json b/src/locales/vi.json index a530d629..0731e003 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -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ữ", diff --git a/src/locales/zh_Hans.json b/src/locales/zh_Hans.json index 2261873b..9d98e7ab 100644 --- a/src/locales/zh_Hans.json +++ b/src/locales/zh_Hans.json @@ -1851,6 +1851,7 @@ "Filter Accounts": "过滤账户", "Filter Transaction Categories": "过滤交易类型", "Filter Transaction Tags": "过滤交易标签", + "Filter transaction description": "过滤交易描述", "User Settings": "用户设置", "User Profile": "用户信息", "Language": "语言", diff --git a/src/locales/zh_Hant.json b/src/locales/zh_Hant.json index e7d1657b..5282727c 100644 --- a/src/locales/zh_Hant.json +++ b/src/locales/zh_Hant.json @@ -1851,6 +1851,7 @@ "Filter Accounts": "篩選帳戶", "Filter Transaction Categories": "篩選交易類型", "Filter Transaction Tags": "篩選交易標籤", + "Filter transaction description": "篩選交易描述", "User Settings": "使用者設定", "User Profile": "使用者資料", "Language": "語言", diff --git a/src/models/transaction.ts b/src/models/transaction.ts index 95c8a17d..1698f329 100644 --- a/src/models/transaction.ts +++ b/src/models/transaction.ts @@ -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; } diff --git a/src/router/desktop.ts b/src/router/desktop.ts index a2b65814..099b5005 100644 --- a/src/router/desktop.ts +++ b/src/router/desktop.ts @@ -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'] }) diff --git a/src/stores/statistics.ts b/src/stores/statistics.ts index 1cdc17ab..239f7a45 100644 --- a/src/stores/statistics.ts +++ b/src/stores/statistics.ts @@ -124,6 +124,7 @@ export interface TransactionStatisticsPartialFilter { filterCategoryIds?: Record; tagIds?: string; tagFilterType?: number; + keyword?: string; sortingType?: number; } @@ -141,6 +142,7 @@ export interface TransactionStatisticsFilter extends TransactionStatisticsPartia filterCategoryIds: Record; 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; diff --git a/src/views/desktop/statistics/TransactionPage.vue b/src/views/desktop/statistics/TransactionPage.vue index 6cd10930..d3cc5d42 100644 --- a/src/views/desktop/statistics/TransactionPage.vue +++ b/src/views/desktop/statistics/TransactionPage.vue @@ -113,6 +113,16 @@ {{ tt('Refresh') }} +
+ +
@@ -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('exportDialog'); const activeTab = ref('statisticsPage'); const initing = ref(true); +const filterKeyword = ref(''); const alwaysShowNav = ref(display.mdAndUp.value); const showNav = ref(display.mdAndUp.value); const showCustomDateRangeDialog = ref(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 }); diff --git a/src/views/mobile/statistics/TransactionPage.vue b/src/views/mobile/statistics/TransactionPage.vue index fa617880..581141a8 100644 --- a/src/views/mobile/statistics/TransactionPage.vue +++ b/src/views/mobile/statistics/TransactionPage.vue @@ -313,6 +313,10 @@ {{ tt('Filter Transaction Categories') }} {{ tt('Filter Transaction Tags') }} + + {{ query.keyword }} + {{ tt('Filter transaction description') }} + {{ tt('Settings') }} @@ -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'); } diff --git a/src/views/mobile/transactions/ListPage.vue b/src/views/mobile/transactions/ListPage.vue index 29357380..90ce8a9e 100644 --- a/src/views/mobile/transactions/ListPage.vue +++ b/src/views/mobile/transactions/ListPage.vue @@ -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();