Skip to content

Commit

Permalink
feat(sort): allow sorting any column with top like navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
ventsislav-georgiev committed Aug 20, 2024
1 parent 88394a4 commit 2a46d90
Show file tree
Hide file tree
Showing 23 changed files with 117 additions and 30 deletions.
12 changes: 8 additions & 4 deletions internal/ui/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ func initKeys() {
tcell.KeyNames[KeyHelp] = "?"
tcell.KeyNames[KeySlash] = "/"
tcell.KeyNames[KeySpace] = "space"
tcell.KeyNames[KeyLess] = "<"
tcell.KeyNames[KeyGreater] = ">"

initNumbKeys()
initStdKeys()
Expand Down Expand Up @@ -76,10 +78,12 @@ const (
KeyX
KeyY
KeyZ
KeyHelp = 63
KeySlash = 47
KeyColon = 58
KeySpace = 32
KeyHelp = 63
KeySlash = 47
KeyColon = 58
KeySpace = 32
KeyLess = 60
KeyGreater = 62
)

// Define Shift Keys.
Expand Down
84 changes: 77 additions & 7 deletions internal/ui/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,26 @@ func (t *Table) SetSortCol(name string, asc bool) {
t.setSortCol(model1.SortColumn{Name: name, ASC: asc})
}

func (t *Table) GetSortCol() (string, bool) {
return t.sortCol.Name, t.sortCol.ASC
}

func (t *Table) isVisible(h model1.HeaderColumn) bool {
if h.Name == "NAMESPACE" && !t.GetModel().ClusterWide() {
return false
}
if h.MX && !t.hasMetrics {
return false
}
if h.Wide && !t.wide {
return false
}
if h.VS && vul.ImgScanner == nil {
return false
}
return true
}

// Update table content.
func (t *Table) Update(data *model1.TableData, hasMetrics bool) *model1.TableData {
if t.decorateFn != nil {
Expand Down Expand Up @@ -321,6 +341,20 @@ func (t *Table) UpdateUI(cdata, data *model1.TableData) {
return true
})

colIndex, ok := cdata.Header().IndexOf(t.sortCol.Name, false)
if ok {
events := cdata.GetRowEvents()
events.Sort(
cdata.GetNamespace(),
colIndex,
t.sortCol.Name == "AGE",
data.Header().IsMetricsCol(colIndex),
t.sortCol.Name == "CAPACITY",
t.sortCol.ASC,
)
cdata.SetRowEvents(events)
}

t.updateSelection(true)
t.UpdateTitle()
}
Expand All @@ -343,13 +377,7 @@ func (t *Table) buildRow(r int, re, ore model1.RowEvent, h model1.Header, pads M
continue
}

if h[c].Name == "NAMESPACE" && !t.GetModel().ClusterWide() {
continue
}
if h[c].MX && !t.hasMetrics {
continue
}
if h[c].VS && vul.ImgScanner == nil {
if !t.isVisible(h[c]) {
continue
}

Expand Down Expand Up @@ -396,6 +424,48 @@ func (t *Table) SortColCmd(name string, asc bool) func(evt *tcell.EventKey) *tce
}
}

// SortColChange changes on which column to sort
func (t *Table) SortColChange(direction SortChange) func(evt *tcell.EventKey) *tcell.EventKey {
return func(evt *tcell.EventKey) *tcell.EventKey {
sortCol := t.sortCol.Name
sortColIdx := -1
newSortColIdx := -1
prevSortColIdx := -1
header := t.GetModel().Peek().GetHeader()

for i, h := range header {
if !t.isVisible(h) {
continue
}

if h.Name == sortCol {
sortColIdx = i
break
}

prevSortColIdx = i
}

if direction == SortPrevCol {
newSortColIdx = prevSortColIdx
} else {
for i := sortColIdx + 1; i < len(header); i++ {
if t.isVisible(header[i]) {
newSortColIdx = i
break
}
}
}

if newSortColIdx != -1 {
t.sortCol.Name = header[newSortColIdx].Name
t.Refresh()
}

return nil
}
}

