fix: make target progress reflect fresh state
This commit is contained in:
+23
-9
@@ -38,6 +38,7 @@ type Model struct {
|
||||
pendingActivation app.Intent
|
||||
status string
|
||||
applying bool
|
||||
refreshing bool
|
||||
profileTransition bool
|
||||
progressTarget string
|
||||
}
|
||||
@@ -46,6 +47,10 @@ type targetOperationDone struct {
|
||||
result app.Result
|
||||
}
|
||||
|
||||
type refreshDone struct {
|
||||
result app.Result
|
||||
}
|
||||
|
||||
type profileOperationProgress struct {
|
||||
result app.Result
|
||||
updates <-chan app.Result
|
||||
@@ -68,6 +73,19 @@ func NewModel(application app.Module) Model {
|
||||
func (m Model) Init() tea.Cmd { return nil }
|
||||
|
||||
func (m Model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
|
||||
if completed, ok := message.(refreshDone); ok {
|
||||
m.refreshing = false
|
||||
m.snapshot = completed.result.Snapshot
|
||||
if completed.result.Err != nil {
|
||||
m.status = "\x1b[31mError: " + completed.result.Err.Error() + "\x1b[0m"
|
||||
} else {
|
||||
m.status = completed.result.Notice
|
||||
}
|
||||
if m.selected >= len(m.availableTargets()) && m.selected > 0 {
|
||||
m.selected--
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
if progress, ok := message.(profileOperationProgress); ok {
|
||||
m.snapshot = progress.result.Snapshot
|
||||
m.progressTarget = ""
|
||||
@@ -166,15 +184,11 @@ func (m Model) updateMain(key tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
m.page = helpPage
|
||||
m.status = ""
|
||||
case "r":
|
||||
if !m.applying {
|
||||
result := m.application.Dispatch(app.Intent{Kind: app.RefreshTargets})
|
||||
m.snapshot = result.Snapshot
|
||||
m.status = result.Notice
|
||||
if result.Err != nil {
|
||||
m.status = "Error: " + result.Err.Error()
|
||||
}
|
||||
if m.selected >= len(m.availableTargets()) && m.selected > 0 {
|
||||
m.selected--
|
||||
if !m.applying && !m.refreshing {
|
||||
m.refreshing = true
|
||||
m.status = "Refreshing Target availability and state…"
|
||||
return m, func() tea.Msg {
|
||||
return refreshDone{result: m.application.Dispatch(app.Intent{Kind: app.RefreshTargets})}
|
||||
}
|
||||
}
|
||||
case "up", "k":
|
||||
|
||||
@@ -107,12 +107,68 @@ func TestHelpListsEveryTargetAndMainListsOnlyAvailableTargets(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshKeyDispatchesDetectionRefresh(t *testing.T) {
|
||||
module := &targetModule{snapshot: app.Snapshot{}, result: app.Result{Snapshot: app.Snapshot{Targets: []app.TargetSnapshot{{ID: "apt", Description: target.Description{Name: "APT"}, Available: true, State: target.External}}}}}
|
||||
func TestRefreshKeyRunsAsynchronouslyAndRendersRefreshingThenCompleted(t *testing.T) {
|
||||
module := &targetModule{snapshot: app.Snapshot{}, result: app.Result{Snapshot: app.Snapshot{Targets: []app.TargetSnapshot{{ID: "apt", Description: target.Description{Name: "APT"}, Available: true, State: target.External}}}, Notice: "Refreshed Target availability and state"}}
|
||||
model := NewModel(module)
|
||||
model = updateKey(model, "r")
|
||||
if len(module.intents) != 1 || module.intents[0].Kind != app.RefreshTargets || !strings.Contains(model.View(), "External") {
|
||||
t.Fatalf("refresh = intents %#v\n%s", module.intents, model.View())
|
||||
updated, command := model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'r'}})
|
||||
model = updated.(Model)
|
||||
if command == nil || len(module.intents) != 0 || !strings.Contains(model.View(), "Refreshing Target availability and state") {
|
||||
t.Fatalf("refresh did not start asynchronously: intents %#v\n%s", module.intents, model.View())
|
||||
}
|
||||
message := command()
|
||||
if len(module.intents) != 1 || module.intents[0].Kind != app.RefreshTargets {
|
||||
t.Fatalf("refresh command intents = %#v", module.intents)
|
||||
}
|
||||
updated, command = model.Update(message)
|
||||
model = updated.(Model)
|
||||
if command != nil || !strings.Contains(model.View(), "External") || !strings.Contains(model.View(), "Refreshed Target availability and state") {
|
||||
t.Fatalf("refresh completion:\n%s", model.View())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTargetPanelNavigationKeysAndQuitCombinations(t *testing.T) {
|
||||
module := &targetModule{snapshot: app.Snapshot{Targets: []app.TargetSnapshot{
|
||||
{ID: "first", Description: target.Description{Name: "First", Summary: "first summary"}, Available: true},
|
||||
{ID: "second", Description: target.Description{Name: "Second", Summary: "second summary"}, Available: true},
|
||||
}}}
|
||||
for _, down := range []tea.KeyMsg{{Type: tea.KeyDown}, {Type: tea.KeyRunes, Runes: []rune{'j'}}} {
|
||||
model := NewModel(module)
|
||||
updated, _ := model.Update(down)
|
||||
model = updated.(Model)
|
||||
if !strings.Contains(model.View(), "> [ ] Second") {
|
||||
t.Fatalf("down key %q did not select second Target:\n%s", down.String(), model.View())
|
||||
}
|
||||
for _, up := range []tea.KeyMsg{{Type: tea.KeyUp}, {Type: tea.KeyRunes, Runes: []rune{'k'}}} {
|
||||
updated, _ = model.Update(up)
|
||||
if !strings.Contains(updated.(Model).View(), "> [ ] First") {
|
||||
t.Fatalf("up key %q did not select first Target:\n%s", up.String(), updated.(Model).View())
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, quit := range []tea.KeyMsg{{Type: tea.KeyRunes, Runes: []rune{'q'}}, {Type: tea.KeyEsc}} {
|
||||
_, command := NewModel(module).Update(quit)
|
||||
if command == nil {
|
||||
t.Fatalf("quit key %q returned no command", quit.String())
|
||||
}
|
||||
if _, ok := command().(tea.QuitMsg); !ok {
|
||||
t.Fatalf("quit key %q command did not return tea.QuitMsg", quit.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestQAndEscapeReturnFromNestedPages(t *testing.T) {
|
||||
module := &targetModule{}
|
||||
for _, key := range []tea.KeyMsg{{Type: tea.KeyRunes, Runes: []rune{'q'}}, {Type: tea.KeyEsc}} {
|
||||
model := updateKey(NewModel(module), "?")
|
||||
updated, command := model.Update(key)
|
||||
if command != nil || !strings.Contains(updated.(Model).View(), "Target panel") {
|
||||
t.Fatalf("help key %q did not return to Target panel", key.String())
|
||||
}
|
||||
model = updateKey(NewModel(module), "p")
|
||||
updated, command = model.Update(key)
|
||||
if command != nil || !strings.Contains(updated.(Model).View(), "Target panel") {
|
||||
t.Fatalf("Profile key %q did not return to Target panel", key.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user