From 3a68097b4fbbccdfb37adb61d312b9f3e53b341a Mon Sep 17 00:00:00 2001 From: Claude Code Date: Wed, 13 May 2026 22:05:31 +0000 Subject: [PATCH] feat(i18n): Aktions-Buttons dynamisch + komplettes Neue-Lage/Bearbeiten-Modal - _updateRefreshButton + _updateArchiveButton (app.js) nutzen T() statt Hardcode -- Aktualisieren/Laeuft/Wiederherstellen/Archivieren/Lesemodus. - Modal-Title-Setter (Lage bearbeiten / Neue Lage anlegen) lokalisiert an drei Stellen (init / openEdit / closeModal). - updateVisibilityHint und toggleTypeDefaults: dynamischer Text via T(). - HTML: ~31 data-i18n + data-i18n-attr im modal-new (Art der Lage, Optionen, Type-Hint, Quellen-Toggles, Sichtbarkeit, Aktualisierung, Intervall-Einheiten, Aufbewahrung, E-Mail-Toggles, Abbrechen). - Cache-Buster app.js auf v=20260514a. --- src/static/dashboard.html | 1650 ++++++++++++++++++------------------- src/static/i18n/de.json | 37 + src/static/i18n/en.json | 37 + src/static/js/app.js | 40 +- 4 files changed, 924 insertions(+), 840 deletions(-) diff --git a/src/static/dashboard.html b/src/static/dashboard.html index 2166149..e997aaa 100644 --- a/src/static/dashboard.html +++ b/src/static/dashboard.html @@ -1,825 +1,825 @@ - - - - - - - - - AegisSight Monitor - - - - - - - - - - - -
- -
-
- -

AegisSight Monitor Dashboard

-
-
-
- ☀︎ -
-
-
- -
- -
- -
-
- - - - - -
-
-
-
Kein Vorfall ausgewählt
-
Erstelle einen neuen Fall oder wähle einen bestehenden aus der Seitenleiste.
-
- - - - - - - -
-
- - - - - - - - - - - - - - - -
-
- AegisSight Assistent -
- - - -
-
-
-
- - -
-
- - - - -
-
-
-
-
- - -
- - - - - - - - - - - - - - - - - -
-
-
Geografische Verteilung
- - -
-
-
- - - - - - - - - - - - - - + + + + + + + + + AegisSight Monitor + + + + + + + + + + + +
+ +
+
+ +

AegisSight Monitor Dashboard

