fix(centralui): apply status/stuck query-string filters on the Site Calls page
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ScadaLink.CentralUI.Components.Shared;
|
||||
using ScadaLink.Commons.Entities.Sites;
|
||||
@@ -26,11 +28,32 @@ namespace ScadaLink.CentralUI.Components.Pages.SiteCalls;
|
||||
/// a relay that never reaches the site is a transient transport condition, surfaced
|
||||
/// to the operator differently from a generic failure.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// Query-string drill-in: the Health-dashboard Site Call KPI tiles deep-link here
|
||||
/// with <c>?status=Parked</c> (Parked tile) or <c>?stuck=true</c> (Stuck tile). On
|
||||
/// initialization those params seed <see cref="_statusFilter"/> / <see cref="_stuckOnly"/>
|
||||
/// BEFORE the first <see cref="RefreshAll"/>, so the first grid load is already
|
||||
/// filtered and the filter card controls reflect the seeded values. Parsing is lax
|
||||
/// — an absent, blank, or unrecognised value is silently dropped and the page loads
|
||||
/// unfiltered, mirroring <c>AuditLogPage</c>'s drill-in convention.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public partial class SiteCallsReport
|
||||
{
|
||||
private const int PageSize = 50;
|
||||
|
||||
[Inject] private NavigationManager Navigation { get; set; } = null!;
|
||||
|
||||
// The Status filter <select> options — the exact strings the dropdown binds and
|
||||
// the KPI tiles emit (e.g. ?status=Parked). A query-string status only seeds the
|
||||
// filter when it matches one of these (case-insensitively); anything else is
|
||||
// dropped so a hand-crafted bad URL still renders the page unfiltered.
|
||||
private static readonly string[] ValidStatuses =
|
||||
{
|
||||
"Submitted", "Forwarded", "Attempted", "Delivered", "Parked", "Failed", "Discarded",
|
||||
};
|
||||
|
||||
private ToastNotification _toast = default!;
|
||||
private List<Site> _sites = new();
|
||||
|
||||
@@ -77,9 +100,51 @@ public partial class SiteCallsReport
|
||||
Logger.LogWarning(ex, "Failed to load sites for the Site Calls source-site filter.");
|
||||
}
|
||||
|
||||
// Seed filters from ?status= / ?stuck= BEFORE the first fetch so the initial
|
||||
// grid load is already filtered (and the filter card controls reflect it).
|
||||
ApplyQueryStringFilters();
|
||||
|
||||
await RefreshAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pre-apply the Health-dashboard KPI-tile drill-in filters from the URL query
|
||||
/// string. <c>?status=<status></c> seeds <see cref="_statusFilter"/> when it
|
||||
/// matches a known status (case-insensitive); <c>?stuck=true</c> seeds
|
||||
/// <see cref="_stuckOnly"/>. Lax parsing — an absent, blank, or unrecognised value
|
||||
/// is silently dropped, leaving the filter empty (the no-param behaviour).
|
||||
/// </summary>
|
||||
private void ApplyQueryStringFilters()
|
||||
{
|
||||
var uri = Navigation.ToAbsoluteUri(Navigation.Uri);
|
||||
var query = QueryHelpers.ParseQuery(uri.Query);
|
||||
|
||||
if (query.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (query.TryGetValue("status", out var statusValues))
|
||||
{
|
||||
var v = statusValues.ToString();
|
||||
// Round-trip the dropdown's own option strings (the KPI tile emits the
|
||||
// canonical casing, e.g. ?status=Parked); normalise to that casing so the
|
||||
// <select> binds. An unrecognised value leaves the filter unset.
|
||||
var match = ValidStatuses.FirstOrDefault(
|
||||
s => string.Equals(s, v?.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
if (match is not null)
|
||||
{
|
||||
_statusFilter = match;
|
||||
}
|
||||
}
|
||||
|
||||
if (query.TryGetValue("stuck", out var stuckValues)
|
||||
&& bool.TryParse(stuckValues.ToString(), out var stuck))
|
||||
{
|
||||
_stuckOnly = stuck;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Re-fetch the current page (Refresh button, and after a relay action).</summary>
|
||||
private async Task RefreshAll()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user