feat(views): sort tasks by their position relative to the view they're in
This commit is contained in:
parent
2502776460
commit
d1d07f462c
@ -99,6 +99,7 @@ This document describes the different errors Vikunja can return.
|
|||||||
| 4023 | 409 | Tried to create a task relation which would create a cycle. |
|
| 4023 | 409 | Tried to create a task relation which would create a cycle. |
|
||||||
| 4024 | 400 | The provided filter expression is invalid. |
|
| 4024 | 400 | The provided filter expression is invalid. |
|
||||||
| 4025 | 400 | The reaction kind is invalid. |
|
| 4025 | 400 | The reaction kind is invalid. |
|
||||||
|
| 4026 | 400 | You must provide a project view ID when sorting by position. |
|
||||||
|
|
||||||
## Team
|
## Team
|
||||||
|
|
||||||
|
@ -1114,6 +1114,25 @@ func (err ErrInvalidReactionEntityKind) HTTPError() web.HTTPError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrMustHaveProjectViewToSortByPosition represents an error where no project view id was supplied
|
||||||
|
type ErrMustHaveProjectViewToSortByPosition struct{}
|
||||||
|
|
||||||
|
func (err ErrMustHaveProjectViewToSortByPosition) Error() string {
|
||||||
|
return "You must provide a project view ID when sorting by position"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrCodeMustHaveProjectViewToSortByPosition holds the unique world-error code of this error
|
||||||
|
const ErrCodeMustHaveProjectViewToSortByPosition = 4026
|
||||||
|
|
||||||
|
// HTTPError holds the http error description
|
||||||
|
func (err ErrMustHaveProjectViewToSortByPosition) HTTPError() web.HTTPError {
|
||||||
|
return web.HTTPError{
|
||||||
|
HTTPCode: http.StatusBadRequest,
|
||||||
|
Code: ErrCodeMustHaveProjectViewToSortByPosition,
|
||||||
|
Message: "You must provide a project view ID when sorting by position",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ============
|
// ============
|
||||||
// Team errors
|
// Team errors
|
||||||
// ============
|
// ============
|
||||||
|
@ -200,6 +200,7 @@ func GetTasksInBucketsForView(s *xorm.Session, view *ProjectView, opts *taskSear
|
|||||||
|
|
||||||
opts.sortby = []*sortParam{
|
opts.sortby = []*sortParam{
|
||||||
{
|
{
|
||||||
|
projectViewID: view.ProjectID,
|
||||||
orderBy: orderAscending,
|
orderBy: orderAscending,
|
||||||
sortBy: taskPropertyPosition,
|
sortBy: taskPropertyPosition,
|
||||||
},
|
},
|
||||||
|
@ -193,6 +193,14 @@ func (tf *TaskCollection) ReadAll(s *xorm.Session, a web.Auth, search string, pa
|
|||||||
opts.page = page
|
opts.page = page
|
||||||
opts.perPage = perPage
|
opts.perPage = perPage
|
||||||
|
|
||||||
|
if view != nil {
|
||||||
|
opts.sortby = append(opts.sortby, &sortParam{
|
||||||
|
projectViewID: view.ID,
|
||||||
|
sortBy: taskPropertyPosition,
|
||||||
|
orderBy: orderAscending,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
shareAuth, is := a.(*LinkSharing)
|
shareAuth, is := a.(*LinkSharing)
|
||||||
if is {
|
if is {
|
||||||
project, err := GetProjectSimpleByID(s, shareAuth.ProjectID)
|
project, err := GetProjectSimpleByID(s, shareAuth.ProjectID)
|
||||||
|
@ -20,6 +20,7 @@ type (
|
|||||||
sortParam struct {
|
sortParam struct {
|
||||||
sortBy string
|
sortBy string
|
||||||
orderBy sortOrder // asc or desc
|
orderBy sortOrder // asc or desc
|
||||||
|
projectViewID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
sortOrder string
|
sortOrder string
|
||||||
@ -72,5 +73,10 @@ func (sp *sortParam) validate() error {
|
|||||||
if sp.orderBy != orderDescending && sp.orderBy != orderAscending {
|
if sp.orderBy != orderDescending && sp.orderBy != orderAscending {
|
||||||
return ErrInvalidSortOrder{OrderBy: sp.orderBy}
|
return ErrInvalidSortOrder{OrderBy: sp.orderBy}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sp.sortBy == taskPropertyPosition && sp.projectViewID == 0 {
|
||||||
|
return ErrMustHaveProjectViewToSortByPosition{}
|
||||||
|
}
|
||||||
|
|
||||||
return validateTaskField(sp.sortBy)
|
return validateTaskField(sp.sortBy)
|
||||||
}
|
}
|
||||||
|
@ -53,14 +53,19 @@ func getOrderByDBStatement(opts *taskSearchOptions) (orderby string, err error)
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var prefix string
|
||||||
|
if param.sortBy == taskPropertyPosition {
|
||||||
|
prefix = "task_positions."
|
||||||
|
}
|
||||||
|
|
||||||
// Mysql sorts columns with null values before ones without null value.
|
// Mysql sorts columns with null values before ones without null value.
|
||||||
// Because it does not have support for NULLS FIRST or NULLS LAST we work around this by
|
// Because it does not have support for NULLS FIRST or NULLS LAST we work around this by
|
||||||
// first sorting for null (or not null) values and then the order we actually want to.
|
// first sorting for null (or not null) values and then the order we actually want to.
|
||||||
if db.Type() == schemas.MYSQL {
|
if db.Type() == schemas.MYSQL {
|
||||||
orderby += "`" + param.sortBy + "` IS NULL, "
|
orderby += prefix + "`" + param.sortBy + "` IS NULL, "
|
||||||
}
|
}
|
||||||
|
|
||||||
orderby += "`" + param.sortBy + "` " + param.orderBy.String()
|
orderby += prefix + "`" + param.sortBy + "` " + param.orderBy.String()
|
||||||
|
|
||||||
// Postgres and sqlite allow us to control how columns with null values are sorted.
|
// Postgres and sqlite allow us to control how columns with null values are sorted.
|
||||||
// To make that consistent with the sort order we have and other dbms, we're adding a separate clause here.
|
// To make that consistent with the sort order we have and other dbms, we're adding a separate clause here.
|
||||||
@ -253,6 +258,13 @@ func (d *dbTaskSearcher) Search(opts *taskSearchOptions) (tasks []*Task, totalCo
|
|||||||
query = query.Limit(limit, start)
|
query = query.Limit(limit, start)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, param := range opts.sortby {
|
||||||
|
if param.sortBy == taskPropertyPosition {
|
||||||
|
query = query.Join("LEFT", "task_positions", "task_positions.task_id = tasks.id AND task_positions.project_view_id = ?", param.projectViewID)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tasks = []*Task{}
|
tasks = []*Task{}
|
||||||
err = query.OrderBy(orderby).Find(&tasks)
|
err = query.OrderBy(orderby).Find(&tasks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user