chore(t-paliad-179): sidebar maps Verfahrensablauf 1:1 to its own URL

Sidebar.tsx href flips from /tools/fristenrechner?path=a to
/tools/verfahrensablauf. The two Werkzeuge entries now resolve to
distinct pathnames, so the SSR navItem helper picks the right active
class on its own — fixVerfahrensablaufActive (which compared search
params client-side to disambiguate) is deleted along with its call
in initSidebar.
This commit is contained in:
mAi
2026-05-13 00:19:16 +02:00
parent 1255ee049f
commit f5eb84718a
2 changed files with 9 additions and 28 deletions

View File

@@ -75,7 +75,6 @@ export function initSidebar() {
initPaliadinLinks();
initUserViewsGroup();
initThemeToggle();
fixVerfahrensablaufActive();
const sidebar = document.querySelector<HTMLElement>(".sidebar");
if (!sidebar) return;
initSidebarResize(sidebar);
@@ -444,29 +443,10 @@ function initUserViewsGroup(): void {
});
}
// fixVerfahrensablaufActive disambiguates the two /tools/fristenrechner
// sidebar entries (t-paliad-168). The SSR navItem helper compares
// hrefs against pathname only, which can't tell ?path=a apart from
// the no-query Fristenrechner — both would render as Fristenrechner=
// active. At the client we know the search params; flip the active
// class so the sidebar lights up the entry the user actually opened.
function fixVerfahrensablaufActive(): void {
if (window.location.pathname !== "/tools/fristenrechner") return;
const path = new URLSearchParams(window.location.search).get("path");
const fristenrechner = document.querySelector<HTMLAnchorElement>(
'a.sidebar-item[href="/tools/fristenrechner"]',
);
const verfahrensablauf = document.querySelector<HTMLAnchorElement>(
'a.sidebar-item[href="/tools/fristenrechner?path=a"]',
);
if (path === "a") {
fristenrechner?.classList.remove("active");
verfahrensablauf?.classList.add("active");
} else {
verfahrensablauf?.classList.remove("active");
fristenrechner?.classList.add("active");
}
}
// fixVerfahrensablaufActive removed (t-paliad-179 Slice 1). The two
// sidebar entries now map 1:1 to distinct URLs (/tools/fristenrechner
// vs /tools/verfahrensablauf), so the SSR navItem helper picks the
// correct active class by pathname alone.
function renderUserViewItem(view: UserViewLite, currentPath: string): HTMLElement {
const a = document.createElement("a");

View File

@@ -7,9 +7,10 @@ const ICON_CLOCK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" s
const ICON_DOWNLOAD = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>';
const ICON_LINK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>';
const ICON_BOOK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>';
// Open-book icon for the /tools/fristenrechner?path=a "Verfahrensablauf"
// nav entry (t-paliad-168). Distinct from ICON_BOOK (Glossar, closed)
// so the two affordances read as different at a glance.
// Open-book icon for the /tools/verfahrensablauf "Verfahrensablauf"
// nav entry (t-paliad-168 → t-paliad-179 Slice 1 split). Distinct from
// ICON_BOOK (Glossar, closed) so the two affordances read as different
// at a glance.
const ICON_BOOK_OPEN = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 4h7a3 3 0 0 1 3 3v13a2 2 0 0 0-2-2H2z"/><path d="M22 4h-7a3 3 0 0 0-3 3v13a2 2 0 0 1 2-2h8z"/></svg>';
const ICON_TABLE = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/><line x1="9" y1="3" x2="9" y2="21"/></svg>';
const ICON_CHECK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>';
@@ -161,7 +162,7 @@ export function Sidebar({ currentPath, authenticated = true }: SidebarProps): st
Gerichte / Glossar), then content (Links / Downloads). */}
{group("nav.group.werkzeuge", "Werkzeuge",
navItem("/tools/fristenrechner", ICON_CLOCK, "nav.fristenrechner", "Fristenrechner", currentPath) +
navItem("/tools/fristenrechner?path=a", ICON_BOOK_OPEN, "nav.verfahrensablauf", "Verfahrensablauf", currentPath) +
navItem("/tools/verfahrensablauf", ICON_BOOK_OPEN, "nav.verfahrensablauf", "Verfahrensablauf", currentPath) +
navItem("/tools/kostenrechner", ICON_CALC, "nav.kostenrechner", "Kostenrechner", currentPath) +
navItem("/tools/gebuehrentabellen", ICON_TABLE, "nav.gebuehrentabellen", "Gebührentabellen", currentPath) +
navItem("/checklists", ICON_CHECK, "nav.checklisten", "Checklisten", currentPath) +