export transaction data based on the conditions on the transaction list page (#55)

This commit is contained in:
MaysWind
2025-06-30 23:49:01 +08:00
parent 53aa4ff390
commit 2e1a9362fc
20 changed files with 236 additions and 11 deletions
+46 -1
View File
@@ -197,6 +197,14 @@ func (a *DataManagementsApi) getExportedFileContent(c *core.WebContext, fileType
return nil, "", errs.ErrDataExportNotAllowed
}
var exportTransactionDataReq models.ExportTransactionDataRequest
err := c.ShouldBindQuery(&exportTransactionDataReq)
if err != nil {
log.Warnf(c, "[data_managements.ExportDataHandler] parse request failed, because %s", err.Error())
return nil, "", errs.NewIncompleteOrIncorrectSubmissionError(err)
}
timezone := time.Local
utcOffset, err := c.GetClientTimezoneOffset()
@@ -253,7 +261,44 @@ func (a *DataManagementsApi) getExportedFileContent(c *core.WebContext, fileType
categoryMap := a.categories.GetCategoryMapByList(categories)
tagMap := a.tags.GetTagMapByList(tags)
allTransactions, err := a.transactions.GetAllTransactions(c, uid, pageCountForDataExport, true)
allAccountIds, err := a.accounts.GetAccountOrSubAccountIds(c, exportTransactionDataReq.AccountIds, uid)
if err != nil {
log.Warnf(c, "[data_managements.ExportDataHandler] get account error, because %s", err.Error())
return nil, "", errs.Or(err, errs.ErrOperationFailed)
}
allCategoryIds, err := a.categories.GetCategoryOrSubCategoryIds(c, exportTransactionDataReq.CategoryIds, uid)
if err != nil {
log.Warnf(c, "[data_managements.ExportDataHandler] get transaction category error, because %s", err.Error())
return nil, "", errs.Or(err, errs.ErrOperationFailed)
}
var allTagIds []int64
noTags := exportTransactionDataReq.TagIds == "none"
if !noTags {
allTagIds, err = a.tags.GetTagIds(exportTransactionDataReq.TagIds)
if err != nil {
log.Warnf(c, "[data_managements.ExportDataHandler] get transaction tag ids error, because %s", err.Error())
return nil, "", errs.Or(err, errs.ErrOperationFailed)
}
}
maxTransactionTime := utils.GetMaxTransactionTimeFromUnixTime(time.Now().Unix())
minTransactionTime := int64(0)
if exportTransactionDataReq.MaxTime > 0 {
maxTransactionTime = utils.GetMaxTransactionTimeFromUnixTime(exportTransactionDataReq.MaxTime)
}
if exportTransactionDataReq.MinTime > 0 {
minTransactionTime = utils.GetMinTransactionTimeFromUnixTime(exportTransactionDataReq.MinTime)
}
allTransactions, err := a.transactions.GetAllSpecifiedTransactions(c, uid, maxTransactionTime, minTransactionTime, exportTransactionDataReq.Type, allCategoryIds, allAccountIds, allTagIds, noTags, exportTransactionDataReq.TagFilterType, exportTransactionDataReq.AmountFilter, exportTransactionDataReq.Keyword, pageCountForDataExport, true)
if err != nil {
log.Errorf(c, "[data_managements.ExportDataHandler] failed to all transactions user \"uid:%d\", because %s", uid, err.Error())
+13
View File
@@ -15,3 +15,16 @@ type DataStatisticsResponse struct {
TotalTransactionTemplateCount int64 `json:"totalTransactionTemplateCount,string"`
TotalScheduledTransactionCount int64 `json:"totalScheduledTransactionCount,string"`
}
// ExportTransactionDataRequest represents export transaction request
type ExportTransactionDataRequest struct {
Type TransactionType `form:"type" binding:"min=0,max=4"`
CategoryIds string `form:"category_ids"`
AccountIds string `form:"account_ids"`
TagIds string `form:"tag_ids"`
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
MaxTime int64 `form:"max_time" binding:"min=0"` // Unix timestamp in seconds
MinTime int64 `form:"min_time" binding:"min=0"` // Unix timestamp in seconds
}
+4 -4
View File
@@ -178,8 +178,8 @@ type TransactionCountRequest struct {
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
MaxTime int64 `form:"max_time" binding:"min=0"`
MinTime int64 `form:"min_time" binding:"min=0"`
MaxTime int64 `form:"max_time" binding:"min=0"` // Transaction time sequence id
MinTime int64 `form:"min_time" binding:"min=0"` // Transaction time sequence id
}
// TransactionListByMaxTimeRequest represents all parameters of transaction listing by max time request
@@ -191,8 +191,8 @@ type TransactionListByMaxTimeRequest struct {
TagFilterType TransactionTagFilterType `form:"tag_filter_type" binding:"min=0,max=3"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
MaxTime int64 `form:"max_time" binding:"min=0"`
MinTime int64 `form:"min_time" binding:"min=0"`
MaxTime int64 `form:"max_time" binding:"min=0"` // Transaction time sequence id
MinTime int64 `form:"min_time" binding:"min=0"` // Transaction time sequence id
Page int32 `form:"page" binding:"min=0"`
Count int32 `form:"count" binding:"required,min=1,max=50"`
WithCount bool `form:"with_count"`
+28
View File
@@ -79,6 +79,34 @@ func (s *TransactionService) GetAllTransactionsByMaxTime(c core.Context, uid int
return s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, nil, nil, false, models.TRANSACTION_TAG_FILTER_HAS_ANY, "", "", 1, count, false, noDuplicated)
}
// GetAllSpecifiedTransactions returns all transactions that match given conditions
func (s *TransactionService) GetAllSpecifiedTransactions(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, amountFilter string, keyword string, pageCount int32, noDuplicated bool) ([]*models.Transaction, error) {
if maxTransactionTime <= 0 {
maxTransactionTime = utils.GetMaxTransactionTimeFromUnixTime(time.Now().Unix())
}
var allTransactions []*models.Transaction
for maxTransactionTime > 0 {
transactions, err := s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountIds, tagIds, noTags, tagFilterType, amountFilter, keyword, 1, pageCount, false, noDuplicated)
if err != nil {
return nil, err
}
allTransactions = append(allTransactions, transactions...)
if len(transactions) < int(pageCount) {
maxTransactionTime = 0
break
}
maxTransactionTime = transactions[len(transactions)-1].TransactionTime - 1
}
return allTransactions, nil
}
// GetTransactionsByMaxTime returns transactions before given time
func (s *TransactionService) GetTransactionsByMaxTime(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagIds []int64, noTags bool, tagFilterType models.TransactionTagFilterType, amountFilter string, keyword string, page int32, count int32, needOneMoreItem bool, noDuplicated bool) ([]*models.Transaction, error) {
if uid <= 0 {
+14 -3
View File
@@ -39,6 +39,7 @@ import type {
RegisterResponse
} from '@/models/auth_response.ts';
import type {
ExportTransactionDataRequest,
ClearDataRequest,
DataStatisticsResponse
} from '@/models/data_management.ts';
@@ -344,13 +345,23 @@ export default {
getUserDataStatistics: (): ApiResponsePromise<DataStatisticsResponse> => {
return axios.get<ApiResponse<DataStatisticsResponse>>('v1/data/statistics.json');
},
getExportedUserData: (fileType: string): Promise<AxiosResponse<BlobPart>> => {
getExportedUserData: (fileType: string, req?: ExportTransactionDataRequest): Promise<AxiosResponse<BlobPart>> => {
let params = '';
if (req) {
const amountFilter = encodeURIComponent(req.amountFilter);
const keyword = encodeURIComponent(req.keyword);
params = `max_time=${req.maxTime}&min_time=${req.minTime}&type=${req.type}&category_ids=${req.categoryIds}&account_ids=${req.accountIds}&tag_ids=${req.tagIds}&tag_filter_type=${req.tagFilterType}&amount_filter=${amountFilter}&keyword=${keyword}`;
} else {
params = 'max_time=0&min_time=0&type=0&category_ids=&account_ids=&tag_ids=&tag_filter_type=0&amount_filter=&keyword=';
}
if (fileType === 'csv') {
return axios.get<BlobPart>('v1/data/export.csv', {
return axios.get<BlobPart>('v1/data/export.csv?' + params, {
timeout: DEFAULT_EXPORT_API_TIMEOUT
} as ApiRequestConfig);
} else if (fileType === 'tsv') {
return axios.get<BlobPart>('v1/data/export.tsv', {
return axios.get<BlobPart>('v1/data/export.tsv?' + params, {
timeout: DEFAULT_EXPORT_API_TIMEOUT
} as ApiRequestConfig);
} else {
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "Einreichen",
"Add": "Hinzufügen",
"Import": "Importieren",
"Export": "Export",
"Apply": "Anwenden",
"Save": "Speichern",
"Save Changes": "Änderungen speichern",
@@ -1941,6 +1942,8 @@
"File Format": "File Format",
"CSV (Comma-separated values) File": "CSV (Kommagetrennte Werte) Datei",
"TSV (Tab-separated values) File": "TSV (Tabulatorgetrennte Werte) Datei",
"Export to CSV (Comma-separated values) File": "Export to CSV (Comma-separated values) File",
"Export to TSV (Tab-separated values) File": "Export to TSV (Tab-separated values) File",
"Markdown File": "Markdown File",
"Clear User Data": "Benutzerdaten löschen",
"Export all transaction data to file.": "Alle Transaktionsdaten in Datei exportieren.",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "Submit",
"Add": "Add",
"Import": "Import",
"Export": "Export",
"Apply": "Apply",
"Save": "Save",
"Save Changes": "Save Changes",
@@ -1941,6 +1942,8 @@
"File Format": "File Format",
"CSV (Comma-separated values) File": "CSV (Comma-separated values) File",
"TSV (Tab-separated values) File": "TSV (Tab-separated values) File",
"Export to CSV (Comma-separated values) File": "Export to CSV (Comma-separated values) File",
"Export to TSV (Tab-separated values) File": "Export to TSV (Tab-separated values) File",
"Markdown File": "Markdown File",
"Clear User Data": "Clear User Data",
"Export all transaction data to file.": "Export all transaction data to file.",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "Enviar",
"Add": "Agregar",
"Import": "Importar",
"Export": "Export",
"Apply": "Aplicar",
"Save": "Guardar",
"Save Changes": "Guardar cambios",
@@ -1941,6 +1942,8 @@
"File Format": "File Format",
"CSV (Comma-separated values) File": "Archivo CSV (valores separados por comas)",
"TSV (Tab-separated values) File": "Archivo TSV (valores separados por tabulaciones)",
"Export to CSV (Comma-separated values) File": "Export to CSV (Comma-separated values) File",
"Export to TSV (Tab-separated values) File": "Export to TSV (Tab-separated values) File",
"Markdown File": "Markdown File",
"Clear User Data": "Borrar datos de usuario",
"Export all transaction data to file.": "Exportar todos los datos de la transacción a un archivo.",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "Invia",
"Add": "Aggiungi",
"Import": "Importa",
"Export": "Export",
"Apply": "Applica",
"Save": "Salva",
"Save Changes": "Salva modifiche",
@@ -1941,6 +1942,8 @@
"File Format": "File Format",
"CSV (Comma-separated values) File": "File CSV (valori separati da virgola)",
"TSV (Tab-separated values) File": "File TSV (valori separati da tabulazione)",
"Export to CSV (Comma-separated values) File": "Export to CSV (Comma-separated values) File",
"Export to TSV (Tab-separated values) File": "Export to TSV (Tab-separated values) File",
"Markdown File": "Markdown File",
"Clear User Data": "Cancella dati utente",
"Export all transaction data to file.": "Esporta tutti i dati delle transazioni in un file.",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "送信",
"Add": "追加",
"Import": "インポート",
"Export": "Export",
"Apply": "適用",
"Save": "保存",
"Save Changes": "変更を保存",
@@ -1941,6 +1942,8 @@
"File Format": "File Format",
"CSV (Comma-separated values) File": "CSV(コンマ区切り)ファイル",
"TSV (Tab-separated values) File": "TSV(タブ区切り)ファイル",
"Export to CSV (Comma-separated values) File": "Export to CSV (Comma-separated values) File",
"Export to TSV (Tab-separated values) File": "Export to TSV (Tab-separated values) File",
"Markdown File": "Markdown File",
"Clear User Data": "ユーザーデータをクリア",
"Export all transaction data to file.": "すべての取引データをファイルにエクスポートします。",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "Enviar",
"Add": "Adicionar",
"Import": "Importar",
"Export": "Export",
"Apply": "Aplicar",
"Save": "Salvar",
"Save Changes": "Salvar Alterações",
@@ -1941,6 +1942,8 @@
"File Format": "Formato de Arquivo",
"CSV (Comma-separated values) File": "Arquivo CSV (Valores separados por vírgulas)",
"TSV (Tab-separated values) File": "Arquivo TSV (Valores separados por tabulações)",
"Export to CSV (Comma-separated values) File": "Export to CSV (Comma-separated values) File",
"Export to TSV (Tab-separated values) File": "Export to TSV (Tab-separated values) File",
"Markdown File": "Arquivo Markdown",
"Clear User Data": "Limpar Dados do Usuário",
"Export all transaction data to file.": "Exportar todos os dados de transação para arquivo.",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "Отправить",
"Add": "Добавить",
"Import": "Импорт",
"Export": "Export",
"Apply": "Применить",
"Save": "Сохранить",
"Save Changes": "Сохранить изменения",
@@ -1941,6 +1942,8 @@
"File Format": "File Format",
"CSV (Comma-separated values) File": "Файл CSV (значения, разделенные запятыми)",
"TSV (Tab-separated values) File": "Файл TSV (значения, разделенные табуляцией)",
"Export to CSV (Comma-separated values) File": "Export to CSV (Comma-separated values) File",
"Export to TSV (Tab-separated values) File": "Export to TSV (Tab-separated values) File",
"Markdown File": "Markdown File",
"Clear User Data": "Очистить данные пользователя",
"Export all transaction data to file.": "Экспортировать все данные о транзакциях в файл.",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "Підтвердити",
"Add": "Додати",
"Import": "Імпортувати",
"Export": "Export",
"Apply": "Застосувати",
"Save": "Зберегти",
"Save Changes": "Зберегти зміни",
@@ -1941,6 +1942,8 @@
"File Format": "File Format",
"CSV (Comma-separated values) File": "Файл CSV (значення, розділені комами)",
"TSV (Tab-separated values) File": "Файл TSV (значення, розділені табуляцією)",
"Export to CSV (Comma-separated values) File": "Export to CSV (Comma-separated values) File",
"Export to TSV (Tab-separated values) File": "Export to TSV (Tab-separated values) File",
"Markdown File": "Markdown File",
"Clear User Data": "Очистити дані користувача",
"Export all transaction data to file.": "Експортувати всі транзакції у файл.",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "Gửi",
"Add": "Thêm",
"Import": "Nhập",
"Export": "Export",
"Apply": "Áp dụng",
"Save": "Lưu",
"Save Changes": "Lưu thay đổi",
@@ -1941,6 +1942,8 @@
"File Format": "File Format",
"CSV (Comma-separated values) File": "Tệp CSV (Giá trị phân cách bằng dấu phẩy)",
"TSV (Tab-separated values) File": "Tệp TSV (Giá trị phân cách bằng tab)",
"Export to CSV (Comma-separated values) File": "Export to CSV (Comma-separated values) File",
"Export to TSV (Tab-separated values) File": "Export to TSV (Tab-separated values) File",
"Markdown File": "Markdown File",
"Clear User Data": "Xóa dữ liệu người dùng",
"Export all transaction data to file.": "Xuất tất cả dữ liệu giao dịch sang tệp.",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "提交",
"Add": "添加",
"Import": "导入",
"Export": "导出",
"Apply": "应用",
"Save": "保存",
"Save Changes": "保存修改",
@@ -1941,6 +1942,8 @@
"File Format": "文件格式",
"CSV (Comma-separated values) File": "CSV (逗号分隔的值) 文件",
"TSV (Tab-separated values) File": "TSV (制表符分隔的值) 文件",
"Export to CSV (Comma-separated values) File": "导出到 CSV (逗号分隔的值) 文件",
"Export to TSV (Tab-separated values) File": "导出到 TSV (制表符分隔的值) 文件",
"Markdown File": "Markdown 文件",
"Clear User Data": "清除用户数据",
"Export all transaction data to file.": "导出所有交易数据到文件。",
+3
View File
@@ -1322,6 +1322,7 @@
"Submit": "提交",
"Add": "新增",
"Import": "匯入",
"Export": "匯出",
"Apply": "套用",
"Save": "儲存",
"Save Changes": "儲存修改",
@@ -1941,6 +1942,8 @@
"File Format": "檔案格式",
"CSV (Comma-separated values) File": "CSV (逗號分隔的值) 檔案",
"TSV (Tab-separated values) File": "TSV (定位點分隔的值) 檔案",
"Export to CSV (Comma-separated values) File": "匯出為 CSV (逗號分隔的值) 檔案",
"Export to TSV (Tab-separated values) File": "匯出為 TSV (定位點分隔的值) 檔案",
"Markdown File": "Markdown 檔案",
"Clear User Data": "清除使用者資料",
"Export all transaction data to file.": "匯出所有交易資料到檔案。",
+12
View File
@@ -1,3 +1,15 @@
export interface ExportTransactionDataRequest {
readonly maxTime: number;
readonly minTime: number;
readonly type: number;
readonly categoryIds: string;
readonly accountIds: string;
readonly tagIds: string;
readonly tagFilterType: number;
readonly amountFilter: string;
readonly keyword: string;
}
export interface ClearDataRequest {
readonly password: string;
}
+18
View File
@@ -29,6 +29,9 @@ import {
type ImportTransactionResponsePageWrapper,
ImportTransaction
} from '@/models/imported_transaction.ts';
import {
type ExportTransactionDataRequest
} from '@/models/data_management.ts';
import {
getUserTransactionDraft,
@@ -780,6 +783,20 @@ export const useTransactionsStore = defineStore('transactions', () => {
return querys.join('&');
}
function getExportTransactionDataRequestByTransactionFilter(): ExportTransactionDataRequest {
return {
maxTime: transactionsFilter.value.maxTime,
minTime: transactionsFilter.value.minTime,
type: transactionsFilter.value.type,
categoryIds: transactionsFilter.value.categoryIds,
accountIds: transactionsFilter.value.accountIds,
tagIds: transactionsFilter.value.tagIds,
tagFilterType: transactionsFilter.value.tagFilterType,
amountFilter: transactionsFilter.value.amountFilter,
keyword: transactionsFilter.value.keyword
};
}
function loadTransactions({ reload, count, page, withCount, autoExpand, defaultCurrency }: { reload?: boolean, count?: number, page?: number, withCount?: boolean, autoExpand: boolean, defaultCurrency: string }): Promise<TransactionPageWrapper> {
let actualMaxTime = transactionsNextTimeId.value;
@@ -1308,6 +1325,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
initTransactionListFilter,
updateTransactionListFilter,
getTransactionListPageParams,
getExportTransactionDataRequestByTransactionFilter,
loadTransactions,
loadMonthlyAllTransactions,
getTransaction,
+3 -2
View File
@@ -16,6 +16,7 @@ import {
} from '@/models/user.ts';
import type {
ExportTransactionDataRequest,
DataStatisticsResponse
} from '@/models/data_management.ts';
@@ -360,9 +361,9 @@ export const useUserStore = defineStore('user', () => {
});
}
function getExportedUserData(fileType: string): Promise<Blob> {
function getExportedUserData(fileType: string, req?: ExportTransactionDataRequest): Promise<Blob> {
return new Promise((resolve, reject) => {
services.getExportedUserData(fileType).then(response => {
services.getExportedUserData(fileType, req).then(response => {
if (response && response.headers) {
if (fileType === 'csv' && response.headers['content-type'] !== 'text/csv') {
reject({ message: 'Unable to retrieve exported user data' });
+65 -1
View File
@@ -74,6 +74,34 @@
:disabled="loading" @click="importTransaction"
v-if="isDataImportingEnabled()">
{{ tt('Import') }}
<v-menu activator="parent" :open-on-hover="true" v-if="isDataExportingEnabled()">
<v-list>
<v-list-item :disabled="loading || exportingData || !transactions || !transactions.length || transactions.length < 1"
@click="exportTransactions('csv')">
<v-list-item-title>{{ tt('Export to CSV (Comma-separated values) File') }}</v-list-item-title>
</v-list-item>
<v-list-item :disabled="loading || exportingData || !transactions || !transactions.length || transactions.length < 1"
@click="exportTransactions('tsv')">
<v-list-item-title>{{ tt('Export to TSV (Tab-separated values) File') }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
<v-btn class="ml-3" color="default" variant="outlined"
:disabled="loading || exportingData || !transactions || !transactions.length || transactions.length < 1" v-if="!isDataImportingEnabled() && isDataExportingEnabled()">
{{ tt('Export') }}
<v-menu activator="parent">
<v-list>
<v-list-item :disabled="loading || exportingData || !transactions || !transactions.length || transactions.length < 1"
@click="exportTransactions('csv')">
<v-list-item-title>{{ tt('Export to CSV (Comma-separated values) File') }}</v-list-item-title>
</v-list-item>
<v-list-item :disabled="loading || exportingData || !transactions || !transactions.length || transactions.length < 1"
@click="exportTransactions('tsv')">
<v-list-item-title>{{ tt('Export to TSV (Tab-separated values) File') }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
<v-btn density="compact" color="default" variant="text" size="24"
class="ml-2" :icon="true" :loading="loading" @click="reload(true, false)">
@@ -652,6 +680,7 @@ import { useI18n } from '@/locales/helpers.ts';
import { TransactionListPageType, useTransactionListPageBase } from '@/views/base/transactions/TransactionListPageBase.ts';
import { useSettingsStore } from '@/stores/setting.ts';
import { useUserStore } from '@/stores/user.ts';
import { useAccountsStore } from '@/stores/account.ts';
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
@@ -704,7 +733,8 @@ import {
categoryTypeToTransactionType,
transactionTypeToCategoryType
} from '@/lib/category.ts';
import { isDataImportingEnabled } from '@/lib/server_settings.ts';
import { isDataExportingEnabled, isDataImportingEnabled } from '@/lib/server_settings.ts';
import { startDownloadFile } from '@/lib/ui/common.ts';
import { scrollToSelectedItem } from '@/lib/ui/desktop.ts';
import logger from '@/lib/logger.ts';
@@ -823,6 +853,7 @@ const {
} = useTransactionListPageBase();
const settingsStore = useSettingsStore();
const userStore = useUserStore();
const accountsStore = useAccountsStore();
const transactionCategoriesStore = useTransactionCategoriesStore();
const transactionTagsStore = useTransactionTagsStore();
@@ -859,6 +890,7 @@ const currentAmountFilterValue2 = ref<number>(0);
const currentPageTransactions = ref<Transaction[]>([]);
const categoryMenuState = ref<boolean>(false);
const amountMenuState = ref<boolean>(false);
const exportingData = ref<boolean>(false);
const alwaysShowNav = ref<boolean>(display.mdAndUp.value);
const showNav = ref<boolean>(display.mdAndUp.value);
const showCustomDateRangeDialog = ref<boolean>(false);
@@ -1574,6 +1606,38 @@ function importTransaction(): void {
});
}
function exportTransactions(fileExtension: string): void {
if (exportingData.value) {
return;
}
const nickname = userStore.currentUserNickname;
let exportFileName = '';
if (nickname) {
exportFileName = tt('dataExport.exportFilename', {
nickname: nickname
}) + '.' + fileExtension;
} else {
exportFileName = tt('dataExport.defaultExportFilename') + '.' + fileExtension;
}
const exportTransactionReq = transactionsStore.getExportTransactionDataRequestByTransactionFilter();
exportingData.value = true;
userStore.getExportedUserData(fileExtension, exportTransactionReq).then(data => {
startDownloadFile(exportFileName, data);
exportingData.value = false;
}).catch(error => {
exportingData.value = false;
if (!error.processed) {
snackbar.value?.showError(error);
}
});
}
function show(transaction: Transaction): void {
if (transaction.type === TransactionType.ModifyBalance) {
return;