DHCP: manuelle Reservierungen, Options-Schutz+Dropdown-UI, Lease-Countdown-Fix
1. Manuelle Reservierungen (dhcp_manual_reservations) fuer Geraete, die nicht als Client in dieser App gepflegt werden -- bewusst eine eigene, explizite Aktion (MAC/IP/Name), damit kein externes Geraet unueberwacht automatisch eine feste IP bekommt. _dhcp_reservation_candidates fuehrt automatische (aus devices) und manuelle Reservierungen jetzt zusammen, case-insensitiv nach MAC dedupliziert (automatisch gewinnt bei Konflikt). Automatische Reservierungen sind in der Tabelle nicht loeschbar (Schloss-Symbol statt Button, sie entstehen/verschwinden mit den Client-Stammdaten), manuelle schon. Live verifiziert: Hinzufuegen, doppelte MAC ablehnen, ungueltige MAC ablehnen, generierte Kea-Config mit gemischten Auto-/manuellen Reservierungen besteht kea-dhcp4 -t. 2. Standard-DHCP-Optionen um 10 weitere verifizierte Optionen erweitert (u.a. host-name/12 -- Kea-Name mit Bindestrich, NICHT "hostname", live gegen echtes Kea geprueft) -- jetzt 57 insgesamt. Standard-Optionen sind nicht mehr loeschbar (Backend lehnt es ab, UI zeigt ein Schloss-Symbol statt Loeschen-Button) -- vorher liess sich eine vorbefuellte Options- Definition versehentlich entfernen. 3. Options-Tabellen (global UND pro Reservierung) zeigen jetzt nur noch tatsaechlich genutzte Options -- eigene immer, Standard-Optionen nur mit gesetztem Wert. Weitere Standard-Optionen kommen ueber ein Dropdown "+ Option hinzufuegen" dazu statt permanent alle 57 als leere Felder zu zeigen. Das neu eingeblendete Feld wird automatisch in den sichtbaren Bereich gescrollt und fokussiert (bei bis zu 57 moeglichen Optionen kann das Feld sonst weit unterhalb des sichtbaren Modal-Ausschnitts liegen und es wirkt so, als waere nichts passiert). 4. Lease-Countdown-Fix: die Ablaufzeit wird jetzt explizit als UTC ausgewiesen (Kea arbeitet intern in UTC-Epoch) und zusaetzlich als live tickender Countdown angezeigt (gleiches Prinzip wie der bestehende "Naechste Pruefung"-Timer). Vorher wirkte eine reine Absolutzeit auf der nicht selbst aktualisierenden Seite bei den kurzen Standard-Lease-Zeiten (600s) schnell "schon abgelaufen", sobald etwas Zeit vergangen war, bis man tatsaechlich hinschaut -- live im echten Betrieb genau als dieses Missverstaendnis beobachtet und anhand der rohen Kea-CSV verifiziert, dass die richtige Spalte (expire) korrekt gelesen wird. 5. UI-Feinschliff: "In Datei schreiben" bei den Reservierungen heisst jetzt "Speichern" und ist der primaere (orange) Button, "Reservierung hinzufuegen" sekundaer -- das Hinzufuegen legt nur einen Datensatz an, erst "Speichern" schreibt die tatsaechlich wirksame Kea-Config. Alles live auf der Test-VM deployt und verifiziert (Playwright fuer die Dropdown-Sichtbarkeit/Fokus-Interaktion, curl fuer die Backend-Validierung, kea-dhcp4 -t fuer die generierte Konfiguration), keine Fehler im journalctl-Log.
This commit is contained in:
@@ -1202,6 +1202,7 @@ select {
|
||||
.mt-3 { margin-top: 14px; }
|
||||
.text-dim { color: var(--text-dim); }
|
||||
.text-faint { color: var(--text-faint); }
|
||||
.text-danger { color: var(--danger); }
|
||||
.hidden { display: none !important; }
|
||||
|
||||
/* ==========================================================================
|
||||
|
||||
@@ -201,6 +201,28 @@
|
||||
setTimeout(remove, 5000);
|
||||
};
|
||||
|
||||
/* Zeigt ein per Dropdown ausgewähltes, bis dahin verstecktes DHCP-Options-
|
||||
Feld (siehe settings_dhcp.html, "+ Option hinzufügen"-Auswahl bei
|
||||
Reservierungen) — so sind nur tatsächlich genutzte Options-Felder
|
||||
sichtbar, statt jede einzeln immer als leeres Eingabefeld anzuzeigen.
|
||||
Scrollt das neue Feld zusätzlich in den sichtbaren Bereich und fokussiert
|
||||
es — bei bis zu ~60 möglichen Optionen kann das neu eingeblendete Feld
|
||||
sonst weit unterhalb des sichtbaren Modal-Ausschnitts liegen und wirkt
|
||||
dann so, als wäre gar nichts passiert. */
|
||||
window.poeShowOptionField = function (select) {
|
||||
const id = select.value;
|
||||
if (id) {
|
||||
const field = document.getElementById(id);
|
||||
if (field) {
|
||||
field.style.display = "";
|
||||
field.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
const input = field.querySelector("input");
|
||||
if (input) input.focus();
|
||||
}
|
||||
select.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
function initFlashedMessages() {
|
||||
const data = document.getElementById("flashed-data");
|
||||
if (!data) return;
|
||||
@@ -384,9 +406,40 @@
|
||||
initNavGroups();
|
||||
initCheckTimer();
|
||||
initRunCheckNow();
|
||||
initLeaseCountdowns();
|
||||
initSortableTables();
|
||||
document.querySelectorAll("[data-theme-toggle]").forEach((btn) => btn.addEventListener("click", toggleTheme));
|
||||
});
|
||||
|
||||
/* ---------------- DHCP-Lease-Countdown (settings_dhcp.html) ---------------- */
|
||||
/* Ergänzt die absolute (UTC-)Ablaufzeit einer Lease um einen live tickenden
|
||||
Countdown — bei den kurzen Standard-Lease-Zeiten (600s) wirkt eine reine
|
||||
Absolutzeit sonst schnell "schon abgelaufen", sobald etwas Zeit vergangen
|
||||
ist, bis man die (nicht selbst aktualisierende) Seite tatsächlich
|
||||
anschaut. Gleiches Tick-Prinzip wie initCheckTimer oben. */
|
||||
function formatLeaseCountdown(remainingMs) {
|
||||
const abs = Math.abs(Math.round(remainingMs / 1000));
|
||||
const m = Math.floor(abs / 60);
|
||||
const s = abs % 60;
|
||||
const duration = m > 0 ? `${m}m ${s}s` : `${s}s`;
|
||||
return remainingMs >= 0 ? `läuft ab in ${duration}` : `abgelaufen vor ${duration}`;
|
||||
}
|
||||
|
||||
function initLeaseCountdowns() {
|
||||
const els = document.querySelectorAll(".lease-countdown");
|
||||
if (!els.length) return;
|
||||
function tick() {
|
||||
const now = Date.now();
|
||||
els.forEach((el) => {
|
||||
const expireMs = parseInt(el.dataset.expireMs, 10);
|
||||
if (isNaN(expireMs)) return;
|
||||
el.textContent = formatLeaseCountdown(expireMs - now);
|
||||
el.classList.toggle("text-danger", expireMs < now);
|
||||
});
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
}
|
||||
|
||||
window.PoeUI = { openModal, closeModal };
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user