+
+
+
+ ☀︎ +
+
+
+ +
+ +
+ +
+
+ + + + + +
+
+
+
Kein Vorfall ausgewählt
+
Erstelle einen neuen Fall oder wähle einen bestehenden aus der Seitenleiste.
+
+ + + + + + + +
+
+ + + + + + + + + + + + + + + +
+
+ AegisSight Assistent +
+ + + +
+
+
+
+ + +
+
+ + + + +
+
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + +
+
+
Geografische Verteilung
+ + +
+
+
+ + + + + + + + + + + + + + diff --git a/src/static/i18n/de.json b/src/static/i18n/de.json index 7094958..c27c930 100644 --- a/src/static/i18n/de.json +++ b/src/static/i18n/de.json @@ -17,6 +17,12 @@ "action.export": "Bericht exportieren", "action.archive": "Archivieren", "action.delete": "Löschen", + "action.refreshing": "Läuft...", + "action.restore": "Wiederherstellen", + "action.budget_exceeded": "Budget aufgebraucht", + "action.read_only": "Nur Lesezugriff", + "action.budget_exceeded_title": "Token-Budget aufgebraucht. Bitte Verwaltung kontaktieren.", + "action.read_only_title": "Lizenz erlaubt keinen Schreibzugriff", "sidebar.empty": "Keine Lagen vorhanden", "header.logout": "Abmelden", "header.new_incident": "+ Neuer Fall", @@ -46,6 +52,37 @@ "modal.new_incident.visibility_public": "Öffentlich", "modal.new_incident.visibility_private": "Privat", "modal.new_incident.submit": "Lage anlegen", + "modal.new_incident.title2": "Neuen Fall anlegen", + "modal.new_incident.edit_title": "Lage bearbeiten", + "modal.placeholder.title": "z.B. Explosion in Madrid", + "modal.placeholder.description": "Weitere Details zum Vorfall (optional)", + "modal.field.type": "Art der Lage", + "modal.option.type_adhoc": "Live-Monitoring : Ereignis beobachten", + "modal.option.type_research": "Recherche : Thema analysieren", + "modal.hint.type_adhoc": "Durchsucht laufend hunderte Nachrichtenquellen nach neuen Meldungen. Empfohlen: Automatische Aktualisierung.", + "modal.hint.type_research": "Strukturierte Tiefenrecherche mit mehreren Durchläufen. Empfohlen: Manuell starten und bei Bedarf vertiefen.", + "modal.field.sources": "Quellen", + "modal.toggle.international": "Internationale Quellen einbeziehen", + "modal.toggle.telegram": "Telegram-Kanäle einbeziehen", + "modal.toggle.visibility_public_text": "Öffentlich : für alle Nutzer sichtbar", + "modal.toggle.visibility_private_text": "Privat : nur für dich sichtbar", + "modal.field.refresh": "Aktualisierung", + "modal.option.manual": "Manuell", + "modal.option.auto": "Automatisch", + "modal.field.interval": "Intervall", + "modal.unit.minutes": "Minuten", + "modal.unit.hours": "Stunden", + "modal.unit.days": "Tage", + "modal.unit.weeks": "Wochen", + "modal.field.start_time": "Erste Aktualisierung um", + "modal.field.retention": "Aufbewahrung (Tage)", + "modal.placeholder.retention": "0 = Unbegrenzt", + "modal.field.notifications": "E-Mail-Benachrichtigungen", + "modal.hint.notifications": "Per E-Mail benachrichtigen bei:", + "modal.notify.summary": "Neues Lagebild", + "modal.notify.new_articles": "Neue Artikel", + "modal.notify.status_change": "Statusänderung Faktencheck", + "aria.close": "Schließen", "modal.sources.title": "Quellenverwaltung", "modal.sources.approve_all_high": "Alle ≥ 0.85 genehmigen", "modal.export.title": "Bericht exportieren", diff --git a/src/static/i18n/en.json b/src/static/i18n/en.json index 5eaf172..bd920e0 100644 --- a/src/static/i18n/en.json +++ b/src/static/i18n/en.json @@ -17,6 +17,12 @@ "action.export": "Export report", "action.archive": "Archive", "action.delete": "Delete", + "action.refreshing": "Running...", + "action.restore": "Restore", + "action.budget_exceeded": "Budget exhausted", + "action.read_only": "Read-only", + "action.budget_exceeded_title": "Token budget exhausted. Please contact administration.", + "action.read_only_title": "License does not permit write access", "sidebar.empty": "No situations yet", "header.logout": "Sign out", "header.new_incident": "+ New situation", @@ -46,6 +52,37 @@ "modal.new_incident.visibility_public": "Public", "modal.new_incident.visibility_private": "Private", "modal.new_incident.submit": "Create situation", + "modal.new_incident.title2": "Create new case", + "modal.new_incident.edit_title": "Edit situation", + "modal.placeholder.title": "e.g. Explosion in Madrid", + "modal.placeholder.description": "More details about the incident (optional)", + "modal.field.type": "Type of situation", + "modal.option.type_adhoc": "Live monitoring : track an event", + "modal.option.type_research": "Research : analyse a topic", + "modal.hint.type_adhoc": "Continuously searches hundreds of news sources for new articles. Recommended: automatic refresh.", + "modal.hint.type_research": "Structured deep research with multiple passes. Recommended: start manually and deepen when needed.", + "modal.field.sources": "Sources", + "modal.toggle.international": "Include international sources", + "modal.toggle.telegram": "Include Telegram channels", + "modal.toggle.visibility_public_text": "Public : visible to all users", + "modal.toggle.visibility_private_text": "Private : only visible to you", + "modal.field.refresh": "Refresh", + "modal.option.manual": "Manual", + "modal.option.auto": "Automatic", + "modal.field.interval": "Interval", + "modal.unit.minutes": "Minutes", + "modal.unit.hours": "Hours", + "modal.unit.days": "Days", + "modal.unit.weeks": "Weeks", + "modal.field.start_time": "First refresh at", + "modal.field.retention": "Retention (days)", + "modal.placeholder.retention": "0 = unlimited", + "modal.field.notifications": "Email notifications", + "modal.hint.notifications": "Notify me by email about:", + "modal.notify.summary": "New briefing", + "modal.notify.new_articles": "New articles", + "modal.notify.status_change": "Fact-check status change", + "aria.close": "Close", "modal.sources.title": "Source management", "modal.sources.approve_all_high": "Approve all ≥ 0.85", "modal.export.title": "Export report", diff --git a/src/static/js/app.js b/src/static/js/app.js index e55b1a5..d48b869 100644 --- a/src/static/js/app.js +++ b/src/static/js/app.js @@ -2178,18 +2178,23 @@ async handleRefresh() { _updateRefreshButton(disabled) { const btn = document.getElementById('refresh-btn'); if (!btn) return; + const _t = (k, fb) => (typeof T === 'function') ? T(k, fb) : fb; // Hard-Stop: Lese-Modus (Budget aufgebraucht / Lizenz abgelaufen) -> immer disabled if (this.user && this.user.read_only) { btn.disabled = true; const reason = this.user.read_only_reason; - btn.textContent = reason === 'budget_exceeded' ? 'Budget aufgebraucht' : 'Nur Lesezugriff'; + btn.textContent = reason === 'budget_exceeded' + ? _t('action.budget_exceeded', 'Budget aufgebraucht') + : _t('action.read_only', 'Nur Lesezugriff'); btn.title = reason === 'budget_exceeded' - ? 'Token-Budget aufgebraucht. Bitte Verwaltung kontaktieren.' - : 'Lizenz erlaubt keinen Schreibzugriff'; + ? _t('action.budget_exceeded_title', 'Token-Budget aufgebraucht. Bitte Verwaltung kontaktieren.') + : _t('action.read_only_title', 'Lizenz erlaubt keinen Schreibzugriff'); return; } btn.disabled = disabled; - btn.textContent = disabled ? 'Läuft...' : 'Aktualisieren'; + btn.textContent = disabled + ? _t('action.refreshing', 'Läuft...') + : _t('action.refresh', 'Aktualisieren'); btn.title = ''; }, @@ -2236,8 +2241,8 @@ async handleRefresh() { toggleRefreshInterval(); // Modal-Titel und Submit ändern - { const _e = document.getElementById('modal-new-title'); if (_e) _e.textContent = 'Lage bearbeiten'; } - { const _e = document.getElementById('modal-new-submit'); if (_e) _e.textContent = 'Speichern'; } + { const _e = document.getElementById('modal-new-title'); if (_e) _e.textContent = (typeof T === 'function') ? T('modal.new_incident.edit_title', 'Lage bearbeiten') : 'Lage bearbeiten'; } + { const _e = document.getElementById('modal-new-submit'); if (_e) _e.textContent = (typeof T === 'function') ? T('common.save', 'Speichern') : 'Speichern'; } // E-Mail-Subscription laden try { @@ -2297,7 +2302,10 @@ async handleRefresh() { _updateArchiveButton(status) { const btn = document.getElementById('archive-incident-btn'); if (!btn) return; - btn.textContent = status === 'archived' ? 'Wiederherstellen' : 'Archivieren'; + const _t = (k, fb) => (typeof T === 'function') ? T(k, fb) : fb; + btn.textContent = status === 'archived' + ? _t('action.restore', 'Wiederherstellen') + : _t('action.archive', 'Archivieren'); }, // === WebSocket Handlers === @@ -3466,8 +3474,8 @@ function openModal(id) { if (id === 'modal-new' && !App._editingIncidentId) { // Create-Modus: Formular zurücksetzen document.getElementById('new-incident-form').reset(); - document.getElementById('modal-new-title').textContent = 'Neue Lage anlegen'; - document.getElementById('modal-new-submit').textContent = 'Lage anlegen'; + document.getElementById('modal-new-title').textContent = (typeof T === 'function') ? T('modal.new_incident.title2', 'Neue Lage anlegen') : 'Neue Lage anlegen'; + document.getElementById('modal-new-submit').textContent = (typeof T === 'function') ? T('modal.new_incident.submit', 'Lage anlegen') : 'Lage anlegen'; { const _b = document.getElementById('btn-enhance-description'); if (_b) _b.disabled = true; } { const _t = document.getElementById("inc-description"); if (_t) { _t.style.height = ""; _autoResizeTextarea(_t); } } // E-Mail-Checkboxen zuruecksetzen @@ -3500,8 +3508,8 @@ function closeModal(id) { } if (id === 'modal-new') { App._editingIncidentId = null; - document.getElementById('modal-new-title').textContent = 'Neue Lage anlegen'; - document.getElementById('modal-new-submit').textContent = 'Lage anlegen'; + document.getElementById('modal-new-title').textContent = (typeof T === 'function') ? T('modal.new_incident.title2', 'Neue Lage anlegen') : 'Neue Lage anlegen'; + document.getElementById('modal-new-submit').textContent = (typeof T === 'function') ? T('modal.new_incident.submit', 'Lage anlegen') : 'Lage anlegen'; } } @@ -3675,9 +3683,10 @@ function updateVisibilityHint() { const isPublic = document.getElementById('inc-visibility').checked; const text = document.getElementById('visibility-text'); if (text) { + const _t = (k, fb) => (typeof T === 'function') ? T(k, fb) : fb; text.textContent = isPublic - ? 'Öffentlich — für alle Nutzer sichtbar' - : 'Privat — nur für dich sichtbar'; + ? _t('modal.toggle.visibility_public_text', 'Öffentlich — für alle Nutzer sichtbar') + : _t('modal.toggle.visibility_private_text', 'Privat — nur für dich sichtbar'); } } @@ -3696,15 +3705,16 @@ function toggleTypeDefaults(preserveMode = false) { const hint = document.getElementById('type-hint'); const refreshMode = document.getElementById('inc-refresh-mode'); + const _t = (k, fb) => (typeof T === 'function') ? T(k, fb) : fb; if (type === 'research') { - hint.textContent = 'Recherchiert in Tiefe: Nachrichtenarchive, Parlamentsdokumente, Fachmedien, Expertenquellen. Empfohlen: Manuell starten und bei Bedarf vertiefen.'; + hint.textContent = _t('modal.hint.type_research', 'Recherchiert in Tiefe: Nachrichtenarchive, Parlamentsdokumente, Fachmedien, Expertenquellen. Empfohlen: Manuell starten und bei Bedarf vertiefen.'); // Nur bei Typ-Wechsel/Neuanlage Modus zurückziehen, beim Edit bestehender Lagen DB-Wert respektieren if (!preserveMode) { refreshMode.value = 'manual'; toggleRefreshInterval(); } } else { - hint.textContent = 'Durchsucht laufend hunderte Nachrichtenquellen nach neuen Meldungen. Empfohlen: Automatische Aktualisierung.'; + hint.textContent = _t('modal.hint.type_adhoc', 'Durchsucht laufend hunderte Nachrichtenquellen nach neuen Meldungen. Empfohlen: Automatische Aktualisierung.'); } // Beschreibungs-Tooltip je nach Typ wechseln