feat(ui): separate OperationStatus per worktree action (refresh/cleanup/reset/force-remove/batch-merge)

Replaces the shared IsBusy/IsMerging flags in WorktreesOverviewModalViewModel and the
reset flow in WorktreesSettingsTabViewModel with dedicated OperationStatus instances
shown via OperationIndicator, so a running Refresh no longer blocks the Cleanup
indicator. ForceRemove gains a CanExecute guard against re-entrancy while it's running,
and the reconcile tick's busy guard now checks all four action statuses instead of the
old IsBusy||IsMerging pair.
This commit is contained in:
Mika Kuns
2026-08-12 09:39:10 +02:00
parent d3abd4b88b
commit a0d5db0db0
8 changed files with 189 additions and 100 deletions
@@ -117,4 +117,29 @@ public class WorktreesOverviewReconcileTickTests
Assert.False(vm.Rows.Single(r => r.TaskId == "d").IsChecked);
Assert.Equal(1, vm.SelectedCount);
}
[Theory]
[InlineData("refresh")]
[InlineData("cleanup")]
[InlineData("forceRemove")]
[InlineData("batchMerge")]
public async Task Tick_skips_the_reload_while_any_action_status_is_running(string which)
{
var (vm, worker) = await BuildLoadedAsync();
var status = which switch
{
"refresh" => vm.RefreshStatus,
"cleanup" => vm.CleanupStatus,
"forceRemove" => vm.ForceRemoveStatus,
"batchMerge" => vm.BatchMergeStatus,
_ => throw new ArgumentOutOfRangeException(nameof(which)),
};
using var op = status.Begin("running");
worker.Worktrees.Add(Wt("d"));
await vm.ReconcileTickAsync();
Assert.DoesNotContain(vm.Rows, r => r.TaskId == "d");
}
}