diff --git a/frontend/src/dashboard.tsx b/frontend/src/dashboard.tsx index 5630b75..5c7343d 100644 --- a/frontend/src/dashboard.tsx +++ b/frontend/src/dashboard.tsx @@ -112,23 +112,23 @@ export function renderDashboard(): string { {/* Traffic-light deadline summary (4+1: Überfällig conditional + 4 universal — t-paliad-110) */}
- +
0
Überfällig
- +
0
Heute
- +
0
Diese Woche
- +
0
Nächste Woche
- +
0
Später
diff --git a/internal/handlers/deadlines_pages.go b/internal/handlers/deadlines_pages.go index 52ab049..cb69615 100644 --- a/internal/handlers/deadlines_pages.go +++ b/internal/handlers/deadlines_pages.go @@ -11,8 +11,15 @@ import "net/http" // to the canonical /events?type=deadline (t-paliad-115). Detail page // /deadlines/{id} stays type-specific. Drop this redirect once we're // confident no caches / bookmarks / external links still hit the old URL. +// +// Preserves the incoming query string so filter params (e.g. status=this_week +// from the dashboard summary cards) survive the redirect. func handleDeadlinesListRedirect(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, "/events?type=deadline", http.StatusMovedPermanently) + target := "/events?type=deadline" + if r.URL.RawQuery != "" { + target += "&" + r.URL.RawQuery + } + http.Redirect(w, r, target, http.StatusMovedPermanently) } func handleDeadlinesNewPage(w http.ResponseWriter, r *http.Request) { diff --git a/internal/handlers/redirects_test.go b/internal/handlers/redirects_test.go index a007dc0..faf2077 100644 --- a/internal/handlers/redirects_test.go +++ b/internal/handlers/redirects_test.go @@ -57,3 +57,29 @@ func TestStandaloneCalendarHandlers_RedirectToEventsKalender(t *testing.T) { } } } + +// /deadlines list redirect must forward the incoming query string so legacy +// dashboard cards and external bookmarks like /deadlines?status=this_week +// land at /events?type=deadline&status=this_week instead of losing the +// filter. Regression for m's 2026-05-21 14:20 report. +func TestDeadlinesListRedirect_PreservesQueryString(t *testing.T) { + cases := []struct { + path string + want string + }{ + {"/deadlines", "/events?type=deadline"}, + {"/deadlines?status=this_week", "/events?type=deadline&status=this_week"}, + {"/deadlines?status=overdue&project_id=abc", "/events?type=deadline&status=overdue&project_id=abc"}, + } + for _, tc := range cases { + req := httptest.NewRequest(http.MethodGet, tc.path, nil) + w := httptest.NewRecorder() + handleDeadlinesListRedirect(w, req) + if w.Code != http.StatusMovedPermanently { + t.Fatalf("%s: status = %d, want 301", tc.path, w.Code) + } + if got := w.Header().Get("Location"); got != tc.want { + t.Fatalf("%s: Location = %q, want %q", tc.path, got, tc.want) + } + } +}