2
1
Fork 0
swim/lane.go

141 lines
3.6 KiB
Go

package main
import (
"fmt"
"strconv"
"strings"
)
type Lane struct {
Title string `json:"LaneTitle"`
Stories []Story `json:"Stories"`
Current int `json:"CurrentStory"` // Index of current story
storyOff int // offset for the lane slice
}
func (l *Lane) CreateStory(name string, b *Board) {
if name == "" {
name = GetEditableLine("Story Title: ", "")
if name == "" {
b.SetMessage("Cancelled story creation", true)
return
}
}
l.Stories = append(l.Stories, MakeStory(name))
if l.Current < 0 {
l.Current = 0
}
unsavedChanges = true
b.SetMessage("Story created", false)
}
// Zeroes out the offset and current values
func (l *Lane) ResetLoadPositions() {
if len(l.Stories) > 0 {
l.Current = 0
} else {
l.Current = -1
}
l.storyOff = 0
}
func (l Lane) Header(width int, selected bool) string {
marker := " "
color := style.Lane
if selected {
marker = "*"
color = style.LaneSelected
}
if len(l.Title) > width {
return fmt.Sprintf("%s\033[1;7m%*.*s%s%s", style.Lane, width, width, l.Title[:width-1], marker, styleOff)
} else {
width := width - 2
leftPad := (width - len(l.Title)) / 2
rightPad := width - len(l.Title) - leftPad
return fmt.Sprintf("%s %s\033[1;7m%*.*s%s%s%*.*s\033[27m%s %s", style.Lane, color, leftPad-1, leftPad-1, "", l.Title, marker, rightPad, rightPad, "", style.Lane, styleOff)
}
}
func (l Lane) StringSlice(width int, selected bool) []string {
out := make([]string, 0, len(l.Stories) * 3 + 1)
for i := l.storyOff; i < len(l.Stories); i++ {
// Top spacer
out = append(out, fmt.Sprintf("%s%*.*s%s", style.Lane, width, width, " ", styleOff))
// First card row
title := l.Stories[i].Title
if len(title) > width-4 {
title = title[:width-5] + "…"
}
leadIn := " "
if selected && l.Current == i {
leadIn = "\033[1m➜ "
}
out = append(out, fmt.Sprintf("%s %s%s%-*.*s%s %s", style.Lane, style.Input, leadIn, width-4, width-4, title, style.Lane, styleOff))
// Second card row
pts := strconv.Itoa(l.Stories[i].Points)
if pts == "0" || pts[0] == '-' {
pts = ""
}
users := l.Stories[i].GetUserAbbrString()
if len(users) > width-4 {
users = users[:width-5] + "…"
}
out = append(out, fmt.Sprintf("%s %s %-*.*s\033[7m%*s\033[27m%s %s", style.Lane, style.Input, width-7, width-7, users, 3, pts, style.Lane, styleOff))
}
if len(out) > 0 {
out = append(out, fmt.Sprintf("%s%*.*s%s", style.Lane, width, width, " ", styleOff))
}
return out
}
func (l *Lane) DeleteStory(b *Board) {
if len(l.Stories) < 1 {
b.SetMessage("There are no stories to delete in this lane", true)
return
}
cont, err := GetConfirmation("Are you sure you want to delete this story? Type 'yes' to delete: ")
if err != nil {
b.SetMessage(err.Error(), true)
return
}
if !cont {
b.SetMessage("Deletion canceled", true)
return
}
if l.Current == len(l.Stories)-1 {
l.Stories = l.Stories[:len(l.Stories)-1]
} else {
l.Stories = append(l.Stories[:l.Current], l.Stories[l.Current+1:]...)
}
if l.Current > len(l.Stories)-1 {
l.Current -= 1
}
b.StoryOpen = false
unsavedChanges = true
b.SetMessage("Story deleted", false)
}
func (l *Lane) Update(args []string, b *Board) {
location := strings.ToLower(args[0])
switch location {
case "title", "t", "name", "n":
title := GetEditableLine("New lane title: ", l.Title)
if title == "" {
b.SetMessage("Canceled lane title update", true)
break
}
l.Title = title
unsavedChanges = true
b.SetMessage("Lane title updated", false)
default:
b.SetMessage(fmt.Sprintf("Unknown lane location %q", args[0]), true)
}
}
func MakeLane(title string) Lane {
return Lane{title, make([]Story,0,5), -1, 0}
}