diff --git a/containers/libreportal/frontend/core/setup/css/setup-wizard.css b/containers/libreportal/frontend/core/setup/css/setup-wizard.css index 9f9e5b9..d8378ed 100755 --- a/containers/libreportal/frontend/core/setup/css/setup-wizard.css +++ b/containers/libreportal/frontend/core/setup/css/setup-wizard.css @@ -1268,36 +1268,15 @@ body.setup-wizard-open { .setup-storage-details:hover { background: rgba(255, 255, 255, 0.16); } .setup-storage-flags { opacity: 0.9; } -/* Modal */ -.setup-modal-backdrop { - position: fixed; inset: 0; z-index: 10000; - background: rgba(4, 20, 38, 0.62); - backdrop-filter: blur(3px); - display: flex; align-items: center; justify-content: center; - padding: 24px; -} -.setup-modal { - width: min(680px, 100%); - max-height: 82vh; - overflow: auto; - border-radius: 14px; - border: 1px solid rgba(255, 255, 255, 0.18); - background: rgba(12, 48, 84, 0.97); - box-shadow: 0 24px 64px rgba(0, 0, 0, 0.45); -} -.setup-modal-head { - display: flex; align-items: center; justify-content: space-between; - gap: 12px; padding: 16px 20px; - border-bottom: 1px solid rgba(255, 255, 255, 0.14); -} -.setup-modal-title { font-weight: 700; font-size: 1.05em; word-break: break-all; } -.setup-modal-close { - background: none; border: none; color: inherit; - font-size: 1.6em; line-height: 1; cursor: pointer; opacity: 0.75; -} -.setup-modal-close:hover { opacity: 1; } -.setup-modal-body { padding: 18px 20px 22px; } +/* The wizard is a full-screen overlay at z-index 9999; the shared modal sits at + 1100. A modal opened from inside the wizard therefore rendered BEHIND it and + looked like the Details button did nothing. Raise it only while the wizard is + up, so no other overlay's stacking is affected. */ +body.setup-wizard-open .eo-modal { z-index: 10000; } +/* Modal chrome comes from the shared eo-modal (core/overlays). Only the + storage-specific CONTENT styles below are ours — they render inside + .eo-modal-body. */ .setup-storage-spec { width: 100%; border-collapse: collapse; margin-bottom: 18px; } .setup-storage-spec th { text-align: left; font-weight: 500; opacity: 0.72; diff --git a/containers/libreportal/frontend/core/setup/js/setup-wizard.js b/containers/libreportal/frontend/core/setup/js/setup-wizard.js index d408710..99de880 100755 --- a/containers/libreportal/frontend/core/setup/js/setup-wizard.js +++ b/containers/libreportal/frontend/core/setup/js/setup-wizard.js @@ -504,14 +504,20 @@ class SetupWizard { } } - // Details modal: the technical spec, every check with its full explanation, - // and — when the drive isn\u2019t in fstab — the offer to make it permanent. + // Details modal — the technical spec, every check with its full explanation, + // and (when the drive isn't in fstab) the offer to make it permanent. + // + // Uses the shared openEoModal rather than a bespoke overlay. Two reasons: it + // is what every other modal in the WebUI looks like, and it appends to + // document.body — a hand-rolled position:fixed backdrop appended INSIDE the + // wizard container resolves against the wizard's containing block (it has a + // backdrop-filter), so it covered part of the screen instead of all of it. showStorageDetails(idx) { const c = this.storageCandidates[idx]; if (!c) return; const esc = (s) => this.escapeHtml(s); - const specRows = [ + const spec = [ ['Mount point', c.path], ['Device', c.device], ['Filesystem', c.fstype], @@ -523,7 +529,7 @@ class SetupWizard { ].map(([k, v]) => `${esc(k)}${esc(v)}`).join(''); const icon = { refuse: '\u26d4', warn: '\u26a0\ufe0f', info: '\u2705' }; - const checkRows = (c.checks || []).map(k => ` + const checks = (c.checks || []).map(k => `
  • ${icon[k.severity] || ''} @@ -532,64 +538,65 @@ class SetupWizard {
  • `).join(''); - const fstab = c.fstab_line ? ` -
    -
    Make this drive mount automatically
    -

    - The system doesn\u2019t mount this drive at boot, so apps stored on it won\u2019t start - until it is mounted again. LibrePortal can add it to /etc/fstab for you. -

    -
    ${esc(c.fstab_line)}
    - -

    - Written with nofail, so if the drive is missing the machine still boots - normally. Your current /etc/fstab is backed up first. -

    -
    ` : ''; + const parts = [ + window.eoSection ? window.eoSection('Drive', `${spec}
    `) + : `${spec}
    `, + window.eoSection ? window.eoSection('Checks', ``) + : ``, + ]; - const modal = document.createElement('div'); - modal.className = 'setup-modal-backdrop'; - modal.innerHTML = ` - `; + if (c.fstab_line) { + parts.push(` +
    +
    Make this drive mount automatically
    +

    + The system doesn\u2019t mount this drive at boot, so apps stored on it won\u2019t start + until it is mounted again. LibrePortal can add it to /etc/fstab for you. +

    +
    ${esc(c.fstab_line)}
    + +

    + Written with nofail, so if the drive is missing the machine still boots + normally. Your current /etc/fstab is backed up first. +

    +
    `); + } - const close = () => modal.remove(); - modal.addEventListener('click', (e) => { if (e.target === modal) close(); }); - modal.querySelector('.setup-modal-close').addEventListener('click', close); - document.addEventListener('keydown', function onKey(e) { - if (e.key === 'Escape') { close(); document.removeEventListener('keydown', onKey); } + // No openEoModal (shouldn't happen — index.html loads it before this file, + // but the wizard must not become unusable if it ever doesn't). + if (typeof window.openEoModal !== 'function') { + console.warn('[setup] openEoModal unavailable; skipping details modal'); + return; + } + + const m = window.openEoModal({ + id: 'lp-storage-details', + size: 'md', + title: c.path, + desc: `${c.size} drive \u00b7 ${c.free} free \u00b7 ${c.fstype}${c.removable ? ' \u00b7 removable' : ''}`, + body: parts.join(''), + actions: [{ label: 'Close', variant: 'secondary' }], }); - // Remember the fstab choice on the wizard, not in the DOM: the modal is - // destroyed on close and the choice has to survive to submit(). - const fstabBox = modal.querySelector('[data-storage-fstab]'); + // The choice is remembered on the wizard, not in the DOM: the modal is + // destroyed on close and this has to survive until submit(). + const fstabBox = m.bodyEl.querySelector('[data-storage-fstab]'); if (fstabBox) { fstabBox.addEventListener('change', () => { const path = fstabBox.dataset.storageFstab; this.fstabWanted = this.fstabWanted.filter(p => p !== path); if (fstabBox.checked) { this.fstabWanted.push(path); - // Adding it to fstab only makes sense if the drive is actually used. + // Mounting it at boot only means anything if the drive is used. const own = this.container.querySelector(`[data-storage-path="${CSS.escape(path)}"]`); if (own && !own.disabled) own.checked = true; } }); } - - this.container.appendChild(modal); } escapeHtml(s) {