refact app view
parent
8515f70fbf
commit
1ffb11dbd6
|
|
@ -50,7 +50,6 @@ type (
|
|||
appView struct {
|
||||
*shellView
|
||||
|
||||
cmdBuff *cmdBuff
|
||||
command *command
|
||||
cancel context.CancelFunc
|
||||
informer *watch.Informer
|
||||
|
|
@ -63,19 +62,13 @@ type (
|
|||
func NewApp(cfg *config.Config) *appView {
|
||||
v := appView{
|
||||
shellView: newShellView(),
|
||||
cmdBuff: newCmdBuff(':'),
|
||||
forwarders: make(map[string]forwarder),
|
||||
}
|
||||
v.config = cfg
|
||||
v.initBench(cfg.K9s.CurrentCluster)
|
||||
v.refreshStyles()
|
||||
v.command = newCommand(&v)
|
||||
|
||||
v.views["menu"] = newMenuView(v.styles)
|
||||
v.views["logo"] = newLogoView(v.styles)
|
||||
v.views["cmd"] = newCmdView(v.styles, '🐶')
|
||||
v.views["flash"] = newFlashView(&v, "Initializing...")
|
||||
v.views["crumbs"] = newCrumbsView(v.styles)
|
||||
v.views["clusterInfo"] = newClusterInfoView(&v, k8s.NewMetricsServer(cfg.GetConnection()))
|
||||
|
||||
v.actions = keyActions{
|
||||
|
|
@ -180,10 +173,6 @@ func (a *appView) stopForwarders() {
|
|||
}
|
||||
}
|
||||
|
||||
func (a *appView) conn() k8s.Connection {
|
||||
return a.config.GetConnection()
|
||||
}
|
||||
|
||||
// Run starts the application loop
|
||||
func (a *appView) Run() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
|
@ -210,14 +199,8 @@ func (a *appView) Run() {
|
|||
}
|
||||
}
|
||||
|
||||
func (a *appView) statusReset() {
|
||||
a.logo().reset()
|
||||
a.Draw()
|
||||
}
|
||||
|
||||
func (a *appView) status(l flashLevel, msg string) {
|
||||
a.flash().info(msg)
|
||||
|
||||
switch l {
|
||||
case flashErr:
|
||||
a.logo().err(msg)
|
||||
|
|
@ -231,47 +214,6 @@ func (a *appView) status(l flashLevel, msg string) {
|
|||
a.Draw()
|
||||
}
|
||||
|
||||
func (a *appView) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
||||
key := evt.Key()
|
||||
if key == tcell.KeyRune {
|
||||
if a.cmdBuff.isActive() && evt.Modifiers() == tcell.ModNone {
|
||||
a.cmdBuff.add(evt.Rune())
|
||||
return nil
|
||||
}
|
||||
key = tcell.Key(evt.Rune())
|
||||
if evt.Modifiers() == tcell.ModAlt {
|
||||
key = tcell.Key(int16(evt.Rune()) * int16(evt.Modifiers()))
|
||||
}
|
||||
}
|
||||
|
||||
if a, ok := a.actions[key]; ok {
|
||||
log.Debug().Msgf(">> AppView handled key: %s", tcell.KeyNames[key])
|
||||
return a.action(evt)
|
||||
}
|
||||
|
||||
return evt
|
||||
}
|
||||
|
||||
func (a *appView) redrawCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
a.Draw()
|
||||
return evt
|
||||
}
|
||||
|
||||
func (a *appView) eraseCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
if a.cmdBuff.isActive() {
|
||||
a.cmdBuff.del()
|
||||
return nil
|
||||
}
|
||||
return evt
|
||||
}
|
||||
|
||||
func (a *appView) escapeCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
if a.cmdBuff.isActive() {
|
||||
a.cmdBuff.reset()
|
||||
}
|
||||
return evt
|
||||
}
|
||||
|
||||
func (a *appView) prevCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
if top, ok := a.command.previousCmd(); ok {
|
||||
log.Debug().Msgf("Previous command %s", top)
|
||||
|
|
@ -298,6 +240,7 @@ func (a *appView) activateCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
a.flash().info("Command mode activated.")
|
||||
a.cmdBuff.setActive(true)
|
||||
a.cmdBuff.clear()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -318,10 +261,6 @@ func (a *appView) helpCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (a *appView) currentView() igniter {
|
||||
return a.content.GetPrimitive("main").(igniter)
|
||||
}
|
||||
|
||||
func (a *appView) aliasCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
if a.inCmdMode() {
|
||||
return evt
|
||||
|
|
@ -360,29 +299,3 @@ func (a *appView) inject(i igniter) {
|
|||
func (a *appView) inCmdMode() bool {
|
||||
return a.cmd().inCmdMode()
|
||||
}
|
||||
|
||||
func (a *appView) setHints(h hints) {
|
||||
a.views["menu"].(*menuView).populateMenu(h)
|
||||
}
|
||||
|
||||
// View Accessors...
|
||||
|
||||
func (a *appView) crumbs() *crumbsView {
|
||||
return a.views["crumbs"].(*crumbsView)
|
||||
}
|
||||
|
||||
func (a *appView) logo() *logoView {
|
||||
return a.views["logo"].(*logoView)
|
||||
}
|
||||
|
||||
func (a *appView) clusterInfo() *clusterInfoView {
|
||||
return a.views["clusterInfo"].(*clusterInfoView)
|
||||
}
|
||||
|
||||
func (a *appView) flash() *flashView {
|
||||
return a.views["flash"].(*flashView)
|
||||
}
|
||||
|
||||
func (a *appView) cmd() *cmdView {
|
||||
return a.views["cmd"].(*cmdView)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ type resTable struct {
|
|||
currentNS string
|
||||
data resource.TableData
|
||||
actions keyActions
|
||||
colorerFn colorerFn
|
||||
}
|
||||
|
||||
func newResTable(app *appView, title string) *resTable {
|
||||
|
|
@ -45,6 +46,24 @@ func newResTable(app *appView, title string) *resTable {
|
|||
return &v
|
||||
}
|
||||
|
||||
func (v *resTable) buildRow(row int, data resource.TableData, sk string, pads maxyPad) {
|
||||
f := v.colorerFn
|
||||
if f == nil {
|
||||
f = defaultColorer
|
||||
}
|
||||
for col, field := range data.Rows[sk].Fields {
|
||||
header := data.Header[col]
|
||||
field, align := v.formatCell(data.NumCols[header], header, field+deltas(data.Rows[sk].Deltas[col], field), pads[col])
|
||||
c := tview.NewTableCell(field)
|
||||
{
|
||||
c.SetExpansion(1)
|
||||
c.SetAlign(align)
|
||||
c.SetTextColor(f(data.Namespace, data.Rows[sk]))
|
||||
}
|
||||
v.SetCell(row, col, c)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *resTable) formatCell(numerical bool, header, field string, padding int) (string, int) {
|
||||
if header == "AGE" {
|
||||
dur, err := time.ParseDuration(field)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package views
|
||||
|
||||
import (
|
||||
"github.com/derailed/k9s/internal/k8s"
|
||||
"github.com/derailed/tview"
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type (
|
||||
|
|
@ -20,15 +22,109 @@ type (
|
|||
pages *tview.Pages
|
||||
content *tview.Pages
|
||||
views map[string]tview.Primitive
|
||||
cmdBuff *cmdBuff
|
||||
}
|
||||
)
|
||||
|
||||
func newShellView() *shellView {
|
||||
return &shellView{
|
||||
s := shellView{
|
||||
Application: tview.NewApplication(),
|
||||
actions: make(keyActions),
|
||||
pages: tview.NewPages(),
|
||||
content: tview.NewPages(),
|
||||
views: make(map[string]tview.Primitive),
|
||||
cmdBuff: newCmdBuff(':'),
|
||||
}
|
||||
|
||||
s.refreshStyles()
|
||||
|
||||
s.views["menu"] = newMenuView(s.styles)
|
||||
s.views["logo"] = newLogoView(s.styles)
|
||||
s.views["cmd"] = newCmdView(s.styles, '🐶')
|
||||
s.views["crumbs"] = newCrumbsView(s.styles)
|
||||
|
||||
return &s
|
||||
}
|
||||
|
||||
func (s *shellView) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
||||
key := evt.Key()
|
||||
if key == tcell.KeyRune {
|
||||
if s.cmdBuff.isActive() && evt.Modifiers() == tcell.ModNone {
|
||||
s.cmdBuff.add(evt.Rune())
|
||||
return nil
|
||||
}
|
||||
key = tcell.Key(evt.Rune())
|
||||
if evt.Modifiers() == tcell.ModAlt {
|
||||
key = tcell.Key(int16(evt.Rune()) * int16(evt.Modifiers()))
|
||||
}
|
||||
}
|
||||
|
||||
if a, ok := s.actions[key]; ok {
|
||||
log.Debug().Msgf(">> AppView handled key: %s", tcell.KeyNames[key])
|
||||
return a.action(evt)
|
||||
}
|
||||
|
||||
return evt
|
||||
}
|
||||
|
||||
func (s *shellView) eraseCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
if s.cmdBuff.isActive() {
|
||||
s.cmdBuff.del()
|
||||
return nil
|
||||
}
|
||||
return evt
|
||||
}
|
||||
|
||||
func (s *shellView) escapeCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
if s.cmdBuff.isActive() {
|
||||
s.cmdBuff.reset()
|
||||
}
|
||||
return evt
|
||||
}
|
||||
|
||||
func (s *shellView) conn() k8s.Connection {
|
||||
return s.config.GetConnection()
|
||||
}
|
||||
|
||||
func (s *shellView) init() {
|
||||
}
|
||||
|
||||
func (s *shellView) redrawCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
s.Draw()
|
||||
return evt
|
||||
}
|
||||
|
||||
func (s *shellView) currentView() igniter {
|
||||
return s.content.GetPrimitive("main").(igniter)
|
||||
}
|
||||
|
||||
func (s *shellView) setHints(h hints) {
|
||||
s.views["menu"].(*menuView).populateMenu(h)
|
||||
}
|
||||
|
||||
func (s *shellView) statusReset() {
|
||||
s.logo().reset()
|
||||
s.Draw()
|
||||
}
|
||||
|
||||
// View Accessors...
|
||||
|
||||
func (s *shellView) crumbs() *crumbsView {
|
||||
return s.views["crumbs"].(*crumbsView)
|
||||
}
|
||||
|
||||
func (s *shellView) logo() *logoView {
|
||||
return s.views["logo"].(*logoView)
|
||||
}
|
||||
|
||||
func (s *appView) clusterInfo() *clusterInfoView {
|
||||
return s.views["clusterInfo"].(*clusterInfoView)
|
||||
}
|
||||
|
||||
func (s *appView) flash() *flashView {
|
||||
return s.views["flash"].(*flashView)
|
||||
}
|
||||
|
||||
func (s *appView) cmd() *cmdView {
|
||||
return s.views["cmd"].(*cmdView)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,10 @@ type tableView struct {
|
|||
*resTable
|
||||
|
||||
cmdBuff *cmdBuff
|
||||
colorerFn colorerFn
|
||||
sortCol sortColumn
|
||||
sortFn sortFn
|
||||
cleanseFn cleanseFn
|
||||
filterFn func(string)
|
||||
sortCol sortColumn
|
||||
}
|
||||
|
||||
func newTableView(app *appView, title string) *tableView {
|
||||
|
|
@ -249,23 +248,9 @@ func (v *tableView) sort(data resource.TableData, row int) {
|
|||
sortFn = v.sortFn
|
||||
}
|
||||
prim, sec := sortAllRows(v.sortCol, data.Rows, sortFn)
|
||||
fgColor := config.AsColor(v.app.styles.Table().FgColor)
|
||||
for _, pk := range prim {
|
||||
for _, sk := range sec[pk] {
|
||||
if v.colorerFn != nil {
|
||||
fgColor = v.colorerFn(data.Namespace, data.Rows[sk])
|
||||
}
|
||||
for col, field := range data.Rows[sk].Fields {
|
||||
header := data.Header[col]
|
||||
field, align := v.formatCell(data.NumCols[header], header, field+deltas(data.Rows[sk].Deltas[col], field), pads[col])
|
||||
c := tview.NewTableCell(field)
|
||||
{
|
||||
c.SetExpansion(1)
|
||||
c.SetAlign(align)
|
||||
c.SetTextColor(fgColor)
|
||||
}
|
||||
v.SetCell(row, col, c)
|
||||
}
|
||||
v.buildRow(row, data, sk, pads)
|
||||
row++
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue