code auf einzelne Datein aufgeteilt
This commit is contained in:
1 parent
7451e0bf78
commit
8c94fc91f6
30 files changed
+5765
-27
No files matched your search
+165
@@ -0,0 +1,165 @@
|
||||
// -----------------------------
|
||||
// Projektübersicht — UI-Zustand (LocalStorage, Theme, Header)
|
||||
// -----------------------------
|
||||
// Diese Datei verwaltet den reinen UI-Zustand: gespeicherte Abteilung in
|
||||
// LocalStorage, den kollabierbaren Header sowie das Light/Dark-Theme. Sie wird
|
||||
// nach js/globals.js von beiden HTML-Einstiegspunkten geladen (Test.html und
|
||||
// project-plan.html). Die bereitgestellten Funktionen werden von js/init.js
|
||||
// beim Start sowie von js/tabs-auth.js (Tab-Wechsel, showTab) und js/store.js
|
||||
// (Abteilungswechsel, switchDepartment) aufgerufen; im Theme-Umschalter der
|
||||
// Seite werden toggleTheme/applyTheme direkt eingebunden.
|
||||
|
||||
// saveUiState: speichert Abteilung und aktiven Tab in den LocalStorage
|
||||
// Parameter: keine. Rückgabe: keine.
|
||||
function saveUiState(){
|
||||
try {
|
||||
const state = { department: currentDepartment, tab: currentTab };
|
||||
window.localStorage.setItem(STORAGE, JSON.stringify(state));
|
||||
} catch (err) {
|
||||
console.warn('UI-State kann nicht gespeichert werden:', err);
|
||||
}
|
||||
}
|
||||
|
||||
// loadUiState: stellt die zuletzt gewählte Abteilung aus dem LocalStorage wieder her
|
||||
// Parameter: keine. Rückgabe: keine (setzt currentDepartment aus js/globals.js).
|
||||
function loadUiState(){
|
||||
try {
|
||||
const state = JSON.parse(window.localStorage.getItem(STORAGE) || '{}');
|
||||
if(state.department && DEPARTMENTS[state.department]) currentDepartment = state.department;
|
||||
// Tab wird nicht aus dem localStorage wiederhergestellt, damit nach dem
|
||||
// Neuladen immer das Projektboard angezeigt wird.
|
||||
} catch (err) {
|
||||
console.warn('UI-State kann nicht geladen werden:', err);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Kollabierbarer Header ----------
|
||||
|
||||
// HEADER_COLLAPSED_KEY: LocalStorage-Key für den Einklapp-Zustand des Header-Menüs
|
||||
const HEADER_COLLAPSED_KEY = 'projuebersicht-header-collapsed';
|
||||
|
||||
// loadHeaderState: liest den gespeicherten Header-Zustand aus dem LocalStorage
|
||||
// Parameter: keine. Rückgabe: keine (wendet den Zustand per setHeaderCollapsed an).
|
||||
function loadHeaderState(){
|
||||
let collapsed = true; // Default: Menü ist beim ersten Start geschlossen
|
||||
try {
|
||||
const stored = window.localStorage.getItem(HEADER_COLLAPSED_KEY);
|
||||
if(stored !== null){
|
||||
collapsed = stored === 'true';
|
||||
}
|
||||
} catch (err) {}
|
||||
setHeaderCollapsed(collapsed, false);
|
||||
}
|
||||
|
||||
// saveHeaderState: speichert den Einklapp-Zustand des Headers im LocalStorage
|
||||
// Parameter: collapsed (Boolean). Rückgabe: keine.
|
||||
function saveHeaderState(collapsed){
|
||||
try {
|
||||
window.localStorage.setItem(HEADER_COLLAPSED_KEY, collapsed ? 'true' : 'false');
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
// setHeaderCollapsed: klappt das Header-Menü auf/zu und aktualisiert Icon und aria-Attribute
|
||||
// Parameter: collapsed (Boolean), persist (Boolean, ob in LocalStorage gespeichert wird). Rückgabe: keine.
|
||||
function setHeaderCollapsed(collapsed, persist){
|
||||
const menu = document.getElementById('headerMenu');
|
||||
const btn = document.querySelector('.header-bar .header-toggle');
|
||||
const icon = document.querySelector('.header-bar .header-toggle-icon');
|
||||
if(!menu) return;
|
||||
if(collapsed){
|
||||
menu.classList.remove('open');
|
||||
menu.setAttribute('aria-hidden', 'true');
|
||||
if(icon) icon.textContent = '☰';
|
||||
if(btn) btn.setAttribute('aria-expanded', 'false');
|
||||
} else {
|
||||
menu.classList.add('open');
|
||||
menu.setAttribute('aria-hidden', 'false');
|
||||
if(icon) icon.textContent = '✕';
|
||||
if(btn) btn.setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
if(persist) saveHeaderState(collapsed);
|
||||
}
|
||||
|
||||
// toggleHeader: klappt das Header-Menü zwischen offen und geschlossen um
|
||||
// Parameter: keine. Rückgabe: keine (persistiert den neuen Zustand).
|
||||
function toggleHeader(){
|
||||
const menu = document.getElementById('headerMenu');
|
||||
const isOpen = menu && menu.classList.contains('open');
|
||||
setHeaderCollapsed(isOpen, true);
|
||||
}
|
||||
|
||||
// ---------- Theme (Light/Dark) ----------
|
||||
|
||||
// applyThemeIcon: setzt das Sonne-/Mond-Icon passend zum effektiven Theme
|
||||
// Parameter: theme (String 'dark'/'light'). Rückgabe: keine.
|
||||
function applyThemeIcon(theme){
|
||||
const icon = document.getElementById('themeIcon');
|
||||
if(!icon) return;
|
||||
icon.textContent = theme === 'dark' ? '☀️' : '🌙';
|
||||
}
|
||||
|
||||
// loadTheme: liest das gespeicherte Theme aus dem LocalStorage und wendet es an
|
||||
// Parameter: keine. Rückgabe: keine.
|
||||
function loadTheme(){
|
||||
let theme = 'auto';
|
||||
try {
|
||||
theme = window.localStorage.getItem('projuebersicht-theme') || 'auto';
|
||||
} catch (err) {
|
||||
console.warn('Theme kann nicht geladen werden:', err);
|
||||
}
|
||||
applyTheme(theme, false);
|
||||
}
|
||||
|
||||
// saveTheme: speichert das gewählte Theme im LocalStorage
|
||||
// Parameter: theme (String 'auto'/'light'/'dark'). Rückgabe: keine.
|
||||
function saveTheme(theme){
|
||||
try {
|
||||
window.localStorage.setItem('projuebersicht-theme', theme);
|
||||
} catch (err) {
|
||||
console.warn('Theme kann nicht gespeichert werden:', err);
|
||||
}
|
||||
}
|
||||
|
||||
// effectiveTheme: ermittelt das tatsächlich verwendete Theme ('light'/'dark')
|
||||
// Parameter: theme (String 'auto'/'light'/'dark'). Rückgabe: 'dark' oder 'light'
|
||||
// (bei 'auto' anhand der Systemeinstellung).
|
||||
function effectiveTheme(theme){
|
||||
if(theme === 'dark') return 'dark';
|
||||
if(theme === 'light') return 'light';
|
||||
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
// applyTheme: setzt das data-theme-Attribut am html-Element und aktualisiert das Icon
|
||||
// Parameter: theme (String), persist (Boolean, ob in LocalStorage gespeichert wird). Rückgabe: keine.
|
||||
function applyTheme(theme, persist){
|
||||
const html = document.documentElement;
|
||||
const eff = effectiveTheme(theme);
|
||||
if(theme === 'dark') html.setAttribute('data-theme', 'dark');
|
||||
else if(theme === 'light') html.setAttribute('data-theme', 'light');
|
||||
else html.removeAttribute('data-theme');
|
||||
applyThemeIcon(eff);
|
||||
if(persist) saveTheme(theme);
|
||||
}
|
||||
|
||||
// toggleTheme: wechselt zwischen hellem und dunklem Theme und speichert die Auswahl
|
||||
// Parameter: keine. Rückgabe: keine.
|
||||
function toggleTheme(){
|
||||
const html = document.documentElement;
|
||||
const currentAttr = html.getAttribute('data-theme');
|
||||
const currentTheme = currentAttr || 'auto';
|
||||
const currentEffective = effectiveTheme(currentTheme);
|
||||
const next = currentEffective === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next, true);
|
||||
}
|
||||
|
||||
// Beim Wechsel der System-Farbschema-Einstellung wird das Theme im
|
||||
// "Auto"-Modus sofort neu angewendet (kein Neuladen nötig).
|
||||
if(window.matchMedia){
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(){
|
||||
let theme = 'auto';
|
||||
try {
|
||||
theme = window.localStorage.getItem('projuebersicht-theme') || 'auto';
|
||||
} catch (err) {}
|
||||
applyTheme(theme, false);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user