summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Bütow <1224732+snonux@users.noreply.github.com>2025-06-19 23:59:05 +0300
committerPaul Bütow <1224732+snonux@users.noreply.github.com>2025-06-19 23:59:05 +0300
commit81fbc1b949f4c5e394e8fc20fa5d4801f338f36e (patch)
tree8bdd31825f08b70b604f5160aad6fdaf024e7acc /internal
parentbf39c17221d1df1815c9cd78fa33b144c9d5dfb6 (diff)
Add table-based UI and extend task fields
Diffstat (limited to 'internal')
-rw-r--r--internal/task/task.go22
-rw-r--r--internal/ui/table.go55
-rw-r--r--internal/ui/ui.go47
3 files changed, 72 insertions, 52 deletions
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()
-}