mirror of
https://codeberg.org/icewind/logsmash.git
synced 2026-06-03 18:14:11 +02:00
lazy histograms for groups list
This commit is contained in:
parent
2631696ddd
commit
06704ebc6a
4 changed files with 91 additions and 51 deletions
|
|
@ -10,25 +10,25 @@ use ratatui::prelude::{StatefulWidget, Widget};
|
|||
use ratatui::text::Text;
|
||||
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
||||
|
||||
pub struct LogsByIdentifier<'a> {
|
||||
pub struct DistinctLogs<'a> {
|
||||
lines: &'a [&'a LogLine<'a>],
|
||||
filter: &'a Filter,
|
||||
grouping: DistinctLogGrouping,
|
||||
}
|
||||
|
||||
pub fn logs_by_identifier<'a>(
|
||||
pub fn distinct_logs<'a>(
|
||||
lines: &'a [&'a LogLine<'a>],
|
||||
filter: &'a Filter,
|
||||
grouping: DistinctLogGrouping,
|
||||
) -> LogsByIdentifier<'a> {
|
||||
LogsByIdentifier {
|
||||
) -> DistinctLogs<'a> {
|
||||
DistinctLogs {
|
||||
lines,
|
||||
filter,
|
||||
grouping,
|
||||
}
|
||||
}
|
||||
|
||||
impl StatefulWidget for LogsByIdentifier<'_> {
|
||||
impl StatefulWidget for DistinctLogs<'_> {
|
||||
type State = ScrollbarTableState;
|
||||
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
|
||||
|
|
@ -1,66 +1,106 @@
|
|||
use crate::app::Filter;
|
||||
use crate::grouping::{GroupingResult, GroupingUi, LogGrouping};
|
||||
use crate::ui::style::TABLE_HEADER_STYLE;
|
||||
use crate::ui::table::ScrollbarTable;
|
||||
use crate::ui::table::{ScrollbarTable, ScrollbarTableState};
|
||||
use ratatui::prelude::*;
|
||||
use ratatui::widgets::{Cell, Row};
|
||||
use std::borrow::Cow;
|
||||
use std::ops::RangeInclusive;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
pub fn grouping_list<'a>(
|
||||
items: &[LogGrouping<'a>],
|
||||
ui: &GroupingUi,
|
||||
pub struct GroupingList<'a, 'b> {
|
||||
items: &'b [LogGrouping<'a>],
|
||||
ui: &'b GroupingUi,
|
||||
time_range: RangeInclusive<OffsetDateTime>,
|
||||
filter: &Filter,
|
||||
) -> ScrollbarTable<'a> {
|
||||
let header = ui
|
||||
.header
|
||||
.iter()
|
||||
.copied()
|
||||
.chain([("Time", Alignment::Left), ("Count", Alignment::Left)]);
|
||||
filter: &'b Filter,
|
||||
}
|
||||
|
||||
let header = header
|
||||
.map(|(text, align)| Text::from(text).alignment(align))
|
||||
.map(Cell::from)
|
||||
.collect::<Row>()
|
||||
.style(TABLE_HEADER_STYLE)
|
||||
.height(1);
|
||||
|
||||
let items: Vec<Row<'a>> = items
|
||||
.iter()
|
||||
.filter(|result| result.matches(filter))
|
||||
.map(|result| grouped_row(result, time_range.clone()))
|
||||
.collect();
|
||||
|
||||
ScrollbarTable::new(
|
||||
pub fn grouping_list<'a, 'b>(
|
||||
items: &'b [LogGrouping<'a>],
|
||||
ui: &'b GroupingUi,
|
||||
time_range: RangeInclusive<OffsetDateTime>,
|
||||
filter: &'b Filter,
|
||||
) -> GroupingList<'a, 'b> {
|
||||
GroupingList {
|
||||
items,
|
||||
ui.widths
|
||||
ui,
|
||||
time_range,
|
||||
filter,
|
||||
}
|
||||
}
|
||||
|
||||
impl StatefulWidget for GroupingList<'_, '_> {
|
||||
type State = ScrollbarTableState;
|
||||
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let header = self
|
||||
.ui
|
||||
.header
|
||||
.iter()
|
||||
.copied()
|
||||
.chain([Constraint::Length(10), Constraint::Min(10)]),
|
||||
)
|
||||
.header(header)
|
||||
.chain([("Time", Alignment::Left), ("Count", Alignment::Left)]);
|
||||
|
||||
let header = header
|
||||
.map(|(text, align)| Text::from(text).alignment(align))
|
||||
.map(Cell::from)
|
||||
.collect::<Row>()
|
||||
.style(TABLE_HEADER_STYLE)
|
||||
.height(1);
|
||||
|
||||
let items: Vec<_> = self
|
||||
.items
|
||||
.iter()
|
||||
.filter(|result| result.matches(self.filter))
|
||||
.enumerate()
|
||||
.map(|(i, result)| {
|
||||
grouped_row(
|
||||
result,
|
||||
self.time_range.clone(),
|
||||
i.abs_diff(state.selected()) < 100,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let table = ScrollbarTable::new(
|
||||
items,
|
||||
self.ui
|
||||
.widths
|
||||
.iter()
|
||||
.copied()
|
||||
.chain([Constraint::Length(10), Constraint::Min(10)]),
|
||||
)
|
||||
.header(header);
|
||||
|
||||
table.render(area, buf, state);
|
||||
}
|
||||
}
|
||||
|
||||
fn grouped_row<'a>(
|
||||
grouping: &LogGrouping<'a>,
|
||||
time_range: RangeInclusive<OffsetDateTime>,
|
||||
is_in_view: bool,
|
||||
) -> Row<'a> {
|
||||
if let Some(match_result) = &grouping.result {
|
||||
let grouping_columns = match_result.render();
|
||||
let columns = grouping_columns.chain([
|
||||
Cow::from(grouping.sparkline(time_range).to_string()),
|
||||
Cow::from(grouping.count().to_string()),
|
||||
]);
|
||||
Row::new(columns).height(match_result.height() as u16)
|
||||
if is_in_view {
|
||||
if let Some(match_result) = &grouping.result {
|
||||
let grouping_columns = match_result.render();
|
||||
let columns = grouping_columns.chain([
|
||||
Cow::from(grouping.sparkline(time_range).to_string()),
|
||||
Cow::from(grouping.count().to_string()),
|
||||
]);
|
||||
Row::new(columns).height(match_result.height() as u16)
|
||||
} else {
|
||||
Row::new([
|
||||
Text::from(grouping.name.unwrap_or_default()),
|
||||
Text::from(""),
|
||||
Text::from(""),
|
||||
Text::from(grouping.sparkline(time_range).to_string()),
|
||||
Text::from(grouping.count().to_string()),
|
||||
])
|
||||
}
|
||||
} else {
|
||||
Row::new([
|
||||
Text::from(grouping.name.unwrap_or_default()),
|
||||
Text::from(""),
|
||||
Text::from(""),
|
||||
Text::from(grouping.sparkline(time_range).to_string()),
|
||||
Text::from(grouping.count().to_string()),
|
||||
])
|
||||
Row::default()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::app::App;
|
||||
use crate::error::UiError;
|
||||
use crate::grouping::LogGrouping;
|
||||
use crate::ui::by_identifier::logs_by_identifier;
|
||||
use crate::ui::distinct_logs::distinct_logs;
|
||||
use crate::ui::error_list::error_list;
|
||||
use crate::ui::footer::footer;
|
||||
use crate::ui::grouping_list::grouping_list;
|
||||
|
|
@ -28,7 +28,7 @@ use std::io;
|
|||
use std::io::stdout;
|
||||
use std::panic::{set_hook, take_hook};
|
||||
|
||||
mod by_identifier;
|
||||
mod distinct_logs;
|
||||
mod error_list;
|
||||
mod footer;
|
||||
mod grouping_list;
|
||||
|
|
@ -186,7 +186,7 @@ fn ui(frame: &mut Frame, app: &App, state: &mut UiState) {
|
|||
..
|
||||
}) => {
|
||||
frame.render_stateful_widget(
|
||||
logs_by_identifier(lines, filter, *grouping),
|
||||
distinct_logs(lines, filter, *grouping),
|
||||
layout[0].union(layout[1]),
|
||||
table_state,
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue