pi-agent: Fix final integrated review
This commit is contained in:
+61
-54
@@ -9,6 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func (p terminalPresentation) mainView(model presentationState, width, height int) terminalPage {
|
||||
dashboard, operation := model.dashboard, model.operation
|
||||
activeProfile := model.snapshot.ActiveProfile
|
||||
if activeProfile == "" {
|
||||
activeProfile = "No Active Profile"
|
||||
@@ -20,11 +21,11 @@ func (p terminalPresentation) mainView(model presentationState, width, height in
|
||||
p.theme.title.Render("proxyctl"), activeProfile, p.stateCountSummary(model.snapshot))
|
||||
}
|
||||
|
||||
catalog := newTargetCatalog(model.snapshot, model.showUnavailable, model.selectedTargetID)
|
||||
catalog := newTargetCatalog(model.snapshot, dashboard.showUnavailable, dashboard.selectedTargetID)
|
||||
footer := p.dashboardFooter(model, catalog)
|
||||
if model.currentError != nil {
|
||||
if operation.currentError != nil {
|
||||
footer += "\ne: expand/collapse current error x: acknowledge error"
|
||||
if model.errorExpanded {
|
||||
if operation.errorExpanded {
|
||||
footer += " PgUp/PgDn: scroll error details"
|
||||
}
|
||||
}
|
||||
@@ -33,22 +34,25 @@ func (p terminalPresentation) mainView(model presentationState, width, height in
|
||||
footer: footer,
|
||||
dashboard: &dashboardRenderState{
|
||||
catalog: catalog,
|
||||
selectedTargetID: model.selectedTargetID,
|
||||
focus: model.dashboardFocus,
|
||||
detailsOffset: model.detailsOffset,
|
||||
operationProgress: model.operationProgress,
|
||||
selectedTargetID: dashboard.selectedTargetID,
|
||||
focus: dashboard.focus,
|
||||
detailsOffset: dashboard.detailsOffset,
|
||||
operationProgress: operation.progress,
|
||||
applyingFrame: operation.spinnerFrame,
|
||||
terminalWidth: width,
|
||||
terminalHeight: height,
|
||||
},
|
||||
}
|
||||
if model.picker.open {
|
||||
if dashboard.picker.open {
|
||||
page.dashboard = nil
|
||||
page.primary = model.picker.view(model.snapshot, width, max(5, height-9))
|
||||
page.primary = dashboard.picker.view(model.snapshot, width, max(5, height-9))
|
||||
page.footer = "Type to search ↑/↓ PgUp/PgDn: select Enter: activate\nEsc: cancel ?: help"
|
||||
if width < 70 {
|
||||
page.footer = "Type: search ↑/↓: select Enter: activate\nEsc: cancel ?: help"
|
||||
}
|
||||
}
|
||||
if model.driftResolutionTargetID != "" && model.confirmation == nil {
|
||||
if selected, ok := newTargetCatalog(model.snapshot, true, model.driftResolutionTargetID).selected(model.driftResolutionTargetID); ok {
|
||||
if dashboard.driftResolutionTargetID != "" && operation.confirmation == nil {
|
||||
if selected, ok := newTargetCatalog(model.snapshot, true, dashboard.driftResolutionTargetID).selected(dashboard.driftResolutionTargetID); ok {
|
||||
page.dashboard = nil
|
||||
page.primary, page.context = p.driftResolutionView(selected)
|
||||
page.wrapPrimary = true
|
||||
@@ -56,10 +60,10 @@ func (p terminalPresentation) mainView(model presentationState, width, height in
|
||||
page.footer = "r: Reapply Active Profile o: Restore Original\nEnter/q/Esc: cancel ?: help"
|
||||
}
|
||||
}
|
||||
if model.confirmation != nil {
|
||||
dialog := newConfirmationDialog(*model.confirmation)
|
||||
if model.confirmationDialog != nil {
|
||||
dialog = *model.confirmationDialog
|
||||
if operation.confirmation != nil {
|
||||
dialog := newConfirmationDialog(*operation.confirmation)
|
||||
if operation.confirmationDialog != nil {
|
||||
dialog = *operation.confirmationDialog
|
||||
}
|
||||
page.dashboard = nil
|
||||
page.primary = dialog.view()
|
||||
@@ -93,71 +97,73 @@ func (p terminalPresentation) driftResolutionView(selected app.TargetSnapshot) (
|
||||
}
|
||||
|
||||
func (p terminalPresentation) dashboardFooter(model presentationState, catalog targetCatalog) string {
|
||||
dashboard, operation, width := model.dashboard, model.operation, model.terminal.width
|
||||
visibility := "u: show unavailable"
|
||||
if model.showUnavailable {
|
||||
if dashboard.showUnavailable {
|
||||
visibility = "u: hide unavailable"
|
||||
}
|
||||
if model.dashboardFocus == targetDetailsPane {
|
||||
if model.exitDeferred {
|
||||
if dashboard.focus == targetDetailsPane {
|
||||
if operation.exitDeferred {
|
||||
return "↑/k ↓/j PgUp/PgDn: browse Tab: focus Targets " + visibility + " ?: help\nExit pending; new work disabled until safe completion"
|
||||
}
|
||||
if model.width < wideWidth {
|
||||
if model.operationActive {
|
||||
if width < wideWidth {
|
||||
if operation.active {
|
||||
return "↑/k ↓/j PgUp/PgDn: browse Tab: focus Targets\n?: help q/Ctrl+C: defer exit; mutations disabled"
|
||||
}
|
||||
if model.width < 70 {
|
||||
if width < 70 {
|
||||
return "↑/k ↓/j PgUp/PgDn: scroll Tab: focus Targets\np: switch Profile m: manage ?: help q: quit"
|
||||
}
|
||||
return "↑/k ↓/j PgUp/PgDn: scroll Tab: focus Targets\np: switch Active Profile m: manage Proxy Profiles ?: help q: quit"
|
||||
}
|
||||
footer := "↑/k ↓/j PgUp/PgDn: scroll Tab: focus Targets " + visibility + "\np: switch Active Profile m: manage Proxy Profiles ?: help q/Ctrl+C: quit"
|
||||
if model.operationActive {
|
||||
if operation.active {
|
||||
footer = "↑/k ↓/j PgUp/PgDn: scroll Tab: focus Targets " + visibility + " ?: help\nq/Ctrl+C: defer safe exit; mutations disabled"
|
||||
}
|
||||
return footer
|
||||
}
|
||||
actions := "↑/k ↓/j: select Tab: focus details " + visibility
|
||||
if model.exitDeferred {
|
||||
if operation.exitDeferred {
|
||||
return actions + " ?: help\nExit pending; new work disabled until safe completion"
|
||||
}
|
||||
selected, ok := catalog.selected(model.selectedTargetID)
|
||||
availability := targetMutationAvailability(selected, ok, model.operationActive || model.exitDeferred)
|
||||
selected, ok := catalog.selected(dashboard.selectedTargetID)
|
||||
availability := targetMutationAvailability(selected, ok, operation.active || operation.exitDeferred)
|
||||
label := targetActionLabel(selected.PrimaryAction.Kind)
|
||||
if availability.available {
|
||||
actions = "Space: " + label + " " + actions
|
||||
} else {
|
||||
actions = "Space: " + label + " disabled (" + availability.compactReason + ") " + actions
|
||||
}
|
||||
if model.width < wideWidth {
|
||||
if width < wideWidth {
|
||||
if availability.available {
|
||||
actions = "Space: " + label + " ↑/k ↓/j: select Tab: focus details"
|
||||
} else {
|
||||
actions = "Space: " + label + " disabled ↑/k ↓/j: select Tab: focus details"
|
||||
}
|
||||
|
||||
if model.operationActive {
|
||||
if operation.active {
|
||||
return actions + "\n?: help q/Ctrl+C: defer exit; mutations disabled"
|
||||
}
|
||||
if model.width < 70 {
|
||||
if width < 70 {
|
||||
return actions + "\np: switch Profile m: manage ?: help q: quit"
|
||||
}
|
||||
return actions + "\np: switch Active Profile m: manage Proxy Profiles ?: help q: quit"
|
||||
}
|
||||
footer := actions + "\np: switch Active Profile m: manage Proxy Profiles r: refresh ?: help q/Ctrl+C: quit"
|
||||
if model.operationActive {
|
||||
if operation.active {
|
||||
footer = actions + "\n?: help q: defer safe exit; new mutations disabled"
|
||||
}
|
||||
return footer
|
||||
}
|
||||
|
||||
func (p terminalPresentation) profilesView(model presentationState) terminalPage {
|
||||
state := model.profile
|
||||
var list strings.Builder
|
||||
if len(model.snapshot.Profiles) == 0 {
|
||||
list.WriteString("No Proxy Profiles saved. Press n to create one.")
|
||||
}
|
||||
for i, item := range model.snapshot.Profiles {
|
||||
cursor, active := " ", " "
|
||||
if i == model.selected {
|
||||
if i == state.selected {
|
||||
cursor = "> "
|
||||
}
|
||||
if item.Name == model.snapshot.ActiveProfile {
|
||||
@@ -171,17 +177,17 @@ func (p terminalPresentation) profilesView(model presentationState) terminalPage
|
||||
|
||||
context := selectedProfileDetails(p, model)
|
||||
footer := "n: create e: edit Enter: edit d: delete PgUp/PgDn: scroll details\n↑/k ↓/j: select ?: help q/Esc: back"
|
||||
if model.width < 80 {
|
||||
if model.terminal.width < 80 {
|
||||
footer = "↑/k ↓/j: select PgUp/PgDn: details n: create\ne/Enter: edit d: delete ?: help q/Esc: back"
|
||||
}
|
||||
if len(model.snapshot.Profiles) == 0 {
|
||||
footer = "n: create a Proxy Profile ?: help q/Esc: back"
|
||||
}
|
||||
if model.profileDelete != nil {
|
||||
if state.deletion != nil {
|
||||
return terminalPage{
|
||||
header: p.theme.title.Render("Proxy Profile management"),
|
||||
primary: model.profileDelete.dialog.view(),
|
||||
primaryOffset: model.profileDelete.dialog.offset,
|
||||
primary: state.deletion.dialog.view(),
|
||||
primaryOffset: state.deletion.dialog.offset,
|
||||
wrapPrimary: true,
|
||||
footer: "←/→/Tab: choose PgUp/PgDn: scroll Enter: choose y: delete\nn/q/Esc: cancel ?: help",
|
||||
focusLine: -1,
|
||||
@@ -192,9 +198,9 @@ func (p terminalPresentation) profilesView(model presentationState) terminalPage
|
||||
primary: list.String(),
|
||||
context: context,
|
||||
footer: footer,
|
||||
focusLine: model.selected,
|
||||
primaryOffset: model.profileOffset,
|
||||
contextOffset: model.profileDetails,
|
||||
focusLine: state.selected,
|
||||
primaryOffset: state.listOffset,
|
||||
contextOffset: state.detailsOffset,
|
||||
wrapContext: true,
|
||||
}
|
||||
}
|
||||
@@ -204,7 +210,7 @@ func sanitizeFormText(value string) string {
|
||||
}
|
||||
|
||||
func selectedProfileDetails(p terminalPresentation, model presentationState) string {
|
||||
selected, ok := profileAt(model.snapshot, model.selected)
|
||||
selected, ok := profileAt(model.snapshot, model.profile.selected)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
@@ -233,36 +239,37 @@ func selectedProfileDetails(p terminalPresentation, model presentationState) str
|
||||
}
|
||||
|
||||
func (p terminalPresentation) formView(model presentationState) terminalPage {
|
||||
form, width := model.form.state, model.terminal.width
|
||||
action := "Create"
|
||||
if model.form.originalName != "" {
|
||||
if form.originalName != "" {
|
||||
action = "Edit"
|
||||
}
|
||||
var fields, bypassPreview strings.Builder
|
||||
focusLine, currentLine := 0, 0
|
||||
for i, item := range model.form.inputs {
|
||||
for i, item := range form.inputs {
|
||||
if fields.Len() > 0 {
|
||||
fields.WriteByte('\n')
|
||||
currentLine++
|
||||
}
|
||||
cursor, focus := " ", ""
|
||||
if i == model.form.field {
|
||||
if i == form.field {
|
||||
cursor, focus = "> ", " [focused]"
|
||||
focusLine = currentLine
|
||||
}
|
||||
fmt.Fprintf(&fields, "%s%s%s: %s", cursor, item.label, focus, model.form.renderedInput(i, model.width))
|
||||
if probeText := model.form.probeText(item.field); probeText != "" {
|
||||
fmt.Fprintf(&fields, "%s%s%s: %s", cursor, item.label, focus, form.renderedInput(i, width))
|
||||
if probeText := form.probeText(item.field); probeText != "" {
|
||||
fmt.Fprintf(&fields, "\n %s", probeText)
|
||||
currentLine++
|
||||
}
|
||||
if item.field == profile.NameField && model.form.hasProbeSourceAttachment() {
|
||||
fmt.Fprintf(&fields, "\n Single proxy URL probe [read-only]: %s", profile.ObscureURLForEditing(model.form.probe.sourceValue))
|
||||
fmt.Fprintf(&fields, "\n %s", model.form.probe.feedback)
|
||||
if item.field == profile.NameField && form.hasProbeSourceAttachment() {
|
||||
fmt.Fprintf(&fields, "\n Single proxy URL probe [read-only]: %s", profile.ObscureURLForEditing(form.probe.sourceValue))
|
||||
fmt.Fprintf(&fields, "\n %s", form.probe.feedback)
|
||||
fields.WriteString("\n Generated Advanced URL fields from this Single proxy URL probe:")
|
||||
currentLine += 3
|
||||
}
|
||||
validation := model.form.validationText(i)
|
||||
validation := form.validationText(i)
|
||||
if item.field == profile.NameField {
|
||||
if conflict := model.form.nameConflict(model.snapshot.Profiles); conflict != "" {
|
||||
if conflict := form.nameConflict(model.snapshot.Profiles); conflict != "" {
|
||||
validation = conflict
|
||||
}
|
||||
}
|
||||
@@ -272,7 +279,7 @@ func (p terminalPresentation) formView(model presentationState) terminalPage {
|
||||
currentLine++
|
||||
}
|
||||
if item.field == profile.BypassField {
|
||||
analysis := model.form.bypassAnalysis()
|
||||
analysis := form.bypassAnalysis()
|
||||
bypassPreview.WriteString("Normalized Bypass preview:")
|
||||
if len(analysis) == 0 {
|
||||
bypassPreview.WriteString(" (none)")
|
||||
@@ -284,24 +291,24 @@ func (p terminalPresentation) formView(model presentationState) terminalPage {
|
||||
}
|
||||
}
|
||||
secondaryHints := "?: help q/Esc: cancel"
|
||||
if model.form.currentField() == profile.BypassField {
|
||||
if form.currentField() == profile.BypassField {
|
||||
secondaryHints = "PgUp/PgDn: scroll form preview " + secondaryHints
|
||||
}
|
||||
if model.form.profile.Mode == profile.SingleMode && model.form.currentField() == profile.SingleURLField {
|
||||
if form.profile.Mode == profile.SingleMode && form.currentField() == profile.SingleURLField {
|
||||
probeHint := "Ctrl+D: probe"
|
||||
if model.form.probe.active {
|
||||
if form.probe.active {
|
||||
probeHint = "Protocol Probe in progress"
|
||||
}
|
||||
secondaryHints = probeHint + " " + secondaryHints
|
||||
}
|
||||
footer := "Tab/Shift+Tab/↑/↓: move Ctrl+T: mode Ctrl+S: save\n" + secondaryHints
|
||||
return terminalPage{
|
||||
header: p.theme.title.Render(fmt.Sprintf("%s Proxy Profile — %s mode", action, model.form.profile.Mode)),
|
||||
header: p.theme.title.Render(fmt.Sprintf("%s Proxy Profile — %s mode", action, form.profile.Mode)),
|
||||
primary: fields.String(),
|
||||
context: bypassPreview.String(),
|
||||
footer: footer,
|
||||
focusLine: focusLine,
|
||||
contextAnchor: model.form.bypassPreviewLine,
|
||||
contextAnchor: form.bypassPreviewLine,
|
||||
anchorContext: true,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user