mirror of
https://codeberg.org/icewind/logsmash.git
synced 2026-06-03 18:14:11 +02:00
plain log list
This commit is contained in:
parent
a07deebbd6
commit
59b55cbca7
4 changed files with 102 additions and 5 deletions
|
|
@ -30,6 +30,7 @@ pub fn footer(app: &App, page: UiPage) -> Table {
|
||||||
fn help(page: UiPage) -> &'static str {
|
fn help(page: UiPage) -> &'static str {
|
||||||
match page {
|
match page {
|
||||||
UiPage::MatchList => "«Q» Exit - «Enter» Select",
|
UiPage::MatchList => "«Q» Exit - «Enter» Select",
|
||||||
UiPage::Match => "«Q» Exit - «Esc» Back",
|
UiPage::Match => "«Q» Exit - «Enter» Select - «Esc» Back",
|
||||||
|
UiPage::Logs => "«Q» Exit - «Esc» Back",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use crate::error::UiError;
|
||||||
use crate::ui::footer::footer;
|
use crate::ui::footer::footer;
|
||||||
use crate::ui::histogram::UiHistogram;
|
use crate::ui::histogram::UiHistogram;
|
||||||
use crate::ui::match_list::match_list;
|
use crate::ui::match_list::match_list;
|
||||||
|
use crate::ui::raw_logs::raw_logs;
|
||||||
use crate::ui::single_match::grouped_lines;
|
use crate::ui::single_match::grouped_lines;
|
||||||
use crate::ui::state::{UiEvent, UiState};
|
use crate::ui::state::{UiEvent, UiState};
|
||||||
use ratatui::crossterm::event::{Event, KeyCode, KeyModifiers};
|
use ratatui::crossterm::event::{Event, KeyCode, KeyModifiers};
|
||||||
|
|
@ -18,6 +19,7 @@ use std::io::stdout;
|
||||||
mod footer;
|
mod footer;
|
||||||
mod histogram;
|
mod histogram;
|
||||||
mod match_list;
|
mod match_list;
|
||||||
|
mod raw_logs;
|
||||||
mod single_match;
|
mod single_match;
|
||||||
mod state;
|
mod state;
|
||||||
pub mod style;
|
pub mod style;
|
||||||
|
|
@ -101,5 +103,15 @@ fn ui(frame: &mut Frame, app: &App, state: &mut UiState) {
|
||||||
frame.render_stateful_widget(grouped_lines(app, result), layout[1], table_state);
|
frame.render_stateful_widget(grouped_lines(app, result), layout[1], table_state);
|
||||||
frame.render_widget(footer(app, page), layout[2]);
|
frame.render_widget(footer(app, page), layout[2]);
|
||||||
}
|
}
|
||||||
|
UiState::Logs {
|
||||||
|
lines, table_state, ..
|
||||||
|
} => {
|
||||||
|
frame.render_stateful_widget(
|
||||||
|
raw_logs(app, lines),
|
||||||
|
layout[0].union(layout[1]),
|
||||||
|
table_state,
|
||||||
|
);
|
||||||
|
frame.render_widget(footer(app, page), layout[2]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
43
src/ui/raw_logs.rs
Normal file
43
src/ui/raw_logs.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
use crate::app::App;
|
||||||
|
use crate::logline::LogLine;
|
||||||
|
use crate::ui::style::{TABLE_HEADER_STYLE, TABLE_SELECTED_STYLE, TIME_FORMAT};
|
||||||
|
use ratatui::layout::{Alignment, Constraint};
|
||||||
|
use ratatui::text::Text;
|
||||||
|
use ratatui::widgets::{Cell, HighlightSpacing, Row, Table};
|
||||||
|
use time::format_description::well_known::Iso8601;
|
||||||
|
|
||||||
|
pub fn raw_logs(app: &App, lines: &[usize]) -> Table<'static> {
|
||||||
|
let lines = lines.iter().copied().map(|i| &app.lines[i]);
|
||||||
|
let header = [
|
||||||
|
Text::from("Level"),
|
||||||
|
Text::from("App"),
|
||||||
|
Text::from("Message"),
|
||||||
|
Text::from("Time").alignment(Alignment::Right),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.map(Cell::from)
|
||||||
|
.collect::<Row>()
|
||||||
|
.style(TABLE_HEADER_STYLE)
|
||||||
|
.height(1);
|
||||||
|
|
||||||
|
let widths = [
|
||||||
|
Constraint::Min(10),
|
||||||
|
Constraint::Min(20),
|
||||||
|
Constraint::Percentage(100),
|
||||||
|
Constraint::Length(27),
|
||||||
|
];
|
||||||
|
let table = Table::new(lines.map(|line| log_row(line)), widths)
|
||||||
|
.header(header)
|
||||||
|
.highlight_style(TABLE_SELECTED_STYLE)
|
||||||
|
.highlight_spacing(HighlightSpacing::Always);
|
||||||
|
table
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_row(line: &LogLine) -> Row<'static> {
|
||||||
|
Row::new([
|
||||||
|
Text::from(line.level.as_str().to_string()),
|
||||||
|
Text::from(line.app.to_string()),
|
||||||
|
Text::from(line.message.clone()),
|
||||||
|
Text::from(line.time.format(&Iso8601::<TIME_FORMAT>).unwrap()).alignment(Alignment::Right),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,11 @@ pub enum UiState<'a> {
|
||||||
table_state: TableState,
|
table_state: TableState,
|
||||||
previous: Box<UiState<'a>>,
|
previous: Box<UiState<'a>>,
|
||||||
},
|
},
|
||||||
|
Logs {
|
||||||
|
lines: &'a [usize],
|
||||||
|
table_state: TableState,
|
||||||
|
previous: Box<UiState<'a>>,
|
||||||
|
},
|
||||||
Quit,
|
Quit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,6 +33,7 @@ impl<'a> UiState<'a> {
|
||||||
match self {
|
match self {
|
||||||
UiState::Quit | UiState::MatchList { .. } => UiPage::MatchList,
|
UiState::Quit | UiState::MatchList { .. } => UiPage::MatchList,
|
||||||
UiState::Match { .. } => UiPage::Match,
|
UiState::Match { .. } => UiPage::Match,
|
||||||
|
UiState::Logs { .. } => UiPage::Logs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,6 +41,7 @@ impl<'a> UiState<'a> {
|
||||||
match self {
|
match self {
|
||||||
UiState::MatchList { table_state } => Some(table_state),
|
UiState::MatchList { table_state } => Some(table_state),
|
||||||
UiState::Match { table_state, .. } => Some(table_state),
|
UiState::Match { table_state, .. } => Some(table_state),
|
||||||
|
UiState::Logs { table_state, .. } => Some(table_state),
|
||||||
UiState::Quit => None,
|
UiState::Quit => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -43,6 +50,7 @@ impl<'a> UiState<'a> {
|
||||||
match self {
|
match self {
|
||||||
UiState::MatchList { .. } => app.match_lines(),
|
UiState::MatchList { .. } => app.match_lines(),
|
||||||
UiState::Match { result, .. } => result.grouped.len(),
|
UiState::Match { result, .. } => result.grouped.len(),
|
||||||
|
UiState::Logs { lines, .. } => lines.len(),
|
||||||
UiState::Quit => 0,
|
UiState::Quit => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,8 +74,13 @@ impl<'a> UiState<'a> {
|
||||||
}
|
}
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
(mut prev @ UiState::MatchList { .. }, UiEvent::Select) => {
|
(
|
||||||
let selected = prev.table_state().unwrap().selected().unwrap_or(0);
|
UiState::MatchList {
|
||||||
|
table_state: prev_state,
|
||||||
|
},
|
||||||
|
UiEvent::Select,
|
||||||
|
) => {
|
||||||
|
let selected = prev_state.selected().unwrap_or(0);
|
||||||
let mut table_state = TableState::default();
|
let mut table_state = TableState::default();
|
||||||
table_state.select(Some(0));
|
table_state.select(Some(0));
|
||||||
|
|
||||||
|
|
@ -81,10 +94,37 @@ impl<'a> UiState<'a> {
|
||||||
UiState::Match {
|
UiState::Match {
|
||||||
result,
|
result,
|
||||||
table_state,
|
table_state,
|
||||||
previous: Box::new(prev),
|
previous: Box::new(UiState::MatchList {
|
||||||
|
table_state: prev_state,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(UiState::Match { previous, .. }, UiEvent::Back) => *previous,
|
(
|
||||||
|
UiState::Match {
|
||||||
|
table_state: prev_state,
|
||||||
|
previous,
|
||||||
|
result,
|
||||||
|
},
|
||||||
|
UiEvent::Select,
|
||||||
|
) => {
|
||||||
|
let selected = prev_state.selected().unwrap_or(0);
|
||||||
|
let mut table_state = TableState::default();
|
||||||
|
table_state.select(Some(0));
|
||||||
|
|
||||||
|
let lines = result.grouped[selected].lines.as_slice();
|
||||||
|
UiState::Logs {
|
||||||
|
lines,
|
||||||
|
table_state,
|
||||||
|
previous: Box::new(UiState::Match {
|
||||||
|
table_state: prev_state,
|
||||||
|
previous,
|
||||||
|
result,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(UiState::Match { previous, .. } | UiState::Logs { previous, .. }, UiEvent::Back) => {
|
||||||
|
*previous
|
||||||
|
}
|
||||||
(state, _) => state,
|
(state, _) => state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,6 +141,7 @@ pub enum UiEvent {
|
||||||
pub enum UiPage {
|
pub enum UiPage {
|
||||||
MatchList,
|
MatchList,
|
||||||
Match,
|
Match,
|
||||||
|
Logs,
|
||||||
}
|
}
|
||||||
|
|
||||||
mod table_state {
|
mod table_state {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue