Skip to content

Commit

Permalink
feat: allow setting of fixed columns in the list of issues
Browse files Browse the repository at this point in the history
  • Loading branch information
martinpovolny committed Dec 3, 2022
1 parent 84206aa commit da97fc4
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 23 deletions.
12 changes: 9 additions & 3 deletions internal/cmd/issue/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ func loadList(cmd *cobra.Command) {
noTruncate, err := cmd.Flags().GetBool("no-truncate")
cmdutil.ExitIfError(err)

fixedColumns, err := cmd.Flags().GetUint("fixed-columns")
cmdutil.ExitIfError(err)

columns, err := cmd.Flags().GetString("columns")
cmdutil.ExitIfError(err)

Expand All @@ -128,16 +131,18 @@ func loadList(cmd *cobra.Command) {
loadList(cmd)
},
Display: view.DisplayFormat{
Plain: plain,
NoHeaders: noHeaders,
NoTruncate: noTruncate,
Plain: plain,
NoHeaders: noHeaders,
NoTruncate: noTruncate,
FixedColumns: fixedColumns,
Columns: func() []string {
if columns != "" {
return strings.Split(columns, ",")
}
return []string{}
}(),
TableStyle: cmdutil.GetTUIStyleConfig(),
CustomKeys: viper.GetStringMap("custom_keys.issues"),
},
}

Expand Down Expand Up @@ -178,6 +183,7 @@ func SetFlags(cmd *cobra.Command) {
cmd.Flags().Bool("plain", false, "Display output in plain mode")
cmd.Flags().Bool("no-headers", false, "Don't display table headers in plain mode. Works only with --plain")
cmd.Flags().Bool("no-truncate", false, "Show all available columns in plain mode. Works only with --plain")
cmd.Flags().Uint("fixed-columns", 1, "Number of fixed columns in the interactive mode.")

if cmd.HasParent() && cmd.Parent().Name() != "sprint" {
cmd.Flags().String("columns", "", "Comma separated list of columns to display in the plain mode.\n"+
Expand Down
19 changes: 19 additions & 0 deletions internal/view/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"io"
"os"
"os/exec"
"strings"
"text/tabwriter"
"time"
Expand Down Expand Up @@ -115,6 +116,24 @@ func jiraURLFromTuiData(server string, r int, d interface{}) string {
return fmt.Sprintf("%s/browse/%s", server, issueKeyFromTuiData(r, d))
}

func runInSh(command string) {
cmd := exec.Command("sh", "-c", command)
_ = cmd.Run()
}

func customKeyFunc(row, column int, data interface{}, command string) {
i := issueKeyFromTuiData(row, data)
expandedCommand := strings.ReplaceAll(command, "%KEY%", i)
if strings.HasPrefix(expandedCommand, "&") {
go func() {
expandedCommand = strings.TrimPrefix(expandedCommand, "&")
runInSh(expandedCommand)
}()
} else {
runInSh(expandedCommand)
}
}

func navigate(server string) tui.SelectedFunc {
return func(r, c int, d interface{}) {
_ = browser.Browse(jiraURLFromTuiData(server, r, d))
Expand Down
14 changes: 9 additions & 5 deletions internal/view/issues.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import (

// DisplayFormat is a issue display type.
type DisplayFormat struct {
Plain bool
NoHeaders bool
NoTruncate bool
Columns []string
TableStyle tui.TableStyle
Plain bool
NoHeaders bool
NoTruncate bool
Columns []string
FixedColumns uint
TableStyle tui.TableStyle
CustomKeys map[string]interface{}
}

// IssueList is a list view for issues.
Expand Down Expand Up @@ -51,6 +53,7 @@ func (l *IssueList) Render() error {
}

view := tui.NewTable(
tui.WithCustomKeyFunc(customKeyFunc, l.Display.CustomKeys),
tui.WithTableStyle(l.Display.TableStyle),
tui.WithTableFooterText(l.FooterText),
tui.WithSelectedFunc(navigate(l.Server)),
Expand All @@ -73,6 +76,7 @@ func (l *IssueList) Render() error {
tui.WithCopyFunc(copyURL(l.Server)),
tui.WithCopyKeyFunc(copyKey()),
tui.WithRefreshFunc(l.Refresh),
tui.WithFixedColumns(l.Display.FixedColumns),
)

return view.Paint(data)
Expand Down
60 changes: 45 additions & 15 deletions pkg/tui/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ type CopyFunc func(row, column int, data interface{})
// CopyKeyFunc is fired when a user press 'CTRL+K' character in the table cell.
type CopyKeyFunc func(row, column int, data interface{})

// CustomKeyFunc is fired when one of custom keys is pressed in the table cell.
type CustomKeyFunc func(row, column int, data interface{}, command string)

// TableData is the data to be displayed in a table.
type TableData [][]string

Expand All @@ -42,20 +45,23 @@ type TableStyle struct {

// Table is a table layout.
type Table struct {
screen *Screen
painter *tview.Pages
view *tview.Table
footer *tview.TextView
style TableStyle
data TableData
colPad uint
maxColWidth uint
footerText string
selectedFunc SelectedFunc
viewModeFunc ViewModeFunc
refreshFunc RefreshFunc
copyFunc CopyFunc
copyKeyFunc CopyKeyFunc
screen *Screen
painter *tview.Pages
view *tview.Table
footer *tview.TextView
style TableStyle
data TableData
colPad uint
colFixed uint
maxColWidth uint
footerText string
selectedFunc SelectedFunc
viewModeFunc ViewModeFunc
customKeys map[string]interface{}
customKeyFunc CustomKeyFunc
refreshFunc RefreshFunc
copyFunc CopyFunc
copyKeyFunc CopyKeyFunc
}

// TableOption is a functional option to wrap table properties.
Expand Down Expand Up @@ -120,6 +126,14 @@ func WithViewModeFunc(fn ViewModeFunc) TableOption {
}
}

// WithCustomKeyFunc sets a func that is triggered when one of custom keys is pressed.
func WithCustomKeyFunc(fn CustomKeyFunc, keys map[string]interface{}) TableOption {
return func(t *Table) {
t.customKeyFunc = fn
t.customKeys = keys
}
}

// WithRefreshFunc sets a func that is triggered when a user press 'CTRL+R' or 'F5'.
func WithRefreshFunc(fn RefreshFunc) TableOption {
return func(t *Table) {
Expand All @@ -141,6 +155,13 @@ func WithCopyKeyFunc(fn CopyKeyFunc) TableOption {
}
}

// WithFixedColumns sets the number of columns that are locked (do not scroll right).
func WithFixedColumns(cols uint) TableOption {
return func(t *Table) {
t.colFixed = cols
}
}

// Paint paints the table layout. First row is treated as a table header.
func (t *Table) Paint(data TableData) error {
if len(data) == 0 {
Expand Down Expand Up @@ -224,12 +245,21 @@ func (t *Table) initTable() {
// Refresh the screen.
t.screen.Draw()
}()
default:
if t.customKeyFunc != nil && t.customKeys != nil {
for k, command := range t.customKeys {
if string(ev.Rune()) == k {
r, c := t.view.GetSelection()
t.customKeyFunc(r, c, t.data, command.(string))
}
}
}
}
}
return ev
})

t.view.SetFixed(1, 1)
t.view.SetFixed(1, int(t.colFixed))
}

func renderTableHeader(t *Table, data []string) {
Expand Down

0 comments on commit da97fc4

Please sign in to comment.