Implement backup upload and deletion functionality in eMMC provisioning dashboard: add API endpoints for uploading image files and deleting backups, enhance UI with upload button and delete options, and improve error handling for file operations. Update documentation to reflect new features.
This commit is contained in:
@@ -399,7 +399,11 @@
|
||||
|
||||
<!-- 3. Saved backups -->
|
||||
<section class="section">
|
||||
<h2 class="section-title">Saved backups <button type="button" class="btn btn-outline btn-sm" id="refreshBackupsBtn" title="Reload list">Refresh</button></h2>
|
||||
<h2 class="section-title">Saved backups
|
||||
<button type="button" class="btn btn-outline btn-sm" id="refreshBackupsBtn" title="Reload list">Refresh</button>
|
||||
<button type="button" class="btn btn-outline btn-sm" id="uploadImageBtn" title="Upload an image file">Upload image</button>
|
||||
<input type="file" id="uploadImageInput" accept=".img,.img.gz,.img.xz,image/*" style="display:none;" />
|
||||
</h2>
|
||||
<p id="goldenHint" class="backups-mono" style="margin-bottom:0.25rem;font-size:0.8rem;"></p>
|
||||
<p id="backupsDirHint" class="backups-mono" style="margin-bottom:0.75rem;font-size:0.75rem;color:var(--muted);"></p>
|
||||
<table class="backups-table" id="backupsTable">
|
||||
@@ -617,7 +621,8 @@
|
||||
compressBtn +
|
||||
'<button type="button" class="btn btn-primary btn-sm set-golden-btn" data-name="' + escapeHtml(b.name) + '">Set as golden</button> ' +
|
||||
'<button type="button" class="btn btn-outline btn-sm rename-file-btn" data-name="' + escapeHtml(b.name) + '" title="Rename file">Rename file</button> ' +
|
||||
'<a href="/api/backups/' + encodeURIComponent(b.name) + '" download class="btn btn-outline btn-sm download-link">Download</a>' +
|
||||
'<a href="/api/backups/' + encodeURIComponent(b.name) + '" download class="btn btn-outline btn-sm download-link">Download</a> ' +
|
||||
'<button type="button" class="btn btn-outline btn-sm delete-backup-btn" data-name="' + escapeHtml(b.name) + '" title="Delete this backup">Delete</button>' +
|
||||
'</td>';
|
||||
tbody.appendChild(tr);
|
||||
});
|
||||
@@ -626,6 +631,25 @@
|
||||
bindRenameFile();
|
||||
bindShrink();
|
||||
bindCompress();
|
||||
bindDeleteBackup();
|
||||
}
|
||||
|
||||
function bindDeleteBackup() {
|
||||
document.querySelectorAll('.delete-backup-btn').forEach(function(btn) {
|
||||
btn.onclick = function() {
|
||||
const name = btn.getAttribute('data-name');
|
||||
if (!confirm('Delete this backup? This cannot be undone.\n\n' + name)) return;
|
||||
btn.disabled = true;
|
||||
fetch('/api/backups/' + encodeURIComponent(name), { method: 'DELETE' })
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.ok) { fetchBackups(); fetchGoldenInfo(); }
|
||||
else alert(data.error || 'Failed');
|
||||
})
|
||||
.catch(function() { alert('Request failed'); })
|
||||
.finally(function() { btn.disabled = false; });
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function bindRenameFile() {
|
||||
@@ -901,6 +925,26 @@
|
||||
});
|
||||
var refreshBackupsBtn = document.getElementById('refreshBackupsBtn');
|
||||
if (refreshBackupsBtn) refreshBackupsBtn.onclick = function() { fetchBackups(); fetchGoldenInfo(); };
|
||||
var uploadImageBtn = document.getElementById('uploadImageBtn');
|
||||
var uploadImageInput = document.getElementById('uploadImageInput');
|
||||
if (uploadImageBtn && uploadImageInput) {
|
||||
uploadImageBtn.onclick = function() { uploadImageInput.click(); };
|
||||
uploadImageInput.onchange = function() {
|
||||
var file = uploadImageInput.files && uploadImageInput.files[0];
|
||||
if (!file) return;
|
||||
var fd = new FormData();
|
||||
fd.append('file', file);
|
||||
uploadImageBtn.disabled = true;
|
||||
fetch('/api/backups/upload', { method: 'POST', body: fd })
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(d) {
|
||||
if (d.ok) { fetchBackups(); fetchGoldenInfo(); alert('Uploaded: ' + (d.name || file.name)); }
|
||||
else alert(d.error || 'Upload failed');
|
||||
})
|
||||
.catch(function() { alert('Upload failed'); })
|
||||
.finally(function() { uploadImageBtn.disabled = false; uploadImageInput.value = ''; });
|
||||
};
|
||||
}
|
||||
|
||||
fetchStatus();
|
||||
fetchLog();
|
||||
|
||||
Reference in New Issue
Block a user