refactor(centralui): SiteCallsReport adopts KeysetPager + DateTimeRangeFilter + tokenized backdrop (T35f)

This commit is contained in:
Joseph Doherty
2026-06-18 19:58:55 -04:00
parent ef2791ffd8
commit e773915e26
2 changed files with 22 additions and 32 deletions
@@ -74,14 +74,9 @@
@bind="_nodeFilter" />
</div>
<div class="col-auto">
<label class="form-label small mb-1" for="sc-from">From</label>
<input id="sc-from" type="datetime-local" class="form-control form-control-sm"
@bind="_fromFilter" />
</div>
<div class="col-auto">
<label class="form-label small mb-1" for="sc-to">To</label>
<input id="sc-to" type="datetime-local" class="form-control form-control-sm"
@bind="_toFilter" />
<DateTimeRangeFilter From="_fromFilter" FromChanged="(v => _fromFilter = v)"
To="_toFilter" ToChanged="(v => _toFilter = v)"
IdPrefix="sc" />
</div>
<div class="col">
<label class="form-label small mb-1" for="sc-search">Target keyword</label>
@@ -215,23 +210,18 @@
@* Keyset paging — the Task 4 query response carries a (CreatedAtUtc, Id)
cursor rather than page numbers, so we keep a stack of cursors to step
backwards and the response's NextAfter* cursor to step forwards. *@
<div class="d-flex justify-content-between align-items-center">
<span class="text-muted small">
@* No "of N" total: keyset paging has no cheap total-count, so
the label is intentionally page-number-only. Do not "fix"
this by adding a total — that would require a COUNT(*). *@
Page @(_cursorStack.Count + 1) · @_siteCalls.Count rows
</span>
<div>
<button class="btn btn-outline-secondary btn-sm me-1"
@onclick="PrevPage" disabled="@(_cursorStack.Count == 0 || _loading)"
data-test="site-calls-prev">Previous</button>
<button class="btn btn-outline-secondary btn-sm"
@onclick="NextPage" disabled="@(!HasNextPage || _loading)"
data-test="site-calls-next">Next</button>
</div>
</div>
backwards and the response's NextAfter* cursor to step forwards. All
cursor logic stays in this code-behind; KeysetPager is presentational.
No "of N" total: keyset paging has no cheap total-count, so the label is
intentionally page-number-only. Do not "fix" this by adding a total —
that would require a COUNT(*). *@
<KeysetPager PageNumber="@(_cursorStack.Count + 1)"
RowCount="_siteCalls.Count"
CanGoBack="@(_cursorStack.Count > 0)"
HasNextPage="@(_nextCursor is not null)"
Disabled="_loading"
OnPrevious="PrevPage"
OnNext="NextPage" />
}
@* ── Trends (K14: collapsible KPI-history charts) ──
@@ -292,7 +282,7 @@
@if (_detailSiteCall != null)
{
var d = _detailSiteCall;
<div class="modal show d-block" tabindex="-1" style="background: rgba(0,0,0,0.4);"
<div class="modal show d-block sb-modal-backdrop" tabindex="-1"
@onclick="CloseDetail">
<div class="modal-dialog modal-dialog-scrollable modal-lg" @onclick:stopPropagation="true">
<div class="modal-content">
@@ -307,9 +307,9 @@ public class SiteCallsReportPageTests : BunitContext
var cut = Render<SiteCallsReportPage>();
cut.WaitForState(() => cut.Markup.Contains("ERP.GetOrder"));
var next = cut.Find("[data-test='site-calls-next']");
var next = cut.Find("[data-test='keyset-next']");
Assert.True(next.HasAttribute("disabled"));
var prev = cut.Find("[data-test='site-calls-prev']");
var prev = cut.Find("[data-test='keyset-prev']");
Assert.True(prev.HasAttribute("disabled"));
}
@@ -338,7 +338,7 @@ public class SiteCallsReportPageTests : BunitContext
var cut = Render<SiteCallsReportPage>();
cut.WaitForState(() => cut.Markup.Contains("ERP.Op0"));
var next = cut.Find("[data-test='site-calls-next']");
var next = cut.Find("[data-test='keyset-next']");
Assert.False(next.HasAttribute("disabled"));
next.Click();
@@ -381,7 +381,7 @@ public class SiteCallsReportPageTests : BunitContext
cut.WaitForState(() => cut.Markup.Contains("ERP.Op0"));
// Step forward — query 2 carries the keyset cursor.
var next = cut.Find("[data-test='site-calls-next']");
var next = cut.Find("[data-test='keyset-next']");
next.Click();
cut.WaitForAssertion(() =>
{
@@ -390,7 +390,7 @@ public class SiteCallsReportPageTests : BunitContext
});
// Previous is now live (the back-stack has one entry); click it.
var prev = cut.Find("[data-test='site-calls-prev']");
var prev = cut.Find("[data-test='keyset-prev']");
Assert.False(prev.HasAttribute("disabled"));
prev.Click();
@@ -402,7 +402,7 @@ public class SiteCallsReportPageTests : BunitContext
Assert.Null(_queryRequests[2].AfterCreatedAtUtc);
Assert.Null(_queryRequests[2].AfterId);
// Back on page 1, the back-stack is empty again so Previous re-disables.
Assert.True(cut.Find("[data-test='site-calls-prev']").HasAttribute("disabled"));
Assert.True(cut.Find("[data-test='keyset-prev']").HasAttribute("disabled"));
});
}