Skip to content

Commit

Permalink
feat: Issue view mode
Browse files Browse the repository at this point in the history
  • Loading branch information
ankitpokhrel committed Dec 29, 2020
1 parent 25397df commit 159f0d9
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 145 deletions.
45 changes: 29 additions & 16 deletions internal/view/epic.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package view
import (
"fmt"

"github.com/ankitpokhrel/jira-cli/api"
"github.com/ankitpokhrel/jira-cli/internal/cmdutil"
"github.com/ankitpokhrel/jira-cli/pkg/jira"
"github.com/ankitpokhrel/jira-cli/pkg/tui"
)
Expand All @@ -17,22 +19,42 @@ type EpicList struct {
Server string
Data []*jira.Issue
Issues EpicIssueFunc

issueCache map[string]tui.TableData
}

// Render renders the epic explorer view.
func (el EpicList) Render() error {
data := el.data()
renderer, err := MDRenderer()
if err != nil {
return err
}

data := el.data()
view := tui.NewPreview(
tui.WithPreviewFooterText(fmt.Sprintf("Showing %d of %d results for project \"%s\"", len(el.Data), el.Total, el.Project)),
tui.WithInitialText(helpText),
tui.WithSidebarSelectedFunc(navigate(el.Server)),
tui.WithContentTableOpts(tui.WithSelectedFunc(navigate(el.Server))),
tui.WithContentTableOpts(
tui.WithSelectedFunc(navigate(el.Server)),
tui.WithViewModeFunc(func(r, c int, d interface{}) error {
issue := func() *jira.Issue {
s := cmdutil.Info("Fetching issue details...")
defer s.Stop()

dt := d.(tui.TableData)
issue, _ := api.Client(jira.Config{Debug: true}).GetIssue(dt[r][1])

return issue
}()
out, err := renderer.Render(Issue{Data: issue}.String())
if err != nil {
return err
}
return PagerOut(out)
}),
),
)

return view.Render(data)
return view.Paint(data)
}

func (el EpicList) data() []tui.PreviewData {
Expand All @@ -51,17 +73,8 @@ func (el EpicList) data() []tui.PreviewData {
Key: issue.Key,
Menu: fmt.Sprintf("➤ %s: %s", issue.Key, prepareTitle(issue.Fields.Summary)),
Contents: func(key string) interface{} {
if el.issueCache == nil {
el.issueCache = make(map[string]tui.TableData)
}

if _, ok := el.issueCache[key]; !ok {
issues := el.Issues(key)

el.issueCache[key] = el.tabularize(issues)
}

return el.issueCache[key]
issues := el.Issues(key)
return el.tabularize(issues)
},
})
}
Expand Down
37 changes: 26 additions & 11 deletions internal/view/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,36 @@ import (
"text/tabwriter"
"time"

"github.com/charmbracelet/glamour"
"github.com/pkg/browser"

"github.com/ankitpokhrel/jira-cli/pkg/tui"
)

