diff --git a/dejacode/static/css/dejacode_bootstrap.css b/dejacode/static/css/dejacode_bootstrap.css index f49cb19d..70012bdf 100644 --- a/dejacode/static/css/dejacode_bootstrap.css +++ b/dejacode/static/css/dejacode_bootstrap.css @@ -159,6 +159,25 @@ table.text-break thead { .navbar #search-form { width: 350px; } +.nav-chip { + transition: background-color 0.15s ease, border-color 0.15s ease; +} +.nav-chip:hover, +.nav-chip:focus-visible { + background-color: rgba(255, 255, 255, 0.18) !important; + border-color: rgba(255, 255, 255, 0.5) !important; +} + +/* -- Side menu -- */ +#side-menu .nav-pills .nav-link.active { + color: #fff !important; +} +#side-menu .nav-link { + text-decoration: none; +} +#side-menu .nav-pills .nav-link:not(.active):hover { + background-color: var(--bs-tertiary-bg); +} /* -- Pagination -- */ nav ul.pagination .disabled { diff --git a/dejacode/static/js/dejacode_main.js b/dejacode/static/js/dejacode_main.js index b6df8b64..9be23ff1 100644 --- a/dejacode/static/js/dejacode_main.js +++ b/dejacode/static/js/dejacode_main.js @@ -128,6 +128,46 @@ function setupHTMX() { }); } +function setupSearchModal() { + const searchForm = document.getElementById('search-form'); + const searchInput = document.getElementById('search-input'); + const searchModal = document.getElementById('search-modal'); + + if (!searchModal) return; + + // Scope selector buttons + if (searchForm) { + document.querySelectorAll('.search-scope-btn').forEach(button => { + button.addEventListener('click', () => { + document.querySelectorAll('.search-scope-btn').forEach(b => b.classList.remove('active')); + button.classList.add('active'); + searchForm.setAttribute('action', button.dataset.scopeAction); + searchInput.focus(); + }); + }); + } + + // Autofocus input when modal opens + searchModal.addEventListener('shown.bs.modal', () => { + searchInput.focus(); + searchInput.select(); + }); + + // Keyboard shortcuts: Ctrl/Cmd+K and / to open the modal + document.addEventListener('keydown', (event) => { + const isTyping = ['INPUT', 'TEXTAREA', 'SELECT'].includes(document.activeElement.tagName) || document.activeElement.isContentEditable; + const modalInstance = bootstrap.Modal.getOrCreateInstance(searchModal); + + if ((event.ctrlKey || event.metaKey) && event.key === 'k') { + event.preventDefault(); + modalInstance.show(); + } else if (event.key === '/' && !isTyping) { + event.preventDefault(); + modalInstance.show(); + } + }); +} + document.addEventListener('DOMContentLoaded', () => { NEXB = {}; NEXB.client_data = JSON.parse(document.getElementById("client_data").textContent); @@ -157,17 +197,10 @@ document.addEventListener('DOMContentLoaded', () => { document.body.appendChild(overlay); } - // Search selection in the header - $('#search-selector-list a').click(function(event) { - event.preventDefault(); - $('#search-form').attr('action', $(this).attr('href')); - $('#search-selector-content').html($(this).html()); - $('#search-input').focus(); - }); - setupTooltips(); setupPopovers(); setupSelectionCheckboxes(); setupBackToTop(); setupHTMX(); + setupSearchModal(); }); diff --git a/dje/templates/bootstrap_base.html b/dje/templates/bootstrap_base.html index c8e22d99..ce0a3ad3 100644 --- a/dje/templates/bootstrap_base.html +++ b/dje/templates/bootstrap_base.html @@ -15,6 +15,9 @@ {% if FAVICON_HREF %}{% endif %}
+ {% block side_menu %} + {% include 'navbar/side_menu.html' %} + {% endblock %}