D1 Part 3: unified drive view + overlay migration

- storage.html: the registry cards and the separate 'Meghajtók (ügynök
  nézet)' merge into ONE view. Each connected registry card gets an
  #agent-extra-<path> slot; the enrichment JS joins the agent /api/disks
  list on mount path and decorates the matching card in place (role tag
  via i-lock, drive class, durable-id mono line, agent-only
  register/eject/wipe actions). Two extra groups render below:
  'Rendszermeghajtók' (system/backup — read-only, lock tag, NO actions)
  and 'Nem regisztrált meghajtók' (unregistered user-data — register
  action only). Agent-down: one warn note into #agent-warn-note, all
  registry cards still render from server data (graceful degradation).
  The agent-view helpers now emit design-system .tag markup instead of
  .badge (roleTag/classTag/dataTag/regTag/appBackingTag); the 🔒 lock
  emoji is gone (sprite i-lock).
- Overlay migration: every native confirm()/prompt() on the four pages
  routes through a light .confirm-overlay dialog (openDialog; texts
  verbatim) — storage remove forms, netStorageRemove, storageMigrateAll,
  storageDisconnect, storageDecommission (migrate + the type-to-confirm
  anyway branch preserved like-for-like), storageReEnroll; and on the
  system page triggerUpdate + controller/server restart; on the security
  page the two geo Hungary-removal confirms. Scenario F grep: zero
  native confirm/prompt in the four templates.
- Deleted the now-orphaned .badge-lock/.lock-ico CSS (grep-zero first).
- Tests: no-native-confirm scan, agent-down warn-note static assertion;
  integrity gate stays green.
This commit is contained in:
2026-07-02 19:17:19 +02:00
parent f8e18a9ec9
commit cb6f04c8fc
5 changed files with 234 additions and 63 deletions
@@ -139,7 +139,24 @@
</div>
</div>
<div id="dialog-root"></div>
<script>
// Light overlay dialog (D1) — replaces the native blocking browser dialogs (same texts).
function escText(s){var d=document.createElement('div');d.textContent=String(s==null?'':s);return d.innerHTML;}
function closeDialog(){ var r=document.getElementById('dialog-root'); if(r) r.innerHTML=''; }
function openDialog(opts){
var root=document.getElementById('dialog-root');
if(!root) return;
root.innerHTML='<div class="confirm-overlay" onclick="if(event.target===this)document.getElementById(\'dialog-cancel\').click()"><div class="confirm-box">'
+'<h3>'+escText(opts.title||'Megerősítés')+'</h3>'
+'<p style="white-space:pre-line">'+escText(opts.message||'')+'</p>'
+'<div class="form-actions"><button id="dialog-go" class="btn btn-primary">'+escText(opts.confirmLabel||'Megerősítés')+'</button>'
+'<button type="button" class="btn btn-outline" id="dialog-cancel">Mégsem</button></div>'
+'</div></div>';
document.getElementById('dialog-go').onclick=function(){ closeDialog(); if(opts.onConfirm) opts.onConfirm(); };
document.getElementById('dialog-cancel').onclick=function(){ closeDialog(); if(opts.onCancel) opts.onCancel(); };
}
function checkUpdate() {
var btn = document.getElementById('btn-check-update');
var msg = document.getElementById('update-status-msg');
@@ -167,7 +184,11 @@ function checkUpdate() {
}
function triggerUpdate() {
if (!confirm('Biztosan frissíti a controllert?\n\nA folyamat alatt a vezérlőpult rövid időre elérhetetlenné válik.')) return;
openDialog({title:'Vezérlő frissítése', confirmLabel:'Frissítés',
message:'Biztosan frissíti a controllert?\n\nA folyamat alatt a vezérlőpult rövid időre elérhetetlenné válik.',
onConfirm:doTriggerUpdate});
}
function doTriggerUpdate() {
var btn = document.getElementById('btn-trigger-update');
var checkBtn = document.getElementById('btn-check-update');
var msg = document.getElementById('update-status-msg');
@@ -238,7 +259,11 @@ pollUntilBack();
<script>
function restartController() {
if (!confirm('Biztosan újraindítja a vezérlőt? A művelet néhány másodpercig tart, és a felület rövid időre elérhetetlen lesz.')) return;
openDialog({title:'Vezérlő újraindítása', confirmLabel:'Újraindítás',
message:'Biztosan újraindítja a vezérlőt? A művelet néhány másodpercig tart, és a felület rövid időre elérhetetlen lesz.',
onConfirm:doRestartController});
}
function doRestartController() {
var btn = document.getElementById('btn-restart-controller');
var status = document.getElementById('restart-status');
btn.disabled = true;
@@ -248,7 +273,11 @@ function restartController() {
.catch(function(){ pollRestart(0); }); // connection may drop as the process exits — poll regardless
}
function restartServer() {
if (!confirm('Biztosan újraindítja a kiszolgálót? Az alkalmazások és a vezérlőpult kb. 30 másodpercre elérhetetlenné válnak.')) return;
openDialog({title:'Kiszolgáló újraindítása', confirmLabel:'Újraindítás',
message:'Biztosan újraindítja a kiszolgálót? Az alkalmazások és a vezérlőpult kb. 30 másodpercre elérhetetlenné válnak.',
onConfirm:doRestartServer});
}
function doRestartServer() {
var btn = document.getElementById('btn-restart-server');
var status = document.getElementById('server-restart-status');
if (btn) btn.disabled = true;