fix: ensure project filters are retained correctly across views (#1643)

This commit is contained in:
kolaente 2025-11-16 15:29:50 +01:00 committed by GitHub
parent 85fc8fffd4
commit 2e3b2cb770
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 251 additions and 4 deletions

View File

@ -6,6 +6,10 @@ import {TaskFactory} from '../../factories/task'
import {prepareProjects} from './prepareProjects'
import {ProjectViewFactory} from "../../factories/project_view";
import {TaskBucketFactory} from "../../factories/task_buckets";
import {
createTasksWithPriorities,
createTasksWithSearch,
} from '../../support/filterTestHelpers'
function createSingleTaskInBucket(count = 1, attrs = {}) {
const projects = ProjectFactory.create(1)
@ -302,4 +306,44 @@ describe('Project View Kanban', () => {
cy.get('.bucket .tasks .task .footer .icon svg')
.should('not.exist')
})
it('Should respect filter query parameter from URL', () => {
const {highPriorityTasks, lowPriorityTasks} = createTasksWithPriorities(buckets)
cy.visit('/projects/1/4?filter=priority%20>=%204')
cy.url()
.should('include', 'filter=priority')
cy.contains('.kanban .bucket', highPriorityTasks[0].title, {timeout: 10000})
.should('exist')
cy.get('.kanban .bucket')
.should('contain', highPriorityTasks[0].title)
cy.get('.kanban .bucket')
.should('contain', highPriorityTasks[1].title)
cy.get('.kanban .bucket')
.should('not.contain', lowPriorityTasks[0].title)
cy.get('.kanban .bucket')
.should('not.contain', lowPriorityTasks[1].title)
})
it('Should respect search query parameter from URL', () => {
const {searchableTask} = createTasksWithSearch(buckets)
cy.visit('/projects/1/4?s=meeting')
cy.url()
.should('include', 's=meeting')
cy.contains('.kanban .bucket', searchableTask.title, {timeout: 10000})
.should('exist')
cy.get('.kanban .bucket')
.should('contain', searchableTask.title)
cy.get('.kanban .bucket .tasks .task')
.should('have.length', 1)
})
})

View File

@ -7,6 +7,10 @@ import {UserFactory} from '../../factories/user'
import {ProjectFactory} from '../../factories/project'
import {prepareProjects, createProjects} from './prepareProjects'
import {BucketFactory} from '../../factories/bucket'
import {
createTasksWithPriorities,
createTasksWithSearch,
} from '../../support/filterTestHelpers'
describe('Project View List', () => {
createFakeUserAndLogin()
@ -193,4 +197,44 @@ describe('Project View List', () => {
cy.get('ul.tasks > div > .subtask-nested')
.should('exist')
})
it('Should respect filter query parameter from URL', () => {
const {highPriorityTasks, lowPriorityTasks} = createTasksWithPriorities()
cy.visit('/projects/1/1?filter=priority%20>=%204')
cy.url()
.should('include', 'filter=priority')
cy.contains('.tasks', highPriorityTasks[0].title, {timeout: 10000})
.should('exist')
cy.get('.tasks')
.should('contain', highPriorityTasks[0].title)
cy.get('.tasks')
.should('contain', highPriorityTasks[1].title)
cy.get('.tasks')
.should('not.contain', lowPriorityTasks[0].title)
cy.get('.tasks')
.should('not.contain', lowPriorityTasks[1].title)
})
it('Should respect search query parameter from URL', () => {
const {searchableTask} = createTasksWithSearch()
cy.visit('/projects/1/1?s=meeting')
cy.url()
.should('include', 's=meeting')
cy.contains('.tasks', searchableTask.title, {timeout: 10000})
.should('exist')
cy.get('.tasks')
.should('contain', searchableTask.title)
cy.get('.tasks .task')
.should('have.length', 1)
})
})

View File

