fix(claude-do): Fix: Statuswechsel schlägt in Task-Row und Detail-Pane erst

## Problem (vom Nutzer bestätigt am 2026-08-05)
Wechselt ein Task den Status, bleiben zwei Stellen stehen, bis man die Liste wechselt und zurückwechselt:

1. **Task-Row in der offenen Liste** (mittlere Insel) — Status-Chip und Gruppen-Einordnung aktualisieren sich nicht.
2. **Detail-Pane des ausgewählten Tasks** (rechte Insel) — Status, Review-Buttons und Header-Bar zeigen weiter den alten Zustand

ClaudeDo-Task: 181d4abf368046b99bd57d5e2a7ab97a
This commit is contained in:
mika kuns
2026-08-05 09:19:10 +02:00
parent 63d8b5c28d
commit 3a07b319f9
4 changed files with 274 additions and 3 deletions
@@ -363,6 +363,10 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
{
if (Task?.IsPlanningParent == true) _ = RefreshPlanningChildAsync(taskId);
_ = RefreshChildOutcomeAsync(taskId);
// The bound row's own status can change from outside (worker run, MCP tool, another
// session) — refresh it directly instead of relying on TasksIslandViewModel mutating
// the same instance, so the detail pane stays correct even if that row was replaced.
if (Task?.Id == taskId) _ = RefreshBoundTaskAsync(taskId);
};
_worker.TaskUpdatedEvent += _workerTaskUpdatedHandler;
@@ -764,6 +768,27 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
catch { /* best-effort */ }
}
// Refreshes the bound row itself (status, planning phase, worktree/branch mirrors, etc.) from
// the DB. Kept independent of TasksIslandViewModel's own handler: the row instance backing
// Task may have been replaced by a full list reload, so this must not assume it stayed live.
private async System.Threading.Tasks.Task RefreshBoundTaskAsync(string taskId)
{
try
{
await using var ctx = await _dbFactory.CreateDbContextAsync();
var entity = await ctx.Tasks
.AsNoTracking()
.Include(t => t.Worktree)
.Include(t => t.List)
.FirstOrDefaultAsync(t => t.Id == taskId);
if (entity is null || Task?.Id != taskId) return;
Task.UpdateFromEntity(entity);
OnPropertyChanged(nameof(CanPickUpInTerminal));
OnPropertyChanged(nameof(CanAcceptDrop));
}
catch { /* best-effort */ }
}
private async System.Threading.Tasks.Task RefreshWorktreeAsync(string taskId)
{
try