Files
tasksquire/pages/report.go
2024-05-20 21:17:47 +02:00

202 lines
4.7 KiB
Go

package pages
import (
"strconv"
"strings"
"tasksquire/common"
"tasksquire/taskwarrior"
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/table"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
type ReportPage struct {
common *common.Common
activeReport *taskwarrior.Report
activeContext *taskwarrior.Context
activeProject string
selectedTask *taskwarrior.Task
tasks taskwarrior.Tasks
taskTable table.Model
tableStyle table.Styles
keymap ReportKeys
subpage tea.Model
subpageActive bool
}
type ReportKeys struct {
Quit key.Binding
Up key.Binding
Down key.Binding
Select key.Binding
ToggleFocus key.Binding
}
func NewReportPage(com *common.Common, report *taskwarrior.Report) *ReportPage {
s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("240")).
BorderBottom(true).
Bold(false)
s.Selected = s.Selected.
Foreground(lipgloss.Color("229")).
Background(lipgloss.Color("57")).
Bold(false)
keys := ReportKeys{
Quit: key.NewBinding(
key.WithKeys("q", "ctrl+c"),
key.WithHelp("q, ctrl+c", "Quit"),
),
Up: key.NewBinding(
key.WithKeys("k", "up"),
key.WithHelp("↑/k", "Up"),
),
Down: key.NewBinding(
key.WithKeys("j", "down"),
key.WithHelp("↓/j", "Down"),
),
Select: key.NewBinding(
key.WithKeys("enter"),
key.WithHelp("enter", "Select"),
),
ToggleFocus: key.NewBinding(
key.WithKeys("esc"),
key.WithHelp("esc", "Toggle focus"),
),
}
return &ReportPage{
common: com,
activeReport: report,
activeContext: com.TW.GetActiveContext(),
activeProject: "",
tableStyle: s,
keymap: keys,
}
}
func (p ReportPage) Init() tea.Cmd {
return p.getTasks()
}
func (p ReportPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case BackMsg:
p.subpageActive = false
case TaskMsg:
p.populateTaskTable(msg)
case UpdateReportMsg:
p.activeReport = msg
cmds = append(cmds, p.getTasks())
case UpdateContextMsg:
p.activeContext = msg
p.common.TW.SetContext(msg)
cmds = append(cmds, p.getTasks())
case UpdateProjectMsg:
p.activeProject = string(msg)
cmds = append(cmds, p.getTasks())
case AddedTaskMsg:
cmds = append(cmds, p.getTasks())
case tea.WindowSizeMsg:
p.taskTable.SetWidth(msg.Width - 2)
p.taskTable.SetHeight(msg.Height - 4)
case tea.KeyMsg:
switch {
case key.Matches(msg, p.common.Keymap.Quit):
return p, tea.Quit
case key.Matches(msg, p.common.Keymap.SetReport):
p.subpage = NewReportPickerPage(p.common, p.activeReport)
p.subpage.Init()
p.subpageActive = true
p.common.PageStack.Push(p)
return p.subpage, nil
case key.Matches(msg, p.common.Keymap.SetContext):
p.subpage = NewContextPickerPage(p.common)
p.subpage.Init()
p.subpageActive = true
p.common.PageStack.Push(p)
return p.subpage, nil
case key.Matches(msg, p.common.Keymap.Add):
p.subpage = NewTaskEditorPage(p.common, taskwarrior.Task{})
p.subpage.Init()
p.subpageActive = true
p.common.PageStack.Push(p)
return p.subpage, nil
case key.Matches(msg, p.common.Keymap.SetProject):
p.subpage = NewProjectPickerPage(p.common, p.activeProject)
p.subpage.Init()
p.subpageActive = true
p.common.PageStack.Push(p)
return p.subpage, nil
}
}
var cmd tea.Cmd
p.taskTable, cmd = p.taskTable.Update(msg)
cmds = append(cmds, cmd)
if p.tasks != nil {
p.selectedTask = (*taskwarrior.Task)(p.tasks[p.taskTable.Cursor()])
}
return p, tea.Batch(cmds...)
}
func (p ReportPage) View() string {
return p.common.Styles.Main.Render(p.taskTable.View()) + "\n"
}
func (p *ReportPage) populateTaskTable(tasks []*taskwarrior.Task) {
columns := []table.Column{
{Title: "ID", Width: 4},
{Title: "Project", Width: 10},
{Title: "Tags", Width: 10},
{Title: "Prio", Width: 2},
{Title: "Due", Width: 10},
{Title: "Task", Width: 50},
}
var rows []table.Row
for _, task := range tasks {
rows = append(rows, table.Row{
strconv.FormatInt(task.Id, 10),
task.Project,
strings.Join(task.Tags, ", "),
task.Priority,
task.Due,
task.Description,
})
}
p.taskTable = table.New(
table.WithColumns(columns),
table.WithRows(rows),
table.WithFocused(true),
// table.WithHeight(7),
// table.WithWidth(100),
)
p.taskTable.SetStyles(p.tableStyle)
}
func (p *ReportPage) getTasks() tea.Cmd {
return func() tea.Msg {
filters := []string{}
if p.activeProject != "" {
filters = append(filters, "project:"+p.activeProject)
}
p.tasks = p.common.TW.GetTasks(p.activeReport, filters...)
return TaskMsg(p.tasks)
}
}
type TaskMsg taskwarrior.Tasks