223 lines
5.6 KiB
Go
Executable File
223 lines
5.6 KiB
Go
Executable File
package ajax
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"local/todo-server/server/ajax/form"
|
|
"local/todo-server/server/ajax/task"
|
|
"net/http"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type taskWithDelta struct {
|
|
task *task.Task
|
|
delta int
|
|
}
|
|
|
|
func (a *Ajax) loadTasks(w http.ResponseWriter, r *http.Request) error {
|
|
listID, _, _ := a.Cur(r)
|
|
filterComplete := filterComplete(form.Get(r, "compl"))
|
|
filterTags := filterTags(form.ToStrArr(form.Get(r, "t")))
|
|
filterSubstr := filterSubstr(form.Get(r, "s"))
|
|
tasks, err := a.storageListTasks(listID, filterComplete, filterTags, filterSubstr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return json.NewEncoder(w).Encode(map[string]interface{}{"list": tasks})
|
|
}
|
|
|
|
func filterComplete(compl string) func(t *task.Task) bool {
|
|
return func(t *task.Task) bool {
|
|
return compl == "" || !t.Complete || (compl == "1" && t.Complete)
|
|
}
|
|
}
|
|
|
|
func filterTags(tags []string) func(t *task.Task) bool {
|
|
return func(t *task.Task) bool {
|
|
for _, whitelisted := range tags {
|
|
found := false
|
|
for _, tag := range t.Tags {
|
|
if whitelisted == tag {
|
|
found = true
|
|
}
|
|
}
|
|
if !found {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
|
|
func filterSubstr(substr string) func(t *task.Task) bool {
|
|
return func(t *task.Task) bool {
|
|
found := substr == "" || strings.Contains(fmt.Sprintf("%+v %+v", t.Title, t.Tags), substr)
|
|
return found
|
|
}
|
|
}
|
|
|
|
func (a *Ajax) newTask(w http.ResponseWriter, r *http.Request) error {
|
|
listID, newTask, err := a.makeTask(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := a.storageSetTask(listID, newTask); err != nil {
|
|
return err
|
|
}
|
|
return json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"total": 1,
|
|
"list": []*task.Task{newTask},
|
|
})
|
|
}
|
|
|
|
func (a *Ajax) makeTask(r *http.Request) (string, *task.Task, error) {
|
|
listID, _, tags := a.Cur(r)
|
|
task, err := task.New(r)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
list, err := a.storageGetList(listID)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
task.Index = list.NextIndex()
|
|
if err := a.storageSetList(list); err != nil {
|
|
return "", nil, err
|
|
}
|
|
task.AppendTags(tags)
|
|
return listID, task, nil
|
|
}
|
|
|
|
func (a *Ajax) deleteTask(w http.ResponseWriter, r *http.Request) error {
|
|
_, taskID, _ := a.Cur(r)
|
|
if err := a.storageDelTask(taskID); err != nil {
|
|
return err
|
|
}
|
|
return json.NewEncoder(w).Encode(map[string]interface{}{"total": 0})
|
|
}
|
|
|
|
func (a *Ajax) completeTask(w http.ResponseWriter, r *http.Request) error {
|
|
listID, taskID, _ := a.Cur(r)
|
|
completedTask, err := a.storageGetTask(taskID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := a.storageDelTask(completedTask.UUID); err != nil {
|
|
return err
|
|
}
|
|
completedTask.SetComplete(form.Get(r, "compl") == "1")
|
|
if err := a.storageSetTask(listID, completedTask); err != nil {
|
|
return err
|
|
}
|
|
return json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"total": 1,
|
|
"list": []*task.Task{completedTask},
|
|
})
|
|
}
|
|
|
|
func (a *Ajax) editNote(w http.ResponseWriter, r *http.Request) error {
|
|
listID, taskID, _ := a.Cur(r)
|
|
editedTask, err := a.storageGetTask(taskID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
editedTask.SetNote(form.Get(r, "note"))
|
|
if err := a.storageSetTask(listID, editedTask); err != nil {
|
|
return err
|
|
}
|
|
return json.NewEncoder(w).Encode(map[string]interface{}{"total": 1, "list": []*task.Task{editedTask}})
|
|
}
|
|
|
|
func (a *Ajax) editTask(w http.ResponseWriter, r *http.Request) error {
|
|
listID, editedTask, err := a.makeTask(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, taskID, _ := a.Cur(r)
|
|
editedTask.UUID = taskID
|
|
if err := a.storageSetTask(listID, editedTask); err != nil {
|
|
return err
|
|
}
|
|
return json.NewEncoder(w).Encode(map[string]interface{}{"total": 1, "list": []*task.Task{editedTask}})
|
|
}
|
|
|
|
func (a *Ajax) setPrio(w http.ResponseWriter, r *http.Request) error {
|
|
listID, taskID, _ := a.Cur(r)
|
|
editedTask, err := a.storageGetTask(taskID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
editedTask.SetPrio(form.ToInt(form.Get(r, "prio")))
|
|
if err := a.storageSetTask(listID, editedTask); err != nil {
|
|
return err
|
|
}
|
|
return json.NewEncoder(w).Encode(map[string]interface{}{"total": 1, "list": []*task.Task{editedTask}})
|
|
}
|
|
|
|
func (a *Ajax) moveTask(w http.ResponseWriter, r *http.Request) error {
|
|
_, taskID, _ := a.Cur(r)
|
|
toList := form.Get(r, "to")
|
|
movedTask, err := a.storageGetTask(taskID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := a.storageDelTask(taskID); err != nil {
|
|
return err
|
|
}
|
|
if err := a.storageSetTask(toList, movedTask); err != nil {
|
|
return err
|
|
}
|
|
return json.NewEncoder(w).Encode(map[string]interface{}{"total": 1, "list": []*task.Task{movedTask}})
|
|
}
|
|
|
|
func (a *Ajax) parseTaskStr(w http.ResponseWriter, r *http.Request) error {
|
|
return errors.New("not impl")
|
|
}
|
|
|
|
func (a *Ajax) changeOrder(w http.ResponseWriter, r *http.Request) error {
|
|
order := form.Get(r, "order")
|
|
orders := strings.Split(order, "&")
|
|
modified := make([]taskWithDelta, 0)
|
|
indices := make([]int, 0)
|
|
for _, order := range orders {
|
|
taskIDDelta := strings.Split(order, "=")
|
|
if len(taskIDDelta) < 2 {
|
|
continue
|
|
}
|
|
taskID := taskIDDelta[0]
|
|
delta, _ := strconv.Atoi(taskIDDelta[1])
|
|
task, err := a.storageGetTask(taskID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
modified = append(modified, taskWithDelta{task: task, delta: delta})
|
|
indices = append(indices, task.Index)
|
|
}
|
|
sort.Slice(modified, func(i, j int) bool {
|
|
if modified[i].delta < modified[j].delta {
|
|
return true
|
|
} else if modified[i].delta > modified[j].delta {
|
|
return false
|
|
}
|
|
return modified[i].task.Index < modified[j].task.Index
|
|
})
|
|
sort.Ints(indices)
|
|
for i := 0; i < len(modified); i++ {
|
|
task := *modified[i].task
|
|
task.Index = indices[i]
|
|
listID, err := a.taskIDToListID(task.UUID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := a.storageSetTask(listID, &task); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
fmt.Fprintf(w, `{"total":1}`)
|
|
return nil
|
|
}
|