Fixed labels being displayed multiple times if they were associated with more than one task (#99)

This commit is contained in:
konrad 2019-09-20 15:52:09 +00:00 committed by Gitea
parent 71ef86e0df
commit 8d5a2685c4
7 changed files with 40 additions and 26 deletions

View file

@ -2,3 +2,7 @@
task_id: 1 task_id: 1
label_id: 4 label_id: 4
created: 0 created: 0
- id: 2
task_id: 2
label_id: 4
created: 0

View file

@ -144,10 +144,11 @@ func (l *Label) ReadAll(search string, a web.Auth, page int) (ls interface{}, er
} }
return getLabelsByTaskIDs(&LabelByTaskIDsOptions{ return getLabelsByTaskIDs(&LabelByTaskIDsOptions{
Search: search, Search: search,
User: u, User: u,
TaskIDs: taskIDs, TaskIDs: taskIDs,
GetUnusedLabels: true, GetUnusedLabels: true,
GroupByLabelIDsOnly: true,
}) })
} }

View file

@ -128,17 +128,18 @@ func (lt *LabelTask) ReadAll(search string, a web.Auth, page int) (labels interf
// Helper struct, contains the label + its task ID // Helper struct, contains the label + its task ID
type labelWithTaskID struct { type labelWithTaskID struct {
TaskID int64 TaskID int64 `json:"-"`
Label `xorm:"extends"` Label `xorm:"extends"`
} }
// LabelByTaskIDsOptions is a struct to not clutter the function with too many optional parameters. // LabelByTaskIDsOptions is a struct to not clutter the function with too many optional parameters.
type LabelByTaskIDsOptions struct { type LabelByTaskIDsOptions struct {
User *User User *User
Search string Search string
Page int Page int
TaskIDs []int64 TaskIDs []int64
GetUnusedLabels bool GetUnusedLabels bool
GroupByLabelIDsOnly bool
} }
// Helper function to get all labels for a set of tasks // Helper function to get all labels for a set of tasks
@ -153,6 +154,15 @@ func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, err
requestOrNil = "label_task.label_id != null OR labels.created_by_id = ?" requestOrNil = "label_task.label_id != null OR labels.created_by_id = ?"
} }
// We still need the task ID when we want to get all labels for a task, but because of this, we get the same label
// multiple times when it is associated to more than one task.
// Because of this whole thing, we need this extra switch here to only group by Task IDs if needed.
// Probably not the most ideal solution.
var groupBy = "labels.id,label_task.task_id"
if opts.GroupByLabelIDsOnly {
groupBy = "labels.id"
}
// Get all labels associated with these tasks // Get all labels associated with these tasks
var labels []*labelWithTaskID var labels []*labelWithTaskID
err = x.Table("labels"). err = x.Table("labels").
@ -161,7 +171,7 @@ func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, err
Where(requestOrNil, uidOrNil). Where(requestOrNil, uidOrNil).
Or(builder.In("label_task.task_id", opts.TaskIDs)). Or(builder.In("label_task.task_id", opts.TaskIDs)).
And("labels.title LIKE ?", "%"+opts.Search+"%"). And("labels.title LIKE ?", "%"+opts.Search+"%").
GroupBy("labels.id,label_task.task_id"). // This filters out doubles GroupBy(groupBy).
Limit(getLimitFromPageIndex(opts.Page)). Limit(getLimitFromPageIndex(opts.Page)).
Find(&labels) Find(&labels)
if err != nil { if err != nil {

View file

@ -65,8 +65,18 @@ func sortTasksForTesting(by SortBy) (tasks []*Task) {
CreatedByID: 1, CreatedByID: 1,
CreatedBy: user1, CreatedBy: user1,
ListID: 1, ListID: 1,
Created: 1543626724, Labels: []*Label{
Updated: 1543626724, {
ID: 4,
Title: "Label #4 - visible via other task",
CreatedByID: 2,
CreatedBy: user2,
Updated: 0,
Created: 0,
},
},
Created: 1543626724,
Updated: 1543626724,
}, },
{ {
ID: 3, ID: 3,

View file

@ -1,6 +1,6 @@
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT // GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// This file was generated by swaggo/swag at // This file was generated by swaggo/swag at
// 2019-08-31 22:48:49.201391811 +0200 CEST m=+0.228973511 // 2019-09-20 17:41:39.321673846 +0200 CEST m=+0.137010842
package swagger package swagger
@ -4278,10 +4278,6 @@ var doc = `{
"description": "The ID of the shared thing", "description": "The ID of the shared thing",
"type": "integer" "type": "integer"
}, },
"list": {
"type": "object",
"$ref": "#/definitions/models.List"
},
"right": { "right": {
"description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", "description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer", "type": "integer",

View file

@ -4264,10 +4264,6 @@
"description": "The ID of the shared thing", "description": "The ID of the shared thing",
"type": "integer" "type": "integer"
}, },
"list": {
"type": "object",
"$ref": "#/definitions/models.List"
},
"right": { "right": {
"description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", "description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer", "type": "integer",

View file

@ -182,9 +182,6 @@ definitions:
id: id:
description: The ID of the shared thing description: The ID of the shared thing
type: integer type: integer
list:
$ref: '#/definitions/models.List'
type: object
right: right:
default: 0 default: 0
description: The right this list is shared with. 0 = Read only, 1 = Read & description: The right this list is shared with. 0 = Read only, 1 = Read &