Browse Source

fix(nc-gui): use dayjs

pull/7611/head
DarkPhoenix2704 8 months ago
parent
commit
0b657a86e3
  1. 77
      packages/nc-gui/components/nc/DateWeekSelector.vue
  2. 126
      packages/nc-gui/components/nc/MonthYearSelector.vue

77
packages/nc-gui/components/nc/DateWeekSelector.vue

@ -1,4 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import dayjs from 'dayjs'
interface Props { interface Props {
selectedDate?: Date | null selectedDate?: Date | null
isDisabled?: boolean isDisabled?: boolean
@ -43,92 +44,90 @@ const currentMonth = computed(() => {
return `${pageDate.value.toLocaleString('default', { month: 'long' })} ${pageDate.value.getFullYear()}` return `${pageDate.value.toLocaleString('default', { month: 'long' })} ${pageDate.value.getFullYear()}`
}) })
const selectWeek = (date: Date) => { const selectWeek = (date: dayjs.Dayjs) => {
if (!date) return if (!date) return
const dayOffset = props.isMondayFirst ? 1 : 0 const dayOffset = props.isMondayFirst ? 1 : 0
const dayOfWeek = (date.getDay() - dayOffset + 7) % 7 const dayOfWeek = (date.get('day') - dayOffset + 7) % 7
const startDate = new Date(date) const startDate = date.subtract(dayOfWeek, 'day')
startDate.setDate(date.getDate() - dayOfWeek)
selectedWeek.value = { selectedWeek.value = {
start: startDate, start: startDate.toDate(),
end: new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + 6), end: startDate.endOf('week').toDate(),
} }
} }
// Generates all dates should be displayed in the calendar // Generates all dates should be displayed in the calendar
// Includes all blank days at the start and end of the month // Includes all blank days at the start and end of the month
const dates = computed(() => { const dates = computed(() => {
const startOfMonth = new Date(pageDate.value.getFullYear(), pageDate.value.getMonth(), 1) const startOfMonth = dayjs(pageDate.value).startOf('month')
const dayOffset = props.isMondayFirst ? 1 : 0 const dayOffset = props.isMondayFirst ? 1 : 0
const dayOfWeek = (startOfMonth.getDay() - dayOffset + 7) % 7 const firstDayOfWeek = startOfMonth.day()
startOfMonth.setDate(startOfMonth.getDate() - dayOfWeek) const startDay = startOfMonth.subtract((firstDayOfWeek - dayOffset + 7) % 7, 'day')
const datesArray = [] const datesArray = []
while (datesArray.length < 42) { for (let i = 0; i < 42; i++) {
datesArray.push(new Date(startOfMonth)) datesArray.push(startDay.add(i, 'day'))
startOfMonth.setDate(startOfMonth.getDate() + 1)
} }
return datesArray return datesArray
}) })
// Check if the date is in the selected week // Check if the date is in the selected week
const isDateInSelectedWeek = (date: Date) => { const isDateInSelectedWeek = (date: dayjs.Dayjs) => {
if (!selectedWeek.value) return false if (!selectedWeek.value) return false
return date >= selectedWeek.value.start && date <= selectedWeek.value.end return date.isBetween(selectedWeek.value.start, selectedWeek.value.end, 'day', '[]')
} }
// Used to check if two dates are the same // Used to check if two dates are the same
const isSameDate = (date1: Date, date2: Date) => { const isSameDate = (date1: dayjs.Dayjs, date2: dayjs.Dayjs) => {
if (!date1 || !date2) return false if (!date1 || !date2) return false
return ( return date1.isSame(date2, 'day')
date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear()
)
} }
// Used in DatePicker for checking if the date is currently selected // Used in DatePicker for checking if the date is currently selected
const isSelectedDate = (dObj: Date) => { const isSelectedDate = (dObj: dayjs.Dayjs) => {
if (!selectedDate.value) return false if (!selectedDate.value) return false
const propDate = new Date(selectedDate.value) const propDate = dayjs(selectedDate.value)
return props.selectedDate ? isSameDate(propDate, dObj) : false return props.selectedDate ? isSameDate(propDate, dObj) : false
} }
const isDayInPagedMonth = (date: Date) => { const isDayInPagedMonth = (date: dayjs.Dayjs) => {
return date.getMonth() === pageDate.value.getMonth() return date.month() === pageDate.value.getMonth()
} }
// Since we are using the same component for week picker and date picker we need to handle the date selection differently // Since we are using the same component for week picker and date picker we need to handle the date selection differently
const handleSelectDate = (date: Date) => { const handleSelectDate = (date: dayjs.Dayjs) => {
if (props.weekPicker) { if (props.weekPicker) {
selectWeek(date) selectWeek(date)
} else { } else {
if (!isDayInPagedMonth(date)) { if (!isDayInPagedMonth(date)) {
pageDate.value = new Date(date) pageDate.value = date.toDate()
emit('update:pageDate', date) emit('update:pageDate', date.toDate())
} }
selectedDate.value = date selectedDate.value = date.toDate()
emit('update:selectedDate', date) emit('update:selectedDate', date.toDate())
} }
} }
// Used to check if a date is in the current month // Used to check if a date is in the current month
const isDateInCurrentMonth = (date: Date) => { const isDateInCurrentMonth = (date: dayjs.Dayjs) => {
return date.getMonth() === pageDate.value.getMonth() return date.month() === pageDate.value.getMonth()
} }
// Used to Check if an event is in the date // Used to Check if an event is in the date
const isActiveDate = (date: Date) => { const isActiveDate = (date: dayjs.Dayjs) => {
return activeDates.value.some((d) => isSameDate(d, date)) return activeDates.value.some((d) => isSameDate(dayjs(d), date))
} }
// Paginate the calendar // Paginate the calendar
const paginate = (action: 'next' | 'prev') => { const paginate = (action: 'next' | 'prev') => {
const newDate = new Date(pageDate.value) let newDate = dayjs(pageDate.value)
if (action === 'next') { if (action === 'next') {
newDate.setMonth(newDate.getMonth() + 1) newDate = newDate.add(1, 'month').clone()
} else { } else {
newDate.setMonth(newDate.getMonth() - 1) newDate = newDate.subtract(1, 'month').clone()
} }
pageDate.value = newDate pageDate.value = newDate.toDate()
emit('update:pageDate', newDate) emit('update:pageDate', newDate.toDate())
} }
</script> </script>
@ -163,15 +162,15 @@ const paginate = (action: 'next' | 'prev') => {
'hover:(border-1 border-gray-200 bg-gray-100)': !isSelectedDate(date) && !weekPicker, 'hover:(border-1 border-gray-200 bg-gray-100)': !isSelectedDate(date) && !weekPicker,
'nc-selected-week z-1': isDateInSelectedWeek(date) && weekPicker, 'nc-selected-week z-1': isDateInSelectedWeek(date) && weekPicker,
'text-gray-400': !isDateInCurrentMonth(date), 'text-gray-400': !isDateInCurrentMonth(date),
'nc-selected-week-start': isSameDate(date, selectedWeek?.start), 'nc-selected-week-start': isSameDate(date, dayjs(selectedWeek?.start)),
'nc-selected-week-end': isSameDate(date, selectedWeek?.end), 'nc-selected-week-end': isSameDate(date, dayjs(selectedWeek?.end)),
}" }"
class="h-9 w-9 px-1 py-2 relative font-medium flex items-center cursor-pointer justify-center" class="h-9 w-9 px-1 py-2 relative font-medium flex items-center cursor-pointer justify-center"
@click="handleSelectDate(date)" @click="handleSelectDate(date)"
> >
<span v-if="isActiveDate(date)" class="absolute z-2 h-1.5 w-1.5 rounded-full bg-brand-500 top-1 right-1"></span> <span v-if="isActiveDate(date)" class="absolute z-2 h-1.5 w-1.5 rounded-full bg-brand-500 top-1 right-1"></span>
<span class="z-2"> <span class="z-2">
{{ date.getDate() }} {{ date.get('date') }}
</span> </span>
</span> </span>
</div> </div>

