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:
1 parent
bc30f2900b
commit
db63a29365
47 files changed
+16486
-3768
No files matched your search
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user