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:
parent
ef0fe0b11d
commit
a4c3939fb6
3 changed files with 59 additions and 23 deletions
|
@ -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(
|
||||||
|
|
|
@ -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') {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ function useSavedFilter(listId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const listId = computed(() => route.params.listId)
|
const listId = computed(() => route.params.listId)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
save,
|
save,
|
||||||
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue