refactor: organize host modules and document architecture with UML
Verify Tessera GUI / verify (push) Failing after 2m2s
Verify Tessera GUI / verify (push) Failing after 2m2s
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
use super::*;
|
||||
|
||||
pub(super) fn build(
|
||||
p: &mut Painter,
|
||||
state: &mut DeveloperToolsState,
|
||||
records: &[Exchange],
|
||||
viewport: Rect,
|
||||
) {
|
||||
let x = viewport.x;
|
||||
let w = viewport.width;
|
||||
let bottom = viewport.height - 22.0;
|
||||
|
||||
p.fill(Rect::new(x, 32.0, w, 30.0), BAR);
|
||||
p.enabled_button(
|
||||
Rect::new(x + 3.0, 32.0, 62.0, 29.0),
|
||||
"Clear",
|
||||
Action::ClearNetwork,
|
||||
records.iter().any(|r| r.id > state.network_after),
|
||||
);
|
||||
let filter_area = Rect::new(x + 72.0, 35.0, (w - 85.0).max(100.0), 24.0);
|
||||
p.ui.text_field(
|
||||
filter_area,
|
||||
Action::Focus(Focus::Filter),
|
||||
state.focus == Some(Focus::Filter),
|
||||
);
|
||||
p.label(
|
||||
filter_area.x + 7.0,
|
||||
filter_area.y + 3.0,
|
||||
&format!(
|
||||
"Filter: {}{}",
|
||||
state.filter,
|
||||
if state.focus == Some(Focus::Filter) {
|
||||
"│"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
),
|
||||
MUTED,
|
||||
false,
|
||||
);
|
||||
|
||||
p.label(
|
||||
x + 10.0,
|
||||
69.0,
|
||||
"METHOD STATUS TIME PATH",
|
||||
MUTED,
|
||||
true,
|
||||
);
|
||||
let divider = 92.0 + (bottom - 92.0) * state.network_fraction;
|
||||
let filter = state.filter.to_lowercase();
|
||||
let visible = records
|
||||
.iter()
|
||||
.filter(|r| r.id > state.network_after)
|
||||
.filter(|r| {
|
||||
format!(
|
||||
"{} {} {}",
|
||||
r.method,
|
||||
r.path,
|
||||
r.status.map_or("pending".into(), |s| s.to_string())
|
||||
)
|
||||
.to_lowercase()
|
||||
.contains(&filter)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let mut lines = Vec::new();
|
||||
for r in &visible {
|
||||
let mut l = Line::new(
|
||||
format!(
|
||||
"{:<7} {:<6} {:>5} ms {}",
|
||||
r.method,
|
||||
r.status.map_or("…".into(), |s| s.to_string()),
|
||||
r.elapsed_ms,
|
||||
r.path
|
||||
),
|
||||
if r.status.is_some_and(|s| s >= 400) {
|
||||
ERROR
|
||||
} else {
|
||||
TEXT
|
||||
},
|
||||
);
|
||||
l.selected = state.selected_request == Some(r.id);
|
||||
l.action = Some(Action::Request(r.id));
|
||||
lines.push(l);
|
||||
}
|
||||
if lines.is_empty() {
|
||||
lines.push(Line::new(
|
||||
"No matching requests. Listening to Tessera's local API.",
|
||||
MUTED,
|
||||
));
|
||||
}
|
||||
p.lines(
|
||||
Rect::new(x + 1.0, 92.0, w - 2.0, divider - 92.0),
|
||||
Region::Requests,
|
||||
&lines,
|
||||
state,
|
||||
false,
|
||||
);
|
||||
p.split(Rect::new(x + 1.0, divider, w - 2.0, 1.0), Split::Network);
|
||||
let selected = records
|
||||
.iter()
|
||||
.find(|r| Some(r.id) == state.selected_request);
|
||||
let mut details = Vec::new();
|
||||
if let Some(r) = selected {
|
||||
request_details(&mut details, r);
|
||||
} else {
|
||||
multiline(
|
||||
&mut details,
|
||||
"Select a request to inspect headers and bodies.\n\nCapture scope: 127.0.0.1:4737 in this Tessera process.\n80 most recent requests; body previews up to 32 KiB.\nOnly Content-Type and Content-Length request headers are recorded.\nExternal browser / OS traffic is not captured.",
|
||||
MUTED,
|
||||
);
|
||||
}
|
||||
p.lines(
|
||||
Rect::new(x + 1.0, divider + 5.0, w - 2.0, bottom - divider - 5.0),
|
||||
Region::Details,
|
||||
&details,
|
||||
state,
|
||||
false,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user