feat: A toggles the sessions column between active and archived
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+13
-2
@@ -73,6 +73,7 @@ class HqtApp(App):
|
||||
Binding("h", "focus_projects", "Projects"),
|
||||
Binding("l", "focus_sessions", "Sessions"),
|
||||
Binding("x", "archive_session", "Archive"),
|
||||
Binding("A", "toggle_archived", "Show Archived"),
|
||||
Binding("d", "delete_session", "Delete Session"),
|
||||
Binding("enter", "attach_session", "Attach", priority=True),
|
||||
Binding("r", "rename_session", "Rename"),
|
||||
@@ -91,6 +92,9 @@ class HqtApp(App):
|
||||
self.register_theme(FRAPPE_THEME)
|
||||
self.theme = "catppuccin-frappe"
|
||||
self._selected_project_id: int | None = None
|
||||
# When True, the Sessions column shows this project's archived sessions
|
||||
# instead of its active ones. Persists across project switches.
|
||||
self._show_archived = False
|
||||
# project_id -> last selected session_id, so switching projects restores
|
||||
# each project's previously highlighted session.
|
||||
self._selected_session_by_project: dict[int, int] = {}
|
||||
@@ -181,7 +185,7 @@ class HqtApp(App):
|
||||
except ServiceError as err:
|
||||
log.warning("Session poll failed: %s", err)
|
||||
return
|
||||
if self._selected_project_id is not None:
|
||||
if self._selected_project_id is not None and not self._show_archived:
|
||||
subset = [
|
||||
i for i in infos if i.session.project_id == self._selected_project_id
|
||||
]
|
||||
@@ -190,7 +194,9 @@ class HqtApp(App):
|
||||
async def _refresh_sessions(self, restore_selection: bool = False) -> None:
|
||||
if self._selected_project_id is None:
|
||||
return
|
||||
infos = await self._sessions().list_sessions(self._selected_project_id)
|
||||
infos = await self._sessions().list_sessions(
|
||||
self._selected_project_id, archived=self._show_archived
|
||||
)
|
||||
sl = self.query_one(SessionList)
|
||||
if restore_selection:
|
||||
# Project switch: restore this project's remembered session, or let the
|
||||
@@ -448,6 +454,11 @@ class HqtApp(App):
|
||||
|
||||
self._run_service_worker(_do())
|
||||
|
||||
def action_toggle_archived(self) -> None:
|
||||
self._show_archived = not self._show_archived
|
||||
self.query_one(SessionList).set_mode(archived=self._show_archived)
|
||||
self._run_service_worker(self._refresh_sessions(restore_selection=True))
|
||||
|
||||
def action_schedule_prompt(self) -> None:
|
||||
sid = self.query_one(SessionList).get_selected_session_id()
|
||||
if sid is None:
|
||||
|
||||
+40
-1
@@ -310,7 +310,7 @@ async def test_new_session_on_dismiss_sequential_create_then_refresh():
|
||||
session=MagicMock(), spawn_ok=True, spawn_error=""
|
||||
)
|
||||
|
||||
async def fake_list(project_id):
|
||||
async def fake_list(project_id, archived=False):
|
||||
call_order.append("list")
|
||||
return []
|
||||
|
||||
@@ -2088,3 +2088,42 @@ async def test_archive_session_action_calls_service_and_refreshes():
|
||||
|
||||
mock_service.archive_session.assert_awaited_once_with(sess_id)
|
||||
mock_service.list_sessions.assert_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_toggle_archived_binding_exists():
|
||||
bindings = {b.key: b for b in HqtApp.BINDINGS}
|
||||
assert bindings["A"].action == "toggle_archived"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_toggle_archived_switches_list_and_header():
|
||||
app = HqtApp()
|
||||
async with app.run_test(size=(120, 40)) as pilot:
|
||||
from hqt.tui.widgets.session_list import SessionList
|
||||
from textual.widgets import Label
|
||||
|
||||
proj_id = 42
|
||||
app._selected_project_id = proj_id
|
||||
|
||||
mock_service = MagicMock()
|
||||
mock_service.list_sessions = AsyncMock(return_value=[])
|
||||
mock_service.sync_window_labels = AsyncMock(return_value=[])
|
||||
app._session_service = mock_service
|
||||
|
||||
assert app._show_archived is False
|
||||
|
||||
await app.run_action("toggle_archived")
|
||||
await pilot.pause()
|
||||
|
||||
assert app._show_archived is True
|
||||
mock_service.list_sessions.assert_awaited_with(proj_id, archived=True)
|
||||
header = app.query_one(SessionList).query_one("#session-header", Label)
|
||||
assert "archived" in str(header.render()).lower()
|
||||
|
||||
await app.run_action("toggle_archived")
|
||||
await pilot.pause()
|
||||
|
||||
assert app._show_archived is False
|
||||
mock_service.list_sessions.assert_awaited_with(proj_id, archived=False)
|
||||
assert str(header.render()) == "Sessions"
|
||||
|
||||
Reference in New Issue
Block a user