good layout
This commit is contained in:
@@ -44,6 +44,13 @@ class FlowMainDetailsPanel(Vertical):
|
||||
|
||||
def update_flow(self, flow: Optional['FlowStats']) -> None:
|
||||
"""Update panel with main flow details"""
|
||||
flow_info = f"{flow.src_ip}:{flow.src_port}" if flow else "None"
|
||||
try:
|
||||
debug_panel = self.app.query_one("#debug-panel")
|
||||
debug_panel.add_debug_message(f"MAIN_PANEL: Update called - {flow_info}")
|
||||
except:
|
||||
pass
|
||||
|
||||
self.current_flow = flow
|
||||
content_widget = self.query_one("#main-details-content", Static)
|
||||
|
||||
@@ -52,6 +59,14 @@ class FlowMainDetailsPanel(Vertical):
|
||||
return
|
||||
|
||||
details = self._create_main_flow_details(flow)
|
||||
|
||||
# Debug what content we're actually setting
|
||||
try:
|
||||
debug_panel = self.app.query_one("#debug-panel")
|
||||
debug_panel.add_debug_message(f"CONTENT: Setting panel content for {flow.src_ip}:{flow.src_port}")
|
||||
except:
|
||||
pass
|
||||
|
||||
content_widget.update(details)
|
||||
|
||||
def _create_main_flow_details(self, flow: 'FlowStats') -> RenderableType:
|
||||
@@ -91,21 +106,57 @@ class FlowMainDetailsPanel(Vertical):
|
||||
sections.append(Text("Enhanced Analysis", style="bold green"))
|
||||
sections.append(enhanced_table)
|
||||
|
||||
# Timing analysis with new columns
|
||||
timing_table = Table(show_header=False, box=None, padding=0)
|
||||
timing_table.add_column(style="dim", width=12)
|
||||
timing_table.add_column()
|
||||
# Timing analysis - only show if no sub-flows exist
|
||||
# Match the same logic as _should_show_subrows in flow_table_v2.py
|
||||
has_subflows = (len(flow.frame_types) > 1 or
|
||||
flow.enhanced_analysis.decoder_type != "Standard")
|
||||
|
||||
timing_table.add_row("Duration:", f"{flow.duration:.2f}s")
|
||||
timing_table.add_row("Avg ΔT:", f"{flow.avg_inter_arrival * 1000:.1f}ms")
|
||||
timing_table.add_row("Std σ:", f"{flow.std_inter_arrival * 1000:.1f}ms")
|
||||
timing_table.add_row("Outliers:", f"{len(flow.outlier_frames)}")
|
||||
timing_table.add_row("Jitter:", f"{flow.jitter * 1000:.2f}ms")
|
||||
timing_table.add_row("First Seen:", self._format_timestamp(flow.first_seen))
|
||||
timing_table.add_row("Last Seen:", self._format_timestamp(flow.last_seen))
|
||||
# Debug output
|
||||
try:
|
||||
debug_panel = self.app.query_one("#debug-panel")
|
||||
debug_panel.add_debug_message(f"TIMING_LOGIC: {flow.src_ip}:{flow.src_port} - types={len(flow.frame_types)}, decoder={flow.enhanced_analysis.decoder_type}, has_subflows={has_subflows}")
|
||||
except:
|
||||
pass
|
||||
|
||||
sections.append(Text("Timing Analysis", style="bold cyan"))
|
||||
sections.append(timing_table)
|
||||
if not has_subflows:
|
||||
try:
|
||||
debug_panel = self.app.query_one("#debug-panel")
|
||||
debug_panel.add_debug_message(f"BRANCH: Taking FULL timing branch for {flow.src_ip}:{flow.src_port}")
|
||||
except:
|
||||
pass
|
||||
|
||||
timing_table = Table(show_header=False, box=None, padding=0)
|
||||
timing_table.add_column(style="dim", width=12)
|
||||
timing_table.add_column()
|
||||
|
||||
timing_table.add_row("Duration:", f"{flow.duration:.2f}s")
|
||||
timing_table.add_row("Avg ΔT:", f"{flow.avg_inter_arrival * 1000:.1f}ms")
|
||||
timing_table.add_row("Std σ:", f"{flow.std_inter_arrival * 1000:.1f}ms")
|
||||
timing_table.add_row("Outliers:", f"{len(flow.outlier_frames)}")
|
||||
timing_table.add_row("Jitter:", f"{flow.jitter * 1000:.2f}ms")
|
||||
timing_table.add_row("First Seen:", self._format_timestamp(flow.first_seen))
|
||||
timing_table.add_row("Last Seen:", self._format_timestamp(flow.last_seen))
|
||||
|
||||
sections.append(Text("Timing Analysis", style="bold cyan"))
|
||||
sections.append(timing_table)
|
||||
else:
|
||||
try:
|
||||
debug_panel = self.app.query_one("#debug-panel")
|
||||
debug_panel.add_debug_message(f"BRANCH: Taking BASIC timeline branch for {flow.src_ip}:{flow.src_port}")
|
||||
except:
|
||||
pass
|
||||
|
||||
# Just show duration and timestamps for flows with sub-flows
|
||||
basic_timing_table = Table(show_header=False, box=None, padding=0)
|
||||
basic_timing_table.add_column(style="dim", width=12)
|
||||
basic_timing_table.add_column()
|
||||
|
||||
basic_timing_table.add_row("Duration:", f"{flow.duration:.2f}s")
|
||||
basic_timing_table.add_row("First Seen:", self._format_timestamp(flow.first_seen))
|
||||
basic_timing_table.add_row("Last Seen:", self._format_timestamp(flow.last_seen))
|
||||
|
||||
sections.append(Text("Flow Timeline", style="bold cyan"))
|
||||
sections.append(basic_timing_table)
|
||||
|
||||
return Group(*sections)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user