Fix UDA colors
This commit is contained in:
@ -15,6 +15,7 @@ type Common struct {
|
|||||||
TW taskwarrior.TaskWarrior
|
TW taskwarrior.TaskWarrior
|
||||||
Keymap *Keymap
|
Keymap *Keymap
|
||||||
Styles *Styles
|
Styles *Styles
|
||||||
|
Udas []string
|
||||||
|
|
||||||
pageStack *Stack[Component]
|
pageStack *Stack[Component]
|
||||||
width int
|
width int
|
||||||
@ -27,6 +28,7 @@ func NewCommon(ctx context.Context, tw taskwarrior.TaskWarrior) *Common {
|
|||||||
TW: tw,
|
TW: tw,
|
||||||
Keymap: NewKeymap(),
|
Keymap: NewKeymap(),
|
||||||
Styles: NewStyles(tw.GetConfig()),
|
Styles: NewStyles(tw.GetConfig()),
|
||||||
|
Udas: tw.GetUdas(),
|
||||||
|
|
||||||
pageStack: NewStack[Component](),
|
pageStack: NewStack[Component](),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,8 @@ type Styles struct {
|
|||||||
ColumnBlurred lipgloss.Style
|
ColumnBlurred lipgloss.Style
|
||||||
ColumnInsert lipgloss.Style
|
ColumnInsert lipgloss.Style
|
||||||
|
|
||||||
|
Colors map[string]lipgloss.Style
|
||||||
|
|
||||||
// TODO: make color config completely dynamic to account for keyword., project., tag. and uda. colors
|
// TODO: make color config completely dynamic to account for keyword., project., tag. and uda. colors
|
||||||
Active lipgloss.Style
|
Active lipgloss.Style
|
||||||
Alternate lipgloss.Style
|
Alternate lipgloss.Style
|
||||||
@ -114,10 +116,12 @@ func NewStyles(config *taskwarrior.TWConfig) *Styles {
|
|||||||
|
|
||||||
func parseColors(config map[string]string) *Styles {
|
func parseColors(config map[string]string) *Styles {
|
||||||
styles := Styles{}
|
styles := Styles{}
|
||||||
|
colors := make(map[string]lipgloss.Style)
|
||||||
|
|
||||||
for key, value := range config {
|
for key, value := range config {
|
||||||
if strings.HasPrefix(key, "color.") {
|
if strings.HasPrefix(key, "color.") {
|
||||||
_, colorValue, _ := strings.Cut(key, ".")
|
_, colorValue, _ := strings.Cut(key, ".")
|
||||||
|
colors[colorValue] = parseColorString(value)
|
||||||
switch colorValue {
|
switch colorValue {
|
||||||
case "active":
|
case "active":
|
||||||
styles.Active = parseColorString(value)
|
styles.Active = parseColorString(value)
|
||||||
@ -217,6 +221,8 @@ func parseColors(config map[string]string) *Styles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
styles.Colors = colors
|
||||||
|
|
||||||
return &styles
|
return &styles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package table
|
package table
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -189,6 +190,18 @@ func (m *Model) parseRowStyles(rows taskwarrior.Tasks) []lipgloss.Style {
|
|||||||
styles[i] = m.common.Styles.Recurring.Inherit(m.styles.Cell).Margin(m.styles.Cell.GetMargin()).Padding(m.styles.Cell.GetPadding())
|
styles[i] = m.common.Styles.Recurring.Inherit(m.styles.Cell).Margin(m.styles.Cell.GetMargin()).Padding(m.styles.Cell.GetPadding())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// TOOD: move udas to proper location
|
||||||
|
if len(m.common.Udas) > 0 {
|
||||||
|
for _, uda := range m.common.Udas {
|
||||||
|
if u, ok := task.Udas[uda]; ok {
|
||||||
|
if style, ok := m.common.Styles.Colors[fmt.Sprintf("uda.%s.%s", uda, u)]; ok {
|
||||||
|
styles[i] = style.Inherit(m.styles.Cell).Margin(m.styles.Cell.GetMargin()).Padding(m.styles.Cell.GetPadding())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// TODO: make styles optional and discard if empty
|
||||||
if len(task.Tags) > 0 {
|
if len(task.Tags) > 0 {
|
||||||
styles[i] = m.common.Styles.Tagged.Inherit(m.styles.Cell).Margin(m.styles.Cell.GetMargin()).Padding(m.styles.Cell.GetPadding())
|
styles[i] = m.common.Styles.Tagged.Inherit(m.styles.Cell).Margin(m.styles.Cell.GetMargin()).Padding(m.styles.Cell.GetPadding())
|
||||||
taskIteration:
|
taskIteration:
|
||||||
@ -200,7 +213,6 @@ func (m *Model) parseRowStyles(rows taskwarrior.Tasks) []lipgloss.Style {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// TODO implement uda
|
|
||||||
styles[i] = m.common.Styles.Base.Inherit(m.styles.Cell).Margin(m.styles.Cell.GetMargin()).Padding(m.styles.Cell.GetPadding())
|
styles[i] = m.common.Styles.Base.Inherit(m.styles.Cell).Margin(m.styles.Cell.GetMargin()).Padding(m.styles.Cell.GetPadding())
|
||||||
}
|
}
|
||||||
return styles
|
return styles
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package pages
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"slices"
|
|
||||||
"strings"
|
"strings"
|
||||||
"tasksquire/common"
|
"tasksquire/common"
|
||||||
|
|
||||||
@ -52,8 +51,6 @@ func NewTaskEditorPage(com *common.Common, task taskwarrior.Task) *TaskEditorPag
|
|||||||
priorityOptions := append([]string{"(none)"}, p.common.TW.GetPriorities()...)
|
priorityOptions := append([]string{"(none)"}, p.common.TW.GetPriorities()...)
|
||||||
projectOptions := append([]string{"(none)"}, p.common.TW.GetProjects()...)
|
projectOptions := append([]string{"(none)"}, p.common.TW.GetProjects()...)
|
||||||
tagOptions := p.common.TW.GetTags()
|
tagOptions := p.common.TW.GetTags()
|
||||||
tagOptions = append(tagOptions, strings.Split(p.common.TW.GetConfig().Get("uda.tasksquire.tags.default"), ",")...)
|
|
||||||
slices.Sort(tagOptions)
|
|
||||||
|
|
||||||
p.areas = map[area]tea.Model{
|
p.areas = map[area]tea.Model{
|
||||||
areaTask: NewTaskEdit(p.common, &p.task.Description, &p.task.Priority, &p.task.Project, priorityOptions, projectOptions),
|
areaTask: NewTaskEdit(p.common, &p.task.Description, &p.task.Priority, &p.task.Project, priorityOptions, projectOptions),
|
||||||
@ -459,11 +456,11 @@ func NewTaskEdit(common *common.Common, description *string, priority *string, p
|
|||||||
return &t
|
return &t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t taskEdit) Init() tea.Cmd {
|
func (t *taskEdit) Init() tea.Cmd {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t taskEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (t *taskEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
switch msg.(type) {
|
switch msg.(type) {
|
||||||
case nextFieldMsg:
|
case nextFieldMsg:
|
||||||
if t.cursor == len(t.fields)-1 {
|
if t.cursor == len(t.fields)-1 {
|
||||||
@ -490,7 +487,7 @@ func (t taskEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t taskEdit) View() string {
|
func (t *taskEdit) View() string {
|
||||||
views := make([]string, len(t.fields))
|
views := make([]string, len(t.fields))
|
||||||
for i, field := range t.fields {
|
for i, field := range t.fields {
|
||||||
views[i] = field.View()
|
views[i] = field.View()
|
||||||
@ -540,11 +537,11 @@ func NewTagEdit(common *common.Common, selected *[]string, options []string) *ta
|
|||||||
return &t
|
return &t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t tagEdit) Init() tea.Cmd {
|
func (t *tagEdit) Init() tea.Cmd {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t tagEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (t *tagEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
switch msg.(type) {
|
switch msg.(type) {
|
||||||
case nextFieldMsg:
|
case nextFieldMsg:
|
||||||
if t.cursor == len(t.fields)-1 {
|
if t.cursor == len(t.fields)-1 {
|
||||||
@ -625,11 +622,11 @@ func NewTimeEdit(common *common.Common, due *string, scheduled *string, wait *st
|
|||||||
return &t
|
return &t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t timeEdit) Init() tea.Cmd {
|
func (t *timeEdit) Init() tea.Cmd {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t timeEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (t *timeEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
switch msg.(type) {
|
switch msg.(type) {
|
||||||
case nextFieldMsg:
|
case nextFieldMsg:
|
||||||
if t.cursor == len(t.fields)-1 {
|
if t.cursor == len(t.fields)-1 {
|
||||||
@ -655,7 +652,7 @@ func (t timeEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t timeEdit) View() string {
|
func (t *timeEdit) View() string {
|
||||||
views := make([]string, len(t.fields))
|
views := make([]string, len(t.fields))
|
||||||
for i, field := range t.fields {
|
for i, field := range t.fields {
|
||||||
views[i] = field.View()
|
views[i] = field.View()
|
||||||
@ -796,12 +793,15 @@ func (p *TaskEditorPage) updateTasksCmd() tea.Msg {
|
|||||||
p.task.Priority = ""
|
p.task.Priority = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if *p.areas[areaTask].(taskEdit).newProjectName != "" {
|
if *(p.areas[areaTask].(*taskEdit).newProjectName) != "" {
|
||||||
p.task.Project = *p.areas[areaTask].(taskEdit).newProjectName
|
p.task.Project = *p.areas[areaTask].(*taskEdit).newProjectName
|
||||||
}
|
}
|
||||||
|
|
||||||
if *p.areas[areaTags].(tagEdit).newTagsValue != "" {
|
if *(p.areas[areaTags].(*tagEdit).newTagsValue) != "" {
|
||||||
p.task.Tags = append(p.task.Tags, strings.Split(*p.areas[areaTags].(tagEdit).newTagsValue, " ")...)
|
newTags := strings.Split(*p.areas[areaTags].(*tagEdit).newTagsValue, " ")
|
||||||
|
if len(newTags) > 0 {
|
||||||
|
p.task.Tags = append(p.task.Tags, newTags...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if p.additionalProject != "" {
|
// if p.additionalProject != "" {
|
||||||
|
|||||||
@ -23,28 +23,29 @@ func (a Annotation) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Task struct {
|
type Task struct {
|
||||||
Id int64 `json:"id,omitempty"`
|
Id int64 `json:"id,omitempty"`
|
||||||
Uuid string `json:"uuid,omitempty"`
|
Uuid string `json:"uuid,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
Project string `json:"project"`
|
Project string `json:"project"`
|
||||||
Priority string `json:"priority"`
|
Priority string `json:"priority"`
|
||||||
Status string `json:"status,omitempty"`
|
Status string `json:"status,omitempty"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
VirtualTags []string `json:"-"`
|
VirtualTags []string `json:"-"`
|
||||||
Depends []string `json:"depends,omitempty"`
|
Depends []string `json:"depends,omitempty"`
|
||||||
DependsIds string `json:"-"`
|
DependsIds string `json:"-"`
|
||||||
Urgency float32 `json:"urgency,omitempty"`
|
Urgency float32 `json:"urgency,omitempty"`
|
||||||
Parent string `json:"parent,omitempty"`
|
Parent string `json:"parent,omitempty"`
|
||||||
Due string `json:"due,omitempty"`
|
Due string `json:"due,omitempty"`
|
||||||
Wait string `json:"wait,omitempty"`
|
Wait string `json:"wait,omitempty"`
|
||||||
Scheduled string `json:"scheduled,omitempty"`
|
Scheduled string `json:"scheduled,omitempty"`
|
||||||
Until string `json:"until,omitempty"`
|
Until string `json:"until,omitempty"`
|
||||||
Start string `json:"start,omitempty"`
|
Start string `json:"start,omitempty"`
|
||||||
End string `json:"end,omitempty"`
|
End string `json:"end,omitempty"`
|
||||||
Entry string `json:"entry,omitempty"`
|
Entry string `json:"entry,omitempty"`
|
||||||
Modified string `json:"modified,omitempty"`
|
Modified string `json:"modified,omitempty"`
|
||||||
Recur string `json:"recur,omitempty"`
|
Recur string `json:"recur,omitempty"`
|
||||||
Annotations []Annotation `json:"annotations,omitempty"`
|
Annotations []Annotation `json:"annotations,omitempty"`
|
||||||
|
Udas map[string]any `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) GetString(fieldWFormat string) string {
|
func (t *Task) GetString(fieldWFormat string) string {
|
||||||
|
|||||||
@ -89,6 +89,8 @@ type TaskWarrior interface {
|
|||||||
GetReport(report string) *Report
|
GetReport(report string) *Report
|
||||||
GetReports() Reports
|
GetReports() Reports
|
||||||
|
|
||||||
|
GetUdas() []string
|
||||||
|
|
||||||
GetTasks(report *Report, filter ...string) Tasks
|
GetTasks(report *Report, filter ...string) Tasks
|
||||||
AddTask(task *Task) error
|
AddTask(task *Task) error
|
||||||
ImportTask(task *Task)
|
ImportTask(task *Task)
|
||||||
@ -169,7 +171,15 @@ func (ts *TaskSquire) GetTasks(report *Report, filter ...string) Tasks {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, task := range tasks {
|
unstructuredTasks := make([]map[string]any, 0)
|
||||||
|
err = json.Unmarshal(output, &unstructuredTasks)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Failed unmarshalling tasks:", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, task := range tasks {
|
||||||
|
task.Udas = unstructuredTasks[i]
|
||||||
if task.Depends != nil && len(task.Depends) > 0 {
|
if task.Depends != nil && len(task.Depends) > 0 {
|
||||||
ids := make([]string, len(task.Depends))
|
ids := make([]string, len(task.Depends))
|
||||||
for i, dependUuid := range task.Depends {
|
for i, dependUuid := range task.Depends {
|
||||||
@ -281,10 +291,18 @@ func (ts *TaskSquire) GetTags() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tags := make([]string, 0)
|
tags := make([]string, 0)
|
||||||
|
tagSet := make(map[string]struct{})
|
||||||
|
|
||||||
for _, tag := range strings.Split(string(output), "\n") {
|
for _, tag := range strings.Split(string(output), "\n") {
|
||||||
if _, ok := virtualTags[tag]; !ok && tag != "" {
|
if _, ok := virtualTags[tag]; !ok && tag != "" {
|
||||||
tags = append(tags, tag)
|
tags = append(tags, tag)
|
||||||
|
tagSet[tag] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tag := range strings.Split(ts.config.Get("uda.tasksquire.tags.default"), ",") {
|
||||||
|
if _, ok := tagSet[tag]; !ok {
|
||||||
|
tags = append(tags, tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,6 +325,27 @@ func (ts *TaskSquire) GetReports() Reports {
|
|||||||
return ts.reports
|
return ts.reports
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ts *TaskSquire) GetUdas() []string {
|
||||||
|
ts.mutex.Lock()
|
||||||
|
defer ts.mutex.Unlock()
|
||||||
|
|
||||||
|
cmd := exec.Command(twBinary, append(ts.defaultArgs, "_udas")...)
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Failed getting config:", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
udas := make([]string, 0)
|
||||||
|
for _, uda := range strings.Split(string(output), "\n") {
|
||||||
|
if uda != "" {
|
||||||
|
udas = append(udas, uda)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return udas
|
||||||
|
}
|
||||||
|
|
||||||
func (ts *TaskSquire) SetContext(context *Context) error {
|
func (ts *TaskSquire) SetContext(context *Context) error {
|
||||||
ts.mutex.Lock()
|
ts.mutex.Lock()
|
||||||
defer ts.mutex.Unlock()
|
defer ts.mutex.Unlock()
|
||||||
|
|||||||
Binary file not shown.
11
test/taskrc
11
test/taskrc
@ -4,3 +4,14 @@ context.test.read=+test
|
|||||||
context.test.write=+test
|
context.test.write=+test
|
||||||
context.home.read=+home
|
context.home.read=+home
|
||||||
context.home.write=+home
|
context.home.write=+home
|
||||||
|
|
||||||
|
uda.testuda.type=string
|
||||||
|
uda.testuda.label=testuda
|
||||||
|
uda.testuda.values=eins,zwei,drei
|
||||||
|
|
||||||
|
report.next.columns=id,testuda,start.age,entry.age,depends,priority,project,tags,recur,scheduled.countdown,due.relative,until.remaining,description,urgency
|
||||||
|
report.next.context=1
|
||||||
|
report.next.description=Most urgent tasks
|
||||||
|
report.next.filter=status:pending -WAITING
|
||||||
|
report.next.labels=ID,UDA,Active,Age,Deps,P,Project,Tag,Recur,S,Due,Until,Description,Urg
|
||||||
|
report.next.sort=urgency-
|
||||||
|
|||||||
Reference in New Issue
Block a user