Skip to content

Commit

Permalink
feat: re-introduce history for top right pane
Browse files Browse the repository at this point in the history
  • Loading branch information
leg100 committed Dec 22, 2024
1 parent 1925a2d commit 41a5ce2
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 14 deletions.
1 change: 0 additions & 1 deletion internal/integration/cost_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ func TestCost(t *testing.T) {
// Wait for infracost task to produce overall total. Each workspace in the
// explorer should also have a cost alongside it.
waitFor(t, tm, func(s string) bool {
t.Log(s)
return strings.Contains(s, "cost") &&
strings.Contains(s, "exited $2621.90") &&
matchPattern(t, `OVERALL TOTAL.*\$2\,621\.90`, s) &&
Expand Down
1 change: 0 additions & 1 deletion internal/integration/explorer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ func TestExplorer_Filter(t *testing.T) {

// Expect table title to show 1 module filtered out of a total 3.
waitFor(t, tm, func(s string) bool {
t.Log(s)
return strings.Contains(s, "󰠱 1  0")
})
}
59 changes: 59 additions & 0 deletions internal/integration/history_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package app

import (
"strings"
"testing"

tea "github.com/charmbracelet/bubbletea"
)

func TestHistory(t *testing.T) {
t.Parallel()

tm := setup(t, "./testdata/single_module")

// Show task list
tm.Type("t")
waitFor(t, tm, func(s string) bool {
return strings.Contains(s, "tasks")
})

// Try go back but get error
tm.Send(tea.KeyMsg{Type: tea.KeyEsc})
waitFor(t, tm, func(s string) bool {
return strings.Contains(s, "already at first page")
})

// Show logs
tm.Type("l")
waitFor(t, tm, func(s string) bool {
return strings.Contains(s, "logs")
})

// Go back, expect task list
tm.Send(tea.KeyMsg{Type: tea.KeyEsc})
waitFor(t, tm, func(s string) bool {
return strings.Contains(s, "tasks")
})

// Try go back but get error
tm.Send(tea.KeyMsg{Type: tea.KeyEsc})
waitFor(t, tm, func(s string) bool {
return strings.Contains(s, "already at first page")
})

// Focus explorer
tm.Type("0")

// Start init task
tm.Type("i")
waitFor(t, tm, func(s string) bool {
return strings.Contains(s, "init 󰠱 modules/a")
})

// Go back, expect task list
tm.Send(tea.KeyMsg{Type: tea.KeyEsc})
waitFor(t, tm, func(s string) bool {
return strings.Contains(s, "tasks")
})
}
2 changes: 0 additions & 2 deletions internal/integration/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ func TestExplorer_SingleApply(t *testing.T) {

// Give approval
waitFor(t, tm, func(s string) bool {
t.Log(s)
return strings.Contains(s, "Auto-apply 1 workspaces? (y/N):")
})
tm.Type("y")
Expand Down Expand Up @@ -408,7 +407,6 @@ func TestExplorer_MultipleDestroys(t *testing.T) {
tm.Type("y")

waitFor(t, tm, func(s string) bool {
t.Log(s)
return strings.Contains(s, "apply (destroy) 3/3") &&
matchPattern(t, `modules/a.*default.*apply \(destroy\).*exited.*\+0~0-10`, s) &&
matchPattern(t, `modules/b.*default.*apply \(destroy\).*exited.*\+0~0-10`, s) &&
Expand Down
1 change: 0 additions & 1 deletion internal/integration/terragrunt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ func TestTerragrunt_Dependencies(t *testing.T) {

// Expect 6 apply tasks.
waitFor(t, tm, func(s string) bool {
t.Log(s)
return strings.Contains(s, "apply (destroy) 6/6") &&
matchPattern(t, `modules/vpc.*default.*apply \(destroy\).*exited.*\+0~0-0`, s) &&
matchPattern(t, `modules/redis.*default.*apply \(destroy\).*exited.*\+0~0-0`, s) &&
Expand Down
2 changes: 0 additions & 2 deletions internal/integration/workspace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,11 @@ func TestWorkspace_Delete(t *testing.T) {

// Give approval
waitFor(t, tm, func(s string) bool {
t.Log(s)
return strings.Contains(s, "Delete workspace dev? (y/N):")
})
tm.Type("y")

waitFor(t, tm, func(s string) bool {
t.Log(s)
return strings.Contains(s, "workspace delete 󰠱 modules/a") &&
strings.Contains(s, `Deleted workspace "dev"!`)
})
Expand Down
5 changes: 5 additions & 0 deletions internal/tui/keys/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type common struct {
Format key.Binding
Cost key.Binding
LastTask key.Binding
Back key.Binding
}

// Keys shared by several models.
Expand Down Expand Up @@ -92,4 +93,8 @@ var Common = common{
key.WithKeys("o"),
key.WithHelp("o", "last task output"),
),
Back: key.NewBinding(
key.WithKeys("esc"),
key.WithHelp("esc", "back"),
),
}
40 changes: 36 additions & 4 deletions internal/tui/pane_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ type PaneManager struct {
leftPaneWidth int
// topRightPaneHeight is the height of the top right pane.
topRightHeight int
// history tracks previously visited models for the top right pane.
history []pane
}

type pane struct {
Expand Down Expand Up @@ -79,6 +81,22 @@ func (p *PaneManager) Update(msg tea.Msg) tea.Cmd {
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.Common.Back):
if p.active != TopRightPane {
// History is only maintained for the top right pane.
break
}
if len(p.history) == 1 {
// At dawn of history; can't go further back.
return ReportError(errors.New("already at first page"))
}
// Pop current model from history
p.history = p.history[:len(p.history)-1]
// Set pane to last model
p.panes[TopRightPane] = p.history[len(p.history)-1]
// A new top right pane replaces any bottom right pane as well.
delete(p.panes, BottomRightPane)
p.updateChildSizes()
case key.Matches(msg, keys.Global.ShrinkPaneWidth):
p.updateLeftWidth(-1)
p.updateChildSizes()
Expand Down Expand Up @@ -234,14 +252,17 @@ func (m *PaneManager) setPane(msg NavigationMsg) (cmd tea.Cmd) {
m.cache.Put(msg.Page, model)
cmd = model.Init()
}
if msg.Position == TopRightPane {
// A new top right pane replaces any bottom right pane as well.
delete(m.panes, BottomRightPane)
}
m.panes[msg.Position] = pane{
model: model,
page: msg.Page,
}
if msg.Position == TopRightPane {
// A new top right pane replaces any bottom right pane as well.
delete(m.panes, BottomRightPane)
// Track the models for the top right pane, so that the user can go back
// to previous models.
m.history = append(m.history, m.panes[TopRightPane])
}
m.updateChildSizes()
if !msg.DisableFocus {
focus := m.focusPane(msg.Position)
Expand Down Expand Up @@ -337,6 +358,17 @@ func (m *PaneManager) renderPane(position Position) string {
return borderize(renderedPane, isActive, borderTexts)
}

func (m *PaneManager) HelpBindings() (bindings []key.Binding) {
if m.active == TopRightPane {
// Only the top right pane has the ability to "go back"
bindings = append(bindings, keys.Common.Back)
}
if model, ok := m.ActiveModel().(ModelHelpBindings); ok {
bindings = append(bindings, model.HelpBindings()...)
}
return bindings
}

func removeEmptyStrings(strs ...string) []string {
n := 0
for _, s := range strs {
Expand Down
4 changes: 1 addition & 3 deletions internal/tui/top/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,7 @@ func (m model) help() string {
case filterMode:
bindings = append(bindings, keys.KeyMapToSlice(keys.Filter)...)
default:
if model, ok := m.ActiveModel().(tui.ModelHelpBindings); ok {
bindings = append(bindings, model.HelpBindings()...)
}
bindings = append(bindings, m.PaneManager.HelpBindings()...)
}
bindings = append(bindings, keys.KeyMapToSlice(keys.Global)...)
bindings = append(bindings, keys.KeyMapToSlice(keys.Navigation)...)
Expand Down

0 comments on commit 41a5ce2

Please sign in to comment.