Endpoint to get tasks on a list (#108)

This commit is contained in:
konrad 2019-11-29 22:59:20 +00:00
parent 4c55b4455c
commit d96831fe3a
8 changed files with 547 additions and 46 deletions

View file

@ -0,0 +1,182 @@
// Copyright 2019 Vikunja and contriubtors. All rights reserved.
//
// This file is part of Vikunja.
//
// Vikunja is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vikunja 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
package integrations
import (
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/web/handler"
"github.com/stretchr/testify/assert"
"net/url"
"testing"
)
func TestTaskCollection(t *testing.T) {
testHandler := webHandlerTest{
user: &testuser1,
strFunc: func() handler.CObject {
return &models.TaskCollection{}
},
t: t,
}
// Only run specific nested tests:
// ^TestTask$/^Update$/^Update_task_items$/^Removing_Assignees_null$
t.Run("ReadAll", func(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(nil, map[string]string{"list": "1"})
assert.NoError(t, err)
// Not using assert.Equal to avoid having the tests break every time we add new fixtures
assert.Contains(t, rec.Body.String(), `task #1`)
assert.Contains(t, rec.Body.String(), `task #2`)
assert.Contains(t, rec.Body.String(), `task #3`)
assert.Contains(t, rec.Body.String(), `task #4`)
assert.Contains(t, rec.Body.String(), `task #5`)
assert.Contains(t, rec.Body.String(), `task #6`)
assert.Contains(t, rec.Body.String(), `task #7`)
assert.Contains(t, rec.Body.String(), `task #8`)
assert.Contains(t, rec.Body.String(), `task #9`)
assert.Contains(t, rec.Body.String(), `task #10`)
assert.Contains(t, rec.Body.String(), `task #11`)
assert.Contains(t, rec.Body.String(), `task #12`)
assert.NotContains(t, rec.Body.String(), `task #13`)
assert.NotContains(t, rec.Body.String(), `task #14`)
assert.NotContains(t, rec.Body.String(), `task #15`) // Shared via team readonly
assert.NotContains(t, rec.Body.String(), `task #16`) // Shared via team write
assert.NotContains(t, rec.Body.String(), `task #17`) // Shared via team admin
assert.NotContains(t, rec.Body.String(), `task #18`) // Shared via user readonly
assert.NotContains(t, rec.Body.String(), `task #19`) // Shared via user write
assert.NotContains(t, rec.Body.String(), `task #20`) // Shared via user admin
assert.NotContains(t, rec.Body.String(), `task #21`) // Shared via namespace team readonly
assert.NotContains(t, rec.Body.String(), `task #22`) // Shared via namespace team write
assert.NotContains(t, rec.Body.String(), `task #23`) // Shared via namespace team admin
assert.NotContains(t, rec.Body.String(), `task #24`) // Shared via namespace user readonly
assert.NotContains(t, rec.Body.String(), `task #25`) // Shared via namespace user write
assert.NotContains(t, rec.Body.String(), `task #26`) // Shared via namespace user admin
assert.Contains(t, rec.Body.String(), `task #27`)
assert.Contains(t, rec.Body.String(), `task #28`)
assert.NotContains(t, rec.Body.String(), `task #32`)
})
t.Run("Search", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"s": []string{"task #6"}}, nil)
assert.NoError(t, err)
assert.NotContains(t, rec.Body.String(), `task #1`)
assert.NotContains(t, rec.Body.String(), `task #2`)
assert.NotContains(t, rec.Body.String(), `task #3`)
assert.NotContains(t, rec.Body.String(), `task #4`)
assert.NotContains(t, rec.Body.String(), `task #5`)
assert.Contains(t, rec.Body.String(), `task #6`)
assert.NotContains(t, rec.Body.String(), `task #7`)
assert.NotContains(t, rec.Body.String(), `task #8`)
assert.NotContains(t, rec.Body.String(), `task #9`)
assert.NotContains(t, rec.Body.String(), `task #10`)
assert.NotContains(t, rec.Body.String(), `task #11`)
assert.NotContains(t, rec.Body.String(), `task #12`)
assert.NotContains(t, rec.Body.String(), `task #13`)
assert.NotContains(t, rec.Body.String(), `task #14`)
})
t.Run("Sort Order", func(t *testing.T) {
// should equal priority desc
t.Run("by priority", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"priority"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
})
t.Run("by priority desc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"prioritydesc"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
})
t.Run("by priority asc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"priorityasc"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0.5,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
})
// should equal duedate desc
t.Run("by duedate", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedate"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
})
t.Run("by duedate desc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedatedesc"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
})
t.Run("by duedate asc", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedateasc"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"doneAt":0,"dueDate":1543616724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
})
t.Run("invalid parameter", func(t *testing.T) {
// Invalid parameter should not sort at all
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"loremipsum"}}, nil)
assert.NoError(t, err)
assert.NotContains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"priority":1`)
assert.NotContains(t, rec.Body.String(), `{"id":4,"text":"task #4 low prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
assert.NotContains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"dueDate":1543636724,"reminderDates":null,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
assert.NotContains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"dueDate":1543616724,"reminderDates":null,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"dueDate":1543636724,"reminderDates":null,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
})
})
t.Run("Date range", func(t *testing.T) {
t.Run("start and end date", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"startdate": []string{"1540000000"}, "enddate": []string{"1544700001"}}, nil)
assert.NoError(t, err)
assert.NotContains(t, rec.Body.String(), `task #1`)
assert.NotContains(t, rec.Body.String(), `task #2`)
assert.NotContains(t, rec.Body.String(), `task #3`)
assert.NotContains(t, rec.Body.String(), `task #4`)
assert.Contains(t, rec.Body.String(), `task #5`)
assert.Contains(t, rec.Body.String(), `task #6`)
assert.Contains(t, rec.Body.String(), `task #7`)
assert.Contains(t, rec.Body.String(), `task #8`)
assert.Contains(t, rec.Body.String(), `task #9`)
assert.NotContains(t, rec.Body.String(), `task #10`)
assert.NotContains(t, rec.Body.String(), `task #11`)
assert.NotContains(t, rec.Body.String(), `task #12`)
assert.NotContains(t, rec.Body.String(), `task #13`)
assert.NotContains(t, rec.Body.String(), `task #14`)
})
t.Run("start date only", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"startdate": []string{"1540000000"}}, nil)
assert.NoError(t, err)
assert.NotContains(t, rec.Body.String(), `task #1`)
assert.NotContains(t, rec.Body.String(), `task #2`)
assert.NotContains(t, rec.Body.String(), `task #3`)
assert.NotContains(t, rec.Body.String(), `task #4`)
assert.Contains(t, rec.Body.String(), `task #5`)
assert.Contains(t, rec.Body.String(), `task #6`)
assert.Contains(t, rec.Body.String(), `task #7`)
assert.Contains(t, rec.Body.String(), `task #8`)
assert.Contains(t, rec.Body.String(), `task #9`)
assert.NotContains(t, rec.Body.String(), `task #10`)
assert.NotContains(t, rec.Body.String(), `task #11`)
assert.NotContains(t, rec.Body.String(), `task #12`)
assert.NotContains(t, rec.Body.String(), `task #13`)
assert.NotContains(t, rec.Body.String(), `task #14`)
})
t.Run("end date only", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"enddate": []string{"1544700001"}}, nil)
assert.NoError(t, err)
// If no start date but an end date is specified, this should be null
// since we don't have any tasks in the fixtures with an end date >
// the current date.
assert.Equal(t, "null\n", rec.Body.String())
})
})
})
}

