feat(tui): support filtering parameters by section

This commit is contained in:
Orhun Parmaksız 2022-01-24 19:53:12 +03:00
parent de08836906
commit 949b7ec0b8
No known key found for this signature in database
GPG key ID: F83424824B3E4B90
4 changed files with 81 additions and 0 deletions

View file

@ -8,6 +8,7 @@ use std::str::FromStr;
use std::time::Instant;
use systeroid_core::sysctl::controller::Sysctl;
use systeroid_core::sysctl::parameter::Parameter;
use systeroid_core::sysctl::section::Section;
use unicode_width::UnicodeWidthStr;
/// Duration of prompt messages.
@ -31,6 +32,8 @@ pub struct App<'a> {
pub options: Option<StatefulTable<&'a str>>,
/// List of sysctl parameters.
pub parameter_list: StatefulTable<Parameter>,
/// List of sysctl sections.
pub section_list: StatefulTable<String>,
#[cfg(feature = "clipboard")]
/// Clipboard context.
clipboard: Option<Box<dyn ClipboardProvider>>,
@ -50,6 +53,14 @@ impl<'a> App<'a> {
docs_scroll_amount: 0,
options: None,
parameter_list: StatefulTable::default(),
section_list: StatefulTable::with_items({
let mut sections = Section::variants()
.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>();
sections.insert(0, String::from("all"));
sections
}),
#[cfg(feature = "clipboard")]
clipboard: None,
sysctl,
@ -233,6 +244,30 @@ impl<'a> App<'a> {
.checked_add(amount.into())
.unwrap_or(self.docs_scroll_amount);
}
Command::Scroll(ScrollArea::Section, direction, _) => {
match direction {
Direction::Up => self.section_list.previous(),
_ => self.section_list.next(),
}
if let Some(section) = self
.section_list
.selected()
.map(|v| Section::from(v.to_string()))
{
self.parameter_list.items = self
.sysctl
.parameters
.clone()
.into_iter()
.filter(|param| section == Section::Unknown || param.section == section)
.collect();
if self.parameter_list.items.is_empty() {
self.parameter_list.state.select(None);
} else {
self.parameter_list.state.select(Some(0));
}
}
}
Command::Scroll(_, _, _) => {}
Command::EnableSearch => {
if self.input_time.is_some() {

View file

@ -86,6 +86,8 @@ impl Command {
Key::Char('b') => Command::Scroll(ScrollArea::List, Direction::Bottom, 0),
Key::Left => Command::Scroll(ScrollArea::Documentation, Direction::Up, 1),
Key::Right => Command::Scroll(ScrollArea::Documentation, Direction::Down, 1),
Key::Char('`') => Command::Scroll(ScrollArea::Section, Direction::Up, 1),
Key::Char('\t') => Command::Scroll(ScrollArea::Section, Direction::Down, 1),
Key::Char(':') => Command::UpdateInput(' '),
Key::Char('/') => Command::EnableSearch,
Key::Char('\n') => Command::Select,

View file

@ -59,4 +59,5 @@ generate_option!(
ScrollArea,
List => "list",
Documentation => "documentation",
Section => "section",
);

View file

@ -106,6 +106,9 @@ fn render_parameter_list<B: Backend>(frame: &mut Frame<'_, B>, rect: Rect, app:
app.parameter_list.items.len()
),
);
if let Some(section) = app.section_list.selected() {
render_section_text(frame, rect, section);
}
if let Some(options) = app.options.as_mut() {
render_options_menu(frame, rect, options);
}
@ -159,6 +162,46 @@ fn render_selection_text<B: Backend>(frame: &mut Frame<'_, B>, rect: Rect, selec
}
}
/// Renders the text for displaying the parameter section.
fn render_section_text<B: Backend>(frame: &mut Frame<'_, B>, rect: Rect, section: &str) {
let section = format!("|{}|", section);
let text_width: u16 = section.width().try_into().unwrap_or(1);
let vertical_area = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Min(1),
Constraint::Min(rect.height.checked_sub(1).unwrap_or(rect.height)),
]
.as_ref(),
)
.split(rect);
let area = Layout::default()
.direction(Direction::Horizontal)
.constraints(
[
Constraint::Min(
rect.width
.checked_sub(text_width + 2)
.unwrap_or(rect.height),
),
Constraint::Min(text_width),
Constraint::Min(1),
]
.as_ref(),
)
.split(vertical_area[0]);
frame.render_widget(Clear, area[1]);
frame.render_widget(
Paragraph::new(Span::styled(section, Style::default().fg(Color::White))).block(
Block::default()
.borders(Borders::NONE)
.style(Style::default().bg(Color::Black)),
),
area[1],
);
}
/// Renders a list as a popup for showing options.
fn render_options_menu<B: Backend>(
frame: &mut Frame<'_, B>,