Files
task-master/internal/ui/views/projects.go
T
SkrueckenandCursor 41feba11de Add multiselect board filters and letter-jump on picker menus.
Persist comma-separated list filters per project, toggle with space, and jump by first letter in board and project pickers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 10:42:59 +02:00

86 lines
1.9 KiB
Go

package views
import (
"unicode"
"github.com/charmbracelet/bubbles/list"
"task/internal/project"
)
// ProjectItem wraps a project for bubbles/list.
type ProjectItem struct {
Project project.Project
Active bool
}
func (i ProjectItem) Title() string {
if i.Active {
return i.Project.Name + " *"
}
return i.Project.Name
}
func (i ProjectItem) Description() string { return i.Project.ID }
func (i ProjectItem) FilterValue() string { return i.Project.Name }
// NewProjectList builds a list of projects.
func NewProjectList(projects []project.Project, activeID string, width, height int) list.Model {
items := make([]list.Item, len(projects))
selected := 0
for i, p := range projects {
items[i] = ProjectItem{Project: p, Active: p.ID == activeID}
if p.ID == activeID {
selected = i
}
}
delegate := list.NewDefaultDelegate()
delegate.ShowDescription = false
l := list.New(items, delegate, width, height)
l.Title = "Projects"
l.SetShowStatusBar(false)
l.SetShowHelp(false)
l.SetFilteringEnabled(false)
l.DisableQuitKeybindings()
if len(items) > 0 {
l.Select(selected)
}
return l
}
// JumpProjectByLetter cycles to the next project whose name starts with r.
func JumpProjectByLetter(l *list.Model, r rune) bool {
r = unicode.ToLower(r)
items := l.Items()
n := len(items)
if n == 0 {
return false
}
start := l.Index()
for step := 1; step <= n; step++ {
i := (start + step) % n
pi, ok := items[i].(ProjectItem)
if !ok {
continue
}
name := []rune(pi.Project.Name)
if len(name) == 0 {
continue
}
if unicode.ToLower(name[0]) == r {
l.Select(i)
return true
}
}
return false
}
// ProjectsToItems converts projects to list items.
func ProjectsToItems(projects []project.Project, activeID string) []list.Item {
items := make([]list.Item, len(projects))
for i, p := range projects {
items[i] = ProjectItem{Project: p, Active: p.ID == activeID}
}
return items
}