feat: processing flow enhancement + responsive UI

Phase 2 - Processing flow:
- Multi-task monitoring: store supports concurrent task tracking
- Task retry: POST /api/tasks/{id}/retry re-runs failed tasks
- Dashboard multi-task cards with progress, error details, retry/dismiss
- Log panel expanded from 10 to 50 lines with "view all" link

Phase 3 - UI/UX:
- Mobile sidebar drawer (< 768px) with hamburger menu
- Layout responsive styles (768px, 480px breakpoints)
- Tasks/Logs pages responsive (stat cards, filters, columns)
- File views responsive (header wrap, button sizing)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-13 19:18:18 +08:00
parent 32af38fe2a
commit 7baf784a39
11 changed files with 585 additions and 101 deletions
+20 -1
View File
@@ -28,9 +28,10 @@ class Task:
result_files: List[str] = field(default_factory=list)
error: Optional[str] = None
log_lines: List[str] = field(default_factory=list)
metadata: Optional[dict] = None
def to_dict(self) -> dict:
return {
d = {
"task_id": self.id,
"name": self.name,
"status": self.status.value,
@@ -40,6 +41,9 @@ class Task:
"error": self.error,
"log_lines": self.log_lines[-100:],
}
if self.metadata:
d["metadata"] = self.metadata
return d
class TaskManager:
@@ -135,6 +139,21 @@ class TaskManager:
)
self._schedule(self._broadcast(task_id))
def retry_task(self, task_id: str) -> Optional[Task]:
"""Create a new task to retry a failed task with its original parameters.
Returns the new task if the original was failed and retryable, else None.
The caller is responsible for dispatching the actual work based on
``new_task.metadata``.
"""
original = self._tasks.get(task_id)
if not original or original.status != TaskStatus.FAILED:
return None
new_task = self.create_task(original.name)
if original.metadata:
new_task.metadata = dict(original.metadata)
return new_task
def set_failed(self, task_id: str, error: str):
task = self._tasks.get(task_id)
if not task: