i think it works

This commit is contained in:
Joe Fleming
2026-03-07 17:04:48 -07:00
parent c3c8683f53
commit f3bb38aea1
2 changed files with 52 additions and 10 deletions

41
app.py
View File

@@ -33,11 +33,14 @@ class MoveCopyDialog(ModalScreen):
# Get currently selected project from tree to exclude from destination list # 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 current_project_id = self.app.filter_project_id if hasattr(self.app, 'filter_project_id') else None
project_options = [ project_options = sorted(
[
(os.path.basename(p.worktree) if p.worktree else (p.name or p.id), p.id) (os.path.basename(p.worktree) if p.worktree else (p.name or p.id), p.id)
for p in self.db.projects.values() for p in self.db.projects.values()
if p.id != current_project_id # Exclude current project if p.id != current_project_id
] ],
key=lambda x: x[0].lower()
)
if not project_options: if not project_options:
project_options = [("-- Same project --", "")] project_options = [("-- Same project --", "")]
@@ -143,6 +146,7 @@ class MoveCopyDialog(ModalScreen):
# Get reference to main app and refresh # Get reference to main app and refresh
app = self.app app = self.app
if hasattr(app, 'refresh_sessions'): if hasattr(app, 'refresh_sessions'):
app.refresh_project_list()
app.refresh_sessions() app.refresh_sessions()
else: else:
self.app.notify(f"Operation failed: {sql}", severity="error") self.app.notify(f"Operation failed: {sql}", severity="error")
@@ -238,6 +242,20 @@ class SessionMoverApp(App):
border: solid $primary-lighten-2; border: solid $primary-lighten-2;
} }
.proj-row {
width: 100%;
height: 1;
}
.proj-name {
width: 1fr;
}
.proj-count {
width: auto;
color: $text-muted;
}
#filter-bar { #filter-bar {
height: auto; height: auto;
padding: 0 0 1 0; padding: 0 0 1 0;
@@ -420,13 +438,21 @@ class SessionMoverApp(App):
lv.clear() lv.clear()
self._project_ids = [] self._project_ids = []
counts = self.db.get_session_counts_by_project()
projects = sorted( projects = sorted(
self.db.projects.values(), self.db.projects.values(),
key=lambda p: (os.path.basename(p.worktree) if p.worktree else (p.name or "")).lower() key=lambda p: (os.path.basename(p.worktree) if p.worktree else (p.name or "")).lower()
) )
for proj in projects: for proj in projects:
proj_name = os.path.basename(proj.worktree) if proj.worktree else (proj.name or "Unknown") 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) self._project_ids.append(proj.id)
def refresh_sessions(self) -> None: def refresh_sessions(self) -> None:
@@ -477,12 +503,18 @@ class SessionMoverApp(App):
count_widget.update("0 selected") count_widget.update("0 selected")
def on_descendant_focus(self, event) -> None: def on_descendant_focus(self, event) -> None:
try:
table = self.query_one("#sessions-table", DataTable) table = self.query_one("#sessions-table", DataTable)
table.show_cursor = table.has_focus table.show_cursor = table.has_focus
except Exception:
pass
def on_descendant_blur(self, event) -> None: def on_descendant_blur(self, event) -> None:
try:
table = self.query_one("#sessions-table", DataTable) table = self.query_one("#sessions-table", DataTable)
table.show_cursor = table.has_focus table.show_cursor = table.has_focus
except Exception:
pass
def on_list_view_highlighted(self, event: ListView.Highlighted) -> None: def on_list_view_highlighted(self, event: ListView.Highlighted) -> None:
"""Handle project list selection.""" """Handle project list selection."""
@@ -595,6 +627,7 @@ class SessionMoverApp(App):
if success: if success:
self.selected_session_ids.clear() self.selected_session_ids.clear()
self.notify(f"Deleted {len(sessions)} session(s)", severity="information") self.notify(f"Deleted {len(sessions)} session(s)", severity="information")
self.refresh_project_list()
self.refresh_sessions() self.refresh_sessions()
else: else:
self.notify(f"Delete failed: {err}", severity="error") self.notify(f"Delete failed: {err}", severity="error")

View File

@@ -201,6 +201,15 @@ class Database:
result.append((proj.name or proj.worktree, ws_names, has_workspaces)) result.append((proj.name or proj.worktree, ws_names, has_workspaces))
return sorted(result) 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]: def get_session(self, session_id: str) -> Optional[Session]:
"""Get a single session by ID.""" """Get a single session by ID."""
sessions = self.get_sessions(include_archived=True) sessions = self.get_sessions(include_archived=True)