Kleine Verbesserungen und Teams, Outlook Integration

- Outlook: Kalender-Abo je Konto (eigene Aufgaben, Meilensteine,
  Abwesenheiten als .ics), einzurichten unter Einstellungen
- Teams: Nachricht in einen Kanal bei neuen Aufgaben, mit Link direkt
  auf die Aufgabe; einzurichten unter Admin → Teams
- Sitzungen nach Bedarf laden: beim Start nur die aktuelle und drei
  davor, im Verlauf „Weitere laden“ in Fünferschritten
- Termin aus Mail: Wahl Aufgabe/Meilenstein, Notiz auch bei
  Meilensteinen, nur aktiv mit eingerichteter KI
- Kalender zeigt die KW, auch statt der Browser-Datumsfelder
- Pfeile bei den Abwesenheiten, kleinere Server-Korrekturen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
erikandClaude Opus 5.5 committed 2026-10-30 08:23:02 +01:00
1 parent a2266662ad
commit 4c2e04e78b
19 files changed
+1100 -139

No files matched your search

+75
View File
@@ -24,9 +24,82 @@
// gerufen. Keine Parameter, keine Rueckgabe.
function renderSettings(){
renderSettingsAccount();
renderSettingsKalender();
renderSettingsAiKeys();
}
// ---------- Kalender in Outlook ----------
// Geheime Abo-Adresse je Konto (GET/POST /mein-kalender). Ohne Adresse ein
// Knopf zum Einrichten; mit Adresse: Kopieren, „In Outlook öffnen“ (webcal:),
// Anleitung, neue Adresse (alte wird ungültig) und Abschalten.
let kalenderUrlAktuell = null;
async function renderSettingsKalender(){
const el = document.getElementById('settingsKalender');
if(!el) return;
if(kalenderUrlAktuell === null){
try {
const d = await fetch(baseUrl() + '/mein-kalender').then(r => r.json());
kalenderUrlAktuell = (d && d.url) || '';
} catch(e){ el.innerHTML = '<span class="settings-warn">Konnte nicht geladen werden.</span>'; return; }
}
const url = kalenderUrlAktuell;
if(!currentUser || !currentUser.personId){
el.innerHTML = '<p class="settings-warn">Ohne Personen-Zuordnung enthält der Kalender nur Ihre Abwesenheiten.</p>';
} else el.innerHTML = '';
if(!url){
el.innerHTML += '<button type="button" onclick="kalenderAdresse(false)">Kalender-Adresse erzeugen</button>';
return;
}
const webcal = url.replace(/^https?:/, 'webcal:');
el.innerHTML += `
<div class="kalender-adresse">
<input type="text" id="kalenderUrlFeld" readonly value="${esc(url)}" onclick="this.select()" aria-label="Kalender-Adresse">
<button type="button" class="secondary" onclick="kalenderKopieren()">Kopieren</button>
<a class="button-link" href="${esc(webcal)}">In Outlook öffnen</a>
</div>
<details class="kalender-anleitung">
<summary>So abonnieren Sie den Kalender</summary>
<ol>
<li><b>Outlook am PC (klassisch):</b> „In Outlook öffnen“ klicken und bestätigen — oder
Kalender → <i>Kalender hinzufügen</i> → <i>Aus dem Internet</i> → Adresse einfügen.</li>
<li><b>Neues Outlook / Outlook im Browser:</b> Kalender → <i>Kalender hinzufügen</i> →
<i>Aus dem Internet abonnieren</i> → Adresse einfügen. Das funktioniert nur, wenn der
Server aus dem Internet erreichbar ist — Microsoft holt den Kalender von außen ab.</li>
</ol>
<p class="hint">Die Adresse ist Ihr persönlicher Schlüssel: Wer sie kennt, sieht Ihre Termine.
Nicht weitergeben. Bei Verdacht „Neue Adresse“ wählen — die alte gilt dann nicht mehr.</p>
</details>
<div class="kalender-aktionen">
<button type="button" class="secondary small" onclick="kalenderAdresse(false, true)">Neue Adresse</button>
<button type="button" class="secondary small" onclick="kalenderAdresse(true)">Abschalten</button>
</div>`;
}
async function kalenderAdresse(aus, nachfragen){
if(aus && !confirm('Kalender-Abo abschalten? Outlook zeigt danach keine neuen Termine mehr.')) return;
if(nachfragen && !confirm('Neue Adresse erzeugen? Die bisherige gilt dann nicht mehr — in Outlook muss der Kalender neu abonniert werden.')) return;
try {
const r = await fetch(baseUrl() + '/mein-kalender', {
method: 'POST', headers: { 'Content-Type': 'application/json; charset=utf-8' },
body: JSON.stringify({ aus: !!aus })
});
const d = await r.json();
if(!r.ok || !d.ok) throw new Error(d.error || 'Fehler');
kalenderUrlAktuell = d.url || '';
renderSettingsKalender();
showSettingsNote(aus ? 'Kalender-Abo abgeschaltet.' : 'Kalender-Adresse erzeugt.');
} catch(e){ alert('Das hat nicht geklappt: ' + e.message); }
}
function kalenderKopieren(){
const feld = document.getElementById('kalenderUrlFeld');
if(!feld) return;
const fertig = () => showSettingsNote('Adresse kopiert.');
if(navigator.clipboard && window.isSecureContext){
navigator.clipboard.writeText(feld.value).then(fertig).catch(() => { feld.select(); document.execCommand('copy'); fertig(); });
} else { feld.select(); document.execCommand('copy'); fertig(); }
}
// ---------- Mein Konto ----------
// renderSettingsAccount: zeigt die Stammdaten des angemeldeten Kontos an.
@@ -234,6 +307,8 @@ function putMyAiKey(provider, patch){
body: JSON.stringify(body)
}).then(r => r.json().then(json => ({ ok: r.ok, json }))).then(({ ok, json }) => {
if(!ok || !json.ok) throw new Error((json && json.error) || 'Speichern fehlgeschlagen.');
// "Termin aus Mail" ist nur mit eingerichteter KI aktiv — Stand neu holen.
if(typeof mailKiStatusLaden === 'function') mailKiStatusLaden();
return json;
});
}