node_launchpad/components/popup/
upgrade_nodes.rsuse super::super::utils::centered_rect_fixed;
use super::super::Component;
use crate::{
action::{Action, OptionsActions},
components::status,
mode::{InputMode, Scene},
style::{clear_area, EUCALYPTUS, GHOST_WHITE, LIGHT_PERIWINKLE, VIVID_SKY_BLUE},
};
use color_eyre::Result;
use crossterm::event::{KeyCode, KeyEvent};
use ratatui::{prelude::*, widgets::*};
pub struct UpgradeNodesPopUp {
nodes_to_start: usize,
active: bool,
}
impl UpgradeNodesPopUp {
pub fn new(nodes_to_start: usize) -> Self {
Self {
nodes_to_start,
active: false,
}
}
}
impl Component for UpgradeNodesPopUp {
fn handle_key_events(&mut self, key: KeyEvent) -> Result<Vec<Action>> {
if !self.active {
return Ok(vec![]);
}
let send_back = match key.code {
KeyCode::Enter => {
debug!("Got Enter, Upgrading nodes...");
vec![
Action::OptionsActions(OptionsActions::UpdateNodes),
Action::SwitchScene(Scene::Status),
]
}
KeyCode::Esc => {
debug!("Got Esc, Not upgrading nodes.");
vec![Action::SwitchScene(Scene::Options)]
}
_ => vec![],
};
Ok(send_back)
}
fn update(&mut self, action: Action) -> Result<Option<Action>> {
let send_back = match action {
Action::SwitchScene(scene) => match scene {
Scene::UpgradeNodesPopUp => {
self.active = true;
Some(Action::SwitchInputMode(InputMode::Entry))
}
_ => {
self.active = false;
None
}
},
Action::StoreNodesToStart(ref nodes_to_start) => {
self.nodes_to_start = *nodes_to_start;
None
}
_ => None,
};
Ok(send_back)
}
fn draw(&mut self, f: &mut crate::tui::Frame<'_>, area: Rect) -> Result<()> {
if !self.active {
return Ok(());
}
let layer_zero = centered_rect_fixed(52, 15, area);
let layer_one = Layout::new(
Direction::Vertical,
[
Constraint::Length(2),
Constraint::Min(1),
Constraint::Length(1),
],
)
.split(layer_zero);
let pop_up_border = Paragraph::new("").block(
Block::default()
.borders(Borders::ALL)
.title(" Upgrade all nodes ")
.bold()
.title_style(Style::new().fg(VIVID_SKY_BLUE))
.padding(Padding::uniform(2))
.border_style(Style::new().fg(VIVID_SKY_BLUE)),
);
clear_area(f, layer_zero);
let layer_two = Layout::new(
Direction::Vertical,
[
Constraint::Length(9),
Constraint::Length(4),
Constraint::Length(1),
],
)
.split(layer_one[1]);
let text = Paragraph::new(vec![
Line::from(Span::styled("\n\n", Style::default())),
Line::from(vec![
Span::styled("This will ", Style::default().fg(LIGHT_PERIWINKLE)),
Span::styled(
"stop and upgrade all nodes. ",
Style::default().fg(GHOST_WHITE),
),
]),
Line::from(Span::styled(
"No data will be lost.",
Style::default().fg(LIGHT_PERIWINKLE),
)),
Line::from(Span::styled(
format!(
"Upgrade time ~ {:.1?} mins ({:?} nodes * {:?} secs)",
self.nodes_to_start * (status::FIXED_INTERVAL / 1_000) as usize / 60,
self.nodes_to_start,
status::FIXED_INTERVAL / 1_000,
),
Style::default().fg(LIGHT_PERIWINKLE),
)),
Line::from(Span::styled("\n\n", Style::default())),
Line::from(vec![
Span::styled("You’ll need to ", Style::default().fg(LIGHT_PERIWINKLE)),
Span::styled("Start ", Style::default().fg(GHOST_WHITE)),
Span::styled(
"them again afterwards.",
Style::default().fg(LIGHT_PERIWINKLE),
),
]),
Line::from(Span::styled(
"Are you sure you want to continue?",
Style::default(),
)),
])
.block(Block::default().padding(Padding::horizontal(2)))
.alignment(Alignment::Center)
.wrap(Wrap { trim: true });
f.render_widget(text, layer_two[0]);
let dash = Block::new()
.borders(Borders::BOTTOM)
.border_style(Style::new().fg(GHOST_WHITE));
f.render_widget(dash, layer_two[1]);
let buttons_layer =
Layout::horizontal(vec![Constraint::Percentage(45), Constraint::Percentage(55)])
.split(layer_two[2]);
let button_no = Line::from(vec![Span::styled(
" No, Cancel [Esc]",
Style::default().fg(LIGHT_PERIWINKLE),
)]);
f.render_widget(button_no, buttons_layer[0]);
let button_yes = Paragraph::new(Line::from(vec![Span::styled(
"Yes, Upgrade [Enter] ",
Style::default().fg(EUCALYPTUS),
)]))
.alignment(Alignment::Right);
f.render_widget(button_yes, buttons_layer[1]);
f.render_widget(pop_up_border, layer_zero);
Ok(())
}
}