Der Monitor-Dashboard zeigte bisher alle sechs Kacheln gleichzeitig in
einem GridStack-Layout (Drag/Resize, je Kachel eigenes Scrolling). Nutzer-
wunsch: Analog zur Lagebild-Seite nur ein Tab-Panel gleichzeitig, maximiert
auf volle Breite, Seiten-Scroll statt interne Scrollbars.
Aenderungen:
- dashboard.html: Layout-Toolbar + grid-stack-Wrapper entfernt; neue tab-nav
mit 6 Buttons + tab-panels mit 6 Panels. GridStack CDN-Links raus.
- layout.js: GridStack-Init/toggleTile/reset komplett entfernt. Neu:
switchTab(tabId) + restoreTabFor(incidentId) mit localStorage-Persistenz
pro Lage osint_tab_id. applyTypeLabels fuer adhoc vs. research. Legacy-
Methoden sind No-Op-Stubs.
- app.js: renderIncidentDetail ruft LayoutManager.restoreTabFor und
applyTypeLabels auf. openContentModal-Trigger aus Card-Titeln raus.
Tile-Resize-Bloecke fuer Quellen und Timeline entfernt.
- components.js: Telegram-Pills bekommen Suffix Telegram-Link, wenn die
URL auf t.me verweist.
- style.css: grid-stack/layout-toggle Klassen raus; neue tab-nav/tab-btn/
tab-panel Klassen. Internes Scrolling entfernt. map-container 600px.
Alte osint_layout-Eintraege werden ignoriert.
_applyLayout entfernte Widgets ohne die Card-Elemente vorher zu parken.
Beim Wiederherstellen eines Layouts mit versteckten Kacheln (z.B. Timeline)
gingen die DOM-Elemente verloren, was zu null-Referenz-Fehlern fuehrte.
Fixes:
- layout.js: Cards in tile-parking retten bevor Widget entfernt wird
- app.js: Null-Guards in rerenderTimeline und _updateTimelineCount
- Neues Geoparsing-Modul (spaCy NER + geonamescache/Nominatim)
- article_locations-Tabelle mit Migration
- Pipeline-Integration nach Artikel-Speicherung
- API-Endpunkt GET /incidents/{id}/locations
- Leaflet.js + MarkerCluster im Dashboard-Grid
- Theme-aware Kartenkacheln (CartoDB dark / OSM light)
- Gold-Akzent MarkerCluster, Popup mit Artikelliste
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>