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
3 changed files with 160 additions and 2 deletions
Showing only changes of commit e7fa1d3383 - Show all commits

View File

@ -49,6 +49,122 @@
:config="flatPickerConfig"
v-model="flatpickrRange"
/>
<p>
{{ $t('input.datepickerRange.math.canuse') }}
<a @click="showHowItWorks = true">{{ $t('input.datepickerRange.math.learnhow') }}</a>.
konrad marked this conversation as resolved
Review

Use BaseButton

Use BaseButton
Review

Done.

Done.
</p>
<modal
@close="() => showHowItWorks = false"
:enabled="showHowItWorks"
transition-name="fade"
:overflow="true"
variant="hint-modal"
>
<card class="has-no-shadow how-it-works-modal" :title="$t('input.datepickerRange.math.title')">
konrad marked this conversation as resolved Outdated

The whole explanation card should be its own component.

The whole explanation card should be its own component.

Done!

Done!
<p>
{{ $t('input.datepickerRange.math.intro') }}
</p>
<p>
<i18n-t keypath="input.datepickerRange.math.expression">
<code>now</code>
<code>||</code>
</i18n-t>
</p>
<p>
<i18n-t keypath="input.datepickerRange.math.similar">
dpschen marked this conversation as resolved Outdated

I think it's really cool, that we support this, but it would be cool, if we could break this down and explain it in our / simpler terms.

I think it's really cool, that we support this, but it would be cool, if we could break this down and explain it in our / simpler terms.

I think I'm already doing that but wanted to highlight for people who know the syntax from Elasticsearch or Grafana they can use it here as well.

Was there anything in the explanation you noticed as not quite understandable?

I think I'm already doing that but wanted to highlight for people who know the syntax from Elasticsearch or Grafana they can use it here as well. Was there anything in the explanation you noticed as not quite understandable?

I didn't even check to be honest.
Was just something I though of while reading this.

I didn't even check to be honest. Was just something I though of while reading this.
<a href="https://grafana.com/docs/grafana/latest/dashboards/time-range-controls/" rel="noreferrer noopener nofollow" target="_blank">
Grafana
</a>
<a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#date-math" rel="noreferrer noopener nofollow" target="_blank">
Elasticsearch
</a>
</i18n-t>
</p>
<p>{{ $t('misc.forExample') }}</p>
<ul>
<li><code>+1d</code>{{ $t('input.datepickerRange.math.add1Day') }}</li>
<li><code>-1d</code>{{ $t('input.datepickerRange.math.minus1Day') }}</li>
<li><code>/d</code>{{ $t('input.datepickerRange.math.roundDay') }}</li>
</ul>
<p>{{ $t('input.datepickerRange.math.supportedUnits') }}</p>
<table class="table">
<tbody>
<tr>
<td><code>s</code></td>
<td>{{ $t('input.datepickerRange.math.units.seconds') }}</td>
</tr>
<tr>
<td><code>m</code></td>
<td>{{ $t('input.datepickerRange.math.units.minutes') }}</td>
</tr>
<tr>
<td><code>h</code></td>
<td>{{ $t('input.datepickerRange.math.units.hours') }}</td>
</tr>
<tr>
<td><code>H</code></td>
<td>{{ $t('input.datepickerRange.math.units.hours') }}</td>
</tr>
<tr>
<td><code>d</code></td>
<td>{{ $t('input.datepickerRange.math.units.days') }}</td>
</tr>
<tr>
<td><code>w</code></td>
<td>{{ $t('input.datepickerRange.math.units.weeks') }}</td>
</tr>
<tr>
<td><code>M</code></td>
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`.
<td>{{ $t('input.datepickerRange.math.units.months') }}</td>

Called here!

Called here!
</tr>
<tr>
<td><code>y</code></td>
<td>{{ $t('input.datepickerRange.math.units.years') }}</td>
</tr>
</tbody>
</table>
<p>{{ $t('input.datepickerRange.math.someExamples') }}</p>
<table class="table">
<tbody>
<tr>
<td><code>now</code></td>
<td>{{ $t('input.datepickerRange.math.examples.now') }}</td>
</tr>
<tr>
<td><code>now+24h</code></td>
<td>{{ $t('input.datepickerRange.math.examples.in24h') }}</td>
</tr>

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?
<tr>
<td><code>now/d</code></td>
<td>{{ $t('input.datepickerRange.math.examples.today') }}</td>
</tr>
<tr>
<td><code>now/w</code></td>
<td>{{ $t('input.datepickerRange.math.examples.beginningOfThisWeek') }}</td>
</tr>
<tr>
<td><code>now/w+1w</code></td>
<td>{{ $t('input.datepickerRange.math.examples.endOfThisWeek') }}</td>
</tr>
<tr>
<td><code>now+30d</code></td>
<td>{{ $t('input.datepickerRange.math.examples.in30Days') }}</td>
</tr>
<tr>
<td><code>{{ exampleDate }}||+1M/d</code></td>
<td>
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.
<i18n-t keypath="input.datepickerRange.math.examples.datePlusMonth">
<code>{{ exampleDate }}</code>
</i18n-t>
</td>
</tr>
</tbody>
</table>
</card>
</modal>
</div>
</div>
</template>
@ -62,6 +178,7 @@ import 'flatpickr/dist/flatpickr.css'
import {computed, ref, watch} from 'vue'
import {useI18n} from 'vue-i18n'
import {store} from '@/store'
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.
import {format} from 'date-fns'
import Popup from '@/components/misc/popup.vue'
import {dateRanges} from '@/components/date/dateRanges'
@ -84,6 +201,9 @@ const flatPickerConfig = computed(() => ({
},
}))
const showHowItWorks = ref(false)
const exampleDate = format(new Date(), 'yyyy-MM-dd')
const flatpickrRange = ref('')
const from = ref('')
@ -226,4 +346,12 @@ const customRangeActive = computed<Boolean>(() => {
}
}
}
.how-it-works-modal{
font-size: 1rem;
p {
display: inline-block !important;
}
}
</style>

View File

@ -207,7 +207,6 @@ export default {
display: flex;
justify-content: space-between;
align-items: center;
}
}
}

View File

@ -525,7 +525,38 @@
},
"datepickerRange": {
"to": "To",
"from": "From"
"from": "From",
"math": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
}
},
"task": {