feat: implement server-wide management actions and enhance TUI dashboard
This commit is contained in:
+64
-3
@@ -14,6 +14,12 @@ const (
|
||||
IntentLoadLogs IntentKind = "load_logs"
|
||||
IntentTick IntentKind = "tick"
|
||||
IntentQuit IntentKind = "quit"
|
||||
|
||||
// Server-wide bulk operations
|
||||
IntentStartAll IntentKind = "start_all"
|
||||
IntentStopAll IntentKind = "stop_all"
|
||||
IntentRestartAll IntentKind = "restart_all"
|
||||
IntentKillAll IntentKind = "kill_all"
|
||||
)
|
||||
|
||||
// Intent is pure data describing a side effect to execute.
|
||||
@@ -45,9 +51,11 @@ func Update(model Model, msg interface{}) (Model, []Intent) {
|
||||
|
||||
case MsgAgentsLoaded:
|
||||
model.Agents = m.Agents
|
||||
// Clamp cursor
|
||||
if model.Cursor >= len(model.Agents) && len(model.Agents) > 0 {
|
||||
model.Cursor = len(model.Agents) - 1
|
||||
// Clamp cursor only on screens that use the agent list
|
||||
if model.Screen == ScreenAgentList {
|
||||
if model.Cursor >= len(model.Agents) && len(model.Agents) > 0 {
|
||||
model.Cursor = len(model.Agents) - 1
|
||||
}
|
||||
}
|
||||
return model, []Intent{{Kind: IntentTick}}
|
||||
|
||||
@@ -59,6 +67,14 @@ func Update(model Model, msg interface{}) (Model, []Intent) {
|
||||
}
|
||||
return model, []Intent{{Kind: IntentLoadAgents}}
|
||||
|
||||
case MsgServerActionDone:
|
||||
if m.Failed == 0 {
|
||||
model.StatusMsg = fmt.Sprintf("%s: %d agents OK", m.Action, m.Total)
|
||||
} else {
|
||||
model.StatusMsg = fmt.Sprintf("%s: %d/%d failed", m.Action, m.Failed, m.Total)
|
||||
}
|
||||
return model, []Intent{{Kind: IntentLoadAgents}}
|
||||
|
||||
case MsgLogsLoaded:
|
||||
model.LogLines = m.Lines
|
||||
model.LogScroll = max(0, len(m.Lines)-visibleLogLines(model))
|
||||
@@ -92,6 +108,8 @@ func updateKey(model Model, key KeyMsg) (Model, []Intent) {
|
||||
return updateAgentActions(model, key)
|
||||
case ScreenLogs:
|
||||
return updateLogs(model, key)
|
||||
case ScreenServer:
|
||||
return updateServerScreen(model, key)
|
||||
}
|
||||
return model, nil
|
||||
}
|
||||
@@ -109,6 +127,11 @@ func updateMainScreen(model Model, key KeyMsg) (Model, []Intent) {
|
||||
model.Screen = ScreenAgentList
|
||||
model.Cursor = 0
|
||||
return model, []Intent{{Kind: IntentLoadAgents}}
|
||||
case "Server":
|
||||
model.Screen = ScreenServer
|
||||
model.Cursor = 0
|
||||
model.StatusMsg = ""
|
||||
return model, []Intent{{Kind: IntentLoadAgents}}
|
||||
case "Quit":
|
||||
return model, []Intent{{Kind: IntentQuit}}
|
||||
}
|
||||
@@ -210,6 +233,44 @@ func updateLogs(model Model, key KeyMsg) (Model, []Intent) {
|
||||
return model, nil
|
||||
}
|
||||
|
||||
func updateServerScreen(model Model, key KeyMsg) (Model, []Intent) {
|
||||
opts := ServerMenuOptions()
|
||||
|
||||
switch key.Str {
|
||||
case "0":
|
||||
model.Screen = ScreenMain
|
||||
model.Cursor = 0
|
||||
model.StatusMsg = ""
|
||||
case "up", "k":
|
||||
model.Cursor = clamp(model.Cursor-1, 0, len(opts)-1)
|
||||
case "down", "j":
|
||||
model.Cursor = clamp(model.Cursor+1, 0, len(opts)-1)
|
||||
case "enter":
|
||||
if model.Cursor < len(opts) {
|
||||
return executeServerAction(model, opts[model.Cursor].Label)
|
||||
}
|
||||
}
|
||||
return model, nil
|
||||
}
|
||||
|
||||
func executeServerAction(model Model, action string) (Model, []Intent) {
|
||||
switch action {
|
||||
case "Start All":
|
||||
model.StatusMsg = "Starting all agents..."
|
||||
return model, []Intent{{Kind: IntentStartAll}}
|
||||
case "Stop All":
|
||||
model.StatusMsg = "Stopping all agents..."
|
||||
return model, []Intent{{Kind: IntentStopAll}}
|
||||
case "Restart All":
|
||||
model.StatusMsg = "Restarting all agents..."
|
||||
return model, []Intent{{Kind: IntentRestartAll}}
|
||||
case "Kill All":
|
||||
model.StatusMsg = "Killing all agents..."
|
||||
return model, []Intent{{Kind: IntentKillAll}}
|
||||
}
|
||||
return model, nil
|
||||
}
|
||||
|
||||
// ── pure helpers ─────────────────────────────────────────────────────────
|
||||
|
||||
func visibleLogLines(m Model) int {
|
||||
|
||||
Reference in New Issue
Block a user