diff --git a/src/ClaudeDo.Ui/ViewModels/TaskListViewModel.cs b/src/ClaudeDo.Ui/ViewModels/TaskListViewModel.cs index c81b37a..baf25f7 100644 --- a/src/ClaudeDo.Ui/ViewModels/TaskListViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/TaskListViewModel.cs @@ -25,6 +25,8 @@ public partial class TaskListViewModel : ViewModelBase [ObservableProperty] private TaskItemViewModel? _selectedTask; [ObservableProperty, NotifyCanExecuteChangedFor(nameof(AddTaskCommand))] private string? _currentListId; + [ObservableProperty] private string _listName = "Tasks"; + [ObservableProperty] private string _inlineAddTitle = ""; public event Action? SelectedTaskChanged; @@ -61,6 +63,16 @@ public partial class TaskListViewModel : ViewModelBase Tasks.Clear(); SelectedTask = null; + if (listId is not null) + { + var list = await _listRepo.GetByIdAsync(listId); + ListName = list?.Name ?? "Tasks"; + } + else + { + ListName = "Tasks"; + } + if (listId is null) return; try @@ -69,7 +81,7 @@ public partial class TaskListViewModel : ViewModelBase foreach (var e in entities) { var tags = await _taskRepo.GetEffectiveTagsAsync(e.Id); - Tasks.Add(new TaskItemViewModel(e, tags, RunNowAsync, () => _worker.IsConnected)); + Tasks.Add(new TaskItemViewModel(e, tags, RunNowAsync, () => _worker.IsConnected, ToggleDoneAsync)); } } catch (Exception ex) @@ -80,6 +92,40 @@ public partial class TaskListViewModel : ViewModelBase private bool CanAddTask() => CurrentListId is not null; + [RelayCommand(CanExecute = nameof(CanAddTask))] + private async Task InlineAdd() + { + var title = InlineAddTitle.Trim(); + if (string.IsNullOrEmpty(title) || CurrentListId is null) return; + + var list = await _listRepo.GetByIdAsync(CurrentListId); + var defaultCommitType = list?.DefaultCommitType ?? "chore"; + + var entity = new TaskEntity + { + Id = Guid.NewGuid().ToString(), + ListId = CurrentListId, + Title = title, + Status = TaskStatus.Manual, + CommitType = defaultCommitType, + CreatedAt = DateTime.UtcNow, + }; + + try + { + await _taskRepo.AddAsync(entity); + var tags = await _taskRepo.GetEffectiveTagsAsync(entity.Id); + var vm = new TaskItemViewModel(entity, tags, RunNowAsync, () => _worker.IsConnected, ToggleDoneAsync); + Tasks.Add(vm); + SelectedTask = vm; + InlineAddTitle = ""; + } + catch (Exception ex) + { + _showMessage($"Error creating task: {ex.Message}"); + } + } + [RelayCommand(CanExecute = nameof(CanAddTask))] private async Task AddTask() { @@ -108,7 +154,7 @@ public partial class TaskListViewModel : ViewModelBase } var tags = await _taskRepo.GetEffectiveTagsAsync(saved.Id); - Tasks.Add(new TaskItemViewModel(saved, tags, RunNowAsync, () => _worker.IsConnected)); + Tasks.Add(new TaskItemViewModel(saved, tags, RunNowAsync, () => _worker.IsConnected, ToggleDoneAsync)); // Auto wake-queue if agent+queued if (saved.Status == TaskStatus.Queued && @@ -206,6 +252,19 @@ public partial class TaskListViewModel : ViewModelBase } } + private async Task ToggleDoneAsync(string taskId) + { + var entity = await _taskRepo.GetByIdAsync(taskId); + if (entity is null) return; + + entity.Status = entity.Status == TaskStatus.Done ? TaskStatus.Manual : TaskStatus.Done; + if (entity.Status == TaskStatus.Done) + entity.FinishedAt = DateTime.UtcNow; + + await _taskRepo.UpdateAsync(entity); + await RefreshSingleAsync(taskId); + } + private async void OnTaskUpdated(string taskId) { if (CurrentListId is null) return;