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
@@ -19,6 +19,8 @@ public sealed partial class WorktreesSettingsTabViewModel : ViewModelBase
[ObservableProperty] private string _statusMessage = "";
[ObservableProperty] private bool _isBusy;
public OperationStatus ResetStatus { get; } = new();
public IReadOnlyList<string> WorktreeStrategies { get; } = new[] { "sibling", "central" };
public WorktreesSettingsTabViewModel(IWorkerClient worker) => _worker = worker;
@@ -56,7 +58,8 @@ public sealed partial class WorktreesSettingsTabViewModel : ViewModelBase
[RelayCommand]
private async Task ConfirmResetAll()
{
ShowResetConfirm = false; IsBusy = true; StatusMessage = "";
ShowResetConfirm = false; StatusMessage = "";
using var op = ResetStatus.Begin(Loc.T("ops.worktrees.resetting"));
try
{
var r = await _worker.ResetAllWorktreesAsync();
@@ -65,6 +68,5 @@ public sealed partial class WorktreesSettingsTabViewModel : ViewModelBase
else StatusMessage = Loc.T("vm.worktreesTab.removedFrom", r.Removed, r.TasksAffected);
}
catch (Exception ex) { StatusMessage = Loc.T("vm.worktreesTab.resetFailed", ex.Message); }
finally { IsBusy = false; }
}
}