Compare commits

...

2 Commits

+110 -74
View File
@@ -177,29 +177,79 @@
} }
.navbar .container-fluid { .navbar .container-fluid {
gap: 10px; gap: 8px;
/* Ensure container respects safe areas on all sides */ /* Ensure container respects safe areas on all sides */
padding-left: max(env(safe-area-inset-left, 0), 16px); padding-left: max(env(safe-area-inset-left, 0), 12px);
padding-right: max(env(safe-area-inset-right, 0), 16px); padding-right: max(env(safe-area-inset-right, 0), 12px);
padding-bottom: env(safe-area-inset-bottom, 0); padding-bottom: env(safe-area-inset-bottom, 0);
} }
.navbar-brand { .navbar-brand {
font-weight: bold; font-weight: bold;
font-size: 1.4rem; font-size: 1.3rem;
padding-right: 10px;
white-space: nowrap;
flex-shrink: 0;
} }
.navbar-brand::before { .navbar-brand::before {
content: attr(data-icon); content: attr(data-icon);
margin-right: 8px; margin-right: 6px;
} }
.navbar-nav .nav-link { .navbar-nav .nav-link {
font-size: 1rem; font-size: 0.95rem;
font-weight: 600; font-weight: 600;
padding: 0.6rem 0.85rem; padding: 0.5rem 0.75rem;
border-radius: 8px; border-radius: 6px;
transition: padding .18s ease, font-size .18s ease; transition: padding .18s ease, font-size .18s ease;
white-space: nowrap;
}
/* iPad/Tablet responsive adjustments */
@media (max-width: 1024px) {
.navbar .container-fluid {
gap: 6px;
padding-left: max(env(safe-area-inset-left, 0), 10px);
padding-right: max(env(safe-area-inset-right, 0), 10px);
}
.navbar-brand {
font-size: 1.1rem;
padding-right: 8px;
}
.navbar-brand::before {
margin-right: 4px;
}
.navbar-nav .nav-link {
font-size: 0.85rem;
padding: 0.45rem 0.6rem;
}
}
/* Small phones responsive adjustments */
@media (max-width: 576px) {
.navbar .container-fluid {
gap: 4px;
padding-left: max(env(safe-area-inset-left, 0), 8px);
padding-right: max(env(safe-area-inset-right, 0), 8px);
}
.navbar-brand {
font-size: 0.95rem;
padding-right: 6px;
}
.navbar-brand::before {
display: none;
}
.navbar-nav .nav-link {
font-size: 0.75rem;
padding: 0.4rem 0.5rem;
}
} }
.navbar.nav-compact .navbar-brand { .navbar.nav-compact .navbar-brand {
@@ -861,25 +911,11 @@
<a class="nav-link {% if current_path == url_for('home') %}nav-active{% endif %}" href="{{ url_for('home') }}">Artikel</a> <a class="nav-link {% if current_path == url_for('home') %}nav-active{% endif %}" href="{{ url_for('home') }}">Artikel</a>
</li> </li>
{% endif %} {% endif %}
{% if 'username' in session %}
{% if current_permissions.pages.get('my_borrowed_items', True) %}
<li class="nav-item" data-nav-fixed="true">
<a class="nav-link quick-link-pill {% if current_path == url_for('my_borrowed_items') %}nav-active{% endif %}" href="{{ url_for('my_borrowed_items') }}">Meine Ausleihen</a>
</li>
{% endif %}
{% if current_permissions.pages.get('tutorial_page', True) %}
<li class="nav-item" data-nav-fixed="true">
<a class="nav-link quick-link-pill {% if current_path == url_for('tutorial_page') %}nav-active{% endif %}" href="{{ url_for('tutorial_page') }}">Tutorial</a>
</li>
{% endif %}
{% endif %}
{% if 'username' in session and current_permissions.pages.get('upload_admin', True) and current_permissions.actions.get('can_insert', True) %} {% if 'username' in session and current_permissions.pages.get('upload_admin', True) and current_permissions.actions.get('can_insert', True) %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link nav-priority-link {% if current_path == url_for('upload_admin') %}nav-active{% endif %}" href="{{ url_for('upload_admin') }}"> Hochladen</a> <a class="nav-link nav-priority-link {% if current_path == url_for('upload_admin') %}nav-active{% endif %}" href="{{ url_for('upload_admin') }}"> Hochladen</a>
</li> </li>
{% endif %} {% endif %}
<li class="nav-item"> <li class="nav-item">
<button id="themeToggleBtn" class="btn btn-link nav-link px-3" aria-label="Dark Mode umschalten" title="Theme umschalten"> <button id="themeToggleBtn" class="btn btn-link nav-link px-3" aria-label="Dark Mode umschalten" title="Theme umschalten">
<span class="theme-icon-light" style="display: none;">☀️</span> <span class="theme-icon-light" style="display: none;">☀️</span>
@@ -991,25 +1027,11 @@
<a class="nav-link {% if current_path == url_for('library_view') %}nav-active{% endif %}" href="{{ url_for('library_view') }}">Medien</a> <a class="nav-link {% if current_path == url_for('library_view') %}nav-active{% endif %}" href="{{ url_for('library_view') }}">Medien</a>
</li> </li>
{% endif %} {% endif %}
{% if 'username' in session %}
{% if current_permissions.pages.get('my_borrowed_items', True) %}
<li class="nav-item" data-nav-fixed="true">
<a class="nav-link quick-link-pill {% if current_path == url_for('my_borrowed_items') %}nav-active{% endif %}" href="{{ url_for('my_borrowed_items') }}">Meine Medien</a>
</li>
{% endif %}
{% if current_permissions.pages.get('tutorial_page', True) %}
<li class="nav-item" data-nav-fixed="true">
<a class="nav-link quick-link-pill {% if current_path == url_for('tutorial_page') %}nav-active{% endif %}" href="{{ url_for('tutorial_page') }}">Tutorial</a>
</li>
{% endif %}
{% endif %}
{% if 'username' in session and current_permissions.actions.get('can_insert', True) and current_permissions.pages.get('library_admin', True) %} {% if 'username' in session and current_permissions.actions.get('can_insert', True) and current_permissions.pages.get('library_admin', True) %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link nav-priority-link {% if current_path == url_for('library_admin') %}nav-active{% endif %}" href="{{ url_for('library_admin') }}">📖 Hochladen</a> <a class="nav-link nav-priority-link {% if current_path == url_for('library_admin') %}nav-active{% endif %}" href="{{ url_for('library_admin') }}">📖 Hochladen</a>
</li> </li>
{% endif %} {% endif %}
<li class="nav-item"> <li class="nav-item">
<button id="themeToggleBtn" class="btn btn-link nav-link px-3" aria-label="Dark Mode umschalten" title="Theme umschalten"> <button id="themeToggleBtn" class="btn btn-link nav-link px-3" aria-label="Dark Mode umschalten" title="Theme umschalten">
<span class="theme-icon-light" style="display: none;">☀️</span> <span class="theme-icon-light" style="display: none;">☀️</span>
@@ -1608,8 +1630,15 @@
const libraryNavList = document.getElementById('libraryNavList'); const libraryNavList = document.getElementById('libraryNavList');
const libNavOverflowAnchor = document.getElementById('lib-nav-overflow-anchor'); const libNavOverflowAnchor = document.getElementById('lib-nav-overflow-anchor');
function initNavbarOverflow(navList, navOverflowAnchor) { function initNavbarOverflow(navList, navOverflowAnchor, options) {
if (!navList || !navOverflowAnchor) return; if (!navList) return;
const moreToggleId = options && options.moreToggleId ? options.moreToggleId : '';
const moreToggle = moreToggleId ? document.getElementById(moreToggleId) : null;
const moreControlItem = moreToggle ? moreToggle.closest('li.nav-item.dropdown') : null;
const moreMenu = moreControlItem ? moreControlItem.querySelector(':scope > ul.dropdown-menu') : null;
const moreLabelDefault = moreToggle ? moreToggle.textContent.trim() : 'Mehr Optionen';
const moreMenuOriginal = moreMenu ? moreMenu.innerHTML : '';
const navRoot = navList.closest('nav.navbar'); const navRoot = navList.closest('nav.navbar');
const navCollapse = navList.closest('.navbar-collapse'); const navCollapse = navList.closest('.navbar-collapse');
@@ -1637,45 +1666,35 @@
return Array.from(navList.children).filter(function(li){ return Array.from(navList.children).filter(function(li){
if (!(li instanceof HTMLElement)) return false; if (!(li instanceof HTMLElement)) return false;
if (!li.classList.contains('nav-item')) return false; if (!li.classList.contains('nav-item')) return false;
if (li.id === navOverflowAnchor.id) return false; if (navOverflowAnchor && li.id === navOverflowAnchor.id) return false;
if (li.dataset.overflowControl === 'true') return false; if (li.dataset.overflowControl === 'true') return false;
if (li.dataset.navFixed === 'true') return false; if (li.dataset.navFixed === 'true') return false;
if (moreControlItem && li === moreControlItem) return false;
return li.style.display !== 'none'; return li.style.display !== 'none';
}); });
} }
function clearOverflowControls() { function clearOverflowControls() {
if (!navList) return; if (!moreMenu) return;
navList.querySelectorAll('[data-overflow-control="true"]').forEach(function(node){ moreMenu.innerHTML = moreMenuOriginal;
node.remove(); if (moreControlItem) {
}); moreControlItem.style.display = '';
}
if (moreToggle) {
moreToggle.textContent = moreLabelDefault;
}
} }
function restoreAllNavItems() { function restoreAllNavItems() {
if (!navList) return; if (!navList) return;
navList.querySelectorAll('li.nav-item').forEach(function(li){ navList.querySelectorAll('li.nav-item').forEach(function(li){
if (li.id === navOverflowAnchor.id) return; if (navOverflowAnchor && li.id === navOverflowAnchor.id) return;
if (li.dataset.overflowControl === 'true') return; if (li.dataset.overflowControl === 'true') return;
li.style.display = ''; li.style.display = '';
}); });
clearOverflowControls(); clearOverflowControls();
} }
function createOverflowControl() {
const li = document.createElement('li');
li.className = 'nav-item dropdown';
li.dataset.overflowControl = 'true';
const toggleId = navOverflowAnchor.id + '-toggle';
const menuId = navOverflowAnchor.id + '-menu';
li.innerHTML =
'<a class="nav-link dropdown-toggle" href="#" id="' + toggleId + '" role="button" data-bs-toggle="dropdown" aria-expanded="false" aria-controls="' + menuId + '">⋮ Weitere</a>' +
'<ul class="dropdown-menu" aria-labelledby="' + toggleId + '" id="' + menuId + '"></ul>';
return li;
}
function getNavCandidatePriority(item) { function getNavCandidatePriority(item) {
if (!(item instanceof HTMLElement)) { if (!(item instanceof HTMLElement)) {
return -1; return -1;
@@ -1758,29 +1777,46 @@
function rebuildOverflowControl(hiddenSources) { function rebuildOverflowControl(hiddenSources) {
clearOverflowControls(); clearOverflowControls();
if (!navList || !navOverflowAnchor || hiddenSources.length === 0) return; if (!moreMenu || hiddenSources.length === 0) return;
const control = createOverflowControl();
const menu = control.querySelector('ul.dropdown-menu');
const controlLink = control.querySelector(':scope > a.nav-link');
if (controlLink) {
controlLink.textContent = '⋮ Weitere (' + hiddenSources.length + ')';
}
const overflowFragment = document.createDocumentFragment();
hiddenSources.forEach(function(source){ hiddenSources.forEach(function(source){
appendSourceToOverflowMenu(source, menu); appendSourceToOverflowMenu(source, overflowFragment);
}); });
const trailingDivider = menu.querySelector('li:last-child .dropdown-divider'); const overflowWrap = document.createElement('div');
if (trailingDivider) { overflowWrap.appendChild(overflowFragment);
const trailingDivider = overflowWrap.querySelector('li:last-child .dropdown-divider');
if (trailingDivider && trailingDivider.parentElement) {
trailingDivider.parentElement.remove(); trailingDivider.parentElement.remove();
} }
navList.insertBefore(control, navOverflowAnchor); const overflowEntries = Array.from(overflowWrap.childNodes);
if (overflowEntries.length > 0) {
const marker = document.createElement('li');
marker.innerHTML = '<h6 class="dropdown-header">Ausgeblendete Navigation</h6>';
moreMenu.insertBefore(marker, moreMenu.firstChild);
overflowEntries.reverse().forEach(function(node){
moreMenu.insertBefore(node, marker.nextSibling);
});
const divider = document.createElement('li');
divider.innerHTML = '<hr class="dropdown-divider">';
moreMenu.insertBefore(divider, marker.nextSibling);
if (moreToggle) {
moreToggle.textContent = moreLabelDefault + ' (' + hiddenSources.length + ')';
}
}
if (moreControlItem) {
moreControlItem.style.display = '';
}
} }
function adaptNavbarByWidth() { function adaptNavbarByWidth() {
if (!navList || !navOverflowAnchor) return; if (!navList) return;
applyCompactMode(); applyCompactMode();
@@ -1845,12 +1881,12 @@
// Initialize overflow control for inventory navbar // Initialize overflow control for inventory navbar
if (navList && navOverflowAnchor) { if (navList && navOverflowAnchor) {
initNavbarOverflow(navList, navOverflowAnchor); initNavbarOverflow(navList, navOverflowAnchor, { moreToggleId: 'invMoreDropdown' });
} }
// Initialize overflow control for library navbar // Initialize overflow control for library navbar
if (libraryNavList && libNavOverflowAnchor) { if (libraryNavList && libNavOverflowAnchor) {
initNavbarOverflow(libraryNavList, libNavOverflowAnchor); initNavbarOverflow(libraryNavList, libNavOverflowAnchor, { moreToggleId: 'libMoreDropdown' });
} }
})(); })();
</script> </script>