Merge pull request #5460 from consuldemocracy/admin_menu_expanded

Use buttons to open/close admin navigation submenus
This commit is contained in:
Javi Martín
2024-04-24 14:40:44 +02:00
committed by GitHub
21 changed files with 271 additions and 166 deletions

View File

@@ -0,0 +1,16 @@
(function() {
"use strict";
App.AdminMenu = {
initialize: function() {
var toggle_buttons = $(".admin-sidebar [aria-expanded]");
toggle_buttons.removeAttr("disabled");
toggle_buttons.filter("[aria-expanded='false']").find("+ *").hide();
toggle_buttons.on("click", function() {
$(this).attr("aria-expanded", !JSON.parse($(this).attr("aria-expanded")));
$(this).next().slideToggle();
});
}
};
}).call(this);

View File

@@ -174,6 +174,7 @@ var initialize_modules = function() {
App.AdminMachineLearningScripts.initialize(); App.AdminMachineLearningScripts.initialize();
App.AdminTenantsForm.initialize(); App.AdminTenantsForm.initialize();
App.AdminVotationTypesFields.initialize(); App.AdminVotationTypesFields.initialize();
App.AdminMenu.initialize();
App.BudgetEditAssociations.initialize(); App.BudgetEditAssociations.initialize();
App.BudgetHideMoney.initialize(); App.BudgetHideMoney.initialize();
App.Datepicker.initialize(); App.Datepicker.initialize();

View File

@@ -214,10 +214,6 @@ $table-header: #ecf1f6;
padding-right: 0; padding-right: 0;
} }
.accordion-title {
font-size: $base-font-size;
}
.button.secondary { .button.secondary {
margin-right: rem-calc(12); margin-right: rem-calc(12);
} }

View File

