Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 0 additions & 157 deletions internal/ui/views_advanced.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,163 +196,6 @@ func (a *App) renderThreadPoolView() string {
return b.String()
}

// renderTasksView renders the currently running tasks view
func (a *App) renderTasksView() string {
var b strings.Builder

b.WriteString(headerStyle.Render(fmt.Sprintf("Running Tasks (%d)", len(a.tasks))))
b.WriteString("\n\n")

if len(a.tasks) == 0 {
b.WriteString(statusGreen.Render("✓ No running tasks"))
return b.String()
}

// Sort by running time (longest first)
type taskWithTime struct {
task TaskInfo
seconds float64
}

var tasksWithTime []taskWithTime
for _, task := range a.tasks {
seconds := parseRunningTime(task.RunningTime)
tasksWithTime = append(tasksWithTime, taskWithTime{task: task, seconds: seconds})
}

// Simple bubble sort by seconds (descending)
for i := 0; i < len(tasksWithTime); i++ {
for j := i + 1; j < len(tasksWithTime); j++ {
if tasksWithTime[j].seconds > tasksWithTime[i].seconds {
tasksWithTime[i], tasksWithTime[j] = tasksWithTime[j], tasksWithTime[i]
}
}
}

// Limit to 50 tasks for performance
displayCount := len(tasksWithTime)
if displayCount > 50 {
displayCount = 50
}

// Check for long-running tasks
criticalCount := 0
warningCount := 0
for i := 0; i < displayCount; i++ {
if tasksWithTime[i].seconds >= 60 {
criticalCount++
} else if tasksWithTime[i].seconds >= 30 {
warningCount++
}
}

if criticalCount > 0 {
b.WriteString(statusRed.Render(fmt.Sprintf("⚠ %d task(s) running ≥60s", criticalCount)))
b.WriteString("\n\n")
} else if warningCount > 0 {
b.WriteString(statusYellow.Render(fmt.Sprintf("⚠ %d task(s) running ≥30s", warningCount)))
b.WriteString("\n\n")
}

// Display tasks
for i := 0; i < displayCount; i++ {
twt := tasksWithTime[i]
task := twt.task
seconds := twt.seconds

var timeStyle lipgloss.Style
if seconds >= 60 {
timeStyle = statusRed
} else if seconds >= 30 {
timeStyle = statusYellow
} else {
timeStyle = statusGreen
}

actionType := simplifyAction(task.Action)

b.WriteString(fmt.Sprintf("%s %s %s\n",
timeStyle.Render(fmt.Sprintf("[%s]", task.RunningTime)),
valueStyle.Render(actionType),
labelStyle.Render(task.Node)))

if task.Description != "" && task.Description != "null" {
desc := task.Description
if len(desc) > 80 {
desc = desc[:77] + "..."
}
b.WriteString(fmt.Sprintf(" %s\n", labelStyle.Render(desc)))
}
b.WriteString("\n")
}

if len(tasksWithTime) > displayCount {
b.WriteString(labelStyle.Render(fmt.Sprintf("... and %d more tasks", len(tasksWithTime)-displayCount)))
b.WriteString("\n")
}

return b.String()
}

