diff --git a/src/static/dashboard.html b/src/static/dashboard.html index e5995ce..67d4a46 100644 --- a/src/static/dashboard.html +++ b/src/static/dashboard.html @@ -764,7 +764,7 @@ - + diff --git a/src/static/js/tutorial.js b/src/static/js/tutorial.js index 1dc5e38..5ff7103 100644 --- a/src/static/js/tutorial.js +++ b/src/static/js/tutorial.js @@ -493,6 +493,17 @@ const Tutorial = { this._stepTimers = []; }, + // Sichere Demo-Ausfuehrung: Faengt Fehler ab und stellt Navigation sicher + _runDemo(fn) { + var self = this; + fn.call(this).catch(function(e) { + self._hideCursor(); + self._clearSubHighlights(); + self._demoRunning = false; + self._enableNavAfterDemo(); + }); + }, + // ----------------------------------------------------------------------- // Scroll-Helfer: Element in den sichtbaren Bereich scrollen // ----------------------------------------------------------------------- @@ -575,7 +586,7 @@ const Tutorial = { if (modalBody) modalBody.scrollTop = 0; var t = document.getElementById('inc-title'); if (t) t.value = ''; var d = document.getElementById('inc-description'); if (d) d.value = ''; - Tutorial._simulateFormTitleDesc(); + Tutorial._runDemo(Tutorial._simulateFormTitleDesc); }, onExit: function() { Tutorial._clearSubHighlights(); @@ -600,7 +611,7 @@ const Tutorial = { if (modalBody) modalBody.scrollTo({ top: 0, behavior: 'smooth' }); Tutorial._stepTimeout(function() { Tutorial._highlightSub('#inc-type'); - Tutorial._simulateTypeSwitch(); + Tutorial._runDemo(Tutorial._simulateTypeSwitch); }, 500); }, onExit: function() { @@ -624,7 +635,7 @@ const Tutorial = { var overlay = document.getElementById('modal-new'); if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active'); if (overlay) overlay.style.zIndex = '9002'; - Tutorial._simulateFormSources(); + Tutorial._runDemo(Tutorial._simulateFormSources); }, onExit: function() { Tutorial._clearSubHighlights(); @@ -645,7 +656,7 @@ const Tutorial = { var overlay = document.getElementById('modal-new'); if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active'); if (overlay) overlay.style.zIndex = '9002'; - Tutorial._simulateFormVisibility(); + Tutorial._runDemo(Tutorial._simulateFormVisibility); }, onExit: function() { Tutorial._clearSubHighlights(); @@ -666,7 +677,7 @@ const Tutorial = { var overlay = document.getElementById('modal-new'); if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active'); if (overlay) overlay.style.zIndex = '9002'; - Tutorial._simulateFormRefresh(); + Tutorial._runDemo(Tutorial._simulateFormRefresh); }, onExit: function() { Tutorial._clearSubHighlights(); @@ -687,7 +698,7 @@ const Tutorial = { var overlay = document.getElementById('modal-new'); if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active'); if (overlay) overlay.style.zIndex = '9002'; - Tutorial._simulateFormRetention(); + Tutorial._runDemo(Tutorial._simulateFormRetention); }, onExit: function() { Tutorial._clearSubHighlights(); @@ -709,7 +720,7 @@ const Tutorial = { var overlay = document.getElementById('modal-new'); if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active'); if (overlay) overlay.style.zIndex = '9002'; - Tutorial._simulateFormNotifications(); + Tutorial._runDemo(Tutorial._simulateFormNotifications); }, onExit: function() { var overlay = document.getElementById('modal-new'); @@ -970,7 +981,7 @@ const Tutorial = { position: 'right', disableNav: true, onEnter: function() { - Tutorial._simulateDrag(); + Tutorial._runDemo(Tutorial._simulateDrag); }, }, // 19 - Resize Demo @@ -984,7 +995,7 @@ const Tutorial = { position: 'left', disableNav: true, onEnter: function() { - Tutorial._simulateResize(); + Tutorial._runDemo(Tutorial._simulateResize); }, }, // 20 - Theme @@ -1044,7 +1055,7 @@ const Tutorial = { } if (overlay) overlay.style.zIndex = '9002'; Tutorial._stepTimeout(function() { - Tutorial._simulateSourcesInfoIcon(); + Tutorial._runDemo(Tutorial._simulateSourcesInfoIcon); }, 1500); }, onExit: function() { @@ -1075,7 +1086,7 @@ const Tutorial = { } } if (overlay) overlay.style.zIndex = '9002'; - Tutorial._simulateSourcesActions(); + Tutorial._runDemo(Tutorial._simulateSourcesActions); }, onExit: function() { var overlay = document.getElementById('modal-sources'); @@ -1594,7 +1605,7 @@ const Tutorial = { } // Nach Zoom: Demo starten setTimeout(function() { - self._simulateMapDemo(); + self._runDemo(self._simulateMapDemo); }, 3200); }, 1200); }, @@ -1680,8 +1691,9 @@ const Tutorial = { // Helfer: Cursor zu einem Element bewegen async _cursorToElement(selector, fromX, fromY) { var el = document.querySelector(selector); - if (!el) return { x: fromX, y: fromY }; + if (!el) return { x: fromX || 400, y: fromY || 300 }; var rect = el.getBoundingClientRect(); + if (!rect.width && !rect.height) return { x: fromX || 400, y: fromY || 300 }; var tx = rect.left + Math.min(rect.width / 2, 60); var ty = rect.top + rect.height / 2; if (fromX !== undefined && fromY !== undefined) { @@ -1707,6 +1719,8 @@ const Tutorial = { // ----------------------------------------------------------------------- async _simulateFormTitleDesc() { this._demoRunning = true; + // Warten bis Modal vollstaendig gerendert + await this._wait(600); var titleInput = document.getElementById('inc-title'); var descInput = document.getElementById('inc-description'); if (!titleInput) { this._demoRunning = false; this._enableNavAfterDemo(); return; }