@@ -10,7 +10,7 @@
padding: 0; padding: 0;
} }
> ul > li a { > ul > li > :first-child {
display: flex; display: flex;
font-weight: bold; font-weight: bold;
@@ -124,16 +124,9 @@
border-left: 2px solid $sidebar-active; border-left: 2px solid $sidebar-active;
font-weight: bold; font-weight: bold;
} }
&[aria-expanded="true"] {
> a::after {
transform: rotate(180deg);
}
}
} }
li a { li > :first-child {
color: inherit; color: inherit;
display: block; display: block;
padding: calc(#{$line-height} / 2); padding: calc(#{$line-height} / 2);
@@ -146,19 +139,27 @@
} }
} }
.is-accordion-submenu-parent { [aria-expanded] {
> a {
@include has-fa-icon(chevron-down, solid, after); @include has-fa-icon(chevron-down, solid, after);
line-height: inherit;
text-align: inherit;
width: 100%;
&::after { &::after {
margin-#{$global-left}: auto; margin-#{$global-left}: auto;
transition: 0.25s; transition: 0.25s;
} }
&:not([disabled]) {
cursor: pointer;
} }
} }
.submenu { [aria-expanded="true"]::after {
transform: rotate(180deg);
}
ul ul {
border-bottom: 0; border-bottom: 0;
margin-left: $line-height; margin-left: $line-height;

View File

@@ -1 +1 @@
<%= link_list(*links, id: "admin_menu", data: { "accordion-menu": true, "multi-open": true }) %> <%= link_list(*links, id: "admin_menu") %>

View File

@@ -60,7 +60,9 @@ class Admin::MenuComponent < ApplicationComponent
def customization? def customization?
controllers_names = ["pages", "banners", "information_texts", "documents", "images", "content_blocks"] controllers_names = ["pages", "banners", "information_texts", "documents", "images", "content_blocks"]
controllers_names.include?(controller_name) || homepage? || pages?
(controllers_names.include?(controller_name) || homepage? || pages?) &&
controller.class.module_parent != Admin::Poll::Questions::Answers
end end
def homepage? def homepage?
@@ -151,15 +153,16 @@ class Admin::MenuComponent < ApplicationComponent
end end
def booths_links def booths_links
link_to(t("admin.menu.title_booths"), "#", class: "booths-link") + section(t("admin.menu.title_booths"), active: booths?, class: "booths-link") do
link_list( link_list(
officers_link, officers_link,
booths_link, booths_link,
booth_assignments_link, booth_assignments_link,
shifts_link, shifts_link,
id: "booths_menu", class: ("is-active" if booths?) id: "booths_menu"
) )
end end
end
def officers_link def officers_link
[ [
@@ -204,15 +207,16 @@ class Admin::MenuComponent < ApplicationComponent
end end
def messages_links def messages_links
link_to(t("admin.menu.messaging_users"), "#", class: "messages-link") + section(t("admin.menu.messaging_users"), active: messages_menu_active?, class: "messages-link") do
link_list( link_list(
newsletters_link, newsletters_link,
admin_notifications_link, admin_notifications_link,
system_emails_link, system_emails_link,
emails_download_link, emails_download_link,
id: "messaging_users_menu", class: ("is-active" if messages_menu_active?) id: "messaging_users_menu"
) )
end end
end
def newsletters_link def newsletters_link
[ [
@@ -247,7 +251,8 @@ class Admin::MenuComponent < ApplicationComponent
end end
def site_customization_links def site_customization_links
link_to(t("admin.menu.title_site_customization"), "#", class: "site-customization-link") + section(t("admin.menu.title_site_customization"),
active: customization?, class: "site-customization-link") do
link_list( link_list(
homepage_link, homepage_link,
pages_link, pages_link,
@@ -255,11 +260,10 @@ class Admin::MenuComponent < ApplicationComponent
information_texts_link, information_texts_link,
documents_link, documents_link,
images_link, images_link,
content_blocks_link, content_blocks_link
class: ("is-active" if customization? &&
controller.class.module_parent != Admin::Poll::Questions::Answers)
) )
end end
end
def homepage_link def homepage_link
[ [
@@ -302,7 +306,8 @@ class Admin::MenuComponent < ApplicationComponent
end end
def moderated_content_links def moderated_content_links
link_to(t("admin.menu.title_moderated_content"), "#", class: "moderated-content-link") + section(t("admin.menu.title_moderated_content"),
active: moderated_content?, class: "moderated-content-link") do
link_list( link_list(
(hidden_proposals_link if feature?(:proposals)), (hidden_proposals_link if feature?(:proposals)),
(hidden_debates_link if feature?(:debates)), (hidden_debates_link if feature?(:debates)),
@@ -310,10 +315,10 @@ class Admin::MenuComponent < ApplicationComponent
hidden_comments_link, hidden_comments_link,
hidden_proposal_notifications_link, hidden_proposal_notifications_link,
hidden_users_link, hidden_users_link,
activity_link, activity_link
class: ("is-active" if moderated_content?)
) )
end end
end
def hidden_proposals_link def hidden_proposals_link
[ [
@@ -372,7 +377,7 @@ class Admin::MenuComponent < ApplicationComponent
end end
def profiles_links def profiles_links
link_to(t("admin.menu.title_profiles"), "#", class: "profiles-link") + section(t("admin.menu.title_profiles"), active: profiles?, class: "profiles-link") do
link_list( link_list(
administrators_link, administrators_link,
organizations_link, organizations_link,
@@ -381,10 +386,10 @@ class Admin::MenuComponent < ApplicationComponent
valuators_link, valuators_link,
managers_link, managers_link,
(sdg_managers_link if feature?(:sdg)), (sdg_managers_link if feature?(:sdg)),
users_link, users_link
class: ("is-active" if profiles?)
) )
end end
end
def administrators_link def administrators_link
[ [
@@ -452,16 +457,16 @@ class Admin::MenuComponent < ApplicationComponent
end end
def settings_links def settings_links
link_to(t("admin.menu.title_settings"), "#", class: "settings-link") + section(t("admin.menu.title_settings"), active: settings?, class: "settings-link") do
link_list( link_list(
settings_link, settings_link,
tenants_link, tenants_link,
tags_link, tags_link,
geozones_link, geozones_link,
local_census_records_link, local_census_records_link
class: ("is-active" if settings?)
) )
end end
end
def settings_link def settings_link
[ [
@@ -522,13 +527,13 @@ class Admin::MenuComponent < ApplicationComponent
end end
def dashboard_links def dashboard_links
link_to(t("admin.menu.dashboard"), "#", class: "dashboard-link") + section(t("admin.menu.dashboard"), active: dashboard?, class: "dashboard-link") do
link_list( link_list(
dashboard_actions_link, dashboard_actions_link,
administrator_tasks_link, administrator_tasks_link
class: ("is-active" if dashboard?)
) )
end end
end
def machine_learning_link def machine_learning_link
[ [
@@ -562,4 +567,12 @@ class Admin::MenuComponent < ApplicationComponent
sdg_managers? sdg_managers?
] ]
end end
def section(title, **, &content)
section_opener(title, **) + content.call
end
def section_opener(title, active:, **options)
button_tag(title, { type: "button", disabled: "disabled", "aria-expanded": active }.merge(options))
end
end end

View File

@@ -0,0 +1 @@
<%= link_list(*links, id: "admin_menu") %>

View File

@@ -0,0 +1,162 @@
class Management::MenuComponent < ApplicationComponent
use_helpers :managed_user, :link_list
def links
[
user_links,
(print_investments_link if Setting["process.budgets"]),
print_proposals_link,
user_invites_link
]
end
private
def user_links
section(t("management.menu.users"), active: true, class: "users-link") do
link_list(
select_user_link,
(reset_password_email_link if managed_user.email),
reset_password_manually_link,
create_proposal_link,
support_proposals_link,
(create_budget_investment_link if Setting["process.budgets"]),
(support_budget_investments_link if Setting["process.budgets"])
)
end
end
def select_user_link
[
t("management.menu.select_user"),
management_document_verifications_path,
users?
]
end
def reset_password_email_link
[
t("management.account.menu.reset_password_email"),
edit_password_email_management_account_path,
edit_password_email?
]
end
def reset_password_manually_link
[
t("management.account.menu.reset_password_manually"),
edit_password_manually_management_account_path,
edit_password_manually?
]
end
def create_proposal_link
[
t("management.menu.create_proposal"),
new_management_proposal_path,
create_proposal?
]
end
def support_proposals_link
[
t("management.menu.support_proposals"),
management_proposals_path,
support_proposal?
]
end
def create_budget_investment_link
[
t("management.menu.create_budget_investment"),
create_investments_management_budgets_path,
create_investments?
]
end
def support_budget_investments_link
[
t("management.menu.support_budget_investments"),
support_investments_management_budgets_path,
support_investments?
]
end
def print_investments_link
[
t("management.menu.print_budget_investments"),
print_investments_management_budgets_path,
print_investments?,
class: "print-investments-link"
]
end
def print_proposals_link
[
t("management.menu.print_proposals"),
print_management_proposals_path,
print_proposals?,
class: "print-proposals-link"
]
end
def user_invites_link
[
t("management.menu.user_invites"),
new_management_user_invite_path,
user_invites?,
class: "invitations-link"
]
end
def users?
["users", "email_verifications", "document_verifications"].include?(controller_name)
end
def edit_password_email?
controller_name == "account" && action_name == "edit_password_email"
end
def edit_password_manually?
controller_name == "account" && action_name == "edit_password_manually"
end
def create_proposal?
controller_name == "proposals" && action_name == "new"
end
def support_proposal?
controller_name == "proposals" && action_name == "index"
end
def print_proposals?
controller_name == "proposals" && action_name == "print"
end
def create_investments?
(controller_name == "budget_investments" && action_name == "new") ||
(controller_name == "budgets" && action_name == "create_investments")
end
def support_investments?
(controller_name == "budget_investments" && action_name == "index") ||
(controller_name == "budgets" && action_name == "support_investments")
end
def print_investments?
(controller_name == "budget_investments" && action_name == "print") ||
(controller_name == "budgets" && action_name == "print_investments")
end
def user_invites?
controller_name == "user_invites"
end
def section(title, **, &content)
section_opener(title, **) + content.call
end
def section_opener(title, active:, **options)
button_tag(title, { type: "button", disabled: "disabled", "aria-expanded": active }.merge(options))
end
end

View File

@@ -1,44 +0,0 @@
module ManagementHelper
def menu_users?
["users", "email_verifications", "document_verifications"].include?(controller_name)
end
def menu_edit_password_email?
controller_name == "account" && action_name == "edit_password_email"
end
def menu_edit_password_manually?
controller_name == "account" && action_name == "edit_password_manually"
end
def menu_create_proposal?
controller_name == "proposals" && action_name == "new"
end
def menu_support_proposal?
controller_name == "proposals" && action_name == "index"
end
def menu_print_proposals?
controller_name == "proposals" && action_name == "print"
end
def menu_create_investments?
(controller_name == "budget_investments" && action_name == "new") ||
(controller_name == "budgets" && action_name == "create_investments")
end
def menu_support_investments?
(controller_name == "budget_investments" && action_name == "index") ||
(controller_name == "budgets" && action_name == "support_investments")
end
def menu_print_investments?
(controller_name == "budget_investments" && action_name == "print") ||
(controller_name == "budgets" && action_name == "print_investments")
end
def menu_user_invites?
controller_name == "user_invites"
end
end

View File

@@ -14,7 +14,7 @@
<%= check_box_tag :show_menu, nil, false, role: "switch" %> <%= check_box_tag :show_menu, nil, false, role: "switch" %>
<nav class="admin-sidebar"> <nav class="admin-sidebar">
<%= render "/management/menu" %> <%= render Management::MenuComponent.new %>
</nav> </nav>
<main id="main" class="admin-content <%= yield(:main_class) %>"> <main id="main" class="admin-content <%= yield(:main_class) %>">

View File

@@ -1,63 +0,0 @@
<ul id="admin_menu" data-accordion-menu>
<li class="section-title">
<a href="#" class="users-link"><%= t("management.menu.users") %></a>
<%= link_list(
[
t("management.menu.select_user"),
management_document_verifications_path,
menu_users?
],
(
[
t("management.account.menu.reset_password_email"),
edit_password_email_management_account_path,
menu_edit_password_email?
] if managed_user.email
),
[
t("management.account.menu.reset_password_manually"),
edit_password_manually_management_account_path,
menu_edit_password_manually?
],
[
t("management.menu.create_proposal"),
new_management_proposal_path,
menu_create_proposal?
],
[
t("management.menu.support_proposals"),
management_proposals_path,
menu_support_proposal?
],
(
[
t("management.menu.create_budget_investment"),
create_investments_management_budgets_path,
menu_create_investments?
] if Setting["process.budgets"]
),
(
[
t("management.menu.support_budget_investments"),
support_investments_management_budgets_path,
menu_support_investments?
] if Setting["process.budgets"]
),
class: "is-active"
) %>
</li>
<% if Setting["process.budgets"] %>
<li <%= "class=is-active" if menu_print_investments? %>>
<%= link_to t("management.menu.print_budget_investments"), print_investments_management_budgets_path, class: "print-investments-link" %>
</li>
<% end %>
<li <%= "class=is-active" if menu_print_proposals? %>>
<%= link_to t("management.menu.print_proposals"), print_management_proposals_path, class: "print-proposals-link" %>
</li>
<li <%= "class=is-active" if menu_user_invites? %>>
<%= link_to t("management.menu.user_invites"), new_management_user_invite_path, class: "invitations-link" %>
</li>
</ul>

View File

@@ -0,0 +1,22 @@
require "rails_helper"
describe Admin::MenuComponent, controller: Admin::NewslettersController do
it "disables all buttons when JavaScript isn't available" do
render_inline Admin::MenuComponent.new
expect(page).to have_button disabled: true
expect(page).not_to have_button disabled: false
end
it "expands the current section" do
render_inline Admin::MenuComponent.new
expect(page).to have_css "button[aria-expanded='true']", exact_text: "Messages to users"
end
it "does not expand other sections" do
render_inline Admin::MenuComponent.new
expect(page).to have_css "button[aria-expanded='false']", exact_text: "Settings"
end
end

View File

@@ -64,7 +64,7 @@ describe "Admin banners magement", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Site content" click_button "Site content"
click_link "Manage banners" click_link "Manage banners"
end end
@@ -133,7 +133,7 @@ describe "Admin banners magement", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Site content" click_button "Site content"
click_link "Manage banners" click_link "Manage banners"
end end

View File

@@ -15,7 +15,7 @@ describe "Admin geozones", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Settings" click_button "Settings"
click_link "Manage geozones" click_link "Manage geozones"
end end

View File

@@ -5,7 +5,7 @@ describe "Admin booths", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Voting booths" click_button "Voting booths"
click_link "Booths location" click_link "Booths location"
end end
@@ -18,7 +18,7 @@ describe "Admin booths", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Voting booths" click_button "Voting booths"
click_link "Booths location" click_link "Booths location"
end end
@@ -38,7 +38,7 @@ describe "Admin booths", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Voting booths" click_button "Voting booths"
click_link "Manage shifts" click_link "Manage shifts"
end end

View File

@@ -23,7 +23,7 @@ describe "Admin custom content blocks", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Site content" click_button "Site content"
click_link "Custom content blocks" click_link "Custom content blocks"
end end
@@ -48,7 +48,7 @@ describe "Admin custom content blocks", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Site content" click_button "Site content"
click_link "Custom content blocks" click_link "Custom content blocks"
end end
@@ -75,7 +75,7 @@ describe "Admin custom content blocks", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Site content" click_button "Site content"
click_link "Custom content blocks" click_link "Custom content blocks"
end end

View File

@@ -5,7 +5,7 @@ describe "Documents", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Site content" click_button "Site content"
click_link "Custom documents" click_link "Custom documents"
end end

View File

@@ -5,7 +5,7 @@ describe "Admin custom images", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Site content" click_button "Site content"
click_link "Custom images" click_link "Custom images"
end end

View File

@@ -33,7 +33,7 @@ describe "Admin custom pages", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Site content" click_button "Site content"
click_link "Custom pages" click_link "Custom pages"
end end
@@ -63,7 +63,7 @@ describe "Admin custom pages", :admin do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Site content" click_button "Site content"
click_link "Custom pages" click_link "Custom pages"
end end

View File

@@ -8,7 +8,7 @@ describe "Tenants", :admin, :seed_tenants do
visit admin_root_path visit admin_root_path
within("#side_menu") do within("#side_menu") do
click_link "Settings" click_button "Settings"
click_link "Multitenancy" click_link "Multitenancy"
end end

View File

@@ -80,7 +80,7 @@ describe "Admin" do
within("#admin_menu") do within("#admin_menu") do
expect(page).to have_link "Participatory budgets" expect(page).to have_link "Participatory budgets"
click_link "Site content" click_button "Site content"
expect(page).to have_link "Participatory budgets" expect(page).to have_link "Participatory budgets"
end end