Protokoll-Import: KI-Erkennung (Gruppe, Teilnehmer, Status, Mehrfachpunkte), Ladeanzeige, Erstellungsdatum je Punkt
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6f18848f86
commit
11eabe42ae
275 files changed
+71952
-3029
No files matched your search
+56
-73
@@ -1,19 +1,16 @@
|
||||
// -----------------------------
|
||||
// Projektübersicht — GANTT-Diagramm (gemeinsam genutzt)
|
||||
// -----------------------------
|
||||
// Gemeinsames Modul für das GANTT-Diagramm: Es wird von Test.html (nach
|
||||
// js/load/load.js) UND von project-plan.html geladen – dort zusammen mit globals,
|
||||
// utils, ui, date-picker, csv, server und den js/plan/*-Modulen, aber OHNE
|
||||
// js/store.js, js/weeks.js, js/board/board.js usw. Es darf daher auf der Plan-Seite
|
||||
// keine Hauptseiten-spezifischen Funktionen voraussetzen; Funktionen, die
|
||||
// currentWeek()/isWeekLocked() aus js/weeks.js brauchen (renderGantt,
|
||||
// fitGanttRange, openProjectPlan), werden nur vom Hauptfenster aufgerufen.
|
||||
// Das Modul stellt u. a. buildGanttHtml(), renderGantt(), fitGanttRange(),
|
||||
// projectAssignees(), ganttRangeFromProjects() sowie openProjectPlan()/
|
||||
// findProjectForPlan() bereit. Die Plan-Seite erweitert buildGanttHtml() über
|
||||
// js/plan/plan-build-gantt.js und bezieht Beteiligte/Range über
|
||||
// projectAssignees()/ganttRangeFromProjects() aus diesem Modul.
|
||||
|
||||
// Gemeinsames Modul für das GANTT-Diagramm. Es wird von Test.html nach
|
||||
// js/load/load.js geladen und ist die Grundlage sowohl der Übersichts-
|
||||
// Diagramme als auch des Terminplans im Projektbereich: die Module unter
|
||||
// js/plan/ setzen darauf auf und müssen deshalb NACH dieser Datei stehen.
|
||||
// Das Modul stellt u. a. buildGanttHtml(), projectAssignees(),
|
||||
// ganttRangeFromProjects() sowie openProjectPlan()/closePlanPage()/
|
||||
// findProjectForPlan() bereit. js/plan/plan-build-gantt.js umhüllt
|
||||
// buildGanttHtml() und ergänzt sie um TODO- und Meilensteinzeilen; diese
|
||||
// Erweiterung greift nur bei gesetzter Option showTodos, die Aufrufe der
|
||||
// Übersicht bleiben also unverändert.
|
||||
// ganttModalProjectId: reservierte Projekt-ID für GANTT-Modal-Dialoge (zurzeit ungenutzt).
|
||||
let ganttModalProjectId = null;
|
||||
|
||||
@@ -35,7 +32,7 @@ function ensurePlan(p){
|
||||
function projectAssignees(p, week = null){
|
||||
const w = week || currentWeek();
|
||||
const people = w ? (w.people || []) : [];
|
||||
const globalList = db.globalPeople[currentDepartment] || [];
|
||||
const globalList = db.globalPeople || [];
|
||||
const result = [];
|
||||
people.forEach(person => {
|
||||
const globalPerson = globalList.find(gp => gp.id === person.id);
|
||||
@@ -63,7 +60,12 @@ function projectColor(p){
|
||||
// Projekt-/TODO-/Meilenstein-Terminen sowie den Abwesenheiten der globalen
|
||||
// Personen, jeweils erweitert um padDays Tage (Standard 7). Parameter:
|
||||
// projects = Projekt-Array, padDays = Puffer; Rückgabe: { start, end } als Date.
|
||||
function ganttRangeFromProjects(projects, padDays = 7){
|
||||
// Parameter `personIds` (optional): Beschränkt die berücksichtigten
|
||||
// Abwesenheiten auf diese Personen. Ohne die Einschränkung zog die Elternzeit
|
||||
// eines völlig unbeteiligten Kollegen den Zeitraum jedes Projektbereichs bis
|
||||
// weit in die Zukunft — obwohl die zugehörige Urlaubszeile gar nicht gezeichnet
|
||||
// wird (renderPlanGantt() filtert sie auf die Projektbeteiligten).
|
||||
function ganttRangeFromProjects(projects, padDays = 7, personIds = null){
|
||||
let min = null, max = null;
|
||||
projects.forEach(p => {
|
||||
const plan = p.plan;
|
||||
@@ -89,8 +91,10 @@ function ganttRangeFromProjects(projects, padDays = 7){
|
||||
});
|
||||
});
|
||||
});
|
||||
// Urlaub berücksichtigen
|
||||
(db.globalPeople[currentDepartment] || []).forEach(person => {
|
||||
// Urlaub berücksichtigen (nur von Personen, deren Zeilen auch gezeichnet werden)
|
||||
const relevant = personIds ? new Set(personIds) : null;
|
||||
(db.globalPeople || []).forEach(person => {
|
||||
if(relevant && !relevant.has(person.id)) return;
|
||||
(person.absences || []).forEach(a => {
|
||||
const s = parseDateISO(a.start), e = parseDateISO(a.end);
|
||||
if(s){ if(!min || s < min) min = s; if(!max || s > max) max = s; }
|
||||
@@ -105,37 +109,11 @@ function ganttRangeFromProjects(projects, padDays = 7){
|
||||
return { start: addDays(min, -padDays), end: addDays(max, padDays) };
|
||||
}
|
||||
|
||||
// fitGanttRange: setzt die Datumsfelder (ganttStart/ganttEnd) auf den
|
||||
// automatisch berechneten Projekt-Zeitrahmen und rendert das Diagramm neu.
|
||||
function fitGanttRange(){
|
||||
const w = currentWeek(); if(!w) return;
|
||||
const range = ganttRangeFromProjects(w.projects, 7);
|
||||
document.getElementById('ganttStart').value = formatDateISO(range.start);
|
||||
document.getElementById('ganttEnd').value = formatDateISO(range.end);
|
||||
renderGantt();
|
||||
}
|
||||
|
||||
// renderGantt: rendert das GANTT-Diagramm der aktuellen Woche in
|
||||
// ganttContainer. Nutzt die Datumsfelder bzw. fällt auf den Projekt-Zeitrahmen
|
||||
// zurück; bei gesperrter Woche ist die Ansicht nicht editierbar.
|
||||
function renderGantt(){
|
||||
const w = currentWeek();
|
||||
const container = document.getElementById('ganttContainer');
|
||||
if(!w || !container){
|
||||
if(container) container.innerHTML = '<div class="hint">Keine Sitzung ausgewählt.</div>';
|
||||
return;
|
||||
}
|
||||
let start = parseDateISO(document.getElementById('ganttStart').value);
|
||||
let end = parseDateISO(document.getElementById('ganttEnd').value);
|
||||
if(!start || !end){
|
||||
const range = ganttRangeFromProjects(w.projects, 7);
|
||||
start = range.start; end = range.end;
|
||||
document.getElementById('ganttStart').value = formatDateISO(start);
|
||||
document.getElementById('ganttEnd').value = formatDateISO(end);
|
||||
}
|
||||
const showVacation = document.getElementById('ganttShowVacation').checked;
|
||||
container.innerHTML = buildGanttHtml(w.projects, start, end, { showVacation, editable: !isWeekLocked(w) });
|
||||
}
|
||||
// HINWEIS: Die frühere GANTT-Ansicht der Hauptseite (renderGantt/fitGanttRange)
|
||||
// ist entfallen. Sie griff auf die Elemente #ganttContainer/#ganttStart/
|
||||
// #ganttEnd/#ganttShowVacation zu, die es in keiner der drei HTML-Seiten mehr
|
||||
// gibt — ein Aufruf hätte sofort geworfen. Das GANTT lebt heute ausschließlich
|
||||
// im Projektbereich (renderPlanGantt/fitPlanGanttRange in js/plan/plan-gantt.js).
|
||||
|
||||
// buildGanttHtml: erzeugt das HTML des GANTT-Diagramms (Kopf mit Monaten/
|
||||
// KW-Zellen, Wochenend-Hintergrund, Heute-Linie, Urlaubs- und Projektzeilen
|
||||
@@ -250,7 +228,7 @@ function buildGanttHtml(projects, start, end, options = {}){
|
||||
|
||||
// Urlaubszeilen
|
||||
if(showVacation){
|
||||
let allPeople = db.globalPeople[currentDepartment] || [];
|
||||
let allPeople = db.globalPeople || [];
|
||||
// Optional: nur Urlaub bestimmter Personen anzeigen
|
||||
if(options.vacationPeople && Array.isArray(options.vacationPeople)){
|
||||
const allowed = new Set(options.vacationPeople);
|
||||
@@ -327,35 +305,40 @@ function buildGanttHtml(projects, start, end, options = {}){
|
||||
|
||||
// ---------- Projektplan-Navigation ----------
|
||||
|
||||
// openProjectPlan: öffnet project-plan.html in einem neuen Tab. Weil
|
||||
// Projekt-IDs nicht persistent sind, werden Wochen-Label und Proj.-Nr. als
|
||||
// URL-Parameter übergeben; Abteilung und Projektname stehen im Pfad nach dem
|
||||
// Schema "/<Abteilung>/Projektplan/<Projektname>". Parameter: pid =
|
||||
// Projekt-ID der aktuellen Woche. Kein Rückgabewert.
|
||||
// openProjectPlan: öffnet den Projektbereich EINES Projekts. Das war einmal
|
||||
// eine Navigation auf ein eigenes Dokument (project-plan.html); inzwischen
|
||||
// ist der Projektbereich der Bereich #plan derselben Seite, also genügt ein
|
||||
// gewöhnlicher Bereichswechsel — Menüband und Seitenleiste bleiben stehen,
|
||||
// die Sitzungsdaten sind schon geladen, nichts blitzt weiß auf.
|
||||
// Weil Projekt-IDs beim Duplizieren einer Sitzung neu vergeben werden,
|
||||
// merkt sich der Bereich stabile Werte (Sitzungs-Label, Projekt-Nr./-Name);
|
||||
// aus ihnen baut updateRouteUrl() auch die verschickbare Adresse
|
||||
// "/Projektplan/<Projektname>?weekLabel=…&projNr=…".
|
||||
// Parameter: pid = Projekt-ID der aktuellen Sitzung. Kein Rückgabewert.
|
||||
function openProjectPlan(pid){
|
||||
const w = currentWeek(); if(!w) return;
|
||||
const p = w.projects.find(x => x.id === pid); if(!p) return;
|
||||
// Projekt-IDs sind in der DB stabil, aber die Plan-Seite ist eine separate
|
||||
// Route. Daher werden stabile Werte (Label, Projekt-Nr.) in der URL übergeben.
|
||||
// Absoluter Pfad mit Abteilung und Projektname als Route-Segment, damit der
|
||||
// Aufruf auch von Deep-Link-URLs wie "/HLS/Auslastung" funktioniert.
|
||||
const url = new URL('/' + currentDepartment + '/' + PLAN_SLUG + '/' + encodeURIComponent(p.name || ''), window.location.origin);
|
||||
url.searchParams.set('weekLabel', w.label);
|
||||
url.searchParams.set('projNr', p.nr || '');
|
||||
window.open(url.toString(), '_blank');
|
||||
setPlanTarget(w.label, p.nr || '', p.name || '');
|
||||
showTab('plan');
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
// Diese Funktion wird von project-plan.html aufgerufen, um das aktuelle
|
||||
// Wochen-/Projekt-Objekt im Hauptfenster zu finden.
|
||||
// Parameter: department, weekId, projectId; Rückgabe: { week, project } oder
|
||||
// null, wenn die Woche/Abteilung nicht (synchron) auflösbar ist.
|
||||
function findProjectForPlan(department, weekId, projectId){
|
||||
if(currentDepartment !== department){
|
||||
const targetWeek = db.weeks.find(w => w.id === weekId);
|
||||
if(!targetWeek) return null;
|
||||
// temporär umschalten ist unpraktisch, daher versuchen wir über load-all
|
||||
return null;
|
||||
}
|
||||
// closePlanPage: Gegenstück zu openProjectPlan() für den "Schließen"-Knopf
|
||||
// in der Kopfzeile des Projektbereichs. Früher ging es hier in der
|
||||
// Browser-Historie zurück, weil der Projektbereich ein eigenes Dokument war.
|
||||
// Jetzt ist es ein schlichter Bereichswechsel zurück auf das Projektboard
|
||||
// (bzw. auf den Bereich, aus dem geöffnet wurde). Kein Parameter, keine
|
||||
// Rückgabe.
|
||||
function closePlanPage(){
|
||||
const back = (typeof previousTab === 'string' && previousTab && previousTab !== 'plan') ? previousTab : 'board';
|
||||
showTab(back);
|
||||
}
|
||||
|
||||
// findProjectForPlan: findet Sitzung und Projekt anhand ihrer IDs im
|
||||
// geladenen Bestand.
|
||||
// Parameter: weekId, projectId; Rückgabe: { week, project } oder null, wenn
|
||||
// die Woche nicht auflösbar ist.
|
||||
function findProjectForPlan(weekId, projectId){
|
||||
const w = db.weeks.find(x => x.id === weekId);
|
||||
if(!w) return null;
|
||||
return { week: w, project: w.projects.find(x => x.id === projectId) };
|
||||
|
||||
Reference in new issue
Block a user