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
@@ -98,7 +98,7 @@ public class WorktreesOverviewBatchMergeTests
Assert.Equal(BatchMergeOutcome.Blocked, a.MergeOutcome);
Assert.Equal(BatchMergeOutcome.Failed, b.MergeOutcome);
Assert.Empty(vm.ConflictRows);
Assert.False(vm.IsMerging);
Assert.False(vm.BatchMergeStatus.IsRunning);
}
[Fact]
@@ -164,7 +164,40 @@ public class WorktreesOverviewBatchMergeTests
Assert.False(vm.MergeAllCommand.CanExecute(null));
vm.SelectedTarget = "main";
Assert.True(vm.MergeAllCommand.CanExecute(null));
vm.IsMerging = true;
Assert.False(vm.MergeAllCommand.CanExecute(null));
using (vm.BatchMergeStatus.Begin("merging"))
{
Assert.False(vm.MergeAllCommand.CanExecute(null));
}
Assert.True(vm.MergeAllCommand.CanExecute(null));
}
[Fact]
public void MergeAll_CanExecuteChanged_fires_when_batch_status_changes()
{
var vm = NewVm();
var a = ActiveRow("a"); a.IsChecked = true;
vm.AddRowForTest(a);
vm.SelectedTarget = "main";
var raised = 0;
vm.MergeAllCommand.CanExecuteChanged += (_, _) => raised++;
using (vm.BatchMergeStatus.Begin("merging")) { }
Assert.Equal(2, raised);
}
[Fact]
public void ForceRemove_canExecute_is_false_while_a_removal_is_in_flight()
{
var vm = NewVm();
var row = ActiveRow("a");
Assert.True(vm.ForceRemoveCommand.CanExecute(row));
using (vm.ForceRemoveStatus.Begin("removing"))
{
Assert.False(vm.ForceRemoveCommand.CanExecute(row));
}
Assert.True(vm.ForceRemoveCommand.CanExecute(row));
}
}