UI evolution

** Re-evaluating need for users to edit list of hosts at runtime **
This commit is contained in:
Trevor Merritt 2025-05-01 14:54:26 -04:00
parent 141d0ee899
commit 17780c02d5

View File

@ -1,19 +1,22 @@
use crate::{duration_to_string};
use crate::duration_to_string;
use crate::target_state::TargetState;
use crate::tui::ratatui_app::RatatuiApp;
use color_eyre::Result;
use crossterm::event;
use crossterm::event::{Event, KeyCode, KeyEventKind};
use ratatui::prelude::*;
use ratatui::widgets::{Block, Borders, Cell, Clear, List, ListItem, Paragraph, Row, Table, TableState};
use ratatui::Frame;
use std::time::{Duration, SystemTime};
use ratatui::layout::Flex;
use crate::tui::ratatui_app::RatatuiApp;
use ratatui::prelude::*;
use ratatui::widgets::{
Block, Borders, Cell, Clear, List, ListItem, Paragraph, Row, Table, TableState,
};
use std::time::{Duration, SystemTime};
pub struct RatatuiMonitoringMode {}
impl RatatuiMonitoringMode {
fn render_hosts_list(frame: &mut Frame, state: &mut RatatuiApp, area: Rect) {
/// Headers
// Headers
let headers = ["Host", "RTT", "Last Change"]
.iter()
.map(|h| Cell::from(*h));
@ -21,39 +24,52 @@ impl RatatuiMonitoringMode {
.style(Style::default().fg(Color::Yellow).bold())
.bottom_margin(1);
/// Rows
// Rows
let mut rows = vec![];
for (_, current) in state.state.iter() {
let name_field = format!("{:<40}", format!("{} ({})", current.name.clone(), current.target.clone()));
let name_field = format!(
"{:<40}",
format!("{} ({})", current.name.clone(), current.target.clone())
);
let name_style = if current.alive { Style::default().fg(Color::Green) } else { Style::default().fg(Color::Red) };
let name_style = if current.alive {
Style::default().fg(Color::Green)
} else {
Style::default().fg(Color::Red)
};
rows.push(Row::new(vec![
Cell::from(name_field).style(name_style),
Cell::from(current.last_rtt.to_string()),
Cell::from(
format!("{} ago.",
Cell::from(format!(
"{} ago.",
duration_to_string(
SystemTime::now()
.duration_since(current.last_alive_change)
.unwrap()
)
)
)
)),
]));
}
/// Table Builder
let table = Table::new(rows, vec![Constraint::Min(30), Constraint::Min(6), Constraint::Min(5), Constraint::Min(30)])
// Table Builder
let table = Table::new(rows, vec![
Constraint::Min(30),
Constraint::Min(6),
Constraint::Min(5),
Constraint::Min(30),
])
.header(header)
.block(Block::default()
.block(
Block::default()
.title(Line::from(format!("PP v{}", env!("CARGO_PKG_VERSION"))))
.borders(Borders::ALL))
.borders(Borders::ALL),
)
.widths(&[
Constraint::Fill(2), // Host
Constraint::Min(4), // RTT
Constraint::Min(30) // TIme Since
Constraint::Min(30), // TIme Since
])
.row_highlight_style(
Style::default()
@ -64,7 +80,7 @@ impl RatatuiMonitoringMode {
.highlight_symbol(">> ");
// frame.render_widget(table, layouts[0]);
frame.render_stateful_widget(table, area, &mut make_state(state.selected_host));
frame.render_stateful_widget(table, area, &mut make_hosts_list_state(state.selected_host));
}
fn render_logs(frame: &mut Frame, state: &mut RatatuiApp, logs_layout: Rect) {
@ -75,20 +91,23 @@ impl RatatuiMonitoringMode {
.collect();
// Log
frame.render_widget(List::new(list_items)
.block(Block::default()
.title("Logs")
.borders(Borders::ALL))
frame.render_widget(
List::new(list_items)
.block(Block::default().title("Logs").borders(Borders::ALL))
.highlight_style(
Style::default()
.fg(Color::Yellow)
.add_modifier(Modifier::BOLD),
), logs_layout);
),
logs_layout,
);
}
fn render_footer_block(frame: &mut Frame, footer_layout: Rect) {
frame.render_widget(
Paragraph::new("Press <ESC> or q to exit | Press d to delete host | Press a to add host")
Paragraph::new(
"Press <ESC> or q to exit | Press d to delete host | Press a to add host",
)
.block(Block::bordered())
.centered(),
footer_layout,
@ -115,20 +134,27 @@ impl RatatuiMonitoringMode {
fn add_popup(frame: &mut Frame, state: &RatatuiApp) {
if state.showing_add_popup {
let area = RatatuiMonitoringMode::popup_area(frame.area(), 60, 20);
let area = RatatuiMonitoringMode::popup_area(frame.area(), 10, 40);
frame.render_widget(Clear, area);
frame.render_widget(Block::bordered().title("Add Host"), area);
frame.render_widget(
Paragraph::new(format!("Host Address : {}", state.add_host_name))
.block(Block::bordered().title("Label")),
area,
);
}
}
fn exit_popup(frame: &mut Frame, state: &RatatuiApp) {
if state.trying_to_exit {
let area = RatatuiMonitoringMode::popup_area(frame.area(), 60, 20);
let area = RatatuiMonitoringMode::popup_area(frame.area(), 5, 20);
frame.render_widget(Clear, area);
frame.render_widget(Paragraph::new("Are you sure? (Y/N)")
.block(Block::bordered().title("Exit")), area);
frame.render_widget(
Paragraph::new("Are you sure? (Y/N)").block(Block::bordered().title("Exit")),
area,
);
}
}
@ -163,13 +189,23 @@ impl RatatuiMonitoringMode {
app.showing_add_popup = false;
}
KeyCode::Backspace => {
app.add_host_name.remove(app.add_host_name.len());
app.add_host_name.remove(app.add_host_name.len() - 1);
}
KeyCode::Enter => {
dbg!("SAVE THE VALUE TO A NEW TARGETSTATE");
app.state.insert(app.add_host_name.clone(), TargetState {
name: app.add_host_name.clone(),
..Default::default()
});
}
KeyCode::Down => {
dbg!("Move down to next field");
}
KeyCode::Up => {
dbg!("Move up to previous field");
}
_ => {
app.add_host_name = format!("{}{}", app.add_host_name, key);
//dbg!(format!("ADD_HOST_NAME: {}", app.add_host_name.clone()));
}
}
}
@ -252,7 +288,7 @@ impl RatatuiMonitoringMode {
}
}
pub fn make_state(selected: usize) -> TableState {
pub fn make_hosts_list_state(selected: usize) -> TableState {
let mut state = TableState::default();
state.select(Some(selected));
state