i think it works
This commit is contained in:
41
app.py
41
app.py
@@ -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")
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user