Batch-Analyse UI: Button im Prüfen-Tab mit BL-Auswahl + Limit + Queue-Polling
This commit is contained in:
parent
cfe36cbd65
commit
5f5d9edf83
@ -889,6 +889,33 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="analysis-result" style="display: none; margin-top: 1rem;"></div>
|
<div id="analysis-result" style="display: none; margin-top: 1rem;"></div>
|
||||||
|
|
||||||
|
<!-- Batch-Analyse -->
|
||||||
|
<div style="margin-top: 2rem; padding-top: 1.5rem; border-top: 2px solid var(--color-lightgray);">
|
||||||
|
<h2 style="margin-bottom: 0.5rem; color: var(--color-blue);">📦 Batch-Analyse</h2>
|
||||||
|
<p style="font-size: 0.85rem; color: #666; margin-bottom: 1rem;">
|
||||||
|
Analysiert automatisch die neuesten ungeprüften Anträge eines Bundeslandes.
|
||||||
|
</p>
|
||||||
|
<div style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap;">
|
||||||
|
<select id="batch-bundesland" style="padding:0.4rem;border:1px solid #ddd;border-radius:4px;">
|
||||||
|
{% for bl in bundeslaender if bl.code != 'ALL' and bl.active %}
|
||||||
|
<option value="{{ bl.code }}">{{ bl.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<select id="batch-limit" style="padding:0.4rem;border:1px solid #ddd;border-radius:4px;">
|
||||||
|
<option value="5">5 Anträge</option>
|
||||||
|
<option value="10" selected>10 Anträge</option>
|
||||||
|
<option value="20">20 Anträge</option>
|
||||||
|
<option value="50">50 Anträge</option>
|
||||||
|
</select>
|
||||||
|
<button id="batch-btn" onclick="startBatch()"
|
||||||
|
${currentUser ? '' : 'disabled title="Nur nach Anmeldung"'}
|
||||||
|
style="padding:0.4rem 1rem;background:var(--color-green);color:white;border:none;border-radius:4px;cursor:pointer;">
|
||||||
|
🚀 Batch starten
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="batch-status" style="margin-top:0.75rem;font-size:0.85rem;"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1318,6 +1345,64 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Batch-Analyse ──────────────────────────────────────────
|
||||||
|
async function startBatch() {
|
||||||
|
const bl = document.getElementById('batch-bundesland').value;
|
||||||
|
const limit = document.getElementById('batch-limit').value;
|
||||||
|
const btn = document.getElementById('batch-btn');
|
||||||
|
const status = document.getElementById('batch-status');
|
||||||
|
|
||||||
|
btn.disabled = true;
|
||||||
|
btn.textContent = '⏳ Wird gestartet...';
|
||||||
|
status.innerHTML = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp = await fetch('/api/batch-analyze', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||||
|
body: `bundesland=${bl}&limit=${limit}`
|
||||||
|
});
|
||||||
|
if (resp.status === 401) {
|
||||||
|
status.innerHTML = '<span style="color:#dc3545;">🔒 Bitte zuerst anmelden.</span>';
|
||||||
|
btn.disabled = false; btn.textContent = '🚀 Batch starten';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const data = await resp.json();
|
||||||
|
if (data.status === 'batch_enqueued') {
|
||||||
|
status.innerHTML = `
|
||||||
|
<span style="color:var(--color-green);">✓ ${data.enqueued} Anträge in die Queue eingereiht</span>
|
||||||
|
${data.skipped_existing > 0 ? `<br><span style="color:#888;">${data.skipped_existing} bereits bewertet (übersprungen)</span>` : ''}
|
||||||
|
<br><span style="color:#888;">Die Analyse läuft im Hintergrund. Ergebnisse erscheinen nach und nach in der Liste.</span>
|
||||||
|
`;
|
||||||
|
// Queue-Status pollen
|
||||||
|
pollBatchQueue(status);
|
||||||
|
} else {
|
||||||
|
status.innerHTML = `<span style="color:#dc3545;">❌ ${data.detail || 'Fehler'}</span>`;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
status.innerHTML = `<span style="color:#dc3545;">❌ ${e.message}</span>`;
|
||||||
|
}
|
||||||
|
btn.disabled = false; btn.textContent = '🚀 Batch starten';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pollBatchQueue(statusEl) {
|
||||||
|
for (let i = 0; i < 200; i++) {
|
||||||
|
await new Promise(r => setTimeout(r, 5000));
|
||||||
|
try {
|
||||||
|
const qs = await fetch('/api/queue/status').then(r => r.json());
|
||||||
|
if (qs.pending === 0) {
|
||||||
|
statusEl.innerHTML += `<br><span style="color:var(--color-green);">✓ Alle Jobs abgeschlossen (${qs.processed_total} verarbeitet)</span>`;
|
||||||
|
loadAssessments(); // Liste aktualisieren
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
statusEl.querySelector('.queue-progress')?.remove();
|
||||||
|
statusEl.insertAdjacentHTML('beforeend',
|
||||||
|
`<span class="queue-progress"><br>⏳ ${qs.pending} Jobs in der Queue, ~${Math.round(qs.estimated_wait_seconds/60)} Min. verbleibend</span>`
|
||||||
|
);
|
||||||
|
} catch { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Merkliste (#94) ────────────────────────────────────────
|
// ─── Merkliste (#94) ────────────────────────────────────────
|
||||||
async function loadBookmarksList() {
|
async function loadBookmarksList() {
|
||||||
const container = document.getElementById('bookmarks-content');
|
const container = document.getElementById('bookmarks-content');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user