mirror of
https://github.com/orhun/systeroid
synced 2024-10-02 21:53:31 +00:00
refactor(tui): show sysctl variables on a table
This commit is contained in:
parent
c94df7a689
commit
6a828cb35b
|
@ -1,6 +1,6 @@
|
|||
use crate::command::Command;
|
||||
use crate::error::Result;
|
||||
use crate::widgets::StatefulList;
|
||||
use crate::widgets::StatefulTable;
|
||||
use std::str::FromStr;
|
||||
use std::time::Instant;
|
||||
use systeroid_core::sysctl::controller::Sysctl;
|
||||
|
@ -19,7 +19,7 @@ pub struct App<'a> {
|
|||
/// Time tracker for measuring the time for clearing the input.
|
||||
pub input_time: Option<Instant>,
|
||||
/// List of sysctl variables.
|
||||
pub variable_list: StatefulList<Parameter>,
|
||||
pub variable_list: StatefulTable<Parameter>,
|
||||
/// Sysctl controller.
|
||||
sysctl: &'a mut Sysctl,
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ impl<'a> App<'a> {
|
|||
running: true,
|
||||
input: None,
|
||||
input_time: None,
|
||||
variable_list: StatefulList::with_items(sysctl.parameters.clone()),
|
||||
variable_list: StatefulTable::with_items(sysctl.parameters.clone()),
|
||||
sysctl,
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ impl<'a> App<'a> {
|
|||
Command::Refresh => {
|
||||
self.input = None;
|
||||
*self.sysctl = Sysctl::init(self.sysctl.config.clone())?;
|
||||
self.variable_list = StatefulList::with_items(self.sysctl.parameters.clone());
|
||||
self.variable_list = StatefulTable::with_items(self.sysctl.parameters.clone());
|
||||
}
|
||||
Command::Exit => {
|
||||
self.running = false;
|
||||
|
|
|
@ -2,8 +2,7 @@ use crate::app::App;
|
|||
use tui::backend::Backend;
|
||||
use tui::layout::{Constraint, Direction, Layout, Rect};
|
||||
use tui::style::{Color, Style};
|
||||
use tui::text::Span;
|
||||
use tui::widgets::{Block, BorderType, Borders, List, ListItem, Paragraph};
|
||||
use tui::widgets::{Block, BorderType, Borders, Cell, Paragraph, Row, Table};
|
||||
use tui::Frame;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
|
@ -11,33 +10,57 @@ use unicode_width::UnicodeWidthStr;
|
|||
pub fn render<B: Backend>(frame: &mut Frame<'_, B>, app: &mut App) {
|
||||
let rect = frame.size();
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Min(rect.height - 3), Constraint::Min(3)].as_ref())
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||
.split(rect);
|
||||
render_variable_list(frame, chunks[0], app);
|
||||
render_input_prompt(frame, chunks[1], rect.height - 2, app);
|
||||
{
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Min(rect.height - 3), Constraint::Min(3)].as_ref())
|
||||
.split(chunks[0]);
|
||||
render_variable_list(frame, chunks[0], app);
|
||||
render_input_prompt(frame, chunks[1], rect.height - 2, app);
|
||||
}
|
||||
}
|
||||
|
||||
/// Renders the list that contains the sysctl variables.
|
||||
fn render_variable_list<B: Backend>(frame: &mut Frame<'_, B>, rect: Rect, app: &mut App) {
|
||||
let max_width = app
|
||||
.variable_list
|
||||
.items
|
||||
.iter()
|
||||
.map(|p| p.name.len())
|
||||
.max_by(|x, y| x.cmp(y))
|
||||
.and_then(|v| u16::try_from(v).ok())
|
||||
.unwrap_or(1);
|
||||
let minimize_rows = rect.width < max_width + 10;
|
||||
let rows = app.variable_list.items.iter().map(|item| {
|
||||
Row::new(if minimize_rows {
|
||||
vec![Cell::from(format!("{} = {}", item.name, item.value))]
|
||||
} else {
|
||||
vec![
|
||||
Cell::from(item.name.clone()),
|
||||
Cell::from(item.value.clone()),
|
||||
]
|
||||
})
|
||||
.height(1)
|
||||
.bottom_margin(1)
|
||||
});
|
||||
frame.render_stateful_widget(
|
||||
List::new(
|
||||
app.variable_list
|
||||
.items
|
||||
.iter()
|
||||
.map(|variable| {
|
||||
ListItem::new(Span::raw(format!("{} = {}", variable.name, variable.value)))
|
||||
})
|
||||
.collect::<Vec<ListItem<'_>>>(),
|
||||
)
|
||||
.block(
|
||||
Block::default()
|
||||
.borders(Borders::all())
|
||||
.border_style(Style::default().fg(Color::White))
|
||||
.border_type(BorderType::Rounded)
|
||||
.style(Style::default().bg(Color::Black)),
|
||||
)
|
||||
.highlight_symbol("> "),
|
||||
Table::new(rows)
|
||||
.block(
|
||||
Block::default()
|
||||
.borders(Borders::all())
|
||||
.border_style(Style::default().fg(Color::White))
|
||||
.border_type(BorderType::Rounded)
|
||||
.style(Style::default().bg(Color::Black)),
|
||||
)
|
||||
.highlight_style(Style::default().bg(Color::White).fg(Color::Black))
|
||||
.widths(&if minimize_rows {
|
||||
[Constraint::Percentage(100), Constraint::Min(0)]
|
||||
} else {
|
||||
[Constraint::Min(max_width), Constraint::Percentage(100)]
|
||||
}),
|
||||
rect,
|
||||
&mut app.variable_list.state,
|
||||
);
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
use tui::widgets::ListState;
|
||||
use tui::widgets::TableState;
|
||||
|
||||
/// List widget with TUI controlled states.
|
||||
#[derive(Debug)]
|
||||
pub struct StatefulList<T> {
|
||||
pub struct StatefulTable<T> {
|
||||
/// List items (states).
|
||||
pub items: Vec<T>,
|
||||
/// State that can be modified by TUI.
|
||||
pub state: ListState,
|
||||
pub state: TableState,
|
||||
}
|
||||
|
||||
impl<T> StatefulList<T> {
|
||||
/// Constructs a new instance of `StatefulList`.
|
||||
pub fn new(items: Vec<T>, mut state: ListState) -> StatefulList<T> {
|
||||
impl<T> StatefulTable<T> {
|
||||
/// Constructs a new instance of `StatefulTable`.
|
||||
pub fn new(items: Vec<T>, mut state: TableState) -> StatefulTable<T> {
|
||||
state.select(Some(0));
|
||||
Self { items, state }
|
||||
}
|
||||
|
||||
/// Construct a new `StatefulList` with given items.
|
||||
pub fn with_items(items: Vec<T>) -> StatefulList<T> {
|
||||
Self::new(items, ListState::default())
|
||||
/// Construct a new `StatefulTable` with given items.
|
||||
pub fn with_items(items: Vec<T>) -> StatefulTable<T> {
|
||||
Self::new(items, TableState::default())
|
||||
}
|
||||
|
||||
/// Returns the selected item.
|
||||
|
@ -62,8 +62,8 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_stateful_list() {
|
||||
let mut list = StatefulList::with_items(vec!["data1", "data2", "data3"]);
|
||||
fn test_stateful_table() {
|
||||
let mut list = StatefulTable::with_items(vec!["data1", "data2", "data3"]);
|
||||
list.state.select(Some(1));
|
||||
assert_eq!(Some(&"data2"), list.selected());
|
||||
list.next();
|
||||
|
|
Loading…
Reference in a new issue