1+ let dashboardGrid ;
2+ let currentPw = "" ;
3+
4+ // 1. Grid initialisieren
5+ function initGridstack ( ) {
6+ dashboardGrid = GridStack . init ( {
7+ cellHeight : 50 ,
8+ margin : 20 ,
9+ animate : true ,
10+ staticGrid : true ,
11+ disableOneColumnMode : false ,
12+ oneColumnModeDomSort : true
13+ } ) ;
14+
15+ dashboardGrid . on ( 'change' , function ( event , items ) {
16+ saveLayout ( ) ;
17+ } ) ;
18+ }
19+
20+ // 2. Layout speichern (Nur in DB und nur wenn PW da ist)
21+ async function saveLayout ( ) {
22+ if ( ! dashboardGrid || ! currentPw || currentPw === "" ) {
23+ return ;
24+ }
25+
26+ const layoutData = dashboardGrid . save ( ) ;
27+
28+ try {
29+ const response = await fetch ( '/api/layout' , {
30+ method : 'POST' ,
31+ headers : {
32+ 'Content-Type' : 'application/json'
33+ } ,
34+ body : JSON . stringify ( {
35+ layout : layoutData ,
36+ pw : currentPw
37+ } )
38+ } ) ;
39+
40+ if ( ! response . ok ) {
41+ const errorText = await response . text ( ) ;
42+ console . error ( "Speichern fehlgeschlagen:" , errorText ) ;
43+ }
44+ } catch ( e ) {
45+ console . error ( "Netzwerkfehler beim Speichern:" , e ) ;
46+ }
47+ }
48+
49+ // 3. Layout beim Starten laden
50+ async function loadLayout ( ) {
51+ let savedLayout = null ;
52+ try {
53+ const response = await fetch ( '/api/layout' ) ;
54+ if ( response . ok ) {
55+ const data = await response . json ( ) ;
56+ if ( data && data . layout ) savedLayout = data . layout ;
57+ }
58+ } catch ( e ) { console . error ( "DB Load failed" , e ) ; }
59+
60+ // Wenn ein Layout auf dem Server existiert, anwenden
61+ if ( savedLayout && dashboardGrid ) {
62+ dashboardGrid . removeAll ( ) ;
63+ dashboardGrid . load ( savedLayout ) ;
64+ console . log ( "Globales Layout erfolgreich geladen." ) ;
65+ }
66+ }
67+
68+ // 4. Reset-Funktion für den Button im Admin-Bereich
69+ async function resetDatabaseLayout ( ) {
70+ if ( ! confirm ( "Möchtest du das Layout für ALLE Nutzer auf den Standard zurücksetzen?" ) ) return ;
71+
72+ if ( ! currentPw ) return alert ( "Bitte erst als Admin einloggen!" ) ;
73+
74+ const res = await fetch ( '/api/layout' , {
75+ method : 'POST' ,
76+ headers : { 'Content-Type' : 'application/json' } ,
77+ body : JSON . stringify ( {
78+ layout : "RESET" , // Signalwort für das Python-Backend
79+ pw : currentPw
80+ } )
81+ } ) ;
82+
83+ if ( res . ok ) {
84+ location . reload ( ) ; // Seite neu laden, um Standard-HTML zu zeigen
85+ }
86+ }
87+
88+ document . addEventListener ( "DOMContentLoaded" , async ( ) => {
89+ // --- PHASE 1: Das Gerüst aufbauen ---
90+ initGridstack ( ) ;
91+ await loadLayout ( ) ; // Wartet, bis Boxen aus DB oder LocalStorage da sind
92+
93+ // --- PHASE 2: Startwerte für Datumsfelder setzen ---
94+ const t = new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ;
95+ const startInput = document . getElementById ( 'start' ) ;
96+ const endInput = document . getElementById ( 'end' ) ;
97+
98+ if ( startInput && endInput ) {
99+ startInput . value = t ;
100+ endInput . value = t ;
101+ startInput . addEventListener ( 'change' , updateQuickButtonsActiveState ) ;
102+ endInput . addEventListener ( 'change' , updateQuickButtonsActiveState ) ;
103+ }
104+
105+ // --- PHASE 3: Daten in die Boxen pumpen ---
106+ // Wir prüfen bei jeder Funktion, ob sie existiert, um Fehler zu vermeiden
107+ try {
108+ if ( typeof fetchData === "function" ) await fetchData ( ) ;
109+ if ( typeof updateWeather === "function" ) updateWeather ( ) ;
110+ if ( typeof updateLive === "function" ) updateLive ( ) ;
111+ if ( typeof updatePeaks === "function" ) updatePeaks ( ) ;
112+ if ( typeof updateQuickButtonsActiveState === "function" ) updateQuickButtonsActiveState ( ) ;
113+
114+ // ML-Funktionen
115+ if ( typeof loadForecast === "function" ) loadForecast ( ) ;
116+ if ( typeof loadGlobalShap === "function" ) loadGlobalShap ( ) ;
117+ if ( typeof loadFeatureImportance === "function" ) loadFeatureImportance ( ) ;
118+
119+ // Heatmaps
120+ if ( typeof initHeatmapYears === "function" ) initHeatmapYears ( ) ;
121+ if ( typeof initHourlyHeatmap === "function" ) initHourlyHeatmap ( ) ;
122+
123+ } catch ( err ) {
124+ console . error ( "Fehler beim initialen Daten-Load:" , err ) ;
125+ }
126+
127+ // --- PHASE 4: Intervalle für Updates starten ---
128+ setInterval ( ( ) => { if ( typeof updateLive === "function" ) updateLive ( ) ; } , 5000 ) ;
129+ setInterval ( ( ) => { if ( typeof fetchData === "function" ) fetchData ( ) ; } , 60000 ) ;
130+ setInterval ( ( ) => { if ( typeof updatePeaks === "function" ) updatePeaks ( ) ; } , 60000 ) ;
131+ setInterval ( ( ) => { if ( typeof checkLoadingStatus === "function" ) checkLoadingStatus ( ) ; } , 500 ) ;
132+
133+ } ) ;
0 commit comments