feat(procedures): U1 fold Mode A (Direkt suchen) (m/paliad#151)

Mounts mountModeA() into #procedures-panel-search when the Direkt-suchen
tab activates. The legacy fristenrechner-mode-a code runs unchanged
inside a wrapper that reseeds the #fristen-overhaul-root /
#fristen-overhaul-mode-host scaffold on every tab activation, so
re-clicking the tab always restores a fresh Mode A surface even if the
previous interaction committed an event into the result view.

`?event=<code>` deep links still resolve: boot detects the param,
activates the search tab, and hands directly to mountResultView() —
the result lands inside the same root, the user sees the picked
event's follow-up rules with the Direkt-suchen tab as the visible
context.

Search-box-in-filter-strip composition with chip filters (m's Q3
divergence) lands later, after Mode B + Verfahrensablauf are folded —
the unified state machine pulls all three behind one search input.
This commit is contained in:
mAi
2026-05-27 20:21:39 +02:00
parent 60907e7153
commit 0568d340a7
2 changed files with 77 additions and 20 deletions

View File

@@ -1,23 +1,20 @@
// /tools/procedures client — U0 skeleton boot // /tools/procedures client (m/paliad#151,
// (m/paliad#151, docs/design-unified-procedural-events-tool-2026-05-27.md). // docs/design-unified-procedural-events-tool-2026-05-27.md).
// //
// U0 owns: // Boot logic + tab switching for the unified procedural-events tool.
// - Tab switching across the four entry modes (proceeding / search / // Each entry tab mounts its own module; the search box and chip
// wizard / akte). URL-driven via ?mode=<name>; cold open lands on // filters in the top filter strip are wired in U1+ as each slice adds
// "proceeding" per design §11.5.Q3. // its dimension-aware behaviour.
// - Showing exactly one panel at a time.
// //
// Later slices wire data: // U0 — Skeleton + tab toggling.
// U1 mounts Mode A into #procedures-panel-search. // U1 — Direkt suchen mounts Mode A (this slice).
// U2 mounts Mode B into #procedures-panel-wizard. // U2 — Geführt mounts Mode B wizard.
// U3 mounts Verfahrensablauf into #procedures-panel-proceeding + // U3 — Verfahren wählen mounts Verfahrensablauf tree + 3-way detail filter.
// #procedures-output-tree.
// The search box in the top filter strip and the chip filters in
// #procedures-filter-chips-* are also wired in U1+ as each slice
// adds its dimension-aware behaviour.
import { initI18n } from "./i18n"; import { initI18n } from "./i18n";
import { initSidebar } from "./sidebar"; import { initSidebar } from "./sidebar";
import { mountModeA } from "./fristenrechner-mode-a";
import { mountResultView } from "./fristenrechner-result";
type ProceduresTab = "proceeding" | "search" | "wizard" | "akte"; type ProceduresTab = "proceeding" | "search" | "wizard" | "akte";
@@ -40,7 +37,24 @@ function writeTabToUrl(tab: ProceduresTab): void {
history.replaceState(null, "", url.pathname + url.search + url.hash); history.replaceState(null, "", url.pathname + url.search + url.hash);
} }
function showTab(tab: ProceduresTab): void { // ensureSearchHost re-seeds the overhaul-root / mode-host scaffold
// inside the Direkt-suchen panel. Idempotent — re-clicking the search
// tab always restores a fresh Mode A surface, even if the user
// previously committed an event into the result view (which had
// replaced the root's innerHTML).
function ensureSearchHost(): void {
const panel = document.getElementById("procedures-panel-search");
if (!panel) return;
panel.innerHTML = `
<div class="procedures-mode-a-host">
<div class="fristen-overhaul-root" id="fristen-overhaul-root">
<div id="fristen-overhaul-mode-host"></div>
</div>
</div>
`;
}
function setActiveTabUI(tab: ProceduresTab): void {
for (const t of TABS) { for (const t of TABS) {
const btn = document.getElementById(`procedures-tab-${t}`); const btn = document.getElementById(`procedures-tab-${t}`);
const panel = document.getElementById(`procedures-panel-${t}`); const panel = document.getElementById(`procedures-panel-${t}`);
@@ -53,20 +67,52 @@ function showTab(tab: ProceduresTab): void {
} }
} }
async function activateTab(tab: ProceduresTab): Promise<void> {
setActiveTabUI(tab);
if (tab === "search") {
ensureSearchHost();
await mountModeA();
}
// U2 will mount the wizard here; U3 will mount Verfahrensablauf.
}
function wireTabs(): void { function wireTabs(): void {
for (const t of TABS) { for (const t of TABS) {
const btn = document.getElementById(`procedures-tab-${t}`); const btn = document.getElementById(`procedures-tab-${t}`);
if (!btn) continue; if (!btn) continue;
btn.addEventListener("click", () => { btn.addEventListener("click", () => {
showTab(t); void activateTab(t);
writeTabToUrl(t); writeTabToUrl(t);
}); });
} }
} }
// boot dispatches on the URL: a deep link with `?event=` jumps straight
// to the linear result view (the Direkt-suchen tab stays as the visible
// context). Otherwise the requested tab — defaulting to "proceeding" —
// activates per readTabFromUrl().
async function boot(): Promise<void> {
const params = new URLSearchParams(window.location.search);
const eventRef = params.get("event") || "";
if (eventRef) {
setActiveTabUI("search");
ensureSearchHost();
await mountResultView({
eventRef,
triggerDate: params.get("trigger_date") || undefined,
party: params.get("party") || undefined,
courtId: params.get("court_id") || undefined,
});
return;
}
await activateTab(readTabFromUrl());
}
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
initI18n(); initI18n();
initSidebar(); initSidebar();
showTab(readTabFromUrl());
wireTabs(); wireTabs();
void boot();
}); });

View File

@@ -148,8 +148,19 @@ export function renderProcedures(): string {
<section className="procedures-panel" id="procedures-panel-search" role="tabpanel" <section className="procedures-panel" id="procedures-panel-search" role="tabpanel"
aria-labelledby="procedures-tab-search" hidden> aria-labelledby="procedures-tab-search" hidden>
<div className="procedures-panel-placeholder" data-i18n="procedures.panel.search.placeholder"> {/* Mode A host. procedures.ts (re-)seeds the inner
Direktsuche folgt in U1. overhaul-root / mode-host structure each time the
Direkt-suchen tab activates, then defers to
mountModeA() / mountResultView() — the legacy
Fristenrechner overhaul code runs unchanged inside
this wrapper. U3 will replace the in-panel commit
behaviour with a pivot into the shared linear-output
region; for U1 the result view simply re-renders
into the same root. */}
<div className="procedures-mode-a-host">
<div className="fristen-overhaul-root" id="fristen-overhaul-root">
<div id="fristen-overhaul-mode-host"></div>
</div>
</div> </div>
</section> </section>