// renderPendingTasksView renders the pending cluster tasks view
func (a *App) renderPendingTasksView() string {
var b strings.Builder

b.WriteString(headerStyle.Render(fmt.Sprintf("Pending Cluster Tasks (%d)", len(a.pendingTasks))))
b.WriteString("\n\n")

if len(a.pendingTasks) == 0 {
b.WriteString(statusGreen.Render("✓ No pending tasks"))
return b.String()
}

// Check for tasks queued too long
criticalCount := 0
warningCount := 0
for _, task := range a.pendingTasks {
ms := parseTimeInQueue(task.TimeInQueue)
if ms >= 5000 {
criticalCount++
} else if ms >= 1000 {
warningCount++
}
}

if criticalCount > 0 {
b.WriteString(statusRed.Render(fmt.Sprintf("⚠ CRITICAL: %d task(s) queued ≥5s", criticalCount)))
b.WriteString("\n")
b.WriteString(labelStyle.Render("Long queue times indicate cluster state update delays"))
b.WriteString("\n\n")
} else if warningCount > 0 {
b.WriteString(statusYellow.Render(fmt.Sprintf("⚠ %d task(s) queued ≥1s", warningCount)))
b.WriteString("\n\n")
}

// Display tasks
for _, task := range a.pendingTasks {
ms := parseTimeInQueue(task.TimeInQueue)

var timeStyle lipgloss.Style
if ms >= 5000 {
timeStyle = statusRed
} else if ms >= 1000 {
timeStyle = statusYellow
} else {
timeStyle = statusGreen
}

b.WriteString(fmt.Sprintf("%s %s\n",
timeStyle.Render(fmt.Sprintf("[%s]", task.TimeInQueue)),
valueStyle.Render(task.Source)))
b.WriteString(fmt.Sprintf(" %s %s %s %s\n",
labelStyle.Render("Priority:"), task.Priority,
labelStyle.Render("Insert Order:"), task.InsertOrder))
b.WriteString("\n")
}

return b.String()
}

// renderRecoveryView renders the shard recovery view
func (a *App) renderRecoveryView() string {
var b strings.Builder
Expand Down
75 changes: 0 additions & 75 deletions internal/ui/views_advanced_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,81 +196,6 @@ func TestApp_RenderThreadPoolView_QueueDepthColorCoding(t *testing.T) {
}
}

// ==================== Tasks View Tests ====================

func TestApp_RenderTasksView_Empty(t *testing.T) {
app := &App{
tasks: []TaskInfo{},
}

result := app.renderTasksView()

if !strings.Contains(result, "No running tasks") {
t.Error("renderTasksView() should show 'No running tasks' for empty list")
}
}

func TestApp_RenderTasksView_WithTasks(t *testing.T) {
app := &App{
tasks: []TaskInfo{
{Action: "indices:data/read/search", Type: "transport", Node: "node-1", RunningTime: "1.5s"},
{Action: "indices:data/write/bulk", Type: "transport", Node: "node-2", RunningTime: "2.3s"},
},
}

result := app.renderTasksView()

if !strings.Contains(result, "Running Tasks (2)") {
t.Error("renderTasksView() should show task count")
}

// Check for simplified action names
if !strings.Contains(result, "Search") || !strings.Contains(result, "Bulk") {
t.Error("renderTasksView() should show simplified action names")
}

if !strings.Contains(result, "node-1") {
t.Error("renderTasksView() should show node names")
}
}

// ==================== Pending Tasks View Tests ====================

func TestApp_RenderPendingTasksView_Empty(t *testing.T) {
app := &App{
pendingTasks: []PendingTaskInfo{},
}

result := app.renderPendingTasksView()

if !strings.Contains(result, "No pending tasks") {
t.Error("renderPendingTasksView() should show 'No pending tasks' for empty list")
}
}

func TestApp_RenderPendingTasksView_WithTasks(t *testing.T) {
app := &App{
pendingTasks: []PendingTaskInfo{
{Priority: "URGENT", Source: "create-index", TimeInQueue: "500ms"},
{Priority: "NORMAL", Source: "update-mapping", TimeInQueue: "100ms"},
},
}

result := app.renderPendingTasksView()

if !strings.Contains(result, "Pending Cluster Tasks (2)") {
t.Error("renderPendingTasksView() should show task count")
}

if !strings.Contains(result, "URGENT") {
t.Error("renderPendingTasksView() should show task priorities")
}

if !strings.Contains(result, "create-index") {
t.Error("renderPendingTasksView() should show task sources")
}
}

// ==================== Recovery View Tests ====================

func TestApp_RenderRecoveryView_Empty(t *testing.T) {
Expand Down
Loading