Files
StreamLens/analyzer/tui/textual/widgets/packet_viewer.py
noisedestroyers 36a576dc2c Enhanced Textual TUI with proper API usage and documentation
- Fixed DataTable row selection and event handling
- Added explicit column keys to prevent auto-generated keys
- Implemented row-to-flow mapping for reliable selection tracking
- Converted left metrics panel to horizontal top bar
- Fixed all missing FlowStats/EnhancedAnalysisData attributes
- Created comprehensive Textual API documentation in Documentation/textual/
- Added validation checklist to prevent future API mismatches
- Preserved cursor position during data refreshes
- Fixed RowKey type handling and event names

The TUI now properly handles flow selection, displays metrics in a compact top bar,
and correctly correlates selected rows with the details pane.
2025-07-27 18:37:55 -04:00

56 lines
1.7 KiB
Python

"""
Packet Decoder Widget - 3-panel packet inspection interface
"""
from textual.widgets import Static, DataTable, Tree
from textual.containers import Horizontal, Vertical
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from ....analysis.core import EthernetAnalyzer
class PacketDecoderWidget(Horizontal):
"""
3-Panel Packet Decoder Interface
Layout:
- Left: Flow summary tree
- Center: Packet list table
- Right: Field details tree
"""
def __init__(self, analyzer: 'EthernetAnalyzer', **kwargs):
super().__init__(**kwargs)
self.analyzer = analyzer
def compose(self):
"""Create the 3-panel layout"""
# Left panel: Flow summary
with Vertical(id="flow-summary-panel"):
yield Static("Flow Summary", id="flow-summary-title")
flow_tree = Tree("Flows", id="flow-tree")
yield flow_tree
# Center panel: Packet list
with Vertical(id="packet-list-panel"):
yield Static("Packet Details", id="packet-list-title")
packet_table = DataTable(id="packet-table")
packet_table.add_columns("Time", "Src", "Dst", "Protocol", "Info")
yield packet_table
# Right panel: Field details
with Vertical(id="field-details-panel"):
yield Static("Field Analysis", id="field-details-title")
field_tree = Tree("Fields", id="field-tree")
yield field_tree
def on_mount(self) -> None:
"""Initialize the widget"""
self.refresh_data()
def refresh_data(self) -> None:
"""Refresh packet decoder data"""
# TODO: Implement packet data refresh
pass