From 0309e0f6b2759d51158d2524c6da090ea988aa94 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Wed, 11 Sep 2024 12:09:21 +0200 Subject: [PATCH] refactor(profile): generalize profile from referrer or for user --- app/controllers/application_controller.rb | 12 +---- .../concerns/nav_bar_profile_concern.rb | 44 +++++++++++++++++++ app/controllers/errors_controller.rb | 2 - app/controllers/release_notes_controller.rb | 2 - app/views/layouts/_header.haml | 4 +- 5 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 app/controllers/concerns/nav_bar_profile_concern.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c4d597cfd..afaf48762 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,6 +2,7 @@ class ApplicationController < ActionController::Base include TrustedDeviceConcern + include NavBarProfileConcern include Pundit::Authorization include Devise::StoreLocationExtension include ApplicationController::LongLivedAuthenticityToken @@ -422,17 +423,6 @@ class ApplicationController < ActionController::Base prepend_view_path "app/custom_views" end - def try_nav_bar_profile_from_referrer - # detect context from referer, simple (no detection when refreshing the page) - params = Rails.application.routes.recognize_path(request&.referer) - - controller_class = "#{params[:controller].camelize}Controller".safe_constantize - return if controller_class.nil? - - controller_instance = controller_class.new - controller_instance.try(:nav_bar_profile) - end - def cast_bool(value) ActiveRecord::Type::Boolean.new.deserialize(value) end diff --git a/app/controllers/concerns/nav_bar_profile_concern.rb b/app/controllers/concerns/nav_bar_profile_concern.rb new file mode 100644 index 000000000..4c856480f --- /dev/null +++ b/app/controllers/concerns/nav_bar_profile_concern.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module NavBarProfileConcern + extend ActiveSupport::Concern + + included do + # Override this method on controller basis for more precise context or custom logic + def nav_bar_profile + end + + def fallback_nav_bar_profile + return :guest if current_user.blank? + + nav_bar_profile_from_referrer || default_nav_bar_profile_for_user + end + + private + + # Shared controllers (search, errors, release notes…) don't have specific context + # Simple attempt to try to re-use the profile from the previous page + # so user does'not feel lost. + def nav_bar_profile_from_referrer + # detect context from referer, simple (no detection when refreshing the page) + params = Rails.application.routes.recognize_path(request&.referer) + + controller_class = "#{params[:controller].camelize}Controller".safe_constantize + return if controller_class.nil? + + controller_instance = controller_class.new + controller_instance.try(:nav_bar_profile) + end + + # Fallback for shared controllers from user account + # to the more relevant profile. + def default_nav_bar_profile_for_user + return :gestionnaire if current_user.gestionnaire? + return :administrateur if current_user.administrateur? + return :instructeur if current_user.instructeur? + return :expert if current_user.expert? + + :user + end + end +end diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb index be1b68565..e44b5ee8b 100644 --- a/app/controllers/errors_controller.rb +++ b/app/controllers/errors_controller.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class ErrorsController < ApplicationController - def nav_bar_profile = try_nav_bar_profile_from_referrer - rescue_from Exception do # catch any error, except errors triggered by middlewares outside controller (like warden middleware) render file: Rails.public_path.join('500.html'), layout: false, status: :internal_server_error diff --git a/app/controllers/release_notes_controller.rb b/app/controllers/release_notes_controller.rb index 494c338fb..cb5c08c1e 100644 --- a/app/controllers/release_notes_controller.rb +++ b/app/controllers/release_notes_controller.rb @@ -23,8 +23,6 @@ class ReleaseNotesController < ApplicationController render "scrollable_list" if params[:page].present? end - def nav_bar_profile = try_nav_bar_profile_from_referrer - private def touch_default_categories_seen_at diff --git a/app/views/layouts/_header.haml b/app/views/layouts/_header.haml index ca22f2acc..3bc89efd5 100644 --- a/app/views/layouts/_header.haml +++ b/app/views/layouts/_header.haml @@ -1,5 +1,5 @@ --# We can't use &. because the controller may not implement #nav_bar_profile -- nav_bar_profile = controller.try(:nav_bar_profile) || :guest +-# We can't use &. or as helper methods because the controllers from view specs does not implement these methods +- nav_bar_profile = controller.try(:nav_bar_profile) || controller.try(:fallback_nav_bar_profile) || :guest - dossier = controller.try(:dossier_for_help) - procedure = controller.try(:procedure_for_help) - is_instructeur_context = nav_bar_profile == :instructeur && instructeur_signed_in?