add explicit type for string-based datetimes, replacing third-party datetime type with internal DateTime type
This commit is contained in:
@@ -17,7 +17,7 @@ import type { TransactionReconciliationStatementResponseItem } from '@/models/tr
|
||||
import { isDefined, isArray } from '@/lib/common.ts';
|
||||
import { sumAmounts } from '@/lib/numeral.ts';
|
||||
import {
|
||||
getYearAndMonthFromUnixTime,
|
||||
getGregorianCalendarYearAndMonthFromUnixTime,
|
||||
getYearFirstUnixTimeBySpecifiedUnixTime,
|
||||
getQuarterFirstUnixTimeBySpecifiedUnixTime,
|
||||
getMonthFirstUnixTimeBySpecifiedUnixTime,
|
||||
@@ -99,8 +99,8 @@ export function useAccountBalanceTrendsChartBase(props: CommonAccountBalanceTren
|
||||
if (!isDefined(props.dateAggregationType)) {
|
||||
return getAllDaysStartAndEndUnixTimes(dataDateRange.value.minUnixTime, dataDateRange.value.maxUnixTime);
|
||||
} else {
|
||||
const startYearMonth = getYearAndMonthFromUnixTime(dataDateRange.value.minUnixTime);
|
||||
const endYearMonth = getYearAndMonthFromUnixTime(dataDateRange.value.maxUnixTime);
|
||||
const startYearMonth = getGregorianCalendarYearAndMonthFromUnixTime(dataDateRange.value.minUnixTime);
|
||||
const endYearMonth = getGregorianCalendarYearAndMonthFromUnixTime(dataDateRange.value.maxUnixTime);
|
||||
return getAllDateRangesByYearMonthRange(startYearMonth, endYearMonth, props.fiscalYearStart, props.dateAggregationType);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4,9 +4,9 @@ import { type TimeRangeAndDateType, type PresetDateRange, type UnixTimeRange, ty
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
|
||||
import {
|
||||
getCurrentUnixTime,
|
||||
getCurrentYear,
|
||||
getUnixTime,
|
||||
getAllowedYearRange,
|
||||
getLocalDatetimeFromUnixTime,
|
||||
getUnixTimeFromLocalDatetime,
|
||||
getTodayFirstUnixTime,
|
||||
getDummyUnixTimeForLocalUsage,
|
||||
getActualUnixTimeForStore,
|
||||
@@ -50,10 +50,7 @@ export function useDateRangeSelectionBase(props: CommonDateRangeSelectionProps)
|
||||
const userStore = useUserStore();
|
||||
const { minDate, maxDate } = getDateRangeFromProps(props);
|
||||
|
||||
const yearRange = ref<number[]>([
|
||||
2000,
|
||||
getCurrentYear() + 1
|
||||
]);
|
||||
const yearRange = ref<number[]>(getAllowedYearRange());
|
||||
|
||||
const dateRange = ref<Date[]>([
|
||||
getLocalDatetimeFromUnixTime(getDummyUnixTimeForLocalUsage(minDate, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())),
|
||||
@@ -65,11 +62,11 @@ export function useDateRangeSelectionBase(props: CommonDateRangeSelectionProps)
|
||||
const isYearFirst = computed<boolean>(() => isLongDateMonthAfterYear());
|
||||
const is24Hour = computed<boolean>(() => isLongTime24HourFormat());
|
||||
const beginDateTime = computed<string>(() => {
|
||||
const actualBeginUnixTime = getActualUnixTimeForStore(getUnixTime(dateRange.value[0]), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes());
|
||||
const actualBeginUnixTime = getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(dateRange.value[0]), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes());
|
||||
return formatUnixTimeToLongDateTime(actualBeginUnixTime);
|
||||
});
|
||||
const endDateTime = computed<string>(() => {
|
||||
const actualEndUnixTime = getActualUnixTimeForStore(getUnixTime(dateRange.value[1]), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes());
|
||||
const actualEndUnixTime = getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(dateRange.value[1]), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes());
|
||||
return formatUnixTimeToLongDateTime(actualEndUnixTime);
|
||||
});
|
||||
const presetRanges = computed<PresetDateRange[]>(() => {
|
||||
@@ -108,8 +105,8 @@ export function useDateRangeSelectionBase(props: CommonDateRangeSelectionProps)
|
||||
const currentMinDate = dateRange.value[0];
|
||||
const currentMaxDate = dateRange.value[1];
|
||||
|
||||
let minUnixTime = getUnixTime(currentMinDate);
|
||||
let maxUnixTime = getUnixTime(currentMaxDate);
|
||||
let minUnixTime = getUnixTimeFromLocalDatetime(currentMinDate);
|
||||
let maxUnixTime = getUnixTimeFromLocalDatetime(currentMaxDate);
|
||||
|
||||
if (minUnixTime < 0 || maxUnixTime < 0) {
|
||||
throw new Error('Date is too early');
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useUserStore } from '@/stores/user.ts';
|
||||
import { type NameValue } from '@/core/base.ts';
|
||||
import { type WeekDayValue } from '@/core/datetime.ts';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
|
||||
import { getCurrentYear } from '@/lib/datetime.ts';
|
||||
import { getAllowedYearRange } from '@/lib/datetime.ts';
|
||||
|
||||
export interface TimePickerValue {
|
||||
value: string;
|
||||
@@ -34,10 +34,7 @@ export function useDateTimeSelectionBase() {
|
||||
const isSecondTwoDigits = ref<boolean>(isLongTimeSecondTwoDigits());
|
||||
const isMeridiemIndicatorFirst = ref<boolean>(isLongTimeMeridiemIndicatorFirst() || false);
|
||||
|
||||
const yearRange = ref<number[]>([
|
||||
2000,
|
||||
getCurrentYear() + 1
|
||||
]);
|
||||
const yearRange = ref<number[]>(getAllowedYearRange());
|
||||
|
||||
const meridiemItems = computed<NameValue[]>(() => getAllMeridiemIndicators());
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ function getFiscalYearStartFromProps(props: CommonFiscalYearStartSelectionProps)
|
||||
export function useFiscalYearStartSelectionBase(props: CommonFiscalYearStartSelectionProps) {
|
||||
const {
|
||||
getAllMinWeekdayNames,
|
||||
formatMonthDayToLongDay
|
||||
formatGregorianCalendarMonthDashDayToLongMonthDay
|
||||
} = useI18n();
|
||||
|
||||
const userStore = useUserStore();
|
||||
@@ -81,7 +81,7 @@ export function useFiscalYearStartSelectionBase(props: CommonFiscalYearStartSele
|
||||
fiscalYearStart = FiscalYearStart.Default;
|
||||
}
|
||||
|
||||
return formatMonthDayToLongDay(fiscalYearStart.toMonthDashDayString());
|
||||
return formatGregorianCalendarMonthDashDayToLongMonthDay(fiscalYearStart.toMonthDashDayString());
|
||||
});
|
||||
|
||||
const allowedMinDate = computed<Date>(() => getLocalDatetimeFromUnixTime(getThisYearFirstUnixTime()));
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { ref, computed } from 'vue';
|
||||
|
||||
import type { Year0BasedMonth } from '@/core/datetime.ts';
|
||||
import type { TextualYearMonth, Year0BasedMonth } from '@/core/datetime.ts';
|
||||
|
||||
import {
|
||||
getYear0BasedMonthObjectFromUnixTime,
|
||||
getYear0BasedMonthObjectFromString,
|
||||
getYearMonthStringFromYear0BasedMonthObject,
|
||||
getCurrentUnixTime,
|
||||
getCurrentYear,
|
||||
getAllowedYearRange,
|
||||
getThisYearFirstUnixTime,
|
||||
getYearMonthFirstUnixTime,
|
||||
getYearMonthLastUnixTime
|
||||
@@ -21,8 +21,8 @@ export interface MonthSelectionValue {
|
||||
}
|
||||
|
||||
export interface CommonMonthRangeSelectionProps {
|
||||
minTime?: string;
|
||||
maxTime?: string;
|
||||
minTime?: TextualYearMonth;
|
||||
maxTime?: TextualYearMonth;
|
||||
title?: string;
|
||||
hint?: string;
|
||||
show: boolean;
|
||||
@@ -64,11 +64,7 @@ export function useMonthRangeSelectionBase(props: CommonMonthRangeSelectionProps
|
||||
const { formatUnixTimeToLongYearMonth, isLongDateMonthAfterYear } = useI18n();
|
||||
const { minDate, maxDate } = getMonthRangeFromProps(props);
|
||||
|
||||
const yearRange = ref<number[]>([
|
||||
2000,
|
||||
getCurrentYear() + 1
|
||||
]);
|
||||
|
||||
const yearRange = ref<number[]>(getAllowedYearRange());
|
||||
const dateRange = ref<MonthSelectionValue[]>([
|
||||
minDate,
|
||||
maxDate
|
||||
@@ -84,7 +80,7 @@ export function useMonthRangeSelectionBase(props: CommonMonthRangeSelectionProps
|
||||
month0base: dateRange.value[1].month
|
||||
})));
|
||||
|
||||
function getMonthSelectionValue(yearMonth: string): MonthSelectionValue | null {
|
||||
function getMonthSelectionValue(yearMonth: TextualYearMonth): MonthSelectionValue | null {
|
||||
const yearMonthObj = getYear0BasedMonthObjectFromString(yearMonth);
|
||||
|
||||
if (!yearMonthObj) {
|
||||
@@ -97,7 +93,7 @@ export function useMonthRangeSelectionBase(props: CommonMonthRangeSelectionProps
|
||||
};
|
||||
}
|
||||
|
||||
function getFinalMonthRange(): { minYearMonth: string, maxYearMonth: string } | null {
|
||||
function getFinalMonthRange(): { minYearMonth: TextualYearMonth | '', maxYearMonth: TextualYearMonth | '' } | null {
|
||||
if (!dateRange.value[0] || !dateRange.value[1]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ import type { Year0BasedMonth } from '@/core/datetime.ts';
|
||||
|
||||
import {
|
||||
getYear0BasedMonthObjectFromUnixTime,
|
||||
getYear0BasedMonthObjectFromString,
|
||||
getYearMonthStringFromYear0BasedMonthObject,
|
||||
getCurrentYear,
|
||||
getAllowedYearRange,
|
||||
getThisMonthFirstUnixTime
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
@@ -18,7 +16,7 @@ export interface MonthSelectionValue {
|
||||
}
|
||||
|
||||
export interface CommonMonthSelectionProps {
|
||||
modelValue?: string;
|
||||
modelValue?: Year0BasedMonth;
|
||||
title?: string;
|
||||
hint?: string;
|
||||
show: boolean;
|
||||
@@ -28,11 +26,7 @@ function getYearMonthValueFromProps(props: CommonMonthSelectionProps): MonthSele
|
||||
let value: Year0BasedMonth = getYear0BasedMonthObjectFromUnixTime(getThisMonthFirstUnixTime());
|
||||
|
||||
if (props.modelValue) {
|
||||
const yearMonth = getYear0BasedMonthObjectFromString(props.modelValue);
|
||||
|
||||
if (yearMonth) {
|
||||
value = yearMonth;
|
||||
}
|
||||
value = props.modelValue;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -44,29 +38,23 @@ function getYearMonthValueFromProps(props: CommonMonthSelectionProps): MonthSele
|
||||
export function useMonthSelectionBase(props: CommonMonthSelectionProps) {
|
||||
const { isLongDateMonthAfterYear } = useI18n();
|
||||
|
||||
const yearRange = ref<number[]>([
|
||||
2000,
|
||||
getCurrentYear() + 1
|
||||
]);
|
||||
|
||||
const yearRange = ref<number[]>(getAllowedYearRange());
|
||||
const monthValue = ref<MonthSelectionValue>(getYearMonthValueFromProps(props));
|
||||
|
||||
const isYearFirst = computed<boolean>(() => isLongDateMonthAfterYear());
|
||||
|
||||
function getMonthSelectionValue(yearMonth: string): MonthSelectionValue | null {
|
||||
const yearMonthObj = getYear0BasedMonthObjectFromString(yearMonth);
|
||||
|
||||
if (!yearMonthObj) {
|
||||
function getMonthSelectionValue(yearMonth: Year0BasedMonth): MonthSelectionValue | null {
|
||||
if (!yearMonth) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
year: yearMonthObj.year,
|
||||
month: yearMonthObj.month0base
|
||||
year: yearMonth.year,
|
||||
month: yearMonth.month0base
|
||||
};
|
||||
}
|
||||
|
||||
function getTextualYearMonth(): string | null {
|
||||
function getYear0BasedMonth(): Year0BasedMonth | null {
|
||||
if (!monthValue.value) {
|
||||
return null;
|
||||
}
|
||||
@@ -75,10 +63,10 @@ export function useMonthSelectionBase(props: CommonMonthSelectionProps) {
|
||||
throw new Error('Date is too early');
|
||||
}
|
||||
|
||||
return getYearMonthStringFromYear0BasedMonthObject({
|
||||
return {
|
||||
year: monthValue.value.year,
|
||||
month0base: monthValue.value.month
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -89,6 +77,6 @@ export function useMonthSelectionBase(props: CommonMonthSelectionProps) {
|
||||
isYearFirst,
|
||||
// functions
|
||||
getMonthSelectionValue,
|
||||
getTextualYearMonth
|
||||
getYear0BasedMonth
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { computed } from 'vue';
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import type {
|
||||
TextualYearMonth,
|
||||
Year1BasedMonth,
|
||||
TimeRangeAndDateType,
|
||||
YearUnixTime,
|
||||
@@ -18,8 +19,8 @@ import { getAllDateRangesFromItems } from '@/lib/statistics.ts';
|
||||
|
||||
export interface CommonMonthlyTrendsChartProps<T extends Year1BasedMonth> {
|
||||
items: YearMonthItems<T>[];
|
||||
startYearMonth: string;
|
||||
endYearMonth: string;
|
||||
startYearMonth: TextualYearMonth | '';
|
||||
endYearMonth: TextualYearMonth | '';
|
||||
fiscalYearStart: number;
|
||||
sortingType: number;
|
||||
dateAggregationType: number;
|
||||
|
||||
@@ -44,13 +44,13 @@ import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
|
||||
import { type WeekDayValue } from '@/core/datetime.ts';
|
||||
import { type TextualYearMonthDay, type WeekDayValue } from '@/core/datetime.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
|
||||
import { getCurrentYear } from '@/lib/datetime.ts';
|
||||
import { getAllowedYearRange } from '@/lib/datetime.ts';
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue?: string;
|
||||
modelValue?: TextualYearMonthDay;
|
||||
disabled?: boolean;
|
||||
readonly?: boolean;
|
||||
clearable?: boolean;
|
||||
@@ -59,22 +59,19 @@ const props = defineProps<{
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: string): void;
|
||||
(e: 'update:modelValue', value: TextualYearMonthDay): void;
|
||||
}>();
|
||||
|
||||
const theme = useTheme();
|
||||
const { tt, getAllMinWeekdayNames, getMonthShortName, formatDateToLongDate, isLongDateMonthAfterYear } = useI18n();
|
||||
const { tt, getAllMinWeekdayNames, getMonthShortName, formatGregorianCalendarYearDashMonthDashDayToLongDate, isLongDateMonthAfterYear } = useI18n();
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const yearRange = ref<number[]>([
|
||||
2000,
|
||||
getCurrentYear() + 1
|
||||
]);
|
||||
const yearRange = ref<number[]>(getAllowedYearRange());
|
||||
|
||||
const dateTime = computed<string>({
|
||||
get: () => props.modelValue ?? '',
|
||||
set: (value: string) => emit('update:modelValue', value)
|
||||
set: (value: string) => emit('update:modelValue', value as TextualYearMonthDay)
|
||||
});
|
||||
|
||||
const isDarkMode = computed<boolean>(() => theme.global.name.value === ThemeType.Dark);
|
||||
@@ -83,7 +80,7 @@ const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllMi
|
||||
const isYearFirst = computed<boolean>(() => isLongDateMonthAfterYear());
|
||||
const displayTime = computed<string>(() => {
|
||||
if (props.modelValue) {
|
||||
return formatDateToLongDate(props.modelValue);
|
||||
return formatGregorianCalendarYearDashMonthDashDayToLongDate(props.modelValue);
|
||||
} else if (props.noDataText) {
|
||||
return props.noDataText;
|
||||
} else {
|
||||
|
||||
@@ -105,7 +105,7 @@ import {
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getLocalDatetimeFromUnixTime,
|
||||
getActualUnixTimeForStore,
|
||||
getUnixTime,
|
||||
getUnixTimeFromLocalDatetime,
|
||||
getAMOrPM,
|
||||
getCombinedDateAndTimeValues
|
||||
} from '@/lib/datetime.ts';
|
||||
@@ -154,7 +154,7 @@ const dateTime = computed<Date>({
|
||||
return getLocalDatetimeFromUnixTime(props.modelValue);
|
||||
},
|
||||
set: (value: Date) => {
|
||||
const unixTime = getUnixTime(value);
|
||||
const unixTime = getUnixTimeFromLocalDatetime(value);
|
||||
|
||||
if (unixTime < 0) {
|
||||
emit('error', 'Date is too early');
|
||||
@@ -225,7 +225,7 @@ const currentSecond = computed<string>({
|
||||
});
|
||||
|
||||
const isDarkMode = computed<boolean>(() => theme.global.name.value === ThemeType.Dark);
|
||||
const displayTime = computed<string>(() => formatUnixTimeToLongDateTime(getActualUnixTimeForStore(getUnixTime(dateTime.value), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())));
|
||||
const displayTime = computed<string>(() => formatUnixTimeToLongDateTime(getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(dateTime.value), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())));
|
||||
|
||||
function toggleMeridiemIndicator(): void {
|
||||
if (currentMeridiemIndicator.value === MeridiemIndicator.AM.name) {
|
||||
|
||||
@@ -71,6 +71,7 @@ import { useI18n } from '@/locales/helpers.ts';
|
||||
import { type CommonMonthRangeSelectionProps, useMonthRangeSelectionBase } from '@/components/base/MonthRangeSelectionBase.ts';
|
||||
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { type TextualYearMonth } from '@/core/datetime.ts';
|
||||
|
||||
interface DesktopMonthRangeSelectionProps extends CommonMonthRangeSelectionProps {
|
||||
persistent?: boolean;
|
||||
@@ -79,7 +80,7 @@ interface DesktopMonthRangeSelectionProps extends CommonMonthRangeSelectionProps
|
||||
const props = defineProps<DesktopMonthRangeSelectionProps>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:show', value: boolean): void;
|
||||
(e: 'dateRange:change', minYearMonth: string, maxYearMonth: string): void;
|
||||
(e: 'dateRange:change', minYearMonth: TextualYearMonth | '', maxYearMonth: TextualYearMonth | ''): void;
|
||||
(e: 'error', message: string): void;
|
||||
}>();
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ import { useI18n } from '@/locales/helpers.ts';
|
||||
import { type CommonMonthSelectionProps, useMonthSelectionBase } from '@/components/base/MonthSelectionBase.ts';
|
||||
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import type { Year0BasedMonth } from '@/core/datetime.ts';
|
||||
|
||||
interface DesktopMonthSelectionProps extends CommonMonthSelectionProps {
|
||||
persistent?: boolean;
|
||||
@@ -57,7 +58,7 @@ interface DesktopMonthSelectionProps extends CommonMonthSelectionProps {
|
||||
|
||||
const props = defineProps<DesktopMonthSelectionProps>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: string): void;
|
||||
(e: 'update:modelValue', value: Year0BasedMonth): void;
|
||||
(e: 'update:show', value: boolean): void;
|
||||
(e: 'error', message: string): void;
|
||||
}>();
|
||||
@@ -65,7 +66,7 @@ const emit = defineEmits<{
|
||||
const theme = useTheme();
|
||||
|
||||
const { tt, getMonthShortName } = useI18n();
|
||||
const { yearRange, monthValue, isYearFirst, getMonthSelectionValue, getTextualYearMonth } = useMonthSelectionBase(props);
|
||||
const { yearRange, monthValue, isYearFirst, getMonthSelectionValue, getYear0BasedMonth } = useMonthSelectionBase(props);
|
||||
|
||||
const isDarkMode = computed<boolean>(() => theme.global.name.value === ThemeType.Dark);
|
||||
const showState = computed<boolean>({
|
||||
@@ -75,7 +76,7 @@ const showState = computed<boolean>({
|
||||
|
||||
function confirm(): void {
|
||||
try {
|
||||
const finalMonthRange = getTextualYearMonth();
|
||||
const finalMonthRange = getYear0BasedMonth();
|
||||
|
||||
if (!finalMonthRange) {
|
||||
return;
|
||||
|
||||
@@ -45,17 +45,17 @@ import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useEnvironmentsStore } from '@/stores/environment.ts';
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
|
||||
import { type WeekDayValue } from '@/core/datetime.ts';
|
||||
import { type TextualYearMonthDay, type WeekDayValue } from '@/core/datetime.ts';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
|
||||
import { getCurrentYear } from '@/lib/datetime.ts';
|
||||
import { getAllowedYearRange } from '@/lib/datetime.ts';
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue?: string;
|
||||
modelValue?: TextualYearMonthDay;
|
||||
show: boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: string): void;
|
||||
(e: 'update:modelValue', value: TextualYearMonthDay): void;
|
||||
(e: 'update:show', value: boolean): void;
|
||||
}>();
|
||||
|
||||
@@ -64,10 +64,7 @@ const { tt, getAllMinWeekdayNames, getMonthShortName, isLongDateMonthAfterYear }
|
||||
const environmentsStore = useEnvironmentsStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const yearRange = ref<number[]>([
|
||||
2000,
|
||||
getCurrentYear() + 1
|
||||
]);
|
||||
const yearRange = ref<number[]>(getAllowedYearRange());
|
||||
const dateTime = ref<string>('');
|
||||
|
||||
const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode || false);
|
||||
@@ -81,7 +78,7 @@ function clear(): void {
|
||||
}
|
||||
|
||||
function confirm(): void {
|
||||
emit('update:modelValue', dateTime.value);
|
||||
emit('update:modelValue', dateTime.value as TextualYearMonthDay);
|
||||
emit('update:show', false);
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ import {
|
||||
getLocalDatetimeFromUnixTime,
|
||||
getActualUnixTimeForStore,
|
||||
getCurrentUnixTime,
|
||||
getUnixTime,
|
||||
getUnixTimeFromLocalDatetime,
|
||||
getAMOrPM,
|
||||
getCombinedDateAndTimeValues
|
||||
} from '@/lib/datetime.ts';
|
||||
@@ -225,7 +225,7 @@ const currentSecond = computed<string>({
|
||||
});
|
||||
|
||||
const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode || false);
|
||||
const displayTime = computed<string>(() => formatUnixTimeToLongDateTime(getActualUnixTimeForStore(getUnixTime(dateTime.value), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())));
|
||||
const displayTime = computed<string>(() => formatUnixTimeToLongDateTime(getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(dateTime.value), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())));
|
||||
const switchButtonTitle = computed<string>(() => mode.value === 'time' ? 'Date' : 'Time');
|
||||
|
||||
function switchMode(): void {
|
||||
@@ -249,7 +249,7 @@ function confirm(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
const unixTime = getUnixTime(dateTime.value);
|
||||
const unixTime = getUnixTimeFromLocalDatetime(dateTime.value);
|
||||
|
||||
if (unixTime < 0) {
|
||||
showToast('Date is too early');
|
||||
|
||||
@@ -52,10 +52,12 @@ import { type CommonMonthRangeSelectionProps, useMonthRangeSelectionBase } from
|
||||
|
||||
import { useEnvironmentsStore } from '@/stores/environment.ts';
|
||||
|
||||
import { type TextualYearMonth } from '@/core/datetime.ts';
|
||||
|
||||
const props = defineProps<CommonMonthRangeSelectionProps>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:show', value: boolean): void;
|
||||
(e: 'dateRange:change', minYearMonth: string, maxYearMonth: string): void;
|
||||
(e: 'dateRange:change', minYearMonth: TextualYearMonth | '', maxYearMonth: TextualYearMonth | ''): void;
|
||||
}>();
|
||||
|
||||
const { tt, getMonthShortName } = useI18n();
|
||||
|
||||
@@ -44,17 +44,18 @@ import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useI18nUIComponents } from '@/lib/ui/mobile.ts';
|
||||
import { type CommonMonthSelectionProps, useMonthSelectionBase } from '@/components/base/MonthSelectionBase.ts';
|
||||
|
||||
import type { Year0BasedMonth } from '@/core/datetime.ts';
|
||||
import { useEnvironmentsStore } from '@/stores/environment.ts';
|
||||
|
||||
const props = defineProps<CommonMonthSelectionProps>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: string): void;
|
||||
(e: 'update:modelValue', value: Year0BasedMonth): void;
|
||||
(e: 'update:show', value: boolean): void;
|
||||
}>();
|
||||
|
||||
const { tt, getMonthShortName } = useI18n();
|
||||
const { showToast } = useI18nUIComponents();
|
||||
const { yearRange, monthValue, isYearFirst, getMonthSelectionValue, getTextualYearMonth } = useMonthSelectionBase(props);
|
||||
const { yearRange, monthValue, isYearFirst, getMonthSelectionValue, getYear0BasedMonth } = useMonthSelectionBase(props);
|
||||
|
||||
const environmentsStore = useEnvironmentsStore();
|
||||
|
||||
@@ -62,7 +63,7 @@ const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode
|
||||
|
||||
function confirm(): void {
|
||||
try {
|
||||
const finalMonthRange = getTextualYearMonth();
|
||||
const finalMonthRange = getYear0BasedMonth();
|
||||
|
||||
if (!finalMonthRange) {
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
import type { TypeAndName, TypeAndDisplayName } from '@/core/base.ts';
|
||||
|
||||
export interface DateTime {
|
||||
getUnixTime(): number;
|
||||
getLocalizedCalendarYear(): number;
|
||||
getGregorianCalendarYear(): number;
|
||||
getGregorianCalendarQuarter(): number;
|
||||
getLocalizedCalendarQuarter(): number;
|
||||
getGregorianCalendarMonth(): number;
|
||||
getGregorianCalendarMonthName(): string;
|
||||
getLocalizedCalendarMonth(): number;
|
||||
getGregorianCalendarDay(): number;
|
||||
getLocalizedCalendarDay(): number;
|
||||
getGregorianCalendarYearDashMonthDashDay(): TextualYearMonthDay;
|
||||
getGregorianCalendarYearDashMonth(): TextualYearMonth;
|
||||
getWeekDay(): WeekDay;
|
||||
toGregorianCalendarYearMonthDay(): YearMonthDay;
|
||||
toGregorianCalendarYear0BasedMonth(): Year0BasedMonth;
|
||||
format(format: string): string;
|
||||
}
|
||||
|
||||
export type TextualYearMonth = `${number}-${number}`;
|
||||
export type TextualYearMonthDay = `${number}-${number}-${number}`;
|
||||
|
||||
export interface YearQuarter {
|
||||
readonly year: number;
|
||||
readonly quarter: number;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { UnixTimeRange } from './datetime.ts';
|
||||
import type { TextualYearMonth, UnixTimeRange } from './datetime.ts';
|
||||
|
||||
export class FiscalYearStart {
|
||||
public static readonly JanuaryFirstDay = new FiscalYearStart(1, 1);
|
||||
@@ -75,8 +75,8 @@ export class FiscalYearStart {
|
||||
return FiscalYearStart.of(month, day);
|
||||
}
|
||||
|
||||
public toMonthDashDayString(): string {
|
||||
return `${this.month.toString().padStart(2, '0')}-${this.day.toString().padStart(2, '0')}`;
|
||||
public toMonthDashDayString(): TextualYearMonth {
|
||||
return `${this.month.toString().padStart(2, '0')}-${this.day.toString().padStart(2, '0')}` as TextualYearMonth;
|
||||
}
|
||||
|
||||
private static isValidFiscalYearMonthDay(month: number, day: number): boolean {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { describe, expect, test, beforeAll } from '@jest/globals';
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
// Import all the fiscal year functions from the lib
|
||||
import type { TextualYearMonth } from '@/core/datetime.ts';
|
||||
import { FiscalYearStart, FiscalYearUnixTime } from '@/core/fiscalyear.ts';
|
||||
|
||||
import {
|
||||
@@ -230,8 +231,8 @@ describe('getFiscalYearTimeRangeFromUnixTime', () => {
|
||||
|
||||
// GET ALL FISCAL YEAR START AND END UNIX TIMES
|
||||
type TestCase_getAllFiscalYearsStartAndEndUnixTimes = {
|
||||
startYearMonth: string;
|
||||
endYearMonth: string;
|
||||
startYearMonth: TextualYearMonth;
|
||||
endYearMonth: TextualYearMonth;
|
||||
fiscalYearStart: string;
|
||||
fiscalYearStartId: string;
|
||||
expected: FiscalYearUnixTime[]
|
||||
|
||||
+163
-126
@@ -2,11 +2,15 @@ import moment from 'moment-timezone';
|
||||
import { type unitOfTime } from 'moment/moment';
|
||||
|
||||
import {
|
||||
type DateTime,
|
||||
type TextualYearMonth,
|
||||
type TextualYearMonthDay,
|
||||
type YearUnixTime,
|
||||
type YearQuarter,
|
||||
type Year0BasedMonth,
|
||||
type Year1BasedMonth,
|
||||
type YearMonthRange,
|
||||
type YearMonthDay,
|
||||
type TimeRange,
|
||||
type TimeRangeAndDateType,
|
||||
type TimeDifference,
|
||||
@@ -35,7 +39,120 @@ import {
|
||||
isNumber
|
||||
} from './common.ts';
|
||||
|
||||
type SupportedDate = Date | moment.Moment;
|
||||
class MomentDateTime implements DateTime {
|
||||
private instance: moment.Moment;
|
||||
|
||||
private constructor(instance: moment.Moment) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public getUnixTime(): number {
|
||||
return this.instance.unix();
|
||||
}
|
||||
|
||||
public getLocalizedCalendarYear(): number {
|
||||
return this.instance.year();
|
||||
}
|
||||
|
||||
public getGregorianCalendarYear(): number {
|
||||
return this.instance.year();
|
||||
}
|
||||
|
||||
public getGregorianCalendarQuarter(): number {
|
||||
return this.instance.quarter();
|
||||
}
|
||||
|
||||
public getLocalizedCalendarQuarter(): number {
|
||||
return this.instance.quarter();
|
||||
}
|
||||
|
||||
public getGregorianCalendarMonth(): number {
|
||||
return this.instance.month() + 1;
|
||||
}
|
||||
|
||||
public getGregorianCalendarMonthName(): string {
|
||||
return (Month.valueOf(this.instance.month() + 1) as Month).name;
|
||||
}
|
||||
|
||||
public getLocalizedCalendarMonth(): number {
|
||||
return this.instance.month() + 1;
|
||||
}
|
||||
|
||||
public getGregorianCalendarDay(): number {
|
||||
return this.instance.date();
|
||||
}
|
||||
|
||||
public getLocalizedCalendarDay(): number {
|
||||
return this.instance.date();
|
||||
}
|
||||
|
||||
public getGregorianCalendarYearDashMonthDashDay(): TextualYearMonthDay {
|
||||
return (this.instance.year() + '-' + (this.instance.month() + 1).toString().padStart(2, '0') + '-' + this.instance.date().toString().padStart(2, '0')) as TextualYearMonthDay;
|
||||
}
|
||||
|
||||
public getGregorianCalendarYearDashMonth(): TextualYearMonth {
|
||||
return (this.instance.year() + '-' + (this.instance.month() + 1).toString().padStart(2, '0')) as TextualYearMonth;
|
||||
}
|
||||
|
||||
public getWeekDay(): WeekDay {
|
||||
return WeekDay.valueOf(this.instance.days()) as WeekDay;
|
||||
}
|
||||
|
||||
public toGregorianCalendarYearMonthDay(): YearMonthDay {
|
||||
return {
|
||||
year: this.instance.year(),
|
||||
month: this.instance.month() + 1,
|
||||
day: this.instance.date()
|
||||
};
|
||||
}
|
||||
|
||||
public toGregorianCalendarYear0BasedMonth(): Year0BasedMonth {
|
||||
return {
|
||||
year: this.instance.year(),
|
||||
month0base: this.instance.month()
|
||||
};
|
||||
}
|
||||
|
||||
public format(format: string): string {
|
||||
return this.instance.format(format);
|
||||
}
|
||||
|
||||
public static of(instance: moment.Moment): DateTime {
|
||||
return new MomentDateTime(instance);
|
||||
}
|
||||
|
||||
public static now(): DateTime {
|
||||
return new MomentDateTime(moment());
|
||||
}
|
||||
|
||||
static isYearFirstTime(dateTime: MomentDateTime): boolean {
|
||||
const currentUnixTime = dateTime.instance.clone().set({ millisecond: 0 }).unix();
|
||||
const expectedUnxTime = dateTime.instance.clone().set({ millisecond: 0 }).startOf('year').unix();
|
||||
return currentUnixTime === expectedUnxTime;
|
||||
}
|
||||
|
||||
static isYearLastTime(dateTime: MomentDateTime): boolean {
|
||||
const currentUnixTime = dateTime.instance.clone().set({ millisecond: 999 }).unix();
|
||||
const expectedUnxTime = dateTime.instance.clone().set({ millisecond: 999 }).endOf('year').unix();
|
||||
return currentUnixTime === expectedUnxTime;
|
||||
}
|
||||
|
||||
static isMonthFirstTime(dateTime: MomentDateTime): boolean {
|
||||
const currentUnixTime = dateTime.instance.clone().set({ millisecond: 0 }).unix();
|
||||
const expectedUnxTime = dateTime.instance.clone().set({ millisecond: 0 }).startOf('month').unix();
|
||||
return currentUnixTime === expectedUnxTime;
|
||||
}
|
||||
|
||||
static isMonthLastTime(dateTime: MomentDateTime): boolean {
|
||||
const currentUnixTime = dateTime.instance.clone().set({ millisecond: 999 }).unix();
|
||||
const expectedUnxTime = dateTime.instance.clone().set({ millisecond: 999 }).endOf('month').unix();
|
||||
return currentUnixTime === expectedUnxTime;
|
||||
}
|
||||
}
|
||||
|
||||
export function getAllowedYearRange(): number[] {
|
||||
return [2000, moment().year() + 1];
|
||||
}
|
||||
|
||||
export function isYear0BasedMonthValid(year: number, month0base: number): boolean {
|
||||
if (!isNumber(year) || !isNumber(month0base)) {
|
||||
@@ -54,7 +171,7 @@ export function getYear0BasedMonthObjectFromUnixTime(unixTime: number): Year0Bas
|
||||
};
|
||||
}
|
||||
|
||||
export function getYear0BasedMonthObjectFromString(yearMonth: string): Year0BasedMonth | null {
|
||||
export function getYear0BasedMonthObjectFromString(yearMonth: TextualYearMonth | ''): Year0BasedMonth | null {
|
||||
if (!isString(yearMonth)) {
|
||||
return null;
|
||||
}
|
||||
@@ -78,12 +195,12 @@ export function getYear0BasedMonthObjectFromString(yearMonth: string): Year0Base
|
||||
};
|
||||
}
|
||||
|
||||
export function getYearMonthStringFromYear0BasedMonthObject(yearMonth: Year0BasedMonth | null): string {
|
||||
export function getYearMonthStringFromYear0BasedMonthObject(yearMonth: Year0BasedMonth | null): TextualYearMonth | '' {
|
||||
if (!yearMonth || !isYear0BasedMonthValid(yearMonth.year, yearMonth.month0base)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return `${yearMonth.year}-${yearMonth.month0base + 1}`;
|
||||
return (`${yearMonth.year}-${yearMonth.month0base + 1}`) as TextualYearMonth;
|
||||
}
|
||||
|
||||
export function getHourIn12HourFormat(hour: number): number {
|
||||
@@ -122,16 +239,8 @@ export function getUtcOffsetByUtcOffsetMinutes(utcOffsetMinutes: number): string
|
||||
const offsetHours = Math.trunc(Math.abs(utcOffsetMinutes) / 60);
|
||||
const offsetMinutes = Math.abs(utcOffsetMinutes) - offsetHours * 60;
|
||||
|
||||
let finalOffsetHours = offsetHours.toString();
|
||||
let finalOffsetMinutes = offsetMinutes.toString();
|
||||
|
||||
if (offsetHours < 10) {
|
||||
finalOffsetHours = '0' + offsetHours;
|
||||
}
|
||||
|
||||
if (offsetMinutes < 10) {
|
||||
finalOffsetMinutes = '0' + offsetMinutes;
|
||||
}
|
||||
const finalOffsetHours = offsetHours.toString().padStart(2, '0');
|
||||
const finalOffsetMinutes = offsetMinutes.toString().padStart(2, '0');
|
||||
|
||||
if (utcOffsetMinutes >= 0) {
|
||||
return `+${finalOffsetHours}:${finalOffsetMinutes}`;
|
||||
@@ -180,23 +289,15 @@ export function getDummyUnixTimeForLocalUsage(unixTime: number, utcOffset: numbe
|
||||
return unixTime + (utcOffset - currentUtcOffset) * 60;
|
||||
}
|
||||
|
||||
export function getCurrentDateTime(): DateTime {
|
||||
return MomentDateTime.now();
|
||||
}
|
||||
|
||||
export function getCurrentUnixTime(): number {
|
||||
return moment().unix();
|
||||
}
|
||||
|
||||
export function getCurrentYear(): number {
|
||||
return moment().year();
|
||||
}
|
||||
|
||||
export function getCurrentYearAndMonth(): string {
|
||||
return getYearAndMonth(moment());
|
||||
}
|
||||
|
||||
export function getCurrentDay(): number {
|
||||
return moment().date();
|
||||
}
|
||||
|
||||
export function parseDateFromUnixTime(unixTime: number, utcOffset?: number, currentUtcOffset?: number): moment.Moment {
|
||||
export function parseDateTimeFromUnixTime(unixTime: number, utcOffset?: number, currentUtcOffset?: number): DateTime {
|
||||
if (isNumber(utcOffset)) {
|
||||
if (!isNumber(currentUtcOffset)) {
|
||||
currentUtcOffset = getTimezoneOffsetMinutes();
|
||||
@@ -205,73 +306,31 @@ export function parseDateFromUnixTime(unixTime: number, utcOffset?: number, curr
|
||||
unixTime = getDummyUnixTimeForLocalUsage(unixTime, utcOffset, currentUtcOffset);
|
||||
}
|
||||
|
||||
return moment.unix(unixTime);
|
||||
return MomentDateTime.of(moment.unix(unixTime));
|
||||
}
|
||||
|
||||
export function formatUnixTime(unixTime: number, format: string, utcOffset?: number, currentUtcOffset?: number) {
|
||||
return parseDateFromUnixTime(unixTime, utcOffset, currentUtcOffset).format(format);
|
||||
export function formatUnixTime(unixTime: number, format: string, utcOffset?: number, currentUtcOffset?: number): string {
|
||||
return parseDateTimeFromUnixTime(unixTime, utcOffset, currentUtcOffset).format(format);
|
||||
}
|
||||
|
||||
export function formatCurrentTime(format: string): string {
|
||||
return moment().format(format);
|
||||
}
|
||||
|
||||
export function formatDate(date: string, format: string): string {
|
||||
export function formatGregorianCalendarYearDashMonthDashDay(date: TextualYearMonthDay, format: string): string {
|
||||
return moment(date, 'YYYY-MM-DD').format(format);
|
||||
}
|
||||
|
||||
export function formatMonthDay(monthDay: string, format: string): string {
|
||||
export function formatGregorianCalendarMonthDashDay(monthDay: TextualYearMonth, format: string): string {
|
||||
return moment(monthDay, 'MM-DD').format(format);
|
||||
}
|
||||
|
||||
export function getUnixTime(date: SupportedDate): number {
|
||||
return moment(date).unix();
|
||||
}
|
||||
|
||||
export function getShortDate(date: SupportedDate): string {
|
||||
date = moment(date);
|
||||
return date.year() + '-' + (date.month() + 1) + '-' + date.date();
|
||||
}
|
||||
|
||||
export function getYear(date: SupportedDate): number {
|
||||
return moment(date).year();
|
||||
}
|
||||
|
||||
export function getQuarter(date: SupportedDate): number {
|
||||
return moment(date).quarter();
|
||||
}
|
||||
|
||||
export function getMonth(date: SupportedDate): number {
|
||||
return moment(date).month() + 1;
|
||||
}
|
||||
|
||||
export function getYearAndMonth(date: SupportedDate): string {
|
||||
const year = getYear(date);
|
||||
const month = getMonth(date);
|
||||
|
||||
return `${year}-${month}`;
|
||||
}
|
||||
|
||||
export function getYearAndMonthFromUnixTime(unixTime: number): string {
|
||||
export function getGregorianCalendarYearAndMonthFromUnixTime(unixTime: number): TextualYearMonth | '' {
|
||||
if (!unixTime) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return getYearAndMonth(parseDateFromUnixTime(unixTime));
|
||||
}
|
||||
|
||||
export function getDay(date: SupportedDate): number {
|
||||
return moment(date).date();
|
||||
}
|
||||
|
||||
export function getDayOfWeekName(date: SupportedDate): string {
|
||||
const dayOfWeek = moment(date).days();
|
||||
return (WeekDay.valueOf(dayOfWeek) as WeekDay).name;
|
||||
}
|
||||
|
||||
export function getMonthName(date: SupportedDate): string {
|
||||
const month = moment(date).month();
|
||||
return (Month.valueOf(month + 1) as Month).name;
|
||||
return parseDateTimeFromUnixTime(unixTime).getGregorianCalendarYearDashMonth();
|
||||
}
|
||||
|
||||
export function getAMOrPM(hour: number): string {
|
||||
@@ -296,15 +355,6 @@ export function getTimeDifferenceHoursAndMinutes(timeDifferenceInMinutes: number
|
||||
};
|
||||
}
|
||||
|
||||
export function getMinuteFirstUnixTime(date: SupportedDate): number {
|
||||
const datetime = moment(date);
|
||||
return datetime.set({ second: 0, millisecond: 0 }).unix();
|
||||
}
|
||||
|
||||
export function getMinuteLastUnixTime(date: SupportedDate): number {
|
||||
return moment.unix(getMinuteFirstUnixTime(date)).add(1, 'minutes').subtract(1, 'seconds').unix();
|
||||
}
|
||||
|
||||
export function getTodayFirstUnixTime(): number {
|
||||
return moment().set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).unix();
|
||||
}
|
||||
@@ -412,7 +462,7 @@ export function getQuarterLastUnixTime(yearQuarter: YearQuarter): number {
|
||||
return moment.unix(getQuarterFirstUnixTime(yearQuarter)).add(3, 'months').subtract(1, 'seconds').unix();
|
||||
}
|
||||
|
||||
export function getYearMonthFirstUnixTime(yearMonth: Year0BasedMonth | Year1BasedMonth | string): number {
|
||||
export function getYearMonthFirstUnixTime(yearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | ''): number {
|
||||
let yearMonthObj: Year0BasedMonth | null = null;
|
||||
|
||||
if (isString(yearMonth)) {
|
||||
@@ -433,11 +483,11 @@ export function getYearMonthFirstUnixTime(yearMonth: Year0BasedMonth | Year1Base
|
||||
return moment().set({ year: yearMonthObj.year, month: yearMonthObj.month0base, date: 1, hour: 0, minute: 0, second: 0, millisecond: 0 }).unix();
|
||||
}
|
||||
|
||||
export function getYearMonthLastUnixTime(yearMonth: Year0BasedMonth | Year1BasedMonth | string): number {
|
||||
export function getYearMonthLastUnixTime(yearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | ''): number {
|
||||
return moment.unix(getYearMonthFirstUnixTime(yearMonth)).add(1, 'months').subtract(1, 'seconds').unix();
|
||||
}
|
||||
|
||||
export function getStartEndYearMonthRange(startYearMonth: Year0BasedMonth | Year1BasedMonth | string, endYearMonth: Year0BasedMonth | Year1BasedMonth | string): YearMonthRange | null {
|
||||
export function getStartEndYearMonthRange(startYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | '', endYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | ''): YearMonthRange | null {
|
||||
let startYearMonthObj: Year0BasedMonth | null = null;
|
||||
let endYearMonthObj: Year0BasedMonth | null = null;
|
||||
|
||||
@@ -473,7 +523,7 @@ export function getStartEndYearMonthRange(startYearMonth: Year0BasedMonth | Year
|
||||
};
|
||||
}
|
||||
|
||||
export function getAllYearsStartAndEndUnixTimes(startYearMonth: Year0BasedMonth | Year1BasedMonth | string, endYearMonth: Year0BasedMonth | Year1BasedMonth | string): YearUnixTime[] {
|
||||
export function getAllYearsStartAndEndUnixTimes(startYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | '', endYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | ''): YearUnixTime[] {
|
||||
const allYearTimes: YearUnixTime[] = [];
|
||||
const range = getStartEndYearMonthRange(startYearMonth, endYearMonth);
|
||||
|
||||
@@ -494,7 +544,7 @@ export function getAllYearsStartAndEndUnixTimes(startYearMonth: Year0BasedMonth
|
||||
return allYearTimes;
|
||||
}
|
||||
|
||||
export function getAllFiscalYearsStartAndEndUnixTimes(startYearMonth: Year0BasedMonth | Year1BasedMonth | string, endYearMonth: Year0BasedMonth | Year1BasedMonth | string, fiscalYearStartValue: number): FiscalYearUnixTime[] {
|
||||
export function getAllFiscalYearsStartAndEndUnixTimes(startYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | '', endYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | '', fiscalYearStartValue: number): FiscalYearUnixTime[] {
|
||||
// user selects date range: start=2024-01 and end=2026-12
|
||||
// result should be 4x FiscalYearUnixTime made up of:
|
||||
// - 2024-01->2024-06 (FY 24) - input start year-month->end of fiscal year in which the input start year-month falls
|
||||
@@ -544,7 +594,7 @@ export function getAllFiscalYearsStartAndEndUnixTimes(startYearMonth: Year0Based
|
||||
return allFiscalYearTimes;
|
||||
}
|
||||
|
||||
export function getAllQuartersStartAndEndUnixTimes(startYearMonth: Year0BasedMonth | Year1BasedMonth | string, endYearMonth: Year0BasedMonth | Year1BasedMonth | string): YearQuarterUnixTime[] {
|
||||
export function getAllQuartersStartAndEndUnixTimes(startYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | '', endYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | ''): YearQuarterUnixTime[] {
|
||||
const allYearQuarterTimes: YearQuarterUnixTime[] = [];
|
||||
const range = getStartEndYearMonthRange(startYearMonth, endYearMonth);
|
||||
|
||||
@@ -578,7 +628,7 @@ export function getAllQuartersStartAndEndUnixTimes(startYearMonth: Year0BasedMon
|
||||
return allYearQuarterTimes;
|
||||
}
|
||||
|
||||
export function getAllMonthsStartAndEndUnixTimes(startYearMonth: Year0BasedMonth | Year1BasedMonth | string, endYearMonth: Year0BasedMonth | Year1BasedMonth | string): YearMonthUnixTime[] {
|
||||
export function getAllMonthsStartAndEndUnixTimes(startYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | '', endYearMonth: Year0BasedMonth | Year1BasedMonth | TextualYearMonth | ''): YearMonthUnixTime[] {
|
||||
const allYearMonthTimes: YearMonthUnixTime[] = [];
|
||||
const range = getStartEndYearMonthRange(startYearMonth, endYearMonth);
|
||||
|
||||
@@ -622,16 +672,11 @@ export function getAllDaysStartAndEndUnixTimes(startUnixTime: number, endUnixTim
|
||||
let unixTime: number = startUnixTime;
|
||||
|
||||
while (unixTime <= endUnixTime) {
|
||||
const currentDay = parseDateFromUnixTime(unixTime);
|
||||
const currentDateTime = parseDateTimeFromUnixTime(unixTime);
|
||||
const currentDayMinUnixTime = getDayFirstUnixTimeBySpecifiedUnixTime(unixTime);
|
||||
const currentDayMaxUnixTime = getDayLastUnixTimeBySpecifiedUnixTime(unixTime);
|
||||
|
||||
allYearMonthDayTimes.push(YearMonthDayUnixTime.of({
|
||||
year: currentDay.year(),
|
||||
month: currentDay.month() + 1,
|
||||
day: currentDay.date()
|
||||
}, currentDayMinUnixTime, currentDayMaxUnixTime));
|
||||
|
||||
allYearMonthDayTimes.push(YearMonthDayUnixTime.of(currentDateTime.toGregorianCalendarYearMonthDay(), currentDayMinUnixTime, currentDayMaxUnixTime));
|
||||
unixTime = currentDayMaxUnixTime + 1;
|
||||
}
|
||||
|
||||
@@ -649,15 +694,15 @@ export function getDateTimeFormatType<T extends DateFormat | TimeFormat>(allForm
|
||||
}
|
||||
|
||||
export function getShiftedDateRange(minTime: number, maxTime: number, scale: number): TimeRange {
|
||||
const minDateTime = parseDateFromUnixTime(minTime).set({ millisecond: 0 });
|
||||
const maxDateTime = parseDateFromUnixTime(maxTime).set({ millisecond: 999 });
|
||||
const minDateTime = moment.unix(parseDateTimeFromUnixTime(minTime).getUnixTime()).set({ millisecond: 0 });
|
||||
const maxDateTime = moment.unix(parseDateTimeFromUnixTime(maxTime).getUnixTime()).set({ millisecond: 999 });
|
||||
|
||||
const firstDayOfMonth = minDateTime.clone().startOf('month');
|
||||
const lastDayOfMonth = maxDateTime.clone().endOf('month');
|
||||
|
||||
// check whether the date range matches full months
|
||||
if (firstDayOfMonth.unix() === minDateTime.unix() && lastDayOfMonth.unix() === maxDateTime.unix()) {
|
||||
const months = getYear(maxDateTime) * 12 + getMonth(maxDateTime) - getYear(minDateTime) * 12 - getMonth(minDateTime) + 1;
|
||||
const months = maxDateTime.year() * 12 + (maxDateTime.month() + 1) - minDateTime.year() * 12 - (minDateTime.month() + 1) + 1;
|
||||
const newMinDateTime = minDateTime.add(months * scale, 'months');
|
||||
const newMaxDateTime = newMinDateTime.clone().add(months, 'months').subtract(1, 'seconds');
|
||||
|
||||
@@ -848,7 +893,7 @@ export function getDateRangeByBillingCycleDateType(dateType: number, firstDayOfW
|
||||
|
||||
if (dateType === DateRange.PreviousBillingCycle.type || dateType === DateRange.CurrentBillingCycle.type) { // Previous Billing Cycle | Current Billing Cycle
|
||||
if (statementDate) {
|
||||
if (getCurrentDay() <= statementDate) {
|
||||
if (getCurrentDateTime().getGregorianCalendarDay() <= statementDate) {
|
||||
maxTime = getThisMonthSpecifiedDayLastUnixTime(statementDate);
|
||||
minTime = getUnixTimeBeforeUnixTime(getUnixTimeAfterUnixTime(getThisMonthSpecifiedDayFirstUnixTime(statementDate), 1, 'days'), 1, 'months');
|
||||
} else {
|
||||
@@ -898,8 +943,8 @@ export function getRecentMonthDateRanges(monthCount: number): RecentMonthDateRan
|
||||
|
||||
const maxTime = getUnixTimeBeforeUnixTime(getUnixTimeAfterUnixTime(minTime, 1, 'months'), 1, 'seconds');
|
||||
let dateType = DateRange.Custom.type;
|
||||
const year = getYear(parseDateFromUnixTime(minTime));
|
||||
const month = getMonth(parseDateFromUnixTime(minTime));
|
||||
const year = parseDateTimeFromUnixTime(minTime).getGregorianCalendarYear();
|
||||
const month = parseDateTimeFromUnixTime(minTime).getGregorianCalendarMonth();
|
||||
|
||||
if (i === 0) {
|
||||
dateType = DateRange.ThisMonth.type;
|
||||
@@ -1004,7 +1049,7 @@ export function getCombinedDateAndTimeValues(date: Date, hour: string, minute: s
|
||||
return newDateTime;
|
||||
}
|
||||
|
||||
export function getValidMonthDayOrCurrentDayShortDate(unixTime: number, currentShortDate: string): string {
|
||||
export function getValidMonthDayOrCurrentDayShortDate(unixTime: number, currentShortDate: string): TextualYearMonthDay {
|
||||
const currentTime = moment();
|
||||
const monthLastTime = moment.unix(getMonthLastUnixTimeBySpecifiedUnixTime(unixTime));
|
||||
|
||||
@@ -1015,43 +1060,35 @@ export function getValidMonthDayOrCurrentDayShortDate(unixTime: number, currentS
|
||||
const currentDay = parseInt(yearMonthDay[2]);
|
||||
|
||||
if (currentDay < monthLastTime.date()) {
|
||||
return getShortDate(monthLastTime.set({ date: currentDay }));
|
||||
return MomentDateTime.of(monthLastTime.set({ date: currentDay })).getGregorianCalendarYearDashMonthDashDay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (monthLastTime.year() === currentTime.year() && monthLastTime.month() === currentTime.month()) {
|
||||
return getShortDate(currentTime);
|
||||
return MomentDateTime.of(currentTime).getGregorianCalendarYearDashMonthDashDay();
|
||||
}
|
||||
|
||||
return getShortDate(monthLastTime);
|
||||
return MomentDateTime.of(monthLastTime).getGregorianCalendarYearDashMonthDashDay();
|
||||
}
|
||||
|
||||
export function isDateRangeMatchFullYears(minTime: number, maxTime: number): boolean {
|
||||
const minDateTime = parseDateFromUnixTime(minTime).set({ millisecond: 0 });
|
||||
const maxDateTime = parseDateFromUnixTime(maxTime).set({ millisecond: 999 });
|
||||
|
||||
const firstDayOfYear = minDateTime.clone().startOf('year');
|
||||
const lastDayOfYear = maxDateTime.clone().endOf('year');
|
||||
|
||||
return firstDayOfYear.unix() === minDateTime.unix() && lastDayOfYear.unix() === maxDateTime.unix();
|
||||
const minDateTime = parseDateTimeFromUnixTime(minTime);
|
||||
const maxDateTime = parseDateTimeFromUnixTime(maxTime);
|
||||
return MomentDateTime.isYearFirstTime(minDateTime as MomentDateTime) && MomentDateTime.isYearLastTime(maxDateTime as MomentDateTime);
|
||||
}
|
||||
|
||||
export function isDateRangeMatchFullMonths(minTime: number, maxTime: number): boolean {
|
||||
const minDateTime = parseDateFromUnixTime(minTime).set({ millisecond: 0 });
|
||||
const maxDateTime = parseDateFromUnixTime(maxTime).set({ millisecond: 999 });
|
||||
|
||||
const firstDayOfMonth = minDateTime.clone().startOf('month');
|
||||
const lastDayOfMonth = maxDateTime.clone().endOf('month');
|
||||
|
||||
return firstDayOfMonth.unix() === minDateTime.unix() && lastDayOfMonth.unix() === maxDateTime.unix();
|
||||
const minDateTime = parseDateTimeFromUnixTime(minTime);
|
||||
const maxDateTime = parseDateTimeFromUnixTime(maxTime);
|
||||
return MomentDateTime.isMonthFirstTime(minDateTime as MomentDateTime) && MomentDateTime.isMonthLastTime(maxDateTime as MomentDateTime);
|
||||
}
|
||||
|
||||
export function isDateRangeMatchOneMonth(minTime: number, maxTime: number): boolean {
|
||||
const minDateTime = parseDateFromUnixTime(minTime);
|
||||
const maxDateTime = parseDateFromUnixTime(maxTime);
|
||||
const minDateTime = parseDateTimeFromUnixTime(minTime);
|
||||
const maxDateTime = parseDateTimeFromUnixTime(maxTime);
|
||||
|
||||
if (getYear(minDateTime) !== getYear(maxDateTime) || getMonth(minDateTime) !== getMonth(maxDateTime)) {
|
||||
if (minDateTime.getGregorianCalendarYear() !== maxDateTime.getGregorianCalendarYear() || minDateTime.getGregorianCalendarMonth() !== maxDateTime.getGregorianCalendarMonth()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Year1BasedMonth, YearUnixTime, YearQuarterUnixTime, YearMonthUnixTime } from '@/core/datetime.ts';
|
||||
import type { TextualYearMonth, Year1BasedMonth, YearUnixTime, YearQuarterUnixTime, YearMonthUnixTime } from '@/core/datetime.ts';
|
||||
import type { FiscalYearUnixTime } from '@/core/fiscalyear.ts';
|
||||
import { ChartSortingType, ChartDateAggregationType } from '@/core/statistics.ts';
|
||||
import type {
|
||||
@@ -48,7 +48,7 @@ export function sortStatisticsItems<T extends SortableTransactionStatisticDataIt
|
||||
}
|
||||
}
|
||||
|
||||
export function getAllDateRangesFromItems<T extends Year1BasedMonth>(items: YearMonthItems<T>[], startYearMonth: Year1BasedMonth | string, endYearMonth: Year1BasedMonth | string, fiscalYearStart: number, dateAggregationType: number): YearUnixTime[] | FiscalYearUnixTime[] | YearQuarterUnixTime[] | YearMonthUnixTime[] {
|
||||
export function getAllDateRangesFromItems<T extends Year1BasedMonth>(items: YearMonthItems<T>[], startYearMonth: Year1BasedMonth | TextualYearMonth | '', endYearMonth: Year1BasedMonth | TextualYearMonth | '', fiscalYearStart: number, dateAggregationType: number): YearUnixTime[] | FiscalYearUnixTime[] | YearQuarterUnixTime[] | YearMonthUnixTime[] {
|
||||
if ((!startYearMonth || !endYearMonth) && items && items.length) {
|
||||
let minYear = Number.MAX_SAFE_INTEGER, minMonth = Number.MAX_SAFE_INTEGER, maxYear = 0, maxMonth = 0;
|
||||
|
||||
@@ -70,14 +70,14 @@ export function getAllDateRangesFromItems<T extends Year1BasedMonth>(items: Year
|
||||
}
|
||||
}
|
||||
|
||||
startYearMonth = `${minYear}-${minMonth}`;
|
||||
endYearMonth = `${maxYear}-${maxMonth}`;
|
||||
startYearMonth = `${minYear}-${minMonth}` as TextualYearMonth;
|
||||
endYearMonth = `${maxYear}-${maxMonth}` as TextualYearMonth;
|
||||
}
|
||||
|
||||
return getAllDateRangesByYearMonthRange(startYearMonth, endYearMonth, fiscalYearStart, dateAggregationType);
|
||||
}
|
||||
|
||||
export function getAllDateRangesByYearMonthRange(startYearMonth: Year1BasedMonth | string, endYearMonth: Year1BasedMonth | string, fiscalYearStart: number, dateAggregationType: number): YearUnixTime[] | FiscalYearUnixTime[] | YearQuarterUnixTime[] | YearMonthUnixTime[] {
|
||||
export function getAllDateRangesByYearMonthRange(startYearMonth: Year1BasedMonth | TextualYearMonth | '', endYearMonth: Year1BasedMonth | TextualYearMonth | '', fiscalYearStart: number, dateAggregationType: number): YearUnixTime[] | FiscalYearUnixTime[] | YearQuarterUnixTime[] | YearMonthUnixTime[] {
|
||||
if (!startYearMonth || !endYearMonth) {
|
||||
return [];
|
||||
}
|
||||
|
||||
+22
-22
@@ -16,6 +16,8 @@ import {
|
||||
} from '@/core/text.ts';
|
||||
|
||||
import {
|
||||
type TextualYearMonth,
|
||||
type TextualYearMonthDay,
|
||||
type DateFormat,
|
||||
type TimeFormat,
|
||||
type LocalizedDateTimeFormat,
|
||||
@@ -148,12 +150,13 @@ import {
|
||||
|
||||
import {
|
||||
formatCurrentTime,
|
||||
formatDate,
|
||||
formatMonthDay,
|
||||
formatGregorianCalendarYearDashMonthDashDay,
|
||||
formatGregorianCalendarMonthDashDay,
|
||||
formatUnixTime,
|
||||
getBrowserTimezoneOffset,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getCurrentUnixTime,
|
||||
parseDateTimeFromUnixTime,
|
||||
getDateTimeFormatType,
|
||||
getFiscalYearTimeRangeFromUnixTime,
|
||||
getFiscalYearTimeRangeFromYear,
|
||||
@@ -161,12 +164,9 @@ import {
|
||||
getTimeDifferenceHoursAndMinutes,
|
||||
getTimezoneOffset,
|
||||
getTimezoneOffsetMinutes,
|
||||
getYear,
|
||||
getQuarter,
|
||||
isDateRangeMatchFullMonths,
|
||||
isDateRangeMatchFullYears,
|
||||
isPM,
|
||||
parseDateFromUnixTime,
|
||||
isPM
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
import {
|
||||
@@ -1441,12 +1441,12 @@ export function useI18n() {
|
||||
});
|
||||
}
|
||||
|
||||
function getWeekdayShortName(weekDayName: string): string {
|
||||
return t(`datetime.${weekDayName}.short`);
|
||||
function getWeekdayShortName(weekDay: WeekDay): string {
|
||||
return t(`datetime.${weekDay.name}.short`);
|
||||
}
|
||||
|
||||
function getWeekdayLongName(weekDayName: string): string {
|
||||
return t(`datetime.${weekDayName}.long`);
|
||||
function getWeekdayLongName(weekDay: WeekDay): string {
|
||||
return t(`datetime.${weekDay.name}.long`);
|
||||
}
|
||||
|
||||
function getMultiMonthdayShortNames(monthDays: number[]): string {
|
||||
@@ -1618,18 +1618,18 @@ export function useI18n() {
|
||||
return getLocalizedLongTimeFormat().indexOf('ss') >= 0;
|
||||
}
|
||||
|
||||
function formatDateToLongDate(date: string): string {
|
||||
return formatDate(date, getLocalizedLongDateFormat());
|
||||
function formatGregorianCalendarYearDashMonthDashDayToLongDate(date: TextualYearMonthDay): string {
|
||||
return formatGregorianCalendarYearDashMonthDashDay(date, getLocalizedLongDateFormat());
|
||||
}
|
||||
|
||||
function formatMonthDayToLongDay(monthDay: string): string {
|
||||
return formatMonthDay(monthDay, getLocalizedLongMonthDayFormat());
|
||||
function formatGregorianCalendarMonthDashDayToLongMonthDay(monthDay: TextualYearMonth): string {
|
||||
return formatGregorianCalendarMonthDashDay(monthDay, getLocalizedLongMonthDayFormat());
|
||||
}
|
||||
|
||||
function formatUnixTimeToYearQuarter(unixTime: number): string {
|
||||
const date = parseDateFromUnixTime(unixTime);
|
||||
const year = getYear(date);
|
||||
const quarter = getQuarter(date);
|
||||
const date = parseDateTimeFromUnixTime(unixTime);
|
||||
const year = date.getLocalizedCalendarYear();
|
||||
const quarter = date.getLocalizedCalendarQuarter();
|
||||
return formatYearQuarter(year, quarter);
|
||||
}
|
||||
|
||||
@@ -1675,8 +1675,8 @@ export function useI18n() {
|
||||
return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime;
|
||||
}
|
||||
|
||||
const startTimeYear = getYear(parseDateFromUnixTime(startTime));
|
||||
const endTimeYear = getYear(parseDateFromUnixTime(endTime));
|
||||
const startTimeYear = parseDateTimeFromUnixTime(startTime).getLocalizedCalendarYear();
|
||||
const endTimeYear = parseDateTimeFromUnixTime(endTime).getLocalizedCalendarYear();
|
||||
|
||||
const format = getLocalizedShortDateFormat();
|
||||
const displayStartTime = formatUnixTime(startTime, format);
|
||||
@@ -1734,7 +1734,7 @@ export function useI18n() {
|
||||
fiscalYearStart = FiscalYearStart.Default;
|
||||
}
|
||||
|
||||
return formatMonthDayToLongDay(fiscalYearStart.toMonthDashDayString());
|
||||
return formatGregorianCalendarMonthDashDayToLongMonthDay(fiscalYearStart.toMonthDashDayString());
|
||||
}
|
||||
|
||||
function getTimezoneDifferenceDisplayText(utcOffset: number): string {
|
||||
@@ -2168,8 +2168,8 @@ export function useI18n() {
|
||||
formatUnixTimeToShortMonthDay: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortMonthDayFormat(), utcOffset, currentUtcOffset),
|
||||
formatUnixTimeToLongTime: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedLongTimeFormat(), utcOffset, currentUtcOffset),
|
||||
formatUnixTimeToShortTime: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortTimeFormat(), utcOffset, currentUtcOffset),
|
||||
formatDateToLongDate,
|
||||
formatMonthDayToLongDay,
|
||||
formatGregorianCalendarYearDashMonthDashDayToLongDate,
|
||||
formatGregorianCalendarMonthDashDayToLongMonthDay,
|
||||
formatUnixTimeToYearQuarter,
|
||||
formatYearQuarter,
|
||||
formatDateRange,
|
||||
|
||||
+14
-14
@@ -1,5 +1,5 @@
|
||||
import type { PartialRecord } from '@/core/base.ts';
|
||||
import type { Year1BasedMonth, StartEndTime } from '@/core/datetime.ts';
|
||||
import type { Year1BasedMonth, TextualYearMonthDay, StartEndTime, WeekDay } from '@/core/datetime.ts';
|
||||
import { type Coordinate, getNormalizedCoordinate } from '@/core/coordinate.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
|
||||
@@ -35,9 +35,9 @@ export class Transaction implements TransactionInfoResponse {
|
||||
private _destinationAccount?: Account; // only for displaying transaction
|
||||
private _tags?: TransactionTag[]; // only for displaying transaction
|
||||
|
||||
private _date?: string = undefined; // only for displaying transaction in transaction list
|
||||
private _day?: number = undefined; // only for displaying transaction in transaction list
|
||||
private _dayOfWeek?: string = undefined; // only for displaying transaction in transaction list
|
||||
private _gregorianCalendarYearDashMonthDashDay?: TextualYearMonthDay = undefined; // only for displaying transaction in transaction list
|
||||
private _gregorianCalendarDayOfMonth?: number = undefined; // only for displaying transaction in transaction list
|
||||
private _displayDayOfWeek?: WeekDay = undefined; // only for displaying transaction in transaction list
|
||||
|
||||
protected constructor(id: string, timeSequenceId: string, type: number, categoryId: string, time: number, timeZone: string | undefined, utcOffset: number, sourceAccountId: string, destinationAccountId: string, sourceAmount: number, destinationAmount: number, hideAmount: boolean, tagIds: string[], comment: string, editable: boolean) {
|
||||
this.id = id;
|
||||
@@ -106,16 +106,16 @@ export class Transaction implements TransactionInfoResponse {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public get date(): string | undefined {
|
||||
return this._date;
|
||||
public get gregorianCalendarYearDashMonthDashDay(): TextualYearMonthDay | undefined {
|
||||
return this._gregorianCalendarYearDashMonthDashDay;
|
||||
}
|
||||
|
||||
public get day(): number | undefined {
|
||||
return this._day;
|
||||
public get gregorianCalendarDayOfMonth(): number | undefined {
|
||||
return this._gregorianCalendarDayOfMonth;
|
||||
}
|
||||
|
||||
public get dayOfWeek(): string | undefined {
|
||||
return this._dayOfWeek;
|
||||
public get displayDayOfWeek(): WeekDay | undefined {
|
||||
return this._displayDayOfWeek;
|
||||
}
|
||||
|
||||
public getCategoryId(): string {
|
||||
@@ -220,10 +220,10 @@ export class Transaction implements TransactionInfoResponse {
|
||||
this._geoLocation = undefined;
|
||||
}
|
||||
|
||||
public setDisplayDate(date: string, day: number, dayOfWeek: string): void {
|
||||
this._date = date;
|
||||
this._day = day;
|
||||
this._dayOfWeek = dayOfWeek;
|
||||
public setDisplayDate(gregorianCalendarYearDashMonthDashDay: TextualYearMonthDay, gregorianCalendarDayOfMonth: number, displayDayOfWeek: WeekDay): void {
|
||||
this._gregorianCalendarYearDashMonthDashDay = gregorianCalendarYearDashMonthDashDay;
|
||||
this._gregorianCalendarDayOfMonth = gregorianCalendarDayOfMonth;
|
||||
this._displayDayOfWeek = displayDayOfWeek;
|
||||
}
|
||||
|
||||
public toCreateRequest(clientSessionId: string, actualTime?: number): TransactionCreateRequest {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { type TextualYearMonthDay } from '@/core/datetime.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
import { TemplateType } from '@/core/template.ts';
|
||||
|
||||
@@ -8,13 +9,13 @@ export class TransactionTemplate extends Transaction implements TransactionTempl
|
||||
public name: string;
|
||||
public scheduledFrequencyType?: number;
|
||||
public scheduledFrequency?: string;
|
||||
public scheduledStartDate?: string;
|
||||
public scheduledEndDate?: string;
|
||||
public scheduledStartDate?: TextualYearMonthDay;
|
||||
public scheduledEndDate?: TextualYearMonthDay;
|
||||
public scheduledAt?: number;
|
||||
public displayOrder: number;
|
||||
public hidden: boolean;
|
||||
|
||||
private constructor(id: string, templateType: number, name: string, type: number, categoryId: string, timeZone: string | undefined, utcOffset: number, sourceAccountId: string, destinationAccountId: string, sourceAmount: number, destinationAmount: number, hideAmount: boolean, scheduledFrequencyType: number | undefined, scheduledFrequency: string | undefined, scheduledStartDate: string | undefined, scheduledEndDate: string | undefined, scheduledAt: number | undefined, tagIds: string[], comment: string, editable: boolean, displayOrder: number, hidden: boolean) {
|
||||
private constructor(id: string, templateType: number, name: string, type: number, categoryId: string, timeZone: string | undefined, utcOffset: number, sourceAccountId: string, destinationAccountId: string, sourceAmount: number, destinationAmount: number, hideAmount: boolean, scheduledFrequencyType: number | undefined, scheduledFrequency: string | undefined, scheduledStartDate: TextualYearMonthDay | undefined, scheduledEndDate: TextualYearMonthDay | undefined, scheduledAt: number | undefined, tagIds: string[], comment: string, editable: boolean, displayOrder: number, hidden: boolean) {
|
||||
super(id, '', type, categoryId, 0, timeZone, utcOffset, sourceAccountId, destinationAccountId, sourceAmount, destinationAmount, hideAmount, tagIds, comment, editable);
|
||||
this.templateType = templateType;
|
||||
this.name = name;
|
||||
@@ -211,8 +212,8 @@ export interface TransactionTemplateInfoResponse extends TransactionInfoResponse
|
||||
readonly name: string;
|
||||
readonly scheduledFrequencyType?: number;
|
||||
readonly scheduledFrequency?: string;
|
||||
readonly scheduledStartDate?: string;
|
||||
readonly scheduledEndDate?: string;
|
||||
readonly scheduledStartDate?: TextualYearMonthDay;
|
||||
readonly scheduledEndDate?: TextualYearMonthDay;
|
||||
readonly scheduledAt?: number;
|
||||
readonly displayOrder: number;
|
||||
readonly hidden: boolean;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useAccountsStore } from './account.ts';
|
||||
import { useTransactionCategoriesStore } from './transactionCategory.ts';
|
||||
import { useExchangeRatesStore } from './exchangeRates.ts';
|
||||
|
||||
import { type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import { type TextualYearMonth, type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import { TransactionTagFilterType } from '@/core/transaction.ts';
|
||||
@@ -50,7 +50,7 @@ import {
|
||||
isObjectEmpty,
|
||||
objectFieldToArrayItem
|
||||
} from '@/lib/common.ts';
|
||||
import { getYearAndMonthFromUnixTime, getDateRangeByDateType } from '@/lib/datetime.ts';
|
||||
import { getGregorianCalendarYearAndMonthFromUnixTime, getDateRangeByDateType } from '@/lib/datetime.ts';
|
||||
import { getFinalAccountIdsByFilteredAccountIds } from '@/lib/account.ts';
|
||||
import { getFinalCategoryIdsByFilteredCategoryIds } from '@/lib/category.ts';
|
||||
import { sortStatisticsItems } from '@/lib/statistics.ts';
|
||||
@@ -118,8 +118,8 @@ export interface TransactionStatisticsPartialFilter {
|
||||
categoricalChartEndTime?: number;
|
||||
trendChartType?: number;
|
||||
trendChartDateType?: number;
|
||||
trendChartStartYearMonth?: string;
|
||||
trendChartEndYearMonth?: string;
|
||||
trendChartStartYearMonth?: TextualYearMonth | '';
|
||||
trendChartEndYearMonth?: TextualYearMonth | '';
|
||||
filterAccountIds?: Record<string, boolean>;
|
||||
filterCategoryIds?: Record<string, boolean>;
|
||||
tagIds?: string;
|
||||
@@ -136,8 +136,8 @@ export interface TransactionStatisticsFilter extends TransactionStatisticsPartia
|
||||
categoricalChartEndTime: number;
|
||||
trendChartType: number;
|
||||
trendChartDateType: number;
|
||||
trendChartStartYearMonth: string;
|
||||
trendChartEndYearMonth: string;
|
||||
trendChartStartYearMonth: TextualYearMonth | '';
|
||||
trendChartEndYearMonth: TextualYearMonth | '';
|
||||
filterAccountIds: Record<string, boolean>;
|
||||
filterCategoryIds: Record<string, boolean>;
|
||||
tagIds: string;
|
||||
@@ -800,8 +800,8 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
|
||||
if (trendChartDateRange) {
|
||||
transactionStatisticsFilter.value.trendChartDateType = trendChartDateRange.dateType;
|
||||
transactionStatisticsFilter.value.trendChartStartYearMonth = getYearAndMonthFromUnixTime(trendChartDateRange.minTime);
|
||||
transactionStatisticsFilter.value.trendChartEndYearMonth = getYearAndMonthFromUnixTime(trendChartDateRange.maxTime);
|
||||
transactionStatisticsFilter.value.trendChartStartYearMonth = getGregorianCalendarYearAndMonthFromUnixTime(trendChartDateRange.minTime);
|
||||
transactionStatisticsFilter.value.trendChartEndYearMonth = getGregorianCalendarYearAndMonthFromUnixTime(trendChartDateRange.maxTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-21
@@ -10,7 +10,7 @@ import { useStatisticsStore } from './statistics.ts';
|
||||
import { useExchangeRatesStore } from './exchangeRates.ts';
|
||||
|
||||
import type { BeforeResolveFunction } from '@/core/base.ts';
|
||||
import { DateRange } from '@/core/datetime.ts';
|
||||
import { type TextualYearMonth, DateRange } from '@/core/datetime.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import { TransactionType, TransactionTagFilterType } from '@/core/transaction.ts';
|
||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||
@@ -51,13 +51,7 @@ import {
|
||||
getTimezoneOffsetMinutes,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getActualUnixTimeForStore,
|
||||
parseDateFromUnixTime,
|
||||
getShortDate,
|
||||
getYear,
|
||||
getMonth,
|
||||
getYearAndMonth,
|
||||
getDay,
|
||||
getDayOfWeekName
|
||||
parseDateTimeFromUnixTime
|
||||
} from '@/lib/datetime.ts';
|
||||
import { getAmountWithDecimalNumberCount } from '@/lib/numeral.ts';
|
||||
import { getCurrencyFraction } from '@/lib/currency.ts';
|
||||
@@ -101,7 +95,7 @@ export interface TransactionTotalAmount {
|
||||
export interface TransactionMonthList {
|
||||
readonly year: number;
|
||||
readonly month: number; // 1-based (1 = January, 12 = December)
|
||||
readonly yearMonth: string;
|
||||
readonly yearDashMonth: TextualYearMonth;
|
||||
opened: boolean;
|
||||
readonly items: Transaction[];
|
||||
readonly totalAmount: TransactionTotalAmount;
|
||||
@@ -177,10 +171,10 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
const item = transactionPageWrapper.items[i];
|
||||
fillTransactionObject(item, currentUtcOffset);
|
||||
|
||||
const transactionTime = parseDateFromUnixTime(item.time, item.utcOffset, currentUtcOffset);
|
||||
const transactionYear = getYear(transactionTime);
|
||||
const transactionMonth = getMonth(transactionTime);
|
||||
const transactionYearMonth = getYearAndMonth(transactionTime);
|
||||
const transactionTime = parseDateTimeFromUnixTime(item.time, item.utcOffset, currentUtcOffset);
|
||||
const transactionYear = transactionTime.getGregorianCalendarYear();
|
||||
const transactionMonth = transactionTime.getGregorianCalendarMonth();
|
||||
const transactionYearDashMonth = transactionTime.getGregorianCalendarYearDashMonth();
|
||||
|
||||
if (i === 0 && transactions.value.length > 0) {
|
||||
const lastMonthList = transactions.value[transactions.value.length - 1];
|
||||
@@ -216,7 +210,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
const monthList: TransactionMonthList = {
|
||||
year: transactionYear,
|
||||
month: transactionMonth,
|
||||
yearMonth: transactionYearMonth,
|
||||
yearDashMonth: transactionYearDashMonth,
|
||||
opened: autoExpand,
|
||||
items: [],
|
||||
totalAmount: {
|
||||
@@ -250,9 +244,9 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
|
||||
function updateTransactionInTransactionList({ transaction, defaultCurrency }: { transaction: Transaction, defaultCurrency: string }): void {
|
||||
const currentUtcOffset = getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone);
|
||||
const transactionTime = parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentUtcOffset);
|
||||
const transactionYear = getYear(transactionTime);
|
||||
const transactionMonth = getMonth(transactionTime);
|
||||
const transactionTime = parseDateTimeFromUnixTime(transaction.time, transaction.utcOffset, currentUtcOffset);
|
||||
const transactionYear = transactionTime.getGregorianCalendarYear();
|
||||
const transactionMonth = transactionTime.getGregorianCalendarMonth();
|
||||
|
||||
for (let i = 0; i < transactions.value.length; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
@@ -267,7 +261,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
|
||||
if (transactionYear !== transactionMonthList.year ||
|
||||
transactionMonth !== transactionMonthList.month ||
|
||||
transaction.day !== transactionMonthList.items[j].day) {
|
||||
transaction.gregorianCalendarDayOfMonth !== transactionMonthList.items[j].gregorianCalendarDayOfMonth) {
|
||||
transactionListStateInvalid.value = true;
|
||||
return;
|
||||
}
|
||||
@@ -346,7 +340,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
|
||||
for (let i = 0; i < transactionMonthList.items.length; i++) {
|
||||
const transaction = transactionMonthList.items[i];
|
||||
const transactionDay = isNumber(transaction.day) ? transaction.day.toString() : '0';
|
||||
const transactionDay = isNumber(transaction.gregorianCalendarDayOfMonth) ? transaction.gregorianCalendarDayOfMonth.toString() : '0';
|
||||
let dailyTotalAmount = dailyTotalAmounts[transactionDay];
|
||||
|
||||
if (!dailyTotalAmount) {
|
||||
@@ -450,8 +444,8 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const transactionTime = parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentUtcOffset);
|
||||
transaction.setDisplayDate(getShortDate(transactionTime), getDay(transactionTime), getDayOfWeekName(transactionTime));
|
||||
const transactionTime = parseDateTimeFromUnixTime(transaction.time, transaction.utcOffset, currentUtcOffset);
|
||||
transaction.setDisplayDate(transactionTime.getGregorianCalendarYearDashMonthDashDay(), transactionTime.getGregorianCalendarDay(), transactionTime.getWeekDay());
|
||||
|
||||
if (transaction.sourceAccountId) {
|
||||
transaction.setSourceAccount(accountsStore.allAccountsMap[transaction.sourceAccountId]);
|
||||
|
||||
@@ -23,9 +23,8 @@ import { replaceAll } from '@/lib/common.ts';
|
||||
import {
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffsetMinutes,
|
||||
parseDateFromUnixTime,
|
||||
formatUnixTime,
|
||||
getUnixTime
|
||||
parseDateTimeFromUnixTime,
|
||||
formatUnixTime
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
export function useReconciliationStatementPageBase() {
|
||||
@@ -132,8 +131,7 @@ export function useReconciliationStatementPageBase() {
|
||||
}
|
||||
|
||||
function getDisplayDateTime(transaction: TransactionReconciliationStatementResponseItem): string {
|
||||
const transactionTime = getUnixTime(parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value));
|
||||
return formatUnixTimeToLongDateTime(transactionTime);
|
||||
return formatUnixTimeToLongDateTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
}
|
||||
|
||||
function getDisplayDate(transaction: TransactionReconciliationStatementResponseItem): string {
|
||||
@@ -210,7 +208,7 @@ export function useReconciliationStatementPageBase() {
|
||||
|
||||
const transactions = reconciliationStatements.value?.transactions ?? [];
|
||||
const rows = transactions.map(transaction => {
|
||||
const transactionTime = getUnixTime(parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value));
|
||||
const transactionTime = parseDateTimeFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value).getUnixTime();
|
||||
const type = getDisplayTransactionType(transaction);
|
||||
let categoryName = allCategoriesMap.value[transaction.categoryId]?.name || '';
|
||||
let displayAmount = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(transaction.sourceAmount);
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { type TransactionListFilter, type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
|
||||
|
||||
import type { TypeAndName } from '@/core/base.ts';
|
||||
import { type LocalizedDateRange, type WeekDayValue, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
||||
import { type TextualYearMonthDay, type Year0BasedMonth, type LocalizedDateRange, type WeekDayValue, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
||||
import { AccountType } from '@/core/account.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
||||
@@ -28,14 +28,10 @@ import {
|
||||
getLocalDatetimeFromUnixTime,
|
||||
getActualUnixTimeForStore,
|
||||
getDummyUnixTimeForLocalUsage,
|
||||
getCurrentYearAndMonth,
|
||||
parseDateFromUnixTime,
|
||||
getYearAndMonth,
|
||||
getYear,
|
||||
getMonth,
|
||||
getCurrentDateTime,
|
||||
parseDateTimeFromUnixTime,
|
||||
getYearMonthFirstUnixTime,
|
||||
getDay,
|
||||
getUnixTime,
|
||||
getUnixTimeFromLocalDatetime,
|
||||
isDateRangeMatchOneMonth
|
||||
} from '@/lib/datetime.ts';
|
||||
|
||||
@@ -99,7 +95,7 @@ export function useTransactionListPageBase() {
|
||||
const loading = ref<boolean>(true);
|
||||
const customMinDatetime = ref<number>(0);
|
||||
const customMaxDatetime = ref<number>(0);
|
||||
const currentCalendarDate = ref<string>('');
|
||||
const currentCalendarDate = ref<TextualYearMonthDay | ''>('');
|
||||
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
|
||||
@@ -175,12 +171,12 @@ 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 queryMonth = computed<string>(() => {
|
||||
const queryMonth = computed<Year0BasedMonth>(() => {
|
||||
if (!query.value.minTime || !query.value.maxTime) {
|
||||
return getCurrentYearAndMonth();
|
||||
return getCurrentDateTime().toGregorianCalendarYear0BasedMonth();
|
||||
}
|
||||
|
||||
return getYearAndMonth(parseDateFromUnixTime(query.value.minTime));
|
||||
return parseDateTimeFromUnixTime(query.value.minTime).toGregorianCalendarYear0BasedMonth();
|
||||
});
|
||||
|
||||
const queryAllFilterCategoryIds = computed<Record<string, boolean>>(() => transactionsStore.allFilterCategoryIds);
|
||||
@@ -248,9 +244,9 @@ export function useTransactionListPageBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
const currentMonthMinDate = parseDateFromUnixTime(query.value.minTime);
|
||||
const currentYear = getYear(currentMonthMinDate);
|
||||
const currentMonth = getMonth(currentMonthMinDate);
|
||||
const currentMonthMinDate = parseDateTimeFromUnixTime(query.value.minTime);
|
||||
const currentYear = currentMonthMinDate.getGregorianCalendarYear();
|
||||
const currentMonth = currentMonthMinDate.getGregorianCalendarMonth();
|
||||
|
||||
for (let i = 0; i < allTransactions.length; i++) {
|
||||
if (allTransactions[i].year === currentYear && allTransactions[i].month === currentMonth) {
|
||||
@@ -262,8 +258,8 @@ export function useTransactionListPageBase() {
|
||||
});
|
||||
|
||||
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 dateTime = parseDateTimeFromUnixTime(getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(date), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes()));
|
||||
return !currentMonthTransactionData.value || !currentMonthTransactionData.value.dailyTotalAmounts || !currentMonthTransactionData.value.dailyTotalAmounts[dateTime.getGregorianCalendarDay()];
|
||||
}
|
||||
|
||||
const canAddTransaction = computed<boolean>(() => {
|
||||
@@ -291,12 +287,11 @@ export function useTransactionListPageBase() {
|
||||
}
|
||||
|
||||
function getDisplayLongDate(transaction: Transaction): string {
|
||||
const transactionTime = getUnixTime(parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value));
|
||||
return formatUnixTimeToLongDate(transactionTime);
|
||||
return formatUnixTimeToLongDate(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
}
|
||||
|
||||
function getDisplayLongYearMonth(transactionMonthList: TransactionMonthList): string {
|
||||
return formatUnixTimeToLongYearMonth(getYearMonthFirstUnixTime(transactionMonthList.yearMonth));
|
||||
return formatUnixTimeToLongYearMonth(getYearMonthFirstUnixTime(transactionMonthList.yearDashMonth));
|
||||
}
|
||||
|
||||
function getDisplayTimezone(transaction: Transaction): string {
|
||||
|
||||
@@ -41,10 +41,7 @@ import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numera
|
||||
|
||||
import { type TransactionMonthlyIncomeAndExpenseData } from '@/models/transaction.ts';
|
||||
|
||||
import {
|
||||
parseDateFromUnixTime,
|
||||
getMonthName
|
||||
} from '@/lib/datetime.ts';
|
||||
import { parseDateTimeFromUnixTime } from '@/lib/datetime.ts';
|
||||
import { getExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
|
||||
|
||||
export interface MonthlyIncomeAndExpenseCardClickEvent {
|
||||
@@ -100,7 +97,7 @@ const chartOptions = computed<object>(() => {
|
||||
if (props.data) {
|
||||
for (let i = 0; i < props.data.length; i++) {
|
||||
const item = props.data[i];
|
||||
const month = getMonthName(parseDateFromUnixTime(item.monthStartTime));
|
||||
const month = parseDateTimeFromUnixTime(item.monthStartTime).getGregorianCalendarMonthName();
|
||||
|
||||
monthNames.push(getMonthShortName(month));
|
||||
incomeAmounts.push(item.incomeAmount);
|
||||
|
||||
@@ -358,7 +358,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { type TransactionStatisticsPartialFilter, useStatisticsStore } from '@/stores/statistics.ts';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import { type TextualYearMonth, type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import {
|
||||
StatisticsAnalysisType,
|
||||
@@ -375,7 +375,7 @@ import {
|
||||
arrayItemToObjectField
|
||||
} from '@/lib/common.ts';
|
||||
import {
|
||||
getYearAndMonthFromUnixTime,
|
||||
getGregorianCalendarYearAndMonthFromUnixTime,
|
||||
getYearMonthFirstUnixTime,
|
||||
getYearMonthLastUnixTime,
|
||||
getShiftedDateRangeAndDateType,
|
||||
@@ -407,8 +407,8 @@ interface TransactionStatisticsProps {
|
||||
initChartDataType?: string,
|
||||
initChartType?: string,
|
||||
initChartDateType?: string,
|
||||
initStartTime?: string,
|
||||
initEndTime?: string,
|
||||
initStartTime?: TextualYearMonth | '',
|
||||
initEndTime?: TextualYearMonth | '',
|
||||
initFilterAccountIds?: string,
|
||||
initFilterCategoryIds?: string,
|
||||
initTagIds?: string,
|
||||
@@ -814,8 +814,8 @@ function setDateFilter(dateType: number): void {
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
trendChartDateType: dateRange.dateType,
|
||||
trendChartStartYearMonth: getYearAndMonthFromUnixTime(dateRange.minTime),
|
||||
trendChartEndYearMonth: getYearAndMonthFromUnixTime(dateRange.maxTime)
|
||||
trendChartStartYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(dateRange.minTime),
|
||||
trendChartEndYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(dateRange.maxTime)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -826,7 +826,7 @@ function setDateFilter(dateType: number): void {
|
||||
}
|
||||
}
|
||||
|
||||
function setCustomDateFilter(startTime: number | string, endTime: number | string): void {
|
||||
function setCustomDateFilter(startTime: number | TextualYearMonth, endTime: number | TextualYearMonth): void {
|
||||
if (!startTime || !endTime) {
|
||||
return;
|
||||
}
|
||||
@@ -882,8 +882,8 @@ function shiftDateRange(scale: number): void {
|
||||
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
trendChartDateType: newDateRange.dateType,
|
||||
trendChartStartYearMonth: getYearAndMonthFromUnixTime(newDateRange.minTime),
|
||||
trendChartEndYearMonth: getYearAndMonthFromUnixTime(newDateRange.maxTime)
|
||||
trendChartStartYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(newDateRange.minTime),
|
||||
trendChartEndYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(newDateRange.maxTime)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -992,8 +992,8 @@ onBeforeRouteUpdate((to) => {
|
||||
initChartDataType: (to.query['chartDataType'] as string | null) || undefined,
|
||||
initChartType: (to.query['chartType'] as string | null) || undefined,
|
||||
initChartDateType: (to.query['chartDateType'] as string | null) || undefined,
|
||||
initStartTime: (to.query['startTime'] as string | null) || undefined,
|
||||
initEndTime: (to.query['endTime'] as string | null) || undefined,
|
||||
initStartTime: (to.query['startTime'] as TextualYearMonth | null) || undefined,
|
||||
initEndTime: (to.query['endTime'] as TextualYearMonth | null) || undefined,
|
||||
initFilterAccountIds: (to.query['filterAccountIds'] as string | null) || undefined,
|
||||
initFilterCategoryIds: (to.query['filterCategoryIds'] as string | null) || undefined,
|
||||
initTagIds: (to.query['tagIds'] as string | null) || undefined,
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text class="transaction-calendar-container pt-0" v-if="pageType === TransactionListPageType.Calendar.type">
|
||||
<vue-date-picker inline auto-apply model-type="yyyy-M-d"
|
||||
<vue-date-picker inline auto-apply model-type="yyyy-MM-dd"
|
||||
month-name-format="long"
|
||||
:config="{ noSwipe: true }"
|
||||
:readonly="loading"
|
||||
@@ -545,13 +545,13 @@
|
||||
:class="{ 'disabled': loading, 'has-bottom-border': idx < transactions.length - 1 }"
|
||||
v-for="(transaction, idx) in transactions">
|
||||
<tr class="transaction-list-row-date no-hover text-sm"
|
||||
v-if="pageType === TransactionListPageType.List.type && (idx === 0 || (idx > 0 && (transaction.date !== transactions[idx - 1].date)))">
|
||||
v-if="pageType === TransactionListPageType.List.type && (idx === 0 || (idx > 0 && (transaction.gregorianCalendarYearDashMonthDashDay !== transactions[idx - 1].gregorianCalendarYearDashMonthDashDay)))">
|
||||
<td :colspan="showTagInTransactionListPage ? 6 : 5" class="font-weight-bold">
|
||||
<div class="d-flex align-center">
|
||||
<span>{{ getDisplayLongDate(transaction) }}</span>
|
||||
<v-chip class="ms-1" color="default" size="x-small"
|
||||
v-if="transaction.dayOfWeek">
|
||||
{{ getWeekdayLongName(transaction.dayOfWeek) }}
|
||||
v-if="transaction.displayDayOfWeek">
|
||||
{{ getWeekdayLongName(transaction.displayDayOfWeek) }}
|
||||
</v-chip>
|
||||
</div>
|
||||
</td>
|
||||
@@ -689,6 +689,7 @@ import { useDesktopPageStore } from '@/stores/desktopPage.ts';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import {
|
||||
type Year0BasedMonth,
|
||||
type LocalizedRecentMonthDateRange,
|
||||
type TimeRangeAndDateType,
|
||||
DateRangeScene,
|
||||
@@ -710,9 +711,7 @@ import {
|
||||
} from '@/lib/common.ts';
|
||||
import {
|
||||
getCurrentUnixTime,
|
||||
parseDateFromUnixTime,
|
||||
getYear,
|
||||
getMonth,
|
||||
parseDateTimeFromUnixTime,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getActualUnixTimeForStore,
|
||||
getDayFirstUnixTimeBySpecifiedUnixTime,
|
||||
@@ -960,7 +959,7 @@ const transactions = computed<Transaction[]>(() => {
|
||||
for (let i = 0; i < transactionData.items.length; i++) {
|
||||
const transaction = transactionData.items[i];
|
||||
|
||||
if (transaction.date === currentCalendarDate.value) {
|
||||
if (transaction.gregorianCalendarYearDashMonthDashDay === currentCalendarDate.value) {
|
||||
transactions.push(transaction);
|
||||
}
|
||||
}
|
||||
@@ -1208,9 +1207,9 @@ function reload(force: boolean, init: boolean): void {
|
||||
}
|
||||
|
||||
if (queryMonthlyData.value) {
|
||||
const currentMonthMinDate = parseDateFromUnixTime(query.value.minTime);
|
||||
const currentYear = getYear(currentMonthMinDate);
|
||||
const currentMonth = getMonth(currentMonthMinDate);
|
||||
const currentMonthMinDate = parseDateTimeFromUnixTime(query.value.minTime);
|
||||
const currentYear = currentMonthMinDate.getGregorianCalendarYear();
|
||||
const currentMonth = currentMonthMinDate.getGregorianCalendarMonth();
|
||||
|
||||
return transactionsStore.loadMonthlyAllTransactions({
|
||||
year: currentYear,
|
||||
@@ -1362,7 +1361,7 @@ function changeCustomDateFilter(minTime: number, maxTime: number): void {
|
||||
updateUrlWhenChanged(changed);
|
||||
}
|
||||
|
||||
function changeCustomMonthDateFilter(yearMonth: string): void {
|
||||
function changeCustomMonthDateFilter(yearMonth: Year0BasedMonth): void {
|
||||
if (!yearMonth) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -936,8 +936,6 @@ import {
|
||||
import { generateRandomUUID } from '@/lib/misc.ts';
|
||||
import logger from '@/lib/logger.ts';
|
||||
import {
|
||||
parseDateFromUnixTime,
|
||||
getUnixTime,
|
||||
getUtcOffsetByUtcOffsetMinutes,
|
||||
getTimezoneOffsetMinutes
|
||||
} from '@/lib/datetime.ts';
|
||||
@@ -1655,8 +1653,7 @@ function isTagValid(tagIds: string[], tagIndex: number): boolean {
|
||||
}
|
||||
|
||||
function getDisplayDateTime(transaction: ImportTransaction): string {
|
||||
const transactionTime = getUnixTime(parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value));
|
||||
return formatUnixTimeToLongDateTime(transactionTime);
|
||||
return formatUnixTimeToLongDateTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||
}
|
||||
|
||||
function getDisplayTimezone(transaction: ImportTransaction): string {
|
||||
|
||||
@@ -125,7 +125,7 @@ import { useSettingsStore } from '@/stores/setting.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { FontSize } from '@/core/font.ts';
|
||||
import { getLocalDatetimeFromUnixTime, getCurrentUnixTime, getDay, getDayOfWeekName } from '@/lib/datetime.ts';
|
||||
import { parseDateTimeFromUnixTime, getCurrentUnixTime } from '@/lib/datetime.ts';
|
||||
import { setAppFontSize, getFontSizePreviewClassName } from '@/lib/ui/mobile.ts';
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -149,8 +149,8 @@ const fontSize = ref<number>(settingsStore.appSettings.fontSize);
|
||||
const textDirection = computed<string>(() => getCurrentLanguageTextDirection());
|
||||
const fontSizePreviewClassName = computed<string>(() => getFontSizePreviewClassName(fontSize.value));
|
||||
const currentLongYearMonth = computed<string>(() => formatUnixTimeToLongYearMonth(currentUnixTime.value));
|
||||
const currentDayOfMonth = computed<number>(() => getDay(getLocalDatetimeFromUnixTime(currentUnixTime.value)));
|
||||
const currentDayOfWeek = computed<string>(() => getWeekdayShortName(getDayOfWeekName(getLocalDatetimeFromUnixTime(currentUnixTime.value))));
|
||||
const currentDayOfMonth = computed<number>(() => parseDateTimeFromUnixTime(currentUnixTime.value).getLocalizedCalendarDay());
|
||||
const currentDayOfWeek = computed<string>(() => getWeekdayShortName(parseDateTimeFromUnixTime(currentUnixTime.value).getWeekDay()));
|
||||
const currentShortTime = computed<string>(() => formatUnixTimeToShortTime(currentUnixTime.value));
|
||||
|
||||
function getFontSizeName(): string {
|
||||
|
||||
@@ -344,7 +344,7 @@ import { useStatisticsStore } from '@/stores/statistics.ts';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import { type TextualYearMonth, type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import {
|
||||
StatisticsAnalysisType,
|
||||
CategoricalChartType,
|
||||
@@ -355,7 +355,7 @@ import {
|
||||
|
||||
import { isString, isNumber } from '@/lib/common.ts';
|
||||
import {
|
||||
getYearAndMonthFromUnixTime,
|
||||
getGregorianCalendarYearAndMonthFromUnixTime,
|
||||
getYearMonthFirstUnixTime,
|
||||
getYearMonthLastUnixTime,
|
||||
getShiftedDateRangeAndDateType,
|
||||
@@ -626,8 +626,8 @@ function setDateFilter(dateType: number): void {
|
||||
} else if (analysisType.value === StatisticsAnalysisType.TrendAnalysis) {
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
trendChartDateType: dateRange.dateType,
|
||||
trendChartStartYearMonth: getYearAndMonthFromUnixTime(dateRange.minTime),
|
||||
trendChartEndYearMonth: getYearAndMonthFromUnixTime(dateRange.maxTime)
|
||||
trendChartStartYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(dateRange.minTime),
|
||||
trendChartEndYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(dateRange.maxTime)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@ function setDateFilter(dateType: number): void {
|
||||
}
|
||||
}
|
||||
|
||||
function setCustomDateFilter(startTime: number | string, endTime: number | string): void {
|
||||
function setCustomDateFilter(startTime: number | TextualYearMonth, endTime: number | TextualYearMonth): void {
|
||||
if (!startTime || !endTime) {
|
||||
return;
|
||||
}
|
||||
@@ -692,8 +692,8 @@ function shiftDateRange(scale: number): void {
|
||||
|
||||
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||
trendChartDateType: newDateRange.dateType,
|
||||
trendChartStartYearMonth: getYearAndMonthFromUnixTime(newDateRange.minTime),
|
||||
trendChartEndYearMonth: getYearAndMonthFromUnixTime(newDateRange.maxTime)
|
||||
trendChartStartYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(newDateRange.minTime),
|
||||
trendChartEndYearMonth: getGregorianCalendarYearAndMonthFromUnixTime(newDateRange.maxTime)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -536,7 +536,7 @@ const {
|
||||
getMultiWeekdayLongNames,
|
||||
formatUnixTimeToLongDate,
|
||||
formatUnixTimeToLongTime,
|
||||
formatDateToLongDate
|
||||
formatGregorianCalendarYearDashMonthDashDayToLongDate
|
||||
} = useI18n();
|
||||
const { showAlert, showConfirm, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
@@ -754,7 +754,7 @@ const transactionDisplayScheduledStartDate = computed<string>(() => {
|
||||
const template = transaction.value as TransactionTemplate;
|
||||
|
||||
if (template.scheduledStartDate) {
|
||||
return formatDateToLongDate(template.scheduledStartDate);
|
||||
return formatGregorianCalendarYearDashMonthDashDayToLongDate(template.scheduledStartDate);
|
||||
} else {
|
||||
return tt('No limit');
|
||||
}
|
||||
@@ -768,7 +768,7 @@ const transactionDisplayScheduledEndDate = computed<string>(() => {
|
||||
const template = transaction.value as TransactionTemplate;
|
||||
|
||||
if (template.scheduledEndDate) {
|
||||
return formatDateToLongDate(template.scheduledEndDate);
|
||||
return formatGregorianCalendarYearDashMonthDashDayToLongDate(template.scheduledEndDate);
|
||||
} else {
|
||||
return tt('No limit');
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
</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"
|
||||
<vue-date-picker inline auto-apply model-type="yyyy-MM-dd"
|
||||
month-name-format="long"
|
||||
class="justify-content-center"
|
||||
:config="{ noSwipe: true }"
|
||||
@@ -174,13 +174,13 @@
|
||||
</f7-list>
|
||||
|
||||
<f7-block class="combination-list-wrapper margin-vertical" :class="{ 'no-accordion-toggle': pageType !== TransactionListPageType.List.type }"
|
||||
:key="transactionMonthList.yearMonth" v-for="(transactionMonthList) in transactions">
|
||||
:key="transactionMonthList.yearDashMonth" v-for="(transactionMonthList) in transactions">
|
||||
<f7-accordion-item :opened="transactionMonthList.opened"
|
||||
@accordion:open="collapseTransactionMonthList(transactionMonthList, false)"
|
||||
@accordion:opened="onTransactionMonthListCollapseStateChanged"
|
||||
@accordion:close="collapseTransactionMonthList(transactionMonthList, true)"
|
||||
@accordion:closed="onTransactionMonthListCollapseStateChanged">
|
||||
<f7-block-title :id="getTransactionMonthTitleDomId(transactionMonthList.yearMonth)" v-if="pageType === TransactionListPageType.List.type">
|
||||
<f7-block-title :id="getTransactionMonthTitleDomId(transactionMonthList.yearDashMonth)" v-if="pageType === TransactionListPageType.List.type">
|
||||
<f7-accordion-toggle>
|
||||
<f7-list strong inset dividers media-list
|
||||
class="transaction-amount-list combination-list-header"
|
||||
@@ -209,7 +209,7 @@
|
||||
v-if="isTransactionMonthListInvisible(transactionMonthList)" />
|
||||
<f7-list strong inset dividers media-list accordion-list
|
||||
class="transaction-info-list transaction-month-list combination-list-content"
|
||||
:id="getTransactionMonthListDomId(transactionMonthList.yearMonth)"
|
||||
:id="getTransactionMonthListDomId(transactionMonthList.yearDashMonth)"
|
||||
v-if="!isTransactionMonthListInvisible(transactionMonthList)"
|
||||
>
|
||||
<f7-list-item swipeout chevron-center accordion-item
|
||||
@@ -222,10 +222,10 @@
|
||||
<template #media>
|
||||
<div class="display-flex flex-direction-column transaction-date" :style="getTransactionDateStyle(transaction, idx > 0 ? transactionMonthList.items[idx - 1] : null)">
|
||||
<span class="transaction-day full-line flex-direction-column">
|
||||
{{ transaction.day }}
|
||||
{{ transaction.gregorianCalendarDayOfMonth }}
|
||||
</span>
|
||||
<span class="transaction-day-of-week full-line flex-direction-column" v-if="transaction.dayOfWeek">
|
||||
{{ getWeekdayShortName(transaction.dayOfWeek) }}
|
||||
<span class="transaction-day-of-week full-line flex-direction-column" v-if="transaction.displayDayOfWeek">
|
||||
{{ getWeekdayShortName(transaction.displayDayOfWeek) }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -620,9 +620,11 @@ import { type TransactionMonthList, useTransactionsStore } from '@/stores/transa
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import {
|
||||
type TextualYearMonth,
|
||||
type Year0BasedMonth,
|
||||
type TimeRangeAndDateType,
|
||||
DateRangeScene,
|
||||
DateRange,
|
||||
DateRange
|
||||
} from '@/core/datetime.ts';
|
||||
import { AmountFilterType } from '@/core/numeral.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
@@ -635,11 +637,9 @@ import {
|
||||
} from '@/lib/common.ts';
|
||||
import {
|
||||
getCurrentUnixTime,
|
||||
parseDateFromUnixTime,
|
||||
parseDateTimeFromUnixTime,
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getActualUnixTimeForStore,
|
||||
getYear,
|
||||
getMonth,
|
||||
getDayFirstUnixTimeBySpecifiedUnixTime,
|
||||
getYearMonthFirstUnixTime,
|
||||
getYearMonthLastUnixTime,
|
||||
@@ -731,8 +731,8 @@ const transactionsStore = useTransactionsStore();
|
||||
const loadingError = ref<unknown | null>(null);
|
||||
const loadingMore = ref<boolean>(false);
|
||||
const transactionToDelete = ref<Transaction | null>(null);
|
||||
const transactionInvisibleYearMonths = ref<Record<string, boolean>>({});
|
||||
const transactionYearMonthListHeights = ref<Record<string, number>>({});
|
||||
const transactionInvisibleYearMonths = ref<Record<TextualYearMonth, boolean>>({});
|
||||
const transactionYearMonthListHeights = ref<Record<TextualYearMonth, number>>({});
|
||||
const showTransactionListPageTypePopover = ref<boolean>(false);
|
||||
const showDatePopover = ref<boolean>(false);
|
||||
const showCategoryPopover = ref<boolean>(false);
|
||||
@@ -768,7 +768,7 @@ const transactions = computed<TransactionMonthList[]>(() => {
|
||||
for (let i = 0; i < transactionData.items.length; i++) {
|
||||
const transaction = transactionData.items[i];
|
||||
|
||||
if (transaction.date === currentCalendarDate.value) {
|
||||
if (transaction.gregorianCalendarYearDashMonthDashDay === currentCalendarDate.value) {
|
||||
transactions.push(transaction);
|
||||
}
|
||||
}
|
||||
@@ -776,7 +776,7 @@ const transactions = computed<TransactionMonthList[]>(() => {
|
||||
const dailyTransactionList: TransactionMonthList = {
|
||||
year: currentMonthTransactionData.value.year,
|
||||
month: currentMonthTransactionData.value.month,
|
||||
yearMonth: currentMonthTransactionData.value.yearMonth,
|
||||
yearDashMonth: currentMonthTransactionData.value.yearDashMonth,
|
||||
opened: true,
|
||||
items: transactions,
|
||||
totalAmount: {
|
||||
@@ -809,11 +809,11 @@ const noTransaction = computed<boolean>(() => {
|
||||
|
||||
const hasMoreTransaction = computed<boolean>(() => transactionsStore.hasMoreTransaction);
|
||||
|
||||
function getTransactionMonthTitleDomId(yearMonth: string): string {
|
||||
function getTransactionMonthTitleDomId(yearMonth: TextualYearMonth): string {
|
||||
return 'transaction_month_title_' + yearMonth;
|
||||
}
|
||||
|
||||
function getTransactionMonthListDomId(yearMonth: string): string {
|
||||
function getTransactionMonthListDomId(yearMonth: TextualYearMonth): string {
|
||||
return 'transaction_month_list_' + yearMonth;
|
||||
}
|
||||
|
||||
@@ -822,7 +822,7 @@ function getTransactionDomId(transaction: Transaction): string {
|
||||
}
|
||||
|
||||
function isTransactionMonthListInvisible(transactionMonthList: TransactionMonthList): boolean {
|
||||
if (!transactionYearMonthListHeights.value[transactionMonthList.yearMonth]) {
|
||||
if (!transactionYearMonthListHeights.value[transactionMonthList.yearDashMonth]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -830,7 +830,7 @@ function isTransactionMonthListInvisible(transactionMonthList: TransactionMonthL
|
||||
return true;
|
||||
}
|
||||
|
||||
if (transactionInvisibleYearMonths.value[transactionMonthList.yearMonth]) {
|
||||
if (transactionInvisibleYearMonths.value[transactionMonthList.yearDashMonth]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -839,7 +839,7 @@ function isTransactionMonthListInvisible(transactionMonthList: TransactionMonthL
|
||||
|
||||
function getTransactionMonthListHeight(transactionMonthList: TransactionMonthList): string {
|
||||
if (isTransactionMonthListInvisible(transactionMonthList)) {
|
||||
return transactionYearMonthListHeights.value[transactionMonthList.yearMonth] + 'px';
|
||||
return transactionYearMonthListHeights.value[transactionMonthList.yearDashMonth] + 'px';
|
||||
}
|
||||
|
||||
return 'auto';
|
||||
@@ -857,12 +857,12 @@ function setTransactionMonthListHeights(reset: boolean): Promise<unknown> {
|
||||
|
||||
for (let i = 0; i < transactions.value.length - 1; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
const yearMonth = transactionMonthList.yearMonth;
|
||||
const domId = getTransactionMonthListDomId(yearMonth);
|
||||
const yearDashMonth = transactionMonthList.yearDashMonth;
|
||||
const domId = getTransactionMonthListDomId(yearDashMonth);
|
||||
const height = heights[domId];
|
||||
|
||||
if (!transactionYearMonthListHeights.value[yearMonth] && isNumber(height)) {
|
||||
transactionYearMonthListHeights.value[yearMonth] = height;
|
||||
if (!transactionYearMonthListHeights.value[yearDashMonth] && isNumber(height)) {
|
||||
transactionYearMonthListHeights.value[yearDashMonth] = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -876,30 +876,30 @@ function setTransactionInvisibleYearMonthList(): void {
|
||||
|
||||
for (let i = 0; i < transactions.value.length - 1; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
const yearMonth = transactionMonthList.yearMonth;
|
||||
const yearDashMonth = transactionMonthList.yearDashMonth;
|
||||
|
||||
const titleDomId = getTransactionMonthTitleDomId(yearMonth);
|
||||
const titleDomId = getTransactionMonthTitleDomId(yearDashMonth);
|
||||
const titleRect = getElementBoundingRect(`#${titleDomId}`);
|
||||
|
||||
if (!titleRect) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const listHeight = transactionYearMonthListHeights.value[yearMonth] || 0;
|
||||
const listHeight = transactionYearMonthListHeights.value[yearDashMonth] || 0;
|
||||
const listRectTop = titleRect.top + titleRect.height;
|
||||
const listRectBottom = listRectTop + listHeight;
|
||||
const invisible = listRectTop > 2 * window.innerHeight || listRectBottom < -2 * window.innerHeight;
|
||||
|
||||
if (invisible) {
|
||||
transactionInvisibleYearMonths.value[yearMonth] = true;
|
||||
transactionInvisibleYearMonths.value[yearDashMonth] = true;
|
||||
} else {
|
||||
delete transactionInvisibleYearMonths.value[yearMonth];
|
||||
delete transactionInvisibleYearMonths.value[yearDashMonth];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTransactionDateStyle(transaction: Transaction, previousTransaction: Transaction | null): Record<string, string> {
|
||||
if (!previousTransaction || transaction.day !== previousTransaction.day) {
|
||||
if (!previousTransaction || transaction.gregorianCalendarDayOfMonth !== previousTransaction.gregorianCalendarDayOfMonth) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -974,9 +974,9 @@ function reload(done?: () => void): void {
|
||||
transactionTagsStore.loadAllTags({ force: false })
|
||||
]).then(() => {
|
||||
if (queryMonthlyData.value) {
|
||||
const currentMonthMinDate = parseDateFromUnixTime(query.value.minTime);
|
||||
const currentYear = getYear(currentMonthMinDate);
|
||||
const currentMonth = getMonth(currentMonthMinDate);
|
||||
const currentMonthMinDate = parseDateTimeFromUnixTime(query.value.minTime);
|
||||
const currentYear = currentMonthMinDate.getGregorianCalendarYear();
|
||||
const currentMonth = currentMonthMinDate.getGregorianCalendarMonth();
|
||||
|
||||
return transactionsStore.loadMonthlyAllTransactions({
|
||||
year: currentYear,
|
||||
@@ -1159,7 +1159,7 @@ function changeCustomDateFilter(minTime: number, maxTime: number): void {
|
||||
}
|
||||
}
|
||||
|
||||
function changeCustomMonthDateFilter(yearMonth: string): void {
|
||||
function changeCustomMonthDateFilter(yearMonth: Year0BasedMonth): void {
|
||||
if (!yearMonth) {
|
||||
return;
|
||||
}
|
||||
@@ -1466,8 +1466,8 @@ function collapseTransactionMonthList(monthList: TransactionMonthList, collapse:
|
||||
collapse: collapse
|
||||
});
|
||||
|
||||
if (!collapse && transactionInvisibleYearMonths.value[monthList.yearMonth]) {
|
||||
delete transactionInvisibleYearMonths.value[monthList.yearMonth];
|
||||
if (!collapse && transactionInvisibleYearMonths.value[monthList.yearDashMonth]) {
|
||||
delete transactionInvisibleYearMonths.value[monthList.yearDashMonth];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user