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 let start_all_command_style = command_disabled;
45 let start_all_text_style = text_disabled;
46
47 match state {
48 NodesToStart::Running => {
49 stop_all_command_style = command_enabled;
50 stop_all_text_style = text_enabled;
51 }
52 NodesToStart::RunningSelected => {
53 remove_command_style = command_enabled;
54 remove_text_style = text_enabled;
55 start_stop_command_style = command_enabled;
56 start_stop_text_style = text_enabled;
57 open_logs_command_style = command_enabled;
58 open_logs_text_style = text_enabled;
59 stop_all_command_style = command_enabled;
60 stop_all_text_style = text_enabled;
61 }
62 NodesToStart::NotRunning => {}
63 NodesToStart::NotRunningSelected => {
64 remove_command_style = command_enabled;
65 remove_text_style = text_enabled;
66 start_stop_command_style = command_enabled;
67 start_stop_text_style = text_enabled;
68 open_logs_command_style = command_enabled;
69 open_logs_text_style = text_enabled;
70 }
71 }
72
73 let commands = vec![
74 Span::styled("[+] ", command_enabled),
75 Span::styled("Add", text_enabled),
76 Span::styled(" ", Style::default()),
77 Span::styled("[-] ", remove_command_style),
78 Span::styled("Remove", remove_text_style),
79 Span::styled(" ", Style::default()),
80 Span::styled("[Ctrl+S] ", start_stop_command_style),
81 Span::styled("Start/Stop Node", start_stop_text_style),
82 Span::styled(" ", Style::default()),
83 Span::styled("[L] ", open_logs_command_style),
84 Span::styled("Open Logs", open_logs_text_style),
85 ];
86
87 let stop_all = vec![
88 Span::styled("[Ctrl+G] ", start_all_command_style),
89 Span::styled("Start All", start_all_text_style),
90 Span::styled(" ", Style::default()),
91 Span::styled("[Ctrl+X] ", stop_all_command_style),
92 Span::styled("Stop All", stop_all_text_style),
93 ];
94
95 let total_width = (layout[0].width - 1) as usize;
96 let spaces = " ".repeat(total_width.saturating_sub(
97 commands.iter().map(|s| s.width()).sum::<usize>()
98 + stop_all.iter().map(|s| s.width()).sum::<usize>(),
99 ));
100
101 let commands_length = 6 + commands.iter().map(|s| s.width()).sum::<usize>() as u16;
102 let spaces_length = spaces.len().saturating_sub(6) as u16;
103 let stop_all_length = stop_all.iter().map(|s| s.width()).sum::<usize>() as u16;
104
105 let cell1 = Cell::from(Line::from(commands));
106 let cell2 = Cell::from(Line::raw(spaces));
107 let cell3 = Cell::from(Line::from(stop_all));
108 let row = Row::new(vec![cell1, cell2, cell3]);
109
110 let table = Table::new(
111 [row],
112 [
113 Constraint::Length(commands_length),
114 Constraint::Length(spaces_length),
115 Constraint::Length(stop_all_length),
116 ],
117 )
118 .block(
119 Block::default()
120 .borders(Borders::ALL)
121 .border_style(Style::default().fg(EUCALYPTUS))
122 .padding(Padding::horizontal(1)),
123 );
124
125 StatefulWidget::render(table, area, buf, &mut TableState::default());
126 }
127}