github.com/wtfutil/wtf@v0.43.0/modules/jira/widget.go (about) 1 package jira 2 3 import ( 4 "fmt" 5 6 "github.com/rivo/tview" 7 "github.com/wtfutil/wtf/utils" 8 "github.com/wtfutil/wtf/view" 9 ) 10 11 type Widget struct { 12 view.ScrollableWidget 13 14 result *SearchResult 15 settings *Settings 16 err error 17 } 18 19 func NewWidget(tviewApp *tview.Application, redrawChan chan bool, pages *tview.Pages, settings *Settings) *Widget { 20 widget := Widget{ 21 ScrollableWidget: view.NewScrollableWidget(tviewApp, redrawChan, pages, settings.Common), 22 23 settings: settings, 24 } 25 26 widget.SetRenderFunction(widget.Render) 27 widget.initializeKeyboardControls() 28 29 return &widget 30 } 31 32 /* -------------------- Exported Functions -------------------- */ 33 34 func (widget *Widget) Refresh() { 35 searchResult, err := widget.IssuesFor( 36 widget.settings.username, 37 widget.settings.projects, 38 widget.settings.jql, 39 ) 40 41 if err != nil { 42 widget.err = err 43 widget.result = nil 44 widget.SetItemCount(0) 45 } else { 46 widget.err = nil 47 widget.result = searchResult 48 widget.SetItemCount(len(searchResult.Issues)) 49 } 50 widget.Render() 51 } 52 53 func (widget *Widget) Render() { 54 widget.Redraw(widget.content) 55 } 56 57 /* -------------------- Unexported Functions -------------------- */ 58 59 func (widget *Widget) openItem() { 60 sel := widget.GetSelected() 61 if sel >= 0 && widget.result != nil && sel < len(widget.result.Issues) { 62 issue := &widget.result.Issues[sel] 63 utils.OpenFile(widget.settings.domain + "/browse/" + issue.Key) 64 } 65 } 66 67 const MaxIssueTypeLength = 7 68 const MaxStatusNameLength = 14 69 70 func (widget *Widget) content() (string, string, bool) { 71 if widget.err != nil { 72 return widget.CommonSettings().Title, widget.err.Error(), true 73 } 74 75 title := widget.CommonSettings().Title 76 77 str := fmt.Sprintf(" [%s]Assigned Issues[white]\n", widget.settings.Colors.Subheading) 78 79 if widget.result == nil || len(widget.result.Issues) == 0 { 80 return title, "No results to display", false 81 } 82 83 longestIssueTypeLength, longestKeyLength, longestStatusNameLength := getLongestColumnLengths(widget.result.Issues) 84 85 for idx, issue := range widget.result.Issues { 86 row := fmt.Sprintf( 87 `[%s] [%s]%-*s[white] [green]%-*s[white] [yellow]%-*s[white] [%s]%s`, 88 widget.RowColor(idx), 89 widget.issueTypeColor(&issue), 90 longestIssueTypeLength+1, 91 trimToMaxLength(issue.IssueFields.IssueType.Name, MaxIssueTypeLength), 92 longestKeyLength+1, 93 issue.Key, 94 longestStatusNameLength+1, 95 trimToMaxLength(issue.IssueFields.IssueStatus.IName, MaxStatusNameLength), 96 widget.RowColor(idx), 97 tview.Escape(issue.IssueFields.Summary), 98 ) 99 100 str += utils.HighlightableHelper(widget.View, row, idx, len(issue.IssueFields.Summary)) 101 } 102 103 return title, str, false 104 } 105 106 func getLongestColumnLengths(issues []Issue) (int, int, int) { 107 longestIssueTypeLength := 0 108 longestKeyLength := 0 109 longestStatusNameLength := 0 110 for _, issue := range issues { 111 issueTypeLength := len(issue.IssueFields.IssueType.Name) 112 if issueTypeLength > longestIssueTypeLength { 113 longestIssueTypeLength = issueTypeLength 114 } 115 116 issueKeyLength := len(issue.Key) 117 if issueKeyLength > longestKeyLength { 118 longestKeyLength = len("WTF-XXX") // issueKeyLength 119 } 120 121 statusNameLength := len(issue.IssueFields.IssueStatus.IName) 122 if statusNameLength > longestStatusNameLength { 123 longestStatusNameLength = statusNameLength 124 } 125 } 126 127 if longestIssueTypeLength > MaxIssueTypeLength { 128 longestIssueTypeLength = MaxIssueTypeLength 129 } 130 131 if longestStatusNameLength > MaxStatusNameLength { 132 longestStatusNameLength = MaxStatusNameLength 133 } 134 135 return longestIssueTypeLength, longestKeyLength, longestStatusNameLength 136 } 137 138 func (*Widget) issueTypeColor(issue *Issue) string { 139 switch issue.IssueFields.IssueType.Name { 140 case "Bug": 141 return "red" 142 case "Story": 143 return "blue" 144 case "Task": 145 return "orange" 146 default: 147 return "white" 148 } 149 } 150 151 func trimToMaxLength(text string, maxLength int) string { 152 if len(text) <= maxLength { 153 return text 154 } else { 155 return text[:maxLength] 156 } 157 }