v0.1.33 — Offboarding-Report und Update-Hinweis
Build & Release MSI / build-msi (push) Canceled after 0s
Build & Release MSI / build-msi (push) Canceled after 0s
- Offboarding: HTML-Report pro Geraet (New-OffboardHtmlReport) + reportUrl; Dialog-Ergebnis pro Geraet gruppiert + Report-Link - Update-Check: GET /api/update/check (Gitea releases/latest, Compare-SemVer); Kopfzeilen-Badge bei neuer Version, Link zur Release-Seite; optionaler read-only Token Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+42
-2
@@ -4784,6 +4784,24 @@ document.getElementById('btnRestoreColors')?.addEventListener('click', () => {
|
||||
// Init
|
||||
// =============================================================
|
||||
|
||||
// Prueft (nicht-blockierend) auf eine neuere Release-Version und zeigt bei Bedarf
|
||||
// das Update-Badge in der Kopfzeile mit Link zur Release-Seite.
|
||||
async function checkForUpdate() {
|
||||
try {
|
||||
const res = await api('/api/update/check');
|
||||
if (res && res.updateAvailable && res.releaseUrl) {
|
||||
const badge = document.getElementById('updateBadge');
|
||||
const txt = document.getElementById('updateBadgeText');
|
||||
if (badge && txt) {
|
||||
txt.textContent = `Update ${res.latest}`;
|
||||
badge.href = res.releaseUrl;
|
||||
badge.title = `Neue Version ${res.latest} verfügbar (aktuell ${res.current}) — Release-Seite öffnen`;
|
||||
badge.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
} catch (e) { /* still: Update-Check ist optional */ }
|
||||
}
|
||||
|
||||
(async function init() {
|
||||
renderConnection();
|
||||
renderTargets();
|
||||
@@ -4807,6 +4825,7 @@ document.getElementById('btnRestoreColors')?.addEventListener('click', () => {
|
||||
}
|
||||
await refreshStatus();
|
||||
refreshTenantSwitcher();
|
||||
checkForUpdate(); // nicht-blockierend
|
||||
if (State.connected) autoLoadAfterConnect();
|
||||
// First-Run: wenn kritische Felder leer sind, Settings-Modal automatisch oeffnen.
|
||||
if (setupNeeded) {
|
||||
@@ -7012,9 +7031,30 @@ async function offExecute() {
|
||||
try {
|
||||
const res = await api('/api/offboard/execute', { method: 'POST', body: { devices: payload, services }, timeoutMs: 180000 });
|
||||
const results = res.results || [];
|
||||
// Ergebnis pro Gerät gruppieren
|
||||
const byDev = new Map();
|
||||
for (const r of results) {
|
||||
if (!byDev.has(r.deviceName)) byDev.set(r.deviceName, []);
|
||||
byDev.get(r.deviceName).push(r);
|
||||
}
|
||||
const devHtml = [...byDev.entries()].map(([name, rows]) => {
|
||||
const errs = rows.filter(r => !r.success).length;
|
||||
const lines = rows.map(r =>
|
||||
`<div class="off-result ${r.success ? 'ok' : 'fail'}">${r.success ? '✓' : '✗'} ${escapeHtml(r.service)} ${escapeHtml(r.action)}${r.error ? ': ' + escapeHtml(r.error) : ''}</div>`
|
||||
).join('');
|
||||
return `<div class="off-result-dev">
|
||||
<div class="off-result-devname">${escapeHtml(name || '—')}${errs ? ` <span class="off-result-badge">${errs} Fehler</span>` : ''}</div>
|
||||
${lines}
|
||||
</div>`;
|
||||
}).join('');
|
||||
const reportLink = res.reportUrl
|
||||
? `<a href="${escapeHtml(res.reportUrl)}" target="_blank" rel="noopener" class="btn btn-secondary btn-sm" style="margin-top:12px;display:inline-flex;align-items:center;gap:6px;">
|
||||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><line x1="10" y1="9" x2="8" y2="9"/></svg>
|
||||
HTML-Report öffnen
|
||||
</a>`
|
||||
: '';
|
||||
document.getElementById('offResults').innerHTML =
|
||||
`<div class="lbl">Ergebnis (${res.successCount}/${res.total})</div>` +
|
||||
results.map(r => `<div class="off-result ${r.success ? 'ok' : 'fail'}">${r.success ? '✓' : '✗'} ${escapeHtml(r.deviceName)} — ${escapeHtml(r.service)} ${escapeHtml(r.action)}${r.error ? ': ' + escapeHtml(r.error) : ''}</div>`).join('');
|
||||
`<div class="lbl">Ergebnis (${res.successCount}/${res.total})</div>${devHtml}${reportLink}`;
|
||||
toast(`${res.successCount}/${res.total} Aktionen erfolgreich.`, res.successCount === res.total ? 'ok' : 'warn', 'Offboarding');
|
||||
// Erfolgreich vollständig offgeboardete Geräte aus der Liste nehmen.
|
||||
const doneNames = new Set(results.filter(r => r.success).map(r => r.deviceName));
|
||||
|
||||
Reference in New Issue
Block a user