UI-Polish: 6 Fixes aus visuellem Review

1. AfD/AFD Duplikat in Partei-Stats: normalizePartei() client-seitig
2. Antragsteller:in Labels: aus item.fraktionen ableiten wenn
   istAntragsteller null (LLM liefert es inconsistent)
3. Überlange Titel in Liste: auf 80 Zeichen + Ellipsis gekürzt
4. Methodik-Text: "verworfen" → "verifiziert / nicht wörtlich markiert"
5. Bewertungsdatum im Header (neben Drucksache-Nr statt nur im Footer)
6. Index-Button: Schloss-Icon + Tooltip "Erfordert Anmeldung"
This commit is contained in:
Dotty Dotter 2026-04-10 22:13:30 +02:00
parent f1a7da8544
commit b851173e6d
3 changed files with 23 additions and 11 deletions

View File

@ -1109,14 +1109,22 @@
blContainer.innerHTML = '';
}
// Partei-Durchschnitte berechnen
// Partei-Durchschnitte berechnen (mit Normalisierung für AfD/AFD etc.)
const normalizePartei = (f) => {
const u = f.toUpperCase();
if (u === 'AFD') return 'AfD';
if (u === 'GRÜNE' || u === 'GRUENE' || u === 'BÜNDNIS 90/DIE GRÜNEN') return 'GRÜNE';
if (u === 'DIE LINKE') return 'LINKE';
return f;
};
const parteiStats = {};
allAssessments.forEach(a => {
if (a.gwoeScore == null) return;
(a.fraktionen || []).forEach(f => {
if (!parteiStats[f]) parteiStats[f] = { sum: 0, count: 0 };
parteiStats[f].sum += a.gwoeScore;
parteiStats[f].count += 1;
const norm = normalizePartei(f);
if (!parteiStats[norm]) parteiStats[norm] = { sum: 0, count: 0 };
parteiStats[norm].sum += a.gwoeScore;
parteiStats[norm].count += 1;
});
});
@ -1159,7 +1167,7 @@
<span class="list-item-id">${blBadge}${item.drucksache}</span>
<span class="list-item-score ${scoreClass}">${scoreText}</span>
</div>
<div class="list-item-title">${item.title || 'Ohne Titel'}</div>
<div class="list-item-title">${(item.title || 'Ohne Titel').length > 80 ? (item.title.substring(0, 80) + '…') : (item.title || 'Ohne Titel')}</div>
<div class="list-item-meta">${fraktionen} · ${item.datum || ''}</div>
${isUnchecked ? `
<button class="btn-check-now"
@ -1650,9 +1658,11 @@
</div>
` : '';
// Labels: Antragsteller:in und Landesregierung
// Labels: Antragsteller:in (aus item.fraktionen) und Landesregierung
// istAntragsteller/istRegierung aus dem LLM ist oft null — ableiten.
const isAntragsteller = (item.fraktionen || []).some(f => normalizePartei(f) === normalizePartei(wp.fraktion));
const roleLabels = [];
if (wp.istAntragsteller) roleLabels.push('<span style="background:#889e33;color:white;padding:0.1rem 0.4rem;border-radius:3px;font-size:0.75rem;">Antragsteller:in</span>');
if (wp.istAntragsteller || isAntragsteller) roleLabels.push('<span style="background:#889e33;color:white;padding:0.1rem 0.4rem;border-radius:3px;font-size:0.75rem;">Antragsteller:in</span>');
if (wp.istRegierung) roleLabels.push('<span style="background:#009da5;color:white;padding:0.1rem 0.4rem;border-radius:3px;font-size:0.75rem;">Landesregierung</span>');
return `
@ -1675,7 +1685,7 @@
<div>
<div class="detail-title">${item.title || 'Ohne Titel'}</div>
${item.bundesland && PARLAMENT_NAMES[item.bundesland] ? `<div class="detail-parlament">${PARLAMENT_NAMES[item.bundesland]}</div>` : ''}
<div class="detail-id">${item.drucksache} · ${(item.fraktionen || []).join(', ')} · ${item.datum || ''}</div>
<div class="detail-id">${item.drucksache} · ${(item.fraktionen || []).join(', ')} · ${item.datum || ''}${item.updatedAt ? ` · Bewertet ${new Date(item.updatedAt).toLocaleDateString('de-DE')}` : ''}</div>
</div>
<div class="score-display">
<div class="score-big ${scoreClass}">${item.gwoeScore}</div>

View File

@ -134,7 +134,9 @@
<p style="margin-top: 0.5rem;">
Alle Bewertungen werden durch ein KI-Sprachmodell erzeugt und anschließend
<strong>automatisch verifiziert</strong> — Zitate werden gegen die Originaltexte
der Wahlprogramme geprüft, nicht-verifizierbare Zitate werden verworfen.
der Wahlprogramme geprüft. Wörtliche Treffer werden als <em>verifiziert</em>
markiert, paraphrasierte Stellen als <em>nicht wörtlich im Programm</em>
gekennzeichnet.
</p>
</div>

View File

@ -211,8 +211,8 @@
</div>
</div>
<div style="margin-top: 1rem;">
<button class="btn btn-primary" onclick="indexAll()">
🔄 Alle Programme indexieren
<button class="btn btn-primary" onclick="indexAll()" title="Erfordert Anmeldung">
🔒 Alle Programme indexieren
</button>
<span id="index-status" style="margin-left: 1rem; color: #888;"></span>
</div>