Geräte-Tab: Wipe-Aktion mit Benutzerdaten-Option, Suchfeld vergrößert
Wipe-Button mit eigenem Modal: Checkbox ob Benutzerdaten behalten werden (keepUserData). Suchfeld auf max-width 600px vergrößert. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+5
-1
@@ -1622,7 +1622,7 @@ function Invoke-DeviceActionEndpoint {
|
||||
if ($err) { return $err }
|
||||
|
||||
$action = [string]$Body.action
|
||||
$allowed = @('syncDevice','rebootNow','remoteLock','collectDiagnostics','rotateBitLockerKeys','retire','autopilotReset')
|
||||
$allowed = @('syncDevice','rebootNow','remoteLock','collectDiagnostics','rotateBitLockerKeys','retire','autopilotReset','wipe')
|
||||
if ($action -notin $allowed) {
|
||||
return @{ statusCode = 400; error = "Unbekannte Aktion: $action" }
|
||||
}
|
||||
@@ -1630,6 +1630,10 @@ function Invoke-DeviceActionEndpoint {
|
||||
if ($action -eq 'autopilotReset') {
|
||||
$uri = "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/$DeviceId/wipe"
|
||||
$bodyJson = '{"keepEnrollmentData":true,"keepUserData":false}'
|
||||
} elseif ($action -eq 'wipe') {
|
||||
$keepUserData = if ($Body.keepUserData) { 'true' } else { 'false' }
|
||||
$uri = "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/$DeviceId/wipe"
|
||||
$bodyJson = "{""keepEnrollmentData"":false,""keepUserData"":$keepUserData}"
|
||||
} else {
|
||||
$uri = "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/$DeviceId/$action"
|
||||
$bodyJson = '{}'
|
||||
|
||||
+49
-3
@@ -5395,6 +5395,25 @@ function devRenderDetail(d) {
|
||||
if (autopilotBtn) autopilotBtn.style.display = isWin ? '' : 'none';
|
||||
}
|
||||
|
||||
// Wipe-Dialog (Promise: true=keepUserData, false=löschen, null=abgebrochen)
|
||||
function devWipeDialog(deviceName) {
|
||||
return new Promise(resolve => {
|
||||
document.getElementById('wipeDeviceName').textContent = deviceName;
|
||||
document.getElementById('wipeKeepUserData').checked = false;
|
||||
const backdrop = document.getElementById('wipeModalBackdrop');
|
||||
backdrop.classList.remove('hidden');
|
||||
|
||||
const close = (result) => {
|
||||
backdrop.classList.add('hidden');
|
||||
resolve(result);
|
||||
};
|
||||
document.getElementById('wipeCancel').onclick = () => close(null);
|
||||
document.getElementById('wipeModalClose').onclick = () => close(null);
|
||||
document.getElementById('wipeConfirm').onclick = () => close(document.getElementById('wipeKeepUserData').checked);
|
||||
backdrop.onclick = (e) => { if (e.target === backdrop) close(null); };
|
||||
});
|
||||
}
|
||||
|
||||
// Aktion ausführen
|
||||
document.getElementById('devActions')?.addEventListener('click', async (e) => {
|
||||
const btn = e.target.closest('.dev-action-btn');
|
||||
@@ -5409,10 +5428,38 @@ document.getElementById('devActions')?.addEventListener('click', async (e) => {
|
||||
collectDiagnostics: 'Diagnose sammeln',
|
||||
rotateBitLockerKeys: 'BitLocker-Schlüssel rotieren',
|
||||
autopilotReset: 'Autopilot Reset',
|
||||
retire: 'Retire (MDM entfernen)'
|
||||
retire: 'Retire (MDM entfernen)',
|
||||
wipe: 'Wipe'
|
||||
};
|
||||
const isDangerous = action === 'retire' || action === 'autopilotReset';
|
||||
const devName = DevState.selected.DeviceName || DevState.selected.Id;
|
||||
|
||||
// Wipe: eigener Dialog mit Benutzerdaten-Option
|
||||
if (action === 'wipe') {
|
||||
const keepUserData = await devWipeDialog(devName);
|
||||
if (keepUserData === null) return;
|
||||
btn.disabled = true;
|
||||
const origText2 = btn.textContent.trim();
|
||||
btn.textContent = '…';
|
||||
try {
|
||||
await api(`/api/devices/${encodeURIComponent(DevState.selected.Id)}/action`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ action: 'wipe', keepUserData })
|
||||
});
|
||||
toast(`Wipe gesendet${keepUserData ? ' (Benutzerdaten behalten)' : ''}`, 'ok');
|
||||
DevState.items = DevState.items.filter(d => d.Id !== DevState.selected.Id);
|
||||
DevState.selected = null;
|
||||
document.getElementById('devDetail').classList.add('hidden');
|
||||
devApplyFilters();
|
||||
} catch (e) {
|
||||
toast(`Fehler bei Wipe: ${e}`, 'error');
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = origText2;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const isDangerous = action === 'retire' || action === 'autopilotReset';
|
||||
const dangerMsg = {
|
||||
retire: `ACHTUNG: "Retire" auf "${devName}" ausführen?\n\nDas MDM-Profil wird entfernt — Gerät wird nicht mehr verwaltet.`,
|
||||
autopilotReset: `ACHTUNG: "Autopilot Reset" auf "${devName}" ausführen?\n\nDas Gerät wird auf OOBE zurückgesetzt. Enrollment-Daten bleiben erhalten, Benutzerdaten werden gelöscht.`
|
||||
@@ -5431,7 +5478,6 @@ document.getElementById('devActions')?.addEventListener('click', async (e) => {
|
||||
});
|
||||
toast(`${labels[action]}: Aktion wurde gesendet`, 'ok');
|
||||
if (action === 'retire') {
|
||||
// Gerät aus Liste entfernen
|
||||
DevState.items = DevState.items.filter(d => d.Id !== DevState.selected.Id);
|
||||
DevState.selected = null;
|
||||
document.getElementById('devDetail').classList.add('hidden');
|
||||
|
||||
@@ -548,12 +548,37 @@
|
||||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14H6L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M9 6V4h6v2"/></svg>
|
||||
Retire
|
||||
</button>
|
||||
<button class="btn btn-danger btn-sm dev-action-btn" data-action="wipe" title="Gerät vollständig zurücksetzen (Wipe)">
|
||||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/></svg>
|
||||
Wipe
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- MODAL: Wipe -->
|
||||
<div class="modal-backdrop hidden" id="wipeModalBackdrop">
|
||||
<div class="modal" style="max-width:420px;">
|
||||
<div class="modal-header">
|
||||
<span class="modal-title">Gerät zurücksetzen (Wipe)</span>
|
||||
<button class="modal-close" id="wipeModalClose">×</button>
|
||||
</div>
|
||||
<div class="modal-body" style="padding:16px 20px;">
|
||||
<p style="margin:0 0 12px;font-size:13.5px;">ACHTUNG: Das Gerät <strong id="wipeDeviceName"></strong> wird vollständig zurückgesetzt und aus dem Enrollment entfernt.</p>
|
||||
<label style="display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;">
|
||||
<input type="checkbox" id="wipeKeepUserData">
|
||||
Benutzerdaten behalten (nur bei Windows Fresh Start)
|
||||
</label>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" id="wipeCancel">Abbrechen</button>
|
||||
<button class="btn btn-danger" id="wipeConfirm">Jetzt zurücksetzen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TOAST CONTAINER -->
|
||||
<div id="toasts" class="toasts"></div>
|
||||
|
||||
|
||||
+1
-1
@@ -5214,7 +5214,7 @@ body.read-only .app-row {
|
||||
border-bottom: 1px solid var(--hairline-soft);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.dev-toolbar .search-wrap { flex: 1; max-width: 380px; }
|
||||
.dev-toolbar .search-wrap { flex: 1; max-width: 600px; }
|
||||
.input-select {
|
||||
padding: 5px 8px;
|
||||
border: 1px solid var(--hairline);
|
||||
|
||||
Reference in New Issue
Block a user