fix task sorting and individual task deadline issues on front page.
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
This commit is contained in:
+19
-1
@@ -2,6 +2,7 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -20,6 +21,7 @@ type Project struct {
|
||||
StatusTag *string `json:"statusTag" db:"status_tag"`
|
||||
Favorite bool `json:"favorite" db:"favorite"`
|
||||
Tags []string `json:"tags" db:"tags"`
|
||||
TaskSortFields []string `json:"taskSortFields" db:"task_sort_fields"`
|
||||
}
|
||||
|
||||
func (project *Project) Update(update ProjectUpdate) {
|
||||
@@ -74,6 +76,9 @@ func (project *Project) Update(update ProjectUpdate) {
|
||||
if update.SetTags != nil {
|
||||
project.Tags = update.SetTags
|
||||
}
|
||||
if update.TaskSortFields != nil {
|
||||
project.TaskSortFields = append(update.TaskSortFields[:0:0], update.TaskSortFields...)
|
||||
}
|
||||
|
||||
if project.StatusTag != nil && project.Active {
|
||||
project.StatusTag = nil
|
||||
@@ -95,14 +100,27 @@ type ProjectUpdate struct {
|
||||
ClearStatusTag bool `json:"clearStatusTag"`
|
||||
SetTags []string `json:"setTags"`
|
||||
Favorite *bool `json:"favorite"`
|
||||
TaskSortFields []string `json:"taskSortFields"`
|
||||
}
|
||||
|
||||
type ProjectResult struct {
|
||||
Project
|
||||
Tasks []*TaskResult `json:"tasks"`
|
||||
Tasks []*TaskResult `json:"tasks"`
|
||||
Subtractions []ProjectSubtraction `json:"subtractions"`
|
||||
}
|
||||
|
||||
func (result *ProjectResult) SortTasks() {
|
||||
sorter := TaskSorter{
|
||||
Data: result.Tasks,
|
||||
Fields: result.Project.TaskSortFields,
|
||||
}
|
||||
if len(sorter.Fields) == 0 {
|
||||
sorter.Fields = []string{"status"}
|
||||
}
|
||||
|
||||
sort.Sort(sorter)
|
||||
}
|
||||
|
||||
type ProjectSubtraction struct {
|
||||
Item Item `json:"item"`
|
||||
Amount int `json:"amount"`
|
||||
|
||||
@@ -94,6 +94,94 @@ type TaskFilter struct {
|
||||
ProjectIDs []string
|
||||
}
|
||||
|
||||
var taskStatusOrder = []string{"", "to do", "on hold", "completed", "failed", "declined"}
|
||||
|
||||
type TaskSorter struct {
|
||||
Data []*TaskResult
|
||||
Fields []string
|
||||
}
|
||||
|
||||
func (s *TaskSorter) Valid() bool {
|
||||
for _, field := range s.Fields {
|
||||
switch field {
|
||||
case "name", "-name", "createdTime", "-createdTime", "amount", "-amount", "status", "-status":
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (s TaskSorter) Len() int {
|
||||
return len(s.Data)
|
||||
}
|
||||
|
||||
func (s TaskSorter) Less(i, j int) bool {
|
||||
a := s.Data[i]
|
||||
b := s.Data[j]
|
||||
|
||||
for _, field := range s.Fields {
|
||||
switch field {
|
||||
case "status", "-status":
|
||||
as := ""
|
||||
if a.StatusTag != nil {
|
||||
as = *a.StatusTag
|
||||
}
|
||||
bs := ""
|
||||
if b.StatusTag != nil {
|
||||
bs = *b.StatusTag
|
||||
}
|
||||
|
||||
if as != bs {
|
||||
asi := 1000
|
||||
bsi := 1000
|
||||
|
||||
for i, sn := range taskStatusOrder {
|
||||
if sn == as {
|
||||
asi = i
|
||||
}
|
||||
if sn == bs {
|
||||
bsi = i
|
||||
}
|
||||
}
|
||||
|
||||
if field == "-status" {
|
||||
return asi > bsi
|
||||
} else {
|
||||
return asi < bsi
|
||||
}
|
||||
}
|
||||
case "amount":
|
||||
if a.ItemAmount != b.ItemAmount {
|
||||
return a.ItemAmount < b.ItemAmount
|
||||
}
|
||||
case "-amount":
|
||||
if a.ItemAmount != b.ItemAmount {
|
||||
return a.ItemAmount > b.ItemAmount
|
||||
}
|
||||
case "name":
|
||||
if a.Name != b.Name {
|
||||
return a.Name < b.Name
|
||||
}
|
||||
case "-name":
|
||||
if a.Name != b.Name {
|
||||
return a.Name > b.Name
|
||||
}
|
||||
case "-time":
|
||||
return a.CreatedTime.After(b.CreatedTime)
|
||||
case "time":
|
||||
return a.CreatedTime.Before(b.CreatedTime)
|
||||
}
|
||||
}
|
||||
|
||||
return a.CreatedTime.Before(b.CreatedTime)
|
||||
}
|
||||
|
||||
func (s TaskSorter) Swap(i, j int) {
|
||||
s.Data[i], s.Data[j] = s.Data[j], s.Data[i]
|
||||
}
|
||||
|
||||
type TaskRepository interface {
|
||||
Find(ctx context.Context, id string) (*Task, error)
|
||||
List(ctx context.Context, filter TaskFilter) ([]*Task, error)
|
||||
|
||||
Reference in New Issue
Block a user