fix: make sure saved filter data is correctly populated when editing a filter

Resolves https://kolaente.dev/vikunja/frontend/issues/2114
This commit is contained in:
kolaente 2022-07-13 17:52:42 +02:00
parent ef0fe0b11d
commit a4c3939fb6
No known key found for this signature in database
GPG key ID: F40E70337AB24C9B
3 changed files with 59 additions and 23 deletions

View file

@ -85,7 +85,12 @@ import DatemathHelp from '@/components/date/datemathHelp.vue'
const store = useStore() const store = useStore()
const {t} = useI18n({useScope: 'global'}) const {t} = useI18n({useScope: 'global'})
const emit = defineEmits(['dateChanged']) const emit = defineEmits(['dateChanged', 'update:modelValue'])
const props = defineProps({
modelValue: {
required: false,
},
})
// FIXME: This seems to always contain the default value - that breaks the picker // FIXME: This seems to always contain the default value - that breaks the picker
const weekStart = computed<number>(() => store.state.auth.settings.weekStart ?? 0) const weekStart = computed<number>(() => store.state.auth.settings.weekStart ?? 0)
@ -108,11 +113,22 @@ const flatpickrRange = ref('')
const from = ref('') const from = ref('')
const to = ref('') const to = ref('')
watch(
() => props.modelValue,
newValue => {
from.value = newValue.dateFrom
to.value = newValue.dateTo
flatpickrRange.value = `${from.value} to ${to.value}`
},
)
function emitChanged() { function emitChanged() {
emit('dateChanged', { const args = {
dateFrom: from.value === '' ? null : from.value, dateFrom: from.value === '' ? null : from.value,
dateTo: to.value === '' ? null : to.value, dateTo: to.value === '' ? null : to.value,
}) }
emit('dateChanged', args)
emit('update:modelValue', args)
} }
watch( watch(

View file

@ -67,7 +67,9 @@
<div class="field"> <div class="field">
<label class="label">{{ $t('task.attributes.dueDate') }}</label> <label class="label">{{ $t('task.attributes.dueDate') }}</label>
<div class="control"> <div class="control">
<datepicker-with-range @dateChanged="values => setDateFilter('due_date', values)"> <datepicker-with-range
@dateChanged="values => setDateFilter('due_date', values)"
v-model="filters.dueDate">
<template #trigger="{toggle, buttonText}"> <template #trigger="{toggle, buttonText}">
<x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2"> <x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2">
{{ buttonText }} {{ buttonText }}
@ -79,7 +81,9 @@
<div class="field"> <div class="field">
<label class="label">{{ $t('task.attributes.startDate') }}</label> <label class="label">{{ $t('task.attributes.startDate') }}</label>
<div class="control"> <div class="control">
<datepicker-with-range @dateChanged="values => setDateFilter('start_date', values)"> <datepicker-with-range
@dateChanged="values => setDateFilter('start_date', values)"
v-model="filters.startDate">
<template #trigger="{toggle, buttonText}"> <template #trigger="{toggle, buttonText}">
<x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2"> <x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2">
{{ buttonText }} {{ buttonText }}
@ -91,7 +95,9 @@
<div class="field"> <div class="field">
<label class="label">{{ $t('task.attributes.endDate') }}</label> <label class="label">{{ $t('task.attributes.endDate') }}</label>
<div class="control"> <div class="control">
<datepicker-with-range @dateChanged="values => setDateFilter('end_date', values)"> <datepicker-with-range
@dateChanged="values => setDateFilter('end_date', values)"
v-model="filters.endDate">
<template #trigger="{toggle, buttonText}"> <template #trigger="{toggle, buttonText}">
<x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2"> <x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2">
{{ buttonText }} {{ buttonText }}
@ -103,7 +109,9 @@
<div class="field"> <div class="field">
<label class="label">{{ $t('task.attributes.reminders') }}</label> <label class="label">{{ $t('task.attributes.reminders') }}</label>
<div class="control"> <div class="control">
<datepicker-with-range @dateChanged="values => setDateFilter('reminders', values)"> <datepicker-with-range
@dateChanged="values => setDateFilter('reminders', values)"
v-model="filters.reminders">
<template #trigger="{toggle, buttonText}"> <template #trigger="{toggle, buttonText}">
<x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2"> <x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2">
{{ buttonText }} {{ buttonText }}
@ -137,7 +145,8 @@
</div> </div>
</div> </div>
<template v-if="$route.name === 'filters.create' || $route.name === 'list.edit'"> <template
v-if="$route.name === 'filters.create' || $route.name === 'list.edit' || $route.name === 'filter.settings.edit'">
<div class="field"> <div class="field">
<label class="label">{{ $t('list.lists') }}</label> <label class="label">{{ $t('list.lists') }}</label>
<div class="control"> <div class="control">
@ -193,6 +202,7 @@ import EditLabels from '@/components/tasks/partials/editLabels.vue'
import {objectToSnakeCase} from '@/helpers/case' import {objectToSnakeCase} from '@/helpers/case'
import {getDefaultParams} from '@/composables/taskList' import {getDefaultParams} from '@/composables/taskList'
import {camelCase} from 'camel-case'
// FIXME: merge with DEFAULT_PARAMS in taskList.js // FIXME: merge with DEFAULT_PARAMS in taskList.js
const DEFAULT_PARAMS = { const DEFAULT_PARAMS = {
@ -368,6 +378,8 @@ export default defineComponent({
this.params.filter_comparator.push('less_equals') this.params.filter_comparator.push('less_equals')
this.params.filter_value.push(dateTo) this.params.filter_value.push(dateTo)
} }
this.filters[camelCase(filterName)] = {dateFrom, dateTo}
this.change() this.change()
return return
} }
@ -397,9 +409,16 @@ export default defineComponent({
} }
if (foundDateStart !== false && foundDateEnd !== false) { if (foundDateStart !== false && foundDateEnd !== false) {
const start = new Date(this.params.filter_value[foundDateStart]) const startDate = new Date(this.params.filter_value[foundDateStart])
const end = new Date(this.params.filter_value[foundDateEnd]) const endDate = new Date(this.params.filter_value[foundDateEnd])
this.filters[variableName] = `${start.getFullYear()}-${start.getMonth() + 1}-${start.getDate()} to ${end.getFullYear()}-${end.getMonth() + 1}-${end.getDate()}` this.filters[variableName] = {
dateFrom: !isNaN(startDate)
? `${startDate.getFullYear()}-${startDate.getMonth() + 1}-${startDate.getDate()}`
: this.params.filter_value[foundDateStart],
dateTo: !isNaN(endDate)
? `${endDate.getFullYear()}-${endDate.getMonth() + 1}-${endDate.getDate()}`
: this.params.filter_value[foundDateEnd],
}
} }
}, },
setSingleValueFilter(filterName, variableName, useVariableName = '', comparator = 'equals') { setSingleValueFilter(filterName, variableName, useVariableName = '', comparator = 'equals') {

View file

@ -52,11 +52,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, shallowRef, computed, watch } from 'vue' import {ref, shallowRef, computed, watch} from 'vue'
import { useRouter, useRoute } from 'vue-router' import {useRouter, useRoute} from 'vue-router'
import { store } from '@/store' import {store} from '@/store'
import { success } from '@/message' import {success} from '@/message'
import { useI18n } from 'vue-i18n' import {useI18n} from 'vue-i18n'
import {default as Editor} from '@/components/input/AsyncEditor' import {default as Editor} from '@/components/input/AsyncEditor'
import CreateEdit from '@/components/misc/create-edit.vue' import CreateEdit from '@/components/misc/create-edit.vue'
@ -68,7 +68,7 @@ import SavedFilterService from '@/services/savedFilter'
import {objectToSnakeCase} from '@/helpers/case' import {objectToSnakeCase} from '@/helpers/case'
import {getSavedFilterIdFromListId} from '@/helpers/savedFilter' import {getSavedFilterIdFromListId} from '@/helpers/savedFilter'
const { t } = useI18n({useScope: 'global'}) const {t} = useI18n({useScope: 'global'})
function useSavedFilter(listId) { function useSavedFilter(listId) {
const filterService = shallowRef(new SavedFilterService()) const filterService = shallowRef(new SavedFilterService())
@ -86,18 +86,18 @@ function useSavedFilter(listId) {
// We assume the listId in the route is the pseudolist // We assume the listId in the route is the pseudolist
const savedFilterId = getSavedFilterIdFromListId(route.params.listId) const savedFilterId = getSavedFilterIdFromListId(route.params.listId)
filter.value = new SavedFilterModel({id: savedFilterId }) filter.value = new SavedFilterModel({id: savedFilterId})
const response = await filterService.value.get(filter.value) const response = await filterService.value.get(filter.value)
response.filters = objectToSnakeCase(filter.value.filters) response.filters = objectToSnakeCase(response.filters)
filter.value = response filter.value = response
}, { immediate: true }) }, {immediate: true})
async function save() { async function save() {
filter.value.filters = filters.value filter.value.filters = filters.value
const response = await filterService.value.update(filter.value) const response = await filterService.value.update(filter.value)
await store.dispatch('namespaces/loadNamespaces') await store.dispatch('namespaces/loadNamespaces')
success({message: t('filters.edit.success')}) success({message: t('filters.edit.success')})
response.filters = objectToSnakeCase(filter.value.filters) response.filters = objectToSnakeCase(response.filters)
filter.value = response filter.value = response
} }
@ -120,6 +120,7 @@ const {
} = useSavedFilter(listId) } = useSavedFilter(listId)
const router = useRouter() const router = useRouter()
async function saveSavedFilter() { async function saveSavedFilter() {
await save() await save()
router.back() router.back()