feat(ui): show newest log entries first in Log Visualizer

Reverses row order in LogVisualizerViewModel.Apply() so the most recent
entry sits at index 0, matching the "what just happened" use case;
filtering and refresh are unaffected since the reversal happens after
the warn/error filter is applied.
This commit is contained in:
mika kuns
2026-08-05 09:08:30 +02:00
parent 63d8b5c28d
commit 47edab5907
3 changed files with 42 additions and 5 deletions
@@ -16,14 +16,17 @@ public class LogVisualizerViewModelTests
private static WorkerLogEntry E(WorkerLogLevel lvl, string msg)
=> new(msg, lvl, new DateTime(2026, 6, 23, 8, 0, 0, DateTimeKind.Utc));
private static WorkerLogEntry E(WorkerLogLevel lvl, string msg, DateTime timestampUtc)
=> new(msg, lvl, timestampUtc);
[Fact]
public async Task Refresh_populates_rows_from_worker()
public async Task Refresh_populates_rows_from_worker_newest_first()
{
var vm = new LogVisualizerViewModel(new FakeClient(new[] { E(WorkerLogLevel.Info, "a"), E(WorkerLogLevel.Error, "b") }));
await vm.RefreshAsync();
Assert.Equal(new[] { "a", "b" }, vm.Rows.Select(r => r.Message));
Assert.Equal(new[] { "b", "a" }, vm.Rows.Select(r => r.Message));
}
[Fact]
@@ -35,7 +38,7 @@ public class LogVisualizerViewModelTests
vm.WarnErrorOnly = true;
Assert.Equal(new[] { "w", "e" }, vm.Rows.Select(r => r.Message));
Assert.Equal(new[] { "e", "w" }, vm.Rows.Select(r => r.Message));
}
[Fact]
@@ -48,4 +51,38 @@ public class LogVisualizerViewModelTests
Assert.Empty(vm.Rows);
Assert.False(string.IsNullOrEmpty(vm.StatusText));
}
[Fact]
public async Task Refresh_orders_newest_entry_first()
{
var t0 = new DateTime(2026, 6, 23, 8, 0, 0, DateTimeKind.Utc);
var vm = new LogVisualizerViewModel(new FakeClient(new[]
{
E(WorkerLogLevel.Info, "oldest", t0),
E(WorkerLogLevel.Info, "middle", t0.AddMinutes(1)),
E(WorkerLogLevel.Info, "newest", t0.AddMinutes(2)),
}));
await vm.RefreshAsync();
Assert.Equal(new[] { "newest", "middle", "oldest" }, vm.Rows.Select(r => r.Message));
}
[Fact]
public async Task Refresh_orders_newest_entry_first_with_warn_error_only()
{
var t0 = new DateTime(2026, 6, 23, 8, 0, 0, DateTimeKind.Utc);
var vm = new LogVisualizerViewModel(new FakeClient(new[]
{
E(WorkerLogLevel.Warn, "oldest", t0),
E(WorkerLogLevel.Info, "skipped", t0.AddMinutes(1)),
E(WorkerLogLevel.Error, "middle", t0.AddMinutes(2)),
E(WorkerLogLevel.Warn, "newest", t0.AddMinutes(3)),
}));
await vm.RefreshAsync();
vm.WarnErrorOnly = true;
Assert.Equal(new[] { "newest", "middle", "oldest" }, vm.Rows.Select(r => r.Message));
}
}