support opening transaction view dialog in insights explorer page

This commit is contained in:
MaysWind
2026-01-04 01:22:23 +08:00
parent 6634d5b791
commit 2fb509beb2
3 changed files with 57 additions and 7 deletions
+14
View File
@@ -7,6 +7,7 @@ import { useAccountsStore } from './account.ts';
import { useTransactionCategoriesStore } from './transactionCategory.ts'; import { useTransactionCategoriesStore } from './transactionCategory.ts';
import { useOverviewStore } from './overview.ts'; import { useOverviewStore } from './overview.ts';
import { useStatisticsStore } from './statistics.ts'; import { useStatisticsStore } from './statistics.ts';
import { useExplorersStore } from '@/stores/explorer.ts';
import { useExchangeRatesStore } from './exchangeRates.ts'; import { useExchangeRatesStore } from './exchangeRates.ts';
import { type BeforeResolveFunction, itemAndIndex, entries, keys } from '@/core/base.ts'; import { type BeforeResolveFunction, itemAndIndex, entries, keys } from '@/core/base.ts';
@@ -108,6 +109,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
const transactionCategoriesStore = useTransactionCategoriesStore(); const transactionCategoriesStore = useTransactionCategoriesStore();
const overviewStore = useOverviewStore(); const overviewStore = useOverviewStore();
const statisticsStore = useStatisticsStore(); const statisticsStore = useStatisticsStore();
const explorersStore = useExplorersStore();
const exchangeRatesStore = useExchangeRatesStore(); const exchangeRatesStore = useExchangeRatesStore();
const transactionDraft = ref<TransactionDraft | null>(getUserTransactionDraft()); const transactionDraft = ref<TransactionDraft | null>(getUserTransactionDraft());
@@ -1078,6 +1080,10 @@ export const useTransactionsStore = defineStore('transactions', () => {
statisticsStore.updateTransactionStatisticsInvalidState(true); statisticsStore.updateTransactionStatisticsInvalidState(true);
} }
if (!explorersStore.transactionExplorerStateInvalid) {
explorersStore.updateTransactionExplorerInvalidState(true);
}
resolve(transaction); resolve(transaction);
}).catch(error => { }).catch(error => {
logger.error('failed to save transaction', error); logger.error('failed to save transaction', error);
@@ -1127,6 +1133,10 @@ export const useTransactionsStore = defineStore('transactions', () => {
statisticsStore.updateTransactionStatisticsInvalidState(true); statisticsStore.updateTransactionStatisticsInvalidState(true);
} }
if (!explorersStore.transactionExplorerStateInvalid) {
explorersStore.updateTransactionExplorerInvalidState(true);
}
resolve(data.result); resolve(data.result);
}).catch(error => { }).catch(error => {
logger.error('failed to move transactions', error); logger.error('failed to move transactions', error);
@@ -1184,6 +1194,10 @@ export const useTransactionsStore = defineStore('transactions', () => {
statisticsStore.updateTransactionStatisticsInvalidState(true); statisticsStore.updateTransactionStatisticsInvalidState(true);
} }
if (!explorersStore.transactionExplorerStateInvalid) {
explorersStore.updateTransactionExplorerInvalidState(true);
}
resolve(data.result); resolve(data.result);
}).catch(error => { }).catch(error => {
logger.error('failed to delete transaction', error); logger.error('failed to delete transaction', error);
+27 -3
View File
@@ -108,8 +108,9 @@
</v-window-item> </v-window-item>
<v-window-item value="table"> <v-window-item value="table">
<explorer-data-table-tab ref="explorerDataTableTab" <explorer-data-table-tab ref="explorerDataTableTab"
:loading="loading" :loading="loading"
v-model:count-per-page="countPerPage" /> v-model:count-per-page="countPerPage"
@click:transaction="onShowTransaction" />
</v-window-item> </v-window-item>
<v-window-item value="chart"> <v-window-item value="chart">
<explorer-chart-tab ref="explorerChartTab" <explorer-chart-tab ref="explorerChartTab"
@@ -130,6 +131,7 @@
@dateRange:change="setCustomDateFilter" @dateRange:change="setCustomDateFilter"
@error="onShowDateRangeError" /> @error="onShowDateRangeError" />
<edit-dialog ref="editDialog" :type="TransactionEditPageType.Transaction" />
<export-dialog ref="exportDialog" /> <export-dialog ref="exportDialog" />
<snack-bar ref="snackbar" /> <snack-bar ref="snackbar" />
@@ -139,6 +141,7 @@
import ExplorerQueryTab from '@/views/desktop/insights/tabs/ExplorerQueryTab.vue'; import ExplorerQueryTab from '@/views/desktop/insights/tabs/ExplorerQueryTab.vue';
import ExplorerDataTableTab from '@/views/desktop/insights/tabs/ExplorerDataTableTab.vue'; import ExplorerDataTableTab from '@/views/desktop/insights/tabs/ExplorerDataTableTab.vue';
import ExplorerChartTab from '@/views/desktop/insights/tabs/ExplorerChartTab.vue'; import ExplorerChartTab from '@/views/desktop/insights/tabs/ExplorerChartTab.vue';
import EditDialog from '@/views/desktop/transactions/list/dialogs/EditDialog.vue';
import ExportDialog from '@/views/desktop/statistics/transaction/dialogs/ExportDialog.vue'; import ExportDialog from '@/views/desktop/statistics/transaction/dialogs/ExportDialog.vue';
import SnackBar from '@/components/desktop/SnackBar.vue'; import SnackBar from '@/components/desktop/SnackBar.vue';
@@ -147,6 +150,7 @@ import { useRouter, onBeforeRouteUpdate } from 'vue-router';
import { useDisplay } from 'vuetify'; import { useDisplay } from 'vuetify';
import { useI18n } from '@/locales/helpers.ts'; import { useI18n } from '@/locales/helpers.ts';
import { TransactionEditPageType } from '@/views/base/transactions/TransactionEditPageBase.ts';
import { useUserStore } from '@/stores/user.ts'; import { useUserStore } from '@/stores/user.ts';
import { useAccountsStore } from '@/stores/account.ts'; import { useAccountsStore } from '@/stores/account.ts';
@@ -160,7 +164,8 @@ import { type WeekDayValue, type LocalizedDateRange, DateRangeScene, DateRange }
import { TimezoneTypeForStatistics } from '@/core/timezone.ts'; import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
import { import {
type TransactionInsightDataItem type TransactionInsightDataItem,
Transaction
} from '@/models/transaction.ts'; } from '@/models/transaction.ts';
import { import {
@@ -196,6 +201,7 @@ type ExplorerPageTabType = 'query' | 'table' | 'chart';
type SnackBarType = InstanceType<typeof SnackBar>; type SnackBarType = InstanceType<typeof SnackBar>;
type ExplorerDataTableTabType = InstanceType<typeof ExplorerDataTableTab>; type ExplorerDataTableTabType = InstanceType<typeof ExplorerDataTableTab>;
type ExplorerChartTabType = InstanceType<typeof ExplorerChartTab>; type ExplorerChartTabType = InstanceType<typeof ExplorerChartTab>;
type EditDialogType = InstanceType<typeof EditDialog>;
type ExportDialogType = InstanceType<typeof ExportDialog>; type ExportDialogType = InstanceType<typeof ExportDialog>;
const router = useRouter(); const router = useRouter();
@@ -225,6 +231,7 @@ const snackbar = useTemplateRef<SnackBarType>('snackbar');
const explorerDataTableTab = useTemplateRef<ExplorerDataTableTabType>('explorerDataTableTab'); const explorerDataTableTab = useTemplateRef<ExplorerDataTableTabType>('explorerDataTableTab');
const explorerChartTab = useTemplateRef<ExplorerChartTabType>('explorerChartTab'); const explorerChartTab = useTemplateRef<ExplorerChartTabType>('explorerChartTab');
const exportDialog = useTemplateRef<ExportDialogType>('exportDialog'); const exportDialog = useTemplateRef<ExportDialogType>('exportDialog');
const editDialog = useTemplateRef<EditDialogType>('editDialog');
const loading = ref<boolean>(true); const loading = ref<boolean>(true);
const initing = ref<boolean>(true); const initing = ref<boolean>(true);
@@ -448,6 +455,23 @@ function shiftDateRange(scale: number): void {
} }
} }
function onShowTransaction(transaction: TransactionInsightDataItem): void {
editDialog.value?.open({
id: transaction.id,
currentTransaction: Transaction.of(transaction)
}).then(result => {
if (result && result.message) {
snackbar.value?.showMessage(result.message);
}
reload(false);
}).catch(error => {
if (error) {
snackbar.value?.showError(error);
}
});
}
function onShowDateRangeError(message: string): void { function onShowDateRangeError(message: string): void {
snackbar.value?.showError(message); snackbar.value?.showError(message);
} }
@@ -60,6 +60,12 @@
v-if="!item.tagIds || !item.tagIds.length"/> v-if="!item.tagIds || !item.tagIds.length"/>
</div> </div>
</template> </template>
<template #item.operation="{ item }">
<v-btn density="compact" variant="text" color="default" :disabled="loading"
@click="showTransaction(item)">
{{ tt('View') }}
</v-btn>
</template>
<template #no-data> <template #no-data>
<div v-if="loading && (!filteredTransactions || filteredTransactions.length < 1)"> <div v-if="loading && (!filteredTransactions || filteredTransactions.length < 1)">
<div class="ms-1" style="padding-top: 3px; padding-bottom: 3px" :key="itemIdx" v-for="itemIdx in skeletonData"> <div class="ms-1" style="padding-top: 3px; padding-bottom: 3px" :key="itemIdx" v-for="itemIdx in skeletonData">
@@ -120,6 +126,7 @@ interface InsightsExplorerDataTableTabProps {
const props = defineProps<InsightsExplorerDataTableTabProps>(); const props = defineProps<InsightsExplorerDataTableTabProps>();
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'click:transaction', value: TransactionInsightDataItem): void;
(e: 'update:countPerPage', value: number): void; (e: 'update:countPerPage', value: number): void;
}>(); }>();
@@ -181,6 +188,7 @@ const dataTableHeaders = computed<object[]>(() => {
} }
headers.push({ key: 'comment', value: 'comment', title: tt('Description'), sortable: true, nowrap: true }); headers.push({ key: 'comment', value: 'comment', title: tt('Description'), sortable: true, nowrap: true });
headers.push({ key: 'operation', title: tt('Operation'), sortable: false, nowrap: true, align: 'center' });
return headers; return headers;
}); });
@@ -252,6 +260,10 @@ function getDisplayDestinationAmount(transaction: TransactionInsightDataItem): s
return formatAmountToLocalizedNumeralsWithCurrency(transaction.destinationAmount, currency); return formatAmountToLocalizedNumeralsWithCurrency(transaction.destinationAmount, currency);
} }
function showTransaction(transaction: TransactionInsightDataItem): void {
emit('click:transaction', transaction);
}
function buildExportResults(): { headers: string[], data: string[][] } | undefined { function buildExportResults(): { headers: string[], data: string[][] } | undefined {
if (!filteredTransactions.value) { if (!filteredTransactions.value) {
return undefined; return undefined;
@@ -324,14 +336,14 @@ defineExpose({
<style> <style>
.v-table.insights-explorer-table > .v-table__wrapper > table { .v-table.insights-explorer-table > .v-table__wrapper > table {
th:not(:last-child), th:not(:nth-last-child(2)),
td:not(:last-child) { td:not(:nth-last-child(2)) {
width: auto !important; width: auto !important;
white-space: nowrap; white-space: nowrap;
} }
th:last-child, th:nth-last-child(2),
td:last-child { td:nth-last-child(2) {
width: 100% !important; width: 100% !important;
} }
} }