feat(i18n): Aktionsleiste + Sidebar (Quellen, Feedback, Archiv, Stats, Empty-States)

- 5 Action-Buttons im Header (Aktualisieren/Bearbeiten/Bericht
  exportieren/Archivieren/Loeschen) via data-i18n.
- Sidebar Archiv-Section, Quellen-Button, Feedback-Button, title-
  Attribute via data-i18n + data-i18n-attr.
- Sidebar-Stats 0 Quellen / 0 Artikel: app.js.updateSidebarStats
  baut die Suffixe ueber T() zusammen.
- Empty-States Kein Live-Monitoring / Keine Deep-Research (inkl.
  eigene-Filter-Varianten) lokalisiert.
- Cache-Buster app.js auf v=20260513g.
Dieser Commit ist enthalten in:
Claude Code
2026-05-13 22:00:00 +00:00
Ursprung 917c260298
Commit 90f0731a86
4 geänderte Dateien mit 57 neuen und 17 gelöschten Zeilen

Datei anzeigen

@@ -695,8 +695,13 @@ const App = {
const activeResearch = filtered.filter(i => i.status === 'active' && i.type === 'research');
const archived = filtered.filter(i => i.status === 'archived');
const emptyLabelAdhoc = this._sidebarFilter === 'mine' ? 'Kein eigenes Live-Monitoring' : 'Kein Live-Monitoring';
const emptyLabelResearch = this._sidebarFilter === 'mine' ? 'Keine eigenen Deep-Research' : 'Keine Deep-Research';
const _tEmpty = (k, fb) => (typeof T === 'function') ? T(k, fb) : fb;
const emptyLabelAdhoc = this._sidebarFilter === 'mine'
? _tEmpty('sidebar.empty_adhoc_mine', 'Kein eigenes Live-Monitoring')
: _tEmpty('sidebar.empty_adhoc', 'Kein Live-Monitoring');
const emptyLabelResearch = this._sidebarFilter === 'mine'
? _tEmpty('sidebar.empty_research_mine', 'Keine eigenen Deep-Research')
: _tEmpty('sidebar.empty_research', 'Keine Deep-Research');
activeContainer.innerHTML = activeAdhoc.length
? activeAdhoc.map(i => UI.renderIncidentItem(i, i.id === this.currentIncidentId)).join('')
@@ -2607,20 +2612,23 @@ async handleRefresh() {
// === Sidebar-Stats ===
async updateSidebarStats() {
const _t = (k, fb) => (typeof T === 'function') ? T(k, fb) : fb;
const lblSources = _t('sidebar.stat.sources_suffix', 'Quellen');
const lblArticles = _t('sidebar.stat.articles_suffix', 'Artikel');
try {
const stats = await API.getSourceStats();
const srcCount = document.getElementById('stat-sources-count');
const artCount = document.getElementById('stat-articles-count');
if (srcCount) srcCount.textContent = `${stats.total_sources} Quellen`;
if (artCount) artCount.textContent = `${stats.total_articles} Artikel`;
if (srcCount) srcCount.textContent = `${stats.total_sources} ${lblSources}`;
if (artCount) artCount.textContent = `${stats.total_articles} ${lblArticles}`;
} catch {
// Fallback: aus Lagen berechnen
const totalArticles = this.incidents.reduce((sum, i) => sum + i.article_count, 0);
const totalSources = this.incidents.reduce((sum, i) => sum + i.source_count, 0);
const srcCount = document.getElementById('stat-sources-count');
const artCount = document.getElementById('stat-articles-count');
if (srcCount) srcCount.textContent = `${totalSources} Quellen`;
if (artCount) artCount.textContent = `${totalArticles} Artikel`;
if (srcCount) srcCount.textContent = `${totalSources} ${lblSources}`;
if (artCount) artCount.textContent = `${totalArticles} ${lblArticles}`;
}
},