feat: add compact and wide table modes
This commit is contained in:
+72
-16
@@ -1100,6 +1100,7 @@ def run_textual(api_url: str, status_url: str, refresh_seconds: int, timeout: in
|
|||||||
("2", "show_requests", "Requests"),
|
("2", "show_requests", "Requests"),
|
||||||
("3", "show_logs", "Logs"),
|
("3", "show_logs", "Logs"),
|
||||||
("4", "show_profiles", "Profiles"),
|
("4", "show_profiles", "Profiles"),
|
||||||
|
("m", "toggle_request_table_density", "Wide/Compact"),
|
||||||
("shift+left", "scroll_table_left", "Scroll Left"),
|
("shift+left", "scroll_table_left", "Scroll Left"),
|
||||||
("shift+right", "scroll_table_right", "Scroll Right"),
|
("shift+right", "scroll_table_right", "Scroll Right"),
|
||||||
("[", "narrow_usage_column", "Narrow Usage"),
|
("[", "narrow_usage_column", "Narrow Usage"),
|
||||||
@@ -1138,7 +1139,44 @@ def run_textual(api_url: str, status_url: str, refresh_seconds: int, timeout: in
|
|||||||
"profiles": "profiles",
|
"profiles": "profiles",
|
||||||
}
|
}
|
||||||
self.request_table_column_keys: dict[str, Any] = {}
|
self.request_table_column_keys: dict[str, Any] = {}
|
||||||
self.request_usage_width = 36
|
self.request_table_density = "compact"
|
||||||
|
self.request_table_width_profiles = {
|
||||||
|
"compact": {
|
||||||
|
"seq": 7,
|
||||||
|
"id": 18,
|
||||||
|
"thread": 18,
|
||||||
|
"started": 19,
|
||||||
|
"status": 7,
|
||||||
|
"path": 22,
|
||||||
|
"model": 16,
|
||||||
|
"reasoning": 10,
|
||||||
|
"usage": 36,
|
||||||
|
"resp": 10,
|
||||||
|
"chunks": 14,
|
||||||
|
"first": 8,
|
||||||
|
"duration": 8,
|
||||||
|
"updated": 8,
|
||||||
|
"note": 22,
|
||||||
|
},
|
||||||
|
"wide": {
|
||||||
|
"seq": 7,
|
||||||
|
"id": 20,
|
||||||
|
"thread": 30,
|
||||||
|
"started": 19,
|
||||||
|
"status": 7,
|
||||||
|
"path": 34,
|
||||||
|
"model": 18,
|
||||||
|
"reasoning": 10,
|
||||||
|
"usage": 52,
|
||||||
|
"resp": 12,
|
||||||
|
"chunks": 16,
|
||||||
|
"first": 8,
|
||||||
|
"duration": 8,
|
||||||
|
"updated": 8,
|
||||||
|
"note": 34,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
self.request_usage_width = self.request_table_width_profiles[self.request_table_density]["usage"]
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header(show_clock=True)
|
yield Header(show_clock=True)
|
||||||
@@ -1158,22 +1196,23 @@ def run_textual(api_url: str, status_url: str, refresh_seconds: int, timeout: in
|
|||||||
requests = self.query_one("#requests_table", DataTable)
|
requests = self.query_one("#requests_table", DataTable)
|
||||||
requests.cursor_type = "row"
|
requests.cursor_type = "row"
|
||||||
requests.zebra_stripes = True
|
requests.zebra_stripes = True
|
||||||
|
width_profile = self.request_table_width_profiles[self.request_table_density]
|
||||||
self.request_table_column_keys = {
|
self.request_table_column_keys = {
|
||||||
"seq": requests.add_column("Seq", width=7, key="seq"),
|
"seq": requests.add_column("Seq", width=width_profile["seq"], key="seq"),
|
||||||
"id": requests.add_column("ID", width=18, key="id"),
|
"id": requests.add_column("ID", width=width_profile["id"], key="id"),
|
||||||
"thread": requests.add_column("Thread", width=18, key="thread"),
|
"thread": requests.add_column("Thread", width=width_profile["thread"], key="thread"),
|
||||||
"started": requests.add_column("Started", width=19, key="started"),
|
"started": requests.add_column("Started", width=width_profile["started"], key="started"),
|
||||||
"status": requests.add_column("Status", width=7, key="status"),
|
"status": requests.add_column("Status", width=width_profile["status"], key="status"),
|
||||||
"path": requests.add_column("Path", width=22, key="path"),
|
"path": requests.add_column("Path", width=width_profile["path"], key="path"),
|
||||||
"model": requests.add_column("Model", width=16, key="model"),
|
"model": requests.add_column("Model", width=width_profile["model"], key="model"),
|
||||||
"reasoning": requests.add_column("Reasoning", width=10, key="reasoning"),
|
"reasoning": requests.add_column("Reasoning", width=width_profile["reasoning"], key="reasoning"),
|
||||||
"usage": requests.add_column("Usage", width=self.request_usage_width, key="usage"),
|
"usage": requests.add_column("Usage", width=self.request_usage_width, key="usage"),
|
||||||
"resp": requests.add_column("Resp", width=10, key="resp"),
|
"resp": requests.add_column("Resp", width=width_profile["resp"], key="resp"),
|
||||||
"chunks": requests.add_column("Chunks", width=14, key="chunks"),
|
"chunks": requests.add_column("Chunks", width=width_profile["chunks"], key="chunks"),
|
||||||
"first": requests.add_column("First", width=8, key="first"),
|
"first": requests.add_column("First", width=width_profile["first"], key="first"),
|
||||||
"duration": requests.add_column("Duration", width=8, key="duration"),
|
"duration": requests.add_column("Duration", width=width_profile["duration"], key="duration"),
|
||||||
"updated": requests.add_column("Updated", width=8, key="updated"),
|
"updated": requests.add_column("Updated", width=width_profile["updated"], key="updated"),
|
||||||
"note": requests.add_column("Note", width=22, key="note"),
|
"note": requests.add_column("Note", width=width_profile["note"], key="note"),
|
||||||
}
|
}
|
||||||
|
|
||||||
logs = self.query_one("#logs_table", DataTable)
|
logs = self.query_one("#logs_table", DataTable)
|
||||||
@@ -1200,7 +1239,7 @@ def run_textual(api_url: str, status_url: str, refresh_seconds: int, timeout: in
|
|||||||
self.query_one("#logs_table").display = active_table == "logs"
|
self.query_one("#logs_table").display = active_table == "logs"
|
||||||
self.query_one("#profiles_table").display = active_table == "profiles"
|
self.query_one("#profiles_table").display = active_table == "profiles"
|
||||||
self.query_one("#controls", Static).update(
|
self.query_one("#controls", Static).update(
|
||||||
"views: 1 overview | 2 requests | 3 logs | 4 profiles | / filter | r refresh | [ ] usage width | Shift-Left/Right scroll | e edit | p probe | s switch | w save | d delete | u open upstream"
|
"views: 1 overview | 2 requests | 3 logs | 4 profiles | / filter | r refresh | m compact/wide | [ ] usage width | Shift-Left/Right scroll | e edit | p probe | s switch | w save | d delete | u open upstream"
|
||||||
)
|
)
|
||||||
self._focus_table()
|
self._focus_table()
|
||||||
self._update_table_headers()
|
self._update_table_headers()
|
||||||
@@ -1452,6 +1491,23 @@ def run_textual(api_url: str, status_url: str, refresh_seconds: int, timeout: in
|
|||||||
table.refresh(layout=True)
|
table.refresh(layout=True)
|
||||||
self._set_status(f"usage column width {self.request_usage_width}")
|
self._set_status(f"usage column width {self.request_usage_width}")
|
||||||
|
|
||||||
|
def _apply_request_table_width_profile(self, density: str) -> None:
|
||||||
|
table = self.query_one("#requests_table", DataTable)
|
||||||
|
width_profile = self.request_table_width_profiles[density]
|
||||||
|
for name, key in self.request_table_column_keys.items():
|
||||||
|
column = table.columns.get(key)
|
||||||
|
if column is None or name not in width_profile:
|
||||||
|
continue
|
||||||
|
column.width = width_profile[name]
|
||||||
|
self.request_table_density = density
|
||||||
|
self.request_usage_width = width_profile["usage"]
|
||||||
|
table.refresh(layout=True)
|
||||||
|
self._set_status(f"request table mode {density}")
|
||||||
|
|
||||||
|
def action_toggle_request_table_density(self) -> None:
|
||||||
|
next_density = "wide" if self.request_table_density == "compact" else "compact"
|
||||||
|
self._apply_request_table_width_profile(next_density)
|
||||||
|
|
||||||
def action_widen_usage_column(self) -> None:
|
def action_widen_usage_column(self) -> None:
|
||||||
self._set_request_usage_width(self.request_usage_width + 4)
|
self._set_request_usage_width(self.request_usage_width + 4)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user