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:
1 parent
a2266662ad
commit
4c2e04e78b
19 files changed
+1100
-139
No files matched your search
@@ -40,7 +40,7 @@ function openDatePicker(opts){
|
||||
document.body.appendChild(pop);
|
||||
|
||||
const anchorRect = opts.anchor ? opts.anchor.getBoundingClientRect() : { left: window.innerWidth/2 - 140, bottom: window.innerHeight/2 - 160 };
|
||||
pop.style.left = Math.max(8, Math.min(anchorRect.left, window.innerWidth - 296)) + 'px';
|
||||
pop.style.left = Math.max(8, Math.min(anchorRect.left, window.innerWidth - 332)) + 'px';
|
||||
pop.style.top = Math.min(anchorRect.bottom + 6, window.innerHeight - 340) + 'px';
|
||||
|
||||
renderRangePicker();
|
||||
@@ -80,7 +80,7 @@ function openRangePicker(opts){
|
||||
|
||||
// Position: unterhalb des Ankers, innerhalb des Viewports halten
|
||||
const anchorRect = opts.anchor ? opts.anchor.getBoundingClientRect() : { left: window.innerWidth/2 - 140, bottom: window.innerHeight/2 - 160 };
|
||||
pop.style.left = Math.max(8, Math.min(anchorRect.left, window.innerWidth - 296)) + 'px';
|
||||
pop.style.left = Math.max(8, Math.min(anchorRect.left, window.innerWidth - 332)) + 'px';
|
||||
pop.style.top = Math.min(anchorRect.bottom + 6, window.innerHeight - 340) + 'px';
|
||||
|
||||
renderRangePicker();
|
||||
@@ -160,6 +160,14 @@ function applyRangePicker(){
|
||||
const selected = start || end;
|
||||
if(startInput) startInput.value = isSingle ? (selected ? formatDateISO(selected) : '') : (start ? formatDateISO(start) : '');
|
||||
if(endInput) endInput.value = end ? formatDateISO(end) : (start ? formatDateISO(start) : '');
|
||||
// Für umgeleitete native Datumsfelder (siehe unten): deren onchange/
|
||||
// oninput-Handler sollen wie bei einer Eingabe von Hand laufen.
|
||||
[startInput, endInput].forEach(el => {
|
||||
if(el && el.type === 'date'){
|
||||
el.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
el.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
}
|
||||
});
|
||||
if(opts.displayId){
|
||||
const disp = document.getElementById(opts.displayId);
|
||||
if(disp){
|
||||
@@ -199,10 +207,15 @@ function renderRangePicker(){
|
||||
</div>
|
||||
<div class="range-picker-hint">${hint}</div>
|
||||
<div class="range-picker-grid">`;
|
||||
// Erste Spalte: Kalenderwoche (Eriks Wunsch — im Büro wird in KW gedacht).
|
||||
html += '<div class="range-picker-weekday range-picker-kw-kopf">KW</div>';
|
||||
['Mo','Di','Mi','Do','Fr','Sa','So'].forEach(w => html += `<div class="range-picker-weekday">${w}</div>`);
|
||||
const kwZelle = d => `<div class="range-picker-kw">${getWeekNumber(d)}</div>`;
|
||||
if(firstWeekday > 0) html += kwZelle(first);
|
||||
for(let i = 0; i < firstWeekday; i++) html += '<div></div>';
|
||||
for(let day = 1; day <= daysInMonth; day++){
|
||||
const d = new Date(st.viewYear, st.viewMonth, day);
|
||||
if(d.getDay() === 1) html += kwZelle(d);
|
||||
const iso = formatDateISO(d);
|
||||
const classes = ['range-picker-day'];
|
||||
if(d.getDay() === 0 || d.getDay() === 6) classes.push('weekend');
|
||||
@@ -218,4 +231,15 @@ function renderRangePicker(){
|
||||
${st.mode !== 'single' && st.start && !st.end ? '<button type="button" class="small" onclick="rangePickerState.end = rangePickerState.start; applyRangePicker()">Nur dieser Tag</button>' : ''}
|
||||
</div>`;
|
||||
pop.innerHTML = html;
|
||||
}
|
||||
}
|
||||
// Native Datumsfelder (<input type="date">) öffnen statt des Browser-
|
||||
// Kalenders (kennt keine KW) denselben Kalender wie der Rest der App. Das
|
||||
// Feld selbst bleibt — Tippen funktioniert weiter, der Picker schreibt den
|
||||
// ISO-Wert hinein und löst input/change aus. Ausnahme: data-nativ.
|
||||
document.addEventListener('click', e => {
|
||||
const input = e.target && e.target.closest ? e.target.closest('input[type="date"]') : null;
|
||||
if(!input || input.disabled || input.readOnly || input.hasAttribute('data-nativ')) return;
|
||||
e.preventDefault();
|
||||
if(!input.id) input.id = 'datum_' + Math.random().toString(36).slice(2, 9);
|
||||
openDatePicker({ anchor: input, inputId: input.id });
|
||||
}, true);
|
||||
Reference in new issue
Block a user