feat: Beschreibung generieren Button im Neuer-Fall-Modal
KI-gestütztes Prompt Enhancement: Button generiert per Haiku aus dem Titel eine strukturierte Beschreibung. Unterscheidet zwischen Live-Monitoring (kompakte Vorfallsbeschreibung) und Recherche (strukturiertes Briefing mit Schwerpunkten und Suchbegriffen). - Neuer Endpoint POST /api/incidents/enhance-description - Button erscheint für beide Lage-Typen, aktiv ab 3 Zeichen Titel - Info-Hinweis wechselt je nach Typ mit Beispiel - Spinner-Animation während der Generierung
Dieser Commit ist enthalten in:
@@ -2076,6 +2076,26 @@ a:hover {
|
||||
margin-top: var(--sp-xs);
|
||||
}
|
||||
|
||||
.description-enhance-row {
|
||||
margin-top: var(--sp-md);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.spinner-inline {
|
||||
display: inline-block;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border: 2px solid var(--border);
|
||||
border-top-color: var(--accent-primary);
|
||||
border-radius: 50%;
|
||||
animation: spin-inline 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin-inline {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* === Inline-Zitate === */
|
||||
.citation {
|
||||
color: var(--accent);
|
||||
|
||||
@@ -335,6 +335,13 @@
|
||||
<div class="form-group">
|
||||
<label for="inc-description">Beschreibung / Kontext</label>
|
||||
<textarea id="inc-description" placeholder="Weitere Details zum Vorfall (optional)"></textarea>
|
||||
<div class="description-enhance-row">
|
||||
<button type="button" class="btn btn-secondary btn-small" id="btn-enhance-description" onclick="App.generateDescription()" disabled>
|
||||
<span id="enhance-btn-text">✦ Beschreibung generieren</span>
|
||||
<span id="enhance-spinner" class="spinner-inline" style="display:none;"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="form-hint" id="description-hint">Beschreibe den Vorfall möglichst genau: Was ist passiert? Wo? Wer ist beteiligt? Je präziser, desto bessere Ergebnisse.</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inc-type">Art der Lage</label>
|
||||
|
||||
@@ -70,6 +70,10 @@ const API = {
|
||||
return this._request('GET', `/incidents${query}`);
|
||||
},
|
||||
|
||||
enhanceDescription(title, description, type) {
|
||||
return this._request('POST', '/incidents/enhance-description', { title, description, type });
|
||||
},
|
||||
|
||||
createIncident(data) {
|
||||
return this._request('POST', '/incidents', data);
|
||||
},
|
||||
|
||||
@@ -1610,6 +1610,31 @@ const App = {
|
||||
}
|
||||
},
|
||||
|
||||
async generateDescription() {
|
||||
const title = document.getElementById('inc-title').value.trim();
|
||||
const description = document.getElementById('inc-description').value.trim();
|
||||
const type = document.getElementById('inc-type').value;
|
||||
const btn = document.getElementById('btn-enhance-description');
|
||||
const btnText = document.getElementById('enhance-btn-text');
|
||||
const spinner = document.getElementById('enhance-spinner');
|
||||
|
||||
if (title.length < 3 || !btn) return;
|
||||
btn.disabled = true;
|
||||
btnText.style.display = 'none';
|
||||
spinner.style.display = '';
|
||||
|
||||
try {
|
||||
const result = await API.enhanceDescription(title, description || null, type);
|
||||
document.getElementById('inc-description').value = result.description;
|
||||
} catch (err) {
|
||||
UI.showToast('Beschreibung konnte nicht generiert werden', 'error');
|
||||
} finally {
|
||||
btnText.style.display = '';
|
||||
spinner.style.display = 'none';
|
||||
btn.disabled = title.length < 3;
|
||||
}
|
||||
},
|
||||
|
||||
async handleRefresh() {
|
||||
if (!this.currentIncidentId) return;
|
||||
if (this._refreshingIncidents.has(this.currentIncidentId)) {
|
||||
@@ -3214,6 +3239,14 @@ function toggleTypeDefaults() {
|
||||
} else {
|
||||
hint.textContent = 'Durchsucht laufend hunderte Nachrichtenquellen nach neuen Meldungen. Empfohlen: Automatische Aktualisierung.';
|
||||
}
|
||||
|
||||
// Beschreibungs-Hinweis je nach Typ wechseln
|
||||
const descHint = document.getElementById('description-hint');
|
||||
if (descHint) {
|
||||
descHint.textContent = type === 'research'
|
||||
? 'Nenne das vollständige Thema, gewünschte Schwerpunkte und relevante URLs. Beispiel: "Muster GmbH \u2014 Fokus auf Führungspersonen, Kontroversen, Finanzkennzahlen"'
|
||||
: 'Beschreibe den Vorfall möglichst genau: Was ist passiert? Wo? Wer ist beteiligt? Je präziser, desto bessere Ergebnisse.';
|
||||
}
|
||||
}
|
||||
|
||||
// Tab-Fokus: Nur Tab-Badge (Titel-Counter) zurücksetzen, nicht alle Notifications
|
||||
@@ -3294,3 +3327,15 @@ document.addEventListener('click', (e) => {
|
||||
|
||||
});
|
||||
document.addEventListener('DOMContentLoaded', () => App.init());
|
||||
|
||||
|
||||
// Titel-Input: Button "Beschreibung generieren" aktivieren/deaktivieren
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const titleInput = document.getElementById('inc-title');
|
||||
if (titleInput) {
|
||||
titleInput.addEventListener('input', function() {
|
||||
const btn = document.getElementById('btn-enhance-description');
|
||||
if (btn) btn.disabled = this.value.trim().length < 3;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren