feat(ui): surface review actions and WaitingForReview status in task rows
Adds Approve/Reject/Park/Cancel buttons with a feedback flyout, a review status chip, and a friendly status label for WaitingForReview tasks. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -63,6 +63,7 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
public bool HasSteps => StepsCount > 0;
|
||||
public bool IsOverdue => ScheduledFor is { } d && d.Date < DateTime.Today && !Done;
|
||||
public bool IsRunning => Status == TaskStatus.Running;
|
||||
public bool IsWaitingForReview => Status == TaskStatus.WaitingForReview;
|
||||
public bool IsQueued => Status == TaskStatus.Queued && string.IsNullOrEmpty(BlockedByTaskId);
|
||||
public bool IsWaiting => Status == TaskStatus.Queued && !string.IsNullOrEmpty(BlockedByTaskId);
|
||||
public bool CanRemoveFromQueue => IsQueued || HasQueuedSubtasks;
|
||||
@@ -78,20 +79,25 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
public string DiffDeletionsText => $"−{DiffDeletions}";
|
||||
public string StepsText => $"{StepsCompleted}/{StepsCount} steps";
|
||||
|
||||
public string StatusLabel => Status == TaskStatus.WaitingForReview ? "Waiting for Review" : Status.ToString();
|
||||
|
||||
public string StatusChipClass => (Status, IsBlocked: !string.IsNullOrEmpty(BlockedByTaskId)) switch
|
||||
{
|
||||
(TaskStatus.Running, _) => "running",
|
||||
(TaskStatus.Failed, _) => "error",
|
||||
(TaskStatus.Done, _) => "review",
|
||||
(TaskStatus.Queued, true) => "waiting",
|
||||
(TaskStatus.Queued, false) => "queued",
|
||||
_ => "idle",
|
||||
(TaskStatus.Running, _) => "running",
|
||||
(TaskStatus.WaitingForReview, _) => "review",
|
||||
(TaskStatus.Failed, _) => "error",
|
||||
(TaskStatus.Done, _) => "done",
|
||||
(TaskStatus.Queued, true) => "waiting",
|
||||
(TaskStatus.Queued, false) => "queued",
|
||||
_ => "idle",
|
||||
};
|
||||
|
||||
partial void OnStatusChanged(TaskStatus value)
|
||||
{
|
||||
OnPropertyChanged(nameof(StatusChipClass));
|
||||
OnPropertyChanged(nameof(StatusLabel));
|
||||
OnPropertyChanged(nameof(IsRunning));
|
||||
OnPropertyChanged(nameof(IsWaitingForReview));
|
||||
OnPropertyChanged(nameof(IsQueued));
|
||||
OnPropertyChanged(nameof(IsWaiting));
|
||||
OnPropertyChanged(nameof(IsDraft));
|
||||
|
||||
@@ -602,6 +602,42 @@ public sealed partial class TasksIslandViewModel : ViewModelBase
|
||||
catch { /* worker offline; the broadcast will reconcile when it returns */ }
|
||||
}
|
||||
|
||||
// ── Review actions (visible when a task is WaitingForReview) ─────────────
|
||||
// Each delegates to the worker hub, which performs the transition and
|
||||
// broadcasts TaskUpdated; the row refreshes from that broadcast.
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ApproveReviewAsync(TaskRowViewModel? row)
|
||||
{
|
||||
if (row is null || !row.IsWaitingForReview || _worker is null) return;
|
||||
try { await _worker.ApproveReviewAsync(row.Id); }
|
||||
catch { /* offline; broadcast reconciles on return */ }
|
||||
}
|
||||
|
||||
public async Task RejectReviewToQueueAsync(TaskRowViewModel row, string feedback)
|
||||
{
|
||||
if (!row.IsWaitingForReview || _worker is null) return;
|
||||
if (string.IsNullOrWhiteSpace(feedback)) return;
|
||||
try { await _worker.RejectReviewToQueueAsync(row.Id, feedback); }
|
||||
catch { /* offline; broadcast reconciles on return */ }
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task RejectReviewToIdleAsync(TaskRowViewModel? row)
|
||||
{
|
||||
if (row is null || !row.IsWaitingForReview || _worker is null) return;
|
||||
try { await _worker.RejectReviewToIdleAsync(row.Id); }
|
||||
catch { /* offline; broadcast reconciles on return */ }
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task CancelReviewAsync(TaskRowViewModel? row)
|
||||
{
|
||||
if (row is null || !row.IsWaitingForReview || _worker is null) return;
|
||||
try { await _worker.CancelReviewAsync(row.Id); }
|
||||
catch { /* offline; broadcast reconciles on return */ }
|
||||
}
|
||||
|
||||
public async Task SetScheduledForAsync(TaskRowViewModel row, DateTime? when)
|
||||
{
|
||||
if (row is null) return;
|
||||
|
||||
Reference in New Issue
Block a user