diff --git a/src/static/dashboard.html b/src/static/dashboard.html index 6f19152..abfef81 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 98e4e2e..6f4ed65 100644 --- a/src/static/js/tutorial.js +++ b/src/static/js/tutorial.js @@ -929,19 +929,19 @@ const Tutorial = { } }, }, - // 22 - Quellen Modal + // 22 - Quellen Modal (mit Cursor-Demo) { id: 'sources-modal', target: '#modal-sources .modal', title: 'Quellen verwalten', - text: 'Die Quellenverwaltung zeigt alle konfigurierten Nachrichtenquellen. ' - + 'Hier sehen Sie für jede Quelle:

' - + 'Name und URL - Die Quellbezeichnung und Adresse
' - + 'Kategorie - Nachrichtenagentur, Qualitätszeitung, etc.
' - + 'Sprache - Deutsch, Englisch oder Mehrsprachig
' - + 'Status - Aktiv oder deaktiviert

' - + 'Sie können Quellen auch für einzelne Lagen ausschließen, ohne sie global zu deaktivieren.', + text: 'Die Quellenverwaltung zeigt alle konfigurierten Nachrichtenquellen.

' + + 'Info-Symbol (i) - Zeigt Typ, Sprache und Ausrichtung der Quelle
' + + 'Kategorie-Badge - Farbige Kennzeichnung der Quellkategorie
' + + 'Ausschlie\u00dfen - Quelle f\u00fcr einzelne Lagen sperren
' + + '+ Quelle - Neue Quellen per URL hinzuf\u00fcgen

' + + 'Beobachten Sie, wie die Quellendetails angezeigt werden:', position: 'left', + disableNav: true, onEnter: function() { var overlay = document.getElementById('modal-sources'); if (overlay && !overlay.classList.contains('active')) { @@ -950,6 +950,10 @@ const Tutorial = { } } if (overlay) overlay.style.zIndex = '9002'; + // Warten bis Quellen geladen, dann Demo starten + Tutorial._stepTimeout(function() { + Tutorial._simulateSourcesDemo(); + }, 1500); }, onExit: function() { var overlay = document.getElementById('modal-sources'); @@ -957,6 +961,10 @@ const Tutorial = { overlay.classList.remove('active'); overlay.style.zIndex = ''; } + // Tooltip entfernen falls manuell erzeugt + var tip = document.getElementById('tutorial-tooltip'); + if (tip) tip.remove(); + Tutorial._clearSubHighlights(); }, }, // 23 - Chat @@ -1903,6 +1911,92 @@ const Tutorial = { this._enableNavAfterDemo(); }, + // ----------------------------------------------------------------------- + // Quellenverwaltung-Demo: Info-Icon hover + Tooltip zeigen + // ----------------------------------------------------------------------- + async _simulateSourcesDemo() { + this._demoRunning = true; + + // Warten bis Quellen geladen sind + var attempts = 0; + while (attempts < 10) { + var infoIcon = document.querySelector('#sources-list .info-icon'); + if (infoIcon) break; + await this._wait(300); + attempts++; + } + + var infoIcon = document.querySelector('#sources-list .info-icon'); + if (!infoIcon) { + this._demoRunning = false; + this._enableNavAfterDemo(); + return; + } + + // 1. Cursor zum ersten Info-Icon + var rect = infoIcon.getBoundingClientRect(); + var targetX = rect.left + rect.width / 2; + var targetY = rect.top + rect.height / 2; + + this._showCursor(targetX - 80, targetY - 60, 'default'); + await this._wait(300); + await this._animateCursor(targetX - 80, targetY - 60, targetX, targetY, 600); + await this._wait(200); + + // 2. Info-Icon highlighten + this._highlightSub('#sources-list .info-icon'); + + // 3. Tooltip manuell anzeigen (da pointer-events blockiert sind) + var tooltipText = infoIcon.getAttribute('data-tooltip') || ''; + if (tooltipText) { + var tooltip = document.createElement('div'); + tooltip.id = 'tutorial-tooltip'; + tooltip.style.cssText = 'position:fixed;z-index:9999;background:var(--bg-card);color:var(--text-primary);' + + 'border:1px solid var(--accent);border-radius:var(--radius);padding:8px 12px;font-size:12px;' + + 'line-height:1.5;max-width:250px;white-space:pre-line;box-shadow:var(--shadow-md);' + + 'pointer-events:none;'; + tooltip.textContent = tooltipText; + document.body.appendChild(tooltip); + + // Tooltip unter dem Icon positionieren + tooltip.style.left = Math.max(8, rect.left - 20) + 'px'; + tooltip.style.top = (rect.bottom + 8) + 'px'; + } + + await this._wait(3000); + + // 4. Tooltip entfernen + var tip = document.getElementById('tutorial-tooltip'); + if (tip) tip.remove(); + this._clearSubHighlights(); + + // 5. Zum "+ Quelle" Button + var addBtn = document.querySelector('.sources-toolbar-actions .btn-primary'); + if (addBtn) { + var addRect = addBtn.getBoundingClientRect(); + await this._animateCursor(targetX, targetY, addRect.left + addRect.width / 2, addRect.top + addRect.height / 2, 500); + this._highlightSub('.sources-toolbar-actions .btn-primary'); + await this._wait(2000); + this._clearSubHighlights(); + } + + // 6. Zum "Ausschlie\u00dfen" Button der ersten Quelle + var excludeBtn = document.querySelector('#sources-list .source-group-actions .btn-secondary'); + if (excludeBtn) { + var exRect = excludeBtn.getBoundingClientRect(); + var prevRect = addBtn ? addBtn.getBoundingClientRect() : rect; + await this._animateCursor(prevRect.left + prevRect.width / 2, prevRect.top + prevRect.height / 2, + exRect.left + exRect.width / 2, exRect.top + exRect.height / 2, 500); + this._highlightSub('#sources-list .source-group-actions .btn-secondary'); + await this._wait(2000); + this._clearSubHighlights(); + } + + this._hideCursor(); + this._demoRunning = false; + this._enableNavAfterDemo(); + }, + // ----------------------------------------------------------------------- // Keyboard // -----------------------------------------------------------------------