Added pagination (#16)
This commit is contained in:
parent
0e7e1b7e38
commit
d232836423
22 changed files with 71 additions and 31 deletions
|
@ -222,7 +222,7 @@ Teams sind global, d.h. Ein Team kann mehrere Namespaces verwalten.
|
||||||
* [ ] Wir brauchen noch ne gute idee, wie man die listen kriegt, auf die man nur so Zugriff hat (ohne namespace)
|
* [ ] Wir brauchen noch ne gute idee, wie man die listen kriegt, auf die man nur so Zugriff hat (ohne namespace)
|
||||||
* Dazu am Besten nen pseudonamespace anlegen (id -1 oder so), der hat das dann alles
|
* Dazu am Besten nen pseudonamespace anlegen (id -1 oder so), der hat das dann alles
|
||||||
* [ ] Validation der ankommenden structs, am besten mit https://github.com/go-validator/validator oder mit dem Ding von echo
|
* [ ] Validation der ankommenden structs, am besten mit https://github.com/go-validator/validator oder mit dem Ding von echo
|
||||||
* [ ] Pagination
|
* [x] Pagination
|
||||||
* Sollte in der Config definierbar sein, wie viel pro Seite angezeigt werden soll, die CRUD-Methoden übergeben dann ein "gibt mir die Seite sowieso" an die CRUDable-Funktionenen, die müssen das dann Auswerten. Geht leider nicht anders, wenn man erst 2342352 Einträge hohlt und die dann nachträglich auf 200 begrenzt ist das ne massive Ressourcenverschwendung.
|
* Sollte in der Config definierbar sein, wie viel pro Seite angezeigt werden soll, die CRUD-Methoden übergeben dann ein "gibt mir die Seite sowieso" an die CRUDable-Funktionenen, die müssen das dann Auswerten. Geht leider nicht anders, wenn man erst 2342352 Einträge hohlt und die dann nachträglich auf 200 begrenzt ist das ne massive Ressourcenverschwendung.
|
||||||
* [ ] Testing mit locust: https://locust.io/
|
* [ ] Testing mit locust: https://locust.io/
|
||||||
* [ ] Methode einbauen, um mit einem gültigen token ein neues gültiges zu kriegen
|
* [ ] Methode einbauen, um mit einem gültigen token ein neues gültiges zu kriegen
|
||||||
|
|
|
@ -4,7 +4,7 @@ Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"username": "user",
|
"username": "user",
|
||||||
"password": "12345"
|
"password": "1234"
|
||||||
}
|
}
|
||||||
|
|
||||||
> {% client.global.set("auth_token", response.body.token); %}
|
> {% client.global.set("auth_token", response.body.token); %}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Get all lists
|
# Get all lists
|
||||||
GET http://localhost:8080/api/v1/lists
|
GET http://localhost:8080/api/v1/lists?page=0
|
||||||
Authorization: Bearer {{auth_token}}
|
Authorization: Bearer {{auth_token}}
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
|
@ -7,6 +7,8 @@ service:
|
||||||
interface: ":3456"
|
interface: ":3456"
|
||||||
# The URL of the frontend, used to send password reset emails.
|
# The URL of the frontend, used to send password reset emails.
|
||||||
frontendurl: ""
|
frontendurl: ""
|
||||||
|
# The number of items which gets returned per page
|
||||||
|
pagecount: 50
|
||||||
|
|
||||||
database:
|
database:
|
||||||
# Database type to use. Supported types are mysql and sqlite.
|
# Database type to use. Supported types are mysql and sqlite.
|
||||||
|
@ -48,4 +50,4 @@ mailer:
|
||||||
# Wether to skip verification of the tls certificate on the server
|
# Wether to skip verification of the tls certificate on the server
|
||||||
skiptlsverify: false
|
skiptlsverify: false
|
||||||
# The default from address when sending emails
|
# The default from address when sending emails
|
||||||
fromemail: 'mail@vikunja'
|
fromemail: 'mail@vikunja'
|
||||||
|
|
|
@ -33,6 +33,8 @@ service:
|
||||||
frontendurl: ""
|
frontendurl: ""
|
||||||
# The base path on the file system where the binary and assets are
|
# The base path on the file system where the binary and assets are
|
||||||
rootpath: <the path of the executable>
|
rootpath: <the path of the executable>
|
||||||
|
# The number of items which gets returned per page
|
||||||
|
pagecount: 50
|
||||||
|
|
||||||
database:
|
database:
|
||||||
# Database type to use. Supported types are mysql and sqlite.
|
# Database type to use. Supported types are mysql and sqlite.
|
||||||
|
|
|
@ -29,6 +29,7 @@ func InitConfig() (err error) {
|
||||||
}
|
}
|
||||||
exPath := filepath.Dir(ex)
|
exPath := filepath.Dir(ex)
|
||||||
viper.SetDefault("service.rootpath", exPath)
|
viper.SetDefault("service.rootpath", exPath)
|
||||||
|
viper.SetDefault("service.pagecount", 50)
|
||||||
// Database
|
// Database
|
||||||
viper.SetDefault("database.type", "sqlite")
|
viper.SetDefault("database.type", "sqlite")
|
||||||
viper.SetDefault("database.host", "localhost")
|
viper.SetDefault("database.host", "localhost")
|
||||||
|
|
|
@ -4,7 +4,7 @@ package models
|
||||||
type CRUDable interface {
|
type CRUDable interface {
|
||||||
Create(*User) error
|
Create(*User) error
|
||||||
ReadOne() error
|
ReadOne() error
|
||||||
ReadAll(*User) (interface{}, error)
|
ReadAll(*User, int) (interface{}, error)
|
||||||
Update() error
|
Update() error
|
||||||
Delete() error
|
Delete() error
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ func GetListsByNamespaceID(nID int64) (lists []*List, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAll gets all lists a user has access to
|
// ReadAll gets all lists a user has access to
|
||||||
func (l *List) ReadAll(u *User) (interface{}, error) {
|
func (l *List) ReadAll(u *User, page int) (interface{}, error) {
|
||||||
lists, err := getRawListsForUser(u)
|
lists, err := getRawListsForUser(u, page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ func (l *List) GetSimpleByID() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the lists only, without any tasks or so
|
// Gets the lists only, without any tasks or so
|
||||||
func getRawListsForUser(u *User) (lists []*List, err error) {
|
func getRawListsForUser(u *User, page int) (lists []*List, err error) {
|
||||||
fullUser, err := GetUserByID(u.ID)
|
fullUser, err := GetUserByID(u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lists, err
|
return lists, err
|
||||||
|
@ -104,6 +104,7 @@ func getRawListsForUser(u *User) (lists []*List, err error) {
|
||||||
Or("ul.user_id = ?", fullUser.ID).
|
Or("ul.user_id = ?", fullUser.ID).
|
||||||
Or("un.user_id = ?", fullUser.ID).
|
Or("un.user_id = ?", fullUser.ID).
|
||||||
GroupBy("l.id").
|
GroupBy("l.id").
|
||||||
|
Limit(getLimitFromPageIndex(page)).
|
||||||
Find(&lists)
|
Find(&lists)
|
||||||
|
|
||||||
return lists, err
|
return lists, err
|
||||||
|
@ -160,14 +161,14 @@ type ListTasksDummy struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAll gets all tasks for a user
|
// ReadAll gets all tasks for a user
|
||||||
func (lt *ListTasksDummy) ReadAll(u *User) (interface{}, error) {
|
func (lt *ListTasksDummy) ReadAll(u *User, page int) (interface{}, error) {
|
||||||
return GetTasksByUser(u)
|
return GetTasksByUser(u, page)
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetTasksByUser returns all tasks for a user
|
//GetTasksByUser returns all tasks for a user
|
||||||
func GetTasksByUser(u *User) (tasks []*ListTask, err error) {
|
func GetTasksByUser(u *User, page int) (tasks []*ListTask, err error) {
|
||||||
// Get all lists
|
// Get all lists
|
||||||
lists, err := getRawListsForUser(u)
|
lists, err := getRawListsForUser(u, page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,14 @@ func TestList_ReadAll(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
lists2 := List{}
|
lists2 := List{}
|
||||||
lists3, err := lists2.ReadAll(&u)
|
lists3, err := lists2.ReadAll(&u, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(lists3).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(lists3).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(lists3)
|
s := reflect.ValueOf(lists3)
|
||||||
assert.Equal(t, s.Len(), 1)
|
assert.Equal(t, s.Len(), 1)
|
||||||
|
|
||||||
// Try getting lists for a nonexistant user
|
// Try getting lists for a nonexistant user
|
||||||
_, err = lists2.ReadAll(&User{ID: 984234})
|
_, err = lists2.ReadAll(&User{ID: 984234}, 1)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrUserDoesNotExist(err))
|
assert.True(t, IsErrUserDoesNotExist(err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
// ReadAll gets all users who have access to a list
|
// ReadAll gets all users who have access to a list
|
||||||
func (ul *ListUser) ReadAll(u *User) (interface{}, error) {
|
func (ul *ListUser) ReadAll(u *User, page int) (interface{}, error) {
|
||||||
// Check if the user has access to the list
|
// Check if the user has access to the list
|
||||||
l := &List{ID: ul.ListID}
|
l := &List{ID: ul.ListID}
|
||||||
if err := l.GetSimpleByID(); err != nil {
|
if err := l.GetSimpleByID(); err != nil {
|
||||||
|
@ -16,6 +16,7 @@ func (ul *ListUser) ReadAll(u *User) (interface{}, error) {
|
||||||
err := x.
|
err := x.
|
||||||
Join("INNER", "users_list", "user_id = users.id").
|
Join("INNER", "users_list", "user_id = users.id").
|
||||||
Where("users_list.list_id = ?", ul.ListID).
|
Where("users_list.list_id = ?", ul.ListID).
|
||||||
|
Limit(getLimitFromPageIndex(page)).
|
||||||
Find(&all)
|
Find(&all)
|
||||||
|
|
||||||
return all, err
|
return all, err
|
||||||
|
|
|
@ -90,3 +90,15 @@ func SetEngine() (err error) {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getLimitFromPageIndex(page int) (limit, start int) {
|
||||||
|
|
||||||
|
// Get everything when page index is -1
|
||||||
|
if page < 0 {
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
limit = viper.GetInt("service.pagecount")
|
||||||
|
start = limit * (page - 1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ func (n *Namespace) ReadOne() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAll gets all namespaces a user has access to
|
// ReadAll gets all namespaces a user has access to
|
||||||
func (n *Namespace) ReadAll(doer *User) (interface{}, error) {
|
func (n *Namespace) ReadAll(doer *User, page int) (interface{}, error) {
|
||||||
|
|
||||||
type namespaceWithLists struct {
|
type namespaceWithLists struct {
|
||||||
Namespace `xorm:"extends"`
|
Namespace `xorm:"extends"`
|
||||||
|
@ -71,6 +71,7 @@ func (n *Namespace) ReadAll(doer *User) (interface{}, error) {
|
||||||
Or("namespaces.owner_id = ?", doer.ID).
|
Or("namespaces.owner_id = ?", doer.ID).
|
||||||
Or("users_namespace.user_id = ?", doer.ID).
|
Or("users_namespace.user_id = ?", doer.ID).
|
||||||
GroupBy("namespaces.id").
|
GroupBy("namespaces.id").
|
||||||
|
Limit(getLimitFromPageIndex(page)).
|
||||||
Find(&all)
|
Find(&all)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -85,7 +85,7 @@ func TestNamespace_Create(t *testing.T) {
|
||||||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||||
|
|
||||||
// Get all namespaces of a user
|
// Get all namespaces of a user
|
||||||
nsps, err := n.ReadAll(&doer)
|
nsps, err := n.ReadAll(&doer, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(nsps).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(nsps).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(nsps)
|
s := reflect.ValueOf(nsps)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
// ReadAll gets all users who have access to a namespace
|
// ReadAll gets all users who have access to a namespace
|
||||||
func (un *NamespaceUser) ReadAll(u *User) (interface{}, error) {
|
func (un *NamespaceUser) ReadAll(u *User, page int) (interface{}, error) {
|
||||||
// Check if the user has access to the namespace
|
// Check if the user has access to the namespace
|
||||||
l, err := GetNamespaceByID(un.NamespaceID)
|
l, err := GetNamespaceByID(un.NamespaceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16,6 +16,7 @@ func (un *NamespaceUser) ReadAll(u *User) (interface{}, error) {
|
||||||
err = x.
|
err = x.
|
||||||
Join("INNER", "users_namespace", "user_id = users.id").
|
Join("INNER", "users_namespace", "user_id = users.id").
|
||||||
Where("users_namespace.namespace_id = ?", un.NamespaceID).
|
Where("users_namespace.namespace_id = ?", un.NamespaceID).
|
||||||
|
Limit(getLimitFromPageIndex(page)).
|
||||||
Find(&all)
|
Find(&all)
|
||||||
|
|
||||||
return all, err
|
return all, err
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
// ReadAll implements the method to read all teams of a list
|
// ReadAll implements the method to read all teams of a list
|
||||||
func (tl *TeamList) ReadAll(u *User) (interface{}, error) {
|
func (tl *TeamList) ReadAll(u *User, page int) (interface{}, error) {
|
||||||
// Check if the user can read the namespace
|
// Check if the user can read the namespace
|
||||||
l := &List{ID: tl.ListID}
|
l := &List{ID: tl.ListID}
|
||||||
if err := l.GetSimpleByID(); err != nil {
|
if err := l.GetSimpleByID(); err != nil {
|
||||||
|
@ -17,6 +17,7 @@ func (tl *TeamList) ReadAll(u *User) (interface{}, error) {
|
||||||
Table("teams").
|
Table("teams").
|
||||||
Join("INNER", "team_list", "team_id = teams.id").
|
Join("INNER", "team_list", "team_id = teams.id").
|
||||||
Where("team_list.list_id = ?", tl.ListID).
|
Where("team_list.list_id = ?", tl.ListID).
|
||||||
|
Limit(getLimitFromPageIndex(page)).
|
||||||
Find(&all)
|
Find(&all)
|
||||||
|
|
||||||
return all, err
|
return all, err
|
||||||
|
|
|
@ -50,27 +50,27 @@ func TestTeamList(t *testing.T) {
|
||||||
assert.True(t, IsErrListDoesNotExist(err))
|
assert.True(t, IsErrListDoesNotExist(err))
|
||||||
|
|
||||||
// Test Read all
|
// Test Read all
|
||||||
teams, err := tl.ReadAll(&u)
|
teams, err := tl.ReadAll(&u, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(teams).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(teams).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(teams)
|
s := reflect.ValueOf(teams)
|
||||||
assert.Equal(t, s.Len(), 1)
|
assert.Equal(t, s.Len(), 1)
|
||||||
|
|
||||||
// Test Read all for nonexistant list
|
// Test Read all for nonexistant list
|
||||||
_, err = tl4.ReadAll(&u)
|
_, err = tl4.ReadAll(&u, 1)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrListDoesNotExist(err))
|
assert.True(t, IsErrListDoesNotExist(err))
|
||||||
|
|
||||||
// Test Read all for a list where the user is owner of the namespace this list belongs to
|
// Test Read all for a list where the user is owner of the namespace this list belongs to
|
||||||
tl5 := tl
|
tl5 := tl
|
||||||
tl5.ListID = 2
|
tl5.ListID = 2
|
||||||
_, err = tl5.ReadAll(&u)
|
_, err = tl5.ReadAll(&u, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Test read all for a list where the user not has access
|
// Test read all for a list where the user not has access
|
||||||
tl6 := tl
|
tl6 := tl
|
||||||
tl6.ListID = 3
|
tl6.ListID = 3
|
||||||
_, err = tl6.ReadAll(&u)
|
_, err = tl6.ReadAll(&u, 1)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNeedToHaveListReadAccess(err))
|
assert.True(t, IsErrNeedToHaveListReadAccess(err))
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
// ReadAll implements the method to read all teams of a namespace
|
// ReadAll implements the method to read all teams of a namespace
|
||||||
func (tn *TeamNamespace) ReadAll(user *User) (interface{}, error) {
|
func (tn *TeamNamespace) ReadAll(user *User, page int) (interface{}, error) {
|
||||||
// Check if the user can read the namespace
|
// Check if the user can read the namespace
|
||||||
n, err := GetNamespaceByID(tn.NamespaceID)
|
n, err := GetNamespaceByID(tn.NamespaceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -17,6 +17,7 @@ func (tn *TeamNamespace) ReadAll(user *User) (interface{}, error) {
|
||||||
err = x.Table("teams").
|
err = x.Table("teams").
|
||||||
Join("INNER", "team_namespaces", "team_id = teams.id").
|
Join("INNER", "team_namespaces", "team_id = teams.id").
|
||||||
Where("team_namespaces.namespace_id = ?", tn.NamespaceID).
|
Where("team_namespaces.namespace_id = ?", tn.NamespaceID).
|
||||||
|
Limit(getLimitFromPageIndex(page)).
|
||||||
Find(&all)
|
Find(&all)
|
||||||
|
|
||||||
return all, err
|
return all, err
|
||||||
|
|
|
@ -49,20 +49,20 @@ func TestTeamNamespace(t *testing.T) {
|
||||||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||||
|
|
||||||
// Check readall
|
// Check readall
|
||||||
teams, err := tn.ReadAll(&dummyuser)
|
teams, err := tn.ReadAll(&dummyuser, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(teams).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(teams).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(teams)
|
s := reflect.ValueOf(teams)
|
||||||
assert.Equal(t, s.Len(), 1)
|
assert.Equal(t, s.Len(), 1)
|
||||||
|
|
||||||
// Check readall for a nonexistant namespace
|
// Check readall for a nonexistant namespace
|
||||||
_, err = tn4.ReadAll(&dummyuser)
|
_, err = tn4.ReadAll(&dummyuser, 1)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||||
|
|
||||||
// Check with no right to read the namespace
|
// Check with no right to read the namespace
|
||||||
nouser := &User{ID: 393}
|
nouser := &User{ID: 393}
|
||||||
_, err = tn.ReadAll(nouser)
|
_, err = tn.ReadAll(nouser, 1)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNeedToHaveNamespaceReadAccess(err))
|
assert.True(t, IsErrNeedToHaveNamespaceReadAccess(err))
|
||||||
|
|
||||||
|
|
|
@ -84,12 +84,13 @@ func (t *Team) ReadOne() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAll gets all teams the user is part of
|
// ReadAll gets all teams the user is part of
|
||||||
func (t *Team) ReadAll(user *User) (teams interface{}, err error) {
|
func (t *Team) ReadAll(user *User, page int) (teams interface{}, err error) {
|
||||||
all := []*Team{}
|
all := []*Team{}
|
||||||
err = x.Select("teams.*").
|
err = x.Select("teams.*").
|
||||||
Table("teams").
|
Table("teams").
|
||||||
Join("INNER", "team_members", "team_members.team_id = teams.id").
|
Join("INNER", "team_members", "team_members.team_id = teams.id").
|
||||||
Where("team_members.user_id = ?", user.ID).
|
Where("team_members.user_id = ?", user.ID).
|
||||||
|
Limit(getLimitFromPageIndex(page)).
|
||||||
Find(&all)
|
Find(&all)
|
||||||
|
|
||||||
return all, err
|
return all, err
|
||||||
|
|
|
@ -32,7 +32,7 @@ func TestTeam_Create(t *testing.T) {
|
||||||
assert.True(t, dummyteam.CanRead(&doer))
|
assert.True(t, dummyteam.CanRead(&doer))
|
||||||
|
|
||||||
// Get all teams the user is part of
|
// Get all teams the user is part of
|
||||||
ts, err := tm.ReadAll(&doer)
|
ts, err := tm.ReadAll(&doer, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(ts).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(ts).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(ts)
|
s := reflect.ValueOf(ts)
|
||||||
|
|
|
@ -39,7 +39,7 @@ func Caldav(c echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all tasks for that user
|
// Get all tasks for that user
|
||||||
tasks, err := models.GetTasksByUser(&u)
|
tasks, err := models.GetTasksByUser(&u, -1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return crud.HandleHTTPError(err)
|
return crud.HandleHTTPError(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package crud
|
package crud
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.vikunja.io/api/pkg/log"
|
||||||
"code.vikunja.io/api/pkg/models"
|
"code.vikunja.io/api/pkg/models"
|
||||||
"github.com/labstack/echo"
|
"github.com/labstack/echo"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadAllWeb is the webhandler to get all objects of a type
|
// ReadAllWeb is the webhandler to get all objects of a type
|
||||||
|
@ -21,7 +23,21 @@ func (c *WebHandler) ReadAllWeb(ctx echo.Context) error {
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, "No or invalid model provided.")
|
return echo.NewHTTPError(http.StatusBadRequest, "No or invalid model provided.")
|
||||||
}
|
}
|
||||||
|
|
||||||
lists, err := currentStruct.ReadAll(¤tUser)
|
// Pagination
|
||||||
|
page := ctx.QueryParam("page")
|
||||||
|
if page == "" {
|
||||||
|
page = "1"
|
||||||
|
}
|
||||||
|
pageNumber, err := strconv.Atoi(page)
|
||||||
|
if err != nil {
|
||||||
|
log.Log.Error(err.Error())
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, "Bad page requested.")
|
||||||
|
}
|
||||||
|
if pageNumber < 0 {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, "Bad page requested.")
|
||||||
|
}
|
||||||
|
|
||||||
|
lists, err := currentStruct.ReadAll(¤tUser, pageNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return HandleHTTPError(err)
|
return HandleHTTPError(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue