From 34fcabab90b62f86e8d54fcb081cdc34a93b93b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Tue, 29 Oct 2024 21:39:00 +0100 Subject: [PATCH] add extra menu (#138) * add extra menu * safe split * add specs * fix specs * fix secrets file --- README.md | 14 +++++ .../stylesheets/somenergia/global_styles.scss | 10 +++- .../decidim/_assembly_navigation.html.erb | 38 ++++++++++++ .../decidim/_process_navigation.html.erb | 32 ++++++++++ config/secrets.yml | 59 ++++++++++++------- spec/factories.rb | 27 +++++++++ spec/lib/overrides_spec.rb | 6 +- spec/system/participatory_processes_spec.rb | 5 ++ spec/system/tech_assembly_menu_spec.rb | 5 ++ 9 files changed, 171 insertions(+), 25 deletions(-) create mode 100644 app/views/layouts/decidim/_assembly_navigation.html.erb create mode 100644 app/views/layouts/decidim/_process_navigation.html.erb diff --git a/README.md b/README.md index c09c1d4a..74173a75 100644 --- a/README.md +++ b/README.md @@ -140,3 +140,17 @@ default: &default - **key**: the identifier for the menu and URL path. For instance, if it is `general_assemblies` we will have a new menu entry for the url `/general_assemblies` and the name specified in the I18n key `decidim.participatory_processes.scoped_participatory_process_slug_prefixes.general_assemblies`. - **position_in_menu**: Where to place the item in the main menu, the usual "PROCESSES" item have the value `2.0`, lower this number will put it before and vice-versa. - **slug_prefixes**: and array of prefixes for the slug of the participatory process. All participatory processes that have an slug starting with this word will be listed here and not in the normal "PROCESSES" menu. + +#### Extra menu items for participatory processes & assemblies + +Extra menu items in a participatory process (or an assembly) can defined in addition to the ones generated by the components. + +Works exclusively using ENV vars following this scheme: + +1. Add an ENV var like `EXTRA_PROCESS_MENU_***` where `***` is the slug of a participatory process. +2. Set the value of that ENV var to a pair of a model and a slug of a participatory space, separated by a slash `/`, for instance: `Decidim::Assembly/some-assembly` or `Decidim::ParticipatoryProcess/some_process` +3. A new menu item will appear to link the referenced participatory space +4. Also works for assemblies, examples: + `EXTRA_ASSEMBLY_MENU_MY_ASSEMBLY=Decidim::ParticipatoryProcess/my_process` + `EXTRA_PROCESS_MENU_MY_PROCESS=Decidim::Assembly/my_assembly` + `EXTRA_PROCESS_MENU_MY_PROCESS=Decidim::ParticipatoryProcess/my_process` diff --git a/app/packs/stylesheets/somenergia/global_styles.scss b/app/packs/stylesheets/somenergia/global_styles.scss index 301acbfe..683b2cf2 100644 --- a/app/packs/stylesheets/somenergia/global_styles.scss +++ b/app/packs/stylesheets/somenergia/global_styles.scss @@ -50,11 +50,18 @@ a { color: #fff !important; text-decoration: none; } - h1,h2,h3,h4,h5,h6, + + h1, + h2, + h3, + h4, + h5, + h6, &.card { text-decoration: none; } } + .section-heading a { text-decoration: none; } @@ -174,6 +181,7 @@ h3, a, .button { text-decoration: none; + &:focus { outline-color: $gray; } diff --git a/app/views/layouts/decidim/_assembly_navigation.html.erb b/app/views/layouts/decidim/_assembly_navigation.html.erb new file mode 100644 index 00000000..b9513218 --- /dev/null +++ b/app/views/layouts/decidim/_assembly_navigation.html.erb @@ -0,0 +1,38 @@ +<% + components = participatory_space.components.published.or(Decidim::Component.where(id: self.try(:current_component))) + items = components.map do |component| + { + name: translated_attribute(component.name), + url: main_component_path(component), + active: is_active_link?(main_component_path(component), :inclusive) + } + end + + model, slug = ENV.fetch("EXTRA_ASSEMBLY_MENU_#{current_participatory_space.slug.upcase}", "").split("/") + klass = model&.safe_constantize + if klass + space = klass.find_by(slug: slug) + if space + link = resource_locator(space).path + items << { + name: translated_attribute(space.title), + url: link, + active: is_active_link?(link, :inclusive) + } + end + end +%> +<%= + extended_navigation_bar(([ + { + name: t(".assembly_menu_item"), + url: decidim_assemblies.assembly_path(current_participatory_space), + active: is_active_link?(decidim_assemblies.assembly_path(current_participatory_space), :exclusive) + }, + participatory_space.members.not_ceased.any? ? { + name: t(".assembly_member_menu_item"), + url: decidim_assemblies.assembly_assembly_members_path(current_participatory_space), + active: is_active_link?(decidim_assemblies.assembly_assembly_members_path(current_participatory_space), :inclusive) + } : nil + ] + items).compact) +%> diff --git a/app/views/layouts/decidim/_process_navigation.html.erb b/app/views/layouts/decidim/_process_navigation.html.erb new file mode 100644 index 00000000..b4ecec92 --- /dev/null +++ b/app/views/layouts/decidim/_process_navigation.html.erb @@ -0,0 +1,32 @@ +<% + components = participatory_space.components.published.or(Decidim::Component.where(id: self.try(:current_component))) + + items = components.map do |component| + { + name: translated_attribute(component.name), + url: main_component_path(component), + active: is_active_link?(main_component_path(component), :inclusive) + } + end + + model, slug = ENV.fetch("EXTRA_PROCESS_MENU_#{current_participatory_space.slug.upcase}", "").split("/") + klass = model&.safe_constantize + if klass + space = klass.find_by(slug: slug) + if space + link = resource_locator(space).path + items << { + name: translated_attribute(space.title), + url: link, + active: is_active_link?(link, :inclusive) + } + end + end +%> +<%= extended_navigation_bar([{ + name: t(".process_menu_item"), + url: decidim_participatory_processes.participatory_process_path(participatory_space), + active: is_active_link?(decidim_participatory_processes.participatory_process_path(participatory_space), :exclusive) || + is_active_link?(decidim_participatory_processes.all_metrics_participatory_process_path(participatory_space), :exclusive) + }] + items) +%> diff --git a/config/secrets.yml b/config/secrets.yml index 8112e7e0..5716b187 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -111,6 +111,28 @@ storage_default: &storage_default auth_provider_x509_cert_url: <%= Decidim::Env.new("GCS_AUTH_PROVIDER_X509_CERT_URL", "https://www.googleapis.com/oauth2/v1/certs").to_s %> client_x509_cert_url: <%= Decidim::Env.new("GCS_CLIENT_X509_CERT_URL").to_s %> +menu_default: &menu_default + localhost: + - key: somenergia.menu.team_et + url: /assemblies/et + position: 10 + if_membership_in: et + prod.participa.somenergia.coop: + - key: somenergia.menu.team_et + url: /assemblies/et + position: 10 + if_membership_in: et + staging.participa.somenergia.coop: + - key: somenergia.menu.team_et + url: /assemblies/et + position: 10 + if_membership_in: et + participa.somenergia.coop: + - key: somenergia.menu.team_et + url: /assemblies/et + position: 10 + if_membership_in: et + default: &default decidim: <<: *decidim_default @@ -155,26 +177,7 @@ default: &default url: //matomo.participa.somenergia.coop/ id: <%= ENV["MATOMO_ID"] %> menu: - localhost: - - key: somenergia.menu.team_et - url: /assemblies/et - position: 10 - if_membership_in: et - prod.participa.somenergia.coop: - - key: somenergia.menu.team_et - url: /assemblies/et - position: 10 - if_membership_in: et - staging.participa.somenergia.coop: - - key: somenergia.menu.team_et - url: /assemblies/et - position: 10 - if_membership_in: et - participa.somenergia.coop: - - key: somenergia.menu.team_et - url: /assemblies/et - position: 10 - if_membership_in: et + <<: *menu_default alternative_assembly_types: - key: local_groups # used to search a I18n key and a route path @@ -191,11 +194,11 @@ development: secret_key_base: 90d17c079bb42e0d52d9a33a8e59eacd887ba2b0c0da5e0792354cb82ac9f94fee61c1b503b81211d9b98cd8aa0f292b8bf3c1126773fa17211391ba2af998f5 test: - <<: *default - secret_key_base: 9f93fabe88fd2169da4ad6f3f535c3056260fa95392573312a331134b3c47e5ba3231d0b5a97a17972ca6a03a67af7714ca37cc7b2055b2237a15943d1a86525 decidim: + <<: *decidim_default available_locales: ["en", "es", "ca"] default_locale: "en" + secret_key_base: 9f93fabe88fd2169da4ad6f3f535c3056260fa95392573312a331134b3c47e5ba3231d0b5a97a17972ca6a03a67af7714ca37cc7b2055b2237a15943d1a86525 omniauth: facebook: enabled: true @@ -206,6 +209,18 @@ test: matomo: url: https://run.mocky.io/v3/ac05e29c-26b8-424b-af06-2f3c7e1f719b? id: 123 + menu: + <<: *menu_default + alternative_assembly_types: + - + key: local_groups # used to search a I18n key and a route path + position_in_menu: 2.6 + assembly_type_ids: [5] + scoped_participatory_process_slug_prefixes: + - + key: general_assemblies # used to search a I18n key and a route path + position_in_menu: 2.1 + slug_prefixes: ["SomAG"] # Do not keep production secrets in the repository, # instead read values from the environment. diff --git a/spec/factories.rb b/spec/factories.rb index 8f54a781..e900078f 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -5,3 +5,30 @@ require "decidim/decidim_awesome/test/factories" require "decidim/consultations/test/factories" require "decidim/initiatives/test/factories" + +shared_examples "a participatory space with extra menu" do |prefix| + let!(:linked_space) { create(:participatory_process, organization: organization) } + + before do + allow(ENV).to receive(:fetch).and_call_original + allow(ENV).to receive(:fetch).with("#{prefix}#{participatory_space.slug.upcase}", "").and_return("Decidim::ParticipatoryProcess/#{linked_space.slug}") + visit visit_path + end + + it "shows the extra menu" do + within "#process-nav-content" do + expect(page).to have_link(href: "/processes/#{linked_space.slug}") + end + end + + context "when visiting another space" do + let!(:another_space) { create(:participatory_process, organization: organization) } + let(:visit_path) { decidim_participatory_processes.participatory_process_path(another_space.slug) } + + it "does not show the extra menu" do + within "#process-nav-content" do + expect(page).not_to have_link(href: "/processes/#{linked_space.slug}") + end + end + end +end diff --git a/spec/lib/overrides_spec.rb b/spec/lib/overrides_spec.rb index f2198ce5..697772cf 100644 --- a/spec/lib/overrides_spec.rb +++ b/spec/lib/overrides_spec.rb @@ -16,13 +16,15 @@ { package: "decidim-assemblies", files: { - "/app/views/decidim/assemblies/_filter_by_type.html.erb" => "c6ddcc8dd42702031f8027bb56b69687" + "/app/views/decidim/assemblies/_filter_by_type.html.erb" => "c6ddcc8dd42702031f8027bb56b69687", + "/app/views/layouts/decidim/_assembly_navigation.html.erb" => "159f168bf1634937183cf5ca56b03a9d" } }, { package: "decidim-participatory_processes", files: { - "/app/cells/decidim/participatory_processes/process_filters_cell.rb" => "cd83acfcd8865c5fe1dbcf8deb5bf319" + "/app/cells/decidim/participatory_processes/process_filters_cell.rb" => "cd83acfcd8865c5fe1dbcf8deb5bf319", + "/app/views/layouts/decidim/_process_navigation.html.erb" => "e4d2322544d80ef4452aa61425034aa3" } }, { diff --git a/spec/system/participatory_processes_spec.rb b/spec/system/participatory_processes_spec.rb index 223c4c8c..5e851697 100644 --- a/spec/system/participatory_processes_spec.rb +++ b/spec/system/participatory_processes_spec.rb @@ -230,4 +230,9 @@ expect(page).to have_content("MORE INFO") end end + + it_behaves_like "a participatory space with extra menu", "EXTRA_PROCESS_MENU_" do + let(:participatory_space) { normal_process } + let(:visit_path) { decidim_participatory_processes.participatory_process_path(normal_process.slug) } + end end diff --git a/spec/system/tech_assembly_menu_spec.rb b/spec/system/tech_assembly_menu_spec.rb index 54491188..32ca2493 100644 --- a/spec/system/tech_assembly_menu_spec.rb +++ b/spec/system/tech_assembly_menu_spec.rb @@ -74,4 +74,9 @@ it_behaves_like "shows menu" end end + + it_behaves_like "a participatory space with extra menu", "EXTRA_ASSEMBLY_MENU_" do + let(:participatory_space) { assembly } + let(:visit_path) { decidim_assemblies.assembly_path(assembly.slug) } + end end