From 81fbc1b949f4c5e394e8fc20fa5d4801f338f36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20B=C3=BCtow?= <1224732+snonux@users.noreply.github.com> Date: Thu, 19 Jun 2025 23:59:05 +0300 Subject: Add table-based UI and extend task fields --- internal/task/task.go | 22 ++++++++++++++++----- internal/ui/table.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ internal/ui/ui.go | 47 ------------------------------------------- 3 files changed, 72 insertions(+), 52 deletions(-) create mode 100644 internal/ui/table.go delete mode 100644 internal/ui/ui.go (limited to 'internal') diff --git a/internal/task/task.go b/internal/task/task.go index dcb3e9a..a39a7f6 100644 --- a/internal/task/task.go +++ b/internal/task/task.go @@ -8,12 +8,24 @@ import ( ) // Task represents a taskwarrior task as returned by `task export`. +type Annotation struct { + Entry string `json:"entry"` + Description string `json:"description"` +} + type Task struct { - ID int `json:"id"` - UUID string `json:"uuid"` - Description string `json:"description"` - Tags []string `json:"tags"` - Status string `json:"status"` + ID int `json:"id"` + UUID string `json:"uuid"` + Description string `json:"description"` + Tags []string `json:"tags"` + Status string `json:"status"` + Start string `json:"start"` + Entry string `json:"entry"` + Due string `json:"due"` + Priority string `json:"priority"` + Recur string `json:"recur"` + Urgency float64 `json:"urgency"` + Annotations []Annotation `json:"annotations"` } // Add creates a new task with the given description and tags. diff --git a/internal/ui/table.go b/internal/ui/table.go new file mode 100644 index 0000000..682a680 --- /dev/null +++ b/internal/ui/table.go @@ -0,0 +1,55 @@ +package ui + +import ( + "github.com/charmbracelet/bubbles/table" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" +) + +// Model wraps a Bubble Tea table.Model to display tasks. +type Model struct{ tbl table.Model } + +// New creates a new UI model with the provided rows. +func New(rows []table.Row) Model { + cols := []table.Column{ + {Title: "ID", Width: 4}, + {Title: "Task", Width: 30}, + {Title: "Active", Width: 6}, + {Title: "Age", Width: 6}, + {Title: "Pri", Width: 4}, + {Title: "Tags", Width: 15}, + {Title: "Recur", Width: 6}, + {Title: "Due", Width: 10}, + {Title: "Urg", Width: 5}, + {Title: "Annotations", Width: 20}, + } + t := table.New( + table.WithColumns(cols), + table.WithRows(rows), + table.WithFocused(true), + ) + styles := table.DefaultStyles() + styles.Header = styles.Header.Foreground(lipgloss.Color("205")) + styles.Selected = styles.Selected.Foreground(lipgloss.Color("229")).Background(lipgloss.Color("57")) + styles.Cell = styles.Cell.Padding(0, 1) + t.SetStyles(styles) + return Model{tbl: t} +} + +// Init implements tea.Model. +func (m Model) Init() tea.Cmd { return nil } + +// Update handles key and window events. +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.WindowSizeMsg: + m.tbl.SetWidth(msg.Width) + m.tbl.SetHeight(msg.Height - 2) + } + var cmd tea.Cmd + m.tbl, cmd = m.tbl.Update(msg) + return m, cmd +} + +// View renders the table UI. +func (m Model) View() string { return m.tbl.View() } diff --git a/internal/ui/ui.go b/internal/ui/ui.go deleted file mode 100644 index 244c191..0000000 --- a/internal/ui/ui.go +++ /dev/null @@ -1,47 +0,0 @@ -package ui - -import ( - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" -) - -// Model wraps a Bubble Tea list.Model to display tasks. -type Model struct { - list list.Model -} - -// New creates a new UI model with the provided Bubble Tea list. -func New(l list.Model) Model { - return Model{list: l} -} - -// Init implements tea.Model. -func (m Model) Init() tea.Cmd { return nil } - -// Update handles key and window events. -func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - case "j": - msg = tea.KeyMsg{Type: tea.KeyDown} - case "k": - msg = tea.KeyMsg{Type: tea.KeyUp} - } - return m.updateList(msg) - case tea.WindowSizeMsg: - m.list.SetSize(msg.Width, msg.Height-2) - } - return m.updateList(msg) -} - -func (m *Model) updateList(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmd tea.Cmd - m.list, cmd = m.list.Update(msg) - return m, cmd -} - -// View renders the list UI. -func (m Model) View() string { - return m.list.View() -} -- cgit v1.2.3