feat(sources): Review-Queue-UI fuer LLM-Klassifikations-Vorschlaege (Admin)
- Tab-Schalter im Quellen-Modal: "Quellenliste" vs. "Klassifikations-Review" (Review-Tab nur fuer org_admin sichtbar, mit Pending-Counter-Badge). - Review-Karten zeigen Diff aktueller Wert -> LLM-Vorschlag pro Achse, Konfidenz-Indikator (gruen/gelb/rot), LLM-Begruendung, Buttons fuer Uebernehmen / Verwerfen / Neu klassifizieren. - Toolbar: Konfidenz-Filter, "Klassifikation starten" (Bulk im Hintergrund), "Alle >= 0.85 genehmigen" (Bulk-Approve). - API-Wrapper in api.js fuer alle 6 neuen Endpoints + erweiterte listSources-Filter. - Backend-Endpoint POST /api/sources/classification/bulk-approve (Admin-only). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -3503,6 +3503,204 @@ a.dev-source-pill:hover {
|
||||
color: var(--info);
|
||||
}
|
||||
|
||||
/* Sources-Modal: Tabs */
|
||||
.sources-tabs {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
border-bottom: 1px solid var(--border-color, rgba(0,0,0,0.1));
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.sources-tab {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--text-secondary, #555);
|
||||
cursor: pointer;
|
||||
border-bottom: 2px solid transparent;
|
||||
margin-bottom: -1px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.sources-tab:hover {
|
||||
color: var(--text-primary, #222);
|
||||
}
|
||||
.sources-tab.active {
|
||||
color: var(--primary, #2a81cb);
|
||||
border-bottom-color: var(--primary, #2a81cb);
|
||||
}
|
||||
.sources-tab-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 20px;
|
||||
padding: 0 6px;
|
||||
height: 18px;
|
||||
border-radius: 9px;
|
||||
background: var(--primary, #2a81cb);
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Review-Queue */
|
||||
.review-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px 12px;
|
||||
background: var(--cat-sonstige-bg, #f6f6fa);
|
||||
border-radius: var(--radius);
|
||||
margin-bottom: 12px;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
.review-toolbar-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.review-conf-filter {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary, #555);
|
||||
}
|
||||
.review-conf-filter select {
|
||||
padding: 2px 6px;
|
||||
font-size: 12px;
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid var(--border-color, rgba(0,0,0,0.15));
|
||||
}
|
||||
.review-toolbar-actions {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.review-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.review-card {
|
||||
background: var(--surface, #fff);
|
||||
border: 1px solid var(--border-color, rgba(0,0,0,0.08));
|
||||
border-radius: var(--radius);
|
||||
padding: 12px 14px;
|
||||
}
|
||||
.review-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.review-card-title {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.review-card-name {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
.review-card-domain {
|
||||
font-size: 11px;
|
||||
color: var(--text-disabled, #888);
|
||||
}
|
||||
.review-global-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 1px 6px;
|
||||
border-radius: var(--radius);
|
||||
background: #5e35b1;
|
||||
color: #fff;
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.review-card-confidence {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 4px 10px;
|
||||
border-radius: var(--radius);
|
||||
min-width: 60px;
|
||||
}
|
||||
.review-card-confidence .conf-value {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.review-card-confidence .conf-label {
|
||||
font-size: 9px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.3px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.review-card-confidence.conf-high { background: #e8f5e9; color: #2e7d32; }
|
||||
.review-card-confidence.conf-medium { background: #fff8e1; color: #ef6c00; }
|
||||
.review-card-confidence.conf-low { background: #ffebee; color: #c62828; }
|
||||
|
||||
.review-card-diff {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.review-diff-row {
|
||||
display: grid;
|
||||
grid-template-columns: 110px 1fr 24px 1fr;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 3px 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.review-diff-row.changed {
|
||||
background: #fff8e1;
|
||||
}
|
||||
.review-diff-label {
|
||||
color: var(--text-secondary, #555);
|
||||
font-weight: 500;
|
||||
}
|
||||
.review-diff-current {
|
||||
color: var(--text-disabled, #888);
|
||||
}
|
||||
.review-diff-arrow {
|
||||
text-align: center;
|
||||
color: var(--text-disabled, #888);
|
||||
font-weight: 600;
|
||||
}
|
||||
.review-diff-proposed {
|
||||
color: var(--text-primary, #222);
|
||||
font-weight: 500;
|
||||
}
|
||||
.review-diff-row.changed .review-diff-proposed {
|
||||
color: #ef6c00;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.review-card-reasoning {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary, #555);
|
||||
background: var(--cat-sonstige-bg, #f6f6fa);
|
||||
padding: 8px 10px;
|
||||
border-radius: var(--radius);
|
||||
margin-bottom: 10px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.review-card-actions {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* Klassifikations-Badges (politisch / reliability / alignments / state) */
|
||||
.source-classification-badges {
|
||||
display: inline-flex;
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren