mirror of
https://github.com/orhun/systeroid
synced 2024-07-23 19:34:58 +00:00
feat(tui): support filtering parameters by section
This commit is contained in:
parent
de08836906
commit
949b7ec0b8
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -59,4 +59,5 @@ generate_option!(
|
|||
ScrollArea,
|
||||
List => "list",
|
||||
Documentation => "documentation",
|
||||
Section => "section",
|
||||
);
|
||||
|
|
|
@ -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>,
|
||||
|
|
Loading…
Reference in a new issue