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
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}