202 lines
4.7 KiB
Go
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
|