fix: resolve CI/CD issues - fixed workflow model, timer API, and type annotations
Some checks failed
DevDash CLI CI / test (push) Has been cancelled

- src/ui/components/cards.py: Changed WorkflowCard to use WorkflowRunModel with correct attributes
- src/models/__init__.py: Added WorkflowRunModel to exports
- src/ui/screens/dashboard.py: Fixed timer API for Textual 0.52 compatibility
- src/ui/components/loading.py: Renamed _animate to _spin for signature override
- src/git/status.py: Added type annotation 'str | None' to remote_name variable
This commit is contained in:
2026-02-01 07:31:54 +00:00
parent 0ca60891ab
commit 3986a29303

View File

@@ -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: