Fix: Ausstehender Autosave ueberschrieb das geladene Projekt

Beim Laden eines Projekts blieb der alte Projektname stehen, wenn kurz
zuvor getippt wurde.

Ursache: projektLaden() brach den laufenden Autosave-Timer nicht ab.
Der feuerte 500 ms nach dem letzten Tastendruck, las die noch alten
Formularfelder aus und schrieb sie ueber den gerade geladenen Stand.
Anschliessend folgte ein location.reload(), der den ueberschriebenen
Stand anzeigte. Auf localhost war das Zeitfenster meist zu klein, ueber
LAN gegen den Container dagegen zuverlaessig zu treffen.

- projektLaden() und projektNeu() brechen saveTimeout und calcTimeout ab.
- /projekte/laden und /projekte/neu liefern den neuen Stand zurueck,
  das Frontend setzt die Felder direkt (neue Funktion standUebernehmen).
- Kein location.reload() mehr. Das beseitigt zusaetzlich die
  Formular-Wiederherstellung, mit der Firefox und Safari von Hand
  geaenderte Felder nach einem Reload zurueckholen -- betroffen waere
  genau das Projektnamen-Feld gewesen.

Reproduziert und gegengeprueft: mit der alten Reihenfolge schreibt der
Autosave "Projekt B" ueber das geladene "Projekt A"; mit dem Fix bleiben
Feld und Serverstand ueber mehrere Wechsel hinweg stabil.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Erik Thiele
2026-08-22 12:10:50 +02:00
parent 1b3ef82db4
commit ab6d02eccb
2 changed files with 45 additions and 7 deletions

View File

@@ -327,6 +327,10 @@ async function projektLaden() {
`Ungespeicherte Aenderungen gehen dabei verloren. Fortfahren?`)) {
return;
}
// Ausstehenden Autosave verwerfen: er wuerde sonst mit den ALTEN
// Formulardaten feuern und den gerade geladenen Stand ueberschreiben.
clearTimeout(saveTimeout);
clearTimeout(calcTimeout);
try {
const res = await fetch('/projekte/laden', {
method: 'POST',
@@ -338,13 +342,37 @@ async function projektLaden() {
showNotification(daten.error || 'Laden fehlgeschlagen');
return;
}
// Neu laden: die Positionskarten baut der Server-Datenblock auf.
location.reload();
standUebernehmen(daten.stand);
showNotification(`Projekt "${name}" geladen`);
} catch (e) {
showNotification('Laden fehlgeschlagen');
}
}
/** Uebernimmt einen vom Server gelieferten Projektstand in die Felder.
*
* Bewusst ohne location.reload(): Firefox und Safari stellen beim Reload
* von Hand geaenderte Formularfelder wieder her und wuerden damit den
* gerade geladenen Projektnamen sofort wieder ueberschreiben.
*/
function standUebernehmen(stand) {
if (!stand) return;
const nameFeld = document.getElementById('projekt-name');
if (nameFeld) nameFeld.value = stand.projektName || '';
const liste = document.getElementById('positionen-liste');
if (liste) {
liste.innerHTML = '';
const positionen = (stand.positionen && stand.positionen.length)
? stand.positionen
: [{ materialPreisProKg: 25, stueckzahl: 1 }];
positionen.forEach(positionAnlegen);
}
recalculate();
projekteAktualisieren();
}
/** Beginnt einen leeren Auftrag. Betriebswerte bleiben erhalten. */
async function projektNeu() {
// Offenen Autosave durchdruecken, damit der Server den wirklich
@@ -364,13 +392,17 @@ async function projektNeu() {
'Trotzdem neu anfangen?')) {
return;
}
clearTimeout(saveTimeout);
clearTimeout(calcTimeout);
try {
const res = await fetch('/projekte/neu', { method: 'POST' });
const daten = await res.json();
if (!res.ok) {
showNotification('Zuruecksetzen fehlgeschlagen');
return;
}
location.reload();
standUebernehmen(daten.stand);
showNotification('Neues Projekt begonnen');
} catch (e) {
showNotification('Zuruecksetzen fehlgeschlagen');
}