Dashboard: GridStack durch Tab-Navigation ersetzen

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.
Dieser Commit ist enthalten in:
claude-dev
2026-04-18 22:34:36 +00:00
Ursprung 3b9e9e25c2
Commit e15ed0c21e
5 geänderte Dateien mit 206 neuen und 571 gelöschten Zeilen

Datei anzeigen

@@ -2136,7 +2136,7 @@ a.dev-source-pill:hover {
}
/* === Blur for First Refresh === */
.grid-stack.blurred .grid-stack-item-content {
.tab-panels.blurred .tab-panel {
filter: blur(8px);
pointer-events: none;
user-select: none;
@@ -3989,74 +3989,55 @@ a.dev-source-pill:hover {
box-shadow: var(--shadow-sm);
}
/* === gridstack Dashboard-Layout === */
.grid-stack {
/* === Tab-basiertes Dashboard-Layout === */
.tab-nav {
display: flex;
gap: 4px;
flex-wrap: wrap;
border-bottom: 1px solid var(--border);
margin-bottom: 20px;
padding: 0 4px;
}
.tab-btn {
padding: 10px 18px;
background: transparent;
border: none;
color: var(--text-secondary);
font-family: inherit;
font-size: 14px;
font-weight: 500;
cursor: pointer;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
transition: color 0.15s, border-color 0.15s;
}
.tab-btn:hover {
color: var(--text-primary);
}
.tab-btn.active {
color: var(--accent);
border-bottom-color: var(--accent);
}
.tab-panels {
display: block;
}
.tab-panel {
display: none;
}
.tab-panel.active {
display: block;
}
.tab-panel > .card {
height: auto;
display: block;
}
.tab-panel .map-container {
min-height: 600px;
}
.tab-panel .ht-timeline-container {
min-height: 200px;
}
.grid-stack > .grid-stack-item > .grid-stack-item-content {
overflow: hidden;
}
.grid-stack-item-content > .card {
height: 100%;
display: flex;
flex-direction: column;
}
.grid-stack-item-content .incident-analysis-summary > #summary-content,
.grid-stack-item-content .incident-analysis-factcheck > .factcheck-list,
.grid-stack-item-content #timeline,
.grid-stack-item-content #zusammenfassung-content {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
min-height: 0;
scrollbar-width: thin;
scrollbar-color: var(--text-disabled) transparent;
}
.grid-stack-item-content .incident-analysis-summary > #summary-content::-webkit-scrollbar,
.grid-stack-item-content .incident-analysis-factcheck > .factcheck-list::-webkit-scrollbar,
.grid-stack-item-content #timeline::-webkit-scrollbar,
.grid-stack-item-content #zusammenfassung-content::-webkit-scrollbar { width: 6px; }
.grid-stack-item-content .incident-analysis-summary > #summary-content::-webkit-scrollbar-track,
.grid-stack-item-content .incident-analysis-factcheck > .factcheck-list::-webkit-scrollbar-track,
.grid-stack-item-content #timeline::-webkit-scrollbar-track,
.grid-stack-item-content #zusammenfassung-content::-webkit-scrollbar-track { background: transparent; border-radius: 3px; }
.grid-stack-item-content .incident-analysis-summary > #summary-content::-webkit-scrollbar-thumb,
.grid-stack-item-content .incident-analysis-factcheck > .factcheck-list::-webkit-scrollbar-thumb,
.grid-stack-item-content #timeline::-webkit-scrollbar-thumb,
.grid-stack-item-content #zusammenfassung-content::-webkit-scrollbar-thumb { background: var(--text-disabled); border-radius: 3px; }
.grid-stack-item-content .incident-analysis-summary > #summary-content::-webkit-scrollbar-thumb:hover,
.grid-stack-item-content .incident-analysis-factcheck > .factcheck-list::-webkit-scrollbar-thumb:hover,
.grid-stack-item-content #timeline::-webkit-scrollbar-thumb:hover,
.grid-stack-item-content #zusammenfassung-content::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }
/* Quellenübersicht: Kachel wächst beim Aufklappen via resizeTileToContent */
.grid-stack-item-content #source-overview-content {
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: var(--text-disabled) transparent;
}
.grid-stack-item-content #source-overview-content::-webkit-scrollbar { width: 6px; }
.grid-stack-item-content #source-overview-content::-webkit-scrollbar-track { background: transparent; border-radius: 3px; }
.grid-stack-item-content #source-overview-content::-webkit-scrollbar-thumb { background: var(--text-disabled); border-radius: 3px; }
.grid-stack-item-content #source-overview-content::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }
.grid-stack-item-content .incident-analysis-summary,
.grid-stack-item-content .incident-analysis-factcheck {
max-height: none;
overflow: hidden;
}
.grid-stack .card-header {
cursor: grab;
}
.tab-panels.blurred { filter: blur(4px); pointer-events: none; }
.grid-stack .card-header:active {
cursor: grabbing;
@@ -4073,56 +4054,6 @@ a.dev-source-pill:hover {
opacity: 0.5;
}
/* Layout-Toolbar */
.layout-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--sp-md) 0;
}
.layout-toggles {
display: flex;
gap: var(--sp-sm);
}
.layout-toggle-btn {
padding: var(--sp-xs) var(--sp-lg);
border-radius: var(--radius);
border: 1px solid var(--border);
background: transparent;
color: var(--text-disabled);
font-size: 12px;
font-family: var(--font-body);
cursor: pointer;
transition: all 0.2s;
text-decoration: line-through;
}
.layout-toggle-btn.active {
background: var(--tint-accent);
color: var(--accent);
border-color: var(--accent);
text-decoration: none;
}
.layout-toggle-btn:hover {
border-color: var(--accent);
}
/* Temporäre Messklasse: hebt alle Höhenbeschränkungen auf */
.grid-stack-item.gs-measuring {
height: auto !important;
}
.gs-measuring > .grid-stack-item-content {
height: auto !important;
position: relative !important;
}
.gs-measuring .grid-stack-item-content > .card {
height: auto !important;
}
/* === Barrierefreiheit (A11y) === */