diff --git a/DebugProbe.AspNetCore/Assets/js/debugprobe-ui.js b/DebugProbe.AspNetCore/Assets/js/debugprobe-ui.js index 0a10fda..f8dfa3d 100644 --- a/DebugProbe.AspNetCore/Assets/js/debugprobe-ui.js +++ b/DebugProbe.AspNetCore/Assets/js/debugprobe-ui.js @@ -302,10 +302,37 @@ const visibleCount = document.getElementById("visibleCount"); const emptyFilterState = document.getElementById("emptyFilterState"); const requestRows = Array.from(document.querySelectorAll("#requestTable tbody tr.clickable-row")); +function updateUrlFilters(search, method, statusFamily) { + const params = new URLSearchParams(window.location.search); + + if (search) { + params.set("search", search); + } else { + params.delete("search"); + } + + if (method) { + params.set("method", method); + } else { + params.delete("method"); + } + + if (statusFamily) { + params.set("status", statusFamily); + } else { + params.delete("status"); + } + + const query = params.toString(); + const newUrl = window.location.pathname + (query ? "?" + query : ""); + window.history.replaceState(null, "", newUrl); +} + function applyRequestFilters() { if (!requestRows.length) return; - const search = (requestSearch?.value ?? "").trim().toLowerCase(); + const rawSearch = (requestSearch?.value ?? "").trim(); + const search = rawSearch.toLowerCase(); const method = methodFilter?.value ?? ""; const statusFamily = statusFilter?.value ?? ""; let shown = 0; @@ -322,6 +349,8 @@ function applyRequestFilters() { if (visibleCount) visibleCount.innerText = shown.toString(); if (emptyFilterState) emptyFilterState.hidden = shown > 0; + + updateUrlFilters(rawSearch, method, statusFamily); } [requestSearch, methodFilter, statusFilter].forEach(control => { @@ -337,6 +366,32 @@ resetFiltersBtn?.addEventListener("click", () => { requestSearch?.focus(); }); +// Load filters from URL on page load +if (requestRows.length > 0) { + const params = new URLSearchParams(window.location.search); + const searchVal = params.get("search"); + const methodVal = params.get("method"); + const statusVal = params.get("status"); + + if (requestSearch && searchVal !== null) { + requestSearch.value = searchVal; + } + if (methodFilter && methodVal !== null) { + const optionExists = Array.from(methodFilter.options).some(opt => opt.value === methodVal); + if (optionExists) { + methodFilter.value = methodVal; + } + } + if (statusFilter && statusVal !== null) { + const optionExists = Array.from(statusFilter.options).some(opt => opt.value === statusVal); + if (optionExists) { + statusFilter.value = statusVal; + } + } + + applyRequestFilters(); +} + // Phase 2: Waterfall Timeline Interactivity document.addEventListener("DOMContentLoaded", () => { let tooltip = document.getElementById("wfTooltip"); diff --git a/DebugProbe.AspNetCore/DebugProbe.AspNetCore.csproj b/DebugProbe.AspNetCore/DebugProbe.AspNetCore.csproj index 94efe31..dc08eee 100644 --- a/DebugProbe.AspNetCore/DebugProbe.AspNetCore.csproj +++ b/DebugProbe.AspNetCore/DebugProbe.AspNetCore.csproj @@ -8,7 +8,7 @@ 1591 DebugProbe.AspNetCore - 1.6.8 + 1.6.9 Georgi Hristov @@ -19,11 +19,11 @@ ## What's New - - Added cURL export support on the trace details page. - - Generate reproducible cURL commands directly from captured HTTP requests. - - Improved debugging workflows by making it easier to share and replay requests. + - Added configurable slow request and dependency badges to highlight performance bottlenecks. + - Added Markdown export for captured traces to simplify sharing in GitHub issues, pull requests, and documentation. + - Improved diagnostics and collaboration with quick, reusable trace summaries. - Thanks to @DevSars24 for the community contribution. + Thanks to @DevSars24 for the community contributions. icon.png