- Replace 12-item flat menu with 4-item main menu: Health Check, Export support bundle, Settings, Exit - Add Health Check screen (Lenovo-style): per-component checkboxes (GPU/MEM/DISK/CPU), Quick/Standard/Express modes, Run All, letter hotkeys G/M/S/C/R/A/1/2/3 - Add two-column main screen: left = menu, right = hardware panel with colored PASS/FAIL/CANCEL/N/A status per component; Tab/→ switches focus, Enter opens component detail - Add app.LoadHardwarePanel() + ComponentDetailResult() reading audit JSON and SAT summary.txt files - Move Network/Services/audit actions into Settings submenu - Export: support bundle only (remove separate audit JSON export) - Delete screen_acceptance.go; add screen_health_check.go, screen_settings.go, app/panel.go - Add BMC + CPU stress-ng tests to backlog - Update bible submodule - Rewrite tui_test.go for new screen/action structure Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
112 lines
2.8 KiB
Go
112 lines
2.8 KiB
Go
package tui
|
|
|
|
import tea "github.com/charmbracelet/bubbletea"
|
|
|
|
func (m model) updateStaticForm(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
|
switch msg.String() {
|
|
case "esc":
|
|
m.screen = screenNetwork
|
|
m.formFields = nil
|
|
m.formIndex = 0
|
|
return m, nil
|
|
case "up", "shift+tab":
|
|
if m.formIndex > 0 {
|
|
m.formIndex--
|
|
}
|
|
case "down", "tab":
|
|
if m.formIndex < len(m.formFields)-1 {
|
|
m.formIndex++
|
|
}
|
|
case "enter":
|
|
if m.formIndex < len(m.formFields)-1 {
|
|
m.formIndex++
|
|
return m, nil
|
|
}
|
|
cfg := m.app.ParseStaticIPv4Config(m.selectedIface, []string{
|
|
m.formFields[0].Value,
|
|
m.formFields[1].Value,
|
|
m.formFields[2].Value,
|
|
m.formFields[3].Value,
|
|
})
|
|
m.busy = true
|
|
m.busyTitle = "Static IPv4: " + m.selectedIface
|
|
return m, func() tea.Msg {
|
|
result, err := m.app.SetStaticIPv4Result(cfg)
|
|
return resultMsg{title: result.Title, body: result.Body, err: err, back: screenNetwork}
|
|
}
|
|
case "backspace":
|
|
field := &m.formFields[m.formIndex]
|
|
if len(field.Value) > 0 {
|
|
field.Value = field.Value[:len(field.Value)-1]
|
|
}
|
|
default:
|
|
if msg.Type == tea.KeyRunes && len(msg.Runes) > 0 {
|
|
m.formFields[m.formIndex].Value += string(msg.Runes)
|
|
}
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
func (m model) updateConfirm(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
|
switch msg.String() {
|
|
case "left", "up", "tab":
|
|
if m.cursor > 0 {
|
|
m.cursor--
|
|
}
|
|
case "right", "down":
|
|
if m.cursor < 1 {
|
|
m.cursor++
|
|
}
|
|
case "esc":
|
|
m.screen = m.confirmCancelTarget()
|
|
m.cursor = 0
|
|
m.pendingAction = actionNone
|
|
return m, nil
|
|
case "enter":
|
|
if m.cursor == 1 { // Cancel
|
|
m.screen = m.confirmCancelTarget()
|
|
m.cursor = 0
|
|
m.pendingAction = actionNone
|
|
return m, nil
|
|
}
|
|
m.busy = true
|
|
switch m.pendingAction {
|
|
case actionExportBundle:
|
|
m.busyTitle = "Export support bundle"
|
|
target := *m.selectedTarget
|
|
return m, func() tea.Msg {
|
|
result, err := m.app.ExportSupportBundleResult(target)
|
|
return resultMsg{title: result.Title, body: result.Body, err: err, back: screenMain}
|
|
}
|
|
case actionRunAll:
|
|
return m.executeRunAll()
|
|
case actionRunMemorySAT:
|
|
m.busyTitle = "Memory test"
|
|
return m, func() tea.Msg {
|
|
result, err := m.app.RunMemoryAcceptancePackResult("")
|
|
return resultMsg{title: result.Title, body: result.Body, err: err, back: screenHealthCheck}
|
|
}
|
|
case actionRunStorageSAT:
|
|
m.busyTitle = "Storage test"
|
|
return m, func() tea.Msg {
|
|
result, err := m.app.RunStorageAcceptancePackResult("")
|
|
return resultMsg{title: result.Title, body: result.Body, err: err, back: screenHealthCheck}
|
|
}
|
|
}
|
|
case "ctrl+c":
|
|
return m, tea.Quit
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
func (m model) confirmCancelTarget() screen {
|
|
switch m.pendingAction {
|
|
case actionExportBundle:
|
|
return screenExportTargets
|
|
case actionRunAll, actionRunMemorySAT, actionRunStorageSAT:
|
|
return screenHealthCheck
|
|
default:
|
|
return screenMain
|
|
}
|
|
}
|