feat: add date math for filters #1342
|
@ -1,46 +1,54 @@
|
|||
<template>
|
||||
<a @click="showPopup = !showPopup">
|
||||
{{ $t('task.show.select') }}
|
||||
</a>
|
||||
|
||||
<div class="datepicker-with-range-container">
|
||||
<transition name="fade">
|
||||
<div class="datepicker-with-range" v-if="showPopup">
|
||||
<div class="selections">
|
||||
<button @click="setDateRange(datesToday)" :class="{'is-active': dateRange === datesToday}">
|
||||
{{ $t('task.show.today') }}
|
||||
</button>
|
||||
<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') }}
|
||||
</button>
|
||||
<button @click="setDateRange(datesThisMonth)" :class="{'is-active': dateRange === datesThisMonth}">
|
||||
{{ $t('task.show.thisMonth') }}
|
||||
</button>
|
||||
<button @click="setDateRange(datesNextMonth)" :class="{'is-active': dateRange === datesNextMonth}">
|
||||
{{ $t('task.show.nextMonth') }}
|
||||
</button>
|
||||
<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>
|
||||
<popup>
|
||||
<template #trigger="{toggle}">
|
||||
<a @click.prevent.stop="toggle()">
|
||||
konrad marked this conversation as resolved
Outdated
|
||||
{{ $t('task.show.select') }}
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
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.
konrad
commented
Moved everything to a slot. Moved everything to a slot.
|
||||
</a>
|
||||
</template>
|
||||
<template #content="{isOpen}">
|
||||
<div class="datepicker-with-range" :class="{'is-open': isOpen}">
|
||||
<div class="selections">
|
||||
<button @click="setDateRange(datesToday)" :class="{'is-active': dateRange === datesToday}">
|
||||
{{ $t('task.show.today') }}
|
||||
</button>
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
Use BaseButton Use BaseButton
konrad
commented
Done. Done.
|
||||
<button @click="setDateRange(datesThisWeek)"
|
||||
:class="{'is-active': dateRange === datesThisWeek}">
|
||||
{{ $t('task.show.thisWeek') }}
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
Use BaseButton Use BaseButton
konrad
commented
Done. Done.
|
||||
</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') }}
|
||||
</button>
|
||||
<button @click="setDateRange(datesThisMonth)"
|
||||
:class="{'is-active': dateRange === datesThisMonth}">
|
||||
{{ $t('task.show.thisMonth') }}
|
||||
</button>
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
Instead of calling Instead of calling `inputChanged` from here better watch the `from` and below the `to` value.
This prevents future mistakes
konrad
commented
Changed. I kept Changed. I kept `inputChanged` though because I need to watchers.
|
||||
<button @click="setDateRange(datesNextMonth)"
|
||||
:class="{'is-active': dateRange === datesNextMonth}">
|
||||
{{ $t('task.show.nextMonth') }}
|
||||
</button>
|
||||
<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>
|
||||
<div class="flatpickr-container">
|
||||
<flat-pickr
|
||||
:config="flatPickerConfig"
|
||||
v-model="dateRange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flatpickr-container">
|
||||
<flat-pickr
|
||||
:config="flatPickerConfig"
|
||||
v-model="dateRange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -51,6 +59,7 @@ import {computed, ref, watch} from 'vue'
|
|||
import {useI18n} from 'vue-i18n'
|
||||
import {store} from '@/store'
|
||||
import {format} from 'date-fns'
|
||||
import Popup from '@/components/misc/popup'
|
||||
|
||||
const {t} = useI18n()
|
||||
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
The whole explanation card should be its own component. The whole explanation card should be its own component.
konrad
commented
Done! Done!
|
||||
|
@ -202,15 +211,25 @@ const customRangeActive = computed<Boolean>(() => {
|
|||
.datepicker-with-range-container {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
:deep(.popup) {
|
||||
margin-top: 1rem;
|
||||
dpschen
commented
I think this is a good usecase for a reactive. I think this is a good usecase for a reactive.
konrad
commented
What would be the advantage over a ref? What would be the advantage over a ref?
dpschen
commented
Both values can be changed at the same time Both values can be changed at the same time
=> watchers aren't triggered twice when you change stuff shortly after each other.
konrad
commented
How do I type it properly? If I only pass a string into a reactive it complains I should pass in an object instead. Edit: using How do I type it properly? If I only pass a string into a reactive it complains I should pass in an object instead.
Edit: using `String` (capital S) seems to work.
konrad
commented
Okay even with the typing solved it still complains when trying to set it: Because we do Okay even with the typing solved it still complains when trying to set it: Because we do `const from = ...` I won't be able to do `from = fromDate`. Any idea how to solve this?
|
||||
border-radius: $radius;
|
||||
border: 1px solid var(--grey-200);
|
||||
background-color: var(--white);
|
||||
box-shadow: $shadow;
|
||||
dpschen
commented
Use v-model for values. Use v-model for values.
Might be useful: https://vueuse.org/core/usevmodel/
konrad
commented
What I don't like with using a v-model here would be the need to introduce another watcher in ShowTasks because we need to push the changes to the route. I think the current way with an event nicely circumvents this. Also I'd like to keep the current behaviour where it only does one route change if you change both values instead of two (but that could easily be kept with passing an object to v-model?). What I don't like with using a v-model here would be the need to introduce another watcher in ShowTasks because we need to push the changes to the route. I think the current way with an event nicely circumvents this.
Also I'd like to keep the current behaviour where it only does one route change if you change both values instead of two (but that could easily be kept with passing an object to v-model?).
dpschen
commented
correct > Also I'd like to keep the current behaviour where it only does one route change if you change both values instead of two (but that could easily be kept with passing an object to v-model?).
correct
|
||||
|
||||
&.is-open {
|
||||
width: 500px;
|
||||
height: 320px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.datepicker-with-range {
|
||||
border-radius: $radius;
|
||||
border: 1px solid var(--grey-200);
|
||||
background-color: var(--white);
|
||||
box-shadow: $shadow;
|
||||
display: flex;
|
||||
width: 500px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
|
||||
:deep(.flatpickr-calendar) {
|
||||
|
|
Provide
buttonText
as slot prop aswellDone.