diff --git a/src/ui/screens/dashboard.py b/src/ui/screens/dashboard.py index f2b3f5a..6bd43c3 100644 --- a/src/ui/screens/dashboard.py +++ b/src/ui/screens/dashboard.py @@ -1,6 +1,7 @@ """Main dashboard screen for DevDash.""" from datetime import datetime +from typing import Any from textual.app import ComposeResult from textual.containers import Container @@ -193,7 +194,7 @@ class DashboardScreen(Container): def stop_auto_refresh(self) -> None: """Stop automatic data refresh.""" if self._timer_id: - self.clear_interval(self._timer_id) + self._timer_id.stop() self._timer_id = None def action_refresh(self) -> None: @@ -228,56 +229,65 @@ class DashboardScreen(Container): def update_header(self) -> None: """Update header with current state.""" if self.repo: - repo_info = self.query_one("#repo-info") + repo_info: Static = self.query_one("#repo-info") repo_info.update(f"[bold]Repository:[/] {self.repo} ({self.provider})") if self.last_refresh: - timer = self.query_one("#refresh-timer") + timer: Static = self.query_one("#refresh-timer") timer.update(f"[dim]Last refresh:[/] {self.last_refresh.strftime('%H:%M:%S')}") + def _build_git_status_lines(self, status: Any) -> list[str]: + """Build git status display lines. + + Args: + status: GitStatus object. + + Returns: + List of formatted status lines. + """ + lines = [] + lines.append(f"[bold]Branch:[/] {status.branch}") + lines.append(f"[bold]Commit:[/] {status.commit_hash[:7]}") + + if status.commit_message: + lines.append(f"[dim]{status.commit_message[:40]}[/]") + + lines.append("") + + if status.is_detached: + lines.append("[yellow]![/] Detached HEAD") + else: + status_indicator = "[green]✓[/] Clean" if status.is_clean else "[yellow]![/] Uncommitted changes" + lines.append(f"[bold]Status:[/] {status_indicator}") + + file_changes = [] + if status.staged_files > 0: + file_changes.append(f"[green]+{status.staged_files}[/]") + if status.unstaged_files > 0: + file_changes.append(f"[yellow]~{status.unstaged_files}[/]") + if status.untracked_files > 0: + file_changes.append(f"[red]?{status.untracked_files}[/]") + + if file_changes: + lines.append(f"[bold]Changes:[/] {' '.join(file_changes)}") + + if status.ahead > 0 or status.behind > 0: + sync_info = [] + if status.ahead > 0: + sync_info.append(f"[green]+{status.ahead}[/]") + if status.behind > 0: + sync_info.append(f"[red]-{status.behind}[/]") + lines.append(f"[bold]Sync:[/] {' '.join(sync_info)}") + + return lines + def update_git_status(self) -> None: """Update git status panel.""" git_panel = self.query_one("#git-status") try: status = get_git_status() - - status_indicator = "[green]✓[/] Clean" if status.is_clean else "[yellow]![/] Uncommitted changes" - - lines = [ - f"[bold]Branch:[/] {status.branch}", - f"[bold]Commit:[/] {status.commit_hash[:7]}", - ] - - if status.commit_message: - lines.append(f"[dim]{status.commit_message[:40]}[/]") - - lines.append("") - - if status.is_detached: - lines.append("[yellow]![/] Detached HEAD") - else: - lines.append(f"[bold]Status:[/] {status_indicator}") - - file_changes = [] - if status.staged_files > 0: - file_changes.append(f"[green]+{status.staged_files}[/]") - if status.unstaged_files > 0: - file_changes.append(f"[yellow]~{status.unstaged_files}[/]") - if status.untracked_files > 0: - file_changes.append(f"[red]?{status.untracked_files}[/]") - - if file_changes: - lines.append(f"[bold]Changes:[/] {' '.join(file_changes)}") - - if status.ahead > 0 or status.behind > 0: - sync_info = [] - if status.ahead > 0: - sync_info.append(f"[green]+{status.ahead}[/]") - if status.behind > 0: - sync_info.append(f"[red]-{status.behind}[/]") - lines.append(f"[bold]Sync:[/] {' '.join(sync_info)}") - + lines = self._build_git_status_lines(status) git_panel.update("\n".join(lines)) except GitStatusError as e: