Feature: Konfig-Export/Import im Web UI (Einstellungen-Tab)

- GET /api/export-config → JSON-Download mit allen Geräten + MQTT (ohne Passwort)
- POST /api/import-config → Validierung + Übernahme + automatischer Neustart
- Einstellungen-Tab: Exportieren-Button + Importieren-Dateiauswahl
- btn-secondary CSS-Klasse hinzugefügt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
retr0
2026-04-27 13:06:54 +02:00
parent fe1bdb057d
commit 6ae2cbf2b2
2 changed files with 99 additions and 0 deletions
+46
View File
@@ -91,6 +91,8 @@
.btn-danger:hover { background: rgba(248,81,73,.1); }
.btn-primary { background: var(--accent); color: #000; border-color: var(--accent); font-weight: 700; }
.btn-primary:hover { opacity: .85; }
.btn-secondary { color: var(--blue); border-color: var(--blue); }
.btn-secondary:hover { background: rgba(88,166,255,.1); }
.inv-card-meta { font-size: 12px; color: var(--text-dim); line-height: 1.7; }
.add-btn { display: flex; align-items: center; justify-content: center; gap: 8px;
padding: 20px; background: var(--surface); border: 2px dashed var(--border);
@@ -189,6 +191,19 @@
<input type="password" id="cfg-mqtt-pass" placeholder="leer = unverändert"></div>
<button class="btn btn-primary" onclick="saveMqtt()">Speichern & Neu starten</button>
</div>
<div class="settings-section">
<h3>Konfiguration sichern</h3>
<p style="color:var(--text-dim);font-size:.85rem;margin:0 0 .75rem">Alle Geräte und MQTT-Einstellungen als JSON exportieren und bei einer Neuinstallation wieder einlesen.</p>
<div style="display:flex;gap:.5rem;flex-wrap:wrap">
<button class="btn btn-secondary" onclick="exportConfig()">&#8659; Exportieren</button>
<label class="btn btn-secondary" style="cursor:pointer">
&#8657; Importieren
<input type="file" id="import-file-input" accept=".json" style="display:none" onchange="importConfig(this)">
</label>
</div>
<div id="import-result" style="margin-top:.5rem;font-size:.85rem"></div>
</div>
</div>
</main>
@@ -529,6 +544,37 @@ async function saveMqtt() {
}
}
// ── Export / Import ───────────────────────────────────────────
function exportConfig() {
window.location.href = api("api/export-config");
}
async function importConfig(input) {
const file = input.files[0];
if (!file) return;
const resultEl = document.getElementById("import-result");
resultEl.textContent = "Wird geladen…";
resultEl.style.color = "var(--text-dim)";
try {
const text = await file.text();
const data = JSON.parse(text);
const res = await fetchJSON(api("api/import-config"), {
method: "POST", headers: {"Content-Type": "application/json"},
body: JSON.stringify(data),
});
resultEl.textContent = `${res.inverters} Gerät(e) importiert. Neustart läuft…`;
resultEl.style.color = "var(--green)";
showToast(`${res.inverters} Gerät(e) importiert`, "ok");
setTimeout(() => { loadSettings(); loadInverters(); }, 3000);
} catch(e) {
resultEl.textContent = `Fehler: ${e.message}`;
resultEl.style.color = "var(--red)";
showToast("Import fehlgeschlagen", "err");
}
input.value = "";
}
// ── Init ──────────────────────────────────────────────────────
(async () => {