scud/commands/spawn/tui/
header.rs1use ratatui::{
4 style::{Modifier, Style, Stylize},
5 text::{Line, Span},
6 widgets::{Block, Borders, Padding, Paragraph},
7 Frame,
8};
9
10use super::app::App;
11use super::theme::*;
12
13pub fn render_header(frame: &mut Frame, area: ratatui::layout::Rect, app: &App) {
15 let (starting, running, completed, failed) = app.status_counts();
16
17 let swarm_indicator = if app.swarm_mode {
19 vec![
20 Span::styled(" ", Style::default()),
21 Span::styled(
22 "SWARM ",
23 Style::default()
24 .fg(SWARM_PURPLE)
25 .add_modifier(Modifier::BOLD),
26 ),
27 ]
28 } else {
29 vec![]
30 };
31
32 let ralph_indicator = if app.ralph_mode {
34 vec![
35 Span::styled(" 🔄 ", Style::default()),
36 Span::styled(
37 "RALPH ",
38 Style::default()
39 .fg(RALPH_ORANGE)
40 .add_modifier(Modifier::BOLD),
41 ),
42 ]
43 } else {
44 vec![]
45 };
46
47 let mut spans = vec![
49 Span::styled(" ", Style::default()),
50 Span::styled(
51 &app.session_name,
52 Style::default().fg(ACCENT).add_modifier(Modifier::BOLD),
53 ),
54 ];
55 spans.extend(swarm_indicator);
56 spans.extend(ralph_indicator);
57 spans.extend(vec![
58 Span::styled(" ", Style::default()),
59 Span::styled("â—‰ ", Style::default().fg(STATUS_STARTING)),
61 Span::styled("Starting ", Style::default().fg(TEXT_MUTED).dim()),
62 Span::styled(
63 format!("{} ", starting),
64 Style::default().fg(STATUS_STARTING),
65 ),
66 Span::styled("â—‰ ", Style::default().fg(STATUS_RUNNING)),
68 Span::styled("Running ", Style::default().fg(TEXT_MUTED).dim()),
69 Span::styled(
70 format!("{} ", running),
71 Style::default().fg(STATUS_RUNNING),
72 ),
73 Span::styled("â—‰ ", Style::default().fg(STATUS_COMPLETED)),
75 Span::styled("Done ", Style::default().fg(TEXT_MUTED).dim()),
76 Span::styled(
77 format!("{} ", completed),
78 Style::default().fg(STATUS_COMPLETED),
79 ),
80 Span::styled("â—‰ ", Style::default().fg(STATUS_FAILED)),
82 Span::styled("Failed ", Style::default().fg(TEXT_MUTED).dim()),
83 Span::styled(format!("{}", failed), Style::default().fg(STATUS_FAILED)),
84 ]);
85 let status_line = Line::from(spans);
86
87 let header = Paragraph::new(status_line).block(
88 Block::default()
89 .borders(Borders::BOTTOM)
90 .border_style(Style::default().fg(BORDER_DEFAULT))
91 .style(Style::default().bg(BG_SECONDARY))
92 .padding(Padding::horizontal(1)),
93 );
94
95 frame.render_widget(header, area);
96}
97
98pub fn render_fullscreen_header(frame: &mut Frame, area: ratatui::layout::Rect, app: &App) {
100 let agent_name = app
101 .selected_agent()
102 .map(|a| format!("{}: {}", a.task_id, a.task_title))
103 .unwrap_or_else(|| "No agent".to_string());
104
105 let title = Line::from(vec![
106 Span::styled(" ", Style::default()),
107 Span::styled(
108 &agent_name,
109 Style::default().fg(ACCENT).add_modifier(Modifier::BOLD),
110 ),
111 ]);
112
113 let header = Paragraph::new(title).block(
114 Block::default()
115 .borders(Borders::BOTTOM)
116 .border_style(Style::default().fg(BORDER_ACTIVE))
117 .style(Style::default().bg(BG_SECONDARY)),
118 );
119
120 frame.render_widget(header, area);
121}