Fix: Abbrechen-Dialog, Overlay-Stacking, Queue-Cancel
1. Confirm-Dialog z-index ueber Progress-Popup (10000 > 9000) 2. Progress-Popup wird ausgeblendet waehrend Confirm-Dialog offen 3. Kein dunkler-werdendes Overlay bei mehrfachem Abbrechen-Klick 4. Abbrechen funktioniert jetzt auch fuer Lagen in der Warteschlange (werden direkt aus der Queue entfernt statt auf Start zu warten) 5. Cancel-Status wird im Popup-Titel angezeigt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -437,22 +437,59 @@ class AgentOrchestrator:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
async def cancel_refresh(self, incident_id: int) -> bool:
|
async def cancel_refresh(self, incident_id: int) -> bool:
|
||||||
"""Fordert Abbruch eines laufenden Refreshes an."""
|
"""Fordert Abbruch eines laufenden oder wartenden Refreshes an."""
|
||||||
if self._current_task != incident_id:
|
# Check if it's the currently running task
|
||||||
return False
|
if self._current_task == incident_id:
|
||||||
self._cancel_requested.add(incident_id)
|
self._cancel_requested.add(incident_id)
|
||||||
logger.info(f"Cancel angefordert fuer Lage {incident_id}")
|
logger.info(f"Cancel angefordert fuer laufende Lage {incident_id}")
|
||||||
if self._ws_manager:
|
if self._ws_manager:
|
||||||
try:
|
try:
|
||||||
vis, cb, tid = await self._get_incident_visibility(incident_id)
|
vis, cb, tid = await self._get_incident_visibility(incident_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
vis, cb, tid = "public", None, None
|
vis, cb, tid = "public", None, None
|
||||||
await self._ws_manager.broadcast_for_incident({
|
await self._ws_manager.broadcast_for_incident({
|
||||||
"type": "status_update",
|
"type": "status_update",
|
||||||
"incident_id": incident_id,
|
"incident_id": incident_id,
|
||||||
"data": {"status": "cancelling", "detail": "Wird abgebrochen..."},
|
"data": {"status": "cancelling", "detail": "Wird abgebrochen..."},
|
||||||
}, vis, cb, tid)
|
}, vis, cb, tid)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# Check if it's in the queue (not yet started)
|
||||||
|
if incident_id in self._queued_ids:
|
||||||
|
self._queued_ids.discard(incident_id)
|
||||||
|
# Remove from asyncio queue (rebuild without this ID)
|
||||||
|
removed = False
|
||||||
|
new_items = []
|
||||||
|
while not self._queue.empty():
|
||||||
|
try:
|
||||||
|
item = self._queue.get_nowait()
|
||||||
|
iid = item[0] if isinstance(item, tuple) else item
|
||||||
|
if iid == incident_id:
|
||||||
|
removed = True
|
||||||
|
self._queue.task_done()
|
||||||
|
else:
|
||||||
|
new_items.append(item)
|
||||||
|
except Exception:
|
||||||
|
break
|
||||||
|
for item in new_items:
|
||||||
|
self._queue.put_nowait(item)
|
||||||
|
|
||||||
|
logger.info(f"Lage {incident_id} aus Warteschlange entfernt (removed={removed})")
|
||||||
|
|
||||||
|
# Send cancelled event
|
||||||
|
if self._ws_manager:
|
||||||
|
try:
|
||||||
|
vis, cb, tid = await self._get_incident_visibility(incident_id)
|
||||||
|
except Exception:
|
||||||
|
vis, cb, tid = "public", None, None
|
||||||
|
await self._ws_manager.broadcast_for_incident({
|
||||||
|
"type": "refresh_cancelled",
|
||||||
|
"incident_id": incident_id,
|
||||||
|
"data": {"status": "cancelled"},
|
||||||
|
}, vis, cb, tid)
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def _check_cancelled(self, incident_id: int):
|
def _check_cancelled(self, incident_id: int):
|
||||||
"""Prüft ob Abbruch angefordert wurde und wirft CancelledError."""
|
"""Prüft ob Abbruch angefordert wurde und wirft CancelledError."""
|
||||||
|
|||||||
@@ -1710,7 +1710,7 @@ a:hover {
|
|||||||
inset: 0;
|
inset: 0;
|
||||||
background: var(--backdrop);
|
background: var(--backdrop);
|
||||||
backdrop-filter: blur(4px);
|
backdrop-filter: blur(4px);
|
||||||
z-index: 100;
|
z-index: 10000;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2224,23 +2224,41 @@ async handleRefresh() {
|
|||||||
|
|
||||||
async cancelRefresh() {
|
async cancelRefresh() {
|
||||||
if (!this.currentIncidentId) return;
|
if (!this.currentIncidentId) return;
|
||||||
const ok = await confirmDialog('Laufende Recherche abbrechen?');
|
|
||||||
if (!ok) return;
|
|
||||||
|
|
||||||
|
// Temporarily hide progress popup so confirm dialog is fully visible
|
||||||
|
const progressOverlay = document.getElementById('progress-overlay');
|
||||||
|
if (progressOverlay) progressOverlay.style.display = 'none';
|
||||||
|
|
||||||
|
const ok = await confirmDialog('Laufende Recherche abbrechen?');
|
||||||
|
|
||||||
|
// Restore progress popup if not confirmed
|
||||||
|
if (!ok) {
|
||||||
|
const state = UI._progressState[this.currentIncidentId];
|
||||||
|
if (state && progressOverlay) progressOverlay.style.display = 'flex';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show cancelling state in popup
|
||||||
|
if (progressOverlay) progressOverlay.style.display = 'flex';
|
||||||
const btn = document.getElementById('progress-cancel-btn');
|
const btn = document.getElementById('progress-cancel-btn');
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.textContent = 'Wird abgebrochen...';
|
btn.textContent = 'Wird abgebrochen...';
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
}
|
}
|
||||||
|
const titleEl = document.getElementById('progress-popup-title');
|
||||||
|
if (titleEl) titleEl.textContent = 'Wird abgebrochen...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await API.cancelRefresh(this.currentIncidentId);
|
const result = await API.cancelRefresh(this.currentIncidentId);
|
||||||
|
if (!result) {
|
||||||
|
UI.showToast('Kein aktiver Refresh zum Abbrechen gefunden.', 'info');
|
||||||
|
if (btn) { btn.textContent = 'Abbrechen'; btn.disabled = false; }
|
||||||
|
if (titleEl) titleEl.textContent = 'Aktualisierung l\u00e4uft';
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
UI.showToast('Abbrechen fehlgeschlagen: ' + err.message, 'error');
|
UI.showToast('Abbrechen fehlgeschlagen: ' + err.message, 'error');
|
||||||
if (btn) {
|
if (btn) { btn.textContent = 'Abbrechen'; btn.disabled = false; }
|
||||||
btn.textContent = 'Abbrechen';
|
if (titleEl) titleEl.textContent = 'Aktualisierung l\u00e4uft';
|
||||||
btn.disabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren