feat: add date math for filters #1342

Merged
konrad merged 88 commits from feature/date-math into main 2022-03-28 17:30:43 +00:00
2 changed files with 97 additions and 9 deletions
Showing only changes of commit 8f8d25ece1 - Show all commits

View File

@ -4,13 +4,25 @@
<button @click="setDateRange(datesToday)" :class="{'is-active': dateRange === datesToday}">
{{ $t('task.show.today') }}
konrad marked this conversation as resolved Outdated

Provide buttonText as slot prop aswell

Provide `buttonText` as slot prop aswell

Done.

Done.
</button>
konrad marked this conversation as resolved Outdated

The styles (=props) selected for the button are hightly specific and create an indirect dependency to its indented use case. The latter might change in the future and then we have to remember this dependency. This is why I think it makes sense to remove at least the specific use case of this button. Since we wouldn't use it then at all anymore (since you need to overwrite the default slot) it might make it simpler to only define the slot.

The styles (=props) selected for the button are hightly specific and create an indirect dependency to its indented use case. The latter might change in the future and then we have to remember this dependency. This is why I think it makes sense to remove at least the specific use case of this button. Since we wouldn't use it then at all anymore (since you need to overwrite the default slot) it might make it simpler to only define the slot.

Moved everything to a slot.

Moved everything to a slot.
<button @click="setDateRange(datesThisWeek)" :class="{'is-active': dateRange === datesThisWeek}">
{{ $t('task.show.thisWeek') }}
</button>
<button @click="setDateRange(datesNextWeek)" :class="{'is-active': dateRange === datesNextWeek}">
{{ $t('task.show.nextWeek') }}
</button>
<button @click="setDateRange(datesNext7Days)" :class="{'is-active': dateRange === datesNext7Days}">
{{ $t('task.show.next7Days') }}
konrad marked this conversation as resolved Outdated

Use BaseButton

Use BaseButton

Done.

Done.
</button>
<button @click="setDateRange(datesThisMonth)" :class="{'is-active': dateRange === datesThisMonth}">
{{ $t('task.show.thisMonth') }}
konrad marked this conversation as resolved Outdated

Use BaseButton

Use BaseButton

Done.