126
packages/nc-gui/components/nc/MonthYearSelector.vue

@ -1,4 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import dayjs from 'dayjs'
interface Props { interface Props {
selectedDate?: Date | null selectedDate?: Date | null
isDisabled?: boolean isDisabled?: boolean
@ -12,20 +14,16 @@ const props = withDefaults(defineProps<Props>(), {
pageDate: new Date(), pageDate: new Date(),
yearPicker: false, yearPicker: false,
}) })
const emit = defineEmits(['update:selected-date', 'update:page-date']) const emit = defineEmits(['update:selectedDate', 'update:pageDate'])
const pageDate = useVModel(props, 'pageDate', emit) const pageDate = useVModel(props, 'pageDate', emit)
const selectedDate = useVModel(props, 'selectedDate', emit) const selectedDate = useVModel(props, 'selectedDate', emit)
const years = computed(() => { const years = computed(() => {
const date = new Date(pageDate.value) const date = dayjs(pageDate.value)
const startYear = date.getFullYear() const startOfYear = date.startOf('year')
const endYear = date.getFullYear() + 11 const years: dayjs.Dayjs[] = []
const years = [] for (let i = 0; i < 12; i++) {
for (let i = startYear; i <= endYear; i++) { years.push(dayjs(startOfYear).add(i, 'year'))
years.push({
label: i,
value: new Date(i, 0, 1),
})
} }
return years return years
}) })
@ -35,87 +33,45 @@ const currentYear = computed(() => {
}) })
const months = computed(() => { const months = computed(() => {
const date = new Date(pageDate.value) const date = dayjs(pageDate.value)
return [
{ const months: dayjs.Dayjs[] = []
label: 'January', for (let i = 0; i < 12; i++) {
value: new Date(date.getFullYear(), 0, 1), months.push(date.add(i, 'month'))
}, }
{ return months
label: 'February',
value: new Date(date.getFullYear(), 1, 1),
},
{
label: 'March',
value: new Date(date.getFullYear(), 2, 1),
},
{
label: 'April',
value: new Date(date.getFullYear(), 3, 1),
},
{
label: 'May',
value: new Date(date.getFullYear(), 4, 1),
},
{
label: 'June',
value: new Date(date.getFullYear(), 5, 1),
},
{
label: 'July',
value: new Date(date.getFullYear(), 6, 1),
},
{
label: 'August',
value: new Date(date.getFullYear(), 7, 1),
},
{
label: 'September',
value: new Date(date.getFullYear(), 8, 1),
},
{
label: 'October',
value: new Date(date.getFullYear(), 9, 1),
},
{
label: 'November',
value: new Date(date.getFullYear(), 10, 1),
},
{
label: 'December',
value: new Date(date.getFullYear(), 11, 1),
},
]
}) })
const compareDates = (date1: Date, date2: Date) => { const compareDates = (date1: dayjs.Dayjs, date2: dayjs.Dayjs) => {
if (!date1 || !date2) return false if (!date1 || !date2) return false
return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() return date1.isSame(date2, 'month') && date1.isSame(date2, 'year')
} }
const isMonthSelected = (date: Date) => { const isMonthSelected = (date: dayjs.Dayjs) => {
if (!selectedDate.value) return false if (!selectedDate.value) return false
return compareDates(date, selectedDate.value) return compareDates(date, dayjs(selectedDate.value))
} }
const paginateMonth = (action: 'next' | 'prev') => { const paginateMonth = (action: 'next' | 'prev') => {
const date = new Date(pageDate.value) const date = dayjs(pageDate.value)
if (action === 'next') { if (action === 'next') {
date.setFullYear(date.getFullYear() + 1) date.add(1, 'month')
} else { } else {
date.setFullYear(date.getFullYear() - 1) date.subtract(1, 'month')
} }
pageDate.value = date pageDate.value = date.toDate()
emit('update:pageDate', date.toDate())
} }
const paginateYear = (action: 'next' | 'prev') => { const paginateYear = (action: 'next' | 'prev') => {
const date = new Date(pageDate.value) let date = dayjs(pageDate.value)
if (action === 'next') { if (action === 'next') {
date.setFullYear(date.getFullYear() + 12) date = date.add(1, 'year').clone()
} else { } else {
date.setFullYear(date.getFullYear() - 12) date = date.subtract(1, 'year').clone()
} }
pageDate.value = date pageDate.value = date.toDate()
emit('update:pageDate', date.toDate())
} }
const paginate = (action: 'next' | 'prev') => { const paginate = (action: 'next' | 'prev') => {
@ -126,9 +82,9 @@ const paginate = (action: 'next' | 'prev') => {
} }
} }
const compareYear = (date1: Date, date2: Date) => { const compareYear = (date1: dayjs.Dayjs, date2: dayjs.Dayjs) => {
if (!date1 || !date2) return false if (!date1 || !date2) return false
return date1.getFullYear() === date2.getFullYear() return date1.isSame(date2, 'year')
} }
</script> </script>
@ -147,28 +103,28 @@ const compareYear = (date1: Date, date2: Date) => {
<div class="grid grid-cols-4 gap-2 p-2"> <div class="grid grid-cols-4 gap-2 p-2">
<template v-if="!yearPicker"> <template v-if="!yearPicker">
<span <span
v-for="month in months" v-for="(month, id) in months"
:key="month.value" :key="id"
:class="{ :class="{
'!bg-brand-50 !border-2 !border-brand-500': isMonthSelected(month.value), '!bg-brand-50 !border-2 !border-brand-500': isMonthSelected(month),
}" }"
class="h-9 rounded-lg flex font-medium items-center justify-center hover:(border-1 border-gray-200 bg-gray-100) text-gray-500 cursor-pointer" class="h-9 rounded-lg flex font-medium items-center justify-center hover:(border-1 border-gray-200 bg-gray-100) text-gray-500 cursor-pointer"
@click="selectedDate = month.value" @click="selectedDate = month.toDate()"
> >
{{ month.label.slice(0, 3) }} {{ month.format('MMM') }}
</span> </span>
</template> </template>
<template v-else> <template v-else>
<span <span
v-for="year in years" v-for="(year, id) in years"
:key="year" :key="id"
:class="{ :class="{
'!bg-brand-50 !border-2 !border-brand-500': compareYear(year.value, selectedDate), '!bg-brand-50 !border-2 !border-brand-500': compareYear(year, dayjs(selectedDate)),
}" }"
class="h-9 rounded-lg flex font-medium items-center justify-center hover:(border-1 border-gray-200 bg-gray-100) text-gray-500 cursor-pointer" class="h-9 rounded-lg flex font-medium items-center justify-center hover:(border-1 border-gray-200 bg-gray-100) text-gray-500 cursor-pointer"
@click="selectedDate = year.value" @click="selectedDate = year.toDate()"
> >
{{ year.label }} {{ year.format('YYYY') }}
</span> </span>
</template> </template>
</div> </div>

Loading…
Cancel
Save