mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-04-24 22:25:15 +00:00
fix(kanban): make bucket query fixed per-view (#1007)
This commit is contained in:
@@ -509,6 +509,7 @@ describe('Task', () => {
|
||||
TaskBucketFactory.create(1, {
|
||||
task_id: tasks[0].id,
|
||||
bucket_id: buckets[0].id,
|
||||
project_view_id: buckets[0].project_view_id,
|
||||
})
|
||||
|
||||
cy.visit(`/projects/${projects[0].id}/4`)
|
||||
@@ -901,6 +902,11 @@ describe('Task', () => {
|
||||
})
|
||||
const labels = LabelFactory.create(1)
|
||||
LabelTaskFactory.truncate()
|
||||
TaskBucketFactory.create(1, {
|
||||
task_id: tasks[0].id,
|
||||
bucket_id: buckets[0].id,
|
||||
project_view_id: buckets[0].project_view_id,
|
||||
})
|
||||
|
||||
cy.visit(`/projects/${projects[0].id}/4`)
|
||||
|
||||
|
||||
@@ -201,6 +201,7 @@ func GetTasksInBucketsForView(s *xorm.Session, view *ProjectView, projects []*Pr
|
||||
|
||||
tasks := []*Task{}
|
||||
|
||||
opts.projectViewID = view.ID
|
||||
opts.sortby = []*sortParam{
|
||||
{
|
||||
projectViewID: view.ID,
|
||||
|
||||
@@ -142,6 +142,10 @@ func getTaskFilterOptsFromCollection(tf *TaskCollection, projectView *ProjectVie
|
||||
filterTimezone: tf.FilterTimezone,
|
||||
}
|
||||
|
||||
if projectView != nil {
|
||||
opts.projectViewID = projectView.ID
|
||||
}
|
||||
|
||||
opts.parsedFilters, err = getTaskFiltersFromFilterString(tf.Filter, tf.FilterTimezone)
|
||||
return opts, err
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ func RecalculateTaskPositions(s *xorm.Session, view *ProjectView, a web.Auth) (e
|
||||
log.Debugf("Recalculating task positions for view %d", view.ID)
|
||||
|
||||
opts := &taskSearchOptions{
|
||||
projectViewID: view.ID,
|
||||
sortby: []*sortParam{
|
||||
{
|
||||
projectViewID: view.ID,
|
||||
|
||||
@@ -350,7 +350,13 @@ func (d *dbTaskSearcher) Search(opts *taskSearchOptions) (tasks []*Task, totalCo
|
||||
}
|
||||
|
||||
if joinTaskBuckets {
|
||||
query = query.Join("LEFT", "task_buckets", "task_buckets.task_id = tasks.id")
|
||||
joinCond := "task_buckets.task_id = tasks.id"
|
||||
if opts.projectViewID > 0 {
|
||||
joinCond += " AND task_buckets.project_view_id = ?"
|
||||
query = query.Join("LEFT", "task_buckets", joinCond, opts.projectViewID)
|
||||
} else {
|
||||
query = query.Join("LEFT", "task_buckets", joinCond)
|
||||
}
|
||||
}
|
||||
if expandSubtasks {
|
||||
query = query.
|
||||
@@ -419,7 +425,13 @@ func (d *dbTaskSearcher) Search(opts *taskSearchOptions) (tasks []*Task, totalCo
|
||||
|
||||
queryCount := d.s.Where(cond)
|
||||
if joinTaskBuckets {
|
||||
queryCount = queryCount.Join("LEFT", "task_buckets", "task_buckets.task_id = tasks.id")
|
||||
joinCond := "task_buckets.task_id = tasks.id"
|
||||
if opts.projectViewID > 0 {
|
||||
joinCond += " AND task_buckets.project_view_id = ?"
|
||||
queryCount = queryCount.Join("LEFT", "task_buckets", joinCond, opts.projectViewID)
|
||||
} else {
|
||||
queryCount = queryCount.Join("LEFT", "task_buckets", joinCond)
|
||||
}
|
||||
}
|
||||
if expandSubtasks {
|
||||
queryCount = queryCount.
|
||||
|
||||
56
pkg/models/task_search_test.go
Normal file
56
pkg/models/task_search_test.go
Normal file
@@ -0,0 +1,56 @@
|
||||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-present Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestKanbanViewBucketFiltering(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := db.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
view, err := GetProjectViewByID(s, 4)
|
||||
require.NoError(t, err)
|
||||
|
||||
project, err := GetProjectSimpleByID(s, view.ProjectID)
|
||||
require.NoError(t, err)
|
||||
|
||||
buckets, err := GetTasksInBucketsForView(s, view, []*Project{project}, &taskSearchOptions{}, &user.User{ID: 1})
|
||||
require.NoError(t, err)
|
||||
|
||||
taskBuckets := map[int64][]int64{}
|
||||
for _, b := range buckets {
|
||||
for _, tsk := range b.Tasks {
|
||||
taskBuckets[tsk.ID] = append(taskBuckets[tsk.ID], b.ID)
|
||||
}
|
||||
}
|
||||
|
||||
for tid, bs := range taskBuckets {
|
||||
assert.Lenf(t, bs, 1, "task %d appears in multiple buckets: %v", tid, bs)
|
||||
}
|
||||
|
||||
for _, id := range []int64{40, 41, 42, 43, 44, 45, 46} {
|
||||
assert.NotContains(t, taskBuckets, id)
|
||||
}
|
||||
}
|
||||
@@ -195,6 +195,7 @@ type taskSearchOptions struct {
|
||||
isSavedFilter bool
|
||||
projectIDs []int64
|
||||
expand []TaskCollectionExpandable
|
||||
projectViewID int64
|
||||
}
|
||||
|
||||
// ReadAll is a dummy function to still have that endpoint documented
|
||||
|
||||
Reference in New Issue
Block a user