feat(lists): selectable list/folder colors with accent-aware swatches and custom picker
This commit is contained in:
@@ -37,6 +37,7 @@ public class ListSettingsModalViewModelTests
|
||||
public TicketSettingsDto? TicketSettings = new("http://ticket.example", true);
|
||||
public Func<Task<List<TicketProjectDto>>>? TicketProjectsFactory;
|
||||
public UpdateListConfigDto? SavedListConfig;
|
||||
public UpdateListDto? SavedList;
|
||||
|
||||
public Exception? GetListConfigThrows;
|
||||
|
||||
@@ -52,6 +53,12 @@ public class ListSettingsModalViewModelTests
|
||||
public override Task<List<TicketProjectDto>> GetTicketProjectsAsync() =>
|
||||
TicketProjectsFactory?.Invoke() ?? Task.FromResult(new List<TicketProjectDto>());
|
||||
|
||||
public override Task UpdateListAsync(UpdateListDto dto)
|
||||
{
|
||||
SavedList = dto;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override Task UpdateListConfigAsync(UpdateListConfigDto dto)
|
||||
{
|
||||
SavedListConfig = dto;
|
||||
@@ -95,6 +102,62 @@ public class ListSettingsModalViewModelTests
|
||||
Assert.False(ListSettingsModalViewModel.IsKnownIcon("mdi:NoSuchIcon"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Color_SwatchAndCustomStaySynced()
|
||||
{
|
||||
var vm = new ListSettingsModalViewModel(new CountingWorker(), NewFactory());
|
||||
|
||||
vm.SelectedSwatch = "Swatch3";
|
||||
Assert.Equal("Swatch3", vm.SelectedColor);
|
||||
Assert.False(vm.IsCustomColor);
|
||||
|
||||
vm.CustomColor = Avalonia.Media.Color.Parse("#112233");
|
||||
Assert.Equal("#112233", vm.SelectedColor);
|
||||
Assert.True(vm.IsCustomColor);
|
||||
Assert.Null(vm.SelectedSwatch);
|
||||
|
||||
vm.SelectedSwatch = null; // what the ListBox pushes while a custom hex is current
|
||||
Assert.Equal("#112233", vm.SelectedColor);
|
||||
|
||||
vm.SelectedSwatch = "";
|
||||
Assert.Equal("", vm.SelectedColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Save_List_SendsColor_AndBlankMeansNull()
|
||||
{
|
||||
var worker = new CountingWorker();
|
||||
var vm = new ListSettingsModalViewModel(worker, NewFactory());
|
||||
await vm.LoadAsync("l1", "List One", "", "feat", color: "Swatch2");
|
||||
|
||||
Assert.Equal("Swatch2", vm.SelectedColor);
|
||||
await vm.SaveCommand.ExecuteAsync(null);
|
||||
Assert.Equal("Swatch2", worker.SavedList!.Color);
|
||||
|
||||
vm.SelectedSwatch = "";
|
||||
await vm.SaveCommand.ExecuteAsync(null);
|
||||
Assert.Null(worker.SavedList!.Color);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Save_Folder_PersistsCustomColor()
|
||||
{
|
||||
var factory = NewFactory();
|
||||
await using (var ctx = await factory.CreateDbContextAsync())
|
||||
{
|
||||
await new ClaudeDo.Data.Repositories.ListRepository(ctx).AddFolderAsync(
|
||||
new ClaudeDo.Data.Models.ListFolderEntity { Id = "f1", Name = "Group", CreatedAt = DateTime.UtcNow });
|
||||
}
|
||||
|
||||
var vm = new ListSettingsModalViewModel(new CountingWorker(), factory);
|
||||
vm.BeginLoadFolder("f1", "Group", null, "Swatch1");
|
||||
vm.CustomColor = Avalonia.Media.Color.Parse("#A1B2C3");
|
||||
await vm.SaveCommand.ExecuteAsync(null);
|
||||
|
||||
await using var check = await factory.CreateDbContextAsync();
|
||||
Assert.Equal("#A1B2C3", (await check.ListFolders.FindAsync("f1"))!.Color);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LoadAsync_CallsGetListConfig_ExactlyOnce()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user