fix: backup close button is now a STATIC element in overlay (never replaced by innerHTML)
CI / lint (push) Failing after 5s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / security (push) Failing after 11s

- Close button created once in createOverlay() as a static DOM element
  outside the panel, positioned absolutely (top-right corner)
- Never touched by setBody() innerHTML replacements
- Uses same class/id pattern as Graph View: editor-btn + backup-close
- Handler attached via addEventListener ONCE, never needs re-binding
- Removed all CLOSE_BTN from render functions (loading/error/empty/main)
This commit is contained in:
2026-06-04 16:36:37 -04:00
parent 05ac6cd756
commit 9f05059800
+19 -23
View File
@@ -83,6 +83,19 @@ function createOverlay() {
panel.id = 'backup-viewer-panel';
overlay.appendChild(panel);
// Close button OUTSIDE the panel — never touched by innerHTML, always present
const closeBtn = document.createElement('button');
closeBtn.className = 'editor-btn backup-close-btn';
closeBtn.id = 'backup-close';
closeBtn.title = 'Fermer';
closeBtn.style.cssText = 'position:absolute;top:12px;right:12px;z-index:1002;flex-shrink:0';
closeBtn.innerHTML = '<i data-lucide="x" style="width:15px;height:15px"></i>';
closeBtn.addEventListener('click', (e) => {
e.stopPropagation();
close();
});
overlay.appendChild(closeBtn);
// Keyboard: Escape closes the viewer
_escHandler = (e) => {
if (e.key === 'Escape' && state.overlay) close();
@@ -92,20 +105,10 @@ function createOverlay() {
return overlay;
}
/** Replace panel content and re-bind the close button. */
/** Replace panel content. Close button is static in the overlay, never replaced. */
function setBody(html) {
const panel = document.getElementById('backup-viewer-panel');
if (!panel) return;
panel.innerHTML = html;
safeCreateIcons();
// Bind close button — same pattern as AdminPanel
const closeBtn = panel.querySelector('.backup-close-btn');
if (closeBtn) {
closeBtn.addEventListener('click', (e) => {
e.stopPropagation();
close();
});
}
if (panel) panel.innerHTML = html;
}
let _escHandler = null;
@@ -127,14 +130,10 @@ function close() {
// Rendering
// ---------------------------------------------------------------------------
/** Close button HTML — same pattern as AdminPanel editor-btn */
const CLOSE_BTN = '<button class="backup-close-btn" title="Fermer"><i data-lucide="x" style="width:16px;height:16px"></i></button>';
function renderLoading() {
return `
<div class="backup-header">
<h3>Backups</h3>
${CLOSE_BTN}
</div>
<div class="backup-body">
<div class="tree-loading" style="padding:2rem;text-align:center">
@@ -145,10 +144,9 @@ function renderLoading() {
}
function renderError(msg) {
return `
return \`
<div class="backup-header">
<h3>Backups</h3>
${CLOSE_BTN}
</div>
<div class="backup-body" style="text-align:center;padding:2rem;color:var(--text-muted)">
<p>${escapeHtml(msg)}</p>
@@ -156,10 +154,9 @@ function renderError(msg) {
}
function renderEmpty() {
return `
return \`
<div class="backup-header">
<h3>Backups — ${escapeHtml(state.path)}</h3>
${CLOSE_BTN}
<h3>Backups — \${escapeHtml(state.path)}</h3>
</div>
<div class="backup-body" style="text-align:center;padding:2rem;color:var(--text-muted)">
<p>Aucun backup disponible pour ce fichier.</p>
@@ -189,8 +186,7 @@ function renderMainView() {
<span class="backup-file-path">${escapeHtml(state.path)}</span>
</div>
<div class="backup-header-right">
<span class="backup-count">${b.length} backup${b.length > 1 ? 's' : ''}</span>
${CLOSE_BTN}
<span class="backup-count">\${b.length} backup\${b.length > 1 ? 's' : ''}</span>
</div>
</div>