feat(ui): Listen und Ordner in einer gemischten Sidebar-Reihenfolge

Die oberste Sidebar-Ebene ist jetzt eine gemischte TopLevel-Collection, so
dass eine Liste auch oberhalb eines Ordners stehen kann. DropAsync deckt
alle vier Quelle/Ziel-Kombinationen ab, ReorderSidebarAsync numeriert die
gesamte sichtbare Reihenfolge ueber lists und list_folders hinweg.
This commit is contained in:
mika kuns
2026-09-10 15:40:10 +02:00
parent 1770b67713
commit bfb1c6523c
9 changed files with 472 additions and 191 deletions
@@ -102,6 +102,36 @@ public sealed class ListFolderTests : IDisposable
Assert.Null((await ctx.Lists.AsNoTracking().FirstAsync(l => l.Id == "l1")).FolderId);
}
[Fact]
public async Task ReorderSidebarAsync_numbers_folders_and_lists_in_one_sequence()
{
await using var ctx = Open();
var repo = new ListRepository(ctx);
await repo.AddFolderAsync(NewFolder("f1"));
await repo.AddAsync(new ListEntity { Id = "inside", Name = "Inside", CreatedAt = DateTime.UtcNow, FolderId = "f1" });
await repo.AddAsync(new ListEntity { Id = "top", Name = "Top", CreatedAt = DateTime.UtcNow });
// Sidebar: the top-level list above the folder, whose one child follows the folder.
await repo.ReorderSidebarAsync([("top", false), ("f1", true), ("inside", false)]);
Assert.Equal(0, (await repo.GetByIdAsync("top"))!.SortOrder);
Assert.Equal(1, (await repo.GetFoldersAsync()).Single().SortOrder);
Assert.Equal(2, (await repo.GetByIdAsync("inside"))!.SortOrder);
}
[Fact]
public async Task AddAsync_appends_past_the_folders_too()
{
await using var ctx = Open();
var repo = new ListRepository(ctx);
await repo.AddFolderAsync(NewFolder("f1"));
await repo.AddFolderAsync(NewFolder("f2"));
await repo.AddAsync(new ListEntity { Id = "l1", Name = "Fresh", CreatedAt = DateTime.UtcNow });
// 2, not 0 — a new list must not jump above the existing folders on the next load.
Assert.Equal(2, (await repo.GetByIdAsync("l1"))!.SortOrder);
}
[Fact]
public async Task AddFolderAsync_appends_in_creation_order()
{