Fix: pattern regex v-flag, help mobile: TOC accordion not slide-over, search always in TOC
CI / lint (push) Failing after 4s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / security (push) Successful in 9s

This commit is contained in:
2026-06-03 11:13:37 -04:00
parent baba4e9fc7
commit 227e157793
4 changed files with 33 additions and 79 deletions
+1 -5
View File
@@ -762,7 +762,7 @@
<div class="editor-modal" id="help-modal">
<div class="editor-container help-container">
<div class="editor-header">
<button class="help-hamburger" id="help-hamburger" title="Sommaire" aria-label="Afficher le sommaire" onclick="var n=document.getElementById('help-nav');var o=document.getElementById('help-nav-overlay');if(n){n.classList.toggle('open');if(o)o.classList.toggle('visible');var s=document.getElementById('help-nav-search');if(n.classList.contains('open')&&s)setTimeout(function(){s.focus()},150);document.body.style.overflow=n.classList.contains('open')?'hidden':''}">
<button class="help-hamburger" id="help-hamburger" title="Sommaire" aria-label="Afficher le sommaire" onclick="var n=document.getElementById('help-nav');if(n){n.style.display=n.style.display==='none'?'flex':'none'}">
<i data-lucide="menu" style="width:18px;height:18px"></i>
</button>
<div class="editor-title" id="help-title">Guide d'utilisation ObsiGate</div>
@@ -772,14 +772,10 @@
</button>
</div>
</div>
<div class="help-nav-overlay" id="help-nav-overlay" onclick="var n=document.getElementById('help-nav');var o=document.getElementById('help-nav-overlay');if(n)n.classList.remove('open');if(o)o.classList.remove('visible');document.body.style.overflow=''"></div>
<div class="editor-body help-body" id="help-body">
<nav class="help-nav" id="help-nav">
<div class="help-nav-header">
<div class="help-nav-title">Sommaire</div>
<button class="help-nav-close" id="help-nav-close" title="Fermer" aria-label="Fermer le sommaire" onclick="var n=document.getElementById('help-nav');var o=document.getElementById('help-nav-overlay');if(n)n.classList.remove('open');if(o)o.classList.remove('visible');document.body.style.overflow=''">
<i data-lucide="x" style="width:16px;height:16px"></i>
</button>
</div>
<div class="help-nav-search-wrap">
<input type="text" class="help-nav-search" id="help-nav-search" placeholder="Rechercher dans l'aide..." autocomplete="off" spellcheck="false">
+1 -1
View File
@@ -465,7 +465,7 @@ const AdminPanel = {
<div class="admin-form-card">
<h3>${title}</h3>
<form id="admin-user-form">
${!isEdit ? '<div class="form-group"><label>Nom d\'utilisateur</label><input type="text" name="username" required pattern="[a-zA-Z0-9_-]{2,32}" placeholder="username"></div>' : ""}
${!isEdit ? '<div class="form-group"><label>Nom d\'utilisateur</label><input type="text" name="username" required pattern="[a-zA-Z0-9_\-]{2,32}" placeholder="username"></div>' : ""}
<div class="form-group"><label>Nom affiché</label><input type="text" name="display_name" value="${isEdit ? user.display_name || "" : ""}"></div>
<div class="form-group"><label>${isEdit ? "Nouveau mot de passe (vide = inchangé)" : "Mot de passe"}</label><input type="password" name="password" ${!isEdit ? 'required minlength="8"' : ""} placeholder="${isEdit ? "Laisser vide pour ne pas changer" : "Min. 8 caractères"}"></div>
<div class="form-group"><label>Rôle</label><select name="role"><option value="user" ${isEdit && user.role === "user" ? "selected" : ""}>Utilisateur</option><option value="admin" ${isEdit && user.role === "admin" ? "selected" : ""}>Admin</option></select></div>
+16 -21
View File
@@ -195,6 +195,9 @@ function initHelpModal() {
modal.classList.add("active");
closeHeaderMenu();
safeCreateIcons();
// Reset TOC to CSS default (mobile: hidden, desktop: visible)
const nav = document.getElementById("help-nav");
if (nav) nav.style.display = '';
if (!helpNavInitialized) {
initHelpNavigation();
helpNavInitialized = true;
@@ -220,9 +223,6 @@ function initHelpNavigation() {
const navList = document.getElementById("help-nav-list");
const nav = document.getElementById("help-nav");
const searchInput = document.getElementById("help-nav-search");
const hamburger = document.getElementById("help-hamburger");
const navClose = document.getElementById("help-nav-close");
const overlay = document.getElementById("help-nav-overlay");
const helpContent = document.querySelector(".help-content");
if (!helpBody || !navList || !nav) return;
@@ -238,23 +238,16 @@ function initHelpNavigation() {
sectionTextCache[s.id] = (s.textContent || '').toLowerCase();
});
// ── Mobile: open/close TOC slide-over ──
function openTOC() {
nav.classList.add("open");
if (overlay) overlay.classList.add("visible");
if (searchInput) setTimeout(() => searchInput.focus(), 150);
document.body.style.overflow = "hidden";
}
function closeTOC() {
nav.classList.remove("open");
if (overlay) overlay.classList.remove("visible");
document.body.style.overflow = "";
}
// ── Mobile: simple display toggle ──
function isMobile() { return window.innerWidth <= 768; }
if (hamburger) hamburger.addEventListener("click", openTOC);
if (navClose) navClose.addEventListener("click", closeTOC);
if (overlay) overlay.addEventListener("click", closeTOC);
function toggleTOC() {
if (nav.style.display === 'none' || nav.style.display === '') {
nav.style.display = 'flex';
if (searchInput) setTimeout(() => searchInput.focus(), 150);
} else {
nav.style.display = 'none';
}
}
// ── Scroll to section ──
function scrollToSection(targetId) {
@@ -262,7 +255,7 @@ function initHelpNavigation() {
if (!section) return;
section.scrollIntoView({ behavior: "smooth", block: "start" });
section.setAttribute("tabindex", "-1");
if (isMobile()) closeTOC();
if (isMobile()) nav.style.display = 'none';
}
// ── Focus the content pane ──
@@ -281,7 +274,9 @@ function initHelpNavigation() {
// ── Focus TOC active link ──
function focusTOC() {
if (isMobile() && !nav.classList.contains("open")) openTOC();
if (isMobile() && (nav.style.display === 'none' || nav.style.display === '')) {
nav.style.display = 'flex';
}
const activeLink = navList.querySelector(".help-nav-link.active:not(.hidden)");
if (activeLink) { activeLink.focus(); return; }
const firstLink = navList.querySelector(".help-nav-link:not(.hidden)");
+15 -52
View File
@@ -2193,9 +2193,6 @@ select {
margin-right: 8px;
}
.help-hamburger:hover { color: var(--accent); border-color: var(--accent); }
.help-nav-overlay {
display: none;
}
.help-nav {
width: 260px;
min-width: 260px;
@@ -2227,19 +2224,6 @@ select {
letter-spacing: 0.05em;
color: var(--text-muted);
}
.help-nav-close {
display: none;
width: 32px; height: 32px;
padding: 0;
border: 1px solid var(--border);
border-radius: 6px;
background: transparent;
color: var(--text-secondary);
cursor: pointer;
align-items: center;
justify-content: center;
}
.help-nav-close:hover { color: var(--accent); border-color: var(--accent); }
.help-nav-search-wrap {
padding: 0 12px 8px;
flex-shrink: 0;
@@ -6449,49 +6433,28 @@ body.popup-mode .content-area {
border-radius: 0;
}
/* Hamburger visible on mobile */
.help-hamburger {
display: inline-flex;
}
/* TOC: slide-over from left */
.help-nav-overlay {
display: block;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.5);
z-index: 1100;
opacity: 0;
pointer-events: none;
transition: opacity 0.25s ease;
}
.help-nav-overlay.visible {
opacity: 1;
pointer-events: auto;
}
/* TOC: collapsible block at top (not slide-over) */
.help-nav {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 280px;
min-width: 280px;
max-height: 100vh;
height: 100vh;
z-index: 1200;
transform: translateX(-100%);
transition: transform 0.25s ease;
border-right: 1px solid var(--border);
box-shadow: 2px 0 16px rgba(0,0,0,0.3);
position: static;
width: 100%;
min-width: 100%;
max-height: none;
height: auto;
z-index: auto;
transform: none;
transition: none;
border-right: none;
border-bottom: 1px solid var(--border);
box-shadow: none;
flex-shrink: 0;
display: none; /* hidden by default on mobile */
}
.help-nav.open {
transform: translateX(0);
}
.help-nav-close {
display: inline-flex;
.help-nav-header {
padding: 10px 16px 6px;
}
/* Content full-width */