-
Notifications
You must be signed in to change notification settings - Fork 0
/
task.go
122 lines (110 loc) · 3.08 KB
/
task.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package entities
import (
"github.com/looplab/fsm"
"time"
)
type TaskStatus string
type Priority uint
const (
ToDo TaskStatus = "todo"
InProgress TaskStatus = "in-progress"
Stopped TaskStatus = "stopped"
Completed TaskStatus = "completed"
Cancelled TaskStatus = "cancelled"
)
const (
UNKNOWN Priority = 0
TRIVIAL Priority = 2
LOW Priority = 4
MEDIUM Priority = 8
HIGH Priority = 16
CRITICAL Priority = 32
)
type TaskLog struct {
StartedAt time.Time `json:"started_at"`
PausedAt time.Time `json:"paused_at"`
}
type Task struct {
Item
Status TaskStatus `json:"status"`
Priority Priority `json:"priority"`
DueDate time.Time `json:"due_date"`
CompletedPercentage uint `json:"completed_percentage"`
DurationInMinutes uint `json:"duration_in_minutes"`
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at"`
CancelledAt time.Time `json:"cancelled_at"`
Logs []TaskLog `json:"logs"`
fsm *fsm.FSM
}
func (task *Task) GetStatus() string {
return string(task.Status)
}
func (task *Task) setLastPausedAt(date time.Time) {
index := len(task.Logs) - 1
if index < 0 {
return
}
lastLog := task.Logs[index]
if lastLog.PausedAt.IsZero() {
lastLog.PausedAt = date
task.Logs[index] = lastLog
}
}
func NewTask(title string, description string, status TaskStatus, tags ...string) *Task {
task := &Task{
Item: *newItem(title, "task", description, tags...),
Status: status,
Priority: UNKNOWN,
DueDate: time.Time{},
StartedAt: time.Time{},
CompletedAt: time.Time{},
CancelledAt: time.Time{},
}
task.fsm = fsm.NewFSM(
string(status),
fsm.Events{
{Name: "start", Src: []string{string(ToDo), string(Stopped), string(Cancelled)}, Dst: string(InProgress)},
{Name: "stop", Src: []string{string(InProgress)}, Dst: string(Stopped)},
{Name: "complete", Src: []string{string(InProgress), string(Stopped)}, Dst: string(Completed)},
{Name: "cancel", Src: []string{string(ToDo), string(Stopped), string(InProgress)}, Dst: string(Cancelled)},
},
fsm.Callbacks{
"enter_state": func(e *fsm.Event) { task.Status = TaskStatus(task.fsm.Current()) },
"enter_in-progress": func(e *fsm.Event) {
now := time.Now()
if task.StartedAt.IsZero() {
task.StartedAt = now
}
task.Logs = append(task.Logs, TaskLog{StartedAt: now})
},
"enter_stopped": func(e *fsm.Event) {
task.setLastPausedAt(time.Now())
},
"enter_completed": func(e *fsm.Event) {
now := time.Now()
task.setLastPausedAt(now)
task.CompletedAt = now
},
"enter_cancelled": func(e *fsm.Event) {
now := time.Now()
task.setLastPausedAt(now)
task.CancelledAt = now
},
},
)
return task
}
func (task *Task) TriggerEvent(event string, args ...interface{}) error {
err := task.fsm.Event(event, args...)
if err != nil {
task.Status = TaskStatus(task.fsm.Current())
}
return err
}
func (task *Task) GetDueDate() *time.Time {
if task.DueDate.IsZero() {
return nil
}
return &task.DueDate
}