Merge pull request #5363 from AntonKhorev/no-compact-nav-2
Dynamic "more" dropdown
This commit is contained in:
commit
9deb3293ed
4 changed files with 87 additions and 63 deletions
|
@ -90,21 +90,76 @@ $(document).ready(function () {
|
|||
// See https://turbo.hotwired.dev/reference/drive#turbo.session.drive
|
||||
Turbo.session.drive = false;
|
||||
|
||||
var headerWidth = 0,
|
||||
compactWidth = 0;
|
||||
const $expandedSecondaryMenu = $("header nav.secondary > ul"),
|
||||
$collapsedSecondaryMenu = $("#compact-secondary-nav > ul"),
|
||||
secondaryMenuItems = [],
|
||||
breakpointWidth = 768;
|
||||
let moreItemWidth = 0;
|
||||
|
||||
function updateHeader() {
|
||||
var windowWidth = $(window).width();
|
||||
|
||||
if (windowWidth < compactWidth) {
|
||||
$("body").removeClass("compact-nav").addClass("small-nav");
|
||||
} else if (windowWidth < headerWidth) {
|
||||
$("body").addClass("compact-nav").removeClass("small-nav");
|
||||
if (windowWidth < breakpointWidth) {
|
||||
$("body").addClass("small-nav");
|
||||
expandAllSecondaryMenuItems();
|
||||
} else {
|
||||
$("body").removeClass("compact-nav").removeClass("small-nav");
|
||||
$("body").removeClass("small-nav");
|
||||
const availableWidth = $expandedSecondaryMenu.width();
|
||||
secondaryMenuItems.forEach(function (item) {
|
||||
$(item[0]).remove();
|
||||
});
|
||||
let runningWidth = 0,
|
||||
i = 0,
|
||||
requiredWidth;
|
||||
for (; i < secondaryMenuItems.length; i++) {
|
||||
runningWidth += secondaryMenuItems[i][1];
|
||||
if (i < secondaryMenuItems.length - 1) {
|
||||
requiredWidth = runningWidth + moreItemWidth;
|
||||
} else {
|
||||
requiredWidth = runningWidth;
|
||||
}
|
||||
if (requiredWidth > availableWidth) {
|
||||
break;
|
||||
}
|
||||
expandSecondaryMenuItem($(secondaryMenuItems[i][0]));
|
||||
}
|
||||
for (; i < secondaryMenuItems.length; i++) {
|
||||
collapseSecondaryMenuItem($(secondaryMenuItems[i][0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function expandAllSecondaryMenuItems() {
|
||||
secondaryMenuItems.forEach(function (item) {
|
||||
expandSecondaryMenuItem($(item[0]));
|
||||
});
|
||||
}
|
||||
|
||||
function expandSecondaryMenuItem($item) {
|
||||
$item.children("a")
|
||||
.removeClass("dropdown-item")
|
||||
.addClass("nav-link")
|
||||
.addClass(function () {
|
||||
return $(this).hasClass("active") ? "text-secondary-emphasis" : "text-secondary";
|
||||
});
|
||||
$item.addClass("nav-item").insertBefore("#compact-secondary-nav");
|
||||
toggleCompactSecondaryNav();
|
||||
}
|
||||
|
||||
function collapseSecondaryMenuItem($item) {
|
||||
$item.children("a")
|
||||
.addClass("dropdown-item")
|
||||
.removeClass("nav-link text-secondary text-secondary-emphasis");
|
||||
$item.removeClass("nav-item").appendTo($collapsedSecondaryMenu);
|
||||
toggleCompactSecondaryNav();
|
||||
}
|
||||
|
||||
function toggleCompactSecondaryNav() {
|
||||
$("#compact-secondary-nav").toggle(
|
||||
$collapsedSecondaryMenu.find("li").length > 0
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Chrome 60 and later seem to fire the "ready" callback
|
||||
* before the DOM is fully ready causing us to measure the
|
||||
|
@ -112,20 +167,10 @@ $(document).ready(function () {
|
|||
* to defer the measurement slightly as a workaround.
|
||||
*/
|
||||
setTimeout(function () {
|
||||
$("header").children(":visible").each(function (i, e) {
|
||||
headerWidth += $(e).outerWidth();
|
||||
$expandedSecondaryMenu.find("li:not(#compact-secondary-nav)").each(function () {
|
||||
secondaryMenuItems.push([this, $(this).width()]);
|
||||
});
|
||||
|
||||
$("body").addClass("compact-nav");
|
||||
|
||||
$("header").children(":visible").each(function (i, e) {
|
||||
compactWidth += $(e).outerWidth();
|
||||
});
|
||||
|
||||
$("body").removeClass("compact-nav");
|
||||
|
||||
$("header").removeClass("text-nowrap");
|
||||
$("header nav.secondary > ul").removeClass("flex-nowrap");
|
||||
moreItemWidth = $("#compact-secondary-nav").width();
|
||||
|
||||
updateHeader();
|
||||
|
||||
|
|
|
@ -131,10 +131,6 @@ header {
|
|||
font-size: 14px;
|
||||
}
|
||||
|
||||
nav.primary {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.username {
|
||||
max-width: 12em;
|
||||
}
|
||||
|
@ -174,7 +170,11 @@ nav.primary {
|
|||
|
||||
nav.secondary {
|
||||
.nav-link {
|
||||
padding: 0.3rem;
|
||||
padding: 0 0.3rem;
|
||||
}
|
||||
|
||||
> ul {
|
||||
height: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,15 +191,6 @@ nav.primary, nav.secondary {
|
|||
display: none;
|
||||
}
|
||||
|
||||
body.compact-nav {
|
||||
#compact-secondary-nav {
|
||||
display: inline-block;
|
||||
}
|
||||
.compact-hide {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
body.small-nav {
|
||||
#menu-icon {
|
||||
display: block;
|
||||
|
@ -240,6 +231,10 @@ body.small-nav {
|
|||
nav.secondary {
|
||||
flex-direction: column;
|
||||
|
||||
> ul {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.user-menu, .login-menu {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ module ApplicationHelper
|
|||
end
|
||||
|
||||
def header_nav_link_class(path)
|
||||
["nav-link", current_page?(path) ? "text-secondary-emphasis" : "text-secondary"]
|
||||
["nav-link", current_page?(path) ? "active text-secondary-emphasis" : "text-secondary"]
|
||||
end
|
||||
|
||||
def application_data
|
||||
|
|
|
@ -27,59 +27,43 @@
|
|||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<nav class='secondary d-flex gap-2 align-items-center'>
|
||||
<ul class='nav flex-nowrap'>
|
||||
<nav class='secondary d-flex gap-2 flex-grow-1 align-items-center'>
|
||||
<ul id='secondary-nav-menu' class='nav flex-grow-1' data-turbo-permanent>
|
||||
<% if Settings.status != "database_offline" && can?(:index, Issue) %>
|
||||
<li class="compact-hide nav-item">
|
||||
<li class="nav-item">
|
||||
<%= link_to issues_path(:status => "open"), :class => header_nav_link_class(issues_path) do %>
|
||||
<%= t("layouts.issues") %>
|
||||
<%= open_issues_count %>
|
||||
<% end -%>
|
||||
</li>
|
||||
<% end %>
|
||||
<li class="compact-hide nav-item">
|
||||
<li class="nav-item">
|
||||
<%= link_to t("layouts.history"), history_path, :class => header_nav_link_class(history_path) %>
|
||||
</li>
|
||||
<li class="compact-hide nav-item">
|
||||
<li class="nav-item">
|
||||
<%= link_to t("layouts.export"), export_path, :class => header_nav_link_class(export_path) %>
|
||||
</li>
|
||||
<li class="compact-hide nav-item">
|
||||
<li class="nav-item">
|
||||
<%= link_to t("layouts.gps_traces"), traces_path, :class => header_nav_link_class(traces_path) %>
|
||||
</li>
|
||||
<li class="compact-hide nav-item">
|
||||
<li class="nav-item">
|
||||
<%= link_to t("layouts.user_diaries"), diary_entries_path, :class => header_nav_link_class(diary_entries_path) %>
|
||||
</li>
|
||||
<li class="compact-hide nav-item">
|
||||
<li class="nav-item">
|
||||
<%= link_to t("layouts.communities"), communities_path, :class => header_nav_link_class(communities_path) %>
|
||||
</li>
|
||||
<li class="compact-hide nav-item">
|
||||
<li class="nav-item">
|
||||
<%= link_to t("layouts.copyright"), copyright_path, :class => header_nav_link_class(copyright_path) %>
|
||||
</li>
|
||||
<li class="compact-hide nav-item">
|
||||
<li class="nav-item">
|
||||
<%= link_to t("layouts.help"), help_path, :class => header_nav_link_class(help_path) %>
|
||||
</li>
|
||||
<li class="compact-hide nav-item">
|
||||
<li class="nav-item">
|
||||
<%= link_to t("layouts.about"), about_path, :class => header_nav_link_class(about_path) %>
|
||||
</li>
|
||||
<li id="compact-secondary-nav" class="dropdown nav-item">
|
||||
<li id="compact-secondary-nav" class="dropdown nav-item ms-auto">
|
||||
<button class="dropdown-toggle nav-link btn btn-outline-secondary border-0 bg-body text-secondary" type="button" data-bs-toggle="dropdown"><%= t "layouts.more" %></button>
|
||||
<ul class="dropdown-menu">
|
||||
<% if Settings.status != "database_offline" && can?(:index, Issue) %>
|
||||
<li>
|
||||
<%= link_to issues_path(:status => "open"), :class => "dropdown-item" do %>
|
||||
<%= t("layouts.issues") %>
|
||||
<%= open_issues_count %>
|
||||
<% end -%>
|
||||
</li>
|
||||
<% end %>
|
||||
<li><%= link_to t("layouts.history"), history_path, :class => "dropdown-item" %></li>
|
||||
<li><%= link_to t("layouts.export"), export_path, :class => "dropdown-item" %></li>
|
||||
<li><%= link_to t("layouts.gps_traces"), traces_path, :class => "dropdown-item" %></li>
|
||||
<li><%= link_to t("layouts.user_diaries"), diary_entries_path, :class => "dropdown-item" %></li>
|
||||
<li><%= link_to t("layouts.communities"), communities_path, :class => "dropdown-item" %></li>
|
||||
<li><%= link_to t("layouts.copyright"), copyright_path, :class => "dropdown-item" %></li>
|
||||
<li><%= link_to t("layouts.help"), help_path, :class => "dropdown-item" %></li>
|
||||
<li><%= link_to t("layouts.about"), about_path, :class => "dropdown-item" %></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue