Tutorial: Formular Feld fuer Feld erklaeren + Klicks blockieren
Formular-Steps komplett ueberarbeitet (Steps 2-9): - Step 3: Titel + Beschreibung mit Tipp-Animation - Step 4: Art der Lage (Live vs Recherche) mit Cursor-Demo + Erklaerung - Step 5: Quellen (International + Telegram) einzeln gehighlightet + erklaert - Step 6: Sichtbarkeit (Oeffentlich/Privat) mit Toggle-Demo - Step 7: Aktualisierung + Intervall, Hinweis auf Creditverbrauch - Step 8: Aufbewahrung erklaert - Step 9: E-Mail-Benachrichtigungen (alle 3 Optionen einzeln gehighlightet) Jedes Feld wird mit Cursor angesteuert, gehighlightet und erklaert. Modal-Body scrollt automatisch zu den jeweiligen Feldern. Klick-Blockierung: Waehrend des Tutorials sind alle Dashboard-Elemente nicht anklickbar (pointer-events:none auf body.tutorial-active). Nur die Tutorial-Bubble mit Navigation bleibt bedienbar. Duplikate der alten Methoden entfernt. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -4943,266 +4943,266 @@ a.map-popup-article:hover {
|
|||||||
position: relative;
|
position: relative;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
Tutorial System
|
Tutorial System
|
||||||
================================================================ */
|
================================================================ */
|
||||||
|
|
||||||
/* Overlay (Hintergrund-Abdunkelung) */
|
/* Overlay (Hintergrund-Abdunkelung) */
|
||||||
.tutorial-overlay {
|
.tutorial-overlay {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 9000;
|
z-index: 9000;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.tutorial-overlay.active {
|
.tutorial-overlay.active {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Spotlight */
|
/* Spotlight */
|
||||||
.tutorial-spotlight {
|
.tutorial-spotlight {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 9001;
|
z-index: 9001;
|
||||||
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.65);
|
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.65);
|
||||||
border: 2px solid var(--accent);
|
border: 2px solid var(--accent);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
transition: top 0.4s ease, left 0.4s ease, width 0.4s ease, height 0.4s ease, opacity 0.3s ease;
|
transition: top 0.4s ease, left 0.4s ease, width 0.4s ease, height 0.4s ease, opacity 0.3s ease;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Target-Element klickbar machen */
|
/* Target-Element klickbar machen */
|
||||||
.tutorial-overlay.active ~ * [data-tutorial-target] {
|
.tutorial-overlay.active ~ * [data-tutorial-target] {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 9002;
|
z-index: 9002;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bubble (Sprechblase) */
|
/* Bubble (Sprechblase) */
|
||||||
.tutorial-bubble {
|
.tutorial-bubble {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 9003;
|
z-index: 9003;
|
||||||
width: 340px;
|
width: 340px;
|
||||||
background: var(--bg-card);
|
background: var(--bg-card);
|
||||||
border: 1px solid var(--accent);
|
border: 1px solid var(--accent);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
box-shadow: var(--shadow-lg), 0 0 20px rgba(150, 121, 26, 0.15);
|
box-shadow: var(--shadow-lg), 0 0 20px rgba(150, 121, 26, 0.15);
|
||||||
padding: var(--sp-xl);
|
padding: var(--sp-xl);
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.3s ease, top 0.4s ease, left 0.4s ease, transform 0.4s ease;
|
transition: opacity 0.3s ease, top 0.4s ease, left 0.4s ease, transform 0.4s ease;
|
||||||
font-family: var(--font-body);
|
font-family: var(--font-body);
|
||||||
}
|
}
|
||||||
.tutorial-bubble.visible {
|
.tutorial-bubble.visible {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bubble-Pfeil */
|
/* Bubble-Pfeil */
|
||||||
.tutorial-bubble::before {
|
.tutorial-bubble::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 12px;
|
width: 12px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
background: var(--bg-card);
|
background: var(--bg-card);
|
||||||
border: 1px solid var(--accent);
|
border: 1px solid var(--accent);
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tutorial-pos-bottom::before {
|
.tutorial-pos-bottom::before {
|
||||||
top: -7px;
|
top: -7px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -6px;
|
margin-left: -6px;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
.tutorial-pos-top::before {
|
.tutorial-pos-top::before {
|
||||||
bottom: -7px;
|
bottom: -7px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -6px;
|
margin-left: -6px;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
}
|
}
|
||||||
.tutorial-pos-right::before {
|
.tutorial-pos-right::before {
|
||||||
left: -7px;
|
left: -7px;
|
||||||
top: 30px;
|
top: 30px;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
.tutorial-pos-left::before {
|
.tutorial-pos-left::before {
|
||||||
right: -7px;
|
right: -7px;
|
||||||
top: 30px;
|
top: 30px;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
}
|
}
|
||||||
.tutorial-pos-center::before {
|
.tutorial-pos-center::before {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bubble-Inhalt */
|
/* Bubble-Inhalt */
|
||||||
.tutorial-bubble-counter {
|
.tutorial-bubble-counter {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
margin-bottom: var(--sp-sm);
|
margin-bottom: var(--sp-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tutorial-bubble-title {
|
.tutorial-bubble-title {
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
margin-bottom: var(--sp-md);
|
margin-bottom: var(--sp-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tutorial-bubble-text {
|
.tutorial-bubble-text {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
margin-bottom: var(--sp-lg);
|
margin-bottom: var(--sp-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close-Button */
|
/* Close-Button */
|
||||||
.tutorial-bubble-close {
|
.tutorial-bubble-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--sp-md);
|
top: var(--sp-md);
|
||||||
right: var(--sp-md);
|
right: var(--sp-md);
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
transition: color 0.15s, background 0.15s;
|
transition: color 0.15s, background 0.15s;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
.tutorial-bubble-close:hover {
|
.tutorial-bubble-close:hover {
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
background: var(--bg-hover);
|
background: var(--bg-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fortschrittspunkte */
|
/* Fortschrittspunkte */
|
||||||
.tutorial-bubble-dots {
|
.tutorial-bubble-dots {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: var(--sp-lg);
|
margin-bottom: var(--sp-lg);
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.tutorial-dot {
|
.tutorial-dot {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--border);
|
background: var(--border);
|
||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
}
|
}
|
||||||
.tutorial-dot.active {
|
.tutorial-dot.active {
|
||||||
background: var(--accent);
|
background: var(--accent);
|
||||||
width: 18px;
|
width: 18px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
.tutorial-dot.done {
|
.tutorial-dot.done {
|
||||||
background: var(--accent-hover);
|
background: var(--accent-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nav-Buttons */
|
/* Nav-Buttons */
|
||||||
.tutorial-bubble-nav {
|
.tutorial-bubble-nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--sp-md);
|
gap: var(--sp-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tutorial-btn {
|
.tutorial-btn {
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
padding: var(--sp-md) var(--sp-xl);
|
padding: var(--sp-md) var(--sp-xl);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 0.15s, color 0.15s;
|
transition: background 0.15s, color 0.15s;
|
||||||
font-family: var(--font-body);
|
font-family: var(--font-body);
|
||||||
}
|
}
|
||||||
.tutorial-btn-back {
|
.tutorial-btn-back {
|
||||||
background: var(--bg-hover);
|
background: var(--bg-hover);
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
.tutorial-btn-back:hover {
|
.tutorial-btn-back:hover {
|
||||||
background: var(--bg-elevated);
|
background: var(--bg-elevated);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
.tutorial-btn-next {
|
.tutorial-btn-next {
|
||||||
background: var(--accent);
|
background: var(--accent);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
.tutorial-btn-next:hover {
|
.tutorial-btn-next:hover {
|
||||||
background: var(--accent-hover);
|
background: var(--accent-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Virtueller Cursor */
|
/* Virtueller Cursor */
|
||||||
.tutorial-cursor {
|
.tutorial-cursor {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 9500;
|
z-index: 9500;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
.tutorial-cursor.visible {
|
.tutorial-cursor.visible {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.tutorial-cursor-default {
|
.tutorial-cursor-default {
|
||||||
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M5 3l14 8-6 2 4 8-3 1-4-8-5 4z' fill='%23fff' stroke='%23000' stroke-width='1'/%3E%3C/svg%3E") no-repeat center/contain;
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M5 3l14 8-6 2 4 8-3 1-4-8-5 4z' fill='%23fff' stroke='%23000' stroke-width='1'/%3E%3C/svg%3E") no-repeat center/contain;
|
||||||
}
|
}
|
||||||
.tutorial-cursor-grabbing {
|
.tutorial-cursor-grabbing {
|
||||||
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M8 10V8a1 1 0 112 0v2h1V7a1 1 0 112 0v3h1V8a1 1 0 112 0v2h.5a1.5 1.5 0 011.5 1.5V16a5 5 0 01-5 5h-2a5 5 0 01-5-5v-3.5A1.5 1.5 0 017.5 11H8z' fill='%23fff' stroke='%23000' stroke-width='0.8'/%3E%3C/svg%3E") no-repeat center/contain;
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M8 10V8a1 1 0 112 0v2h1V7a1 1 0 112 0v3h1V8a1 1 0 112 0v2h.5a1.5 1.5 0 011.5 1.5V16a5 5 0 01-5 5h-2a5 5 0 01-5-5v-3.5A1.5 1.5 0 017.5 11H8z' fill='%23fff' stroke='%23000' stroke-width='0.8'/%3E%3C/svg%3E") no-repeat center/contain;
|
||||||
}
|
}
|
||||||
.tutorial-cursor-resize {
|
.tutorial-cursor-resize {
|
||||||
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M22 22H20V20H22V22ZM22 18H18V22H16V16H22V18ZM18 18V14H22V12H16V18H18ZM14 22H12V16H18V14H10V22H14Z' fill='%23fff' stroke='%23000' stroke-width='0.3'/%3E%3C/svg%3E") no-repeat center/contain;
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M22 22H20V20H22V22ZM22 18H18V22H16V16H22V18ZM18 18V14H22V12H16V18H18ZM14 22H12V16H18V14H10V22H14Z' fill='%23fff' stroke='%23000' stroke-width='0.3'/%3E%3C/svg%3E") no-repeat center/contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chat Tutorial-Hinweis */
|
/* Chat Tutorial-Hinweis */
|
||||||
.chat-tutorial-hint {
|
.chat-tutorial-hint {
|
||||||
background: var(--bg-card);
|
background: var(--bg-card);
|
||||||
border: 1px solid var(--accent);
|
border: 1px solid var(--accent);
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
padding: var(--sp-lg);
|
padding: var(--sp-lg);
|
||||||
margin: var(--sp-md) var(--sp-md) 0;
|
margin: var(--sp-md) var(--sp-md) 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 0.15s;
|
transition: background 0.15s;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
.chat-tutorial-hint:hover {
|
.chat-tutorial-hint:hover {
|
||||||
background: var(--tint-accent-subtle);
|
background: var(--tint-accent-subtle);
|
||||||
}
|
}
|
||||||
.chat-tutorial-hint strong {
|
.chat-tutorial-hint strong {
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Sub-Element Highlight innerhalb von Tutorial-Steps */
|
/* Sub-Element Highlight innerhalb von Tutorial-Steps */
|
||||||
.tutorial-sub-highlight {
|
.tutorial-sub-highlight {
|
||||||
outline: 2px solid var(--accent) !important;
|
outline: 2px solid var(--accent) !important;
|
||||||
outline-offset: 3px;
|
outline-offset: 3px;
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
animation: tutorial-sub-pulse 1.5s ease-in-out infinite;
|
animation: tutorial-sub-pulse 1.5s ease-in-out infinite;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 9002;
|
z-index: 9002;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes tutorial-sub-pulse {
|
@keyframes tutorial-sub-pulse {
|
||||||
0%, 100% { outline-color: var(--accent); }
|
0%, 100% { outline-color: var(--accent); }
|
||||||
50% { outline-color: rgba(150, 121, 26, 0.4); }
|
50% { outline-color: rgba(150, 121, 26, 0.4); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chat Tutorial-Hint Layout */
|
/* Chat Tutorial-Hint Layout */
|
||||||
.chat-tutorial-hint {
|
.chat-tutorial-hint {
|
||||||
@@ -5228,3 +5228,17 @@ a.map-popup-article:hover {
|
|||||||
.chat-tutorial-hint-close:hover {
|
.chat-tutorial-hint-close:hover {
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Tutorial: Klicks auf Dashboard blockieren */
|
||||||
|
body.tutorial-active .dashboard,
|
||||||
|
body.tutorial-active .modal-overlay,
|
||||||
|
body.tutorial-active .chat-toggle-btn,
|
||||||
|
body.tutorial-active #chat-window {
|
||||||
|
pointer-events: none !important;
|
||||||
|
}
|
||||||
|
/* Bubble und Cursor bleiben klickbar */
|
||||||
|
body.tutorial-active .tutorial-bubble,
|
||||||
|
body.tutorial-active .tutorial-cursor {
|
||||||
|
pointer-events: auto !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<link rel="stylesheet" href="/static/vendor/MarkerCluster.css">
|
<link rel="stylesheet" href="/static/vendor/MarkerCluster.css">
|
||||||
<link rel="stylesheet" href="/static/vendor/MarkerCluster.Default.css">
|
<link rel="stylesheet" href="/static/vendor/MarkerCluster.Default.css">
|
||||||
<link rel="stylesheet" href="/static/css/network.css?v=20260316a">
|
<link rel="stylesheet" href="/static/css/network.css?v=20260316a">
|
||||||
<link rel="stylesheet" href="/static/css/style.css?v=20260316e">
|
<link rel="stylesheet" href="/static/css/style.css?v=20260316f">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<a href="#main-content" class="skip-link">Zum Hauptinhalt springen</a>
|
<a href="#main-content" class="skip-link">Zum Hauptinhalt springen</a>
|
||||||
@@ -764,7 +764,7 @@
|
|||||||
<script src="/static/js/api_network.js?v=20260316a"></script>
|
<script src="/static/js/api_network.js?v=20260316a"></script>
|
||||||
<script src="/static/js/network-graph.js?v=20260316a"></script>
|
<script src="/static/js/network-graph.js?v=20260316a"></script>
|
||||||
<script src="/static/js/app_network.js?v=20260316a"></script>
|
<script src="/static/js/app_network.js?v=20260316a"></script>
|
||||||
<script src="/static/js/tutorial.js?v=20260316g"></script>
|
<script src="/static/js/tutorial.js?v=20260316h"></script>
|
||||||
<script src="/static/js/chat.js?v=20260316f"></script>
|
<script src="/static/js/chat.js?v=20260316f"></script>
|
||||||
<script>document.addEventListener("DOMContentLoaded",function(){Chat.init();Tutorial.init()});</script>
|
<script>document.addEventListener("DOMContentLoaded",function(){Chat.init();Tutorial.init()});</script>
|
||||||
|
|
||||||
|
|||||||
@@ -460,14 +460,13 @@ const Tutorial = {
|
|||||||
id: 'new-incident-btn',
|
id: 'new-incident-btn',
|
||||||
target: '#new-incident-btn',
|
target: '#new-incident-btn',
|
||||||
title: 'Neue Lage anlegen',
|
title: 'Neue Lage anlegen',
|
||||||
text: 'Mit diesem Button erstellen Sie eine neue Lage. Wir simulieren jetzt die Eingabe f\u00fcr Sie.',
|
text: 'Mit diesem Button öffnen Sie das Formular zur Erstellung einer neuen Lage. '
|
||||||
|
+ 'Wir gehen jetzt gemeinsam alle Felder durch.',
|
||||||
position: 'right',
|
position: 'right',
|
||||||
onEnter: function() {
|
onEnter: function() {
|
||||||
Tutorial._stepTimeout(function() {
|
Tutorial._stepTimeout(function() {
|
||||||
var overlay = document.getElementById('modal-new');
|
var overlay = document.getElementById('modal-new');
|
||||||
if (overlay && !overlay.classList.contains('active')) {
|
if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active');
|
||||||
overlay.classList.add('active');
|
|
||||||
}
|
|
||||||
}, 1500);
|
}, 1500);
|
||||||
},
|
},
|
||||||
onExit: function() {
|
onExit: function() {
|
||||||
@@ -475,51 +474,45 @@ const Tutorial = {
|
|||||||
if (overlay) overlay.classList.remove('active');
|
if (overlay) overlay.classList.remove('active');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// 3 - Formular ausf\u00fcllen (Cursor-Demo)
|
// 3 - Titel und Beschreibung (Cursor-Demo)
|
||||||
{
|
{
|
||||||
id: 'new-incident-modal',
|
id: 'form-title-desc',
|
||||||
target: '#modal-new .modal',
|
target: '#modal-new .modal',
|
||||||
title: 'Lage konfigurieren',
|
title: 'Titel und Beschreibung',
|
||||||
text: 'Beobachten Sie, wie das Formular Schritt f\u00fcr Schritt ausgef\u00fcllt wird. '
|
text: 'Geben Sie einen aussagekräftigen <strong>Titel</strong> ein, der das Ereignis klar beschreibt. '
|
||||||
+ 'So legen Sie eine neue Lage an.',
|
+ 'Die <strong>Beschreibung</strong> liefert zusätzlichen Kontext für die Recherche.<br><br>'
|
||||||
|
+ 'Beobachten Sie die Eingabe:',
|
||||||
position: 'left',
|
position: 'left',
|
||||||
disableNav: true,
|
disableNav: true,
|
||||||
onEnter: function() {
|
onEnter: function() {
|
||||||
var overlay = document.getElementById('modal-new');
|
var overlay = document.getElementById('modal-new');
|
||||||
if (overlay && !overlay.classList.contains('active')) {
|
if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active');
|
||||||
overlay.classList.add('active');
|
|
||||||
}
|
|
||||||
if (overlay) overlay.style.zIndex = '9002';
|
if (overlay) overlay.style.zIndex = '9002';
|
||||||
// Formular zuruecksetzen
|
var modalBody = document.querySelector('#modal-new .modal-body');
|
||||||
|
if (modalBody) modalBody.scrollTop = 0;
|
||||||
var t = document.getElementById('inc-title'); if (t) t.value = '';
|
var t = document.getElementById('inc-title'); if (t) t.value = '';
|
||||||
var d = document.getElementById('inc-description'); if (d) d.value = '';
|
var d = document.getElementById('inc-description'); if (d) d.value = '';
|
||||||
var r = document.getElementById('inc-refresh-mode'); if (r) { r.value = 'manual'; try { r.dispatchEvent(new Event('change')); } catch(e) {} }
|
Tutorial._simulateFormTitleDesc();
|
||||||
Tutorial._simulateFormFill();
|
|
||||||
},
|
},
|
||||||
onExit: function() {
|
onExit: function() {
|
||||||
// Werte stehen lassen (werden in stop() aufgeraeumt)
|
Tutorial._clearSubHighlights();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// 4 - Lage-Typ: Live vs Recherche (mit Cursor-Demo)
|
// 4 - Art der Lage (Cursor-Demo)
|
||||||
{
|
{
|
||||||
id: 'incident-type',
|
id: 'form-type',
|
||||||
target: '#modal-new .modal',
|
target: '#modal-new .modal',
|
||||||
title: 'Live-Monitoring vs. Recherche',
|
title: 'Art der Lage',
|
||||||
text: '<strong>Live-Monitoring</strong> beobachtet ein Ereignis in Echtzeit. '
|
text: '<strong>Live-Monitoring</strong> beobachtet ein Ereignis in Echtzeit. Hunderte Quellen werden '
|
||||||
+ 'Hunderte Nachrichtenquellen werden automatisch durchsucht. '
|
+ 'laufend durchsucht. Ideal für aktuelle Krisen und sich entwickelnde Lagen.<br><br>'
|
||||||
+ 'Ideal f\u00fcr aktuelle Vorf\u00e4lle, Krisen oder sich entwickelnde Lagen.<br><br>'
|
+ '<strong>Analyse/Recherche</strong> untersucht ein Thema tiefergehend ohne automatische Updates. '
|
||||||
+ '<strong>Analyse/Recherche</strong> untersucht ein Thema tiefergehend. '
|
+ 'Ideal für Hintergrundanalysen und Lageberichte.',
|
||||||
+ 'Keine automatischen Updates, stattdessen gezielte Recherche mit eigenen Suchbegriffen. '
|
|
||||||
+ 'Ideal f\u00fcr Hintergrundanalysen und Lageberichte.',
|
|
||||||
position: 'left',
|
position: 'left',
|
||||||
disableNav: true,
|
disableNav: true,
|
||||||
onEnter: function() {
|
onEnter: function() {
|
||||||
var overlay = document.getElementById('modal-new');
|
var overlay = document.getElementById('modal-new');
|
||||||
if (overlay && !overlay.classList.contains('active')) {
|
if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active');
|
||||||
overlay.classList.add('active');
|
|
||||||
}
|
|
||||||
if (overlay) overlay.style.zIndex = '9002';
|
if (overlay) overlay.style.zIndex = '9002';
|
||||||
// Modal-Body nach oben scrollen zum Typ-Feld
|
|
||||||
var modalBody = document.querySelector('#modal-new .modal-body');
|
var modalBody = document.querySelector('#modal-new .modal-body');
|
||||||
if (modalBody) modalBody.scrollTo({ top: 0, behavior: 'smooth' });
|
if (modalBody) modalBody.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
Tutorial._stepTimeout(function() {
|
Tutorial._stepTimeout(function() {
|
||||||
@@ -527,19 +520,124 @@ const Tutorial = {
|
|||||||
Tutorial._simulateTypeSwitch();
|
Tutorial._simulateTypeSwitch();
|
||||||
}, 500);
|
}, 500);
|
||||||
},
|
},
|
||||||
|
onExit: function() {
|
||||||
|
var sel = document.getElementById('inc-type');
|
||||||
|
if (sel) { sel.value = 'adhoc'; try { sel.dispatchEvent(new Event('change')); } catch(e) {} }
|
||||||
|
Tutorial._clearSubHighlights();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 5 - Quellen
|
||||||
|
{
|
||||||
|
id: 'form-sources',
|
||||||
|
target: '#modal-new .modal',
|
||||||
|
title: 'Quellen konfigurieren',
|
||||||
|
text: '<strong>Internationale Quellen</strong> bezieht englischsprachige und internationale Medien '
|
||||||
|
+ 'ein (Reuters, BBC, Al Jazeera etc.). Erhöht die Abdeckung, aber auch den Analyseumfang.<br><br>'
|
||||||
|
+ '<strong>Telegram-Kanäle</strong> liefern oft frühzeitige OSINT-Informationen, '
|
||||||
|
+ 'können aber auch unbestätigte Meldungen enthalten. Für sensible Lagen empfohlen.',
|
||||||
|
position: 'left',
|
||||||
|
disableNav: true,
|
||||||
|
onEnter: function() {
|
||||||
|
var overlay = document.getElementById('modal-new');
|
||||||
|
if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active');
|
||||||
|
if (overlay) overlay.style.zIndex = '9002';
|
||||||
|
Tutorial._simulateFormSources();
|
||||||
|
},
|
||||||
|
onExit: function() {
|
||||||
|
Tutorial._clearSubHighlights();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 6 - Sichtbarkeit
|
||||||
|
{
|
||||||
|
id: 'form-visibility',
|
||||||
|
target: '#modal-new .modal',
|
||||||
|
title: 'Sichtbarkeit',
|
||||||
|
text: '<strong>Öffentlich</strong> bedeutet, dass alle Nutzer Ihrer Organisation diese Lage sehen '
|
||||||
|
+ 'und darauf zugreifen können.<br><br>'
|
||||||
|
+ '<strong>Privat</strong> macht die Lage nur für Sie persönlich sichtbar. '
|
||||||
|
+ 'Nützlich für persönliche Recherchen oder sensible Vorgänge.',
|
||||||
|
position: 'left',
|
||||||
|
disableNav: true,
|
||||||
|
onEnter: function() {
|
||||||
|
var overlay = document.getElementById('modal-new');
|
||||||
|
if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active');
|
||||||
|
if (overlay) overlay.style.zIndex = '9002';
|
||||||
|
Tutorial._simulateFormVisibility();
|
||||||
|
},
|
||||||
|
onExit: function() {
|
||||||
|
Tutorial._clearSubHighlights();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 7 - Aktualisierung und Intervall
|
||||||
|
{
|
||||||
|
id: 'form-refresh',
|
||||||
|
target: '#modal-new .modal',
|
||||||
|
title: 'Aktualisierung',
|
||||||
|
text: '<strong>Manuell</strong>: Sie starten Aktualisierungen selbst per Button.<br>'
|
||||||
|
+ '<strong>Automatisch</strong>: Der Monitor aktualisiert im eingestellten Intervall.<br><br>'
|
||||||
|
+ '<strong>Wichtig:</strong> Kürzere Intervalle liefern aktuellere Daten, '
|
||||||
|
+ 'erhöhen aber den Creditverbrauch. Für die meisten Lagen sind 15 bis 30 Minuten ein guter Richtwert.',
|
||||||
|
position: 'left',
|
||||||
|
disableNav: true,
|
||||||
|
onEnter: function() {
|
||||||
|
var overlay = document.getElementById('modal-new');
|
||||||
|
if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active');
|
||||||
|
if (overlay) overlay.style.zIndex = '9002';
|
||||||
|
Tutorial._simulateFormRefresh();
|
||||||
|
},
|
||||||
|
onExit: function() {
|
||||||
|
Tutorial._clearSubHighlights();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 8 - Aufbewahrung
|
||||||
|
{
|
||||||
|
id: 'form-retention',
|
||||||
|
target: '#modal-new .modal',
|
||||||
|
title: 'Aufbewahrung',
|
||||||
|
text: 'Legen Sie fest, wie lange die Lage aktiv bleibt. Nach Ablauf der Frist '
|
||||||
|
+ 'wird sie automatisch ins <strong>Archiv</strong> verschoben.<br><br>'
|
||||||
|
+ 'Setzen Sie den Wert auf <strong>0</strong> für unbegrenzte Aufbewahrung. '
|
||||||
|
+ 'Standard sind 30 Tage.',
|
||||||
|
position: 'left',
|
||||||
|
disableNav: true,
|
||||||
|
onEnter: function() {
|
||||||
|
var overlay = document.getElementById('modal-new');
|
||||||
|
if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active');
|
||||||
|
if (overlay) overlay.style.zIndex = '9002';
|
||||||
|
Tutorial._simulateFormRetention();
|
||||||
|
},
|
||||||
|
onExit: function() {
|
||||||
|
Tutorial._clearSubHighlights();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 9 - E-Mail-Benachrichtigungen
|
||||||
|
{
|
||||||
|
id: 'form-notifications',
|
||||||
|
target: '#modal-new .modal',
|
||||||
|
title: 'E-Mail-Benachrichtigungen',
|
||||||
|
text: 'Lassen Sie sich per E-Mail informieren bei:<br><br>'
|
||||||
|
+ '<strong>Neues Lagebild</strong> - Wenn eine aktualisierte Zusammenfassung vorliegt<br>'
|
||||||
|
+ '<strong>Neue Artikel</strong> - Wenn neue Quellen gefunden werden<br>'
|
||||||
|
+ '<strong>Statusänderung Faktencheck</strong> - Wenn sich die Bewertung einer Behauptung ändert<br><br>'
|
||||||
|
+ 'So bleiben Sie auch ohne ständiges Einloggen auf dem Laufenden.',
|
||||||
|
position: 'left',
|
||||||
|
disableNav: true,
|
||||||
|
onEnter: function() {
|
||||||
|
var overlay = document.getElementById('modal-new');
|
||||||
|
if (overlay && !overlay.classList.contains('active')) overlay.classList.add('active');
|
||||||
|
if (overlay) overlay.style.zIndex = '9002';
|
||||||
|
Tutorial._simulateFormNotifications();
|
||||||
|
},
|
||||||
onExit: function() {
|
onExit: function() {
|
||||||
var overlay = document.getElementById('modal-new');
|
var overlay = document.getElementById('modal-new');
|
||||||
if (overlay) {
|
if (overlay) {
|
||||||
overlay.classList.remove('active');
|
overlay.classList.remove('active');
|
||||||
overlay.style.zIndex = '';
|
overlay.style.zIndex = '';
|
||||||
}
|
}
|
||||||
// Select zur\u00fccksetzen
|
|
||||||
var sel = document.getElementById('inc-type');
|
|
||||||
if (sel) { sel.value = 'adhoc'; sel.dispatchEvent(new Event('change')); }
|
|
||||||
Tutorial._clearSubHighlights();
|
Tutorial._clearSubHighlights();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// 5 - Sidebar Filter
|
// 5 - Sidebar Filter
|
||||||
{
|
{
|
||||||
id: 'sidebar-filters',
|
id: 'sidebar-filters',
|
||||||
target: '.sidebar-filter',
|
target: '.sidebar-filter',
|
||||||
@@ -905,8 +1003,9 @@ const Tutorial = {
|
|||||||
// Chat schließen falls offen
|
// Chat schließen falls offen
|
||||||
if (typeof Chat !== 'undefined' && Chat._isOpen) Chat.close();
|
if (typeof Chat !== 'undefined' && Chat._isOpen) Chat.close();
|
||||||
|
|
||||||
// Overlay einblenden
|
// Overlay einblenden + Klicks blockieren
|
||||||
this._els.overlay.classList.add('active');
|
this._els.overlay.classList.add('active');
|
||||||
|
document.body.classList.add('tutorial-active');
|
||||||
|
|
||||||
// Keyboard
|
// Keyboard
|
||||||
this._keyHandler = this._onKey.bind(this);
|
this._keyHandler = this._onKey.bind(this);
|
||||||
@@ -929,8 +1028,9 @@ const Tutorial = {
|
|||||||
this._currentStep = -1;
|
this._currentStep = -1;
|
||||||
this._demoRunning = false;
|
this._demoRunning = false;
|
||||||
|
|
||||||
// Overlay ausblenden
|
// Overlay ausblenden + Klicks freigeben
|
||||||
this._els.overlay.classList.remove('active');
|
this._els.overlay.classList.remove('active');
|
||||||
|
document.body.classList.remove('tutorial-active');
|
||||||
this._els.spotlight.style.opacity = '0';
|
this._els.spotlight.style.opacity = '0';
|
||||||
this._els.bubble.classList.remove('visible');
|
this._els.bubble.classList.remove('visible');
|
||||||
this._hideCursor();
|
this._hideCursor();
|
||||||
@@ -1307,146 +1407,117 @@ const Tutorial = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// Helfer: Cursor zu einem Element bewegen
|
||||||
// Formular-Ausf\u00fcll-Demo (Step 3)
|
async _cursorToElement(selector, fromX, fromY) {
|
||||||
// -----------------------------------------------------------------------
|
var el = document.querySelector(selector);
|
||||||
async _simulateFormFill() {
|
if (!el) return { x: fromX, y: fromY };
|
||||||
this._demoRunning = true;
|
var rect = el.getBoundingClientRect();
|
||||||
|
var tx = rect.left + Math.min(rect.width / 2, 60);
|
||||||
|
var ty = rect.top + rect.height / 2;
|
||||||
|
if (fromX !== undefined && fromY !== undefined) {
|
||||||
|
await this._animateCursor(fromX, fromY, tx, ty, 500);
|
||||||
|
} else {
|
||||||
|
this._showCursor(tx, ty, 'default');
|
||||||
|
}
|
||||||
|
await this._wait(200);
|
||||||
|
return { x: tx, y: ty };
|
||||||
|
},
|
||||||
|
|
||||||
|
// Helfer: Modal-Body zu einem Element scrollen
|
||||||
|
_scrollModalTo(selector) {
|
||||||
|
var el = document.querySelector(selector);
|
||||||
|
var modalBody = document.querySelector('#modal-new .modal-body');
|
||||||
|
if (!el || !modalBody) return;
|
||||||
|
var elTop = el.offsetTop - modalBody.offsetTop;
|
||||||
|
modalBody.scrollTo({ top: Math.max(0, elTop - 20), behavior: 'smooth' });
|
||||||
|
},
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Step 3: Titel + Beschreibung
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
async _simulateFormTitleDesc() {
|
||||||
|
this._demoRunning = true;
|
||||||
var titleInput = document.getElementById('inc-title');
|
var titleInput = document.getElementById('inc-title');
|
||||||
var descInput = document.getElementById('inc-description');
|
var descInput = document.getElementById('inc-description');
|
||||||
var refreshSelect = document.getElementById('inc-refresh-mode');
|
if (!titleInput) { this._demoRunning = false; this._enableNavAfterDemo(); return; }
|
||||||
var modal = document.querySelector('#modal-new .modal');
|
|
||||||
|
|
||||||
if (!titleInput || !modal) {
|
// Cursor zum Titel
|
||||||
this._demoRunning = false;
|
|
||||||
this._enableNavAfterDemo();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modal-Body scrollen wir nach oben
|
|
||||||
var modalBody = modal.querySelector('.modal-body');
|
|
||||||
if (modalBody) modalBody.scrollTop = 0;
|
|
||||||
|
|
||||||
// 1. Cursor zum Titel-Feld
|
|
||||||
var titleRect = titleInput.getBoundingClientRect();
|
|
||||||
var startX = titleRect.left - 60;
|
|
||||||
var startY = titleRect.top - 40;
|
|
||||||
this._showCursor(startX, startY, 'default');
|
|
||||||
await this._wait(300);
|
|
||||||
await this._animateCursor(startX, startY, titleRect.left + 20, titleRect.top + titleRect.height / 2, 600);
|
|
||||||
await this._wait(200);
|
|
||||||
|
|
||||||
// Fokus + Tippen
|
|
||||||
titleInput.focus();
|
|
||||||
this._highlightSub('#inc-title');
|
this._highlightSub('#inc-title');
|
||||||
|
var pos = await this._cursorToElement('#inc-title');
|
||||||
|
titleInput.focus();
|
||||||
await this._simulateTyping(titleInput, 'Explosion in Hamburger Hafen', 1200);
|
await this._simulateTyping(titleInput, 'Explosion in Hamburger Hafen', 1200);
|
||||||
await this._wait(500);
|
await this._wait(400);
|
||||||
this._clearSubHighlights();
|
this._clearSubHighlights();
|
||||||
|
|
||||||
// 2. Cursor zur Beschreibung
|
// Cursor zur Beschreibung
|
||||||
if (descInput) {
|
if (descInput) {
|
||||||
var descRect = descInput.getBoundingClientRect();
|
|
||||||
await this._animateCursor(titleRect.left + 20, titleRect.top + titleRect.height / 2, descRect.left + 20, descRect.top + 12, 500);
|
|
||||||
await this._wait(200);
|
|
||||||
descInput.focus();
|
|
||||||
this._highlightSub('#inc-description');
|
this._highlightSub('#inc-description');
|
||||||
await this._simulateTyping(descInput, 'Schwere Explosion im Hafengebiet', 1000);
|
pos = await this._cursorToElement('#inc-description', pos.x, pos.y);
|
||||||
await this._wait(500);
|
descInput.focus();
|
||||||
|
await this._simulateTyping(descInput, 'Schwere Explosion im Hafengebiet, Burchardkai-Terminal', 1200);
|
||||||
|
await this._wait(400);
|
||||||
this._clearSubHighlights();
|
this._clearSubHighlights();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Modal-Body runterscrollen zum Refresh-Feld
|
|
||||||
if (refreshSelect && modalBody) {
|
|
||||||
// Sanft scrollen
|
|
||||||
modalBody.scrollTo({ top: modalBody.scrollHeight, behavior: 'smooth' });
|
|
||||||
await this._wait(600);
|
|
||||||
|
|
||||||
var refRect = refreshSelect.getBoundingClientRect();
|
|
||||||
var prevRect = descInput ? descInput.getBoundingClientRect() : titleRect;
|
|
||||||
await this._animateCursor(prevRect.left + 20, prevRect.top + 12, refRect.left + refRect.width / 2, refRect.top + refRect.height / 2, 600);
|
|
||||||
await this._wait(200);
|
|
||||||
|
|
||||||
this._highlightSub('#inc-refresh-mode');
|
|
||||||
refreshSelect.value = 'auto';
|
|
||||||
try { refreshSelect.dispatchEvent(new Event('change')); } catch(e) {}
|
|
||||||
await this._wait(1200);
|
|
||||||
this._clearSubHighlights();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Cursor verschwindet
|
|
||||||
this._hideCursor();
|
this._hideCursor();
|
||||||
await this._wait(300);
|
|
||||||
|
|
||||||
this._demoRunning = false;
|
this._demoRunning = false;
|
||||||
this._enableNavAfterDemo();
|
this._enableNavAfterDemo();
|
||||||
},
|
},
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Typ-Wechsel-Demo (Step 4)
|
// Step 4: Art der Lage (Typ-Wechsel)
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
async _simulateTypeSwitch() {
|
async _simulateTypeSwitch() {
|
||||||
this._demoRunning = true;
|
this._demoRunning = true;
|
||||||
var sel = document.getElementById('inc-type');
|
var sel = document.getElementById('inc-type');
|
||||||
if (!sel) { this._demoRunning = false; this._enableNavAfterDemo(); return; }
|
if (!sel) { this._demoRunning = false; this._enableNavAfterDemo(); return; }
|
||||||
|
|
||||||
var rect = sel.getBoundingClientRect();
|
var pos = await this._cursorToElement('#inc-type');
|
||||||
var targetX = rect.left + rect.width / 2;
|
|
||||||
var targetY = rect.top + rect.height / 2;
|
|
||||||
|
|
||||||
// 1. Cursor erscheint oben links im Modal, f\u00e4hrt zum Select
|
|
||||||
var startX = rect.left - 80;
|
|
||||||
var startY = rect.top - 60;
|
|
||||||
this._showCursor(startX, startY, 'default');
|
|
||||||
await this._wait(400);
|
|
||||||
await this._animateCursor(startX, startY, targetX, targetY, 800);
|
|
||||||
await this._wait(300);
|
await this._wait(300);
|
||||||
|
|
||||||
// 2. Klick - wechselt zu Recherche
|
// Wechsel zu Recherche
|
||||||
sel.value = 'research';
|
sel.value = 'research';
|
||||||
sel.dispatchEvent(new Event('change'));
|
sel.dispatchEvent(new Event('change'));
|
||||||
this._highlightSub('#inc-type');
|
|
||||||
await this._wait(2000);
|
await this._wait(2000);
|
||||||
|
|
||||||
// 3. Zur\u00fcck zu Live-Monitoring
|
// Zur\u00fcck zu Live-Monitoring
|
||||||
sel.value = 'adhoc';
|
sel.value = 'adhoc';
|
||||||
sel.dispatchEvent(new Event('change'));
|
sel.dispatchEvent(new Event('change'));
|
||||||
await this._wait(1000);
|
await this._wait(800);
|
||||||
|
|
||||||
// 4. Cursor verschwindet
|
|
||||||
this._hideCursor();
|
this._hideCursor();
|
||||||
this._demoRunning = false;
|
this._demoRunning = false;
|
||||||
this._enableNavAfterDemo();
|
this._enableNavAfterDemo();
|
||||||
},
|
},
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Drag-Demo
|
// Step 5: Quellen (International + Telegram toggles)
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
async _simulateDrag() {
|
async _simulateFormSources() {
|
||||||
this._demoRunning = true;
|
this._demoRunning = true;
|
||||||
var el = document.querySelector('[gs-id="lagebild"] .card-header');
|
this._scrollModalTo('#inc-international');
|
||||||
if (!el) { this._demoRunning = false; this._enableNavAfterDemo(); return; }
|
await this._wait(400);
|
||||||
|
|
||||||
var rect = el.getBoundingClientRect();
|
// International-Toggle highlighten
|
||||||
var startX = rect.left + rect.width / 2;
|
var intlCheckbox = document.getElementById('inc-international');
|
||||||
var startY = rect.top + rect.height / 2;
|
var intlLabel = intlCheckbox ? intlCheckbox.closest('.toggle-label') : null;
|
||||||
var endX = startX + 200;
|
if (intlLabel) {
|
||||||
var endY = startY;
|
this._highlightSub('#inc-international');
|
||||||
|
var pos = await this._cursorToElement('#inc-international');
|
||||||
|
await this._wait(1500);
|
||||||
|
this._clearSubHighlights();
|
||||||
|
|
||||||
this._showCursor(startX, startY, 'default');
|
// Telegram-Toggle
|
||||||
await this._wait(500);
|
var telegramCheckbox = document.getElementById('inc-telegram');
|
||||||
|
if (telegramCheckbox) {
|
||||||
this._els.cursor.classList.remove('tutorial-cursor-default');
|
this._highlightSub('#inc-telegram');
|
||||||
this._els.cursor.classList.add('tutorial-cursor-grabbing');
|
pos = await this._cursorToElement('#inc-telegram', pos.x, pos.y);
|
||||||
await this._wait(300);
|
// Aktivieren
|
||||||
|
telegramCheckbox.checked = true;
|
||||||
await this._animateCursor(startX, startY, endX, endY, 1500);
|
await this._wait(1500);
|
||||||
await this._wait(200);
|
this._clearSubHighlights();
|
||||||
|
}
|
||||||
this._els.cursor.classList.remove('tutorial-cursor-grabbing');
|
}
|
||||||
this._els.cursor.classList.add('tutorial-cursor-default');
|
|
||||||
await this._animateCursor(endX, endY, startX, startY, 800);
|
|
||||||
await this._wait(300);
|
|
||||||
|
|
||||||
this._hideCursor();
|
this._hideCursor();
|
||||||
this._demoRunning = false;
|
this._demoRunning = false;
|
||||||
@@ -1454,52 +1525,121 @@ const Tutorial = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Resize-Demo
|
// Step 6: Sichtbarkeit
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
async _simulateResize() {
|
async _simulateFormVisibility() {
|
||||||
this._demoRunning = true;
|
this._demoRunning = true;
|
||||||
var el = document.querySelector('[gs-id="faktencheck"]');
|
this._scrollModalTo('#inc-visibility');
|
||||||
if (!el) { this._demoRunning = false; this._enableNavAfterDemo(); return; }
|
await this._wait(400);
|
||||||
|
|
||||||
var rect = el.getBoundingClientRect();
|
var checkbox = document.getElementById('inc-visibility');
|
||||||
var startX = rect.right - 4;
|
if (checkbox) {
|
||||||
var startY = rect.bottom - 4;
|
this._highlightSub('#inc-visibility');
|
||||||
var endX = startX + 100;
|
var pos = await this._cursorToElement('#inc-visibility');
|
||||||
var endY = startY + 60;
|
await this._wait(1000);
|
||||||
|
|
||||||
this._showCursor(startX, startY, 'resize');
|
// Umschalten auf Privat
|
||||||
await this._wait(500);
|
checkbox.checked = false;
|
||||||
|
var textEl = document.getElementById('visibility-text');
|
||||||
|
if (textEl) textEl.textContent = 'Privat \u2014 nur f\u00fcr dich sichtbar';
|
||||||
|
await this._wait(1500);
|
||||||
|
|
||||||
await this._animateCursor(startX, startY, endX, endY, 1200);
|
// Zur\u00fcck auf \u00d6ffentlich
|
||||||
await this._wait(200);
|
checkbox.checked = true;
|
||||||
|
if (textEl) textEl.textContent = '\u00d6ffentlich \u2014 f\u00fcr alle Nutzer sichtbar';
|
||||||
await this._animateCursor(endX, endY, startX, startY, 800);
|
await this._wait(800);
|
||||||
await this._wait(300);
|
this._clearSubHighlights();
|
||||||
|
}
|
||||||
|
|
||||||
this._hideCursor();
|
this._hideCursor();
|
||||||
this._demoRunning = false;
|
this._demoRunning = false;
|
||||||
this._enableNavAfterDemo();
|
this._enableNavAfterDemo();
|
||||||
},
|
},
|
||||||
|
|
||||||
_enableNavAfterDemo() {
|
// -----------------------------------------------------------------------
|
||||||
var bubble = this._els.bubble;
|
// Step 7: Aktualisierung + Intervall
|
||||||
var nav = bubble.querySelector('.tutorial-bubble-nav');
|
// -----------------------------------------------------------------------
|
||||||
if (!nav) return;
|
async _simulateFormRefresh() {
|
||||||
var index = this._currentStep;
|
this._demoRunning = true;
|
||||||
var total = this._steps.length;
|
this._scrollModalTo('#inc-refresh-mode');
|
||||||
|
await this._wait(400);
|
||||||
|
|
||||||
var navHtml = '';
|
var refreshSelect = document.getElementById('inc-refresh-mode');
|
||||||
if (index > 0) {
|
if (refreshSelect) {
|
||||||
navHtml += '<button class="tutorial-btn tutorial-btn-back" onclick="Tutorial.prev()">Zurück</button>';
|
this._highlightSub('#inc-refresh-mode');
|
||||||
} else {
|
var pos = await this._cursorToElement('#inc-refresh-mode');
|
||||||
navHtml += '<span></span>';
|
await this._wait(800);
|
||||||
|
|
||||||
|
// Auf Auto wechseln
|
||||||
|
refreshSelect.value = 'auto';
|
||||||
|
try { refreshSelect.dispatchEvent(new Event('change')); } catch(e) {}
|
||||||
|
await this._wait(1000);
|
||||||
|
this._clearSubHighlights();
|
||||||
|
|
||||||
|
// Intervall-Feld highlighten
|
||||||
|
var intervalField = document.getElementById('refresh-interval-field');
|
||||||
|
var intervalInput = document.getElementById('inc-refresh-value');
|
||||||
|
if (intervalField && intervalInput) {
|
||||||
|
this._highlightSub('#inc-refresh-value');
|
||||||
|
pos = await this._cursorToElement('#inc-refresh-value', pos.x, pos.y);
|
||||||
|
await this._wait(1500);
|
||||||
|
this._clearSubHighlights();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (index < total - 1) {
|
|
||||||
navHtml += '<button class="tutorial-btn tutorial-btn-next" onclick="Tutorial.next()">Weiter</button>';
|
this._hideCursor();
|
||||||
} else {
|
this._demoRunning = false;
|
||||||
navHtml += '<button class="tutorial-btn tutorial-btn-next" onclick="Tutorial.stop()">Fertig</button>';
|
this._enableNavAfterDemo();
|
||||||
|
},
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Step 8: Aufbewahrung
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
async _simulateFormRetention() {
|
||||||
|
this._demoRunning = true;
|
||||||
|
this._scrollModalTo('#inc-retention');
|
||||||
|
await this._wait(400);
|
||||||
|
|
||||||
|
var retentionInput = document.getElementById('inc-retention');
|
||||||
|
if (retentionInput) {
|
||||||
|
this._highlightSub('#inc-retention');
|
||||||
|
var pos = await this._cursorToElement('#inc-retention');
|
||||||
|
await this._wait(2000);
|
||||||
|
this._clearSubHighlights();
|
||||||
}
|
}
|
||||||
nav.innerHTML = navHtml;
|
|
||||||
|
this._hideCursor();
|
||||||
|
this._demoRunning = false;
|
||||||
|
this._enableNavAfterDemo();
|
||||||
|
},
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Step 9: E-Mail-Benachrichtigungen
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
async _simulateFormNotifications() {
|
||||||
|
this._demoRunning = true;
|
||||||
|
this._scrollModalTo('#inc-notify-summary');
|
||||||
|
await this._wait(400);
|
||||||
|
|
||||||
|
var checks = ['#inc-notify-summary', '#inc-notify-new-articles', '#inc-notify-status-change'];
|
||||||
|
var pos;
|
||||||
|
for (var i = 0; i < checks.length; i++) {
|
||||||
|
var cb = document.querySelector(checks[i]);
|
||||||
|
if (!cb) continue;
|
||||||
|
this._highlightSub(checks[i]);
|
||||||
|
if (pos) {
|
||||||
|
pos = await this._cursorToElement(checks[i], pos.x, pos.y);
|
||||||
|
} else {
|
||||||
|
pos = await this._cursorToElement(checks[i]);
|
||||||
|
}
|
||||||
|
cb.checked = true;
|
||||||
|
await this._wait(1000);
|
||||||
|
this._clearSubHighlights();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._hideCursor();
|
||||||
|
this._demoRunning = false;
|
||||||
|
this._enableNavAfterDemo();
|
||||||
},
|
},
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren