kanban

Kanban client in Gio
Log | Files | Refs | README | LICENSE

commit 04efaa119ebcb4458b0b9c809c3b0e65ac2a0a04
parent d83630684c3b39c5c4ee09b11799c5adf58127fc
Author: Jack Mordaunt <jackmordaunt@gmail.com>
Date:   Thu,  5 Nov 2020 11:05:15 +0800

feat: time tracking

Diffstat:
Mcmd/kanban/main.go | 24++++++++++++++++++++----
Mkanban.go | 47++++++++++++++++++++++++++---------------------
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 -}