feat(ui): Usage-Monitor zeigt Reset-Uhrzeit hinter der Restzeit

This commit is contained in:
mika kuns
2026-08-21 16:22:26 +02:00
parent 8dce2d0898
commit 8f983851b4
4 changed files with 31 additions and 3 deletions
+1 -1
View File
@@ -497,7 +497,7 @@
"staleGateHint": "Das Gate greift in diesem Zustand nicht.",
"gateBlockedFormat": "Warteschlange pausiert {0}",
"throttleFormat": "Warteschlange gedrosselt: {0}/{1} Slots ({2})",
"resetIn": "Reset in {0}",
"resetIn": "Reset in {0} ({1})",
"dragHint": "Marker ziehen oder Wert unten eintragen.",
"legendSoft": "Soft · 2 Slots",
"legendHard": "Hard · 1 Slot",
+1 -1
View File
@@ -497,7 +497,7 @@
"staleGateHint": "The gate does not apply while values are stale.",
"gateBlockedFormat": "Queue paused — {0}",
"throttleFormat": "Queue throttled: {0}/{1} slots ({2})",
"resetIn": "Reset in {0}",
"resetIn": "Reset in {0} ({1})",
"dragHint": "Drag a marker, or type the value below.",
"legendSoft": "Soft · 2 slots",
"legendHard": "Hard · 1 slot",
@@ -391,7 +391,9 @@ public sealed partial class UsageGaugeRowViewModel : ObservableObject
public bool IsWarnSeverity => !string.Equals(Severity, "normal", StringComparison.OrdinalIgnoreCase);
public string ResetText => ResetsAt is { } r ? Loc.T("modals.usageMonitor.resetIn", FormatRemaining(r)) : "";
public string ResetText => ResetsAt is { } r
? Loc.T("modals.usageMonitor.resetIn", FormatRemaining(r), r.ToLocalTime().ToString("HH:mm"))
: "";
/// <summary>Live values from a fresh snapshot, without replacing the row instance mid-view.</summary>
public void Update(string label, double percent, string severity, DateTimeOffset? resetsAt,
@@ -586,6 +586,32 @@ public class UsageMonitorModalViewModelTests
Assert.Null(UsageThresholdDrag.Nearest(50, 65, 80, percent: 20, tolerancePercent: 5));
}
// ── Reset text ───────────────────────────────────────────────────────────
[Fact]
public async Task ResetText_WithResetsAt_IncludesLocalResetTime()
{
var resetsAt = DateTimeOffset.UtcNow.AddHours(2).AddMinutes(15);
var worker = new FakeWorker { Snapshot = Snapshot(new[] { Limit("session", resetsAt: resetsAt) }) };
var vm = new UsageMonitorModalViewModel(worker);
await vm.LoadAsync();
var expectedClock = resetsAt.ToLocalTime().ToString("HH:mm");
Assert.StartsWith("Reset in", vm.GaugeRows[0].ResetText);
Assert.EndsWith($"({expectedClock})", vm.GaugeRows[0].ResetText);
Assert.Matches(@"2 h 1[45] m", vm.GaugeRows[0].ResetText);
}
[Fact]
public async Task ResetText_NoResetsAt_IsEmpty()
{
var worker = new FakeWorker { Snapshot = Snapshot(new[] { Limit("session", resetsAt: null) }) };
var vm = new UsageMonitorModalViewModel(worker);
await vm.LoadAsync();
Assert.Equal("", vm.GaugeRows[0].ResetText);
}
// ── Stale / gate bands ───────────────────────────────────────────────────
[Fact]