feat(ui): add "move to list" to the task row context menu

Reuses the existing drag-drop move (MoveTaskToListAsync) so the same
running/worktree guards apply — only ListId changes.

Also count WaitingForReview tasks (not Done-with-a-branch) for the
review portion of the status pill, and localize the pill and open-task
count strings that were still hardcoded English.
This commit is contained in:
mika kuns
2026-09-02 10:00:21 +02:00
parent c347e4fc5f
commit 80fe188a48
4 changed files with 34 additions and 5 deletions
@@ -6,6 +6,7 @@ using Avalonia.Interactivity;
using Avalonia.VisualTree;
using ClaudeDo.Data.Models;
using ClaudeDo.Ui.Localization;
using ClaudeDo.Ui.ViewModels;
using ClaudeDo.Ui.ViewModels.Islands;
using TaskStatus = ClaudeDo.Data.Models.TaskStatus;
@@ -97,6 +98,23 @@ public partial class TaskRowView : UserControl
schedule.Items.Add(MakeItem("tasks.ctxRemoveFromMyDay", OnRemoveFromMyDayClick, row.IsMyDay));
menu.Items.Add(schedule);
// "Move to list" — user lists only, current list excluded. Reuses the drag-drop move
// (MoveTaskToListAsync), so nothing but ListId changes and the same running/worktree
// guards apply. Hidden entirely when there is nowhere to move to.
var targets = (TopLevel.GetTopLevel(this)?.DataContext as IslandsShellViewModel)?.Lists?.UserLists
.Where(l => l.Id != vm.CurrentListId).ToList() ?? [];
if (targets.Count > 0)
{
var moveTo = new MenuItem { Header = Loc.T("tasks.ctxMoveToList"), DataContext = row };
foreach (var target in targets)
{
var item = new MenuItem { Header = target.Name, DataContext = row, Tag = target };
item.Click += OnMoveToListClick;
moveTo.Items.Add(item);
}
menu.Items.Add(moveTo);
}
menu.Items.Add(new Separator());
menu.Items.Add(MakeItem("tasks.ctxDeleteTask", OnDeleteTaskClick, reason: row.DeleteDisabledReason));
@@ -152,6 +170,13 @@ public partial class TaskRowView : UserControl
await vm.RemoveFromMyDayCommand.ExecuteAsync(row);
}
private async void OnMoveToListClick(object? sender, RoutedEventArgs e)
{
if (sender is not MenuItem { Tag: ListNavItemViewModel target }) return;
if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
await vm.MoveTaskToListAsync(row, target);
}
private async void OnDeleteTaskClick(object? sender, RoutedEventArgs e)
{
if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)