Added a third panel to display current projecct information and tool
information.
This commit is contained in:
+114
-5
@@ -5,6 +5,7 @@ use crossterm::{
|
||||
execute,
|
||||
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
|
||||
};
|
||||
use iced::alignment::Vertical::Bottom;
|
||||
use ratatui::{
|
||||
prelude::*,
|
||||
widgets::{Block, Borders, List, ListItem, ListState, Paragraph},
|
||||
@@ -82,7 +83,11 @@ pub fn run_tui(
|
||||
.split(f.area());
|
||||
let top_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Percentage(30), Constraint::Percentage(70)])
|
||||
.constraints([
|
||||
Constraint::Percentage(20),
|
||||
Constraint::Percentage(45),
|
||||
Constraint::Percentage(35),
|
||||
])
|
||||
.split(main_chunks[0]);
|
||||
let projects: Vec<ListItem> = state
|
||||
.projects
|
||||
@@ -103,6 +108,86 @@ pub fn run_tui(
|
||||
)
|
||||
.highlight_symbol(">> ");
|
||||
f.render_stateful_widget(projects_list, top_chunks[0], &mut project_list_state);
|
||||
let mut info_lines: Vec<Line> = Vec::new();
|
||||
let project = state.projects[state.selected_project].clone();
|
||||
info_lines.push(Line::from(Span::styled(
|
||||
"--- PROJECT INFORMATION ---",
|
||||
Style::default().fg(Color::Green),
|
||||
)));
|
||||
info_lines.push(Line::from(format!("ORG: {}", project.org_name)));
|
||||
info_lines.push(Line::from(format!("NAME: {}", project.name)));
|
||||
info_lines.push(Line::from(format!("NOTES: {}", project.notes.display())));
|
||||
info_lines.push(Line::from(format!("Files: {}", project.files.display())));
|
||||
if let Some(db) = project.db {
|
||||
info_lines.push(Line::from(format!("DISTROBOX: {}", db.name)));
|
||||
}
|
||||
if project.current {
|
||||
info_lines.push(Line::from("STATUS: CURRENT"));
|
||||
} else {
|
||||
info_lines.push(Line::from("STATUS: UPCOMING"));
|
||||
}
|
||||
if !project.hosts.is_empty() {
|
||||
info_lines.push(Line::from(Span::styled(
|
||||
"--- PROJECT HOST INFORMATION ---",
|
||||
Style::default().fg(Color::Green),
|
||||
)));
|
||||
for host in &project.hosts {
|
||||
info_lines.push(Line::from(format!("- {}:{}", host.hostname, host.ip)));
|
||||
info_lines.push(Line::from(format!(" - PWNED: {}", host.pwned)));
|
||||
info_lines.push(Line::from(format!(
|
||||
" - CONTROL PORT: {}",
|
||||
host.control_port
|
||||
)));
|
||||
if !host.open_ports.is_empty() {
|
||||
info_lines.push(Line::from(format!(" - PORTS:")));
|
||||
for port in &host.open_ports {
|
||||
info_lines.push(Line::from(format!(" - {}", port)));
|
||||
}
|
||||
}
|
||||
if !host.users.is_empty() {
|
||||
info_lines.push(Line::from(format!(" - USERS:")));
|
||||
for user in &host.users {
|
||||
info_lines.push(Line::from(format!(
|
||||
" - {} - PWNED: {}",
|
||||
user.name, user.compromised
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let spacer = format!("{}", "+".repeat(top_chunks[2].width as usize - 2));
|
||||
info_lines.push(Line::from(Span::styled(
|
||||
&spacer,
|
||||
Style::default().fg(Color::Green),
|
||||
)));
|
||||
info_lines.push(Line::from(Span::styled(
|
||||
"--- Tool Information ---",
|
||||
Style::default().fg(Color::Green),
|
||||
)));
|
||||
info_lines.push(Line::from(format!(
|
||||
"CONFIG FILE: {}",
|
||||
state.config_file.display()
|
||||
)));
|
||||
for setting in state.config.keys() {
|
||||
info_lines.push(Line::from(format!(
|
||||
"{}: {}",
|
||||
setting.to_uppercase(),
|
||||
state.config.get(setting).unwrap()
|
||||
)));
|
||||
}
|
||||
let info_area_height = top_chunks[1].height.saturating_sub(2) as usize;
|
||||
if state.info_scroll as usize > info_lines.len().saturating_sub(info_area_height) {
|
||||
state.info_scroll = info_lines.len().saturating_sub(info_area_height) as u16;
|
||||
}
|
||||
let info_paragraph = Paragraph::new(info_lines)
|
||||
.block(
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.title("Selected Project Information"),
|
||||
)
|
||||
.scroll((state.info_scroll, 0))
|
||||
.wrap(ratatui::widgets::Wrap { trim: false });
|
||||
f.render_widget(info_paragraph, top_chunks[2]);
|
||||
let output_lines: Vec<Line> = state
|
||||
.output
|
||||
.iter()
|
||||
@@ -341,10 +426,34 @@ pub fn run_tui(
|
||||
}
|
||||
}
|
||||
AppEvent::Mouse(mouse) => {
|
||||
if mouse.kind == crossterm::event::MouseEventKind::ScrollUp {
|
||||
state.output_scroll = state.output_scroll.saturating_sub(1);
|
||||
} else if mouse.kind == crossterm::event::MouseEventKind::ScrollDown {
|
||||
state.output_scroll = state.output_scroll.saturating_add(1);
|
||||
if let Ok(size) = terminal.size() {
|
||||
let main_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Min(0), Constraint::Max(3)])
|
||||
.split(ratatui::layout::Rect::from(size));
|
||||
|
||||
let top_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([
|
||||
Constraint::Percentage(20),
|
||||
Constraint::Percentage(45),
|
||||
Constraint::Percentage(35),
|
||||
])
|
||||
.split(main_chunks[0]);
|
||||
let left_side_cutoff = top_chunks[0].width + top_chunks[1].width;
|
||||
if mouse.column < left_side_cutoff {
|
||||
if mouse.kind == crossterm::event::MouseEventKind::ScrollUp {
|
||||
state.output_scroll = state.output_scroll.saturating_sub(1);
|
||||
} else if mouse.kind == crossterm::event::MouseEventKind::ScrollDown {
|
||||
state.output_scroll = state.output_scroll.saturating_add(1);
|
||||
}
|
||||
} else {
|
||||
if mouse.kind == crossterm::event::MouseEventKind::ScrollUp {
|
||||
state.info_scroll = state.info_scroll.saturating_sub(1);
|
||||
} else if mouse.kind == crossterm::event::MouseEventKind::ScrollDown {
|
||||
state.info_scroll = state.info_scroll.saturating_add(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user