node_launchpad/components/popup/
upgrade_nodes.rs1use super::super::utils::centered_rect_fixed;
10use super::super::Component;
11use crate::{
12 action::{Action, OptionsActions},
13 components::status,
14 mode::{InputMode, Scene},
15 style::{clear_area, EUCALYPTUS, GHOST_WHITE, LIGHT_PERIWINKLE, VIVID_SKY_BLUE},
16};
17use color_eyre::Result;
18use crossterm::event::{KeyCode, KeyEvent};
19use ratatui::{prelude::*, widgets::*};
20
21pub struct UpgradeNodesPopUp {
22 nodes_to_start: usize,
23 active: bool,
25}
26
27impl UpgradeNodesPopUp {
28 pub fn new(nodes_to_start: usize) -> Self {
29 Self {
30 nodes_to_start,
31 active: false,
32 }
33 }
34}
35
36impl Component for UpgradeNodesPopUp {
37 fn handle_key_events(&mut self, key: KeyEvent) -> Result<Vec<Action>> {
38 if !self.active {
39 return Ok(vec![]);
40 }
41 let send_back = match key.code {
43 KeyCode::Enter => {
44 debug!("Got Enter, Upgrading nodes...");
45 vec![
46 Action::OptionsActions(OptionsActions::UpdateNodes),
47 Action::SwitchScene(Scene::Status),
48 ]
49 }
50 KeyCode::Esc => {
51 debug!("Got Esc, Not upgrading nodes.");
52 vec![Action::SwitchScene(Scene::Options)]
53 }
54 _ => vec![],
55 };
56 Ok(send_back)
57 }
58
59 fn update(&mut self, action: Action) -> Result<Option<Action>> {
60 let send_back = match action {
61 Action::SwitchScene(scene) => match scene {
62 Scene::UpgradeNodesPopUp => {
63 self.active = true;
64 Some(Action::SwitchInputMode(InputMode::Entry))
65 }
66 _ => {
67 self.active = false;
68 None
69 }
70 },
71 Action::StoreNodesToStart(ref nodes_to_start) => {
72 self.nodes_to_start = *nodes_to_start;
73 None
74 }
75 _ => None,
76 };
77 Ok(send_back)
78 }
79
80 fn draw(&mut self, f: &mut crate::tui::Frame<'_>, area: Rect) -> Result<()> {
81 if !self.active {
82 return Ok(());
83 }
84
85 let layer_zero = centered_rect_fixed(52, 15, area);
86
87 let layer_one = Layout::new(
88 Direction::Vertical,
89 [
90 Constraint::Length(2),
92 Constraint::Min(1),
94 Constraint::Length(1),
96 ],
97 )
98 .split(layer_zero);
99
100 let pop_up_border = Paragraph::new("").block(
102 Block::default()
103 .borders(Borders::ALL)
104 .title(" Upgrade all nodes ")
105 .bold()
106 .title_style(Style::new().fg(VIVID_SKY_BLUE))
107 .padding(Padding::uniform(2))
108 .border_style(Style::new().fg(VIVID_SKY_BLUE)),
109 );
110 clear_area(f, layer_zero);
111
112 let layer_two = Layout::new(
114 Direction::Vertical,
115 [
116 Constraint::Length(9),
118 Constraint::Length(4),
120 Constraint::Length(1),
122 ],
123 )
124 .split(layer_one[1]);
125
126 let text = Paragraph::new(vec![
127 Line::from(Span::styled("\n\n", Style::default())),
128 Line::from(vec![
129 Span::styled("This will ", Style::default().fg(LIGHT_PERIWINKLE)),
130 Span::styled(
131 "stop and upgrade all nodes. ",
132 Style::default().fg(GHOST_WHITE),
133 ),
134 ]),
135 Line::from(Span::styled(
136 "No data will be lost.",
137 Style::default().fg(LIGHT_PERIWINKLE),
138 )),
139 Line::from(Span::styled(
140 format!(
141 "Upgrade time ~ {:.1?} mins ({:?} nodes * {:?} secs)",
142 self.nodes_to_start * (status::FIXED_INTERVAL / 1_000) as usize / 60,
143 self.nodes_to_start,
144 status::FIXED_INTERVAL / 1_000,
145 ),
146 Style::default().fg(LIGHT_PERIWINKLE),
147 )),
148 Line::from(Span::styled("\n\n", Style::default())),
149 Line::from(vec![
150 Span::styled("You’ll need to ", Style::default().fg(LIGHT_PERIWINKLE)),
151 Span::styled("Start ", Style::default().fg(GHOST_WHITE)),
152 Span::styled(
153 "them again afterwards.",
154 Style::default().fg(LIGHT_PERIWINKLE),
155 ),
156 ]),
157 Line::from(Span::styled(
158 "Are you sure you want to continue?",
159 Style::default(),
160 )),
161 ])
162 .block(Block::default().padding(Padding::horizontal(2)))
163 .alignment(Alignment::Center)
164 .wrap(Wrap { trim: true });
165
166 f.render_widget(text, layer_two[0]);
167
168 let dash = Block::new()
169 .borders(Borders::BOTTOM)
170 .border_style(Style::new().fg(GHOST_WHITE));
171 f.render_widget(dash, layer_two[1]);
172
173 let buttons_layer =
174 Layout::horizontal(vec![Constraint::Percentage(45), Constraint::Percentage(55)])
175 .split(layer_two[2]);
176
177 let button_no = Line::from(vec![Span::styled(
178 " No, Cancel [Esc]",
179 Style::default().fg(LIGHT_PERIWINKLE),
180 )]);
181 f.render_widget(button_no, buttons_layer[0]);
182
183 let button_yes = Paragraph::new(Line::from(vec![Span::styled(
184 "Yes, Upgrade [Enter] ",
185 Style::default().fg(EUCALYPTUS),
186 )]))
187 .alignment(Alignment::Right);
188 f.render_widget(button_yes, buttons_layer[1]);
189 f.render_widget(pop_up_border, layer_zero);
190
191 Ok(())
192 }
193}