@ -2,6 +2,10 @@ import {createFakeUserAndLogin} from '../../support/authenticateUser'
import {TaskFactory} from '../../factories/task'
import {prepareProjects} from './prepareProjects'
import {
createTasksWithPriorities,
createTasksWithSearch,
} from '../../support/filterTestHelpers'
describe('Project View Table', () => {
createFakeUserAndLogin()
@ -53,4 +57,44 @@ describe('Project View Table', () => {
cy.url()
.should('contain', `/tasks/${tasks[0].id}`)
})
it('Should respect filter query parameter from URL', () => {
const {highPriorityTasks, lowPriorityTasks} = createTasksWithPriorities()
cy.visit('/projects/1/3?filter=priority%20>=%204')
cy.url()
.should('include', 'filter=priority')
cy.contains('.project-table table.table', highPriorityTasks[0].title, {timeout: 10000})
.should('exist')
cy.get('.project-table table.table')
.should('contain', highPriorityTasks[0].title)
cy.get('.project-table table.table')
.should('contain', highPriorityTasks[1].title)
cy.get('.project-table table.table')
.should('not.contain', lowPriorityTasks[0].title)
cy.get('.project-table table.table')
.should('not.contain', lowPriorityTasks[1].title)
})
it('Should respect search query parameter from URL', () => {
const {searchableTask} = createTasksWithSearch()
cy.visit('/projects/1/3?s=meeting')
cy.url()
.should('include', 's=meeting')
cy.contains('.project-table table.table', searchableTask.title, {timeout: 10000})
.should('exist')
cy.get('.project-table table.table')
.should('contain', searchableTask.title)
cy.get('.project-table table.table tbody tr')
.should('have.length', 1)
})
})

View File

@ -0,0 +1,119 @@
import {TaskFactory} from '../factories/task'
import {TaskBucketFactory} from '../factories/task_buckets'
export function createTasksWithPriorities(buckets?: any[]) {
TaskFactory.truncate()
const highPriorityTask1 = TaskFactory.create(1, {
id: 1,
project_id: 1,
priority: 4,
title: 'High Priority Task 1',
}, false)[0]
const highPriorityTask2 = TaskFactory.create(1, {
id: 2,
project_id: 1,
priority: 4,
title: 'High Priority Task 2',
}, false)[0]
const lowPriorityTask1 = TaskFactory.create(1, {
id: 3,
project_id: 1,
priority: 1,
title: 'Low Priority Task 1',
}, false)[0]
const lowPriorityTask2 = TaskFactory.create(1, {
id: 4,
project_id: 1,
priority: 1,
title: 'Low Priority Task 2',
}, false)[0]
// If buckets are provided (for Kanban), add tasks to buckets
if (buckets && buckets.length > 0) {
TaskBucketFactory.truncate()
TaskBucketFactory.create(1, {
task_id: highPriorityTask1.id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
}, false)
TaskBucketFactory.create(1, {
task_id: highPriorityTask2.id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
}, false)
TaskBucketFactory.create(1, {
task_id: lowPriorityTask1.id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
}, false)
TaskBucketFactory.create(1, {
task_id: lowPriorityTask2.id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
}, false)
}
return {
highPriorityTasks: [highPriorityTask1, highPriorityTask2],
lowPriorityTasks: [lowPriorityTask1, lowPriorityTask2],
}
}
export function createTasksWithSearch(buckets?: any[]) {
TaskFactory.truncate()
const task1 = TaskFactory.create(1, {
id: 1,
project_id: 1,
title: 'Regular task 1',
}, false)[0]
const task2 = TaskFactory.create(1, {
id: 2,
project_id: 1,
title: 'Regular task 2',
}, false)[0]
const task3 = TaskFactory.create(1, {
id: 3,
project_id: 1,
title: 'Regular task 3',
}, false)[0]
const searchableTask = TaskFactory.create(1, {
id: 4,
project_id: 1,
title: 'Meeting notes for project',
}, false)[0]
// If buckets are provided (for Kanban), add tasks to buckets
if (buckets && buckets.length > 0) {
TaskBucketFactory.truncate()
TaskBucketFactory.create(1, {
task_id: task1.id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
}, false)
TaskBucketFactory.create(1, {
task_id: task2.id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
}, false)
TaskBucketFactory.create(1, {
task_id: task3.id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
}, false)
TaskBucketFactory.create(1, {
task_id: searchableTask.id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
}, false)
}
return { searchableTask }
}

View File

@ -361,10 +361,6 @@ const {
} = taskList
const tasks: Ref<ITask[]> = taskList.tasks
Object.assign(params.value, {
filter: '',
})
watch(
() => activeColumns.value,
() => setActiveColumnsSortParam(),