feat(ui): merge action and robust jump-to-task in worktrees overview
Add Merge entry to the worktrees overview context menu wiring the existing MergeModalViewModel, replace fire-and-forget list selection with a collection-change-aware JumpToTaskHelper, and propagate list renames to visible task rows via a new ListUpdated event. Harden worktree state changes: WorkerHub.SetWorktreeState now rejects invalid transitions, WorktreeMaintenanceService only drops the DB row when the on-disk worktree was actually removed, and Cleanup/Reset broadcast WorktreeUpdated for affected tasks. SetWorktreeStateAsync returns the hub error message so the modal can surface it. Also: de-duplicate the worktrees overview modal opener, hook OnParentTaskIdChanged to refresh IsDraft, fix MergeModal CanExecute notifications, and add WorktreeStateHubTests for the transition rules. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,7 @@ public sealed partial class TasksIslandViewModel : ViewModelBase
|
||||
_worker.TaskUpdatedEvent += OnWorkerTaskUpdated;
|
||||
_worker.WorktreeUpdatedEvent += OnWorkerTaskUpdated;
|
||||
_worker.TaskMessageEvent += OnWorkerTaskMessage;
|
||||
_worker.ListUpdatedEvent += OnWorkerListUpdated;
|
||||
_worker.ConnectionRestoredEvent += () => LoadForList(_currentList);
|
||||
}
|
||||
}
|
||||
@@ -67,6 +68,29 @@ public sealed partial class TasksIslandViewModel : ViewModelBase
|
||||
if (row is not null) row.LiveTail = line;
|
||||
}
|
||||
|
||||
private async void OnWorkerListUpdated(string listId)
|
||||
{
|
||||
// Mirror the renamed list onto every task row that references it,
|
||||
// so the per-row ListName chip on virtual lists stays current.
|
||||
try
|
||||
{
|
||||
await using var db = await _dbFactory.CreateDbContextAsync();
|
||||
var entity = await db.Lists.AsNoTracking().FirstOrDefaultAsync(l => l.Id == listId);
|
||||
if (entity is null) return;
|
||||
var visibleIds = Items.Select(r => r.Id).ToHashSet();
|
||||
if (visibleIds.Count == 0) return;
|
||||
var matchingIds = await db.Tasks.AsNoTracking()
|
||||
.Where(t => t.ListId == listId && visibleIds.Contains(t.Id))
|
||||
.Select(t => t.Id)
|
||||
.ToListAsync();
|
||||
var matching = matchingIds.ToHashSet();
|
||||
foreach (var row in Items)
|
||||
if (matching.Contains(row.Id) && row.ListName != entity.Name)
|
||||
row.ListName = entity.Name;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private async void OnWorkerTaskUpdated(string taskId)
|
||||
{
|
||||
var list = _currentList;
|
||||
|
||||
Reference in New Issue
Block a user