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