From 429c7ca2c1273cc4912afaa728e569e078280986 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 28 Aug 2024 15:30:40 +0200 Subject: [PATCH] feat(task): always insert new tasks at the top Resolves https://community.vikunja.io/t/kanban-cards-in-wrong-order/2731 --- .../project/views/ProjectKanban.vue | 6 ++-- frontend/src/stores/kanban.ts | 2 +- pkg/models/task_position.go | 36 +++++++++++++++++++ pkg/models/tasks.go | 19 +++++----- 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/frontend/src/components/project/views/ProjectKanban.vue b/frontend/src/components/project/views/ProjectKanban.vue index aac0f2b1b..8cb08d643 100644 --- a/frontend/src/components/project/views/ProjectKanban.vue +++ b/frontend/src/components/project/views/ProjectKanban.vue @@ -564,15 +564,15 @@ async function addTaskToBucket(bucketId: IBucket['id']) { }) newTaskText.value = '' kanbanStore.addTaskToBucket(task) - scrollTaskContainerToBottom(bucketId) + scrollTaskContainerToTop(bucketId) } -function scrollTaskContainerToBottom(bucketId: IBucket['id']) { +function scrollTaskContainerToTop(bucketId: IBucket['id']) { const bucketEl = taskContainerRefs.value[bucketId] if (!bucketEl) { return } - bucketEl.scrollTop = bucketEl.scrollHeight + bucketEl.scrollTop = 0 } async function createNewBucket() { diff --git a/frontend/src/stores/kanban.ts b/frontend/src/stores/kanban.ts index 4b9bca38b..e08e66d99 100644 --- a/frontend/src/stores/kanban.ts +++ b/frontend/src/stores/kanban.ts @@ -194,8 +194,8 @@ export const useKanbanStore = defineStore('kanban', () => { ...oldBucket, count: (oldBucket?.count || 0) + 1, tasks: [ - ...oldBucket.tasks, task, + ...oldBucket.tasks, ], } buckets.value[bucketIndex] = newBucket diff --git a/pkg/models/task_position.go b/pkg/models/task_position.go index 9a68ceeea..67a1d777c 100644 --- a/pkg/models/task_position.go +++ b/pkg/models/task_position.go @@ -192,3 +192,39 @@ func getPositionsForView(s *xorm.Session, view *ProjectView) (positions []*TaskP Find(&positions) return } + +func calculateNewPositionForTask(s *xorm.Session, a web.Auth, t *Task, view *ProjectView) (*TaskPosition, error) { + if t.Position == 0 { + lowestPosition := &TaskPosition{} + exists, err := s.Where("project_view_id = ?", view.ID). + OrderBy("position asc"). + Get(lowestPosition) + if err != nil { + return nil, err + } + if exists { + if lowestPosition.Position == 0 { + err = RecalculateTaskPositions(s, view, a) + if err != nil { + return nil, err + } + + lowestPosition = &TaskPosition{} + _, err = s.Where("project_view_id = ?", view.ID). + OrderBy("position asc"). + Get(lowestPosition) + if err != nil { + return nil, err + } + } + + t.Position = lowestPosition.Position / 2 + } + } + + return &TaskPosition{ + TaskID: t.ID, + ProjectViewID: view.ID, + Position: calculateDefaultPosition(t.Index, t.Position), + }, nil +} diff --git a/pkg/models/tasks.go b/pkg/models/tasks.go index 0735a3dbb..702b4bb8b 100644 --- a/pkg/models/tasks.go +++ b/pkg/models/tasks.go @@ -791,11 +791,12 @@ func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool, setB }) } - positions = append(positions, &TaskPosition{ - TaskID: t.ID, - ProjectViewID: view.ID, - Position: calculateDefaultPosition(t.Index, t.Position), - }) + newPosition, err := calculateNewPositionForTask(s, a, t, view) + if err != nil { + return err + } + + positions = append(positions, newPosition) } if len(positions) > 0 { @@ -955,11 +956,11 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) { return err } - tp := TaskPosition{ - TaskID: t.ID, - ProjectViewID: view.ID, - Position: calculateDefaultPosition(t.Index, t.Position), + tp, err := calculateNewPositionForTask(s, a, t, view) + if err != nil { + return err } + err = tp.Update(s, a) if err != nil { return err