commit 04efaa119ebcb4458b0b9c809c3b0e65ac2a0a04
parent d83630684c3b39c5c4ee09b11799c5adf58127fc
Author: Jack Mordaunt <jackmordaunt@gmail.com>
Date: Thu, 5 Nov 2020 11:05:15 +0800
feat: time tracking
Diffstat:
2 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/cmd/kanban/main.go b/cmd/kanban/main.go
@@ -8,6 +8,7 @@ import (
"os"
"path/filepath"
"strconv"
+ "time"
"unsafe"
"git.sr.ht/~jackmordaunt/kanban"
@@ -466,13 +467,28 @@ func (t *Ticket) Layout(gtx C, th *material.Theme) D {
}),
layout.Stacked(func(gtx C) D {
return layout.Flex{
- Axis: layout.Horizontal,
+ Axis: layout.Horizontal,
+ Alignment: layout.Middle,
}.Layout(
gtx,
- layout.Flexed(1, func(gtx C) D {
- return D{Size: gtx.Constraints.Max}
+ layout.Rigid(func(gtx C) D {
+ return layout.Inset{
+ Left: unit.Px(10),
+ }.Layout(gtx, func(gtx C) D {
+ return material.Label(th, unit.Dp(10), func() string {
+ d := time.Since(t.Created)
+ d = d.Round(time.Minute)
+ h := d / time.Hour
+ d -= h * time.Hour
+ m := d / time.Minute
+ return fmt.Sprintf("%02d:%02d", h, m)
+ }()).Layout(gtx)
+ })
}),
layout.Flexed(1, func(gtx C) D {
+ return D{Size: gtx.Constraints.Min}
+ }),
+ layout.Rigid(func(gtx C) D {
return Button(
&t.PrevButton,
WithIcon(icons.BackIcon),
@@ -482,7 +498,7 @@ func (t *Ticket) Layout(gtx C, th *material.Theme) D {
WithBgColor(bottomBarColor),
).Layout(gtx)
}),
- layout.Flexed(1, func(gtx C) D {
+ layout.Rigid(func(gtx C) D {
return Button(
&t.NextButton,
WithIcon(icons.ForwardIcon),
diff --git a/kanban.go b/kanban.go
@@ -2,6 +2,7 @@ package kanban
import (
"fmt"
+ "time"
"github.com/asdine/storm/v3"
)
@@ -11,6 +12,24 @@ type Kanban struct {
Store *storm.DB
}
+// Stage in the kanban pipeline, can hold a number of tickets.
+type Stage struct {
+ ID int `storm:"id,index"`
+ Name string
+ Tickets []Ticket
+}
+
+// Ticket in a stage.
+type Ticket struct {
+ ID int
+ Title string
+ Category string
+ Summary string
+ Details string
+ References []int
+ Created time.Time
+}
+
// ListStages returns a list of stages.
func (k Kanban) ListStages() ([]Stage, error) {
var stages []Stage
@@ -136,11 +155,14 @@ func (k *Kanban) StageFor(ticket int) (string, error) {
}
func (k *Kanban) Assign(name string, ticket Ticket) error {
- id, err := k.nextID()
- if err != nil {
- return fmt.Errorf("generating ID: %w", err)
+ if ticket.ID == 0 {
+ id, err := k.nextID()
+ if err != nil {
+ return fmt.Errorf("generating ID: %w", err)
+ }
+ ticket.ID = id
+ ticket.Created = time.Now()
}
- ticket.ID = id
stage, err := k.Stage(name)
if err != nil {
return fmt.Errorf("finding stage: %w", err)
@@ -197,20 +219,3 @@ func (k *Kanban) nextID() (int, error) {
}
return max + 1, nil
}
-
-// Stage in the kanban pipeline, can hold a number of tickets.
-type Stage struct {
- ID int `storm:"id,index"`
- Name string
- Tickets []Ticket
-}
-
-// Ticket in a stage.
-type Ticket struct {
- ID int
- Title string
- Category string
- Summary string
- Details string
- References []int
-}