Skip to content

Commit 1593a57

Browse files
feat: implement URL-persistent filters for the dashboard (Feature #7)
feat: implement URL-persistent filters for the dashboard
2 parents 1781053 + 37c5421 commit 1593a57

1 file changed

Lines changed: 56 additions & 1 deletion

File tree

DebugProbe.AspNetCore/Assets/js/debugprobe-ui.js

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,37 @@ const visibleCount = document.getElementById("visibleCount");
302302
const emptyFilterState = document.getElementById("emptyFilterState");
303303
const requestRows = Array.from(document.querySelectorAll("#requestTable tbody tr.clickable-row"));
304304

305+
function updateUrlFilters(search, method, statusFamily) {
306+
const params = new URLSearchParams(window.location.search);
307+
308+
if (search) {
309+
params.set("search", search);
310+
} else {
311+
params.delete("search");
312+
}
313+
314+
if (method) {
315+
params.set("method", method);
316+
} else {
317+
params.delete("method");
318+
}
319+
320+
if (statusFamily) {
321+
params.set("status", statusFamily);
322+
} else {
323+
params.delete("status");
324+
}
325+
326+
const query = params.toString();
327+
const newUrl = window.location.pathname + (query ? "?" + query : "");
328+
window.history.replaceState(null, "", newUrl);
329+
}
330+
305331
function applyRequestFilters() {
306332
if (!requestRows.length) return;
307333

308-
const search = (requestSearch?.value ?? "").trim().toLowerCase();
334+
const rawSearch = (requestSearch?.value ?? "").trim();
335+
const search = rawSearch.toLowerCase();
309336
const method = methodFilter?.value ?? "";
310337
const statusFamily = statusFilter?.value ?? "";
311338
let shown = 0;
@@ -322,6 +349,8 @@ function applyRequestFilters() {
322349

323350
if (visibleCount) visibleCount.innerText = shown.toString();
324351
if (emptyFilterState) emptyFilterState.hidden = shown > 0;
352+
353+
updateUrlFilters(rawSearch, method, statusFamily);
325354
}
326355

327356
[requestSearch, methodFilter, statusFilter].forEach(control => {
@@ -337,6 +366,32 @@ resetFiltersBtn?.addEventListener("click", () => {
337366
requestSearch?.focus();
338367
});
339368

369+
// Load filters from URL on page load
370+
if (requestRows.length > 0) {
371+
const params = new URLSearchParams(window.location.search);
372+
const searchVal = params.get("search");
373+
const methodVal = params.get("method");
374+
const statusVal = params.get("status");
375+
376+
if (requestSearch && searchVal !== null) {
377+
requestSearch.value = searchVal;
378+
}
379+
if (methodFilter && methodVal !== null) {
380+
const optionExists = Array.from(methodFilter.options).some(opt => opt.value === methodVal);
381+
if (optionExists) {
382+
methodFilter.value = methodVal;
383+
}
384+
}
385+
if (statusFilter && statusVal !== null) {
386+
const optionExists = Array.from(statusFilter.options).some(opt => opt.value === statusVal);
387+
if (optionExists) {
388+
statusFilter.value = statusVal;
389+
}
390+
}
391+
392+
applyRequestFilters();
393+
}
394+
340395
// Phase 2: Waterfall Timeline Interactivity
341396
document.addEventListener("DOMContentLoaded", () => {
342397
let tooltip = document.getElementById("wfTooltip");

0 commit comments

Comments
 (0)