fix: improve display for strings and numbers in v1 shell tables (#420)

* fix: improve alignment for strings and numbers

* add scientific toggle command for table format

* enter altscreen when in table format interactive mode

* chore: run go mod tidy
This commit is contained in:
Andrew Lee 2022-07-01 10:22:13 -06:00 committed by GitHub
parent da2899d71d
commit b9ffcb4b5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 15 deletions

View File

@ -118,8 +118,9 @@ func newSugNodeFn(subsugs ...string) subsuggestFnType {
func (c *Client) completer(d prompt.Document) []prompt.Suggest {
// the commented-out lines are unsupported in 2.x
suggestions := map[string]SuggestNode{
"use": {Description: "Set current database", subsuggestFn: c.suggestUse},
"pretty": {Description: "Toggle pretty print for the json format"},
"use": {Description: "Set current database", subsuggestFn: c.suggestUse},
"pretty": {Description: "Toggle pretty print for the json format"},
"scientific": {Description: "Toggle scientific number format for the table format"},
"precision": {Description: "Specify the format of the timestamp",
subsuggestFn: newSugNodeFn(
"rfc3339",

View File

@ -50,40 +50,58 @@ func NewModel(
curRes int,
resMax int,
curSer int,
serMax int) Model {
serMax int,
scientific bool) Model {
cols := make([]table.Column, len(*res.Columns)+1)
colWidths := make([]int, len(*res.Columns)+1)
alignment := make([]lipgloss.Position, len(*res.Columns)+1)
rows := make([]table.Row, len(*res.Values))
colNames := *res.Columns
for rowI, row := range *res.Values {
rd := table.RowData{}
rd["index"] = fmt.Sprintf("%d", rowI+1)
alignment[0] = lipgloss.Right
colWidths[0] = len("index") + colPadding
for colI, rowVal := range row {
var item string
var colLen int
switch val := rowVal.(type) {
case int:
item = fmt.Sprintf("%d", val)
colLen = len(item)
alignment[colI+1] = lipgloss.Right
case string:
item = fmt.Sprintf("%q", val)
item = color.YellowString(val)
colLen = len(val)
alignment[colI+1] = lipgloss.Left
case float32, float64:
if scientific {
item = fmt.Sprintf("%.10e", val)
} else {
item = fmt.Sprintf("%.10f", val)
}
colLen = len(item)
alignment[colI+1] = lipgloss.Right
default:
item = fmt.Sprintf("%v", val)
colLen = len(item)
alignment[colI+1] = lipgloss.Right
}
rd[colNames[colI]] = item
if colWidths[colI+1] < len(item)+colPadding {
colWidths[colI+1] = len(item) + colPadding
if colWidths[colI+1] < colLen+colPadding {
colWidths[colI+1] = colLen + colPadding
}
}
rows[rowI] = table.NewRow(rd).
WithStyle(lipgloss.NewStyle().Align(lipgloss.Center))
WithStyle(lipgloss.NewStyle())
}
cols[0] = table.NewColumn("index", "index", colWidths[0])
indexStyle := lipgloss.NewStyle()
if isatty.IsTerminal(os.Stdout.Fd()) {
indexStyle = indexStyle.
Faint(true).
Align(lipgloss.Center)
Align(lipgloss.Right)
}
cols[0] = cols[0].WithStyle(indexStyle)
for colI, colTitle := range colNames {
@ -91,7 +109,7 @@ func NewModel(
colWidths[colI+1] = len(colTitle) + colPadding
}
cols[colI+1] = table.NewColumn(colTitle, color.HiCyanString(colTitle), colWidths[colI+1]).
WithStyle(lipgloss.NewStyle().Align(lipgloss.Center))
WithStyle(lipgloss.NewStyle().Align(alignment[colI+1]))
}
colNames = append([]string{"index"}, colNames...)
screenPadding := 10
@ -122,6 +140,7 @@ func NewModel(
keybind.FilterClear.Unbind()
m.simpleTable = table.New(m.allCols).
HeaderStyle(lipgloss.NewStyle().Align(lipgloss.Center)).
WithRows(m.rows).
WithPageSize(15).
WithMaxTotalWidth(500).
@ -143,7 +162,11 @@ func NewModel(
func (m Model) Init() tea.Cmd {
color.Magenta("Interactive Table View (press q to exit mode, shift+up/down to navigate tables):")
builder := strings.Builder{}
fmt.Printf("Name: %s\n", color.GreenString(m.name))
if m.name != "" {
fmt.Printf("Name: %s\n", color.GreenString(m.name))
} else {
fmt.Println("") // keep a consistent height, so print an empty line
}
if len(m.tags) > 0 {
fmt.Print("Tags: ")
for key, val := range m.tags {
@ -204,9 +227,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} else {
m.simpleTable = m.simpleTable.PageDown()
}
case "<":
case "[":
m.simpleTable = m.simpleTable.PageFirst()
case ">":
case "]":
m.simpleTable = m.simpleTable.PageLast()
}
case tea.WindowSizeMsg:

View File

@ -23,6 +23,7 @@ import (
"github.com/influxdata/go-prompt"
"github.com/influxdata/influx-cli/v2/api"
"github.com/influxdata/influx-cli/v2/clients"
"github.com/muesli/termenv"
)
type Client struct {
@ -42,6 +43,7 @@ type PersistentQueryParams struct {
Precision string
Format FormatType
Pretty bool
Scientific bool
// Autocompletion Storage
historyFilePath string
historyLimit int
@ -200,6 +202,8 @@ func (c *Client) executor(cmd string) {
c.settings()
case "pretty":
c.togglePretty()
case "scientific":
c.toggleScientific()
case "use":
c.use(cmdArgs)
case "insert":
@ -367,9 +371,10 @@ func (c *Client) runAndShowQuery(query string) {
func (c *Client) help() {
fmt.Println(`Usage:
pretty toggles pretty print for the json format
use <db_name> sets current database
format <format> specifies the format of the server responses: json, csv, column, table
pretty toggles pretty print for the json format
scientific toggles scientific numeric format for table format
precision <format> specifies the format of the timestamp: rfc3339, h, m, s, ms, u or ns
history displays command history
settings outputs the current settings for the shell
@ -403,6 +408,7 @@ func (c *Client) settings() {
fmt.Fprintf(w, "Database\t%s\n", c.Database)
fmt.Fprintf(w, "RetentionPolicy\t%s\n", c.RetentionPolicy)
fmt.Fprintf(w, "Pretty\t%v\n", c.Pretty)
fmt.Fprintf(w, "Scientific\t%v\n", c.Scientific)
fmt.Fprintf(w, "Format\t%s\n", c.Format)
fmt.Fprintf(w, "Precision\t%s\n", c.Precision)
fmt.Fprintln(w)
@ -640,6 +646,8 @@ outer:
}
allSeries := res.GetSeries()
for seriesIdx < len(allSeries) {
termenv.AltScreen()
defer termenv.ExitAltScreen()
series := allSeries[seriesIdx]
p := tea.NewProgram(NewModel(series,
jumpToLastPage,
@ -648,7 +656,9 @@ outer:
resIdx+1,
len(allResults),
seriesIdx+1,
len(allSeries)))
len(allSeries),
c.Scientific),
)
model, err := p.StartReturningModel()
jumpToLastPage = false
if err != nil {
@ -688,6 +698,11 @@ func (c *Client) togglePretty() {
color.HiBlack("Pretty: %v", c.Pretty)
}
func (c *Client) toggleScientific() {
c.Scientific = !c.Scientific
color.HiBlack("Scientific: %v", c.Scientific)
}
func (c *Client) use(args []string) {
if len(args) != 2 {
color.Red("wrong number of args for \"use <database>\"")

2
go.mod
View File

@ -18,6 +18,7 @@ require (
github.com/influxdata/go-prompt v0.2.7
github.com/influxdata/influxdb/v2 v2.3.0
github.com/mattn/go-isatty v0.0.14
github.com/muesli/termenv v0.12.0
github.com/olekukonko/tablewriter v0.0.5
github.com/stretchr/testify v1.7.0
github.com/urfave/cli v1.22.5
@ -44,7 +45,6 @@ require (
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
github.com/muesli/cancelreader v0.2.0 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.12.0 // indirect
github.com/pkg/term v1.2.0-beta.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect