move the "Timezone Used for Date Range" option from insights explorer settings into each exploration
This commit is contained in:
@@ -31,7 +31,6 @@ var ALL_ALLOWED_CLOUD_SYNC_APP_SETTING_KEY_TYPES = map[string]UserApplicationClo
|
||||
"alwaysShowTransactionPicturesInMobileTransactionEditPage": USER_APPLICATION_CLOUD_SETTING_TYPE_BOOLEAN,
|
||||
// Insights Explorer Page
|
||||
"insightsExplorerDefaultDateRangeType": USER_APPLICATION_CLOUD_SETTING_TYPE_NUMBER,
|
||||
"timezoneUsedForInsightsExplorerPage": USER_APPLICATION_CLOUD_SETTING_TYPE_NUMBER,
|
||||
// Account List Page
|
||||
"totalAmountExcludeAccountIds": USER_APPLICATION_CLOUD_SETTING_TYPE_STRING_BOOLEAN_MAP,
|
||||
// Exchange Rates Data Page
|
||||
|
||||
@@ -52,7 +52,6 @@ export interface ApplicationSettings extends BaseApplicationSetting {
|
||||
alwaysShowTransactionPicturesInMobileTransactionEditPage: boolean;
|
||||
// Insights Explorer Page
|
||||
insightsExplorerDefaultDateRangeType: number;
|
||||
timezoneUsedForInsightsExplorerPage: number;
|
||||
// Account List Page
|
||||
totalAmountExcludeAccountIds: Record<string, boolean>;
|
||||
// Exchange Rates Data Page
|
||||
@@ -117,7 +116,6 @@ export const ALL_ALLOWED_CLOUD_SYNC_APP_SETTING_KEY_TYPES: Record<string, UserAp
|
||||
'alwaysShowTransactionPicturesInMobileTransactionEditPage': UserApplicationCloudSettingType.Boolean,
|
||||
// Insights Explorer Page
|
||||
'insightsExplorerDefaultDateRangeType': UserApplicationCloudSettingType.Number,
|
||||
'timezoneUsedForInsightsExplorerPage': UserApplicationCloudSettingType.Number,
|
||||
// Account List Page
|
||||
'totalAmountExcludeAccountIds': UserApplicationCloudSettingType.StringBooleanMap,
|
||||
// Exchange Rates Data Page
|
||||
@@ -167,7 +165,6 @@ export const DEFAULT_APPLICATION_SETTINGS: ApplicationSettings = {
|
||||
alwaysShowTransactionPicturesInMobileTransactionEditPage: false,
|
||||
// Insights Explorer Page
|
||||
insightsExplorerDefaultDateRangeType: DEFAULT_TRANSACTION_EXPLORER_DATE_RANGE.type,
|
||||
timezoneUsedForInsightsExplorerPage: TimezoneTypeForStatistics.Default.type,
|
||||
// Account List Page
|
||||
totalAmountExcludeAccountIds: {},
|
||||
// Exchange Rates Data Page
|
||||
|
||||
+53
-38
@@ -44,17 +44,18 @@ import {
|
||||
import {
|
||||
parseDateTimeFromUnixTime,
|
||||
parseDateTimeFromUnixTimeWithTimezoneOffset,
|
||||
getYearFirstUnixTimeBySpecifiedUnixTime,
|
||||
getQuarterFirstUnixTimeBySpecifiedUnixTime,
|
||||
getMonthFirstUnixTimeBySpecifiedUnixTime,
|
||||
getDayFirstUnixTimeBySpecifiedUnixTime,
|
||||
getDateRangeByDateType,
|
||||
getFiscalYearStartUnixTime
|
||||
getFiscalYearFromUnixTime
|
||||
} from '@/lib/datetime.ts';
|
||||
import services from '@/lib/services.ts';
|
||||
import logger from '@/lib/logger.ts';
|
||||
|
||||
export enum TransactionExplorerDimensionType {
|
||||
DateTime = 'YYYY-MM-DD HH:mm:ss',
|
||||
YearMonthDay = 'YYYY-MM-DD',
|
||||
YearMonth = 'YYYY-MM',
|
||||
YearQuarter = 'YYYY-Q',
|
||||
Year = 'YYYY',
|
||||
TransactionType = 'transactionType',
|
||||
Category = 'category',
|
||||
Account = 'account',
|
||||
@@ -67,6 +68,7 @@ export interface TransactionExplorerPartialFilter {
|
||||
startTime?: number;
|
||||
endTime?: number;
|
||||
queryId?: string;
|
||||
timezoneUsedForDateRange?: number;
|
||||
chartType?: TransactionExplorerChartTypeValue;
|
||||
categoryDimension?: TransactionExplorerDataDimensionType;
|
||||
seriesDimension?: TransactionExplorerDataDimensionType;
|
||||
@@ -78,6 +80,7 @@ export interface TransactionExplorerFilter extends TransactionExplorerPartialFil
|
||||
startTime: number;
|
||||
endTime: number;
|
||||
query: TransactionExplorerQuery[];
|
||||
timezoneUsedForDateRange: number;
|
||||
chartType: TransactionExplorerChartTypeValue;
|
||||
categoryDimension: TransactionExplorerDataDimensionType;
|
||||
seriesDimension: TransactionExplorerDataDimensionType;
|
||||
@@ -124,10 +127,10 @@ export const useExplorersStore = defineStore('explorers', () => {
|
||||
const transactionTagsStore = useTransactionTagsStore();
|
||||
const exchangeRatesStore = useExchangeRatesStore();
|
||||
|
||||
function getDataCategoryInfo(dimension: TransactionExplorerDataDimension, queryName: string, queryIndex: number, transaction: TransactionInsightDataItem): CategoriedInfo {
|
||||
function getDataCategoryInfo(timezoneUsedForDateRange: number, dimension: TransactionExplorerDataDimension, queryName: string, queryIndex: number, transaction: TransactionInsightDataItem): CategoriedInfo {
|
||||
let transactionTimeUtfOffset: number | undefined = undefined;
|
||||
|
||||
if (settingsStore.appSettings.timezoneUsedForInsightsExplorerPage === TimezoneTypeForStatistics.TransactionTimezone.type) {
|
||||
if (timezoneUsedForDateRange === TimezoneTypeForStatistics.TransactionTimezone.type) {
|
||||
transactionTimeUtfOffset = transaction.utcOffset;
|
||||
}
|
||||
|
||||
@@ -158,52 +161,56 @@ export const useExplorersStore = defineStore('explorers', () => {
|
||||
};
|
||||
}
|
||||
} else if (dimension === TransactionExplorerDataDimension.DateTime) {
|
||||
const unixTime = transaction.time.toString(10);
|
||||
const dateTime = isDefined(transactionTimeUtfOffset) ? parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transactionTimeUtfOffset) : parseDateTimeFromUnixTime(transaction.time);
|
||||
const textualDateTime = `${dateTime.getGregorianCalendarYearDashMonthDashDay()} ${dateTime.getHour().toString(10).padStart(2, '0')}:${dateTime.getMinute().toString(10).padStart(2, '0')}:${dateTime.getSecond().toString(10).padStart(2, '0')}`;
|
||||
|
||||
return {
|
||||
categoryName: unixTime,
|
||||
categoryId: unixTime,
|
||||
categoryIdType: TransactionExplorerDimensionType.Other
|
||||
categoryName: textualDateTime,
|
||||
categoryId: textualDateTime,
|
||||
categoryIdType: TransactionExplorerDimensionType.DateTime
|
||||
};
|
||||
} else if (dimension === TransactionExplorerDataDimension.DateTimeByYearMonthDay) {
|
||||
const unixTime = getDayFirstUnixTimeBySpecifiedUnixTime(transaction.time, transactionTimeUtfOffset).toString(10);
|
||||
const dateTime = isDefined(transactionTimeUtfOffset) ? parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transactionTimeUtfOffset) : parseDateTimeFromUnixTime(transaction.time);
|
||||
const yearMonthDay = dateTime.getGregorianCalendarYearDashMonthDashDay();
|
||||
|
||||
return {
|
||||
categoryName: unixTime,
|
||||
categoryId: unixTime,
|
||||
categoryIdType: TransactionExplorerDimensionType.Other
|
||||
categoryName: yearMonthDay,
|
||||
categoryId: yearMonthDay,
|
||||
categoryIdType: TransactionExplorerDimensionType.YearMonthDay
|
||||
};
|
||||
} else if (dimension === TransactionExplorerDataDimension.DateTimeByYearMonth) {
|
||||
const unixTime = getMonthFirstUnixTimeBySpecifiedUnixTime(transaction.time, transactionTimeUtfOffset).toString(10);
|
||||
const dateTime = isDefined(transactionTimeUtfOffset) ? parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transactionTimeUtfOffset) : parseDateTimeFromUnixTime(transaction.time);
|
||||
const yearMonth = dateTime.getGregorianCalendarYearDashMonth();
|
||||
|
||||
return {
|
||||
categoryName: unixTime,
|
||||
categoryId: unixTime,
|
||||
categoryIdType: TransactionExplorerDimensionType.Other
|
||||
categoryName: yearMonth,
|
||||
categoryId: yearMonth,
|
||||
categoryIdType: TransactionExplorerDimensionType.YearMonth
|
||||
};
|
||||
} else if (dimension === TransactionExplorerDataDimension.DateTimeByYearQuarter) {
|
||||
const unixTime = getQuarterFirstUnixTimeBySpecifiedUnixTime(transaction.time, transactionTimeUtfOffset).toString(10);
|
||||
const dateTime = isDefined(transactionTimeUtfOffset) ? parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transactionTimeUtfOffset) : parseDateTimeFromUnixTime(transaction.time);
|
||||
const yearQuarter = `${dateTime.getGregorianCalendarYear().toString(10)}-${dateTime.getGregorianCalendarQuarter().toString(10)}`;
|
||||
|
||||
return {
|
||||
categoryName: unixTime,
|
||||
categoryId: unixTime,
|
||||
categoryIdType: TransactionExplorerDimensionType.Other
|
||||
categoryName: yearQuarter,
|
||||
categoryId: yearQuarter,
|
||||
categoryIdType: TransactionExplorerDimensionType.YearQuarter
|
||||
};
|
||||
} else if (dimension === TransactionExplorerDataDimension.DateTimeByYear) {
|
||||
const unixTime = getYearFirstUnixTimeBySpecifiedUnixTime(transaction.time, transactionTimeUtfOffset).toString(10);
|
||||
const dateTime = isDefined(transactionTimeUtfOffset) ? parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transactionTimeUtfOffset) : parseDateTimeFromUnixTime(transaction.time);
|
||||
|
||||
return {
|
||||
categoryName: unixTime,
|
||||
categoryId: unixTime,
|
||||
categoryIdType: TransactionExplorerDimensionType.Other
|
||||
categoryName: dateTime.getGregorianCalendarYear().toString(10),
|
||||
categoryId: dateTime.getGregorianCalendarYear().toString(10),
|
||||
categoryIdType: TransactionExplorerDimensionType.Year
|
||||
};
|
||||
} else if (dimension === TransactionExplorerDataDimension.DateTimeByFiscalYear) {
|
||||
const unixTime = getFiscalYearStartUnixTime(transaction.time, userStore.currentUserFiscalYearStart, transactionTimeUtfOffset).toString(10);
|
||||
const fiscalYear = getFiscalYearFromUnixTime(transaction.time, userStore.currentUserFiscalYearStart, transactionTimeUtfOffset).toString(10);
|
||||
|
||||
return {
|
||||
categoryName: unixTime,
|
||||
categoryId: unixTime,
|
||||
categoryIdType: TransactionExplorerDimensionType.Other
|
||||
categoryName: fiscalYear,
|
||||
categoryId: fiscalYear,
|
||||
categoryIdType: TransactionExplorerDimensionType.Year
|
||||
};
|
||||
} else if (dimension === TransactionExplorerDataDimension.DateTimeByDayOfWeek) {
|
||||
const dateTime = isDefined(transactionTimeUtfOffset) ? parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transactionTimeUtfOffset) : parseDateTimeFromUnixTime(transaction.time);
|
||||
@@ -336,8 +343,8 @@ export const useExplorersStore = defineStore('explorers', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function addTransactionToCategoriedDataMap(categoriedDataMap: Record<string, CategoriedTransactions>, categoryDimension: TransactionExplorerDataDimension, seriesDemension: TransactionExplorerDataDimension, queryName: string, queryIndex: number, transaction: TransactionInsightDataItem): void {
|
||||
const categoriedInfo = getDataCategoryInfo(categoryDimension, queryName, queryIndex, transaction);
|
||||
function addTransactionToCategoriedDataMap(timezoneUsedForDateRange: number, categoriedDataMap: Record<string, CategoriedTransactions>, categoryDimension: TransactionExplorerDataDimension, seriesDemension: TransactionExplorerDataDimension, queryName: string, queryIndex: number, transaction: TransactionInsightDataItem): void {
|
||||
const categoriedInfo = getDataCategoryInfo(timezoneUsedForDateRange, categoryDimension, queryName, queryIndex, transaction);
|
||||
let categoriedData = categoriedDataMap[categoriedInfo.categoryId];
|
||||
|
||||
if (!categoriedData) {
|
||||
@@ -352,7 +359,7 @@ export const useExplorersStore = defineStore('explorers', () => {
|
||||
categoriedDataMap[categoriedInfo.categoryId] = categoriedData;
|
||||
}
|
||||
|
||||
const seriesedInfo = getDataCategoryInfo(seriesDemension, queryName, queryIndex, transaction);
|
||||
const seriesedInfo = getDataCategoryInfo(timezoneUsedForDateRange, seriesDemension, queryName, queryIndex, transaction);
|
||||
let seriesedData = categoriedData.trasactions[seriesedInfo.categoryId];
|
||||
|
||||
if (!seriesedData) {
|
||||
@@ -375,10 +382,11 @@ export const useExplorersStore = defineStore('explorers', () => {
|
||||
startTime: 0,
|
||||
endTime: 0,
|
||||
query: [],
|
||||
timezoneUsedForDateRange: TimezoneTypeForStatistics.Default.type,
|
||||
chartType: TransactionExplorerChartType.Default.value,
|
||||
categoryDimension: TransactionExplorerDataDimension.CategoryDimensionDefault.value,
|
||||
seriesDimension: TransactionExplorerDataDimension.SeriesDimensionDefault.value,
|
||||
valueMetric: TransactionExplorerValueMetric.Default.value,
|
||||
chartType: TransactionExplorerChartType.Default.value
|
||||
valueMetric: TransactionExplorerValueMetric.Default.value
|
||||
});
|
||||
|
||||
const transactionExplorerAllData = ref<TransactionInfoResponse[]>([]);
|
||||
@@ -498,13 +506,13 @@ export const useExplorersStore = defineStore('explorers', () => {
|
||||
|
||||
for (const transaction of allTransactions.value) {
|
||||
if (!transactionExplorerFilter.value.query || transactionExplorerFilter.value.query.length < 1) {
|
||||
addTransactionToCategoriedDataMap(categoriedDataMap, categoryDimension, seriesDimension, '', 0, transaction);
|
||||
addTransactionToCategoriedDataMap(transactionExplorerFilter.value.timezoneUsedForDateRange, categoriedDataMap, categoryDimension, seriesDimension, '', 0, transaction);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const [query, index] of itemAndIndex(transactionExplorerFilter.value.query)) {
|
||||
if (query.match(transaction)) {
|
||||
addTransactionToCategoriedDataMap(categoriedDataMap, categoryDimension, seriesDimension, query.name, index, transaction);
|
||||
addTransactionToCategoriedDataMap(transactionExplorerFilter.value.timezoneUsedForDateRange, categoriedDataMap, categoryDimension, seriesDimension, query.name, index, transaction);
|
||||
|
||||
if (categoryDimension !== TransactionExplorerDataDimension.Query) {
|
||||
break;
|
||||
@@ -640,6 +648,7 @@ export const useExplorersStore = defineStore('explorers', () => {
|
||||
transactionExplorerFilter.value.startTime = 0;
|
||||
transactionExplorerFilter.value.endTime = 0;
|
||||
transactionExplorerFilter.value.query = [];
|
||||
transactionExplorerFilter.value.timezoneUsedForDateRange = TimezoneTypeForStatistics.Default.type;
|
||||
transactionExplorerFilter.value.chartType = TransactionExplorerChartType.Default.value;
|
||||
transactionExplorerFilter.value.categoryDimension = TransactionExplorerDataDimension.CategoryDimensionDefault.value;
|
||||
transactionExplorerFilter.value.seriesDimension = TransactionExplorerDataDimension.SeriesDimensionDefault.value;
|
||||
@@ -686,6 +695,7 @@ export const useExplorersStore = defineStore('explorers', () => {
|
||||
|
||||
if (resetQuery) {
|
||||
transactionExplorerFilter.value.query = [];
|
||||
transactionExplorerFilter.value.timezoneUsedForDateRange = TimezoneTypeForStatistics.Default.type;
|
||||
transactionExplorerFilter.value.chartType = TransactionExplorerChartType.Default.value;
|
||||
transactionExplorerFilter.value.categoryDimension = TransactionExplorerDataDimension.CategoryDimensionDefault.value;
|
||||
transactionExplorerFilter.value.seriesDimension = TransactionExplorerDataDimension.SeriesDimensionDefault.value;
|
||||
@@ -711,6 +721,11 @@ export const useExplorersStore = defineStore('explorers', () => {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (filter && isDefined(filter.timezoneUsedForDateRange) && transactionExplorerFilter.value.timezoneUsedForDateRange !== filter.timezoneUsedForDateRange) {
|
||||
transactionExplorerFilter.value.timezoneUsedForDateRange = filter.timezoneUsedForDateRange;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (filter && isDefined(filter.chartType) && transactionExplorerFilter.value.chartType !== filter.chartType) {
|
||||
transactionExplorerFilter.value.chartType = filter.chartType;
|
||||
changed = true;
|
||||
|
||||
@@ -252,12 +252,6 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
updateUserApplicationCloudSettingValue('insightsExplorerDefaultDateRangeType', value);
|
||||
}
|
||||
|
||||
function setTimezoneUsedForInsightsExplorerPage(value: number): void {
|
||||
updateApplicationSettingsValue('timezoneUsedForInsightsExplorerPage', value);
|
||||
appSettings.value.timezoneUsedForInsightsExplorerPage = value;
|
||||
updateUserApplicationCloudSettingValue('timezoneUsedForInsightsExplorerPage', value);
|
||||
}
|
||||
|
||||
// Account List Page
|
||||
function setTotalAmountExcludeAccountIds(value: Record<string, boolean>): void {
|
||||
updateApplicationSettingsValue('totalAmountExcludeAccountIds', value);
|
||||
@@ -482,7 +476,6 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
setAlwaysShowTransactionPicturesInMobileTransactionEditPage,
|
||||
// -- Insights Explorer Page
|
||||
setInsightsExplorerDefaultDateRangeType,
|
||||
setTimezoneUsedForInsightsExplorerPage,
|
||||
// -- Account List Page
|
||||
setTotalAmountExcludeAccountIds,
|
||||
// -- Exchange Rates Data Page
|
||||
|
||||
@@ -53,14 +53,13 @@ export const ALL_APPLICATION_CLOUD_SETTINGS: CategorizedApplicationCloudSettingI
|
||||
{
|
||||
categoryName: 'Insights Explorer Page',
|
||||
items: [
|
||||
{ settingKey: 'insightsExplorerDefaultDateRangeType', settingName: 'Default Date Range', mobile: false, desktop: true },
|
||||
{ settingKey: 'timezoneUsedForInsightsExplorerPage', settingName: 'Timezone Used for Date Range', mobile: false, desktop: true },
|
||||
{ settingKey: 'insightsExplorerDefaultDateRangeType', settingName: 'Default Date Range', mobile: false, desktop: true }
|
||||
]
|
||||
},
|
||||
{
|
||||
categoryName: 'Account List Page',
|
||||
items: [
|
||||
{ settingKey: 'totalAmountExcludeAccountIds', settingName: 'Accounts Included in Total', mobile: true, desktop: true },
|
||||
{ settingKey: 'totalAmountExcludeAccountIds', settingName: 'Accounts Included in Total', mobile: true, desktop: true }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -240,18 +240,6 @@
|
||||
v-model="insightsExplorerDefaultDateRangeType"
|
||||
/>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
item-title="displayName"
|
||||
item-value="type"
|
||||
persistent-placeholder
|
||||
:label="tt('Timezone Used for Date Range')"
|
||||
:placeholder="tt('Timezone Used for Date Range')"
|
||||
:items="allTimezoneTypesUsedForStatistics"
|
||||
v-model="timezoneUsedForInsightsExplorerPage"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-form>
|
||||
@@ -339,7 +327,6 @@ import { useAppSettingPageBase } from '@/views/base/settings/AppSettingsPageBase
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
import { useAccountsStore } from '@/stores/account.ts';
|
||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useExplorersStore } from '@/stores/explorer.ts';
|
||||
|
||||
import type { LocalizedSwitchOption } from '@/core/base.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
@@ -383,7 +370,6 @@ const {
|
||||
const settingsStore = useSettingsStore();
|
||||
const accountsStore = useAccountsStore();
|
||||
const transactionCategoriesStore = useTransactionCategoriesStore();
|
||||
const explorersStore = useExplorersStore();
|
||||
|
||||
const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
||||
|
||||
@@ -419,14 +405,6 @@ const insightsExplorerDefaultDateRangeType = computed<number>({
|
||||
set: (value) => settingsStore.setInsightsExplorerDefaultDateRangeType(value)
|
||||
});
|
||||
|
||||
const timezoneUsedForInsightsExplorerPage = computed<number>({
|
||||
get: () => settingsStore.appSettings.timezoneUsedForInsightsExplorerPage,
|
||||
set: (value: number) => {
|
||||
settingsStore.setTimezoneUsedForInsightsExplorerPage(value);
|
||||
explorersStore.updateTransactionExplorerInvalidState(true);
|
||||
}
|
||||
});
|
||||
|
||||
function init(): void {
|
||||
loadingAccounts.value = true;
|
||||
|
||||
|
||||
@@ -77,15 +77,25 @@
|
||||
</v-btn>
|
||||
<v-spacer/>
|
||||
<v-btn density="comfortable" color="default" variant="text" class="ms-2"
|
||||
:disabled="loading" :icon="true"
|
||||
v-if="activeTab === 'table' || activeTab === 'chart'">
|
||||
:disabled="loading" :icon="true">
|
||||
<v-icon :icon="mdiDotsVertical" />
|
||||
<v-menu activator="parent">
|
||||
<v-list>
|
||||
<v-list-subheader :title="tt('Timezone Used for Date Range')"
|
||||
v-if="activeTab === 'query'"/>
|
||||
<template v-if="activeTab === 'query'">
|
||||
<v-list-item :key="timezoneType.type" :value="timezoneType.type"
|
||||
:prepend-icon="timezoneTypeIconMap[timezoneType.type]"
|
||||
:append-icon="(query.timezoneUsedForDateRange === timezoneType.type ? mdiCheck : undefined)"
|
||||
:title="timezoneType.displayName"
|
||||
v-for="timezoneType in allTimezoneTypesUsedForDateRange"
|
||||
@click="updateTimezoneUsedForDateRange(timezoneType.type)"></v-list-item>
|
||||
</template>
|
||||
<v-list-item :prepend-icon="mdiExport"
|
||||
:title="tt('Export Results')"
|
||||
:disabled="loading || !filteredTransactions || filteredTransactions.length < 1"
|
||||
@click="exportResults"></v-list-item>
|
||||
@click="exportResults"
|
||||
v-if="activeTab === 'table' || activeTab === 'chart'"></v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-btn>
|
||||
@@ -144,9 +154,10 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { type TransactionExplorerPartialFilter, type TransactionExplorerFilter, useExplorersStore } from '@/stores/explorer.ts';
|
||||
|
||||
import type { NameNumeralValue } from '@/core/base.ts';
|
||||
import type { NameNumeralValue, TypeAndDisplayName } from '@/core/base.ts';
|
||||
import type { NumeralSystem } from '@/core/numeral.ts';
|
||||
import { type WeekDayValue, type LocalizedDateRange, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
||||
|
||||
import {
|
||||
type TransactionInsightDataItem
|
||||
@@ -166,6 +177,8 @@ import {
|
||||
mdiCheck,
|
||||
mdiRefresh,
|
||||
mdiDotsVertical,
|
||||
mdiHomeClockOutline,
|
||||
mdiInvoiceTextClockOutline,
|
||||
mdiExport
|
||||
} from '@mdi/js';
|
||||
|
||||
@@ -191,6 +204,7 @@ const display = useDisplay();
|
||||
const {
|
||||
tt,
|
||||
getAllDateRanges,
|
||||
getAllTimezoneTypesUsedForStatistics,
|
||||
getCurrentNumeralSystemType,
|
||||
formatDateTimeToLongDateTime,
|
||||
formatDateRange
|
||||
@@ -202,6 +216,11 @@ const transactionCategoriesStore = useTransactionCategoriesStore();
|
||||
const transactionTagsStore = useTransactionTagsStore();
|
||||
const explorersStore = useExplorersStore();
|
||||
|
||||
const timezoneTypeIconMap = {
|
||||
[TimezoneTypeForStatistics.ApplicationTimezone.type]: mdiHomeClockOutline,
|
||||
[TimezoneTypeForStatistics.TransactionTimezone.type]: mdiInvoiceTextClockOutline
|
||||
};
|
||||
|
||||
const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
||||
const explorerDataTableTab = useTemplateRef<ExplorerDataTableTabType>('explorerDataTableTab');
|
||||
const explorerChartTab = useTemplateRef<ExplorerChartTabType>('explorerChartTab');
|
||||
@@ -224,6 +243,7 @@ const query = computed<TransactionExplorerFilter>(() => explorersStore.transacti
|
||||
const filteredTransactions = computed<TransactionInsightDataItem[]>(() => explorersStore.filteredTransactions);
|
||||
|
||||
const allDateRanges = computed<LocalizedDateRange[]>(() => getAllDateRanges(DateRangeScene.InsightsExplorer, true));
|
||||
const allTimezoneTypesUsedForDateRange = computed<TypeAndDisplayName[]>(() => getAllTimezoneTypesUsedForStatistics());
|
||||
const canShiftDateRange = computed<boolean>(() => query.value.dateRangeType !== DateRange.All.type);
|
||||
const displayQueryDateRangeName = computed<string>(() => formatDateRange(query.value.dateRangeType, query.value.startTime, query.value.endTime));
|
||||
const displayQueryStartTime = computed<string>(() => formatDateTimeToLongDateTime(parseDateTimeFromUnixTime(query.value.startTime)));
|
||||
@@ -337,6 +357,12 @@ function reload(force: boolean): Promise<unknown> | null {
|
||||
});
|
||||
}
|
||||
|
||||
function updateTimezoneUsedForDateRange(timezoneType: number): void {
|
||||
explorersStore.updateTransactionExplorerFilter({
|
||||
timezoneUsedForDateRange: timezoneType
|
||||
});
|
||||
}
|
||||
|
||||
function exportResults(): void {
|
||||
if (activeTab.value === 'table' && filteredTransactions.value) {
|
||||
const results = explorerDataTableTab.value?.buildExportResults();
|
||||
|
||||
@@ -80,7 +80,6 @@
|
||||
/>
|
||||
<pie-chart
|
||||
:items="categoryDimensionTransactionExplorerData && categoryDimensionTransactionExplorerData.length ? categoryDimensionTransactionExplorerData : []"
|
||||
:min-valid-percent="0.0001"
|
||||
:show-value="true"
|
||||
:show-percent="true"
|
||||
:enable-click-item="true"
|
||||
@@ -152,7 +151,7 @@ import {
|
||||
} from '@/lib/common.ts';
|
||||
|
||||
import {
|
||||
parseDateTimeFromUnixTime
|
||||
parseDateTimeFromString
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
interface InsightsExplorerDataTableTabProps {
|
||||
@@ -184,7 +183,7 @@ const {
|
||||
formatDateTimeToGregorianLikeShortYear,
|
||||
formatDateTimeToGregorianLikeShortYearMonth,
|
||||
formatDateTimeToGregorianLikeYearQuarter,
|
||||
formatDateTimeToGregorianLikeFiscalYear,
|
||||
formatGregorianYearToGregorianLikeFiscalYear,
|
||||
formatAmountToLocalizedNumerals,
|
||||
formatAmountToWesternArabicNumeralsWithoutDigitGrouping
|
||||
} = useI18n();
|
||||
@@ -238,18 +237,21 @@ function getCategoriedDataDisplayName(info: CategoriedInfo | SeriesedInfo): stri
|
||||
let name: string = '';
|
||||
let needI18n: boolean | undefined = false;
|
||||
let i18nParameters: Record<string, unknown> | undefined = undefined;
|
||||
let dimessionType: TransactionExplorerDataDimensionType = TransactionExplorerDataDimension.None.value;
|
||||
let dimessionType: TransactionExplorerDimensionType = TransactionExplorerDimensionType.Other;
|
||||
let dimession: TransactionExplorerDataDimensionType = TransactionExplorerDataDimension.None.value;
|
||||
|
||||
if ('categoryName' in info) {
|
||||
name = info.categoryName;
|
||||
needI18n = info.categoryNameNeedI18n;
|
||||
i18nParameters = info.categoryNameI18nParameters;
|
||||
dimessionType = explorersStore.transactionExplorerFilter.categoryDimension;
|
||||
dimessionType = info.categoryIdType;
|
||||
dimession = explorersStore.transactionExplorerFilter.categoryDimension;
|
||||
} else if ('seriesName' in info) {
|
||||
name = info.seriesName;
|
||||
needI18n = info.seriesNameNeedI18n;
|
||||
i18nParameters = info.seriesNameI18nParameters;
|
||||
dimessionType = explorersStore.transactionExplorerFilter.seriesDimension;
|
||||
dimessionType = info.seriesIdType;
|
||||
dimession = explorersStore.transactionExplorerFilter.seriesDimension;
|
||||
}
|
||||
|
||||
let displayName: string = name;
|
||||
@@ -262,32 +264,40 @@ function getCategoriedDataDisplayName(info: CategoriedInfo | SeriesedInfo): stri
|
||||
}
|
||||
|
||||
// convert the name to formatted date time if needed
|
||||
if (dimessionType === TransactionExplorerDataDimension.DateTime.value) {
|
||||
displayName = formatDateTimeToShortDateTime(parseDateTimeFromUnixTime(parseInt(name)));
|
||||
} else if (dimessionType === TransactionExplorerDataDimension.DateTimeByYearMonthDay.value) {
|
||||
displayName = formatDateTimeToShortDate(parseDateTimeFromUnixTime(parseInt(name)));
|
||||
} else if (dimessionType === TransactionExplorerDataDimension.DateTimeByYearMonth.value) {
|
||||
displayName = formatDateTimeToGregorianLikeShortYearMonth(parseDateTimeFromUnixTime(parseInt(name)));
|
||||
} else if (dimessionType === TransactionExplorerDataDimension.DateTimeByYearQuarter.value) {
|
||||
displayName = formatDateTimeToGregorianLikeYearQuarter(parseDateTimeFromUnixTime(parseInt(name)));
|
||||
} else if (dimessionType === TransactionExplorerDataDimension.DateTimeByYear.value) {
|
||||
displayName = formatDateTimeToGregorianLikeShortYear(parseDateTimeFromUnixTime(parseInt(name)));
|
||||
} else if (dimessionType === TransactionExplorerDataDimension.DateTimeByFiscalYear.value) {
|
||||
displayName = formatDateTimeToGregorianLikeFiscalYear(parseDateTimeFromUnixTime(parseInt(name)));
|
||||
} else if (dimessionType === TransactionExplorerDataDimension.DateTimeByDayOfWeek.value) {
|
||||
if (dimession === TransactionExplorerDataDimension.DateTime.value) {
|
||||
const dateTime = parseDateTimeFromString(name, dimessionType);
|
||||
displayName = dateTime ? formatDateTimeToShortDateTime(dateTime) : tt('Unknown');
|
||||
} else if (dimession === TransactionExplorerDataDimension.DateTimeByYearMonthDay.value) {
|
||||
const dateTime = parseDateTimeFromString(name, dimessionType);
|
||||
displayName = dateTime ? formatDateTimeToShortDate(dateTime) : tt('Unknown');
|
||||
} else if (dimession === TransactionExplorerDataDimension.DateTimeByYearMonth.value) {
|
||||
const dateTime = parseDateTimeFromString(name, dimessionType);
|
||||
displayName = dateTime ? formatDateTimeToGregorianLikeShortYearMonth(dateTime) : tt('Unknown');
|
||||
} else if (dimession === TransactionExplorerDataDimension.DateTimeByYearQuarter.value) {
|
||||
const parts = name.split('-');
|
||||
const year = parts.length === 2 ? parts[0] : '';
|
||||
const quarter = parts.length === 2 ? parseInt(parts[1] as string) : 0;
|
||||
const dateTime = year && quarter ? parseDateTimeFromString(`${year}-${quarter * 3}`, TransactionExplorerDimensionType.YearMonth) : undefined;
|
||||
displayName = dateTime ? formatDateTimeToGregorianLikeYearQuarter(dateTime) : tt('Unknown');
|
||||
} else if (dimession === TransactionExplorerDataDimension.DateTimeByYear.value) {
|
||||
const dateTime = parseDateTimeFromString(name, dimessionType);
|
||||
displayName = dateTime ? formatDateTimeToGregorianLikeShortYear(dateTime) : tt('Unknown');
|
||||
} else if (dimession === TransactionExplorerDataDimension.DateTimeByFiscalYear.value) {
|
||||
displayName = formatGregorianYearToGregorianLikeFiscalYear(parseInt(name));
|
||||
} else if (dimession === TransactionExplorerDataDimension.DateTimeByDayOfWeek.value) {
|
||||
const weekDay = WeekDay.parse(name);
|
||||
displayName = weekDay ? getWeekdayLongName(weekDay) : tt('Unknown');
|
||||
} else if (dimessionType === TransactionExplorerDataDimension.DateTimeByDayOfMonth.value) {
|
||||
} else if (dimession === TransactionExplorerDataDimension.DateTimeByDayOfMonth.value) {
|
||||
displayName = getMonthdayShortName(parseInt(name));
|
||||
} else if (dimessionType === TransactionExplorerDataDimension.DateTimeByMonthOfYear.value) {
|
||||
} else if (dimession === TransactionExplorerDataDimension.DateTimeByMonthOfYear.value) {
|
||||
const month = Month.valueOf(parseInt(name));
|
||||
displayName = month ? getMonthLongName(month.name) : tt('Unknown');
|
||||
} else if (dimessionType === TransactionExplorerDataDimension.DateTimeByQuarterOfYear.value) {
|
||||
} else if (dimession === TransactionExplorerDataDimension.DateTimeByQuarterOfYear.value) {
|
||||
displayName = getQuarterName(parseInt(name));
|
||||
}
|
||||
|
||||
if (dimessionType === TransactionExplorerDataDimension.SourceAmount.value
|
||||
|| dimessionType === TransactionExplorerDataDimension.DestinationAmount.value) {
|
||||
if (dimession === TransactionExplorerDataDimension.SourceAmount.value
|
||||
|| dimession === TransactionExplorerDataDimension.DestinationAmount.value) {
|
||||
if (name !== '' && name !== 'none' && Number.isFinite(parseInt(name))) {
|
||||
displayName = formatAmountToLocalizedNumerals(parseInt(name));
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<span>{{ getDisplayDateTime(item) }}</span>
|
||||
<v-chip class="ms-1" variant="flat" color="secondary" size="x-small"
|
||||
v-if="!isSameAsDefaultTimezoneOffsetMinutes(item)">{{ getDisplayTimezone(item) }}</v-chip>
|
||||
<v-tooltip activator="parent" v-if="!isSameAsDefaultTimezoneOffsetMinutes(item)">{{ getDisplayTimeInDefaultTimezone(item) }}</v-tooltip>
|
||||
</template>
|
||||
<template #item.type="{ item }">
|
||||
<v-chip label variant="outlined" size="x-small"
|
||||
@@ -79,6 +80,7 @@ import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
import { useExplorersStore } from '@/stores/explorer.ts';
|
||||
|
||||
import type { NumeralSystem } from '@/core/numeral.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
|
||||
import {
|
||||
@@ -108,6 +110,7 @@ const emit = defineEmits<{
|
||||
|
||||
const {
|
||||
tt,
|
||||
getCurrentNumeralSystemType,
|
||||
formatDateTimeToLongDateTime,
|
||||
formatDateTimeToGregorianDefaultDateTime,
|
||||
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
||||
@@ -119,6 +122,7 @@ const explorersStore = useExplorersStore();
|
||||
|
||||
const currentPage = ref<number>(1);
|
||||
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||
|
||||
const filteredTransactions = computed<TransactionInsightDataItem[]>(() => explorersStore.filteredTransactions);
|
||||
@@ -172,6 +176,13 @@ function getDisplayTimezone(transaction: TransactionInsightDataItem): string {
|
||||
return `UTC${getUtcOffsetByUtcOffsetMinutes(transaction.utcOffset)}`;
|
||||
}
|
||||
|
||||
function getDisplayTimeInDefaultTimezone(transaction: TransactionInsightDataItem): string {
|
||||
const timezoneOffsetMinutes = getTimezoneOffsetMinutes(transaction.time);
|
||||
const dateTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, timezoneOffsetMinutes);
|
||||
const utcOffset = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(getUtcOffsetByUtcOffsetMinutes(timezoneOffsetMinutes));
|
||||
return `${formatDateTimeToLongDateTime(dateTime)} (UTC${utcOffset})`;
|
||||
}
|
||||
|
||||
function getDisplayTransactionType(transaction: TransactionInsightDataItem): string {
|
||||
if (transaction.type === TransactionType.ModifyBalance) {
|
||||
return tt('Modify Balance');
|
||||
|
||||
Reference in New Issue
Block a user