diff --git a/app/assets/javascripts/admin/menu.js b/app/assets/javascripts/admin/menu.js new file mode 100644 index 000000000..f6d91978a --- /dev/null +++ b/app/assets/javascripts/admin/menu.js @@ -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); diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 86a0f8243..9e6031dd4 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -174,6 +174,7 @@ var initialize_modules = function() { App.AdminMachineLearningScripts.initialize(); App.AdminTenantsForm.initialize(); App.AdminVotationTypesFields.initialize(); + App.AdminMenu.initialize(); App.BudgetEditAssociations.initialize(); App.BudgetHideMoney.initialize(); App.Datepicker.initialize(); diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 70258353f..fd61560b3 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -214,10 +214,6 @@ $table-header: #ecf1f6; padding-right: 0; } - .accordion-title { - font-size: $base-font-size; - } - .button.secondary { margin-right: rem-calc(12); } diff --git a/app/assets/stylesheets/admin/menu.scss b/app/assets/stylesheets/admin/menu.scss index 3a6cd7514..1993ff53a 100644 --- a/app/assets/stylesheets/admin/menu.scss +++ b/app/assets/stylesheets/admin/menu.scss @@ -10,7 +10,7 @@ padding: 0; } - > ul > li a { + > ul > li > :first-child { display: flex; font-weight: bold; @@ -124,16 +124,9 @@ border-left: 2px solid $sidebar-active; font-weight: bold; } - - &[aria-expanded="true"] { - - > a::after { - transform: rotate(180deg); - } - } } - li a { + li > :first-child { color: inherit; display: block; padding: calc(#{$line-height} / 2); @@ -146,19 +139,27 @@ } } - .is-accordion-submenu-parent { + [aria-expanded] { + @include has-fa-icon(chevron-down, solid, after); + line-height: inherit; + text-align: inherit; + width: 100%; - > a { - @include has-fa-icon(chevron-down, solid, after); + &::after { + margin-#{$global-left}: auto; + transition: 0.25s; + } - &::after { - margin-#{$global-left}: auto; - transition: 0.25s; - } + &:not([disabled]) { + cursor: pointer; } } - .submenu { + [aria-expanded="true"]::after { + transform: rotate(180deg); + } + + ul ul { border-bottom: 0; margin-left: $line-height; diff --git a/app/components/admin/menu_component.html.erb b/app/components/admin/menu_component.html.erb index 5b4a80597..0edc468b4 100644 --- a/app/components/admin/menu_component.html.erb +++ b/app/components/admin/menu_component.html.erb @@ -1 +1 @@ -<%= link_list(*links, id: "admin_menu", data: { "accordion-menu": true, "multi-open": true }) %> +<%= link_list(*links, id: "admin_menu") %> diff --git a/app/components/admin/menu_component.rb b/app/components/admin/menu_component.rb index 8ec7df693..480be1b89 100644 --- a/app/components/admin/menu_component.rb +++ b/app/components/admin/menu_component.rb @@ -60,7 +60,9 @@ class Admin::MenuComponent < ApplicationComponent def customization? 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 def homepage? @@ -151,14 +153,15 @@ class Admin::MenuComponent < ApplicationComponent end 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( officers_link, booths_link, booth_assignments_link, shifts_link, - id: "booths_menu", class: ("is-active" if booths?) + id: "booths_menu" ) + end end def officers_link @@ -204,14 +207,15 @@ class Admin::MenuComponent < ApplicationComponent end 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( newsletters_link, admin_notifications_link, system_emails_link, emails_download_link, - id: "messaging_users_menu", class: ("is-active" if messages_menu_active?) + id: "messaging_users_menu" ) + end end def newsletters_link @@ -247,7 +251,8 @@ class Admin::MenuComponent < ApplicationComponent end 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( homepage_link, pages_link, @@ -255,10 +260,9 @@ class Admin::MenuComponent < ApplicationComponent information_texts_link, documents_link, images_link, - content_blocks_link, - class: ("is-active" if customization? && - controller.class.module_parent != Admin::Poll::Questions::Answers) + content_blocks_link ) + end end def homepage_link @@ -302,7 +306,8 @@ class Admin::MenuComponent < ApplicationComponent end 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( (hidden_proposals_link if feature?(:proposals)), (hidden_debates_link if feature?(:debates)), @@ -310,9 +315,9 @@ class Admin::MenuComponent < ApplicationComponent hidden_comments_link, hidden_proposal_notifications_link, hidden_users_link, - activity_link, - class: ("is-active" if moderated_content?) + activity_link ) + end end def hidden_proposals_link @@ -372,7 +377,7 @@ class Admin::MenuComponent < ApplicationComponent end 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( administrators_link, organizations_link, @@ -381,9 +386,9 @@ class Admin::MenuComponent < ApplicationComponent valuators_link, managers_link, (sdg_managers_link if feature?(:sdg)), - users_link, - class: ("is-active" if profiles?) + users_link ) + end end def administrators_link @@ -452,15 +457,15 @@ class Admin::MenuComponent < ApplicationComponent end 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( settings_link, tenants_link, tags_link, geozones_link, - local_census_records_link, - class: ("is-active" if settings?) + local_census_records_link ) + end end def settings_link @@ -522,12 +527,12 @@ class Admin::MenuComponent < ApplicationComponent end 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( dashboard_actions_link, - administrator_tasks_link, - class: ("is-active" if dashboard?) + administrator_tasks_link ) + end end def machine_learning_link @@ -562,4 +567,12 @@ class Admin::MenuComponent < ApplicationComponent sdg_managers? ] 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 diff --git a/app/components/management/menu_component.html.erb b/app/components/management/menu_component.html.erb new file mode 100644 index 000000000..0edc468b4 --- /dev/null +++ b/app/components/management/menu_component.html.erb @@ -0,0 +1 @@ +<%= link_list(*links, id: "admin_menu") %> diff --git a/app/components/management/menu_component.rb b/app/components/management/menu_component.rb new file mode 100644 index 000000000..be11c0fd4 --- /dev/null +++ b/app/components/management/menu_component.rb @@ -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 diff --git a/app/helpers/management_helper.rb b/app/helpers/management_helper.rb deleted file mode 100644 index 99bc18023..000000000 --- a/app/helpers/management_helper.rb +++ /dev/null @@ -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 diff --git a/app/views/layouts/management.html.erb b/app/views/layouts/management.html.erb index 4c01900d2..7f8f1ba60 100644 --- a/app/views/layouts/management.html.erb +++ b/app/views/layouts/management.html.erb @@ -14,7 +14,7 @@ <%= check_box_tag :show_menu, nil, false, role: "switch" %>
diff --git a/app/views/management/_menu.html.erb b/app/views/management/_menu.html.erb deleted file mode 100644 index 42fa308a0..000000000 --- a/app/views/management/_menu.html.erb +++ /dev/null @@ -1,63 +0,0 @@ - diff --git a/spec/components/admin/menu_component_spec.rb b/spec/components/admin/menu_component_spec.rb new file mode 100644 index 000000000..0a7ccf82f --- /dev/null +++ b/spec/components/admin/menu_component_spec.rb @@ -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 diff --git a/spec/system/admin/banners_spec.rb b/spec/system/admin/banners_spec.rb index 0ac2a009e..c604f6d6e 100644 --- a/spec/system/admin/banners_spec.rb +++ b/spec/system/admin/banners_spec.rb @@ -64,7 +64,7 @@ describe "Admin banners magement", :admin do visit admin_root_path within("#side_menu") do - click_link "Site content" + click_button "Site content" click_link "Manage banners" end @@ -133,7 +133,7 @@ describe "Admin banners magement", :admin do visit admin_root_path within("#side_menu") do - click_link "Site content" + click_button "Site content" click_link "Manage banners" end diff --git a/spec/system/admin/geozones_spec.rb b/spec/system/admin/geozones_spec.rb index 95c862baf..384cccc73 100644 --- a/spec/system/admin/geozones_spec.rb +++ b/spec/system/admin/geozones_spec.rb @@ -15,7 +15,7 @@ describe "Admin geozones", :admin do visit admin_root_path within("#side_menu") do - click_link "Settings" + click_button "Settings" click_link "Manage geozones" end diff --git a/spec/system/admin/poll/booths_spec.rb b/spec/system/admin/poll/booths_spec.rb index 61b440bc0..392f01b62 100644 --- a/spec/system/admin/poll/booths_spec.rb +++ b/spec/system/admin/poll/booths_spec.rb @@ -5,7 +5,7 @@ describe "Admin booths", :admin do visit admin_root_path within("#side_menu") do - click_link "Voting booths" + click_button "Voting booths" click_link "Booths location" end @@ -18,7 +18,7 @@ describe "Admin booths", :admin do visit admin_root_path within("#side_menu") do - click_link "Voting booths" + click_button "Voting booths" click_link "Booths location" end @@ -38,7 +38,7 @@ describe "Admin booths", :admin do visit admin_root_path within("#side_menu") do - click_link "Voting booths" + click_button "Voting booths" click_link "Manage shifts" end diff --git a/spec/system/admin/site_customization/content_blocks_spec.rb b/spec/system/admin/site_customization/content_blocks_spec.rb index 012fc28ee..6f77b1c31 100644 --- a/spec/system/admin/site_customization/content_blocks_spec.rb +++ b/spec/system/admin/site_customization/content_blocks_spec.rb @@ -23,7 +23,7 @@ describe "Admin custom content blocks", :admin do visit admin_root_path within("#side_menu") do - click_link "Site content" + click_button "Site content" click_link "Custom content blocks" end @@ -48,7 +48,7 @@ describe "Admin custom content blocks", :admin do visit admin_root_path within("#side_menu") do - click_link "Site content" + click_button "Site content" click_link "Custom content blocks" end @@ -75,7 +75,7 @@ describe "Admin custom content blocks", :admin do visit admin_root_path within("#side_menu") do - click_link "Site content" + click_button "Site content" click_link "Custom content blocks" end diff --git a/spec/system/admin/site_customization/documents_spec.rb b/spec/system/admin/site_customization/documents_spec.rb index 76fff934b..3f4ec063c 100644 --- a/spec/system/admin/site_customization/documents_spec.rb +++ b/spec/system/admin/site_customization/documents_spec.rb @@ -5,7 +5,7 @@ describe "Documents", :admin do visit admin_root_path within("#side_menu") do - click_link "Site content" + click_button "Site content" click_link "Custom documents" end diff --git a/spec/system/admin/site_customization/images_spec.rb b/spec/system/admin/site_customization/images_spec.rb index 11cf9fc0e..801e0576a 100644 --- a/spec/system/admin/site_customization/images_spec.rb +++ b/spec/system/admin/site_customization/images_spec.rb @@ -5,7 +5,7 @@ describe "Admin custom images", :admin do visit admin_root_path within("#side_menu") do - click_link "Site content" + click_button "Site content" click_link "Custom images" end diff --git a/spec/system/admin/site_customization/pages_spec.rb b/spec/system/admin/site_customization/pages_spec.rb index 6192d5632..19a084ce6 100644 --- a/spec/system/admin/site_customization/pages_spec.rb +++ b/spec/system/admin/site_customization/pages_spec.rb @@ -33,7 +33,7 @@ describe "Admin custom pages", :admin do visit admin_root_path within("#side_menu") do - click_link "Site content" + click_button "Site content" click_link "Custom pages" end @@ -63,7 +63,7 @@ describe "Admin custom pages", :admin do visit admin_root_path within("#side_menu") do - click_link "Site content" + click_button "Site content" click_link "Custom pages" end diff --git a/spec/system/admin/tenants_spec.rb b/spec/system/admin/tenants_spec.rb index acabe6464..0616eaa58 100644 --- a/spec/system/admin/tenants_spec.rb +++ b/spec/system/admin/tenants_spec.rb @@ -8,7 +8,7 @@ describe "Tenants", :admin, :seed_tenants do visit admin_root_path within("#side_menu") do - click_link "Settings" + click_button "Settings" click_link "Multitenancy" end diff --git a/spec/system/admin_spec.rb b/spec/system/admin_spec.rb index a0f31c04d..d09d9bdeb 100644 --- a/spec/system/admin_spec.rb +++ b/spec/system/admin_spec.rb @@ -80,7 +80,7 @@ describe "Admin" do within("#admin_menu") do expect(page).to have_link "Participatory budgets" - click_link "Site content" + click_button "Site content" expect(page).to have_link "Participatory budgets" end