add transaction calendar for mobile version

This commit is contained in:
MaysWind
2025-05-09 01:14:35 +08:00
parent fbc8c5e8c7
commit 56ba4d88f4
12 changed files with 336 additions and 50 deletions
+1
View File
@@ -48,6 +48,7 @@ input[type=number] {
/** Custom class **/
:root {
--default-icon-color: #000;
--ebk-primary-color: 198, 126, 72;
--v-expand-panel-title-bg: rgba(var(--v-theme-on-surface), var(--v-hover-opacity));
--v-card-title-bg: rgba(var(--v-theme-on-surface), var(--v-hover-opacity));
}
+2
View File
@@ -75,6 +75,8 @@
--ebk-transaction-date-width: 25px;
--ebk-transaction-day-font-size: 16px;
--ebk-transaction-day-of-week-font-size: 12px;
--ebk-transaction-calendar-amount-font-size: 12px;
--ebk-transaction-calendar-daily-amounts-height: 65px;
--ebk-transaction-account-arrow-font-size: 12px;
--ebk-transaction-account-arrow-margin-top: -1px;
--ebk-transaction-tag-icon-font-size: 22px;
+2
View File
@@ -75,6 +75,8 @@
--ebk-transaction-date-width: 28px;
--ebk-transaction-day-font-size: 17px;
--ebk-transaction-day-of-week-font-size: 13px;
--ebk-transaction-calendar-amount-font-size: 13px;
--ebk-transaction-calendar-daily-amounts-height: 65px;
--ebk-transaction-account-arrow-font-size: 13px;
--ebk-transaction-account-arrow-margin-top: -2px;
--ebk-transaction-tag-icon-font-size: 24px;
+2
View File
@@ -75,6 +75,8 @@
--ebk-transaction-date-width: 25px;
--ebk-transaction-day-font-size: 16px;
--ebk-transaction-day-of-week-font-size: 12px;
--ebk-transaction-calendar-amount-font-size: 12px;
--ebk-transaction-calendar-daily-amounts-height: 65px;
--ebk-transaction-account-arrow-font-size: 12px;
--ebk-transaction-account-arrow-margin-top: -1px;
--ebk-transaction-tag-icon-font-size: 20px;
+2
View File
@@ -75,6 +75,8 @@
--ebk-transaction-date-width: 30px;
--ebk-transaction-day-font-size: 18px;
--ebk-transaction-day-of-week-font-size: 14px;
--ebk-transaction-calendar-amount-font-size: 14px;
--ebk-transaction-calendar-daily-amounts-height: 70px;
--ebk-transaction-account-arrow-font-size: 14px;
--ebk-transaction-account-arrow-margin-top: -2px;
--ebk-transaction-tag-icon-font-size: 26px;
+2
View File
@@ -75,6 +75,8 @@
--ebk-transaction-date-width: 32px;
--ebk-transaction-day-font-size: 20px;
--ebk-transaction-day-of-week-font-size: 15px;
--ebk-transaction-calendar-amount-font-size: 15px;
--ebk-transaction-calendar-daily-amounts-height: 75px;
--ebk-transaction-account-arrow-font-size: 15px;
--ebk-transaction-account-arrow-margin-top: -3px;
--ebk-transaction-tag-icon-font-size: 28px;
@@ -75,6 +75,8 @@
--ebk-transaction-date-width: 36px;
--ebk-transaction-day-font-size: 22px;
--ebk-transaction-day-of-week-font-size: 17px;
--ebk-transaction-calendar-amount-font-size: 17px;
--ebk-transaction-calendar-daily-amounts-height: 80px;
--ebk-transaction-account-arrow-font-size: 17px;
--ebk-transaction-account-arrow-margin-top: -4px;
--ebk-transaction-tag-icon-font-size: 30px;
@@ -75,6 +75,8 @@
--ebk-transaction-date-width: 40px;
--ebk-transaction-day-font-size: 24px;
--ebk-transaction-day-of-week-font-size: 19px;
--ebk-transaction-calendar-amount-font-size: 19px;
--ebk-transaction-calendar-daily-amounts-height: 85px;
--ebk-transaction-account-arrow-font-size: 19px;
--ebk-transaction-account-arrow-margin-top: -4px;
--ebk-transaction-tag-icon-font-size: 32px;
+5
View File
@@ -108,6 +108,7 @@ i.icon.la, i.icon.las, i.icon.lab {
/** custom class **/
:root {
--default-icon-color: #000;
--ebk-primary-color: 198, 126, 72;
--ebk-transaction-tag-chip-bg-color: rgba(0, 0, 0, 0.04);
}
@@ -535,6 +536,10 @@ i.icon.la, i.icon.las, i.icon.lab {
border-radius: 0 0 var(--f7-list-inset-border-radius) var(--f7-list-inset-border-radius);
}
.combination-list-wrapper.no-accordion-toggle .list.combination-list-content.inset > ul {
border-radius: var(--f7-list-inset-border-radius);
}
/** Nested List item for framework7 **/
.nested-list-item .item-title {
width: 100%;
@@ -23,9 +23,17 @@ import {
getUtcOffsetByUtcOffsetMinutes,
getTimezoneOffset,
getTimezoneOffsetMinutes,
getBrowserTimezoneOffsetMinutes,
getLocalDatetimeFromUnixTime,
getActualUnixTimeForStore,
getDummyUnixTimeForLocalUsage,
parseDateFromUnixTime,
getUnixTime,
getYearMonthFirstUnixTime
getYear,
getMonth,
getDay,
getYearMonthFirstUnixTime,
isDateRangeMatchOneMonth
} from '@/lib/datetime.ts';
import {
@@ -162,6 +170,7 @@ export function useTransactionListPageBase() {
});
const queryMinTime = computed<string>(() => formatUnixTimeToLongDateTime(query.value.minTime));
const queryMaxTime = computed<string>(() => formatUnixTimeToLongDateTime(query.value.maxTime));
const queryMonthlyData = computed<boolean>(() => isDateRangeMatchOneMonth(query.value.minTime, query.value.maxTime));
const queryAllFilterCategoryIds = computed<Record<string, boolean>>(() => transactionsStore.allFilterCategoryIds);
const queryAllFilterAccountIds = computed<Record<string, boolean>>(() => transactionsStore.allFilterAccountIds);
const queryAllFilterTagIds = computed<Record<string, boolean>>(() => transactionsStore.allFilterTagIds);
@@ -217,6 +226,34 @@ export function useTransactionListPageBase() {
return displayAmount.join(' ~ ');
});
const transactionCalendarMinDate = computed<Date>(() => getLocalDatetimeFromUnixTime(getDummyUnixTimeForLocalUsage(query.value.minTime, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())));
const transactionCalendarMaxDate = computed<Date>(() => getLocalDatetimeFromUnixTime(getDummyUnixTimeForLocalUsage(query.value.maxTime, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())));
const currentMonthTransactionData = computed<TransactionMonthList | null>(() => {
const allTransactions = transactionsStore.transactions;
if (!allTransactions || !allTransactions.length) {
return null;
}
const currentMonthMinDate = parseDateFromUnixTime(query.value.minTime);
const currentYear = getYear(currentMonthMinDate);
const currentMonth = getMonth(currentMonthMinDate);
for (let i = 0; i < allTransactions.length; i++) {
if (allTransactions[i].year === currentYear && allTransactions[i].month === currentMonth) {
return allTransactions[i];
}
}
return null;
});
function noTransactionInMonthDay(date: Date): boolean {
const dateTime = parseDateFromUnixTime(getActualUnixTimeForStore(getUnixTime(date), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes()));
return !currentMonthTransactionData.value || !currentMonthTransactionData.value.dailyTotalAmounts || !currentMonthTransactionData.value.dailyTotalAmounts[getDay(dateTime)];
}
const canAddTransaction = computed<boolean>(() => {
if (query.value.accountIds && queryAllFilterAccountIdsCount.value === 1) {
const account = allAccountsMap.value[query.value.accountIds];
@@ -335,6 +372,7 @@ export function useTransactionListPageBase() {
queryDateRangeName,
queryMinTime,
queryMaxTime,
queryMonthlyData,
queryAllFilterCategoryIds,
queryAllFilterAccountIds,
queryAllFilterTagIds,
@@ -345,6 +383,10 @@ export function useTransactionListPageBase() {
queryCategoryName,
queryTagName,
queryAmount,
transactionCalendarMinDate,
transactionCalendarMaxDate,
currentMonthTransactionData,
noTransactionInMonthDay,
canAddTransaction,
// functions
getDisplayTime,
+14 -34
View File
@@ -146,8 +146,8 @@
:month-change-on-arrows="false"
:enable-time-picker="false"
:hide-offset-dates="true"
:min-date="getShortDate(parseDateFromUnixTime(query.minTime))"
:max-date="getShortDate(parseDateFromUnixTime(query.maxTime))"
:min-date="transactionCalendarMinDate"
:max-date="transactionCalendarMaxDate"
:disabled-dates="noTransactionInMonthDay"
:prevent-min-max-navigation="true"
:clearable="false"
@@ -648,7 +648,7 @@ import { useSettingsStore } from '@/stores/setting.ts';
import { useAccountsStore } from '@/stores/account.ts';
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
import { type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
import { useTransactionsStore } from '@/stores/transaction.ts';
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
import { useDesktopPageStore } from '@/stores/desktopPage.ts';
@@ -676,10 +676,8 @@ import {
import {
getCurrentUnixTime,
parseDateFromUnixTime,
getShortDate,
getYear,
getMonth,
getDay,
getSpecifiedDayFirstUnixTime,
getBrowserTimezoneOffsetMinutes,
getActualUnixTimeForStore,
@@ -691,8 +689,7 @@ import {
getDateRangeByBillingCycleDateType,
getRecentDateRangeIndex,
getFullMonthDateRange,
getMonthFirstDayOrCurrentDayShortDate,
isDateRangeMatchOneMonth
getMonthFirstDayOrCurrentDayShortDate
} from '@/lib/datetime.ts';
import {
categoryTypeToTransactionType,
@@ -763,7 +760,6 @@ const {
getAllLongWeekdayNames,
getAllRecentMonthDateRanges,
getAllTransactionTagFilterTypes,
getMonthShortName,
getWeekdayLongName
} = useI18n();
@@ -790,6 +786,7 @@ const {
query,
queryMinTime,
queryMaxTime,
queryMonthlyData,
queryAllFilterCategoryIds,
queryAllFilterAccountIds,
queryAllFilterTagIds,
@@ -800,6 +797,10 @@ const {
queryCategoryName,
queryTagName,
queryAmount,
transactionCalendarMinDate,
transactionCalendarMaxDate,
currentMonthTransactionData,
noTransactionInMonthDay,
canAddTransaction,
getDisplayTime,
getDisplayLongDate,
@@ -930,26 +931,6 @@ const transactions = computed<Transaction[]>(() => {
}
});
const currentMonthTransactionData = computed<TransactionMonthList | null>(() => {
const allTransactions = transactionsStore.transactions;
if (!allTransactions || !allTransactions.length) {
return null;
}
const currentMonthMinDate = parseDateFromUnixTime(query.value.minTime);
const currentYear = getYear(currentMonthMinDate);
const currentMonth = getMonth(currentMonthMinDate);
for (let i = 0; i < allTransactions.length; i++) {
if (allTransactions[i].year === currentYear && allTransactions[i].month === currentMonth) {
return allTransactions[i];
}
}
return null;
});
const recentDateRangeIndex = computed<number>({
get: () => getRecentDateRangeIndex(recentMonthDateRanges.value, query.value.dateType, query.value.minTime, query.value.maxTime, firstDayOfWeek.value),
set: (value) => {
@@ -1001,8 +982,6 @@ const queryAllSelectedFilterTagIds = computed<string>(() => {
}
});
const queryMonthlyData = computed<boolean>(() => isDateRangeMatchOneMonth(query.value.minTime, query.value.maxTime));
const countPerPage = computed<number>({
get: () => {
if (temporaryCountPerPage.value) {
@@ -1066,10 +1045,6 @@ const currentMonthTotalAmount = computed<TransactionListDisplayTotalAmount | nul
}
});
function noTransactionInMonthDay(date: Date): boolean {
return !currentMonthTransactionData.value || !currentMonthTransactionData.value.dailyTotalAmounts || !currentMonthTransactionData.value.dailyTotalAmounts[getDay(date)];
}
function getCategoryListItemCheckedClass(category: TransactionCategory, queryCategoryIds: Record<string, boolean>): Record<string, boolean> {
if (queryCategoryIds && queryCategoryIds[category.id]) {
return {
@@ -1150,6 +1125,7 @@ function init(initProps: TransactionListProps): void {
});
if (changed) {
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(query.value.minTime);
updateUrlWhenChanged(changed);
return;
}
@@ -1243,6 +1219,7 @@ function changePageType(type: number): void {
maxTime: dateRange.maxTime,
minTime: dateRange.minTime
});
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(query.value.minTime);
}
}
@@ -1281,6 +1258,7 @@ function changeDateFilter(dateRange: TimeRangeAndDateType | number | null): void
if (fullMonthDateRange) {
dateRange = fullMonthDateRange;
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(dateRange.minTime);
}
}
@@ -1316,6 +1294,7 @@ function changeCustomDateFilter(minTime: number, maxTime: number): void {
minTime = dateRange.minTime;
maxTime = dateRange.maxTime;
dateType = dateRange.dateType;
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(minTime);
}
}
@@ -1355,6 +1334,7 @@ function shiftDateRange(startTime: number, endTime: number, scale: number): void
if (fullMonthDateRange) {
newDateRange = fullMonthDateRange;
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(newDateRange.minTime);
}
}
+259 -15
View File
@@ -9,7 +9,12 @@
@infinite="loadMore(true)">
<f7-navbar>
<f7-nav-left :back-link="tt('Back')"></f7-nav-left>
<f7-nav-title :title="tt('Transaction List')"></f7-nav-title>
<f7-nav-title>
<f7-link popover-open=".chart-data-type-popover-menu">
<span style="color: var(--f7-text-color)">{{ displayPageTypeName }}</span>
<f7-icon size="16px" color="gray" style="opacity: 0.5" f7="chevron_down_circle_fill"></f7-icon>
</f7-link>
</f7-nav-title>
<f7-nav-right class="navbar-compact-icons">
<f7-link icon-f7="plus" :class="{ 'disabled': !canAddTransaction }" :href="`/transaction/add?type=${query.type}&categoryId=${queryAllFilterCategoryIdsCount === 1 ? query.categoryIds : ''}&accountId=${queryAllFilterAccountIdsCount === 1 ? query.accountIds : ''}&tagIds=${query.tagIds || ''}`"></f7-link>
</f7-nav-right>
@@ -25,6 +30,21 @@
</f7-subnavbar>
</f7-navbar>
<f7-popover class="chart-data-type-popover-menu"
v-model:opened="showTransactionListPageTypePopover">
<f7-list dividers>
<f7-list-item :title="tt(type.name)"
:class="{ 'list-item-selected': pageType === type.type }"
:key="type.type"
v-for="type in TransactionListPageType.values()"
@click="changePageType(type.type); showTransactionListPageTypePopover = false">
<template #after>
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="pageType === type.type"></f7-icon>
</template>
</f7-list-item>
</f7-list>
</f7-popover>
<f7-toolbar tabbar bottom class="toolbar-item-auto-size transaction-list-toolbar">
<f7-link :class="{ 'disabled': loading || query.dateType === DateRange.All.type }" @click="shiftDateRange(query.minTime, query.maxTime, -1)">
<f7-icon f7="arrow_left_square"></f7-icon>
@@ -46,10 +66,41 @@
</f7-link>
</f7-toolbar>
<f7-block class="transaction-calendar-container margin-vertical" v-if="pageType === TransactionListPageType.Calendar.type">
<vue-date-picker inline auto-apply model-type="yyyy-M-d"
month-name-format="long"
class="justify-content-center"
:config="{ noSwipe: true }"
:readonly="loading"
:disable-month-year-select="true"
:month-change-on-scroll="false"
:month-change-on-arrows="false"
:enable-time-picker="false"
:hide-offset-dates="true"
:min-date="transactionCalendarMinDate"
:max-date="transactionCalendarMaxDate"
:disabled-dates="noTransactionInMonthDay"
:prevent-min-max-navigation="true"
:clearable="false"
:dark="isDarkMode"
:week-start="firstDayOfWeek"
:day-names="dayNames"
v-model="currentCalendarDate">
<template #day="{ day }">
<div class="transaction-calendar-daily-amounts display-flex flex-direction-column align-items-center justify-content-center">
<span>{{ day }}</span>
<small class="text-income" v-if="currentMonthTransactionData && currentMonthTransactionData.dailyTotalAmounts[day] && currentMonthTransactionData.dailyTotalAmounts[day].income">{{ getDisplayMonthTotalAmount(currentMonthTransactionData.dailyTotalAmounts[day].income, false, '', currentMonthTransactionData.dailyTotalAmounts[day].incompleteIncome) }}</small>
<small class="text-expense" v-if="currentMonthTransactionData && currentMonthTransactionData.dailyTotalAmounts[day] && currentMonthTransactionData.dailyTotalAmounts[day].expense">{{ getDisplayMonthTotalAmount(currentMonthTransactionData.dailyTotalAmounts[day].expense, false, '', currentMonthTransactionData.dailyTotalAmounts[day].incompleteExpense) }}</small>
</div>
</template>
</vue-date-picker>
</f7-block>
<div class="skeleton-text" v-if="loading">
<f7-block class="combination-list-wrapper margin-vertical" :key="blockIdx" v-for="blockIdx in [ 1, 2 ]">
<f7-block class="combination-list-wrapper margin-vertical" :class="{ 'no-accordion-toggle': pageType !== TransactionListPageType.List.type }"
:key="blockIdx" v-for="blockIdx in (pageType === TransactionListPageType.List.type ? [ 1, 2 ] : [ 1 ])">
<f7-accordion-item>
<f7-block-title>
<f7-block-title v-if="pageType === TransactionListPageType.List.type">
<f7-accordion-toggle>
<f7-list strong inset dividers media-list
class="transaction-amount-list combination-list-header combination-list-opened">
@@ -122,12 +173,12 @@
<f7-list-item :title="tt('No transaction data')"></f7-list-item>
</f7-list>
<f7-block class="combination-list-wrapper margin-vertical"
<f7-block class="combination-list-wrapper margin-vertical" :class="{ 'no-accordion-toggle': pageType !== TransactionListPageType.List.type }"
:key="transactionMonthList.yearMonth" v-for="(transactionMonthList) in transactions">
<f7-accordion-item :opened="transactionMonthList.opened"
@accordion:open="collapseTransactionMonthList(transactionMonthList, false)"
@accordion:close="collapseTransactionMonthList(transactionMonthList, true)">
<f7-block-title>
<f7-block-title v-if="pageType === TransactionListPageType.List.type">
<f7-accordion-toggle>
<f7-list strong inset dividers media-list
class="transaction-amount-list combination-list-header"
@@ -254,7 +305,8 @@
</f7-accordion-item>
</f7-block>
<f7-block class="text-align-center" :class="{ 'disabled': loadingMore }" v-show="!loading && hasMoreTransaction">
<f7-block class="text-align-center" :class="{ 'disabled': loadingMore }" v-show="!loading && hasMoreTransaction"
v-if="pageType === TransactionListPageType.List.type">
<f7-link href="#" @click="loadMore(false)">{{ tt('Load More') }}</f7-link>
</f7-block>
@@ -266,6 +318,7 @@
:class="{ 'list-item-selected': query.dateType === dateRange.type }"
:key="dateRange.type"
v-for="dateRange in allDateRanges"
v-show="pageType === TransactionListPageType.List.type || dateRange.type === DateRange.ThisMonth.type || dateRange.type === DateRange.LastMonth.type || dateRange.type === DateRange.Custom.type"
@click="changeDateFilter(dateRange.type)">
<template #after>
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.dateType === dateRange.type"></f7-icon>
@@ -525,8 +578,9 @@ import type { Router } from 'framework7/types';
import { useI18n } from '@/locales/helpers.ts';
import { type Framework7Dom, useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted, scrollToSelectedItem } from '@/lib/ui/mobile.ts';
import { useTransactionListPageBase } from '@/views/base/transactions/TransactionListPageBase.ts';
import { TransactionListPageType, useTransactionListPageBase } from '@/views/base/transactions/TransactionListPageBase.ts';
import { useEnvironmentsStore } from '@/stores/environment.ts';
import { useAccountsStore } from '@/stores/account.ts';
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
@@ -543,8 +597,12 @@ import { TransactionType } from '@/core/transaction.ts';
import type { TransactionCategory } from '@/models/transaction_category.ts';
import type { Transaction } from '@/models/transaction.ts';
import {
arrangeArrayWithNewStartIndex
} from '@/lib/common.ts';
import {
getCurrentUnixTime,
parseDateFromUnixTime,
getSpecifiedDayFirstUnixTime,
getBrowserTimezoneOffsetMinutes,
getActualUnixTimeForStore,
@@ -553,7 +611,9 @@ import {
getDateTypeByDateRange,
getDateTypeByBillingCycleDateRange,
getDateRangeByDateType,
getDateRangeByBillingCycleDateType
getDateRangeByBillingCycleDateType,
getFullMonthDateRange,
getMonthFirstDayOrCurrentDayShortDate, getYear, getMonth
} from '@/lib/datetime.ts';
import {
categoryTypeToTransactionType,
@@ -567,6 +627,7 @@ const props = defineProps<{
const {
tt,
getAllShortWeekdayNames,
getAllTransactionTagFilterTypes,
getWeekdayShortName
} = useI18n();
@@ -574,9 +635,11 @@ const {
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const {
pageType,
loading,
customMinDatetime,
customMaxDatetime,
currentCalendarDate,
currentTimezoneOffsetMinutes,
firstDayOfWeek,
defaultCurrency,
@@ -591,10 +654,12 @@ const {
allAvailableCategoriesCount,
allTransactionTags,
allAvailableTagsCount,
displayPageTypeName,
query,
queryDateRangeName,
queryMinTime,
queryMaxTime,
queryMonthlyData,
queryAllFilterCategoryIds,
queryAllFilterAccountIds,
queryAllFilterTagIds,
@@ -604,6 +669,10 @@ const {
queryAccountName,
queryCategoryName,
queryAmount,
transactionCalendarMinDate,
transactionCalendarMaxDate,
currentMonthTransactionData,
noTransactionInMonthDay,
canAddTransaction,
getDisplayTime,
getDisplayLongYearMonth,
@@ -613,14 +682,19 @@ const {
getTransactionTypeName,
} = useTransactionListPageBase();
const environmentsStore = useEnvironmentsStore();
const accountsStore = useAccountsStore();
const transactionCategoriesStore = useTransactionCategoriesStore();
const transactionTagsStore = useTransactionTagsStore();
const transactionsStore = useTransactionsStore();
const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode || false);
const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllShortWeekdayNames(), firstDayOfWeek.value));
const loadingError = ref<unknown | null>(null);
const loadingMore = ref<boolean>(false);
const transactionToDelete = ref<Transaction | null>(null);
const showTransactionListPageTypePopover = ref<boolean>(false);
const showDatePopover = ref<boolean>(false);
const showCategoryPopover = ref<boolean>(false);
const showAccountPopover = ref<boolean>(false);
@@ -635,10 +709,60 @@ const transactions = computed<TransactionMonthList[]>(() => {
return [];
}
return transactionsStore.transactions;
if (pageType.value === TransactionListPageType.List.type) {
return transactionsStore.transactions;
} else if (pageType.value === TransactionListPageType.Calendar.type) {
if (queryMonthlyData.value) {
const transactionData = currentMonthTransactionData.value;
if (!transactionData || !transactionData.items) {
return [];
}
const transactions :Transaction[] = [];
for (let i = 0; i < transactionData.items.length; i++) {
const transaction = transactionData.items[i];
if (transaction.date === currentCalendarDate.value) {
transactions.push(transaction);
}
}
const dailyTransactionList: TransactionMonthList = {
year: currentMonthTransactionData.value.year,
month: currentMonthTransactionData.value.month,
yearMonth: currentMonthTransactionData.value.yearMonth,
opened: true,
items: transactions,
totalAmount: {
income: 0,
expense: 0,
incompleteIncome: false,
incompleteExpense: false
},
dailyTotalAmounts: {}
};
return [dailyTransactionList];
} else {
return [];
}
} else {
return [];
}
});
const noTransaction = computed<boolean>(() => {
if (pageType.value === TransactionListPageType.List.type) {
return transactionsStore.noTransaction;
} else if (pageType.value === TransactionListPageType.Calendar.type) {
return !transactions.value || !transactions.value.length || !transactions.value[0].items || !transactions.value[0].items.length;
} else {
return true;
}
});
const noTransaction = computed<boolean>(() => transactionsStore.noTransaction);
const hasMoreTransaction = computed<boolean>(() => transactionsStore.hasMoreTransaction);
function getTransactionDomId(transaction: Transaction): string {
@@ -716,11 +840,24 @@ function reload(done?: () => void): void {
transactionCategoriesStore.loadAllCategories({ force: false }),
transactionTagsStore.loadAllTags({ force: false })
]).then(() => {
return transactionsStore.loadTransactions({
reload: true,
autoExpand: true,
defaultCurrency: defaultCurrency.value
});
if (queryMonthlyData.value) {
const currentMonthMinDate = parseDateFromUnixTime(query.value.minTime);
const currentYear = getYear(currentMonthMinDate);
const currentMonth = getMonth(currentMonthMinDate);
return transactionsStore.loadMonthlyAllTransactions({
year: currentYear,
month: currentMonth,
autoExpand: true,
defaultCurrency: defaultCurrency.value
});
} else {
return transactionsStore.loadTransactions({
reload: true,
autoExpand: true,
defaultCurrency: defaultCurrency.value
});
}
}).then(() => {
done?.();
@@ -772,6 +909,28 @@ function loadMore(autoExpand: boolean): void {
});
}
function changePageType(type: number): void {
pageType.value = type;
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(query.value.minTime);
if (pageType.value === TransactionListPageType.Calendar.type) {
const dateRange = getFullMonthDateRange(query.value.minTime, query.value.maxTime, firstDayOfWeek.value);
if (dateRange) {
const changed = transactionsStore.updateTransactionListFilter({
dateType: dateRange.dateType,
maxTime: dateRange.maxTime,
minTime: dateRange.minTime
});
if (changed) {
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(query.value.minTime);
reload();
}
}
}
}
function changeDateFilter(dateType: number): void {
if (dateType === DateRange.Custom.type) { // Custom
if (!query.value.minTime || !query.value.maxTime) {
@@ -801,6 +960,16 @@ function changeDateFilter(dateType: number): void {
return;
}
if (pageType.value === TransactionListPageType.Calendar.type) {
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(dateRange.minTime);
const fullMonthDateRange = getFullMonthDateRange(dateRange.minTime, dateRange.maxTime, firstDayOfWeek.value);
if (fullMonthDateRange) {
dateRange = fullMonthDateRange;
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(dateRange.minTime);
}
}
const changed = transactionsStore.updateTransactionListFilter({
dateType: dateRange.dateType,
maxTime: dateRange.maxTime,
@@ -825,6 +994,18 @@ function changeCustomDateFilter(minTime: number, maxTime: number): void {
dateType = getDateTypeByDateRange(minTime, maxTime, firstDayOfWeek.value, DateRangeScene.Normal);
}
if (pageType.value === TransactionListPageType.Calendar.type) {
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(minTime);
const dateRange = getFullMonthDateRange(minTime, maxTime, firstDayOfWeek.value);
if (dateRange) {
minTime = dateRange.minTime;
maxTime = dateRange.maxTime;
dateType = dateRange.dateType;
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(minTime);
}
}
const changed = transactionsStore.updateTransactionListFilter({
dateType: dateType,
maxTime: maxTime,
@@ -853,6 +1034,16 @@ function shiftDateRange(minTime: number, maxTime: number, scale: number): void {
newDateRange = getShiftedDateRangeAndDateType(minTime, maxTime, scale, firstDayOfWeek.value, DateRangeScene.Normal);
}
if (pageType.value === TransactionListPageType.Calendar.type) {
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(newDateRange.minTime);
const fullMonthDateRange = getFullMonthDateRange(newDateRange.minTime, newDateRange.maxTime, firstDayOfWeek.value);
if (fullMonthDateRange) {
newDateRange = fullMonthDateRange;
currentCalendarDate.value = getMonthFirstDayOrCurrentDayShortDate(newDateRange.minTime);
}
}
const changed = transactionsStore.updateTransactionListFilter({
dateType: newDateRange.dateType,
maxTime: newDateRange.maxTime,
@@ -1199,4 +1390,57 @@ init();
max-height: 400px;
overflow-y: auto;
}
.transaction-calendar-container .dp__main .dp__menu {
--dp-border-radius: var(--f7-list-inset-border-radius);
--dp-menu-border-color: transparent;
}
.transaction-calendar-container .dp__main .dp__menu.dp__theme_dark {
--dp-background-color: var(--f7-list-strong-bg-color);
}
.transaction-calendar-container .dp__main .dp__calendar .dp__calendar_row {
--dp-cell-size: var(--ebk-transaction-calendar-daily-amounts-height);
--dp-cell-padding: 1px;
--dp-primary-text-color: var(--f7-theme-color);
}
.transaction-calendar-container .dp__main .dp__calendar .dp__calendar_row > .dp__calendar_item .transaction-calendar-daily-amounts {
width: 100%;
height: 100%;
background-color: var(--f7-list-group-title-bg-color);
border-radius: 6px;
}
.transaction-calendar-container .dp__main .dp__calendar .dp__calendar_row > .dp__calendar_item > .dp__active_date {
background-color: transparent;
}
.transaction-calendar-container .dp__main .dp__calendar .dp__calendar_row > .dp__calendar_item > .dp__today {
border: inherit;
}
.transaction-calendar-container .dp__main .dp__calendar .dp__calendar_row > .dp__calendar_item > .dp__active_date .transaction-calendar-daily-amounts {
background-color: rgba(var(--ebk-primary-color), 0.16);
}
.transaction-calendar-container .dp__main .dp__calendar .dp__calendar_row > .dp__calendar_item > .dp__today .transaction-calendar-daily-amounts {
border: 1px solid var(--dp-primary-color);
}
.transaction-calendar-container .dp__main .dp__calendar .dp__calendar_row > .dp__calendar_item {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.transaction-calendar-container .dp__main .dp__calendar .dp__calendar_row > .dp__calendar_item .transaction-calendar-daily-amounts > small {
display: block;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: var(--ebk-transaction-calendar-amount-font-size);
}
</style>