View file

@ -54,8 +54,21 @@ func TestTask(t *testing.T) {
assert.Contains(t, rec.Body.String(), `task #12`) assert.Contains(t, rec.Body.String(), `task #12`)
assert.NotContains(t, rec.Body.String(), `task #13`) assert.NotContains(t, rec.Body.String(), `task #13`)
assert.NotContains(t, rec.Body.String(), `task #14`) assert.NotContains(t, rec.Body.String(), `task #14`)
// TODO: add more tasks, since the whole point of this is to get all tasks in all lists where the user assert.NotContains(t, rec.Body.String(), `task #13`)
// has at least read access assert.NotContains(t, rec.Body.String(), `task #14`)
assert.Contains(t, rec.Body.String(), `task #15`) // Shared via team readonly
assert.Contains(t, rec.Body.String(), `task #16`) // Shared via team write
assert.Contains(t, rec.Body.String(), `task #17`) // Shared via team admin
assert.Contains(t, rec.Body.String(), `task #18`) // Shared via user readonly
assert.Contains(t, rec.Body.String(), `task #19`) // Shared via user write
assert.Contains(t, rec.Body.String(), `task #20`) // Shared via user admin
assert.Contains(t, rec.Body.String(), `task #21`) // Shared via namespace team readonly
assert.Contains(t, rec.Body.String(), `task #22`) // Shared via namespace team write
assert.Contains(t, rec.Body.String(), `task #23`) // Shared via namespace team admin
assert.Contains(t, rec.Body.String(), `task #24`) // Shared via namespace user readonly
assert.Contains(t, rec.Body.String(), `task #25`) // Shared via namespace user write
assert.Contains(t, rec.Body.String(), `task #26`) // Shared via namespace user admin
// TODO: Add some cases where the user has access to the list, somhow shared
}) })
t.Run("Search", func(t *testing.T) { t.Run("Search", func(t *testing.T) {
rec, err := testHandler.testReadAllWithUser(url.Values{"s": []string{"task #6"}}, nil) rec, err := testHandler.testReadAllWithUser(url.Values{"s": []string{"task #6"}}, nil)

View file

@ -0,0 +1,113 @@
// Copyright 2019 Vikunja and contriubtors. All rights reserved.
//
// This file is part of Vikunja.
//
// Vikunja is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vikunja 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
package models
import (
"code.vikunja.io/web"
"time"
)
// TaskCollection is a struct used to hold filter details and not clutter the Task struct with information not related to actual tasks.
type TaskCollection struct {
ListID int64 `param:"list"`
Sorting string `query:"sort"` // Parameter to sort by
StartDateSortUnix int64 `query:"startdate"`
EndDateSortUnix int64 `query:"enddate"`
Lists []*List
web.CRUDable `xorm:"-" json:"-"`
web.Rights `xorm:"-" json:"-"`
}
// ReadAll gets all tasks for a collection
// @Summary Get tasks on a list
// @Description Returns all tasks for the current list.
// @tags task
// @Accept json
// @Produce json
// @Param listID path int true "The list ID."
// @Param page query int false "The page number. Used for pagination. If not provided, the first page of results is returned."
// @Param per_page query int false "The maximum number of items per page. Note this parameter is limited by the configured maximum of items per page."
// @Param s query string false "Search tasks by task text."
// @Param sort query string false "The sorting parameter. Possible values to sort by are priority, prioritydesc, priorityasc, duedate, duedatedesc, duedateasc."
// @Param startdate query int false "The start date parameter to filter by. Expects a unix timestamp. If no end date, but a start date is specified, the end date is set to the current time."
// @Param enddate query int false "The end date parameter to filter by. Expects a unix timestamp. If no start date, but an end date is specified, the start date is set to the current time."
// @Security JWTKeyAuth
// @Success 200 {array} models.Task "The tasks"
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{listID}/tasks [get]
func (tf *TaskCollection) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, totalItems int64, err error) {
var sortby SortBy
switch tf.Sorting {
case "priority":
sortby = SortTasksByPriorityDesc
case "prioritydesc":
sortby = SortTasksByPriorityDesc
case "priorityasc":
sortby = SortTasksByPriorityAsc
case "duedate":
sortby = SortTasksByDueDateDesc
case "duedatedesc":
sortby = SortTasksByDueDateDesc
case "duedateasc":
sortby = SortTasksByDueDateAsc
default:
sortby = SortTasksByUnsorted
}
taskopts := &taskOptions{
search: search,
sortby: sortby,
startDate: time.Unix(tf.StartDateSortUnix, 0),
endDate: time.Unix(tf.EndDateSortUnix, 0),
page: page,
perPage: perPage,
}
shareAuth, is := a.(*LinkSharing)
if is {
list := &List{ID: shareAuth.ListID}
err := list.GetSimpleByID()
if err != nil {
return nil, 0, 0, err
}
return getTasksForLists([]*List{list}, taskopts)
}
// If the list ID is not set, we get all tasks for the user.
// This allows to use this function in Task.ReadAll with a possibility to deprecate the latter at some point.
if tf.ListID == 0 {
tf.Lists, _, _, err = getRawListsForUser("", &User{ID: a.GetID()}, -1, 0)
if err != nil {
return nil, 0, 0, err
}
} else {
// Check the list exists and the user has acess on it
list := &List{ID: tf.ListID}
canRead, err := list.CanRead(a)
if err != nil {
return nil, 0, 0, err
}
if !canRead {
return nil, 0, 0, ErrUserDoesNotHaveAccessToList{ListID: tf.ListID}
}
tf.Lists = []*List{{ID: tf.ListID}}
}
return getTasksForLists(tf.Lists, taskopts)
}

View file

@ -134,50 +134,12 @@ const (
// @Failure 500 {object} models.Message "Internal error" // @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/all [get] // @Router /tasks/all [get]
func (t *Task) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, totalItems int64, err error) { func (t *Task) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, totalItems int64, err error) {
var sortby SortBy tc := &TaskCollection{
switch t.Sorting { Sorting: t.Sorting,
case "priority": StartDateSortUnix: t.StartDateSortUnix,
sortby = SortTasksByPriorityDesc EndDateSortUnix: t.EndDateSortUnix,
case "prioritydesc":
sortby = SortTasksByPriorityDesc
case "priorityasc":
sortby = SortTasksByPriorityAsc
case "duedate":
sortby = SortTasksByDueDateDesc
case "duedatedesc":
sortby = SortTasksByDueDateDesc
case "duedateasc":
sortby = SortTasksByDueDateAsc
default:
sortby = SortTasksByUnsorted
} }
return tc.ReadAll(a, search, page, perPage)
taskopts := &taskOptions{
search: search,
sortby: sortby,
startDate: time.Unix(t.StartDateSortUnix, 0),
endDate: time.Unix(t.EndDateSortUnix, 0),
page: page,
perPage: perPage,
}
shareAuth, is := a.(*LinkSharing)
if is {
list := &List{ID: shareAuth.ListID}
err := list.GetSimpleByID()
if err != nil {
return nil, 0, 0, err
}
return getTasksForLists([]*List{list}, taskopts)
}
// Get all lists for the user
lists, _, _, err := getRawListsForUser("", &User{ID: a.GetID()}, -1, 0)
if err != nil {
return nil, 0, 0, err
}
return getTasksForLists(lists, taskopts)
} }
type taskOptions struct { type taskOptions struct {

View file

@ -226,6 +226,13 @@ func registerAPIRoutes(a *echo.Group) {
a.DELETE("/tasks/:listtask", taskHandler.DeleteWeb) a.DELETE("/tasks/:listtask", taskHandler.DeleteWeb)
a.POST("/tasks/:listtask", taskHandler.UpdateWeb) a.POST("/tasks/:listtask", taskHandler.UpdateWeb)
taskCollectionHandler := &handler.WebHandler{
EmptyStruct: func() handler.CObject {
return &models.TaskCollection{}
},
}
a.GET("/lists/:list/tasks", taskCollectionHandler.ReadAllWeb)
bulkTaskHandler := &handler.WebHandler{ bulkTaskHandler := &handler.WebHandler{
EmptyStruct: func() handler.CObject { EmptyStruct: func() handler.CObject {
return &models.BulkTask{} return &models.BulkTask{}

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-11-02 21:06:44.848486087 +0100 CET m=+0.175638002 // 2019-11-29 18:11:53.766019702 +0100 CET m=+0.153156633
package swagger package swagger
@ -967,6 +967,88 @@ var doc = `{
} }
} }
}, },
"/lists/{listID}/tasks": {
"get": {
"security": [
{
"JWTKeyAuth": []
}
],
"description": "Returns all tasks for the current list.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"task"
],
"summary": "Get tasks on a list",
"parameters": [
{
"type": "integer",
"description": "The list ID.",
"name": "listID",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "The page number. Used for pagination. If not provided, the first page of results is returned.",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "The maximum number of items per page. Note this parameter is limited by the configured maximum of items per page.",
"name": "per_page",
"in": "query"
},
{
"type": "string",
"description": "Search tasks by task text.",
"name": "s",
"in": "query"
},
{
"type": "string",
"description": "The sorting parameter. Possible values to sort by are priority, prioritydesc, priorityasc, duedate, duedatedesc, duedateasc.",
"name": "sort",
"in": "query"
},
{
"type": "integer",
"description": "The start date parameter to filter by. Expects a unix timestamp. If no end date, but a start date is specified, the end date is set to the current time.",
"name": "startdate",
"in": "query"
},
{
"type": "integer",
"description": "The end date parameter to filter by. Expects a unix timestamp. If no start date, but an end date is specified, the start date is set to the current time.",
"name": "enddate",
"in": "query"
}
],
"responses": {
"200": {
"description": "The tasks",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/models.Task"
}
}
},
"500": {
"description": "Internal error",
"schema": {
"$ref": "#/definitions/models.Message"
}
}
}
}
},
"/lists/{listID}/teams/{teamID}": { "/lists/{listID}/teams/{teamID}": {
"post": { "post": {
"security": [ "security": [

View file

@ -949,6 +949,88 @@
} }
} }
}, },
"/lists/{listID}/tasks": {
"get": {
"security": [
{
"JWTKeyAuth": []
}
],
"description": "Returns all tasks for the current list.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"task"
],
"summary": "Get tasks on a list",
"parameters": [
{
"type": "integer",
"description": "The list ID.",
"name": "listID",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "The page number. Used for pagination. If not provided, the first page of results is returned.",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "The maximum number of items per page. Note this parameter is limited by the configured maximum of items per page.",
"name": "per_page",
"in": "query"
},
{
"type": "string",
"description": "Search tasks by task text.",
"name": "s",
"in": "query"
},
{
"type": "string",
"description": "The sorting parameter. Possible values to sort by are priority, prioritydesc, priorityasc, duedate, duedatedesc, duedateasc.",
"name": "sort",
"in": "query"
},
{
"type": "integer",
"description": "The start date parameter to filter by. Expects a unix timestamp. If no end date, but a start date is specified, the end date is set to the current time.",
"name": "startdate",
"in": "query"
},
{
"type": "integer",
"description": "The end date parameter to filter by. Expects a unix timestamp. If no start date, but an end date is specified, the start date is set to the current time.",
"name": "enddate",
"in": "query"
}
],
"responses": {
"200": {
"description": "The tasks",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/models.Task"
}
}
},
"500": {
"description": "Internal error",
"schema": {
"$ref": "#/definitions/models.Message"
}
}
}
}
},
"/lists/{listID}/teams/{teamID}": { "/lists/{listID}/teams/{teamID}": {
"post": { "post": {
"security": [ "security": [

View file

@ -1642,6 +1642,66 @@ paths:
summary: Get one link shares for a list summary: Get one link shares for a list
tags: tags:
- sharing - sharing
/lists/{listID}/tasks:
get:
consumes:
- application/json
description: Returns all tasks for the current list.
parameters:
- description: The list ID.
in: path
name: listID
required: true
type: integer
- description: The page number. Used for pagination. If not provided, the first
page of results is returned.
in: query
name: page
type: integer
- description: The maximum number of items per page. Note this parameter is
limited by the configured maximum of items per page.
in: query
name: per_page
type: integer
- description: Search tasks by task text.
in: query
name: s
type: string
- description: The sorting parameter. Possible values to sort by are priority,
prioritydesc, priorityasc, duedate, duedatedesc, duedateasc.
in: query
name: sort
type: string
- description: The start date parameter to filter by. Expects a unix timestamp.
If no end date, but a start date is specified, the end date is set to the
current time.
in: query
name: startdate
type: integer
- description: The end date parameter to filter by. Expects a unix timestamp.
If no start date, but an end date is specified, the start date is set to
the current time.
in: query
name: enddate
type: integer
produces:
- application/json
responses:
"200":
description: The tasks
schema:
items:
$ref: '#/definitions/models.Task'
type: array
"500":
description: Internal error
schema:
$ref: '#/definitions/models.Message'
security:
- JWTKeyAuth: []
summary: Get tasks on a list
tags:
- task
/lists/{listID}/teams/{teamID}: /lists/{listID}/teams/{teamID}:
delete: delete:
description: Delets a team from a list. The team won't have access to the list description: Delets a team from a list. The team won't have access to the list