zooming
This commit is contained in:
parent
bb8f6bedf6
commit
4a6c1020f4
10 changed files with 113 additions and 34 deletions
17
Cargo.lock
generated
17
Cargo.lock
generated
|
|
@ -228,6 +228,12 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "color-ansi"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e56460573dab12b4bb6dfdb0abbb021e35d6a2bbd925acd2f5a9accff5654a8e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
|
@ -1163,6 +1169,16 @@ dependencies = [
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pretty-print"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c5ad516586f2191e7ce412b9b164e61ee6403638aa70e98672b978c1f448e63f"
|
||||||
|
dependencies = [
|
||||||
|
"color-ansi",
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prettyplease"
|
name = "prettyplease"
|
||||||
version = "0.2.37"
|
version = "0.2.37"
|
||||||
|
|
@ -1430,6 +1446,7 @@ dependencies = [
|
||||||
"jiff",
|
"jiff",
|
||||||
"logparse",
|
"logparse",
|
||||||
"nix 0.31.1",
|
"nix 0.31.1",
|
||||||
|
"pretty-print",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
"ratatui-themes",
|
"ratatui-themes",
|
||||||
"regex",
|
"regex",
|
||||||
|
|
|
||||||
|
|
@ -26,3 +26,4 @@ regex = "1"
|
||||||
crossterm = "*"
|
crossterm = "*"
|
||||||
dumpster = "2.1"
|
dumpster = "2.1"
|
||||||
logparse = {path = "./logparse/", version="0.2.0"}
|
logparse = {path = "./logparse/", version="0.2.0"}
|
||||||
|
pretty-print = "0.1"
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,13 @@ pub struct Span<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configuration options for [`into_spans`]
|
/// Configuration options for [`into_spans`]
|
||||||
|
#[derive(Default)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// Turn sequences of more than 1 space into exactly 1 space.
|
/// Turn sequences of more than 1 space into exactly 1 space.
|
||||||
pub collapse_space: bool,
|
pub collapse_space: bool,
|
||||||
|
/// Pretty print: wrap at braces etc
|
||||||
|
pub pretty_print: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IntoSpans<'a>: private::IntoSpansImpl<'a> {}
|
pub trait IntoSpans<'a>: private::IntoSpansImpl<'a> {}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use crate::tui::{
|
||||||
LogViewer,
|
LogViewer,
|
||||||
input::{FieldMatcher, InputTarget},
|
input::{FieldMatcher, InputTarget},
|
||||||
},
|
},
|
||||||
model::{FieldsName, LogEntry},
|
model::{LogEntry, SpanDescriptor},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod serialize_regex {
|
mod serialize_regex {
|
||||||
|
|
@ -56,7 +56,7 @@ impl MatcherValue {
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub enum Matcher {
|
pub enum Matcher {
|
||||||
Field {
|
Field {
|
||||||
span: FieldsName,
|
span: SpanDescriptor,
|
||||||
name: String,
|
name: String,
|
||||||
value: MatcherValue,
|
value: MatcherValue,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::tui::{
|
||||||
input::{FieldMatcher, InputState, InputTarget},
|
input::{FieldMatcher, InputState, InputTarget},
|
||||||
view::LogView,
|
view::LogView,
|
||||||
},
|
},
|
||||||
model::{FieldsName, LogEntry, id},
|
model::{LogEntry, SpanDescriptor, id},
|
||||||
processing::Cursor,
|
processing::Cursor,
|
||||||
widgets::{fieldtree, last_error::LastError},
|
widgets::{fieldtree, last_error::LastError},
|
||||||
};
|
};
|
||||||
|
|
@ -54,7 +54,7 @@ impl LogViewer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_selected_field(&self) -> Option<(FieldsName, String, String)> {
|
pub fn get_selected_field(&self) -> Option<(SpanDescriptor, String, String)> {
|
||||||
let (span_idx, name_idx) = self.field_state.get()?;
|
let (span_idx, name_idx) = self.field_state.get()?;
|
||||||
let entry = self.selected().map(|(s, _)| s)?;
|
let entry = self.selected().map(|(s, _)| s)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ use crossterm::{
|
||||||
},
|
},
|
||||||
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
|
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
|
||||||
};
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
|
use logparse::{self as lp, Config, into_spans, parse_input};
|
||||||
use ratatui_themes::{Color, Theme, ThemeName};
|
use ratatui_themes::{Color, Theme, ThemeName};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
|
@ -23,10 +25,11 @@ use crate::tui::{
|
||||||
LogViewer,
|
LogViewer,
|
||||||
input::{FieldMatcher, InputState, InputTarget},
|
input::{FieldMatcher, InputState, InputTarget},
|
||||||
},
|
},
|
||||||
|
model::SpanDescriptor,
|
||||||
reader::LogfileReader,
|
reader::LogfileReader,
|
||||||
widgets::{
|
widgets::{
|
||||||
fieldtree::FieldTree, hyperlink::Hyperlink, items::Items, last_error::LastError,
|
fieldtree::FieldTree, hyperlink::Hyperlink, items::Items, last_error::LastError,
|
||||||
styled::IntoStyled,
|
line_text::style_span, styled::IntoStyled,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
|
|
@ -37,7 +40,7 @@ use ratatui::{
|
||||||
prelude::CrosstermBackend,
|
prelude::CrosstermBackend,
|
||||||
style::Style,
|
style::Style,
|
||||||
symbols::merge::MergeStrategy,
|
symbols::merge::MergeStrategy,
|
||||||
text::Line,
|
text::{Line, Span},
|
||||||
widgets::{
|
widgets::{
|
||||||
Block, Clear, List, ListItem, ListState, Padding, Paragraph, StatefulWidget, Widget, Wrap,
|
Block, Clear, List, ListItem, ListState, Padding, Paragraph, StatefulWidget, Widget, Wrap,
|
||||||
},
|
},
|
||||||
|
|
@ -64,6 +67,7 @@ const HELP_TEXT: &str = "Generic:
|
||||||
-> / enter / l enter nested view
|
-> / enter / l enter nested view
|
||||||
|
|
||||||
f toggle show active filters
|
f toggle show active filters
|
||||||
|
z zoom in on a selected field
|
||||||
|
|
||||||
───────────────────────────────────────────────────────
|
───────────────────────────────────────────────────────
|
||||||
targeting logs:
|
targeting logs:
|
||||||
|
|
@ -127,6 +131,11 @@ enum Tab {
|
||||||
LogViewer(LogViewer),
|
LogViewer(LogViewer),
|
||||||
Empty,
|
Empty,
|
||||||
Help,
|
Help,
|
||||||
|
Zoom {
|
||||||
|
span: SpanDescriptor,
|
||||||
|
name: String,
|
||||||
|
value: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tab {
|
impl Tab {
|
||||||
|
|
@ -137,6 +146,11 @@ impl Tab {
|
||||||
(Tab::LogViewer(_), Some(path)) => format!("logs of {}", path.display()),
|
(Tab::LogViewer(_), Some(path)) => format!("logs of {}", path.display()),
|
||||||
(Tab::LogViewer(_), None) => "logs".to_string(),
|
(Tab::LogViewer(_), None) => "logs".to_string(),
|
||||||
(Tab::Help, _) => "help".to_string(),
|
(Tab::Help, _) => "help".to_string(),
|
||||||
|
(Tab::Zoom { span, name, .. }, _) => match span {
|
||||||
|
SpanDescriptor::Main => format!("{name}"),
|
||||||
|
SpanDescriptor::Span(s) => format!("{name} in {s}"),
|
||||||
|
SpanDescriptor::Numbered(n) => format!("{name} in span #{n}"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -244,6 +258,7 @@ impl App {
|
||||||
match self.tabs.last_mut().unwrap() {
|
match self.tabs.last_mut().unwrap() {
|
||||||
Tab::Help => {}
|
Tab::Help => {}
|
||||||
Tab::Empty => {}
|
Tab::Empty => {}
|
||||||
|
Tab::Zoom { .. } => {}
|
||||||
Tab::FileChooser {
|
Tab::FileChooser {
|
||||||
files,
|
files,
|
||||||
state,
|
state,
|
||||||
|
|
@ -327,6 +342,11 @@ impl App {
|
||||||
|
|
||||||
KeyCode::Char('u') => lv.undo(),
|
KeyCode::Char('u') => lv.undo(),
|
||||||
KeyCode::Char('r') => lv.redo(),
|
KeyCode::Char('r') => lv.redo(),
|
||||||
|
KeyCode::Char('z') => {
|
||||||
|
if let Some((span, name, value)) = lv.get_selected_field() {
|
||||||
|
self.push_tab(Tab::Zoom { span, name, value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KeyCode::Tab => {
|
KeyCode::Tab => {
|
||||||
lv.input_state.target(InputTarget::Fields(None));
|
lv.input_state.target(InputTarget::Fields(None));
|
||||||
|
|
@ -592,6 +612,7 @@ impl Widget for &mut App {
|
||||||
|
|
||||||
let (footer_focused, header_focused) = match self.current_tab() {
|
let (footer_focused, header_focused) = match self.current_tab() {
|
||||||
Tab::Help => (false, false),
|
Tab::Help => (false, false),
|
||||||
|
Tab::Zoom { .. } => (false, false),
|
||||||
Tab::FileChooser { .. } => (false, true),
|
Tab::FileChooser { .. } => (false, true),
|
||||||
Tab::LogViewer(lv) => {
|
Tab::LogViewer(lv) => {
|
||||||
let target_fields =
|
let target_fields =
|
||||||
|
|
@ -716,6 +737,42 @@ impl Widget for &mut App {
|
||||||
|
|
||||||
Paragraph::new(HELP_TEXT).render(popup_area, buf);
|
Paragraph::new(HELP_TEXT).render(popup_area, buf);
|
||||||
}
|
}
|
||||||
|
Tab::Zoom { value, .. } => {
|
||||||
|
Clear.render(popup_area, buf);
|
||||||
|
let popup_area = {
|
||||||
|
let block = Block::bordered()
|
||||||
|
.title_top("zoom")
|
||||||
|
.style(styles.default)
|
||||||
|
.padding(Padding::symmetric(3, 1))
|
||||||
|
.border_style(styles.border_highlighted);
|
||||||
|
let inner = block.inner(popup_area);
|
||||||
|
block.render(popup_area, buf);
|
||||||
|
inner
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Ok(parsed) = parse_input(&value) {
|
||||||
|
let spans = into_spans(
|
||||||
|
parsed,
|
||||||
|
Config {
|
||||||
|
collapse_space: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let spans = spans
|
||||||
|
.into_iter()
|
||||||
|
.map(|lp::Span { text, kind }| {
|
||||||
|
let span = Span::from(text.into_owned());
|
||||||
|
|
||||||
|
let style = style_span(kind, styles.default, &styles);
|
||||||
|
span.style(style)
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
Paragraph::new(Line::from(spans)).render(popup_area, buf);
|
||||||
|
} else {
|
||||||
|
Paragraph::new(value.clone()).render(popup_area, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_error.clone().styled(&styles).render(error, buf);
|
self.last_error.clone().styled(&styles).render(error, buf);
|
||||||
|
|
|
||||||
|
|
@ -396,7 +396,7 @@ unsafe impl<V: Visitor> TraceWith<V> for RawLogEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Hash, Clone, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(PartialEq, Eq, Debug, Hash, Clone, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum FieldsName {
|
pub enum SpanDescriptor {
|
||||||
/// The main fields (not of a span) of a log entry
|
/// The main fields (not of a span) of a log entry
|
||||||
Main,
|
Main,
|
||||||
Span(String),
|
Span(String),
|
||||||
|
|
@ -409,23 +409,23 @@ pub struct SpansRef<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SpansRef<'a> {
|
impl<'a> SpansRef<'a> {
|
||||||
pub fn find(&self, span: &FieldsName, name: &str) -> Option<&String> {
|
pub fn find(&self, span: &SpanDescriptor, name: &str) -> Option<&String> {
|
||||||
self.named()
|
self.named()
|
||||||
.find(|(name, _)| name == span)
|
.find(|(name, _)| name == span)
|
||||||
.and_then(|(_, fields)| fields.get(name))
|
.and_then(|(_, fields)| fields.get(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn named(&self) -> impl Iterator<Item = (FieldsName, &'a LogFields)> {
|
pub fn named(&self) -> impl Iterator<Item = (SpanDescriptor, &'a LogFields)> {
|
||||||
iter::once((FieldsName::Main, self.main)).chain(self.spans.iter().rev().enumerate().map(
|
iter::once((SpanDescriptor::Main, self.main)).chain(
|
||||||
|(idx, fields)| {
|
self.spans.iter().rev().enumerate().map(|(idx, fields)| {
|
||||||
(
|
(
|
||||||
fields
|
fields
|
||||||
.name()
|
.name()
|
||||||
.map(|i| FieldsName::Span(i.to_string()))
|
.map(|i| SpanDescriptor::Span(i.to_string()))
|
||||||
.unwrap_or_else(|| FieldsName::Numbered(idx)),
|
.unwrap_or_else(|| SpanDescriptor::Numbered(idx)),
|
||||||
fields,
|
fields,
|
||||||
)
|
)
|
||||||
},
|
}),
|
||||||
))
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ mod tests {
|
||||||
use crate::tui::{
|
use crate::tui::{
|
||||||
filter::{Filter, FilterKind, Matcher, MatcherValue},
|
filter::{Filter, FilterKind, Matcher, MatcherValue},
|
||||||
log_viewer::filters::Filters,
|
log_viewer::filters::Filters,
|
||||||
model::FieldsName,
|
model::SpanDescriptor,
|
||||||
processing::Cursor,
|
processing::Cursor,
|
||||||
widgets::last_error::LastError,
|
widgets::last_error::LastError,
|
||||||
};
|
};
|
||||||
|
|
@ -311,7 +311,7 @@ mod tests {
|
||||||
matcher: Matcher::Field {
|
matcher: Matcher::Field {
|
||||||
name: "message".to_string(),
|
name: "message".to_string(),
|
||||||
value: MatcherValue::Exact("foo".to_string()),
|
value: MatcherValue::Exact("foo".to_string()),
|
||||||
span: FieldsName::Main,
|
span: SpanDescriptor::Main,
|
||||||
},
|
},
|
||||||
kind: FilterKind::Remove,
|
kind: FilterKind::Remove,
|
||||||
}));
|
}));
|
||||||
|
|
@ -337,7 +337,7 @@ mod tests {
|
||||||
matcher: Matcher::Field {
|
matcher: Matcher::Field {
|
||||||
name: "message".to_string(),
|
name: "message".to_string(),
|
||||||
value: MatcherValue::Exact("baz".to_string()),
|
value: MatcherValue::Exact("baz".to_string()),
|
||||||
span: FieldsName::Main,
|
span: SpanDescriptor::Main,
|
||||||
},
|
},
|
||||||
kind: FilterKind::Remove,
|
kind: FilterKind::Remove,
|
||||||
}));
|
}));
|
||||||
|
|
@ -368,7 +368,7 @@ mod tests {
|
||||||
matcher: Matcher::Field {
|
matcher: Matcher::Field {
|
||||||
name: "name".to_string(),
|
name: "name".to_string(),
|
||||||
value: MatcherValue::Exact("nest".to_string()),
|
value: MatcherValue::Exact("nest".to_string()),
|
||||||
span: FieldsName::Main,
|
span: SpanDescriptor::Main,
|
||||||
},
|
},
|
||||||
kind: FilterKind::Inline,
|
kind: FilterKind::Inline,
|
||||||
}));
|
}));
|
||||||
|
|
@ -415,7 +415,7 @@ mod tests {
|
||||||
matcher: Matcher::Field {
|
matcher: Matcher::Field {
|
||||||
name: "name".to_string(),
|
name: "name".to_string(),
|
||||||
value: MatcherValue::Exact("nest".to_string()),
|
value: MatcherValue::Exact("nest".to_string()),
|
||||||
span: FieldsName::Main,
|
span: SpanDescriptor::Main,
|
||||||
},
|
},
|
||||||
kind: FilterKind::Inline,
|
kind: FilterKind::Inline,
|
||||||
}));
|
}));
|
||||||
|
|
@ -465,7 +465,7 @@ mod tests {
|
||||||
matcher: Matcher::Field {
|
matcher: Matcher::Field {
|
||||||
name: "name".to_string(),
|
name: "name".to_string(),
|
||||||
value: MatcherValue::Exact("nest1".to_string()),
|
value: MatcherValue::Exact("nest1".to_string()),
|
||||||
span: FieldsName::Main,
|
span: SpanDescriptor::Main,
|
||||||
},
|
},
|
||||||
kind: FilterKind::Inline,
|
kind: FilterKind::Inline,
|
||||||
}));
|
}));
|
||||||
|
|
@ -473,7 +473,7 @@ mod tests {
|
||||||
matcher: Matcher::Field {
|
matcher: Matcher::Field {
|
||||||
name: "name".to_string(),
|
name: "name".to_string(),
|
||||||
value: MatcherValue::Exact("nest2".to_string()),
|
value: MatcherValue::Exact("nest2".to_string()),
|
||||||
span: FieldsName::Main,
|
span: SpanDescriptor::Main,
|
||||||
},
|
},
|
||||||
kind: FilterKind::Inline,
|
kind: FilterKind::Inline,
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use tui_widget_list::{ListBuilder, ListState, ListView};
|
||||||
use crate::tui::{
|
use crate::tui::{
|
||||||
block_around,
|
block_around,
|
||||||
log_viewer::LogViewer,
|
log_viewer::LogViewer,
|
||||||
model::{FieldsName, LogEntry, LogFields},
|
model::{SpanDescriptor, LogEntry, LogFields},
|
||||||
widgets::{line_text::style_span, styled::Styled},
|
widgets::{line_text::style_span, styled::Styled},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -91,7 +91,7 @@ impl<'a> FieldTree<'a> {
|
||||||
self.lv.selected().map(|(s, _)| s)
|
self.lv.selected().map(|(s, _)| s)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_span_fields(&mut self, spans: &[(FieldsName, &LogFields)]) -> Vec<(String, String)> {
|
fn current_span_fields(&mut self, spans: &[(SpanDescriptor, &LogFields)]) -> Vec<(String, String)> {
|
||||||
let mut selected = self.state().current_span.selected.unwrap_or(0);
|
let mut selected = self.state().current_span.selected.unwrap_or(0);
|
||||||
if selected > spans.len() {
|
if selected > spans.len() {
|
||||||
selected = spans.len().saturating_sub(1);
|
selected = spans.len().saturating_sub(1);
|
||||||
|
|
@ -120,7 +120,7 @@ impl<'a> FieldTree<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Styled<'_, &mut FieldTree<'_>> {
|
impl Styled<'_, &mut FieldTree<'_>> {
|
||||||
fn areas(&self, area: Rect, buf: &mut Buffer, name: Option<&FieldsName>) -> (Rect, Rect, Rect) {
|
fn areas(&self, area: Rect, buf: &mut Buffer, name: Option<&SpanDescriptor>) -> (Rect, Rect, Rect) {
|
||||||
let [spans_area, fields_area] = Layout::horizontal([
|
let [spans_area, fields_area] = Layout::horizontal([
|
||||||
Constraint::Length(if self.spans_focussed() || !self.focussed {
|
Constraint::Length(if self.spans_focussed() || !self.focussed {
|
||||||
25
|
25
|
||||||
|
|
@ -146,9 +146,9 @@ impl Styled<'_, &mut FieldTree<'_>> {
|
||||||
self.styles,
|
self.styles,
|
||||||
Some(if let Some(i) = name {
|
Some(if let Some(i) = name {
|
||||||
match i {
|
match i {
|
||||||
FieldsName::Main => "own fields".to_string(),
|
SpanDescriptor::Main => "own fields".to_string(),
|
||||||
FieldsName::Span(s) => format!("fields of {s}"),
|
SpanDescriptor::Span(s) => format!("fields of {s}"),
|
||||||
FieldsName::Numbered(idx) => format!("fields of span #{idx}"),
|
SpanDescriptor::Numbered(idx) => format!("fields of span #{idx}"),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
"fields".to_string()
|
"fields".to_string()
|
||||||
|
|
@ -191,9 +191,9 @@ impl Widget for Styled<'_, &mut FieldTree<'_>> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut item = Line::from(match span_name {
|
let mut item = Line::from(match span_name {
|
||||||
FieldsName::Main => "own fields".to_string(),
|
SpanDescriptor::Main => "own fields".to_string(),
|
||||||
FieldsName::Span(s) => s.to_string(),
|
SpanDescriptor::Span(s) => s.to_string(),
|
||||||
FieldsName::Numbered(idx) => format!("span #{idx}"),
|
SpanDescriptor::Numbered(idx) => format!("span #{idx}"),
|
||||||
});
|
});
|
||||||
if cx.is_selected && self_focussed {
|
if cx.is_selected && self_focussed {
|
||||||
item = item.style(self.styles.highlighted);
|
item = item.style(self.styles.highlighted);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::tui::{
|
||||||
filters::Filters,
|
filters::Filters,
|
||||||
input::{FieldMatcher, InputState, InputTarget},
|
input::{FieldMatcher, InputState, InputTarget},
|
||||||
},
|
},
|
||||||
model::{FieldsName, LogEntry},
|
model::{SpanDescriptor, LogEntry},
|
||||||
widgets::{
|
widgets::{
|
||||||
last_error::LastError,
|
last_error::LastError,
|
||||||
line_text::Highlighted,
|
line_text::Highlighted,
|
||||||
|
|
@ -23,7 +23,7 @@ pub struct Items<'a> {
|
||||||
input_state: &'a InputState,
|
input_state: &'a InputState,
|
||||||
filters: &'a Filters,
|
filters: &'a Filters,
|
||||||
|
|
||||||
selected_footer_field: Option<(FieldsName, String, String)>,
|
selected_footer_field: Option<(SpanDescriptor, String, String)>,
|
||||||
last_error: LastError,
|
last_error: LastError,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ impl<'a> Items<'a> {
|
||||||
filters: &'a Filters,
|
filters: &'a Filters,
|
||||||
selected_offset: usize,
|
selected_offset: usize,
|
||||||
input_state: &'a InputState,
|
input_state: &'a InputState,
|
||||||
selected_footer_field: Option<(FieldsName, String, String)>,
|
selected_footer_field: Option<(SpanDescriptor, String, String)>,
|
||||||
last_error: LastError,
|
last_error: LastError,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue