diff --git a/app/templates/_header.html b/app/templates/_header.html index 3bc2933..3079bb1 100644 --- a/app/templates/_header.html +++ b/app/templates/_header.html @@ -6,18 +6,6 @@ Page active : `active_nav` (déduite du gabarit dans render()). Fil d'Ariane : `owner`+`repo` (board) ou `full_name` (projet). Le wallboard (TV) n'inclut pas ce partiel, volontairement. #} - {% set nav_groups = [ ("principal", "Principal", [ ("home", "/", "🏠", "Projets"), @@ -42,6 +30,37 @@ ("wall", "/wall", "🖥️", "Wallboard"), ]), ] %} +{% set active_group = namespace(key="principal") %} +{% for gkey, group, links in nav_groups %} + {% for key, href, icon, label in links %} + {% if active_nav == key %}{% set active_group.key = gkey %}{% endif %} + {% endfor %} +{% endfor %} +
diff --git a/static/js/nav.js b/static/js/nav.js index dcdb1d3..29e2622 100644 --- a/static/js/nav.js +++ b/static/js/nav.js @@ -43,46 +43,33 @@ }); } - /* Accordion sections: the closed set lives in body classes - (applied pre-paint by the bootstrap script in _header.html) - and is persisted here on every toggle. */ + /* Accordéon EXCLUSIF (0.22.0) : une seule section ouverte + à la fois. Ouvrir une section ferme les autres ; cliquer + la section ouverte la referme. L'état initial vient du + script d'amorce de _header.html (section de la page + courante ou choix mémorisé dans kanbante-nav-open). */ var groupBtns = document.querySelectorAll('[data-group-btn]'); - function persistClosedGroups() { - var closed = []; - groupBtns.forEach(function (btn) { - if (document.body.classList.contains('nav-closed-' + btn.getAttribute('data-group-btn'))) { - closed.push(btn.getAttribute('data-group-btn')); - } - }); - try { - localStorage.setItem('kanbante-nav-closed', JSON.stringify(closed)); - } catch (e) { /* non-fatal */ } - } function syncGroupBtn(btn) { var closed = document.body.classList.contains( 'nav-closed-' + btn.getAttribute('data-group-btn')); btn.setAttribute('aria-expanded', closed ? 'false' : 'true'); } + function setOpenGroup(openKey) { + groupBtns.forEach(function (btn) { + var key = btn.getAttribute('data-group-btn'); + document.body.classList.toggle('nav-closed-' + key, key !== openKey); + syncGroupBtn(btn); + }); + try { + localStorage.setItem('kanbante-nav-open', openKey); + } catch (e) { /* non-fatal */ } + } groupBtns.forEach(function (btn) { syncGroupBtn(btn); btn.addEventListener('click', function () { - document.body.classList.toggle( - 'nav-closed-' + btn.getAttribute('data-group-btn')); - syncGroupBtn(btn); - persistClosedGroups(); + var key = btn.getAttribute('data-group-btn'); + var isOpen = !document.body.classList.contains('nav-closed-' + key); + setOpenGroup(isOpen ? '' : key); }); }); - /* The section holding the current page is always opened. */ - var activeLink = document.querySelector('.sidebar .side-link.active'); - if (activeLink) { - var section = activeLink.closest('.side-section'); - if (section) { - var key = section.getAttribute('data-group'); - if (document.body.classList.contains('nav-closed-' + key)) { - document.body.classList.remove('nav-closed-' + key); - groupBtns.forEach(syncGroupBtn); - persistClosedGroups(); - } - } - } })();