Wandtafel-Dashboard, Dateibereinigung und Auslastungs-Vereinfachung

Neue Wandtafel (Touch-Dashboard für Kiosk-Anzeige): Auslastung/Besprochen je
Gewerk, Aufgaben-Kennzahlen, Ereignis-Feed nach Art gruppiert, vollständige
Projektliste zum Scrollen, automatischer Rücksprung nach Untätigkeit mit
sichtbarem Countdown. Eigene Kiosk-Rolle ohne Fachrolle und ohne Schreibrechte.
Auslastung: Möglichkeit zum Wechsel der ausgewerteten Sitzung entfernt.
Aufräumen nicht mehr benötigter Dateien, README auf aktuellen Stand gebracht.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
erikandClaude Sonnet 5 committed 2026-10-02 15:14:47 +02:00
1 parent bc30f2900b
commit db63a29365
47 files changed
+16486 -3768

No files matched your search

+19 -30
View File
@@ -18,7 +18,7 @@
// Projekt-Identität, die project_id (wird bei jedem cloneWeek() neu
// vergeben) nicht bieten konnte. Die Bearbeitung der Projekte selbst
// (Kommentar-Editor, LPH, Beteiligte) läuft vollständig über die bestehenden
// Funktionen aus js/board/board.js (editProj/editLph/cycleAssign/
// Funktionen aus js/board/board.js (editLph/cycleAssign/
// renderCommentEditor/renderBoardDrawer/renderBoardRow) — dieses Modul
// ergänzt die Gruppierung/Diff-Logik, das Layout des Berichts und die
// Anwesenheitserfassung am Seitenfuß (renderAttendance(), weiter unten).
@@ -26,7 +26,7 @@
// diesem Tab die Sitzung abgearbeitet wird.
//
// Läuft wie board.js als klassisches globales Skript (kein Modul/IIFE), nur
// von Test.html geladen (nach js/board/board.js).
// von App.html geladen (nach js/board/board.js).
// findPreviousWeek: liefert die chronologisch vorherige Sitzung zu `week`
// (nach weekSortKey sortiert) oder null, wenn `week` die früheste ist.
@@ -89,11 +89,12 @@ function classifyProjectChange(p, prevWeek){
}
// BERICHT_OPTS: Darstellungs-Optionen, die dieser Tab an die gemeinsamen
// Render-Funktionen aus js/board/board.js übergibt. Im Wochenbericht werden
// nur die beauftragten Leistungsphasen gezeigt (p.beauftragteLP) — im
// Projektboard bleibt es bei allen. Den Verlauf der Vorwochen hängt
// renderBoardDrawer() inzwischen überall an (renderProjektVerlauf() in
// js/utils.js), er braucht deshalb kein eigenes Kennzeichen mehr.
// Render-Funktionen aus js/board/board.js übergibt. dicht ist das einzige,
// was den Wochenbericht noch vom Projektboard unterscheidet (zwei statt drei
// Spalten) — nurBeauftragteLph gilt inzwischen für beide (BOARD_OPTS,
// js/board/board.js). Den Verlauf der Vorwochen hängt renderBoardDrawer()
// überall an (renderProjektVerlauf() in js/utils.js), er braucht deshalb kein
// eigenes Kennzeichen mehr.
const BERICHT_OPTS = { nurBeauftragteLph: true, dicht: true };
// renderReportCard: baut die immer aufgeklappte Karte eines Projekts im
@@ -120,27 +121,6 @@ function renderReportCard(p, reason, allPeople, locked, weekLabel, variant){
</div>`;
}
// renderReportSection: baut einen Abschnitt des Berichts (Überschrift mit
// Anzahl, Liste der zugehörigen Projekte). `expanded` steuert, ob die volle
// Karte (renderReportCard) oder die normale einklappbare Board-Zeile
// (renderBoardRow) genutzt wird. Parameter: title, entries (Array
// {p, reason}), allPeople, locked, expanded (Boolean), emptyText. Rückgabe:
// HTML-String.
function renderReportSection(title, entries, allPeople, locked, expanded, emptyText, weekLabel, variant){
let html = `<div class="section-title">${esc(title)} (${entries.length})</div>`;
if(entries.length === 0){
html += `<div class="hint">${esc(emptyText)}</div>`;
return html;
}
html += `<div class="${expanded ? 'report-list' : 'board-list'}">`;
html += entries.map(({p, reason}) => expanded
? renderReportCard(p, reason, allPeople, locked, weekLabel, variant)
: renderBoardRow(p, allPeople, locked, weekLabel, BERICHT_OPTS)
).join('');
html += `</div>`;
return html;
}
// ---------- Anwesenheit der Sitzung ----------
// Die Anwesenheit hing ursprünglich als Zweitfunktion an der Kürzel-Legende
// unter dem Projektboard ("klick für Anwesenheit") — Namenserklärung und
@@ -672,8 +652,13 @@ function openTodoAusKommentar(pid){
// Vorschlag aus dem gerade im Feld stehenden Text, nicht aus dem
// gespeicherten: Im Meeting tippt man den Beschluss und legt sofort die
// Aufgabe an, ohne vorher zu speichern.
// feld ist seit der Umstellung auf contenteditable (Eriks Wunsch nach
// echter Fett-/Kursiv-/Farbdarstellung statt sichtbarer Markup-Zeichen,
// js/utils.js) ein <div> ohne .value — statusTextMitZeilen() liefert
// daraus reinen Text mit erhaltenen Zeilenumbrüchen, aus dem unten die
// erste Zeile als Titelvorschlag gezogen wird.
const feld = document.querySelector('#wochenbericht .comment-field');
const text = feld ? feld.value : statusPlainText(p.status);
const text = feld ? statusTextMitZeilen(feld.innerHTML) : statusPlainText(p.status);
const ersteZeile = String(text || '').split('\n').map(z => z.replace(/^[-•*\s]+/, '').trim()).find(z => z) || '';
document.getElementById('todoKommentarTitel').value = ersteZeile.slice(0, 120);
@@ -844,7 +829,11 @@ document.addEventListener('keydown', function(e){
if(typeof currentTab === 'undefined' || currentTab !== 'wochenbericht') return;
const w = currentWeek();
if(!w) return;
const imFeld = e.target && e.target.matches && e.target.matches('input, textarea, select');
// isContentEditable erfasst das Kommentarfeld (seit der Umstellung auf
// contenteditable ein <div>, kein <textarea> mehr, siehe js/utils.js) —
// ohne diese Ergänzung griffen ↓/↑ dort als Projekt-Wechsel statt als
// normale Cursorbewegung im Text.
const imFeld = e.target && ((e.target.matches && e.target.matches('input, textarea, select')) || e.target.isContentEditable);
if((e.key === 'Enter') && (e.ctrlKey || e.metaKey)){
const feld = e.target && e.target.closest ? e.target.closest('.comment-field') : null;