fix: Beschreibung generieren — AbortController, Readonly, Gold-Styling
- Textarea readonly + visuell gedimmt während Generierung läuft - AbortController bricht Request ab wenn Modal geschlossen wird - Stern-Icon entfernt, Button-Text in Gold (Akzentfarbe) - api.js _request() unterstützt externen AbortSignal
Dieser Commit ist enthalten in:
@@ -2082,6 +2082,22 @@ a:hover {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#btn-enhance-description {
|
||||
color: var(--accent-primary);
|
||||
border-color: var(--accent-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#btn-enhance-description:hover:not(:disabled) {
|
||||
background: var(--accent-primary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.textarea--loading {
|
||||
opacity: 0.5;
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
.spinner-inline {
|
||||
display: inline-block;
|
||||
width: 14px;
|
||||
|
||||
@@ -337,7 +337,7 @@
|
||||
<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-btn-text">Beschreibung generieren</span>
|
||||
<span id="enhance-spinner" class="spinner-inline" style="display:none;"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -12,10 +12,15 @@ const API = {
|
||||
};
|
||||
},
|
||||
|
||||
async _request(method, path, body = null) {
|
||||
async _request(method, path, body = null, externalSignal = null) {
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 30000);
|
||||
|
||||
// Externen Abort weiterleiten an internen Controller
|
||||
if (externalSignal) {
|
||||
externalSignal.addEventListener('abort', () => controller.abort(), { once: true });
|
||||
}
|
||||
|
||||
const options = {
|
||||
method,
|
||||
headers: this._getHeaders(),
|
||||
@@ -70,8 +75,8 @@ const API = {
|
||||
return this._request('GET', `/incidents${query}`);
|
||||
},
|
||||
|
||||
enhanceDescription(title, description, type) {
|
||||
return this._request('POST', '/incidents/enhance-description', { title, description, type });
|
||||
enhanceDescription(title, description, type, signal = null) {
|
||||
return this._request('POST', '/incidents/enhance-description', { title, description, type }, signal);
|
||||
},
|
||||
|
||||
createIncident(data) {
|
||||
|
||||
@@ -1617,21 +1617,34 @@ async generateDescription() {
|
||||
const btn = document.getElementById('btn-enhance-description');
|
||||
const btnText = document.getElementById('enhance-btn-text');
|
||||
const spinner = document.getElementById('enhance-spinner');
|
||||
const textarea = document.getElementById('inc-description');
|
||||
|
||||
if (title.length < 3 || !btn) return;
|
||||
|
||||
// Vorherigen Request abbrechen falls noch aktiv
|
||||
if (this._enhanceController) this._enhanceController.abort();
|
||||
this._enhanceController = new AbortController();
|
||||
|
||||
btn.disabled = true;
|
||||
btnText.style.display = 'none';
|
||||
spinner.style.display = '';
|
||||
textarea.readOnly = true;
|
||||
textarea.classList.add('textarea--loading');
|
||||
|
||||
try {
|
||||
const result = await API.enhanceDescription(title, description || null, type);
|
||||
document.getElementById('inc-description').value = result.description;
|
||||
const result = await API.enhanceDescription(title, description || null, type, this._enhanceController.signal);
|
||||
textarea.value = result.description;
|
||||
} catch (err) {
|
||||
if (err.name !== 'AbortError') {
|
||||
UI.showToast('Beschreibung konnte nicht generiert werden', 'error');
|
||||
}
|
||||
} finally {
|
||||
btnText.style.display = '';
|
||||
spinner.style.display = 'none';
|
||||
btn.disabled = title.length < 3;
|
||||
textarea.readOnly = false;
|
||||
textarea.classList.remove('textarea--loading');
|
||||
this._enhanceController = null;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -3029,6 +3042,13 @@ function openModal(id) {
|
||||
}
|
||||
|
||||
function closeModal(id) {
|
||||
// Laufenden Beschreibung-generieren-Request abbrechen
|
||||
if (id === 'modal-new' && App._enhanceController) {
|
||||
App._enhanceController.abort();
|
||||
App._enhanceController = null;
|
||||
const ta = document.getElementById('inc-description');
|
||||
if (ta) { ta.readOnly = false; ta.classList.remove('textarea--loading'); }
|
||||
}
|
||||
const modal = document.getElementById(id);
|
||||
releaseFocus(modal);
|
||||
modal.classList.remove('active');
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren