feat(ui): add Continue and Reset commands to DetailsIslandViewModel
This commit is contained in:
@@ -39,11 +39,21 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
public bool IsDone => AgentStatusLabel == "Done";
|
public bool IsDone => AgentStatusLabel == "Done";
|
||||||
public bool IsFailed => AgentStatusLabel == "Failed";
|
public bool IsFailed => AgentStatusLabel == "Failed";
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
[NotifyCanExecuteChangedFor(nameof(ContinueCommand))]
|
||||||
|
[NotifyCanExecuteChangedFor(nameof(ResetCommand))]
|
||||||
|
private bool _showFailedActions;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
[NotifyCanExecuteChangedFor(nameof(ContinueCommand))]
|
||||||
|
private string? _latestRunSessionId;
|
||||||
|
|
||||||
partial void OnAgentStatusLabelChanged(string value)
|
partial void OnAgentStatusLabelChanged(string value)
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(IsRunning));
|
OnPropertyChanged(nameof(IsRunning));
|
||||||
OnPropertyChanged(nameof(IsDone));
|
OnPropertyChanged(nameof(IsDone));
|
||||||
OnPropertyChanged(nameof(IsFailed));
|
OnPropertyChanged(nameof(IsFailed));
|
||||||
|
ShowFailedActions = value == "Failed";
|
||||||
}
|
}
|
||||||
[ObservableProperty] private string? _model;
|
[ObservableProperty] private string? _model;
|
||||||
[ObservableProperty] private string? _worktreePath;
|
[ObservableProperty] private string? _worktreePath;
|
||||||
@@ -108,11 +118,15 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
// Subscribe once; filter by current task id inside the handler
|
// Subscribe once; filter by current task id inside the handler
|
||||||
_worker.TaskMessageEvent += OnTaskMessage;
|
_worker.TaskMessageEvent += OnTaskMessage;
|
||||||
|
|
||||||
// Re-evaluate RunNow CanExecute when worker connection flips.
|
// Re-evaluate CanExecute when worker connection flips.
|
||||||
_worker.PropertyChanged += (_, e) =>
|
_worker.PropertyChanged += (_, e) =>
|
||||||
{
|
{
|
||||||
if (e.PropertyName == nameof(WorkerClient.IsConnected))
|
if (e.PropertyName == nameof(WorkerClient.IsConnected))
|
||||||
|
{
|
||||||
RunNowCommand.NotifyCanExecuteChanged();
|
RunNowCommand.NotifyCanExecuteChanged();
|
||||||
|
ContinueCommand.NotifyCanExecuteChanged();
|
||||||
|
ResetCommand.NotifyCanExecuteChanged();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the task row's live status changes (e.g. TaskStarted/Finished), mirror it.
|
// If the task row's live status changes (e.g. TaskStarted/Finished), mirror it.
|
||||||
@@ -215,6 +229,8 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
WorktreePath = null;
|
WorktreePath = null;
|
||||||
BranchLine = null;
|
BranchLine = null;
|
||||||
AgentStatusLabel = "Idle";
|
AgentStatusLabel = "Idle";
|
||||||
|
LatestRunSessionId = null;
|
||||||
|
ShowFailedActions = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,6 +259,11 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
BranchLine = entity.Worktree is { } w ? $"{w.BranchName} \u2190 main" : null;
|
BranchLine = entity.Worktree is { } w ? $"{w.BranchName} \u2190 main" : null;
|
||||||
AgentStatusLabel = entity.Status.ToString();
|
AgentStatusLabel = entity.Status.ToString();
|
||||||
|
|
||||||
|
var runRepo = new TaskRunRepository(ctx);
|
||||||
|
var latestRun = await runRepo.GetLatestByTaskIdAsync(row.Id, ct);
|
||||||
|
ct.ThrowIfCancellationRequested();
|
||||||
|
LatestRunSessionId = latestRun?.SessionId;
|
||||||
|
|
||||||
// Subscribe only after DB load confirms the task exists
|
// Subscribe only after DB load confirms the task exists
|
||||||
_subscribedTaskId = row.Id;
|
_subscribedTaskId = row.Id;
|
||||||
|
|
||||||
@@ -391,6 +412,32 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
|
|
||||||
private bool CanRunNow() =>
|
private bool CanRunNow() =>
|
||||||
Task != null && _worker.IsConnected && !IsRunning;
|
Task != null && _worker.IsConnected && !IsRunning;
|
||||||
|
|
||||||
|
[RelayCommand(CanExecute = nameof(CanContinue))]
|
||||||
|
private async System.Threading.Tasks.Task ContinueAsync()
|
||||||
|
{
|
||||||
|
if (Task == null) return;
|
||||||
|
await _worker.ContinueTaskAsync(Task.Id, "Continue working on this task.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanContinue() =>
|
||||||
|
Task != null && _worker.IsConnected && ShowFailedActions && !string.IsNullOrEmpty(LatestRunSessionId);
|
||||||
|
|
||||||
|
[RelayCommand(CanExecute = nameof(CanReset))]
|
||||||
|
private async System.Threading.Tasks.Task ResetAsync()
|
||||||
|
{
|
||||||
|
if (Task == null) return;
|
||||||
|
if (ConfirmAsync != null)
|
||||||
|
{
|
||||||
|
var branchName = $"claudedo/{Task.Id.Replace("-", "")}";
|
||||||
|
var ok = await ConfirmAsync($"Discard worktree and reset task?\nThis deletes branch {branchName} and all uncommitted changes.");
|
||||||
|
if (!ok) return;
|
||||||
|
}
|
||||||
|
await _worker.ResetTaskAsync(Task.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanReset() =>
|
||||||
|
Task != null && _worker.IsConnected && ShowFailedActions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed partial class SubtaskRowViewModel : ViewModelBase
|
public sealed partial class SubtaskRowViewModel : ViewModelBase
|
||||||
|
|||||||
Reference in New Issue
Block a user