122 lines
5.2 KiB
JavaScript
122 lines
5.2 KiB
JavaScript
// -----------------------------
|
||
// Projektübersicht — allgemeine Helferfunktionen
|
||
// -----------------------------
|
||
// Diese Datei bündelt kleine, allgemein verwendbare Hilfsfunktionen (Escape-,
|
||
// ID-, Sortier- und Datumsfunktionen) und wird nach js/globals.js von beiden
|
||
// HTML-Einstiegspunkten geladen. Sie stellt ausschließlich globale Funktionen
|
||
// ohne eigenen Zustand bereit; genutzt wird sie praktisch von allen Modulen,
|
||
// u. a. js/csv.js, js/board/board.js, js/load/load.js sowie den Plan-Modulen unter js/plan/*
|
||
// (z. B. für ISO-Datumsformate und Werktage) und von js/gantt.js.
|
||
|
||
// departmentParam: gibt ein Query-String-Fragment fuer die aktuelle Abteilung zurueck.
|
||
// Parameter: keine. Rückgabe: String wie '?department=ELT'.
|
||
function departmentParam(){
|
||
return '?department=' + encodeURIComponent(currentDepartment);
|
||
}
|
||
|
||
// esc: einfache Escape-Funktion für Ausgabe in HTML
|
||
// Parameter: s (String). Rückgabe: HTML-sicherer String (&, <, >, " ersetzt).
|
||
function esc(s){ return (s||"").replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); }
|
||
|
||
// uid: generiert eine einfache, ausreichend eindeutige ID
|
||
// Parameter: keine. Rückgabe: String aus Zeitstempel und Zufallsteil.
|
||
function uid(){ return Date.now().toString(36)+Math.random().toString(36).slice(2,7); }
|
||
|
||
// assignKey: Schlüssel für Projektzuordnungen (Person + Rolle getrennt)
|
||
// Parameter: personId (String), role (String). Rückgabe: kombinierter Schlüssel 'personId|role'.
|
||
function assignKey(personId, role){ return personId + '|' + role; }
|
||
|
||
// sortGroups: sortiert Gruppen-Namen nach GROUP_ORDER, unbekannte ans Ende
|
||
// Parameter: arr (Array von Gruppennamen, wird in-place sortiert). Rückgabe: dasselbe Array.
|
||
function sortGroups(arr){
|
||
return arr.sort((a,b)=>{
|
||
const ia=GROUP_ORDER.indexOf(a), ib=GROUP_ORDER.indexOf(b);
|
||
return (ia===-1?999:ia)-(ib===-1?999:ib);
|
||
});
|
||
}
|
||
|
||
// Persistente ID fuer eine Person aus dem Kuerzel, damit Anwesenheit und
|
||
// Zuordnungen auch nach einem Neuladen stabil bleiben.
|
||
// Parameter: name (String). Rückgabe: String wie 'p_ab'.
|
||
function personIdForName(name){
|
||
return 'p_' + String(name).trim().toLowerCase().replace(/[^a-z0-9]/g,'_');
|
||
}
|
||
|
||
// formatWeekDate: wandelt ein ISO-Datum (YYYY-MM-DD) in deutsches Format DD.MM.YYYY um
|
||
// Parameter: dateString (String). Rückgabe: formatierter String oder leer.
|
||
function formatWeekDate(dateString){
|
||
if(!dateString) return '';
|
||
const parts = dateString.split('-');
|
||
if(parts.length!==3) return dateString;
|
||
return `${parts[2]}.${parts[1]}.${parts[0]}`;
|
||
}
|
||
|
||
// ---------- Datumshilfsfunktionen (GANTT) ----------
|
||
|
||
// parseDateISO: parst einen ISO-Datumsstring (YYYY-MM-DD) in ein Date-Objekt (lokal)
|
||
// Parameter: d (String). Rückgabe: Date-Objekt oder null bei ungültigem Format.
|
||
function parseDateISO(d){
|
||
if(!d) return null;
|
||
const m = String(d).match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
||
if(!m) return null;
|
||
const date = new Date(parseInt(m[1]), parseInt(m[2])-1, parseInt(m[3]));
|
||
if(isNaN(date.getTime())) return null;
|
||
return date;
|
||
}
|
||
|
||
// formatDateISO: formatiert ein Date-Objekt als ISO-Datum (YYYY-MM-DD)
|
||
// Parameter: d (Date). Rückgabe: String oder leer bei ungültigem Datum.
|
||
function formatDateISO(d){
|
||
if(!d || isNaN(d.getTime())) return '';
|
||
const y = d.getFullYear();
|
||
const m = String(d.getMonth()+1).padStart(2,'0');
|
||
const day = String(d.getDate()).padStart(2,'0');
|
||
return `${y}-${m}-${day}`;
|
||
}
|
||
|
||
// addDays: addiert n Tage zu einem Datum (ohne das Original zu verändern)
|
||
// Parameter: d (Date), n (Anzahl Tage). Rückgabe: neues Date-Objekt.
|
||
function addDays(d, n){
|
||
const res = new Date(d.getTime());
|
||
res.setDate(res.getDate() + n);
|
||
return res;
|
||
}
|
||
|
||
// daysBetween: Anzahl der Kalendertage zwischen zwei Daten
|
||
// Parameter: a, b (Date). Rückgabe: ganzzahlige Tagesdifferenz (b - a).
|
||
function daysBetween(a, b){
|
||
const ms = b.getTime() - a.getTime();
|
||
return Math.round(ms / (1000 * 60 * 60 * 24));
|
||
}
|
||
|
||
// workdaysBetween: Anzahl der Werktage (Mo–Fr) im Zeitraum inkl. Start- und Endtag.
|
||
// Wochenendtage (Sa/So) werden nicht mitgezählt – z.B. für die Auslastung.
|
||
// Parameter: a, b (Date). Rückgabe: Anzahl der Werktage oder 0 bei ungültigem Zeitraum.
|
||
function workdaysBetween(a, b){
|
||
if(!a || !b || b < a) return 0;
|
||
let count = 0;
|
||
let current = new Date(a.getTime());
|
||
while(current <= b){
|
||
const day = current.getDay();
|
||
if(day !== 0 && day !== 6) count++;
|
||
current = addDays(current, 1);
|
||
}
|
||
return count;
|
||
}
|
||
|
||
// formatDateDE: formatiert ein Date-Objekt als deutsches Datum (DD.MM.YYYY)
|
||
// Parameter: d (Date). Rückgabe: String oder leer bei ungültigem Datum.
|
||
function formatDateDE(d){
|
||
if(!d || isNaN(d.getTime())) return '';
|
||
return `${String(d.getDate()).padStart(2,'0')}.${String(d.getMonth()+1).padStart(2,'0')}.${d.getFullYear()}`;
|
||
}
|
||
|
||
// ISO-Kalenderwoche nach https://en.wikipedia.org/wiki/ISO_week_date
|
||
// Parameter: d (Date). Rückgabe: Kalenderwochennummer (1-53).
|
||
function getWeekNumber(d){
|
||
const date = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
|
||
const dayNum = date.getUTCDay() || 7;
|
||
date.setUTCDate(date.getUTCDate() + 4 - dayNum);
|
||
const yearStart = new Date(Date.UTC(date.getUTCFullYear(), 0, 1));
|
||
return Math.ceil((((date - yearStart) / 86400000) + 1) / 7);
|
||
} |