feat(sync): Frontend pusht Aenderungen und laedt Server-Stand beim Start

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kenearos 2026-07-07 15:59:48 +02:00
parent 787bc1416b
commit 67a3f4b546
4 changed files with 23 additions and 2 deletions

6
app.js
View file

@ -1230,7 +1230,11 @@ class DienstplanApp {
// Initialize app when DOM is ready
let app;
document.addEventListener('DOMContentLoaded', () => {
document.addEventListener('DOMContentLoaded', async () => {
if (window.DataSync) {
try { await window.DataSync.boot(); }
catch (e) { console.error('Sync-Boot fehlgeschlagen, App laeuft lokal weiter:', e); }
}
app = new DienstplanApp();
window.app = app;
});

View file

@ -326,6 +326,7 @@
<script src="variants.js"></script>
<script src="calculator.js"></script>
<script src="storage.js"></script>
<script src="sync.js"></script>
<script src="app.js"></script>
<script src="image-import.js"></script>
</body>

View file

@ -45,6 +45,7 @@ class DataStorage {
throw new TypeError('employees muss ein Array sein');
}
localStorage.setItem(this.STORAGE_KEY_EMPLOYEES, JSON.stringify(employees));
this._notifyChange();
} catch (e) {
console.error('Fehler beim Speichern der Mitarbeiter-Daten:', e);
throw e;
@ -117,6 +118,7 @@ class DataStorage {
throw new TypeError('duties muss ein gültiges Objekt sein');
}
localStorage.setItem(this.STORAGE_KEY_DUTIES, JSON.stringify(duties));
this._notifyChange();
} catch (e) {
console.error('Fehler beim Speichern der Dienst-Daten:', e);
throw e;
@ -285,6 +287,7 @@ class DataStorage {
if (!map[employeeName]) map[employeeName] = {};
map[employeeName][yearMonth] = Boolean(value);
localStorage.setItem(this.STORAGE_KEY_VACATION, JSON.stringify(map));
this._notifyChange();
} catch (e) {
console.error('Fehler beim Speichern des Urlaubsmodus:', e);
throw e;
@ -319,6 +322,16 @@ class DataStorage {
return map;
}
/**
* Signalisiert dem Sync-Layer eine Aenderung (falls vorhanden).
* Wird unterdrueckt, waehrend DataSync gerade Server-Daten uebernimmt.
*/
_notifyChange() {
if (typeof window !== 'undefined' && window.DataSync && !window.DataSync._applying) {
window.DataSync.push();
}
}
/**
* Clear all data
*/
@ -326,6 +339,7 @@ class DataStorage {
localStorage.removeItem(this.STORAGE_KEY_EMPLOYEES);
localStorage.removeItem(this.STORAGE_KEY_DUTIES);
localStorage.removeItem(this.STORAGE_KEY_VACATION);
this._notifyChange();
}
/**
@ -363,6 +377,7 @@ class DataStorage {
if (data.vacation && typeof data.vacation === 'object') {
localStorage.setItem(this.STORAGE_KEY_VACATION, JSON.stringify(data.vacation));
}
this._notifyChange();
return true;
} catch (e) {
console.error('Import failed:', e);

3
sw.js
View file

@ -1,4 +1,4 @@
const CACHE_NAME = 'dienstplan-pro-v4';
const CACHE_NAME = 'dienstplan-pro-v5';
const ASSETS = [
'./',
'./index.html',
@ -8,6 +8,7 @@ const ASSETS = [
'./variants.js',
'./holidays.js',
'./storage.js',
'./sync.js',
'./image-import.js'
];