Kommentare je Gewerk klar getrennt, abgewählte Gewerke ausgeblendet
- Kommentare mehrerer Gewerke mit Überschrift und Linie: Gewerk in seiner Farbe, rechts Verfasser und Zeit, darunter der Text (Projekt-Dashboard, Projektliste, Wandtafel, Verlauf-Kacheln) - Behoben: Im Projekt-Dashboard erschienen Kommentare von Gewerken, die das Projekt nicht mehr hat (z. B. HLS bei 21-4030); Anzeige und Verlauf zeigen nur noch Gewerke des Projekts - Sitzungswechsel übernimmt nur noch Kommentare der Gewerke des Projekts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e291ca8438
commit
4ac3d8d53d
7 files changed
+95
-24
No files matched your search
@@ -4871,6 +4871,31 @@ Kommentare nach dreimaligem Bereinigen unverändert). `entitiesReparieren()`
|
||||
`project_kommentare.status` und `protokoll_punkte.text` aller Sitzungen über
|
||||
`entitiesEntstapeln()` zurück.
|
||||
|
||||
## Behobener Fehler: Kommentare abgewählter Gewerke (11/2026)
|
||||
|
||||
Eriks Meldung zu 21-4030: Im Projekt-Dashboard stand ein HLS-Kommentar,
|
||||
obwohl das Projekt seit KW 31 nur noch ELT hat. Ursache: Die einmalige
|
||||
Umstellung `kommentareInAktuelleSitzungUebernehmen()` hatte je Gewerk den
|
||||
jüngsten früheren Kommentar übernommen, ohne die aktuellen Gewerke des
|
||||
Projekts zu prüfen; der Sitzungswechsel trug ihn weiter. Jetzt:
|
||||
`kommentareDesProjekts()` (js/utils.js) — die Gesamtanzeige
|
||||
(`kommentarVon(p, null)`, `kommentarAnzeigeHtml()`) und der Verlauf im
|
||||
Projekt-Dashboard (`planKommentarDaten()`, je Sitzung mit DEREN Gewerken)
|
||||
zeigen nur Gewerke des Projekts; `ensureCurrentWeekRollover()` übernimmt nur
|
||||
Kommentare dieser Gewerke. Gelöscht wird nichts — die verirrte Kopie fällt
|
||||
beim nächsten Sitzungswechsel aus der aktuellen Sitzung heraus.
|
||||
|
||||
**Darstellung mehrerer Gewerke „B – Überschrift mit Linie“** (Eriks Wahl
|
||||
aus dem Artifact „Kommentare je Gewerk“): `kommentarAnzeigeHtml(p, null,
|
||||
mitMeta)` zeichnet je Gewerk eine Kopfzeile (Gewerk in seiner Farbe
|
||||
`--gewerk-elt/-hls/-arch`, feine Linie, mit `mitMeta` Verfasser und Zeit)
|
||||
und darunter den Text; bei nur einem Gewerk wie bisher nur den Text.
|
||||
Genutzt von der Kachel „Kommentar der Sitzung“ im Projekt-Dashboard (dort
|
||||
entfällt dann die gemeinsame Verfasserzeile, `kommentarGewerkeMitText()`),
|
||||
der Kommentaransicht der Projektliste/Wandtafel (`renderKommentarAnsicht()`)
|
||||
und den Verlauf-Kacheln (ohne Verfasser). Stile `.kommentar-gewerke`,
|
||||
`.kommentar-kopf` in `styles.css`.
|
||||
|
||||
## Behobene Fehler (Testlauf 10/2026, fünf Test-Agents)
|
||||
|
||||
- **Gesperrte Sitzungen sind für Nicht-Admins auch inhaltlich unveränderlich**:
|
||||
|
||||
+4
-4
@@ -38,7 +38,7 @@
|
||||
<link rel="icon" type="image/png" href="/logo.png">
|
||||
<link rel="alternate icon" href="/logo.ico">
|
||||
<link rel="apple-touch-icon" href="/logo.png">
|
||||
<link rel="stylesheet" href="/styles.css?v=122">
|
||||
<link rel="stylesheet" href="/styles.css?v=123">
|
||||
<link rel="stylesheet" href="/plan-styles.css?v=56">
|
||||
<!-- Glas-Darstellung (public/glas.css, als letztes Stylesheet): greift nur mit
|
||||
der Klasse html.glas. Gesetzt wird sie hier, vor dem ersten Zeichnen,
|
||||
@@ -1954,7 +1954,7 @@
|
||||
</div>
|
||||
|
||||
<script src="/js/globals.js?v=10"></script>
|
||||
<script src="/js/utils.js?v=31"></script>
|
||||
<script src="/js/utils.js?v=33"></script>
|
||||
<script src="/js/icons.js?v=2"></script>
|
||||
<script src="/js/ui.js?v=9"></script>
|
||||
<script src="/js/date-picker.js?v=6"></script>
|
||||
@@ -1962,7 +1962,7 @@
|
||||
<script src="/js/auth.js?v=11"></script>
|
||||
<script src="/js/store.js?v=17"></script>
|
||||
<script src="/js/weeks.js?v=12"></script>
|
||||
<script src="/js/board/board.js?v=41"></script>
|
||||
<script src="/js/board/board.js?v=42"></script>
|
||||
<script src="/js/wochenbericht/wochenbericht.js?v=29"></script>
|
||||
<script src="/js/people/people.js?v=8"></script>
|
||||
<script src="/js/planung/planung.js?v=3"></script>
|
||||
@@ -2001,7 +2001,7 @@
|
||||
umhuellt. -->
|
||||
<script src="/js/plan/plan-state.js?v=25"></script>
|
||||
<script src="/js/plan/plan-sections.js?v=12"></script>
|
||||
<script src="/js/plan/plan-info.js?v=15"></script>
|
||||
<script src="/js/plan/plan-info.js?v=17"></script>
|
||||
<script src="/js/plan/plan-history.js?v=4"></script>
|
||||
<script src="/js/plan/plan-build-gantt.js?v=11"></script>
|
||||
<script src="/js/plan/plan-gantt.js?v=23"></script>
|
||||
|
||||
@@ -748,7 +748,7 @@ function renderBoardDrawer(p, allPeople, locked, weekLabel, opts){
|
||||
// renderKommentarAnsicht: der Kommentar der laufenden Sitzung, nur zu lesen.
|
||||
// Parameter: p (Projekt), locked. Rückgabe: HTML-String.
|
||||
function renderKommentarAnsicht(p, locked){
|
||||
const text = sanitizeStatusHtml(kommentarVon(p, kommentarGewerk()).status || '');
|
||||
const text = kommentarAnzeigeHtml(p, kommentarGewerk(), true);
|
||||
return `<div class="status-edit is-ansicht locked-cell">${text ||
|
||||
'<span class="hint" style="margin:0">Für diese Sitzung ist noch kein Kommentar erfasst.</span>'}</div>`;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
for(let i = versionen.length - 1; i >= 0; i--){
|
||||
const k = kommentarVon(versionen[i].project, null);
|
||||
if(statusPlainText(k.status)){
|
||||
letzter = { week: versionen[i].week, k, aktuell: i === versionen.length - 1 };
|
||||
letzter = { week: versionen[i].week, k, project: versionen[i].project, aktuell: i === versionen.length - 1 };
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,8 @@
|
||||
gewerke.forEach(g => {
|
||||
let vorher = '';
|
||||
versionen.forEach(v => {
|
||||
const k = kommentarVon(v.project, g);
|
||||
// Nur, wenn das Projekt in JENER Sitzung das Gewerk hatte.
|
||||
const k = (g in kommentareDesProjekts(v.project)) ? kommentarVon(v.project, g) : { status: '' };
|
||||
const text = statusPlainText(k.status);
|
||||
if(text && text !== vorher && !(letzter && v.week === letzter.week)){
|
||||
verlauf.push({ week: v.week, gewerk: g, html: sanitizeStatusHtml(k.status), autor: k.statusAuthor || '', at: k.statusAt || '' });
|
||||
@@ -184,8 +185,9 @@
|
||||
if(editEl){
|
||||
editEl.className = 'status-edit is-ansicht';
|
||||
editEl.contentEditable = 'false';
|
||||
// Alle Gewerke zusammen, je mit Gewerk davor (kommentarVon(), js/utils.js).
|
||||
const text = kom.letzter ? sanitizeStatusHtml(kom.letzter.k.status) : '';
|
||||
// Alle Gewerke zusammen; bei mehreren je mit Überschrift, Linie und
|
||||
// Verfasser (kommentarAnzeigeHtml(), js/utils.js, Eriks Wahl „B“).
|
||||
const text = kom.letzter ? kommentarAnzeigeHtml(kom.letzter.project, null, true) : '';
|
||||
editEl.innerHTML = text || '<span class="hint" style="margin:0">Zu diesem Projekt ist noch kein Kommentar erfasst.</span>';
|
||||
}
|
||||
const hinweisEl = document.getElementById('planStatusHinweis');
|
||||
@@ -200,7 +202,9 @@
|
||||
const autorEl = document.getElementById('planStatusAutor');
|
||||
if(autorEl){
|
||||
const k = kom.letzter ? kom.letzter.k : {};
|
||||
autorEl.innerHTML = k.status && k.statusAuthor
|
||||
// Bei mehreren Gewerken steht der Verfasser schon je Gewerk im Text.
|
||||
const mehrere = kom.letzter && kommentarGewerkeMitText(kom.letzter.project) > 1;
|
||||
autorEl.innerHTML = !mehrere && k.status && k.statusAuthor
|
||||
? `<span class="plan-autor-ava">${esc(initialsForName(k.statusAuthor))}</span>${esc(k.statusAuthor)}`
|
||||
+ (k.statusAt && typeof formatCommentStamp === 'function' ? ', ' + esc(formatCommentStamp(k.statusAt)) : '')
|
||||
: '';
|
||||
|
||||
+39
-8
@@ -385,8 +385,21 @@ function kommentarGewerk(){
|
||||
// Verfasser/Zeit des jüngsten, besprochen nur, wenn ALLE Gewerke des
|
||||
// Projekts es abgehakt haben. Parameter: p (Projekt), g (Gewerk oder
|
||||
// null/undefined). Rückgabe: { status, statusAuthor, statusAt, besprochen }.
|
||||
function kommentarVon(p, g){
|
||||
// kommentareDesProjekts: die Kommentare nur der Gewerke, die das Projekt hat.
|
||||
// Ein Kommentar eines Gewerks, das dem Projekt nicht (mehr) gehört — etwa aus
|
||||
// einer Zeit, als es noch HLS hatte —, gehört nicht in die Gesamtanzeige
|
||||
// (Eriks Meldung zu 21-4030). Ohne gepflegte Gewerke: alle. Rückgabe: Objekt.
|
||||
function kommentareDesProjekts(p){
|
||||
const alle = (p && p.kommentare) || {};
|
||||
const gewerke = Array.isArray(p && p.gewerke) ? p.gewerke : [];
|
||||
if(!gewerke.length) return alle;
|
||||
const aus = {};
|
||||
Object.keys(alle).forEach(k => { if(gewerke.includes(k)) aus[k] = alle[k]; });
|
||||
return aus;
|
||||
}
|
||||
|
||||
function kommentarVon(p, g){
|
||||
const alle = g ? ((p && p.kommentare) || {}) : kommentareDesProjekts(p);
|
||||
if(g){
|
||||
const e = alle[g] || {};
|
||||
return { status: e.status || '', statusAuthor: e.statusAuthor || '', statusAt: e.statusAt || '', besprochen: !!e.besprochen };
|
||||
@@ -408,19 +421,37 @@ function kommentarVon(p, g){
|
||||
}
|
||||
|
||||
// kommentarAnzeigeHtml: der Kommentar zur ANZEIGE, bereinigt. Mit Gewerk g
|
||||
// nur dessen Text; ohne Gewerk die Texte aller Gewerke, bei mehreren je mit
|
||||
// dem Gewerk als eigener, dezenter Beschriftung (.kommentar-gewerk) —
|
||||
// Systemtext, nicht Teil des Kommentars (anders als die fette "ELT:"-Zeile,
|
||||
// die kommentarVon() für Klartext-Vorschauen einfügt). Rückgabe: HTML ('' ohne Text).
|
||||
function kommentarAnzeigeHtml(p, g){
|
||||
// nur dessen Text; ohne Gewerk die Texte aller Gewerke des Projekts. Bei
|
||||
// mehreren Gewerken Darstellung „B – Überschrift mit Linie“ (Eriks Wahl):
|
||||
// je Gewerk eine Kopfzeile mit dem Gewerk in seiner Farbe, einer feinen Linie
|
||||
// und (mitMeta) Verfasser und Zeit, darunter der Text — Systemtext, nicht
|
||||
// Teil des Kommentars (anders als die fette "ELT:"-Zeile, die kommentarVon()
|
||||
// für Klartext-Vorschauen einfügt). Parameter: p, g, mitMeta.
|
||||
// Rückgabe: HTML ('' ohne Text).
|
||||
function kommentarAnzeigeHtml(p, g, mitMeta){
|
||||
if(g) return sanitizeStatusHtml(kommentarVon(p, g).status || '');
|
||||
const alle = (p && p.kommentare) || {};
|
||||
const alle = kommentareDesProjekts(p);
|
||||
const reihenfolge = (typeof DEPARTMENTS === 'object' && DEPARTMENTS) ? Object.keys(DEPARTMENTS) : ['ELT','HLS','ARCH'];
|
||||
Object.keys(alle).forEach(k => { if(!reihenfolge.includes(k)) reihenfolge.push(k); });
|
||||
const mitText = reihenfolge.filter(k => alle[k] && statusPlainText(alle[k].status) !== '');
|
||||
if(mitText.length === 0) return '';
|
||||
if(mitText.length === 1) return sanitizeStatusHtml(alle[mitText[0]].status);
|
||||
return mitText.map(k => `<div class="kommentar-gewerk">${esc(k)}</div><div>${sanitizeStatusHtml(alle[k].status)}</div>`).join('');
|
||||
return '<div class="kommentar-gewerke">' + mitText.map(k => {
|
||||
const e = alle[k];
|
||||
const zeit = e.statusAt && typeof formatCommentStamp === 'function' ? formatCommentStamp(e.statusAt) : '';
|
||||
const meta = mitMeta ? [e.statusAuthor, zeit].filter(Boolean).join(' · ') : '';
|
||||
return '<div class="kommentar-block">'
|
||||
+ '<div class="kommentar-kopf"><span class="kommentar-gewerk gewerk-' + esc(k.toLowerCase()) + '">' + esc(k) + '</span>'
|
||||
+ '<span class="kommentar-linie"></span>' + (meta ? '<span class="kommentar-meta">' + esc(meta) + '</span>' : '') + '</div>'
|
||||
+ '<div class="kommentar-text">' + sanitizeStatusHtml(e.status) + '</div></div>';
|
||||
}).join('') + '</div>';
|
||||
}
|
||||
|
||||
// kommentarGewerkeMitText: wie viele Gewerke des Projekts einen Kommentar
|
||||
// haben (für die Frage, ob eine gemeinsame Verfasserzeile Sinn ergibt).
|
||||
function kommentarGewerkeMitText(p){
|
||||
const alle = kommentareDesProjekts(p);
|
||||
return Object.keys(alle).filter(k => alle[k] && statusPlainText(alle[k].status) !== '').length;
|
||||
}
|
||||
|
||||
// kommentarSetzen: ändert den Kommentar-Eintrag eines Gewerks (nur die in
|
||||
|
||||
+13
-6
@@ -4188,12 +4188,19 @@ tr.is-menu-open { background: var(--surface-alt); }
|
||||
min-height: 3em;
|
||||
}
|
||||
.timeline-text p { margin: 0; }
|
||||
/* Gewerk über dem Kommentar: Systemtext, nicht Teil des Kommentars. */
|
||||
.kommentar-gewerk {
|
||||
font-size: 11px; font-weight: 600; letter-spacing: 0;
|
||||
color: var(--text-subtle); margin-top: 4px;
|
||||
}
|
||||
.kommentar-gewerk:first-child { margin-top: 0; }
|
||||
/* Kommentare mehrerer Gewerke, Darstellung „B – Überschrift mit Linie“
|
||||
(Eriks Wahl): Gewerk in seiner Farbe, feine Linie, Verfasser und Zeit,
|
||||
darunter der Text. Systemtext, nicht Teil des Kommentars. */
|
||||
.kommentar-gewerke { display: flex; flex-direction: column; gap: 16px; }
|
||||
.kommentar-block { display: flex; flex-direction: column; gap: 4px; }
|
||||
.kommentar-kopf { display: flex; align-items: center; gap: 12px; }
|
||||
.kommentar-gewerk { flex: none; font-size: 12px; font-weight: 500; letter-spacing: 0; color: var(--text-muted); }
|
||||
.kommentar-gewerk.gewerk-elt { color: var(--gewerk-elt); }
|
||||
.kommentar-gewerk.gewerk-hls { color: var(--gewerk-hls); }
|
||||
.kommentar-gewerk.gewerk-arch { color: var(--gewerk-arch); }
|
||||
.kommentar-linie { flex: 1; height: 1px; background: var(--line-soft); min-width: 16px; }
|
||||
.kommentar-meta { flex: none; font-size: 12px; font-weight: 400; color: var(--text-subtle); white-space: nowrap; }
|
||||
:root { --gewerk-elt: var(--accent); --gewerk-hls: var(--green); --gewerk-arch: var(--amber); }
|
||||
.timeline-leer { color: var(--text-muted); font-style: normal; }
|
||||
|
||||
.timeline-lph-list { display: flex; flex-direction: column; gap: 1px; }
|
||||
|
||||
@@ -2956,8 +2956,12 @@ function ensureCurrentWeekRollover(){
|
||||
// zur Sitzung und beginnt leer.
|
||||
const vorher = p.kommentare || {};
|
||||
p.kommentare = {};
|
||||
// Nur Gewerke, die das Projekt hat — sonst lebte ein Kommentar eines
|
||||
// längst abgewählten Gewerks Woche für Woche weiter (21-4030).
|
||||
const gewerke = Array.isArray(p.gewerke) ? p.gewerke : [];
|
||||
Object.keys(vorher).forEach(g => {
|
||||
const k = vorher[g] || {};
|
||||
if(gewerke.length && !gewerke.includes(g)) return;
|
||||
if(!String(k.status || '').trim()) return;
|
||||
p.kommentare[g] = { status: k.status, statusAuthor: k.statusAuthor || '',
|
||||
statusAt: k.statusAt || '', besprochen: false };
|
||||
|
||||
Reference in new issue
Block a user