Done.
</button>
<button @click="setDateRange(datesNextMonth)" :class="{'is-active': dateRange === datesNextMonth}">
{{ $t('task.show.nextMonth') }}
</button>
<button @click="setDateRange('')" :class="{'is-active': customRangeActive}">
<button @click="setDateRange(datesNext30Days)" :class="{'is-active': dateRange === datesNext30Days}">
{{ $t('task.show.next30Days') }}
</button>
<button @click="setDateRange('')" :class="{'is-active': customRangeActive}">
{{ $t('misc.custom') }}
</button>
</div>
@ -45,7 +57,7 @@ const flatPickerConfig = computed(() => ({
mode: 'range',
/*locale: {
// FIXME: This seems to always contain the default value - that breaks the picker
firstDayOfWeek: weekStart,
firstDayOf7Days: weekStart,
},*/
}))
@ -75,21 +87,89 @@ function formatDate(date: Date): string {
return format(date, 'yyyy-MM-dd HH:mm')
}
function startOfDay(date: Date): Date {
date.setHours(0)
date.setMinutes(0)
return date
}
function endOfDay(date: Date): Date {
date.setHours(23)
date.setMinutes(59)
return date
}
const datesToday = computed<string>(() => {
const startDate = new Date()
const endDate = new Date((new Date()).setDate((new Date()).getDate() + 1))
const startDate = startOfDay(new Date())
const endDate = endOfDay(new Date())
return `${formatDate(startDate)} to ${formatDate(endDate)}`
})
function thisWeek() {
const startDate = startOfDay(new Date())
const first = startDate.getDate() - startDate.getDay()
startDate.setDate(first)
const endDate = endOfDay(new Date((new Date(startDate).setDate(first + 6))))
return {
startDate,
endDate,
konrad marked this conversation as resolved Outdated

Why do we need to reset this every time?

Why do we need to reset this every time?

I don't think we have to. I've checked and it looks like this doesn't really break anything so I've removed it. Lets us get rid of inputChanged.

I don't think we have to. I've checked and it looks like this doesn't really break anything so I've removed it. Lets us get rid of `inputChanged`.
}

Called here!

Called here!
}
const datesThisWeek = computed<string>(() => {
const {startDate, endDate} = thisWeek()
return `${formatDate(startDate)} to ${formatDate(endDate)}`
})
const datesNextWeek = computed<string>(() => {
const startDate = new Date()
const endDate = new Date((new Date()).getTime() + 7 * 24 * 60 * 60 * 1000)
const {startDate, endDate} = thisWeek()
startDate.setDate(startDate.getDate() + 7)
endDate.setDate(endDate.getDate() + 7)
return `${formatDate(startDate)} to ${formatDate(endDate)}`
})
const datesNext7Days = computed<string>(() => {
const startDate = startOfDay(new Date())
const endDate = endOfDay(new Date((new Date()).getTime() + 7 * 24 * 60 * 60 * 1000))

This is triggered three times!

Once for each of these lines:

from.value = fromDate
to.value = toDate

in the called function inputChanged of the watcher.
And then here again.

This is triggered three times! Once for each of these lines: ```js from.value = fromDate to.value = toDate ``` in the called function inputChanged of the watcher. And then here again.

mhh how can we fix this? Using a debounce to prevent it getting called three times if it changed all values at once? Or removing the watchers again?

It looks like the tasks are only loaded once, not three times. Maybe that's already enough?

mhh how can we fix this? Using a debounce to prevent it getting called three times if it changed all values at once? Or removing the watchers again? It looks like the tasks are only loaded once, not three times. Maybe that's already enough?
return `${formatDate(startDate)} to ${formatDate(endDate)}`
})
function thisMonth() {
const startDate = startOfDay(new Date())
startDate.setDate(1)
const endDate = endOfDay(new Date((new Date()).getFullYear(), (new Date()).getMonth() + 1, 0))
return {
startDate,
endDate,
}
}
const datesThisMonth = computed<string>(() => {
const {startDate, endDate} = thisMonth()
return `${formatDate(startDate)} to ${formatDate(endDate)}`
})
konrad marked this conversation as resolved Outdated

picky: el is a bit misleading here. We don't have elements

picky: `el` is a bit misleading here. We don't have elements

right, I've changed it.

right, I've changed it.
const datesNextMonth = computed<string>(() => {
const startDate = new Date()
const endDate = new Date((new Date()).setMonth((new Date()).getMonth() + 1))
const {startDate, endDate} = thisMonth()
startDate.setMonth(startDate.getMonth() + 1)
endDate.setMonth(endDate.getMonth() + 1)
return `${formatDate(startDate)} to ${formatDate(endDate)}`
})
const datesNext30Days = computed<string>(() => {
const startDate = startOfDay(new Date())
const endDate = endOfDay(new Date((new Date()).setMonth((new Date()).getMonth() + 1)))
return `${formatDate(startDate)} to ${formatDate(endDate)}`
})
@ -99,8 +179,12 @@ function setDateRange(range: string) {
const customRangeActive = computed<Boolean>(() => {
konrad marked this conversation as resolved Outdated

After using it a while I prefer now to use the useStore method to get the current store instance.
The reason is that it makes it easier to refactor in composables later because useStore will always give you the store.

After using it a while I prefer now to use the `useStore` method to get the current store instance. The reason is that it makes it easier to refactor in composables later because `useStore` will always give you the store.

Makes sense! Changed it.

Makes sense! Changed it.
return dateRange.value !== datesToday.value &&
dateRange.value !== datesThisWeek.value &&
dateRange.value !== datesNextWeek.value &&
dateRange.value !== datesNextMonth.value
dateRange.value !== datesNext7Days.value &&
dateRange.value !== datesThisMonth.value &&
dateRange.value !== datesNextMonth.value &&
dateRange.value !== datesNext30Days.value
})
</script>

View File

@ -536,8 +536,12 @@
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a range:",
"today": "Today",
"thisWeek": "This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"thisMonth": "This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"noTasks": "Nothing to do — Have a nice day!"
},
"detail": {