feat: format empty partitions on system disk (v0.32.6)

Detect and offer to format empty (no filesystem) partitions on the system
disk. Adds IsSystemPartition() for granular per-partition safety checks
instead of blocking the entire system disk. Init wizard shows formatable
partitions with appropriate warnings. Add felhotest demo node to docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 16:54:16 +01:00
parent 2c0064ac87
commit b4bda38fa1
11 changed files with 270 additions and 39 deletions
@@ -146,27 +146,53 @@ function scanDisks() {
function renderScanResult(data) {
var availEl = document.getElementById('available-disks');
var sysEl = document.getElementById('system-disks-note');
var hasAvail = data.available && data.available.length > 0;
var hasFP = data.formatable_partitions && data.formatable_partitions.length > 0;
if (!data.available || data.available.length === 0) {
availEl.innerHTML = '<div class="empty-state" style="padding:1rem">Nem található inicializálható meghajtó.</div>';
if (!hasAvail && !hasFP) {
availEl.innerHTML = '<div class="empty-state" style="padding:1rem">Nem található inicializálható meghajtó vagy partíció.</div>';
} else {
var html = '<h4 style="margin-bottom:.75rem">Talált meghajtók (' + data.available.length + '):</h4>';
data.available.forEach(function(disk) {
var partInfo = '';
if (disk.Partitions && disk.Partitions.length > 0) {
partInfo = disk.Partitions.map(function(p) {
return p.Name + (p.FSType ? ' (' + p.FSType + ')' : ' (nincs fájlrendszer)') + (p.MountPoint ? ' → ' + p.MountPoint : '');
}).join(', ');
}
html += '<div class="storage-path-item" style="cursor:pointer;border:2px solid transparent" ' +
'onclick="selectDisk(this, \'' + disk.Path + '\', ' + JSON.stringify(disk.CreatePartition !== false) + ')" ' +
'data-path="' + disk.Path + '" id="disk-' + disk.Name + '">' +
'<div class="storage-path-header"><div class="storage-path-info">' +
'<span class="storage-path-label">○ ' + disk.Path + ' — ' + (disk.Size || '?') + '</span>' +
(disk.Model ? '<span class="storage-path-path">' + disk.Model + '</span>' : '') +
(partInfo ? '<span class="form-hint">' + partInfo + '</span>' : '<span class="form-hint">Nincs partíció</span>') +
'</div></div></div>';
});
var html = '';
if (hasAvail) {
html += '<h4 style="margin-bottom:.75rem">Talált meghajtók (' + data.available.length + '):</h4>';
data.available.forEach(function(disk) {
var partInfo = '';
if (disk.Partitions && disk.Partitions.length > 0) {
partInfo = disk.Partitions.map(function(p) {
return p.Name + (p.FSType ? ' (' + p.FSType + ')' : ' (nincs fájlrendszer)') + (p.MountPoint ? ' → ' + p.MountPoint : '');
}).join(', ');
}
html += '<div class="storage-path-item" style="cursor:pointer;border:2px solid transparent" ' +
'onclick="selectDisk(this, \'' + disk.Path + '\', true)" ' +
'data-path="' + disk.Path + '" id="disk-' + disk.Name + '">' +
'<div class="storage-path-header"><div class="storage-path-info">' +
'<span class="storage-path-label">○ ' + disk.Path + ' — ' + (disk.Size || '?') + '</span>' +
(disk.Model ? '<span class="storage-path-path">' + disk.Model + '</span>' : '') +
(partInfo ? '<span class="form-hint">' + partInfo + '</span>' : '<span class="form-hint">Nincs partíció</span>') +
'</div></div></div>';
});
}
if (hasFP) {
html += '<h4 style="margin-bottom:.75rem;margin-top:1.5rem">Formázható partíciók a rendszermeghajtón (' +
data.formatable_partitions.length + '):</h4>';
html += '<div class="alert alert-info" style="margin-bottom:.75rem;font-size:.85rem">' +
'Az alábbi partíciók a rendszermeghajtón találhatók, de nincsenek használatban. ' +
'Formázás után adattárolóként használhatók.</div>';
data.formatable_partitions.forEach(function(fp) {
var parentInfo = fp.ParentDiskPath + ' (' + fp.ParentDiskSize + ')';
if (fp.ParentDiskModel) parentInfo += ' — ' + fp.ParentDiskModel;
html += '<div class="storage-path-item" style="cursor:pointer;border:2px solid transparent" ' +
'onclick="selectDisk(this, \'' + fp.Path + '\', false)" ' +
'data-path="' + fp.Path + '">' +
'<div class="storage-path-header"><div class="storage-path-info">' +
'<span class="storage-path-label">○ ' + fp.Path + ' — ' + (fp.Size || '?') + '</span>' +
'<span class="form-hint">Rendszermeghajtó partíciója: ' + parentInfo + '</span>' +
'<span class="form-hint">Nincs fájlrendszer — formázásra kész</span>' +
'</div></div></div>';
});
}
availEl.innerHTML = html;
}
@@ -192,6 +218,20 @@ function selectDisk(el, path, needsPartition) {
document.getElementById('create-partition').value = needsPartition ? 'true' : 'false';
document.getElementById('selected-device-display').textContent = path;
// Update warning text based on whole-disk vs partition-only operation
var warningEl = document.querySelector('#wizard-configure .alert-error');
if (needsPartition) {
warningEl.innerHTML = '<strong>⚠️ FIGYELEM:</strong> A meghajtó <strong>ÖSSZES</strong> adata törlődik!<br>' +
'Ez a művelet <strong>NEM vonható vissza.</strong>';
} else {
warningEl.innerHTML = '<strong>⚠️ FIGYELEM:</strong> A partíció formázva lesz, a rajta lévő adatok törlődnek!<br>' +
'A rendszermeghajtó többi partíciója <strong>NEM</strong> érintett.';
}
// Show/hide the partitioning progress step
var partStep = document.getElementById('pstep-partitioning');
if (partStep) partStep.style.display = needsPartition ? '' : 'none';
// Show configure step
document.getElementById('wizard-configure').style.display = 'block';
document.getElementById('wizard-configure').scrollIntoView({behavior:'smooth'});