node_launchpad/components/
footer.rs

1// Copyright 2024 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
4// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
5// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
6// KIND, either express or implied. Please review the Licences for the specific language governing
7// permissions and limitations relating to use of the SAFE Network Software.
8
9use 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}