const helpText = `Use up and down arrow keys or 'j' and 'k' letters to navigate through the list.
Press 'w' to toggle focus between the sidebar and the contents screen. On contents screen,
you can use arrow keys or 'j', 'k', 'h', and 'l' letters to navigate through the epic issue list.
Press ENTER to open the selected issue in the browser.
const (
wordWrap = 120
helpText = `USAGE
-----
The layout contains 2 sections, viz: Sidebar and Contents screen.
You can use up and down arrow keys or 'j' and 'k' letters to navigate through the sidebar.
Press 'w' to toggle focus between the sidebar and the contents screen.
On contents screen:
- Use arrow keys or 'j', 'k', 'h', and 'l' letters to navigate through the issue list.
- Use 'g' and 'SHIFT+G' to quickly navigate to the top and bottom respectively.
- Press 'v' to view selected issue details.
- Hit ENTER to open the selected issue in a browser.
Press 'q' / ESC / CTRL+C to quit.`
)

func formatDateTime(dt, format string) string {
t, err := time.Parse(format, dt)
if err != nil {
return dt
}

return t.Format("2006-01-02 15:04:05")
}

Expand All @@ -38,7 +48,6 @@ func formatDateTimeHuman(dt, format string) string {
if err != nil {
return dt
}

return t.Format("Mon, 02 Jan 06")
}

Expand Down Expand Up @@ -80,14 +89,12 @@ func navigate(server string) tui.SelectedFunc {
func renderPlain(w io.Writer, data tui.TableData) error {
for _, items := range data {
n := len(items)

for j, v := range items {
_, _ = fmt.Fprintf(w, "%s", v)
if j != n-1 {
_, _ = fmt.Fprintf(w, "\t")
}
}

_, _ = fmt.Fprintln(w)
}

Expand Down Expand Up @@ -151,3 +158,11 @@ func PagerOut(out string) error {
cmd.Stdout = os.Stdout
return cmd.Run()
}

// MDRenderer constructs markdown renderer.
func MDRenderer() (*glamour.TermRenderer, error) {
return glamour.NewTermRenderer(
glamour.WithAutoStyle(),
glamour.WithWordWrap(wordWrap),
)
}
14 changes: 6 additions & 8 deletions internal/view/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
"github.com/ankitpokhrel/jira-cli/pkg/tui"
)

const wordWrap = 120

// Issue is a list view for issues.
type Issue struct {
Data *jira.Issue
Expand All @@ -28,10 +26,7 @@ func (i Issue) Render() error {
}

data := i.data()
r, err := glamour.NewTermRenderer(
glamour.WithAutoStyle(),
glamour.WithWordWrap(wordWrap),
)
r, err := MDRenderer()
if err != nil {
return err
}
Expand All @@ -43,6 +38,10 @@ func (i Issue) Render() error {
}

func (i Issue) data() tui.TextData {
return tui.TextData(i.String())
}

func (i Issue) String() string {
as := i.Data.Fields.Assignee.Name
if as == "" {
as = "Unassigned"
Expand All @@ -64,15 +63,14 @@ func (i Issue) data() tui.TextData {
tr := adf.NewTranslator(i.Data.Fields.Description.(*adf.ADF), &adf.MarkdownTranslator{})
desc = tr.Translate()
}
dt := fmt.Sprintf(
return fmt.Sprintf(
"%s %s %s %s ⌛ %s 👷 %s\n# %s\n⏱️ %s 🔎 %s 🚀 %s 🏷️ %s\n\n-----------\n%s",
iti, it, sti, st, formatDateTimeHuman(i.Data.Fields.Updated, jira.RFC3339), as,
i.Data.Fields.Summary,
formatDateTimeHuman(i.Data.Fields.Created, jira.RFC3339), i.Data.Fields.Reporter.Name,
i.Data.Fields.Priority.Name, lbl,
desc,
)
return tui.TextData(dt)
}

// renderPlain renders the issue in plain view.
Expand Down
25 changes: 23 additions & 2 deletions internal/view/issues.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"strings"
"text/tabwriter"

"github.com/ankitpokhrel/jira-cli/api"
"github.com/ankitpokhrel/jira-cli/internal/cmdutil"
"github.com/ankitpokhrel/jira-cli/pkg/jira"
"github.com/ankitpokhrel/jira-cli/pkg/tui"
)
Expand Down Expand Up @@ -40,16 +42,35 @@ func (l IssueList) Render() error {
return l.renderPlain(w)
}

data := l.data()
renderer, err := MDRenderer()
if err != nil {
return err
}

data := l.data()
view := tui.NewTable(
tui.WithColPadding(colPadding),
tui.WithMaxColWidth(maxColWidth),
tui.WithTableFooterText(fmt.Sprintf("Showing %d of %d results for project \"%s\"", len(data)-1, l.Total, l.Project)),
tui.WithSelectedFunc(navigate(l.Server)),
tui.WithViewModeFunc(func(r, c int, _ interface{}) error {
issue := func() *jira.Issue {
s := cmdutil.Info("Fetching issue details...")
defer s.Stop()

issue, _ := api.Client(jira.Config{Debug: true}).GetIssue(data[r][1])

return issue
}()
out, err := renderer.Render(Issue{Data: issue}.String())
if err != nil {
return err
}
return PagerOut(out)
}),
)

return view.Render(data)
return view.Paint(data)
}

// renderPlain renders the issue in plain view.
Expand Down
47 changes: 30 additions & 17 deletions internal/view/sprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"text/tabwriter"
"time"

"github.com/ankitpokhrel/jira-cli/api"
"github.com/ankitpokhrel/jira-cli/internal/cmdutil"
"github.com/ankitpokhrel/jira-cli/pkg/jira"
"github.com/ankitpokhrel/jira-cli/pkg/tui"
)
Expand All @@ -23,14 +25,16 @@ type SprintList struct {
Data []*jira.Sprint
Issues SprintIssueFunc
Display DisplayFormat

issueCache map[string]tui.TableData
}

// Render renders the sprint explorer view.
func (sl SprintList) Render() error {
data := sl.data()
renderer, err := MDRenderer()
if err != nil {
return err
}

data := sl.data()
view := tui.NewPreview(
tui.WithPreviewFooterText(
fmt.Sprintf(
Expand All @@ -39,10 +43,28 @@ func (sl SprintList) Render() error {
),
),
tui.WithInitialText(helpText),
tui.WithContentTableOpts(tui.WithSelectedFunc(navigate(sl.Server))),
tui.WithContentTableOpts(
tui.WithSelectedFunc(navigate(sl.Server)),
tui.WithViewModeFunc(func(r, c int, d interface{}) error {
issue := func() *jira.Issue {
s := cmdutil.Info("Fetching issue details...")
defer s.Stop()

dt := d.(tui.TableData)
issue, _ := api.Client(jira.Config{Debug: true}).GetIssue(dt[r][1])

return issue
}()
out, err := renderer.Render(Issue{Data: issue}.String())
if err != nil {
return err
}
return PagerOut(out)
}),
),
)

return view.Render(data)
return view.Paint(data)
}

// RenderInTable renders the list in table view.
Expand All @@ -65,7 +87,7 @@ func (sl SprintList) RenderInTable() error {
),
)

return view.Render(data)
return view.Paint(data)
}

// renderPlain renders the issue in plain view.
Expand Down Expand Up @@ -97,17 +119,8 @@ func (sl SprintList) data() []tui.PreviewData {
formatDateTimeHuman(s.EndDate, time.RFC3339),
),
Contents: func(key string) interface{} {
if sl.issueCache == nil {
sl.issueCache = make(map[string]tui.TableData)
}

if _, ok := sl.issueCache[key]; !ok {
issues := sl.Issues(bid, sid)

sl.issueCache[key] = sl.tabularize(issues)
}

return sl.issueCache[key]
issues := sl.Issues(bid, sid)
return sl.tabularize(issues)
},
})
}
Expand Down
33 changes: 0 additions & 33 deletions pkg/tui/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ package tui
import (
"bufio"
"strings"

"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)

func pad(in string, n uint) string {
Expand Down Expand Up @@ -41,33 +38,3 @@ func splitText(s string) []string {

return lines
}

func renderTableHeader(t *Table, data []string) {
style := tcell.StyleDefault.Bold(true).Background(tcell.ColorDarkCyan)

for c := 0; c < len(data); c++ {
text := " " + data[c]

cell := tview.NewTableCell(text).
SetStyle(style).
SetSelectable(false).
SetMaxWidth(int(t.maxColWidth)).
SetTextColor(tcell.ColorSnow)

t.view.SetCell(0, c, cell)
}
}

func renderTableCell(t *Table, data [][]string) {
rows, cols := len(data), len(data[0])

for r := 1; r < rows; r++ {
for c := 0; c < cols; c++ {
cell := tview.NewTableCell(pad(data[r][c], t.colPad)).
SetMaxWidth(int(t.maxColWidth)).
SetTextColor(tcell.ColorDefault)

t.view.SetCell(r, c, cell)
}
}
}
Loading

0 comments on commit 159f0d9

Please sign in to comment.