From c73dcb51e42910fc6870400707f18d280e4dade7 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sat, 11 Jan 2025 17:57:14 +0800 Subject: [PATCH] migrate month range selection sheet / dialog to composition API and typescript --- .../base/MonthRangeSelectionBase.ts | 99 ++++++++++ .../desktop/MonthRangeSelectionDialog.vue | 176 +++++++----------- .../mobile/MonthRangeSelectionSheet.vue | 162 ++++++---------- src/lib/datetime.ts | 9 + .../desktop/statistics/TransactionPage.vue | 3 +- 5 files changed, 236 insertions(+), 213 deletions(-) create mode 100644 src/components/base/MonthRangeSelectionBase.ts diff --git a/src/components/base/MonthRangeSelectionBase.ts b/src/components/base/MonthRangeSelectionBase.ts new file mode 100644 index 00000000..2d4aa6e9 --- /dev/null +++ b/src/components/base/MonthRangeSelectionBase.ts @@ -0,0 +1,99 @@ +import { ref, computed } from 'vue'; + +import type { YearMonth } from '@/core/datetime.ts'; + +import { + getYearMonthObjectFromUnixTime, + getYearMonthObjectFromString, + getYearMonthStringFromObject, + getCurrentUnixTime, + getCurrentYear, + getThisYearFirstUnixTime, + getYearMonthFirstUnixTime, + getYearMonthLastUnixTime +} from '@/lib/datetime.ts'; + +import { useI18n } from '@/locales/helpers.ts'; + +export interface CommonMonthRangeSelectionProps { + minTime?: string; + maxTime?: string; + title?: string; + hint?: string; + show: boolean; +} + +function getMonthRangeFromProps(props: CommonMonthRangeSelectionProps): { minDate: YearMonth; maxDate: YearMonth } { + let minDate: YearMonth = getYearMonthObjectFromUnixTime(getThisYearFirstUnixTime()); + let maxDate: YearMonth = getYearMonthObjectFromUnixTime(getCurrentUnixTime()); + + if (props.minTime) { + const yearMonth = getYearMonthObjectFromString(props.minTime); + + if (yearMonth) { + minDate = yearMonth; + } + } + + if (props.maxTime) { + const yearMonth = getYearMonthObjectFromString(props.maxTime); + + if (yearMonth) { + maxDate = yearMonth; + } + } + + return { + minDate, + maxDate + }; +} + +export function useMonthRangeSelectionBase(props: CommonMonthRangeSelectionProps) { + const { formatUnixTimeToLongYearMonth, isLongDateMonthAfterYear } = useI18n(); + const { minDate, maxDate } = getMonthRangeFromProps(props); + + const yearRange = ref([ + 2000, + getCurrentYear() + 1 + ]); + + const dateRange = ref([ + minDate, + maxDate + ]); + + const isYearFirst = computed(() => isLongDateMonthAfterYear()); + const beginDateTime = computed(() => formatUnixTimeToLongYearMonth(getYearMonthFirstUnixTime(dateRange.value[0]))); + const endDateTime = computed(() => formatUnixTimeToLongYearMonth(getYearMonthLastUnixTime(dateRange.value[1]))); + + function getFinalMonthRange(): { minYearMonth: string, maxYearMonth: string } | null { + if (!dateRange.value[0] || !dateRange.value[1]) { + return null; + } + + if (dateRange.value[0].year <= 0 || dateRange.value[0].month < 0 || dateRange.value[1].year <= 0 || dateRange.value[1].month < 0) { + throw new Error('Date is too early'); + } + + const minYearMonth = getYearMonthStringFromObject(dateRange.value[0]); + const maxYearMonth = getYearMonthStringFromObject(dateRange.value[1]); + + return { + minYearMonth, + maxYearMonth + }; + } + + return { + // states + yearRange, + dateRange, + // computed states + isYearFirst, + beginDateTime, + endDateTime, + // functions + getFinalMonthRange + }; +} diff --git a/src/components/desktop/MonthRangeSelectionDialog.vue b/src/components/desktop/MonthRangeSelectionDialog.vue index 80ddd9a7..a4756994 100644 --- a/src/components/desktop/MonthRangeSelectionDialog.vue +++ b/src/components/desktop/MonthRangeSelectionDialog.vue @@ -26,7 +26,7 @@ :dark="isDarkMode" :year-range="yearRange" :year-first="isYearFirst" - v-model="startTime"> + v-model="dateRange[0]"> @@ -42,7 +42,7 @@ :dark="isDarkMode" :year-range="yearRange" :year-first="isYearFirst" - v-model="endTime"> + v-model="dateRange[1]"> @@ -55,132 +55,86 @@
- {{ $t('OK') }} - {{ $t('Cancel') }} + {{ tt('OK') }} + {{ tt('Cancel') }}
-