// SortInvertCmd reverses sorting order.
func (t *Table) SortInvertCmd(evt *tcell.EventKey) *tcell.EventKey {
t.toggleSortCol()
Expand Down
10 changes: 10 additions & 0 deletions internal/ui/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ import (
"k8s.io/apimachinery/pkg/runtime"
)

type (
// SortChange changes the column on which to sort
SortChange bool
)

const (
SortNextCol SortChange = true
SortPrevCol SortChange = false
)

// Namespaceable represents a namespaceable model.
type Namespaceable interface {
// ClusterWide returns true if the model represents resource in all namespaces.
Expand Down
2 changes: 1 addition & 1 deletion internal/view/alias_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestAliasNew(t *testing.T) {

assert.Nil(t, v.Init(makeContext()))
assert.Equal(t, "Aliases", v.Name())
assert.Equal(t, 6, len(v.Hints()))
assert.Equal(t, 9, len(v.Hints()))
}

func TestAliasSearch(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion internal/view/cm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestConfigMapNew(t *testing.T) {

assert.Nil(t, s.Init(makeCtx()))
assert.Equal(t, "ConfigMaps", s.Name())
assert.Equal(t, 7, len(s.Hints()))
assert.Equal(t, 10, len(s.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestContainerNew(t *testing.T) {

assert.Nil(t, c.Init(makeCtx()))
assert.Equal(t, "Containers", c.Name())
assert.Equal(t, 18, len(c.Hints()))
assert.Equal(t, 21, len(c.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestContext(t *testing.T) {

assert.Nil(t, ctx.Init(makeCtx()))
assert.Equal(t, "Contexts", ctx.Name())
assert.Equal(t, 5, len(ctx.Hints()))
assert.Equal(t, 8, len(ctx.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/dir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ func TestDir(t *testing.T) {

assert.Nil(t, v.Init(makeCtx()))
assert.Equal(t, "Directory", v.Name())
assert.Equal(t, 7, len(v.Hints()))
assert.Equal(t, 10, len(v.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/dp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestDeploy(t *testing.T) {

assert.Nil(t, v.Init(makeCtx()))
assert.Equal(t, "Deployments", v.Name())
assert.Equal(t, 16, len(v.Hints()))
assert.Equal(t, 19, len(v.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/ds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestDaemonSet(t *testing.T) {

assert.Nil(t, v.Init(makeCtx()))
assert.Equal(t, "DaemonSets", v.Name())
assert.Equal(t, 17, len(v.Hints()))
assert.Equal(t, 20, len(v.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestHelp(t *testing.T) {
v := view.NewHelp(app)

assert.Nil(t, v.Init(ctx))
assert.Equal(t, 29, v.GetRowCount())
assert.Equal(t, 32, v.GetRowCount())
assert.Equal(t, 8, v.GetColumnCount())
assert.Equal(t, "<a>", strings.TrimSpace(v.GetCell(1, 0).Text))
assert.Equal(t, "Attach", strings.TrimSpace(v.GetCell(1, 1).Text))
Expand Down
2 changes: 1 addition & 1 deletion internal/view/ns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestNSCleanser(t *testing.T) {

assert.Nil(t, ns.Init(makeCtx()))
assert.Equal(t, "Namespaces", ns.Name())
assert.Equal(t, 7, len(ns.Hints()))
assert.Equal(t, 10, len(ns.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/pf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestPortForwardNew(t *testing.T) {

assert.Nil(t, pf.Init(makeCtx()))
assert.Equal(t, "PortForwards", pf.Name())
assert.Equal(t, 10, len(pf.Hints()))
assert.Equal(t, 13, len(pf.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestPodNew(t *testing.T) {

assert.Nil(t, po.Init(makeCtx()))
assert.Equal(t, "Pods", po.Name())
assert.Equal(t, 28, len(po.Hints()))
assert.Equal(t, 31, len(po.Hints()))
}

// Helpers...
Expand Down
2 changes: 1 addition & 1 deletion internal/view/priorityclass_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestPriorityClassNew(t *testing.T) {

assert.Nil(t, s.Init(makeCtx()))
assert.Equal(t, "PriorityClass", s.Name())
assert.Equal(t, 6, len(s.Hints()))
assert.Equal(t, 9, len(s.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/pvc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestPVCNew(t *testing.T) {

assert.Nil(t, v.Init(makeCtx()))
assert.Equal(t, "PersistentVolumeClaims", v.Name())
assert.Equal(t, 11, len(v.Hints()))
assert.Equal(t, 14, len(v.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/rbac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestRbacNew(t *testing.T) {

assert.Nil(t, v.Init(makeCtx()))
assert.Equal(t, "Rbac", v.Name())
assert.Equal(t, 5, len(v.Hints()))
assert.Equal(t, 8, len(v.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/reference_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestReferenceNew(t *testing.T) {

assert.Nil(t, s.Init(makeCtx()))
assert.Equal(t, "References", s.Name())
assert.Equal(t, 4, len(s.Hints()))
assert.Equal(t, 7, len(s.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/screen_dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestScreenDumpNew(t *testing.T) {

assert.Nil(t, po.Init(makeCtx()))
assert.Equal(t, "ScreenDumps", po.Name())
assert.Equal(t, 5, len(po.Hints()))
assert.Equal(t, 8, len(po.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestSecretNew(t *testing.T) {

assert.Nil(t, s.Init(makeCtx()))
assert.Equal(t, "Secrets", s.Name())
assert.Equal(t, 8, len(s.Hints()))
assert.Equal(t, 11, len(s.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/sts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestStatefulSetNew(t *testing.T) {

assert.Nil(t, s.Init(makeCtx()))
assert.Equal(t, "StatefulSets", s.Name())
assert.Equal(t, 14, len(s.Hints()))
assert.Equal(t, 17, len(s.Hints()))
}
2 changes: 1 addition & 1 deletion internal/view/svc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,5 @@ func TestServiceNew(t *testing.T) {

assert.Nil(t, s.Init(makeCtx()))
assert.Equal(t, "Services", s.Name())
assert.Equal(t, 12, len(s.Hints()))
assert.Equal(t, 15, len(s.Hints()))
}
3 changes: 3 additions & 0 deletions internal/view/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ func (t *Table) bindKeys() {
tcell.KeyCtrlW: ui.NewKeyAction("Toggle Wide", t.toggleWideCmd, false),
ui.KeyShiftN: ui.NewKeyAction("Sort Name", t.SortColCmd(nameCol, true), false),
ui.KeyShiftA: ui.NewKeyAction("Sort Age", t.SortColCmd(ageCol, true), false),
ui.KeyQ: ui.NewKeyAction("Reverse Sort Order", t.SortInvertCmd, false),
ui.KeyLess: ui.NewKeyAction("Sort Previous Column", t.SortColChange(ui.SortPrevCol), false),
ui.KeyGreater: ui.NewKeyAction("Sort Next Column", t.SortColChange(ui.SortNextCol), false),
})
}

Expand Down

0 comments on commit 2a46d90

Please sign in to comment.