feat: implement auto-save and persistence for rotation angle
Deploy Bürgerwind / deploy (push) Successful in 16s Details

This commit is contained in:
Johannes Baumeister 2026-04-28 13:43:09 +02:00
parent c6642c25fc
commit c182baf2bd
2 changed files with 56 additions and 36 deletions

40
app.js
View File

@ -396,6 +396,7 @@ document.addEventListener('DOMContentLoaded', async () => {
updateLabel(turbine, newGeoms); updateLabel(turbine, newGeoms);
updateProximityLines(); updateProximityLines();
updateLegend(); // Show symbols in legend updateLegend(); // Show symbols in legend
triggerAutoSave();
if (activeTurbine && activeTurbine.id === turbine.id) { if (activeTurbine && activeTurbine.id === turbine.id) {
// Keep fields updated // Keep fields updated
editNr.value = turbine.nr; editNr.value = turbine.nr;
@ -430,8 +431,11 @@ document.addEventListener('DOMContentLoaded', async () => {
updateRotationHandlePos(turbine); updateRotationHandlePos(turbine);
}); });
turbine.layers.rotationHandle.on('dragend', triggerAutoSave);
state.turbines.push(turbine); state.turbines.push(turbine);
updateProximityLines(); updateProximityLines();
triggerAutoSave();
if (!loadedNr) openEditPanel(turbine); if (!loadedNr) openEditPanel(turbine);
} }
@ -471,6 +475,7 @@ document.addEventListener('DOMContentLoaded', async () => {
activeTurbine.layers.mf.clearLayers().addData(geoms.mf); activeTurbine.layers.mf.clearLayers().addData(geoms.mf);
updateLabel(activeTurbine, geoms); updateLabel(activeTurbine, geoms);
updateProximityLines(); updateProximityLines();
triggerAutoSave();
document.getElementById('statusInfo').innerText = `WEA ${newNr} gespeichert.`; document.getElementById('statusInfo').innerText = `WEA ${newNr} gespeichert.`;
}; };
@ -481,6 +486,7 @@ document.addEventListener('DOMContentLoaded', async () => {
Object.values(activeTurbine.layers).forEach(l => variantLayers[activeTurbine.variant].removeLayer(l)); Object.values(activeTurbine.layers).forEach(l => variantLayers[activeTurbine.variant].removeLayer(l));
state.turbines = state.turbines.filter(t => t.id !== activeTurbine.id); state.turbines = state.turbines.filter(t => t.id !== activeTurbine.id);
updateProximityLines(); updateProximityLines();
triggerAutoSave();
closeEditPanel(); closeEditPanel();
} }
}; };
@ -1417,19 +1423,27 @@ document.addEventListener('DOMContentLoaded', async () => {
document.getElementById('statusInfo').innerText = "Projekt lokal exportiert."; document.getElementById('statusInfo').innerText = "Projekt lokal exportiert.";
}); });
const btnSaveDB = document.getElementById('btnSaveDB'); // DB Persistence
if (btnSaveDB) { let autoSaveTimeout = null;
btnSaveDB.addEventListener('click', async () => { function triggerAutoSave() {
const statusEl = document.getElementById('statusInfo'); if (autoSaveTimeout) clearTimeout(autoSaveTimeout);
statusEl.innerText = "Speichere in Datenbank..."; autoSaveTimeout = setTimeout(() => {
saveTurbinesToDB();
}, 1500); // 1.5 Seconds debounce
}
const projekt_id = "BWSamern-Ohne"; // Could be dynamic from config async function saveTurbinesToDB() {
const statusEl = document.getElementById('statusInfo');
if (statusEl) statusEl.innerText = "Automatische Speicherung...";
const projekt_id = "BWSamern-Ohne";
const turbineData = state.turbines.map(t => ({ const turbineData = state.turbines.map(t => ({
nr: t.nr, nr: t.nr,
variant: t.variant, variant: t.variant,
type: t.type, type: t.type,
rd: t.rd, rd: t.rd,
hh: t.hh, hh: t.hh,
ksfAngle: t.ksfAngle,
latlng: t.layers.marker.getLatLng() latlng: t.layers.marker.getLatLng()
})); }));
@ -1442,15 +1456,19 @@ document.addEventListener('DOMContentLoaded', async () => {
const result = await response.json(); const result = await response.json();
if (response.ok) { if (response.ok) {
statusEl.innerHTML = `<span style="color: #2ecc71;">${result.message}</span>`; if (statusEl) statusEl.innerHTML = `<span style="color: #2ecc71;">${result.message}</span>`;
} else { } else {
throw new Error(result.error || "Fehler beim Speichern in DB"); throw new Error(result.error || "Fehler beim Speichern in DB");
} }
} catch (err) { } catch (err) {
console.error(err); console.error(err);
statusEl.innerHTML = `<span style="color: #ff4444;">Fehler beim DB-Sync: ${err.message}</span>`; if (statusEl) statusEl.innerHTML = `<span style="color: #ff4444;">Auto-Save Fehler: ${err.message}</span>`;
} }
}); }
const btnSaveDB = document.getElementById('btnSaveDB');
if (btnSaveDB) {
btnSaveDB.addEventListener('click', saveTurbinesToDB);
} }
async function loadTurbinesFromDB() { async function loadTurbinesFromDB() {
@ -1475,7 +1493,8 @@ document.addEventListener('DOMContentLoaded', async () => {
nr: t.nr, nr: t.nr,
type: t.type, type: t.type,
rd: t.rd, rd: t.rd,
hh: t.hh hh: t.hh,
ksfAngle: t.ksfangle || t.ksfAngle
}); });
}); });
statusEl.innerText = `${dbTurbines.length} WEAs aus Datenbank geladen.`; statusEl.innerText = `${dbTurbines.length} WEAs aus Datenbank geladen.`;
@ -1536,6 +1555,7 @@ document.addEventListener('DOMContentLoaded', async () => {
updateProximityLines(); updateProximityLines();
updateLegend(); updateLegend();
triggerAutoSave();
document.getElementById('statusInfo').innerText = "Projekt geladen."; document.getElementById('statusInfo').innerText = "Projekt geladen.";
} catch (err) { } catch (err) {

View File

@ -75,9 +75,9 @@ app.post('/api/wea', async (req, res) => {
log(`Füge WEA ein: Nr=${t.nr}, Typ=${t.type}, Pos=${t.latlng?.lat},${t.latlng?.lng}`); log(`Füge WEA ein: Nr=${t.nr}, Typ=${t.type}, Pos=${t.latlng?.lat},${t.latlng?.lng}`);
await client.query( await client.query(
`INSERT INTO ${schema}.wea_standorte `INSERT INTO ${schema}.wea_standorte
(projekt_id, wea_nummer, anlagentyp, nabenhoehe, rotordurchmesser, geom) (projekt_id, wea_nummer, anlagentyp, nabenhoehe, rotordurchmesser, ksf_drehung, geom)
VALUES ($1, $2, $3, $4, $5, ST_Transform(ST_SetSRID(ST_MakePoint($6, $7), 4326), 25832))`, VALUES ($1, $2, $3, $4, $5, $6, ST_Transform(ST_SetSRID(ST_MakePoint($7, $8), 4326), 25832))`,
[targetProject, t.nr, t.type, t.hh, t.rd, t.latlng.lng, t.latlng.lat] [targetProject, t.nr, t.type, t.hh, t.rd, t.ksfAngle, t.latlng.lng, t.latlng.lat]
); );
} }
} }