diff --git a/internal/ui/dropdown.go b/internal/ui/dropdown.go index 5e3b8c4..58fff3c 100644 --- a/internal/ui/dropdown.go +++ b/internal/ui/dropdown.go @@ -1,21 +1,25 @@ package ui import ( + "fmt" + "github.com/derailed/tview" "github.com/gdamore/tcell/v2" ) +const DropDownIndicatiorColor string = "green" + type DropDown struct { *tview.DropDown - label string - options []string + label string + options []string } func NewDropDown(label string, options []string) *DropDown { d := DropDown{ - DropDown: tview.NewDropDown(), - label: label, - options: options, + DropDown: tview.NewDropDown(), + label: label, + options: options, } d.build() return &d @@ -33,5 +37,7 @@ func (d *DropDown) build() { d.SetOptions(d.options, func(text string, index int) {}) d.SetCurrentOption(0) d.SetBorderPadding(0, 0, 0, 0) - //profileDropdown.SetBorder(true) + d.SetTextOptions(" ", " ", fmt.Sprintf("[%s::bd]▽[-:-:-] ", DropDownIndicatiorColor), "", "") + d.SetFieldBackgroundColor(tcell.ColorBlack.TrueColor()) + d.SetFieldTextColor(tcell.ColorAntiqueWhite.TrueColor()) } diff --git a/internal/ui/info.go b/internal/ui/info.go index f577cf1..79c69fe 100644 --- a/internal/ui/info.go +++ b/internal/ui/info.go @@ -1,21 +1,23 @@ package ui import ( + "strings" + "github.com/derailed/tview" "github.com/gdamore/tcell/v2" ) +const DropdownPadSpaces int = 3 + type Info struct { *tview.Flex - dropdowns []DropDown - items map[string]tview.Primitive + items map[string]tview.Primitive } func NewInfo(items map[string]tview.Primitive) *Info { i := Info{ - Flex: tview.NewFlex(), - items: items, - dropdowns: []DropDown{}, + Flex: tview.NewFlex(), + items: items, } i.padDropDownLabels() i.build() @@ -23,10 +25,25 @@ func NewInfo(items map[string]tview.Primitive) *Info { } func (i *Info) padDropDownLabels() { + maxLabelLen := 0 + maxOptionLen := 0 + for _, p := range i.items { + d, ok := p.(*DropDown) + if ok { + if len(d.GetLabel()) > maxLabelLen { + maxLabelLen = len(d.GetLabel()) + } + if d.GetFieldWidth() > maxOptionLen { + maxOptionLen = d.GetFieldWidth() + } + } + } + for _, p := range i.items { - d, ok := p.(DropDown) + d, ok := p.(*DropDown) if ok { - i.dropdowns = append(i.dropdowns, d) + d.SetFieldWidth(maxOptionLen + DropdownPadSpaces) + d.SetLabel(d.GetLabel() + strings.Repeat(" ", (maxLabelLen-len(d.GetLabel()))+1)) } } } @@ -35,11 +52,8 @@ func (i *Info) build() { i.Clear() i.SetDirection(tview.FlexRow) i.SetBorderColor(tcell.ColorBlack.TrueColor()) - i.SetBorderPadding(1, 1, 1, 1) + i.SetBorderPadding(0, 4, 1, 1) for _, p := range i.items { i.AddItem(p, 0, 1, false) } - // for k, v := range i.data { - // fmt.Fprintf(i, "[%s::b]%s: [%s::b]%s\n", "orange", k, "#ffffff", v) - // } } diff --git a/internal/ui/table.go b/internal/ui/table.go index 9e3c319..00c5e68 100644 --- a/internal/ui/table.go +++ b/internal/ui/table.go @@ -40,8 +40,8 @@ func NewTable(res string) *Table { func (t *Table) Init(ctx context.Context) { t.SetFixed(1, 0) t.SetBorder(true) - t.SetBorderColor(tcell.ColorDeepSkyBlue) - //t.SetBorderFocusColor(tcell.ColorSpringGreen) + t.SetBorderColor(tcell.ColorLightSkyBlue) + t.SetBorderFocusColor(tcell.ColorDeepSkyBlue) t.SetBorderPadding(0, 0, 1, 1) t.SetSelectable(true, false) t.SetSelectionChangedFunc(t.selectionChanged) @@ -167,7 +167,7 @@ func (t *Table) Refresh() { // UpdateTitle refreshes the table title. func (t *Table) UpdateTitle() { - title := strings.Join([]string{" ", t.Resource(), " "}, "") + title := strings.Join([]string{" ", strings.ToUpper(t.Resource()), " "}, "") t.SetTitle(fmt.Sprintf("[aqua::b]%s", title)) } diff --git a/internal/view/app.go b/internal/view/app.go index c91e3b2..40178ac 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -59,11 +59,11 @@ func (a *App) Init(profiles, regions []string, ctx context.Context) error { ctx = context.WithValue(ctx, internal.KeyApp, a) a.SetContext(ctx) - p := ui.NewDropDown("Profile", profiles) + p := ui.NewDropDown("Profile:", profiles) p.SetSelectedFunc(a.profileChanged) a.Views()["profile"] = p - r := ui.NewDropDown("Region", regions) + r := ui.NewDropDown("Region:", regions) r.SetSelectedFunc(a.regionChanged) a.Views()["region"] = r @@ -1000,6 +1000,7 @@ func (a *App) bindKeys() { a.AddActions(ui.KeyActions{ tcell.KeyCtrlE: ui.NewKeyAction("ToggleHeader", a.toggleHeaderCmd, false), tcell.KeyEnter: ui.NewKeyAction("Goto", a.gotoCmd, false), + tcell.KeyTAB: ui.NewKeyAction("switch", NewTab(a).tabAction, false), }) } diff --git a/internal/view/command.go b/internal/view/command.go index 312b8f4..c50a0b6 100644 --- a/internal/view/command.go +++ b/internal/view/command.go @@ -119,10 +119,8 @@ func (c *Command) viewMetaFor(cmd string) (string, *MetaViewer, error) { func (c *Command) componentFor(res, path string, v *MetaViewer) ResourceViewer { var view ResourceViewer if v.viewerFn != nil { - log.Info().Msg(fmt.Sprintf("If res: %v, Path: %v", res, path)) view = v.viewerFn(res) } else { - log.Info().Msg(fmt.Sprintf("else: res: %v, Path: %v", res, path)) view = NewBrowser(res) } @@ -150,7 +148,6 @@ func (c *Command) exec(cmd, gvr string, comp model.Component, clearStack bool) ( // err = fmt.Errorf("Invalid command %q", cmd) // } }() - log.Info().Msg(fmt.Sprintf("cmd: %v, res: %v, comp: %T", cmd, gvr, comp)) if comp == nil { return fmt.Errorf("No component found for %s", gvr) diff --git a/internal/view/ec2.go b/internal/view/ec2.go index a9265a3..21a00ab 100644 --- a/internal/view/ec2.go +++ b/internal/view/ec2.go @@ -20,21 +20,19 @@ func NewEC2(resource string) ResourceViewer { func (e *EC2) bindKeys(aa ui.KeyActions) { aa.Add(ui.KeyActions{ - ui.KeyShiftI: ui.NewKeyAction("Sort Instance-Id", e.GetTable().SortColCmd("Instance-Id", true), true), - ui.KeyShiftS: ui.NewKeyAction("Sort Instance-State", e.GetTable().SortColCmd("Instance-State", true), true), - ui.KeyShiftT: ui.NewKeyAction("Sort Instance-Type", e.GetTable().SortColCmd("Instance-Type", true), true), - ui.KeyShiftL: ui.NewKeyAction("Sort Launch-Time", e.GetTable().SortColCmd("Launch-Time", true), true), - ui.KeyShiftM: ui.NewKeyAction("Sort Monitoring-State", e.GetTable().SortColCmd("Monitoring-State", true), true), - ui.KeyShiftP: ui.NewKeyAction("Sort Public-DNS", e.GetTable().SortColCmd("Public-DNS", true), true), - tcell.KeyEscape: ui.NewKeyAction("Back", e.App().PrevCmd, true), - tcell.KeyEnter: ui.NewKeyAction("View", e.enterCmd, true), + ui.KeyShiftI: ui.NewKeyAction("Sort Instance-Id", e.GetTable().SortColCmd("Instance-Id", true), false), + ui.KeyShiftS: ui.NewKeyAction("Sort Instance-State", e.GetTable().SortColCmd("Instance-State", true), false), + ui.KeyShiftT: ui.NewKeyAction("Sort Instance-Type", e.GetTable().SortColCmd("Instance-Type", true), false), + ui.KeyShiftL: ui.NewKeyAction("Sort Launch-Time", e.GetTable().SortColCmd("Launch-Time", true), false), + ui.KeyShiftM: ui.NewKeyAction("Sort Monitoring-State", e.GetTable().SortColCmd("Monitoring-State", true), false), + ui.KeyShiftP: ui.NewKeyAction("Sort Public-DNS", e.GetTable().SortColCmd("Public-DNS", true), false), + tcell.KeyEscape: ui.NewKeyAction("Back", e.App().PrevCmd, false), + tcell.KeyEnter: ui.NewKeyAction("View", e.enterCmd, false), }) } func (e *EC2) enterCmd(evt *tcell.EventKey) *tcell.EventKey { instanceId := e.GetTable().GetSelectedItem() - e.App().Flash().Info("Instance-Id: " + instanceId) - f := describeResource if e.GetTable().enterFn != nil { f = e.GetTable().enterFn diff --git a/internal/view/tab.go b/internal/view/tab.go new file mode 100644 index 0000000..a66c6b8 --- /dev/null +++ b/internal/view/tab.go @@ -0,0 +1,55 @@ +package view + +import ( + "github.com/derailed/tview" + "github.com/gdamore/tcell/v2" +) + +type Tab struct { + *App + items []tview.Primitive +} + +func NewTab(app *App) *Tab { + t := Tab{App: app, items: []tview.Primitive{}} + t.Add() + return &t +} + +func (t *Tab) Add() { + t.items = append(t.items, t.App.profile()) + t.items = append(t.items, t.App.region()) +} + +func (t *Tab) tabAction(event *tcell.EventKey) *tcell.EventKey { + if t.InCmdMode() { + return event + } + + focusIdx := t.currentFocusIdx() + + if event.Key() == tcell.KeyTAB { + if focusIdx + 1 == len(t.items) { + t.App.Application.SetFocus(t.Content.Pages.Current()) + return event + } + focusIdx = focusIdx + 1 + } + + if focusIdx < 0 { + focusIdx = 0 + } + t.App.Application.SetFocus(t.items[focusIdx]) + return event +} + +func (t *Tab) currentFocusIdx() int { + focusIdx := -1 + for i, p := range t.items { + if p.HasFocus() { + focusIdx = i + break + } + } + return focusIdx +} diff --git a/internal/view/table.go b/internal/view/table.go index 3638939..028f9f6 100644 --- a/internal/view/table.go +++ b/internal/view/table.go @@ -85,7 +85,7 @@ func (t *Table) keyboard(evt *tcell.EventKey) *tcell.EventKey { func (t *Table) bindKeys() { t.Actions().Add(ui.KeyActions{ - tcell.KeyCtrlW: ui.NewKeyAction("Toggle Wide", t.toggleWideCmd, true), + tcell.KeyCtrlW: ui.NewKeyAction("Toggle Wide", t.toggleWideCmd, false), ui.KeyHelp: ui.NewKeyAction("Help", t.App().helpCmd, true), ui.KeyZ: ui.NewKeyAction("CSV", t.importAsCSV, true), })