From f3bb38aea10ac29eb8eed7e419665c2bcae91320 Mon Sep 17 00:00:00 2001 From: Joe Fleming Date: Sat, 7 Mar 2026 17:04:48 -0700 Subject: [PATCH] i think it works --- app.py | 53 +++++++++++++++++++++++++++++++++++++++++++---------- database.py | 9 +++++++++ 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/app.py b/app.py index 0cda6f8..2ea29ab 100644 --- a/app.py +++ b/app.py @@ -33,11 +33,14 @@ class MoveCopyDialog(ModalScreen): # Get currently selected project from tree to exclude from destination list current_project_id = self.app.filter_project_id if hasattr(self.app, 'filter_project_id') else None - project_options = [ - (os.path.basename(p.worktree) if p.worktree else (p.name or p.id), p.id) - for p in self.db.projects.values() - if p.id != current_project_id # Exclude current project - ] + project_options = sorted( + [ + (os.path.basename(p.worktree) if p.worktree else (p.name or p.id), p.id) + for p in self.db.projects.values() + if p.id != current_project_id + ], + key=lambda x: x[0].lower() + ) if not project_options: project_options = [("-- Same project --", "")] @@ -143,6 +146,7 @@ class MoveCopyDialog(ModalScreen): # Get reference to main app and refresh app = self.app if hasattr(app, 'refresh_sessions'): + app.refresh_project_list() app.refresh_sessions() else: self.app.notify(f"Operation failed: {sql}", severity="error") @@ -238,6 +242,20 @@ class SessionMoverApp(App): border: solid $primary-lighten-2; } + .proj-row { + width: 100%; + height: 1; + } + + .proj-name { + width: 1fr; + } + + .proj-count { + width: auto; + color: $text-muted; + } + #filter-bar { height: auto; padding: 0 0 1 0; @@ -420,13 +438,21 @@ class SessionMoverApp(App): lv.clear() self._project_ids = [] + counts = self.db.get_session_counts_by_project() projects = sorted( self.db.projects.values(), key=lambda p: (os.path.basename(p.worktree) if p.worktree else (p.name or "")).lower() ) for proj in projects: proj_name = os.path.basename(proj.worktree) if proj.worktree else (proj.name or "Unknown") - lv.append(ListItem(Label(proj_name))) + count = counts.get(proj.id, 0) + lv.append(ListItem( + Horizontal( + Label(proj_name, classes="proj-name"), + Label(f"({count})", classes="proj-count"), + classes="proj-row", + ) + )) self._project_ids.append(proj.id) def refresh_sessions(self) -> None: @@ -477,12 +503,18 @@ class SessionMoverApp(App): count_widget.update("0 selected") def on_descendant_focus(self, event) -> None: - table = self.query_one("#sessions-table", DataTable) - table.show_cursor = table.has_focus + try: + table = self.query_one("#sessions-table", DataTable) + table.show_cursor = table.has_focus + except Exception: + pass def on_descendant_blur(self, event) -> None: - table = self.query_one("#sessions-table", DataTable) - table.show_cursor = table.has_focus + try: + table = self.query_one("#sessions-table", DataTable) + table.show_cursor = table.has_focus + except Exception: + pass def on_list_view_highlighted(self, event: ListView.Highlighted) -> None: """Handle project list selection.""" @@ -595,6 +627,7 @@ class SessionMoverApp(App): if success: self.selected_session_ids.clear() self.notify(f"Deleted {len(sessions)} session(s)", severity="information") + self.refresh_project_list() self.refresh_sessions() else: self.notify(f"Delete failed: {err}", severity="error") diff --git a/database.py b/database.py index a65f311..8876368 100644 --- a/database.py +++ b/database.py @@ -201,6 +201,15 @@ class Database: result.append((proj.name or proj.worktree, ws_names, has_workspaces)) return sorted(result) + def get_session_counts_by_project(self) -> dict: + """Return a dict of project_id -> active session count.""" + assert self.conn is not None + cursor = self.conn.cursor() + cursor.execute( + "SELECT project_id, COUNT(*) FROM session WHERE time_archived IS NULL GROUP BY project_id" + ) + return {row[0]: row[1] for row in cursor.fetchall()} + def get_session(self, session_id: str) -> Optional[Session]: """Get a single session by ID.""" sessions = self.get_sessions(include_archived=True)