diff --git a/src/agents/orchestrator.py b/src/agents/orchestrator.py index cc968e1..b9839e1 100644 --- a/src/agents/orchestrator.py +++ b/src/agents/orchestrator.py @@ -1167,6 +1167,9 @@ class AgentOrchestrator: # Cancel-Check nach paralleler Verarbeitung self._check_cancelled(incident_id) + # Cancel-Check nach Analyse+Faktencheck + self._check_cancelled(incident_id) + # --- Faktencheck-Ergebnisse verarbeiten --- # Pre-Dedup: Duplikate aus LLM-Antwort entfernen fact_checks = deduplicate_new_facts(fact_checks) diff --git a/src/static/css/style.css b/src/static/css/style.css index 0d4469c..60db7d7 100644 --- a/src/static/css/style.css +++ b/src/static/css/style.css @@ -1900,141 +1900,218 @@ a:hover { } /* === Fortschrittsanzeige === */ -.progress-bar { +/* === Fortschritts-Popup === */ +.progress-overlay { + position: fixed; + inset: 0; + z-index: 9000; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; +} +.progress-overlay.blocking { + pointer-events: auto; + background: rgba(0,0,0,0.15); +} +.progress-popup { + pointer-events: auto; + background: var(--bg-primary); + border: 1px solid var(--border); + border-radius: 12px; + width: 420px; + max-width: 92vw; + box-shadow: 0 16px 48px rgba(0,0,0,0.5); + overflow: hidden; + animation: popupIn 0.25s ease-out; +} +@keyframes popupIn { + from { opacity: 0; transform: scale(0.95) translateY(10px); } + to { opacity: 1; transform: scale(1) translateY(0); } +} +.progress-popup-header { + display: flex; + align-items: center; + gap: 8px; + padding: 16px 20px 12px; + border-bottom: 1px solid var(--border); +} +.progress-popup-title { + font-size: 14px; + font-weight: 600; + color: var(--text-primary); + flex: 1; +} +.progress-popup-timer { + font-family: var(--font-mono, 'Courier New', monospace); + font-size: 13px; + color: var(--accent); + font-weight: 600; + min-width: 42px; + text-align: right; +} +.progress-popup-minimize { + background: none; + border: 1px solid var(--border); + color: var(--text-secondary); + width: 28px; + height: 28px; + border-radius: 6px; + cursor: pointer; + font-size: 18px; + line-height: 1; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.15s; +} +.progress-popup-minimize:hover { + background: var(--bg-secondary); + color: var(--text-primary); +} +.progress-popup-body { padding: 16px 20px; } +.progress-popup-pass { + font-size: 11px; + color: var(--accent-primary); + font-weight: 600; + letter-spacing: 0.3px; + margin-bottom: 12px; + text-align: center; +} +.progress-checklist { display: flex; flex-direction: column; gap: 6px; } +.progress-check-item { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 10px; + border-radius: 6px; + transition: background 0.2s; +} +.progress-check-item.active { background: rgba(240,180,41,0.08); } +.progress-check-item.done { opacity: 0.55; } +.progress-check-icon { + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + color: var(--text-disabled); + flex-shrink: 0; +} +.progress-check-item.active .progress-check-icon { color: var(--accent); } +.progress-check-item.done .progress-check-icon { color: var(--success); } +.progress-check-item.error .progress-check-icon { color: var(--error); } +.progress-check-icon .spinner { + width: 16px; height: 16px; + border: 2px solid var(--border); + border-top-color: var(--accent); + border-radius: 50%; + animation: spin 0.8s linear infinite; +} +@keyframes spin { to { transform: rotate(360deg); } } +.progress-check-label { font-size: 13px; color: var(--text-secondary); flex: 1; } +.progress-check-item.active .progress-check-label { color: var(--text-primary); font-weight: 500; } +.progress-check-detail { font-size: 11px; color: var(--text-disabled); } +.progress-complete-summary { + margin-top: 12px; + padding: 12px; + background: rgba(34,197,94,0.08); + border-radius: 6px; + font-size: 13px; + color: var(--success); + line-height: 1.5; +} +.progress-complete-summary .total-time { + display: block; margin-top: 6px; + font-family: var(--font-mono, 'Courier New', monospace); + font-size: 12px; color: var(--text-secondary); +} +.progress-popup-footer { + padding: 10px 20px 16px; + display: flex; justify-content: center; +} +.progress-cancel-btn { + background: none; border: none; + color: var(--text-disabled); font-size: 12px; + cursor: pointer; text-decoration: underline; + padding: 4px 8px; transition: color 0.2s; +} +.progress-cancel-btn:hover { color: var(--error); } + +/* === Mini Progress Bar === */ +.progress-mini { background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius); - padding: var(--sp-xl); + padding: 10px 16px; margin-bottom: var(--sp-xl); - position: relative; + display: flex; align-items: center; gap: 10px; + cursor: pointer; + transition: border-color 0.2s, background 0.2s; } - -.progress-steps { - display: flex; - justify-content: space-between; - margin-bottom: var(--sp-lg); -} - -.progress-step { - display: flex; - align-items: center; - gap: var(--sp-md); - font-size: 12px; - color: var(--text-disabled); - transition: color 0.3s ease; -} - -.progress-step.active { - color: var(--accent); - font-weight: 600; -} - -.progress-step.done { - color: var(--success); -} - -.progress-step-dot { - width: 10px; - height: 10px; - border-radius: 50%; - background: var(--text-disabled); - transition: all 0.3s ease; +.progress-mini:hover { border-color: var(--accent); background: var(--bg-secondary); } +.progress-mini-dot { + width: 8px; height: 8px; border-radius: 50%; + background: var(--accent); + animation: pulse 1.5s ease-in-out infinite; flex-shrink: 0; } - -.progress-step.active .progress-step-dot { - background: var(--accent); - box-shadow: var(--glow-accent); - animation: pulse 1.5s ease-in-out infinite; +.progress-mini-text { font-size: 12px; color: var(--text-secondary); flex: 1; } +.progress-mini-timer { + font-family: var(--font-mono, 'Courier New', monospace); + font-size: 12px; color: var(--accent); font-weight: 600; } -.progress-step.done .progress-step-dot { - background: var(--success); +/* === Blur for First Refresh === */ +.grid-stack.blurred .grid-stack-item-content { + filter: blur(8px); + pointer-events: none; + user-select: none; + transition: filter 0.4s ease; } -.progress-track { - height: 4px; - background: var(--bg-secondary); - border-radius: 2px; - overflow: hidden; - margin-bottom: var(--sp-md); -} - -.progress-fill { - height: 100%; - background: linear-gradient(90deg, var(--accent), var(--success)); - border-radius: 2px; - transition: width 0.5s ease-out; - width: 0%; -} - -.progress-label-container { - display: flex; - justify-content: center; - align-items: center; - gap: var(--sp-md); +/* === Sidebar Refreshing Indicator === */ +.incident-item.refreshing-item { + border: 1px solid transparent; + background-size: 300% 300%; + animation: sidebarRefreshBorder 3s ease infinite; + border-image: linear-gradient(135deg, var(--accent), transparent, var(--accent)) 1; + border-radius: var(--radius); position: relative; } - -.progress-label { - font-size: 12px; - color: var(--text-secondary); -} - -.progress-timer { - font-family: var(--font-mono, 'Courier New', monospace); - color: var(--text-disabled); - font-size: 12px; -} - -.progress-pass-info { - font-size: 11px; - color: var(--accent-primary); - margin-left: 8px; - font-weight: 600; - letter-spacing: 0.3px; -} - -.progress-cancel-btn { +.incident-item.refreshing-item::after { + content: ''; position: absolute; - right: var(--sp-xl); - bottom: var(--sp-lg); - background: none; - border: none; - color: var(--text-disabled); - font-size: 11px; - cursor: pointer; - text-decoration: underline; - padding: 2px 4px; - transition: color 0.2s ease; + inset: -1px; + border-radius: var(--radius); + border: 1px solid var(--accent); + opacity: 0.3; + animation: sidebarGlow 2s ease-in-out infinite; + pointer-events: none; } - -.progress-cancel-btn:hover { - color: var(--error); +@keyframes sidebarGlow { + 0%, 100% { opacity: 0.15; box-shadow: 0 0 4px var(--accent); } + 50% { opacity: 0.4; box-shadow: 0 0 12px var(--accent); } } - -.progress-bar--complete .progress-cancel-btn, -.progress-bar--error .progress-cancel-btn { - display: none; +.incident-refresh-status { + font-size: 10px; + color: var(--accent); + margin-top: 2px; + display: flex; + align-items: center; + gap: 4px; + animation: fadeIn 0.3s ease; } - -.progress-bar--complete .progress-fill { - background: linear-gradient(90deg, var(--success), #34D399); - width: 100% !important; -} - -.progress-bar--complete .progress-label { - color: var(--success); - font-weight: 600; -} - -.progress-bar--error .progress-fill { - background: linear-gradient(90deg, var(--error), #F87171); -} - -.progress-bar--error .progress-label { - color: var(--error); +.incident-refresh-status .mini-spinner { + width: 10px; height: 10px; + border: 1.5px solid var(--border); + border-top-color: var(--accent); + border-radius: 50%; + animation: spin 0.8s linear infinite; + flex-shrink: 0; } +@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } /* === Briefing === */ .briefing-content { diff --git a/src/static/dashboard.html b/src/static/dashboard.html index 3b246a6..8d6af31 100644 --- a/src/static/dashboard.html +++ b/src/static/dashboard.html @@ -183,31 +183,11 @@ - -
+ + + +