feat: add server-side device deletion
- add portal API and UI action to delete non-default devices - protect the configured portal default device from deletion - document that trip/history pages still scope to the single DEVICE_NAME Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -7,6 +7,7 @@ const createDeviceButton = document.getElementById('create-device-button');
|
||||
const newDeviceName = document.getElementById('new-device-name');
|
||||
const rotateKeyButton = document.getElementById('rotate-key-button');
|
||||
const requestSyncButton = document.getElementById('request-sync-button');
|
||||
const deleteDeviceButton = document.getElementById('delete-device-button');
|
||||
const copyCredentialsButton = document.getElementById('copy-credentials-button');
|
||||
|
||||
const selectedSummary = {
|
||||
@@ -64,6 +65,7 @@ function setFormEnabled(enabled) {
|
||||
}
|
||||
rotateKeyButton.disabled = !enabled;
|
||||
requestSyncButton.disabled = !enabled;
|
||||
deleteDeviceButton.disabled = !enabled;
|
||||
updateDirtyState();
|
||||
}
|
||||
|
||||
@@ -239,6 +241,36 @@ async function requestSync() {
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteDevice() {
|
||||
if (selectedDeviceId === null) return;
|
||||
const device = devices.find(candidate => candidate.id === selectedDeviceId);
|
||||
if (!device) return;
|
||||
if (!window.confirm(`Delete device "${device.name}" and all of its server-side trips, tracking logs, and dashcam files?`)) {
|
||||
return;
|
||||
}
|
||||
hideMessage();
|
||||
deleteDeviceButton.disabled = true;
|
||||
try {
|
||||
const response = await fetch(`/api/v1/portal/devices/${selectedDeviceId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
const payload = await response.json();
|
||||
if (!response.ok) {
|
||||
throw new Error(payload.error || 'Could not delete device.');
|
||||
}
|
||||
latestApiKey = '';
|
||||
credentialFields.apiKey.value = '';
|
||||
copyCredentialsButton.disabled = true;
|
||||
selectedDeviceId = null;
|
||||
await loadDevices();
|
||||
showMessage('Device deleted from the server.', 'success');
|
||||
} catch (error) {
|
||||
showMessage(error.message, 'danger');
|
||||
} finally {
|
||||
deleteDeviceButton.disabled = selectedDeviceId === null;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveConfig(event) {
|
||||
event.preventDefault();
|
||||
if (selectedDeviceId === null) return;
|
||||
@@ -284,6 +316,7 @@ form.addEventListener('submit', saveConfig);
|
||||
createDeviceButton.addEventListener('click', createDevice);
|
||||
rotateKeyButton.addEventListener('click', rotateKey);
|
||||
requestSyncButton.addEventListener('click', requestSync);
|
||||
deleteDeviceButton.addEventListener('click', deleteDevice);
|
||||
copyCredentialsButton.addEventListener('click', () => {
|
||||
copyCredentials().catch(error => showMessage(`Could not copy credentials: ${error.message}`, 'danger'));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user