feat(views)!: make updating a bucket work again
This commit is contained in:
parent
a13276e28e
commit
f2a0d69670
@ -33,8 +33,9 @@ func (task20240315110428) TableName() string {
|
||||
}
|
||||
|
||||
type taskBuckets20240315110428 struct {
|
||||
BucketID int64 `xorm:"bigint not null index"`
|
||||
TaskID int64 `xorm:"bigint not null index"`
|
||||
BucketID int64 `xorm:"bigint not null index"`
|
||||
TaskID int64 `xorm:"bigint not null index"`
|
||||
ProjectViewID int64 `xorm:"bigint not null index"`
|
||||
}
|
||||
|
||||
func (taskBuckets20240315110428) TableName() string {
|
||||
|
@ -71,8 +71,13 @@ func (b *Bucket) TableName() string {
|
||||
}
|
||||
|
||||
type TaskBucket struct {
|
||||
BucketID int64 `xorm:"bigint not null index"`
|
||||
TaskID int64 `xorm:"bigint not null index"`
|
||||
BucketID int64 `xorm:"bigint not null index"`
|
||||
TaskID int64 `xorm:"bigint not null index"`
|
||||
ProjectViewID int64 `xorm:"bigint not null index"`
|
||||
}
|
||||
|
||||
func (b *TaskBucket) TableName() string {
|
||||
return "task_buckets"
|
||||
}
|
||||
|
||||
func getBucketByID(s *xorm.Session, id int64) (b *Bucket, err error) {
|
||||
|
@ -151,6 +151,14 @@ func (p *ProjectView) TableName() string {
|
||||
return "project_views"
|
||||
}
|
||||
|
||||
func getViewsForProject(s *xorm.Session, projectID int64) (views []*ProjectView, err error) {
|
||||
views = []*ProjectView{}
|
||||
err = s.
|
||||
Where("project_id = ?", projectID).
|
||||
Find(&views)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadAll gets all project views
|
||||
// @Summary Get all project views for a project
|
||||
// @Description Returns all project views for a sepcific project
|
||||
@ -173,12 +181,9 @@ func (p *ProjectView) ReadAll(s *xorm.Session, a web.Auth, _ string, _ int, _ in
|
||||
return nil, 0, 0, ErrGenericForbidden{}
|
||||
}
|
||||
|
||||
projectViews := []*ProjectView{}
|
||||
err = s.
|
||||
Where("project_id = ?", p.ProjectID).
|
||||
Find(&projectViews)
|
||||
projectViews, err := getViewsForProject(s, p.ProjectID)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
totalCount, err := s.
|
||||
|
@ -648,41 +648,48 @@ func checkBucketLimit(s *xorm.Session, t *Task, bucket *Bucket) (err error) {
|
||||
}
|
||||
|
||||
// Contains all the task logic to figure out what bucket to use for this task.
|
||||
func setTaskBucket(s *xorm.Session, task *Task, originalTask *Task, doCheckBucketLimit bool, view *ProjectView) (targetBucket *Bucket, err error) {
|
||||
func setTaskBucket(s *xorm.Session, task *Task, originalTask *Task, view *ProjectView, targetBucket *TaskBucket) (err error) {
|
||||
|
||||
if view == nil {
|
||||
view, err = GetProjectViewByID(s, view.ID, task.ProjectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var shouldChangeBucket = true
|
||||
if targetBucket == nil {
|
||||
targetBucket = &TaskBucket{
|
||||
BucketID: 0,
|
||||
TaskID: task.ID,
|
||||
ProjectViewID: view.ID,
|
||||
}
|
||||
}
|
||||
|
||||
var bucket *Bucket
|
||||
if task.Done && originalTask != nil &&
|
||||
(!originalTask.Done || task.ProjectID != originalTask.ProjectID) {
|
||||
task.BucketID = view.DoneBucketID
|
||||
oldTaskBucket := &TaskBucket{}
|
||||
_, err = s.
|
||||
Where("task_id = ? AND project_view_id = ?", task.ID, view.ID).
|
||||
Get(oldTaskBucket)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if task.BucketID == 0 && originalTask != nil && originalTask.BucketID != 0 {
|
||||
task.BucketID = originalTask.BucketID
|
||||
if task.Done && originalTask != nil &&
|
||||
(!originalTask.Done || task.ProjectID != originalTask.ProjectID) {
|
||||
targetBucket.BucketID = view.DoneBucketID
|
||||
}
|
||||
|
||||
if targetBucket.BucketID == 0 && oldTaskBucket.BucketID != 0 {
|
||||
shouldChangeBucket = false
|
||||
}
|
||||
|
||||
// Either no bucket was provided or the task was moved between projects
|
||||
// But if the task was moved between projects, don't update the done bucket
|
||||
// because then we have it already updated to the done bucket.
|
||||
if task.BucketID == 0 ||
|
||||
if targetBucket.BucketID == 0 ||
|
||||
(originalTask != nil && task.ProjectID != 0 && originalTask.ProjectID != task.ProjectID && !task.Done) {
|
||||
task.BucketID, err = getDefaultBucketID(s, view)
|
||||
targetBucket.BucketID, err = getDefaultBucketID(s, view)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if bucket == nil {
|
||||
bucket, err = getBucketByID(s, task.BucketID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
bucket, err := getBucketByID(s, targetBucket.BucketID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If there is a bucket set, make sure they belong to the same project as the task
|
||||
@ -693,9 +700,10 @@ func setTaskBucket(s *xorm.Session, task *Task, originalTask *Task, doCheckBucke
|
||||
|
||||
// Check the bucket limit
|
||||
// Only check the bucket limit if the task is being moved between buckets, allow reordering the task within a bucket
|
||||
if doCheckBucketLimit {
|
||||
if err := checkBucketLimit(s, task, bucket); err != nil {
|
||||
return nil, err
|
||||
if targetBucket.BucketID != 0 && targetBucket.BucketID != oldTaskBucket.BucketID {
|
||||
err = checkBucketLimit(s, task, bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@ -703,7 +711,26 @@ func setTaskBucket(s *xorm.Session, task *Task, originalTask *Task, doCheckBucke
|
||||
task.Done = true
|
||||
}
|
||||
|
||||
return bucket, nil
|
||||
// If the task was moved into the done bucket and the task has a repeating cycle we should not update
|
||||
// the bucket.
|
||||
if bucket.ID == view.DoneBucketID && task.RepeatAfter > 0 {
|
||||
task.Done = true // This will trigger the correct re-scheduling of the task (happening in updateDone later)
|
||||
shouldChangeBucket = false
|
||||
}
|
||||
|
||||
if shouldChangeBucket {
|
||||
_, err = s.
|
||||
Where("task_id = ? AND project_view_id = ?", task.ID, view.ID).
|
||||
Delete(&TaskBucket{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
targetBucket.BucketID = bucket.ID
|
||||
_, err = s.Insert(targetBucket)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func calculateDefaultPosition(entityID int64, position float64) float64 {
|
||||
@ -714,6 +741,18 @@ func calculateDefaultPosition(entityID int64, position float64) float64 {
|
||||
return position
|
||||
}
|
||||
|
||||
func (t *Task) setTaskPosition(s *xorm.Session, position float64, view *ProjectView) (err error) {
|
||||
|
||||
pos := &TaskPosition{
|
||||
TaskID: t.ID,
|
||||
ProjectViewID: view.ID,
|
||||
Position: calculateDefaultPosition(t.Index, position),
|
||||
}
|
||||
|
||||
_, err = s.Insert(pos)
|
||||
return
|
||||
}
|
||||
|
||||
func getNextTaskIndex(s *xorm.Session, projectID int64) (nextIndex int64, err error) {
|
||||
latestTask := &Task{}
|
||||
_, err = s.
|
||||
@ -771,21 +810,12 @@ func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool) (err
|
||||
t.UID = uuid.NewString()
|
||||
}
|
||||
|
||||
// Get the default bucket and move the task there
|
||||
_, err = setTaskBucket(s, t, nil, true, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the index for this task
|
||||
t.Index, err = getNextTaskIndex(s, t.ProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If no position was supplied, set a default one
|
||||
t.Position = calculateDefaultPosition(t.Index, t.Position)
|
||||
|
||||
t.HexColor = utils.NormalizeHex(t.HexColor)
|
||||
|
||||
_, err = s.Insert(t)
|
||||
@ -793,6 +823,25 @@ func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool) (err
|
||||
return err
|
||||
}
|
||||
|
||||
views, err := getViewsForProject(s, t.ProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, view := range views {
|
||||
|
||||
// Get the default bucket and move the task there
|
||||
err = setTaskBucket(s, t, nil, view, &TaskBucket{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = t.setTaskPosition(s, t.Position, view)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
t.CreatedBy = createdBy
|
||||
|
||||
// Update the assignees
|
||||
@ -864,21 +913,29 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) {
|
||||
// Old task has the stored reminders
|
||||
ot.Reminders = reminders
|
||||
|
||||
project, err := GetProjectSimpleByID(s, t.ProjectID)
|
||||
views, err := getViewsForProject(s, t.ProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
targetBucket, err := setTaskBucket(s, t, &ot, t.BucketID != 0 && t.BucketID != ot.BucketID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, view := range views {
|
||||
// bucket id mitgeben, dann den view zu dem bucket suchen und updaten wenn nötig
|
||||
|
||||
// If the task was moved into the done bucket and the task has a repeating cycle we should not update
|
||||
// the bucket.
|
||||
if targetBucket.ID == project.DoneBucketID && t.RepeatAfter > 0 {
|
||||
t.Done = true // This will trigger the correct re-scheduling of the task (happening in updateDone later)
|
||||
t.BucketID = ot.BucketID
|
||||
taskBucket := &TaskBucket{
|
||||
BucketID: t.BucketID,
|
||||
TaskID: t.ID,
|
||||
ProjectViewID: view.ID,
|
||||
}
|
||||
|
||||
err = setTaskBucket(s, t, &ot, view, taskBucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = t.setTaskPosition(s, t.Position, view)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// When a repeating task is marked as done, we update all deadlines and reminders and set it as undone
|
||||
@ -909,7 +966,6 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) {
|
||||
"percent_done",
|
||||
"project_id",
|
||||
"bucket_id",
|
||||
"position",
|
||||
"repeat_mode",
|
||||
"cover_image_attachment_id",
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user