Charm-based CLI with JSON persistence, status/list filters, external editor editing, command-history undo/redo, and glamour markdown without AutoStyle OSC hangs. Co-authored-by: Cursor <cursoragent@cursor.com>
67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package views
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"task/internal/ticket"
|
|
)
|
|
|
|
// BoardMenu renders a board-list picker overlay.
|
|
type BoardMenu struct {
|
|
Cursor int
|
|
Width int
|
|
Styles StatusMenuStyles
|
|
}
|
|
|
|
// NewBoardMenu creates a menu with the given board list pre-selected.
|
|
func NewBoardMenu(current ticket.BoardList, width int, styles StatusMenuStyles) BoardMenu {
|
|
return BoardMenu{
|
|
Cursor: current.Index(),
|
|
Width: width,
|
|
Styles: styles,
|
|
}
|
|
}
|
|
|
|
// MoveDown moves the selection down.
|
|
func (m *BoardMenu) MoveDown() {
|
|
if m.Cursor < len(ticket.AllBoardLists)-1 {
|
|
m.Cursor++
|
|
}
|
|
}
|
|
|
|
// MoveUp moves the selection up.
|
|
func (m *BoardMenu) MoveUp() {
|
|
if m.Cursor > 0 {
|
|
m.Cursor--
|
|
}
|
|
}
|
|
|
|
// Selected returns the currently highlighted board list.
|
|
func (m BoardMenu) Selected() ticket.BoardList {
|
|
if m.Cursor < 0 || m.Cursor >= len(ticket.AllBoardLists) {
|
|
return ticket.BoardAll
|
|
}
|
|
return ticket.AllBoardLists[m.Cursor]
|
|
}
|
|
|
|
// View renders the board menu.
|
|
func (m BoardMenu) View() string {
|
|
var lines []string
|
|
lines = append(lines, m.Styles.Title.Render("Switch list"))
|
|
for i, bl := range ticket.AllBoardLists {
|
|
label := " " + bl.Label()
|
|
if i == m.Cursor {
|
|
label = m.Styles.Selected.Render("▸ " + bl.Label())
|
|
} else {
|
|
label = m.Styles.Normal.Render(label)
|
|
}
|
|
lines = append(lines, label)
|
|
}
|
|
body := strings.Join(lines, "\n")
|
|
w := m.Width
|
|
if w < 20 {
|
|
w = 20
|
|
}
|
|
return m.Styles.Box.Width(min(40, w-2)).Render(body)
|
|
}
|