display total transactions, total amount, average amount, median amount, minimum amount, and maximum amount in the Data Table tab of Insights Explorer page
This commit is contained in:
@@ -111,6 +111,15 @@ export interface CategoriedTransactionExplorerDataItem extends SeriesInfo {
|
|||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface InsightsExplorerTransactionStatisticData {
|
||||||
|
totalCount: number;
|
||||||
|
totalAmount: number;
|
||||||
|
averageAmount: number;
|
||||||
|
medianAmount: number;
|
||||||
|
minimumAmount: number;
|
||||||
|
maximumAmount: number;
|
||||||
|
}
|
||||||
|
|
||||||
export const useExplorersStore = defineStore('explorers', () => {
|
export const useExplorersStore = defineStore('explorers', () => {
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@@ -578,6 +587,53 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const filteredTransactionsInDataTableStatistic = computed<InsightsExplorerTransactionStatisticData>(() => {
|
||||||
|
const statisticData: InsightsExplorerTransactionStatisticData = {
|
||||||
|
totalCount: 0,
|
||||||
|
totalAmount: 0,
|
||||||
|
averageAmount: 0,
|
||||||
|
medianAmount: 0,
|
||||||
|
minimumAmount: Number.MAX_SAFE_INTEGER,
|
||||||
|
maximumAmount: Number.MIN_SAFE_INTEGER
|
||||||
|
};
|
||||||
|
|
||||||
|
const sourceAmounts: number[] = [];
|
||||||
|
|
||||||
|
for (const transaction of filteredTransactionsInDataTable.value) {
|
||||||
|
statisticData.totalCount++;
|
||||||
|
statisticData.totalAmount += transaction.sourceAmount;
|
||||||
|
|
||||||
|
if (transaction.sourceAmount >= 0 && transaction.sourceAmount < statisticData.minimumAmount) {
|
||||||
|
statisticData.minimumAmount = transaction.sourceAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transaction.sourceAmount > statisticData.maximumAmount) {
|
||||||
|
statisticData.maximumAmount = transaction.sourceAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceAmounts.push(transaction.sourceAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statisticData.totalCount > 0) {
|
||||||
|
statisticData.averageAmount = Math.trunc(statisticData.totalAmount / statisticData.totalCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceAmounts.length > 0) {
|
||||||
|
sourceAmounts.sort((a, b) => a - b);
|
||||||
|
statisticData.medianAmount = sourceAmounts[Math.floor(sourceAmounts.length / 2)] as number;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statisticData.minimumAmount === Number.MAX_SAFE_INTEGER) {
|
||||||
|
statisticData.minimumAmount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statisticData.maximumAmount === Number.MIN_SAFE_INTEGER) {
|
||||||
|
statisticData.maximumAmount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return statisticData;
|
||||||
|
});
|
||||||
|
|
||||||
const categoriedTransactions = computed<Record<string, CategoriedTransactions>>(() => {
|
const categoriedTransactions = computed<Record<string, CategoriedTransactions>>(() => {
|
||||||
if (!allTransactions.value || allTransactions.value.length < 1) {
|
if (!allTransactions.value || allTransactions.value.length < 1) {
|
||||||
return {};
|
return {};
|
||||||
@@ -1174,6 +1230,7 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
insightsExplorerListStateInvalid,
|
insightsExplorerListStateInvalid,
|
||||||
// computed
|
// computed
|
||||||
filteredTransactionsInDataTable,
|
filteredTransactionsInDataTable,
|
||||||
|
filteredTransactionsInDataTableStatistic,
|
||||||
categoriedTransactionExplorerData,
|
categoriedTransactionExplorerData,
|
||||||
// functions
|
// functions
|
||||||
updateTransactionExplorerInvalidState,
|
updateTransactionExplorerInvalidState,
|
||||||
|
|||||||
@@ -407,6 +407,16 @@ html[dir="rtl"] .v-img.img-with-direction > img {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-tooltip {
|
||||||
|
&.v-tooltip > .v-overlay__content {
|
||||||
|
background-color: initial;
|
||||||
|
|
||||||
|
.v-table {
|
||||||
|
box-shadow: 0 6px 16px 0 rgba(var(--v-shadow-key-umbra-color), var(--v-shadow-lg-opacity)), 0 0 transparent, 0 0 transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.v-snackbar {
|
.v-snackbar {
|
||||||
.v-snackbar__content {
|
.v-snackbar__content {
|
||||||
color: rgb(var(--v-tooltip-color));
|
color: rgb(var(--v-tooltip-color));
|
||||||
|
|||||||
@@ -25,6 +25,49 @@
|
|||||||
:items="allPageCounts"
|
:items="allPageCounts"
|
||||||
v-model="currentExplorer.countPerPage"
|
v-model="currentExplorer.countPerPage"
|
||||||
/>
|
/>
|
||||||
|
<v-spacer/>
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<span class="text-subtitle-1">{{ tt('Total Transactions') }}</span>
|
||||||
|
<span v-if="loading">
|
||||||
|
<v-skeleton-loader class="skeleton-no-margin ms-2" type="text" style="width: 50px" :loading="true"></v-skeleton-loader>
|
||||||
|
</span>
|
||||||
|
<span class="text-subtitle-1 ms-2" v-else-if="!loading">
|
||||||
|
{{ formatNumberToLocalizedNumerals(filteredTransactions.length) }}
|
||||||
|
</span>
|
||||||
|
<span class="text-subtitle-1 ms-3" v-if="loading || filteredTransactionsStatistic">{{ tt('Total Amount') }}</span>
|
||||||
|
<span v-if="loading">
|
||||||
|
<v-skeleton-loader class="skeleton-no-margin ms-2" type="text" style="width: 80px" :loading="true"></v-skeleton-loader>
|
||||||
|
</span>
|
||||||
|
<span class="text-subtitle-1 ms-2" v-else-if="!loading && filteredTransactionsStatistic">
|
||||||
|
{{ formatAmountToLocalizedNumeralsWithCurrency(filteredTransactionsStatistic.totalAmount) }}
|
||||||
|
</span>
|
||||||
|
<v-tooltip interactive class="table-tooltip" activator="parent" v-if="!loading && filteredTransactionsStatistic">
|
||||||
|
<v-table density="compact">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{{ tt('Total Amount') }}</td>
|
||||||
|
<td class="text-end">{{ formatAmountToLocalizedNumeralsWithCurrency(filteredTransactionsStatistic.totalAmount) }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ tt('Average Amount') }}</td>
|
||||||
|
<td class="text-end">{{ formatAmountToLocalizedNumeralsWithCurrency(filteredTransactionsStatistic.averageAmount) }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ tt('Median Amount') }}</td>
|
||||||
|
<td class="text-end">{{ formatAmountToLocalizedNumeralsWithCurrency(filteredTransactionsStatistic.medianAmount) }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ tt('Minimum Amount') }}</td>
|
||||||
|
<td class="text-end">{{ formatAmountToLocalizedNumeralsWithCurrency(filteredTransactionsStatistic.minimumAmount) }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ tt('Maximum Amount') }}</td>
|
||||||
|
<td class="text-end">{{ formatAmountToLocalizedNumeralsWithCurrency(filteredTransactionsStatistic.maximumAmount) }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</v-table>
|
||||||
|
</v-tooltip>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
@@ -126,7 +169,7 @@ import { useI18n } from '@/locales/helpers.ts';
|
|||||||
|
|
||||||
import { useSettingsStore } from '@/stores/setting.ts';
|
import { useSettingsStore } from '@/stores/setting.ts';
|
||||||
import { useUserStore } from '@/stores/user.ts';
|
import { useUserStore } from '@/stores/user.ts';
|
||||||
import { useExplorersStore } from '@/stores/explorer.ts';
|
import { type InsightsExplorerTransactionStatisticData, useExplorersStore } from '@/stores/explorer.ts';
|
||||||
|
|
||||||
import { type NameValue, type NameNumeralValue, itemAndIndex } from '@/core/base.ts';
|
import { type NameValue, type NameNumeralValue, itemAndIndex } from '@/core/base.ts';
|
||||||
import type { NumeralSystem } from '@/core/numeral.ts';
|
import type { NumeralSystem } from '@/core/numeral.ts';
|
||||||
@@ -166,7 +209,8 @@ const {
|
|||||||
formatDateTimeToLongDateTime,
|
formatDateTimeToLongDateTime,
|
||||||
formatDateTimeToGregorianDefaultDateTime,
|
formatDateTimeToGregorianDefaultDateTime,
|
||||||
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
||||||
formatAmountToLocalizedNumeralsWithCurrency
|
formatAmountToLocalizedNumeralsWithCurrency,
|
||||||
|
formatNumberToLocalizedNumerals
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
@@ -181,6 +225,7 @@ const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurre
|
|||||||
const currentExplorer = computed<InsightsExplorer>(() => explorersStore.currentInsightsExplorer);
|
const currentExplorer = computed<InsightsExplorer>(() => explorersStore.currentInsightsExplorer);
|
||||||
|
|
||||||
const filteredTransactions = computed<TransactionInsightDataItem[]>(() => explorersStore.filteredTransactionsInDataTable);
|
const filteredTransactions = computed<TransactionInsightDataItem[]>(() => explorersStore.filteredTransactionsInDataTable);
|
||||||
|
const filteredTransactionsStatistic = computed<InsightsExplorerTransactionStatisticData | undefined>(() => explorersStore.filteredTransactionsInDataTableStatistic);
|
||||||
|
|
||||||
const allDataTableQuerySources = computed<NameValue[]>(() => {
|
const allDataTableQuerySources = computed<NameValue[]>(() => {
|
||||||
const sources: NameValue[] = [];
|
const sources: NameValue[] = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user