diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/ListNavItemViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/ListNavItemViewModel.cs index 851eab3..b524b67 100644 --- a/src/ClaudeDo.Ui/ViewModels/Islands/ListNavItemViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Islands/ListNavItemViewModel.cs @@ -6,6 +6,7 @@ public sealed partial class ListNavItemViewModel : ViewModelBase { public required string Id { get; init; } public required string Name { get; init; } + public required ListKind Kind { get; init; } [ObservableProperty] private int _count; [ObservableProperty] private bool _isActive; public string? IconKey { get; init; } diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs index 29379c3..69b1383 100644 --- a/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs @@ -1,11 +1,62 @@ +using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using ClaudeDo.Data; +using ClaudeDo.Data.Repositories; +using Microsoft.EntityFrameworkCore; namespace ClaudeDo.Ui.ViewModels.Islands; +public enum ListKind { Smart, Virtual, User } + public sealed partial class ListsIslandViewModel : ViewModelBase { + private readonly IDbContextFactory _dbFactory; + public event EventHandler? SelectionChanged; + + public ObservableCollection Items { get; } = new(); + + [ObservableProperty] private string _searchText = ""; [ObservableProperty] private ListNavItemViewModel? _selectedList; - partial void OnSelectedListChanged(ListNavItemViewModel? value) => + + public ListsIslandViewModel(IDbContextFactory dbFactory) + { + _dbFactory = dbFactory; + } + + public async Task LoadAsync(CancellationToken ct = default) + { + Items.Clear(); + Items.Add(new ListNavItemViewModel { Id = "smart:my-day", Name = "My Day", Kind = ListKind.Smart, IconKey = "Sun" }); + Items.Add(new ListNavItemViewModel { Id = "smart:important", Name = "Important", Kind = ListKind.Smart, IconKey = "Star" }); + Items.Add(new ListNavItemViewModel { Id = "smart:planned", Name = "Planned", Kind = ListKind.Smart, IconKey = "Calendar" }); + Items.Add(new ListNavItemViewModel { Id = "virtual:running", Name = "Running", Kind = ListKind.Virtual, IconKey = "Pulse" }); + Items.Add(new ListNavItemViewModel { Id = "virtual:review", Name = "Review", Kind = ListKind.Virtual, IconKey = "Eye" }); + + await using var ctx = await _dbFactory.CreateDbContextAsync(ct); + var lists = new ListRepository(ctx); + var seedNames = new HashSet(new[] { "My Day", "Important", "Planned" }); + foreach (var l in await lists.GetAllAsync(ct)) + if (!seedNames.Contains(l.Name)) + Items.Add(new ListNavItemViewModel { Id = $"user:{l.Id}", Name = l.Name, Kind = ListKind.User, IconKey = "Folder" }); + + await RefreshCountsAsync(ct); + SelectedList = Items.FirstOrDefault(); + } + + public async Task RefreshCountsAsync(CancellationToken ct = default) + { + foreach (var i in Items) i.Count = 0; + await Task.CompletedTask; + } + + [RelayCommand] + private void Select(ListNavItemViewModel item) => SelectedList = item; + + partial void OnSelectedListChanged(ListNavItemViewModel? value) + { + foreach (var i in Items) i.IsActive = ReferenceEquals(i, value); SelectionChanged?.Invoke(this, EventArgs.Empty); + } } diff --git a/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs b/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs index 1cd9d46..daabb6a 100644 --- a/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs @@ -29,5 +29,6 @@ public sealed partial class IslandsShellViewModel : ViewModelBase Lists = lists; Tasks = tasks; Details = details; Lists.SelectionChanged += (_, _) => Tasks.LoadForList(Lists.SelectedList); Tasks.SelectionChanged += (_, _) => Details.Bind(Tasks.SelectedTask); + _ = Lists.LoadAsync(); } }