1
0

fix(filters): correctly transform and populate saved filter when creating and editing

This fixes a bug where the checkbox "include nulls" during creation was not checked but would be saved as such.

(cherry picked from commit 4dd9d5de6777967203533b8f88756c3cab4d2bd5)
This commit is contained in:
kolaente 2024-09-19 12:21:19 +02:00
parent 320fc75c27
commit 51f26d14b9
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
3 changed files with 13 additions and 29 deletions

View File

@ -1,11 +1,12 @@
import type {IAbstract} from './IAbstract' import type {IAbstract} from './IAbstract'
import type {IUser} from './IUser' import type {IUser} from './IUser'
// FIXME: what makes this different from TaskFilterParams?
interface Filters { interface Filters {
sortBy: ('start_date' | 'done' | 'id' | 'position')[], sort_by: ('start_date' | 'done' | 'id' | 'position')[],
orderBy: ('asc' | 'desc')[], order_by: ('asc' | 'desc')[],
filter: string, filter: string,
filterIncludeNulls: boolean, filter_include_nulls: boolean,
s: string, s: string,
} }

View File

@ -1,3 +1,4 @@
import { objectToSnakeCase } from '@/helpers/case'
import AbstractModel from './abstractModel' import AbstractModel from './abstractModel'
import UserModel from '@/models/user' import UserModel from '@/models/user'
@ -9,10 +10,10 @@ export default class SavedFilterModel extends AbstractModel<ISavedFilter> implem
title = '' title = ''
description = '' description = ''
filters: ISavedFilter['filters'] = { filters: ISavedFilter['filters'] = {
sortBy: ['done', 'id'], sort_by: ['done', 'id'],
orderBy: ['asc', 'desc'], order_by: ['asc', 'desc'],
filter: 'done = false', filter: 'done = false',
filterIncludeNulls: true, filter_include_nulls: true,
s: '', s: '',
} }
@ -26,6 +27,10 @@ export default class SavedFilterModel extends AbstractModel<ISavedFilter> implem
this.owner = new UserModel(this.owner) this.owner = new UserModel(this.owner)
// Filters are in snake_case for the API - this makes it consistent with the way filter params are used with one-off filters.
// Should probably be camelCase everywhere, but that's a task for another day.
this.filters = objectToSnakeCase(this.filters)
this.created = new Date(this.created) this.created = new Date(this.created)
this.updated = new Date(this.updated) this.updated = new Date(this.updated)
} }

View File

@ -13,7 +13,6 @@ import SavedFilterModel from '@/models/savedFilter'
import {useBaseStore} from '@/stores/base' import {useBaseStore} from '@/stores/base'
import {useProjectStore} from '@/stores/projects' import {useProjectStore} from '@/stores/projects'
import {objectToSnakeCase, objectToCamelCase} from '@/helpers/case'
import {success} from '@/message' import {success} from '@/message'
import ProjectModel from '@/models/project' import ProjectModel from '@/models/project'
@ -55,23 +54,6 @@ export default class SavedFilterService extends AbstractService<ISavedFilter> {
modelFactory(data) { modelFactory(data) {
return new SavedFilterModel(data) return new SavedFilterModel(data)
} }
processModel(model) {
// Make filters from this.filters camelCase and set them to the model property:
// That's easier than making the whole filter component configurable since that still needs to provide
// the filter values in snake_sćase for url parameters.
model.filters = objectToCamelCase(model.filters)
return model
}
beforeUpdate(model) {
return this.processModel(model)
}
beforeCreate(model) {
return this.processModel(model)
}
} }
export function useSavedFilter(projectId?: MaybeRefOrGetter<IProject['id']>) { export function useSavedFilter(projectId?: MaybeRefOrGetter<IProject['id']>) {
@ -98,10 +80,7 @@ export function useSavedFilter(projectId?: MaybeRefOrGetter<IProject['id']>) {
// We assume the projectId in the route is the pseudoproject // We assume the projectId in the route is the pseudoproject
const savedFilterId = getSavedFilterIdFromProjectId(watchedProjectId) const savedFilterId = getSavedFilterIdFromProjectId(watchedProjectId)
filter.value = new SavedFilterModel({id: savedFilterId}) filter.value = await filterService.get(new SavedFilterModel({id: savedFilterId}))
const response = await filterService.get(filter.value)
response.filters = objectToSnakeCase(response.filters)
filter.value = response
await validateTitleField() await validateTitleField()
}, {immediate: true}) }, {immediate: true})
@ -115,7 +94,6 @@ export function useSavedFilter(projectId?: MaybeRefOrGetter<IProject['id']>) {
const response = await filterService.update(filter.value) const response = await filterService.update(filter.value)
await projectStore.loadAllProjects() await projectStore.loadAllProjects()
success({message: t('filters.edit.success')}) success({message: t('filters.edit.success')})
response.filters = objectToSnakeCase(response.filters)
filter.value = response filter.value = response
await useBaseStore().setCurrentProject(new ProjectModel({ await useBaseStore().setCurrentProject(new ProjectModel({
id: getProjectId(filter.value), id: getProjectId(filter.value),