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:
@@ -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();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user