Get tasks between a date range (#41)
This commit is contained in:
parent
784b890f70
commit
5a93475be9
10 changed files with 356 additions and 52 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
.idea/
|
||||
.idea/*/*
|
||||
.idea/httpRequests
|
||||
config.yml
|
||||
config.yaml
|
||||
*.db
|
||||
|
|
|
@ -255,6 +255,9 @@ Teams sind global, d.h. Ein Team kann mehrere Namespaces verwalten.
|
|||
### Later/Nice to have
|
||||
|
||||
* [x] Deps nach mod umziehen
|
||||
* [x] Start/Enddatum für Tasks
|
||||
* [x] Timeline/Calendar view -> Dazu tasks die in einem Bestimmten Bereich due sind, macht dann das Frontend
|
||||
* [x] Tasks innerhalb eines definierbarem Bereich, sollte aber trotzdem der server machen, so à la "Gib mir alles für diesen Monat"
|
||||
* [ ] Websockets
|
||||
* Nur lesend? (-> Updates wie bisher)
|
||||
* sollen den geupdaten Kram an alle anderen user schicken
|
||||
|
@ -268,15 +271,12 @@ Teams sind global, d.h. Ein Team kann mehrere Namespaces verwalten.
|
|||
* [ ] Mgl. zum Accountlöschen haben (so richtig krass mit emailverifiezierung und dass alle Privaten Listen gelöscht werden und man alle geteilten entweder wem übertragen muss oder auf privat stellen)
|
||||
* [ ] IMAP-Integration -> Man schickt eine email an Vikunja und es macht daraus dann nen task -> Achtung missbrauchsmöglichkeiten
|
||||
* [ ] In und Out webhooks, mit Templates vom Payload
|
||||
* [x] Start/Enddatum für Tasks
|
||||
* [ ] Timeline/Calendar view -> Dazu tasks die in einem Bestimmten Bereich due sind, macht dann das Frontend
|
||||
* [ ] "Smart Lists", Listen nach bestimmten Kriterien gefiltert -> nur UI?
|
||||
* [ ] "Performance-Statistik" -> Wie viele Tasks man in bestimmten Zeiträumen so geschafft hat etc
|
||||
* [ ] Activity Feed, so à la "der und der hat das und das gemacht etc"
|
||||
* [ ] Assignees
|
||||
* [ ] Attachments
|
||||
* [ ] Labels
|
||||
* [ ] Tasks innerhalb eines definierbarem Bereich, sollte aber trotzdem der server machen, so à la "Gib mir alles für diesen Monat"
|
||||
* [ ] Task-Templates innerhalb namespaces und Listen (-> Mehrere, die auswählbar sind)
|
||||
* [ ] Bulk-edit -> Transactions
|
||||
* [ ] Ein Task muss von mehreren Assignees abgehakt werden bis er als done markiert wird
|
|
@ -118,6 +118,12 @@ Authorization: Bearer {{auth_token}}
|
|||
|
||||
###
|
||||
|
||||
# Get all pending tasks in a range
|
||||
GET http://localhost:8080/api/v1/tasks/all/dueadateasc/1546784000/1548784000
|
||||
Authorization: Bearer {{auth_token}}
|
||||
|
||||
###
|
||||
|
||||
# Get all pending tasks in caldav
|
||||
GET http://localhost:8080/api/v1/tasks/caldav
|
||||
#Authorization: Bearer {{auth_token}}
|
||||
|
@ -125,10 +131,10 @@ GET http://localhost:8080/api/v1/tasks/caldav
|
|||
###
|
||||
|
||||
# Update a task
|
||||
POST http://localhost:8080/api/v1/tasks/32
|
||||
POST http://localhost:8080/api/v1/tasks/3491
|
||||
Authorization: Bearer {{auth_token}}
|
||||
Content-Type: application/json
|
||||
|
||||
{"done":true}
|
||||
{"startDate":1546804000, "endDate": 1546805000}
|
||||
|
||||
###
|
|
@ -39,3 +39,25 @@
|
|||
created: 1543626724
|
||||
updated: 1543626724
|
||||
due_date_unix: 1543616724
|
||||
- id: 7
|
||||
text: 'task #7 with start date'
|
||||
created_by_id: 1
|
||||
list_id: 1
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
start_date_unix: 1544600000
|
||||
- id: 8
|
||||
text: 'task #8 with end date'
|
||||
created_by_id: 1
|
||||
list_id: 1
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
end_date_unix: 1544700000
|
||||
- id: 9
|
||||
text: 'task #9 with start and end date'
|
||||
created_by_id: 1
|
||||
list_id: 1
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
start_date_unix: 1544600000
|
||||
end_date_unix: 1544700000
|
|
@ -6,7 +6,10 @@
|
|||
|
||||
package models
|
||||
|
||||
import "code.vikunja.io/web"
|
||||
import (
|
||||
"code.vikunja.io/web"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SortBy declares constants to sort
|
||||
type SortBy int
|
||||
|
@ -73,11 +76,11 @@ func (lt *ListTask) ReadAll(search string, a web.Auth, page int) (interface{}, e
|
|||
sortby = SortTasksByUnsorted
|
||||
}
|
||||
|
||||
return GetTasksByUser(search, u, page, sortby)
|
||||
return GetTasksByUser(search, u, page, sortby, time.Unix(lt.StartDateSortUnix, 0), time.Unix(lt.EndDateSortUnix, 0))
|
||||
}
|
||||
|
||||
//GetTasksByUser returns all tasks for a user
|
||||
func GetTasksByUser(search string, u *User, page int, sortby SortBy) (tasks []*ListTask, err error) {
|
||||
func GetTasksByUser(search string, u *User, page int, sortby SortBy, startDate time.Time, endDate time.Time) (tasks []*ListTask, err error) {
|
||||
// Get all lists
|
||||
lists, err := getRawListsForUser("", u, page)
|
||||
if err != nil {
|
||||
|
@ -103,9 +106,37 @@ func GetTasksByUser(search string, u *User, page int, sortby SortBy) (tasks []*L
|
|||
}
|
||||
|
||||
// Then return all tasks for that lists
|
||||
if err := x.In("list_id", listIDs).Where("text LIKE ?", "%"+search+"%").OrderBy(orderby).Find(&tasks); err != nil {
|
||||
if startDate.Unix() != 0 || endDate.Unix() != 0 {
|
||||
|
||||
startDateUnix := time.Now().Unix()
|
||||
if startDate.Unix() != 0 {
|
||||
startDateUnix = startDate.Unix()
|
||||
}
|
||||
|
||||
endDateUnix := time.Now().Unix()
|
||||
if endDate.Unix() != 0 {
|
||||
endDateUnix = endDate.Unix()
|
||||
}
|
||||
|
||||
if err := x.In("list_id", listIDs).
|
||||
Where("text LIKE ?", "%"+search+"%").
|
||||
And("((due_date_unix BETWEEN ? AND ?) OR "+
|
||||
"(start_date_unix BETWEEN ? and ?) OR "+
|
||||
"(end_date_unix BETWEEN ? and ?))", startDateUnix, endDateUnix, startDateUnix, endDateUnix, startDateUnix, endDateUnix).
|
||||
And("(parent_task_id = 0 OR parent_task_id IS NULL)").
|
||||
OrderBy(orderby).
|
||||
Find(&tasks); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := x.In("list_id", listIDs).
|
||||
Where("text LIKE ?", "%"+search+"%").
|
||||
And("(parent_task_id = 0 OR parent_task_id IS NULL)").
|
||||
OrderBy(orderby).
|
||||
Find(&tasks); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return tasks, err
|
||||
}
|
||||
|
|
|
@ -69,6 +69,34 @@ func sortTasksForTesting(by SortBy) (tasks []*ListTask) {
|
|||
Updated: 1543626724,
|
||||
DueDateUnix: 1543616724,
|
||||
},
|
||||
{
|
||||
ID: 7,
|
||||
Text: "task #7 with start date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
},
|
||||
{
|
||||
ID: 8,
|
||||
Text: "task #8 with end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
{
|
||||
ID: 9,
|
||||
Text: "task #9 with start and end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
}
|
||||
|
||||
switch by {
|
||||
|
@ -107,6 +135,8 @@ func TestListTask_ReadAll(t *testing.T) {
|
|||
ParentTaskID int64
|
||||
Priority int64
|
||||
Sorting string
|
||||
StartDateSortUnix int64
|
||||
EndDateSortUnix int64
|
||||
Subtasks []*ListTask
|
||||
Created int64
|
||||
Updated int64
|
||||
|
@ -160,7 +190,89 @@ func TestListTask_ReadAll(t *testing.T) {
|
|||
a: &User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: sortTasksForTesting(SortTasksByPriorityAsc),
|
||||
want: []*ListTask{
|
||||
{
|
||||
ID: 1,
|
||||
Text: "task #1",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Text: "task #2 done",
|
||||
Done: true,
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 5,
|
||||
Text: "task #5 higher due date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
DueDateUnix: 1543636724,
|
||||
},
|
||||
{
|
||||
ID: 6,
|
||||
Text: "task #6 lower due date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
DueDateUnix: 1543616724,
|
||||
},
|
||||
{
|
||||
ID: 7,
|
||||
Text: "task #7 with start date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
},
|
||||
{
|
||||
ID: 8,
|
||||
Text: "task #8 with end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
{
|
||||
ID: 9,
|
||||
Text: "task #9 with start and end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
Text: "task #4 low prio",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Text: "task #3 high prio",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
Priority: 100,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
|
@ -177,7 +289,7 @@ func TestListTask_ReadAll(t *testing.T) {
|
|||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "ReadAll ListTasks sorted by due date default (desc)",
|
||||
name: "ReadAll ListTasks sorted by due date default desc",
|
||||
fields: fields{
|
||||
Sorting: "dueadate",
|
||||
},
|
||||
|
@ -215,6 +327,107 @@ func TestListTask_ReadAll(t *testing.T) {
|
|||
want: sortTasksForTesting(SortTasksByDueDateDesc),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "ReadAll ListTasks with range",
|
||||
fields: fields{
|
||||
StartDateSortUnix: 1544500000,
|
||||
EndDateSortUnix: 1544600000,
|
||||
},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*ListTask{
|
||||
{
|
||||
ID: 7,
|
||||
Text: "task #7 with start date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
},
|
||||
{
|
||||
ID: 9,
|
||||
Text: "task #9 with start and end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "ReadAll ListTasks with range",
|
||||
fields: fields{
|
||||
StartDateSortUnix: 1544700000,
|
||||
EndDateSortUnix: 1545000000,
|
||||
},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*ListTask{
|
||||
{
|
||||
ID: 8,
|
||||
Text: "task #8 with end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
{
|
||||
ID: 9,
|
||||
Text: "task #9 with start and end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "ReadAll ListTasks with range without end date",
|
||||
fields: fields{
|
||||
StartDateSortUnix: 1544700000,
|
||||
},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*ListTask{
|
||||
{
|
||||
ID: 8,
|
||||
Text: "task #8 with end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
{
|
||||
ID: 9,
|
||||
Text: "task #9 with start and end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -231,6 +444,8 @@ func TestListTask_ReadAll(t *testing.T) {
|
|||
ParentTaskID: tt.fields.ParentTaskID,
|
||||
Priority: tt.fields.Priority,
|
||||
Sorting: tt.fields.Sorting,
|
||||
StartDateSortUnix: tt.fields.StartDateSortUnix,
|
||||
EndDateSortUnix: tt.fields.EndDateSortUnix,
|
||||
Subtasks: tt.fields.Subtasks,
|
||||
Created: tt.fields.Created,
|
||||
Updated: tt.fields.Updated,
|
||||
|
@ -245,6 +460,20 @@ func TestListTask_ReadAll(t *testing.T) {
|
|||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("ListTask.ReadAll() = %v, want %v", got, tt.want)
|
||||
/*fmt.Println("Got:")
|
||||
gotslice := got.([]*ListTask)
|
||||
for _, g := range gotslice {
|
||||
fmt.Println(g.Priority, g.Text)
|
||||
//fmt.Println(g.StartDateUnix)
|
||||
//fmt.Println(g.EndDateUnix)
|
||||
}
|
||||
fmt.Println("Want:")
|
||||
wantslice := tt.want.([]*ListTask)
|
||||
for _, w := range wantslice {
|
||||
fmt.Println(w.Priority, w.Text)
|
||||
//fmt.Println(w.StartDateUnix)
|
||||
//fmt.Println(w.EndDateUnix)
|
||||
}*/
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -34,10 +34,13 @@ type ListTask struct {
|
|||
RepeatAfter int64 `xorm:"int(11) INDEX" json:"repeatAfter"`
|
||||
ParentTaskID int64 `xorm:"int(11) INDEX" json:"parentTaskID"`
|
||||
Priority int64 `xorm:"int(11)" json:"priority"`
|
||||
Sorting string `xorm:"-" json:"-" param:"sort"` // Parameter to sort by
|
||||
StartDateUnix int64 `xorm:"int(11) INDEX" json:"startDate"`
|
||||
EndDateUnix int64 `xorm:"int(11) INDEX" json:"endDate"`
|
||||
|
||||
Sorting string `xorm:"-" json:"-" param:"sort"` // Parameter to sort by
|
||||
StartDateSortUnix int64 `xorm:"-" json:"-" param:"startdatefilter"`
|
||||
EndDateSortUnix int64 `xorm:"-" json:"-" param:"enddatefilter"`
|
||||
|
||||
Subtasks []*ListTask `xorm:"-" json:"subtasks"`
|
||||
|
||||
Created int64 `xorm:"created" json:"created"`
|
||||
|
|
|
@ -114,7 +114,18 @@ func (i *ListTask) Update() (err error) {
|
|||
ot.Done = false
|
||||
}
|
||||
|
||||
_, err = x.ID(i.ID).Cols("text", "description", "done", "due_date_unix", "reminders_unix", "repeat_after").Update(ot)
|
||||
_, err = x.ID(i.ID).
|
||||
Cols("text",
|
||||
"description",
|
||||
"done",
|
||||
"due_date_unix",
|
||||
"reminders_unix",
|
||||
"repeat_after",
|
||||
"parent_task_id",
|
||||
"priority",
|
||||
"start_date_unix",
|
||||
"end_date_unix").
|
||||
Update(ot)
|
||||
*i = ot
|
||||
return
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ func Caldav(c echo.Context) error {
|
|||
}
|
||||
|
||||
// Get all tasks for that user
|
||||
tasks, err := models.GetTasksByUser("", &u, -1, models.SortTasksByUnsorted)
|
||||
tasks, err := models.GetTasksByUser("", &u, -1, models.SortTasksByUnsorted, time.Now(), time.Now().Add(24*356*time.Hour))
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
|
@ -218,6 +218,7 @@ func RegisterRoutes(e *echo.Echo) {
|
|||
a.PUT("/lists/:list", taskHandler.CreateWeb)
|
||||
a.GET("/tasks/all", taskHandler.ReadAllWeb)
|
||||
a.GET("/tasks/all/:sort", taskHandler.ReadAllWeb)
|
||||
a.GET("/tasks/all/:sort/:startdatefilter/:enddatefilter", taskHandler.ReadAllWeb)
|
||||
a.DELETE("/tasks/:listtask", taskHandler.DeleteWeb)
|
||||
a.POST("/tasks/:listtask", taskHandler.UpdateWeb)
|
||||
|
||||
|
|
Loading…
Reference in a new issue