feat: add enrollment ui to admin dashboard

This commit is contained in:
2025-12-31 00:56:33 +01:00
parent a3a7298447
commit 96d559f819

View File

@ -133,6 +133,20 @@
<p class="text-center text-muted mt-1">Lade Update-Status...</p>
</div>
<!-- Enrollment Section -->
<div id="enrollmentSection" class="hidden" style="margin-bottom: 1rem; padding: 1rem; background: rgba(255, 255, 255, 0.05); border-radius: var(--radius-sm); border: 1px dashed var(--color-border);">
<h4 style="margin-top: 0; margin-bottom: 0.5rem;"><i data-lucide="link"></i> Gerät registrieren (Enrollment)</h4>
<p class="text-muted" style="font-size: 0.875rem; margin-bottom: 0.5rem;">
Dieses Gerät ist noch nicht beim Update-Service registriert. Bitte geben Sie einen gültigen Enrollment-Token ein.
</p>
<form id="enrollmentForm" style="display: flex; gap: 0.5rem; align-items: center;">
<input type="text" id="enrollToken" placeholder="Enrollment-Token eingeben..." required style="flex: 1;" />
<button type="submit" class="small">
<i data-lucide="check"></i> Registrieren
</button>
</form>
</div>
<div class="grid">
<button id="checkUpdateBtn" type="button">
<i data-lucide="search"></i>
@ -395,6 +409,8 @@
// Update management
async function refreshUpdateStatus() {
const statusDiv = document.getElementById('updateStatus');
// Do not clear the div if we are just refreshing to avoid flickering, maybe?
// Actually, loading spinner is fine.
statusDiv.innerHTML = '<div class="spinner" style="margin: 0 auto;"></div><p class="text-center text-muted mt-1">Lade Update-Status...</p>';
try {
@ -408,12 +424,28 @@
? '<span class="badge error"><i data-lucide="x-circle"></i> Fehlgeschlagen</span>'
: '<span class="badge neutral"><i data-lucide="minus-circle"></i> Unbekannt</span>';
const enrolledBadge = data.enrolled
? '<span class="badge success"><i data-lucide="link"></i> Verbunden</span>'
: '<span class="badge warning"><i data-lucide="link-2-off"></i> Nicht registriert</span>';
// Toggle Enrollment Section
const enrollSection = document.getElementById('enrollmentSection');
if (data.enrolled) {
enrollSection.classList.add('hidden');
} else {
enrollSection.classList.remove('hidden');
}
statusDiv.innerHTML = `
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem;">
<div>
<div class="text-muted" style="font-size: 0.75rem; text-transform: uppercase; margin-bottom: 0.25rem;">Version</div>
<div style="color: var(--color-accent); font-weight: 600;">${data.current_version}</div>
</div>
<div>
<div class="text-muted" style="font-size: 0.75rem; text-transform: uppercase; margin-bottom: 0.25rem;">Registrierung</div>
<div>${enrolledBadge}</div>
</div>
<div>
<div class="text-muted" style="font-size: 0.75rem; text-transform: uppercase; margin-bottom: 0.25rem;">Letzter Status</div>
<div>${statusBadge}</div>
@ -637,6 +669,35 @@
document.getElementById('refreshLogsBtn').addEventListener('click', refreshUpdateLogs);
document.getElementById('enrollmentForm').addEventListener('submit', async (e) => {
e.preventDefault();
const tokenInput = document.getElementById('enrollToken');
const token = tokenInput.value.trim();
const btn = e.target.querySelector('button');
if (!token) return;
const originalHTML = btn.innerHTML;
btn.innerHTML = '<div class="spinner"></div> Registriere...';
btn.disabled = true;
try {
await api('/update/enroll', {
method: 'POST',
body: JSON.stringify({ enroll_token: token })
});
showToast('Gerät erfolgreich registriert!', 'success');
tokenInput.value = '';
await refreshUpdateStatus();
} catch (err) {
showToast('Registrierung fehlgeschlagen: ' + err.message, 'error');
} finally {
btn.innerHTML = originalHTML;
btn.disabled = false;
lucide.createIcons();
}
});
// Initialize
checkSession();
checkOidcStatus();