pi-agent: Implement Help navigation consistency
This commit is contained in:
+24
-14
@@ -19,7 +19,6 @@ const (
|
||||
mainPage page = iota
|
||||
profilesPage
|
||||
formPage
|
||||
helpPage
|
||||
)
|
||||
|
||||
type formState struct {
|
||||
@@ -49,6 +48,7 @@ type Model struct {
|
||||
driftResolutionTargetID string
|
||||
picker profilePickerState
|
||||
form formState
|
||||
help helpDialogState
|
||||
status string
|
||||
operation operationCoordinator
|
||||
detect func(context.Context, string) (probe.Capabilities, error)
|
||||
@@ -139,12 +139,19 @@ func (m Model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, nil
|
||||
}
|
||||
if key, ok := message.(tea.KeyMsg); ok {
|
||||
// q exits the unobscured dashboard. While the searchable picker is open,
|
||||
// it is ordinary filter input; Escape remains deterministic cancellation.
|
||||
exitRequest := key.String() == "ctrl+c" || (m.page == mainPage && !m.picker.open && key.String() == "q")
|
||||
if exitRequest {
|
||||
// Ctrl+C is global. q exits only the dashboard when no dialog obscures it;
|
||||
// otherwise the top dialog or child page owns q.
|
||||
if key.String() == "ctrl+c" || (key.String() == "q" && m.dashboardQuitAvailable()) {
|
||||
return m, m.operation.requestQuit()
|
||||
}
|
||||
// Help is available from every page and dialog. Opening it explicitly
|
||||
// places it above the current dialog without changing state underneath.
|
||||
if key.String() == "?" {
|
||||
if !m.help.top(m.operation.confirmation) {
|
||||
m.help.show()
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
}
|
||||
if progress, ok := message.(operationProgress); ok {
|
||||
if !m.operation.active || progress.updates != m.operation.updates {
|
||||
@@ -166,6 +173,11 @@ func (m Model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
if m.operation.confirmation != nil {
|
||||
m.page = mainPage
|
||||
if m.help.open {
|
||||
// A safety confirmation requested after Help was opened is the new
|
||||
// top dialog. Cancelling it reveals the unchanged Help beneath.
|
||||
m.help.confirmationAbove = true
|
||||
}
|
||||
}
|
||||
if progress.update.IsTerminal() {
|
||||
return m, m.operation.deferredQuit()
|
||||
@@ -220,6 +232,10 @@ func (m Model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
|
||||
if !ok {
|
||||
return m, nil
|
||||
}
|
||||
if m.help.top(m.operation.confirmation) {
|
||||
m.help.update(key.String())
|
||||
return m, nil
|
||||
}
|
||||
switch m.page {
|
||||
case mainPage:
|
||||
return m.updateMain(key)
|
||||
@@ -227,11 +243,6 @@ func (m Model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m.updateProfiles(key)
|
||||
case formPage:
|
||||
return m.updateForm(key)
|
||||
case helpPage:
|
||||
if key.String() == "q" || key.String() == "esc" {
|
||||
m.page = mainPage
|
||||
}
|
||||
return m, nil
|
||||
default:
|
||||
return m, nil
|
||||
}
|
||||
@@ -314,7 +325,7 @@ func (m Model) updateMain(key tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
if m.driftResolutionTargetID != "" {
|
||||
switch key.String() {
|
||||
case "enter", "esc", "n":
|
||||
case "enter", "esc", "n", "q":
|
||||
m.driftResolutionTargetID = ""
|
||||
return m, nil
|
||||
case "r", "o":
|
||||
@@ -381,8 +392,6 @@ func (m Model) updateMain(key tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
m.operation.status = app.OperationStatus{}
|
||||
}
|
||||
}
|
||||
case "?":
|
||||
m.page = helpPage
|
||||
case "r":
|
||||
if m.operation.active || m.operation.quitRequested {
|
||||
m.operation.status = app.OperationStatus{Kind: app.StatusBlocked, Summary: "Wait for the current mutation to finish before refreshing Targets"}
|
||||
@@ -546,7 +555,7 @@ func newProfileDeleteConfirmation(selected profile.Profile, final, active bool)
|
||||
|
||||
func (m Model) updateForm(key tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
switch key.String() {
|
||||
case "esc":
|
||||
case "q", "esc":
|
||||
m.page = profilesPage
|
||||
m.status = ""
|
||||
m.form = formState{}
|
||||
@@ -723,6 +732,7 @@ func (m Model) View() string {
|
||||
driftResolutionTargetID: m.driftResolutionTargetID,
|
||||
picker: m.picker,
|
||||
form: m.form,
|
||||
help: m.help,
|
||||
confirmation: m.operation.confirmation,
|
||||
confirmationDialog: &m.operation.confirmationDialog,
|
||||
status: m.status,
|
||||
|
||||
Reference in New Issue
Block a user