All new
alle new
This commit is contained in:
1 parent
da64472251
commit
5b20adee48
1605 files changed
+396517
-1674
No files matched your search
@@ -0,0 +1,164 @@
|
||||
// -----------------------------
|
||||
// Projektplan — Verlauf über mehrere Sitzungen
|
||||
// -----------------------------
|
||||
// Dieses Modul macht die Sitzungs-Historie eines Projekts sichtbar: die
|
||||
// Kompakt-Karte "Verlauf" unter dem GANTT zeigt den letzten Kommentarwechsel,
|
||||
// ein Klick öffnet #planHistoryModal mit dem vollständigen Verlauf.
|
||||
//
|
||||
// Der Verlauf selbst wird NICHT hier gezeichnet, sondern von
|
||||
// renderProjektVerlauf() in js/utils.js — derselben Darstellung, die auch der
|
||||
// Wochenbericht unter der Projektkarte und die Projektliste zeigen. Zuvor
|
||||
// hatte jede dieser Stellen ihre eigene Fassung mit eigener Auswahl (hier nur
|
||||
// Sitzungen mit Kommentarwechsel, im Bericht auch Termine und
|
||||
// Leistungsphasen), weshalb derselbe Projektverlauf je nach Aufrufort anders
|
||||
// aussah und sich widersprechen konnte. Der Dialog übergibt kein weekLabel:
|
||||
// Er kennt keine "aktuelle" Fassung, die auszulassen wäre, und zeigt deshalb
|
||||
// alle Sitzungen einschließlich der geöffneten.
|
||||
//
|
||||
// Hintergrund: Beim wöchentlichen cloneWeek() (js/weeks.js) wird der
|
||||
// Kommentartext in die neue Sitzung kopiert und dort überschrieben. Der alte
|
||||
// Text bleibt zwar in der alten Sitzung erhalten, war aber praktisch
|
||||
// unsichtbar, weil niemand in alte Sitzungen zurückwechselt. Damit ging der
|
||||
// Gesprächsfaden eines Projekts verloren — genau das, wofür das wöchentliche
|
||||
// Board ursprünglich gedacht war.
|
||||
//
|
||||
// WICHTIG — kein neuer Endpunkt nötig: Die Projektplan-Seite lädt über
|
||||
// GET /load-all ohnehin ALLE Sitzungen mit allen Projekten nach db.weeks
|
||||
// (siehe loadPlanData() in plan-state.js). Zusammen mit project_uid (der
|
||||
// dauerhaften, wochenunabhängigen Projekt-Identität, siehe
|
||||
// migrateAddProjectUid() in server.js) lässt sich der Verlauf daher rein im
|
||||
// Browser zusammenstellen. Ein serverseitiges GET /projects/:uid/history wird
|
||||
// erst nötig, wenn der Verlauf auch außerhalb dieser Seite gebraucht wird.
|
||||
//
|
||||
// Die hier definierten Helfer projectVersions()/previousProjectVersion()
|
||||
// werden auch von plan-build-gantt.js gebraucht (Geister-Balken der Vorwoche)
|
||||
// und deshalb auf window.PlanApp exportiert. Dieses Modul muss daher VOR
|
||||
// plan-build-gantt.js geladen werden.
|
||||
//
|
||||
// Läuft wie alle plan-Module in einem IIFE; Zustand: window.PlanApp
|
||||
// (plan-state.js).
|
||||
|
||||
(function(){
|
||||
const app = window.PlanApp;
|
||||
|
||||
// projectVersions: alle Fassungen des aktuellen Projekts über alle
|
||||
// geladenen Sitzungen, chronologisch aufsteigend. Die eigentliche Logik
|
||||
// liegt seit der Kommentar-Überarbeitung in js/utils.js
|
||||
// (projectVersionsForUid), weil das Board sie ebenfalls braucht; hier bleibt
|
||||
// nur die Bindung an das aktuell geöffnete Projekt.
|
||||
function projectVersions(){
|
||||
return projectVersionsForUid(app.project && app.project.projectUid);
|
||||
}
|
||||
|
||||
// previousProjectVersion: die Fassung des Projekts aus der Sitzung
|
||||
// unmittelbar VOR der gerade geöffneten, oder null (früheste Sitzung bzw.
|
||||
// kein projectUid). Rückgabe: { week, project } | null.
|
||||
function previousProjectVersion(){
|
||||
const versions = projectVersions();
|
||||
const idx = versions.findIndex(v => app.week && v.week.label === app.week.label);
|
||||
return idx > 0 ? versions[idx - 1] : null;
|
||||
}
|
||||
|
||||
// previousPlannedProjectVersion: die jüngste frühere Fassung, die überhaupt
|
||||
// einen befüllten Terminplan hat (mindestens eine Aufgabe oder einen
|
||||
// Meilenstein). Grundlage für die Geister-Balken im GANTT.
|
||||
//
|
||||
// Warum nicht einfach previousProjectVersion(): In der Praxis gibt es
|
||||
// Sitzungen, in denen ein Projekt zwar geführt wird, aber (noch) keinen
|
||||
// Terminplan hat — etwa weil die Sitzung neu angelegt statt dupliziert
|
||||
// wurde. Ein Vergleich gegen so eine leere Fassung würde gar nichts
|
||||
// anzeigen und die Funktion wirkte kaputt, obwohl es zwei Sitzungen weiter
|
||||
// hinten sehr wohl Vergleichsdaten gibt. Deshalb wird rückwärts gesucht,
|
||||
// bis eine Fassung mit Planinhalt gefunden ist. Die gefundene Sitzung wird
|
||||
// in den Tooltips namentlich genannt, damit der Bezug nie unklar ist.
|
||||
// Rückgabe: { week, project } | null.
|
||||
function previousPlannedProjectVersion(){
|
||||
const versions = projectVersions();
|
||||
const idx = versions.findIndex(v => app.week && v.week.label === app.week.label);
|
||||
if(idx <= 0) return null;
|
||||
for(let i = idx - 1; i >= 0; i--){
|
||||
const plan = versions[i].project.plan;
|
||||
if(!plan) continue;
|
||||
const hasTodos = Array.isArray(plan.todos) && plan.todos.length > 0;
|
||||
const hasMilestones = Array.isArray(plan.milestones) && plan.milestones.length > 0;
|
||||
if(hasTodos || hasMilestones) return versions[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// historyEntries: die Verlaufsliste des aktuell geöffneten Projekts
|
||||
// (neueste zuerst, Wiederholungen desselben Textes gefiltert). Logik in
|
||||
// js/utils.js, siehe projectStatusHistory().
|
||||
function historyEntries(){
|
||||
return projectStatusHistory(app.project && app.project.projectUid);
|
||||
}
|
||||
|
||||
// renderPlanHistory: füllt die Kompakt-Karte "Verlauf" (#planHistorySummary
|
||||
// in Test.html) — Anzahl der Einträge und die Sitzung des letzten
|
||||
// Kommentarwechsels. Wird von renderPlanPage() (plan-state.js) nach dem
|
||||
// Laden aufgerufen. Keine Parameter, keine Rückgabe.
|
||||
window.renderPlanHistory = function(){
|
||||
const summaryEl = document.getElementById('planHistorySummary');
|
||||
if(!summaryEl || !app.project) return;
|
||||
|
||||
// Ein Sandbox-Plan der Planung lebt in genau einer, nie geklonten Sitzung
|
||||
// (SANDBOX_WEEK_LABEL) — es gibt also nie einen "Verlauf über mehrere
|
||||
// Sitzungen" zu zeigen, nur immer denselben einen Schnappschuss.
|
||||
if(app.isSandboxPlan && app.isSandboxPlan()){
|
||||
summaryEl.innerHTML = '<span class="hint">Kein Verlauf — dieser Terminplan gehört zu keiner Sitzung.</span>';
|
||||
return;
|
||||
}
|
||||
|
||||
if(!app.project.projectUid){
|
||||
summaryEl.innerHTML = '<span class="hint">Für dieses Projekt ist kein Verlauf verfügbar.</span>';
|
||||
return;
|
||||
}
|
||||
const entries = historyEntries();
|
||||
if(entries.length === 0){
|
||||
summaryEl.innerHTML = '<span class="hint">Noch keine Kommentare erfasst.</span>';
|
||||
return;
|
||||
}
|
||||
const latest = entries[0];
|
||||
const versionCount = projectVersions().length;
|
||||
summaryEl.innerHTML = `<div class="plan-mini-card-preview">${esc(latest.text)}</div>
|
||||
<div class="plan-mini-chip-row">
|
||||
<span class="plan-mini-chip">${entries.length} Eintrag${entries.length === 1 ? '' : 'e'}</span>
|
||||
<span class="plan-mini-chip">zuletzt ${esc(latest.week.label)}</span>
|
||||
<span class="plan-mini-chip">${versionCount} Sitzung${versionCount === 1 ? '' : 'en'}</span>
|
||||
</div>`;
|
||||
};
|
||||
|
||||
// openHistoryModal/closeHistoryModal: öffnen bzw. schließen das
|
||||
// Verlaufs-Modal (#planHistoryModal). Der Inhalt wird beim Öffnen frisch
|
||||
// aufgebaut, damit ein gerade im Projektinfo-Modal geänderter Kommentar
|
||||
// sofort mit auftaucht.
|
||||
window.openHistoryModal = function(){
|
||||
const listEl = document.getElementById('planHistoryList');
|
||||
if(listEl){
|
||||
if(!app.project || !app.project.projectUid){
|
||||
listEl.innerHTML = '<span class="hint">Dieses Projekt hat keine dauerhafte Projekt-Kennung und kann daher nicht über Sitzungen hinweg verfolgt werden.</span>';
|
||||
} else {
|
||||
// Dieselbe Darstellung wie im Wochenbericht und im Projektboard
|
||||
// (renderProjektVerlauf(), js/utils.js). Der Dialog hatte zuvor eine
|
||||
// eigene, enger gefasste Liste — sie zeigte nur Kommentartexte und
|
||||
// konnte dem Verlauf an den anderen Stellen widersprechen.
|
||||
//
|
||||
// weekLabel bleibt leer: Im Dialog gibt es keine "aktuelle" Fassung,
|
||||
// die auszulassen wäre — hier sollen ALLE Sitzungen erscheinen,
|
||||
// einschließlich der gerade geöffneten.
|
||||
listEl.innerHTML = renderProjektVerlauf(app.project, '', app.isLocked());
|
||||
}
|
||||
}
|
||||
document.getElementById('planHistoryModal').style.display = 'flex';
|
||||
};
|
||||
|
||||
window.closeHistoryModal = function(){
|
||||
document.getElementById('planHistoryModal').style.display = 'none';
|
||||
};
|
||||
|
||||
// Export für die anderen plan-Module (plan-gantt.js/plan-build-gantt.js:
|
||||
// Geister-Balken der letzten geplanten Sitzung).
|
||||
app.projectVersions = projectVersions;
|
||||
app.previousProjectVersion = previousProjectVersion;
|
||||
app.previousPlannedProjectVersion = previousPlannedProjectVersion;
|
||||
})();
|
||||
Reference in new issue
Block a user