node_launchpad/components/
footer.rs1use crate::style::{COOL_GREY, EUCALYPTUS, GHOST_WHITE, LIGHT_PERIWINKLE};
10use ratatui::{prelude::*, widgets::*};
11
12pub enum NodesToStart {
13 Running,
14 NotRunning,
15 RunningSelected,
16 NotRunningSelected,
17}
18
19#[derive(Default)]
20pub struct Footer {}
21
22impl StatefulWidget for Footer {
23 type State = NodesToStart;
24
25 fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
26 let layout = Layout::default()
27 .direction(Direction::Vertical)
28 .constraints(vec![Constraint::Length(3)])
29 .split(area);
30
31 let command_enabled = Style::default().fg(GHOST_WHITE);
32 let text_enabled = Style::default().fg(EUCALYPTUS);
33 let command_disabled = Style::default().fg(LIGHT_PERIWINKLE);
34 let text_disabled = Style::default().fg(COOL_GREY);
35
36 let mut remove_command_style = command_disabled;
37 let mut remove_text_style = text_disabled;
38 let mut start_stop_command_style = command_disabled;
39 let mut start_stop_text_style = text_disabled;
40 let mut open_logs_command_style = command_disabled;
41 let mut open_logs_text_style = text_disabled;
42 let mut stop_all_command_style = command_disabled;
43 let mut stop_all_text_style = text_disabled;
44
45 match state {
46 NodesToStart::Running => {
47 stop_all_command_style = command_enabled;
48 stop_all_text_style = text_enabled;
49 }
50 NodesToStart::RunningSelected => {
51 remove_command_style = command_enabled;
52 remove_text_style = text_enabled;
53 start_stop_command_style = command_enabled;
54 start_stop_text_style = text_enabled;
55 open_logs_command_style = command_enabled;
56 open_logs_text_style = text_enabled;
57 stop_all_command_style = command_enabled;
58 stop_all_text_style = text_enabled;
59 }
60 NodesToStart::NotRunning => {}
61 NodesToStart::NotRunningSelected => {
62 remove_command_style = command_enabled;
63 remove_text_style = text_enabled;
64 start_stop_command_style = command_enabled;
65 start_stop_text_style = text_enabled;
66 open_logs_command_style = command_enabled;
67 open_logs_text_style = text_enabled;
68 }
69 }
70
71 let commands = vec![
72 Span::styled("[+] ", command_enabled),
73 Span::styled("Add", text_enabled),
74 Span::styled(" ", Style::default()),
75 Span::styled("[-] ", remove_command_style),
76 Span::styled("Remove", remove_text_style),
77 Span::styled(" ", Style::default()),
78 Span::styled("[Ctrl+S] ", start_stop_command_style),
79 Span::styled("Start/Stop Node", start_stop_text_style),
80 Span::styled(" ", Style::default()),
81 Span::styled("[L] ", open_logs_command_style),
82 Span::styled("Open Logs", open_logs_text_style),
83 ];
84
85 let stop_all = vec![
86 Span::styled("[Ctrl+X] ", stop_all_command_style),
87 Span::styled("Stop All", stop_all_text_style),
88 ];
89
90 let total_width = (layout[0].width - 1) as usize;
91 let spaces = " ".repeat(total_width.saturating_sub(
92 commands.iter().map(|s| s.width()).sum::<usize>()
93 + stop_all.iter().map(|s| s.width()).sum::<usize>(),
94 ));
95
96 let commands_length = 6 + commands.iter().map(|s| s.width()).sum::<usize>() as u16;
97 let spaces_length = spaces.len().saturating_sub(6) as u16;
98 let stop_all_length = stop_all.iter().map(|s| s.width()).sum::<usize>() as u16;
99
100 let cell1 = Cell::from(Line::from(commands));
101 let cell2 = Cell::from(Line::raw(spaces));
102 let cell3 = Cell::from(Line::from(stop_all));
103 let row = Row::new(vec![cell1, cell2, cell3]);
104
105 let table = Table::new(
106 [row],
107 [
108 Constraint::Length(commands_length),
109 Constraint::Length(spaces_length),
110 Constraint::Length(stop_all_length),
111 ],
112 )
113 .block(
114 Block::default()
115 .borders(Borders::ALL)
116 .border_style(Style::default().fg(EUCALYPTUS))
117 .padding(Padding::horizontal(1)),
118 );
119
120 StatefulWidget::render(table, area, buf, &mut TableState::default());
121 }
122}