Skip to content

Commit

Permalink
Merge pull request #10778 from colinux/sharerd-controller-nav-bar-pro…
Browse files Browse the repository at this point in the history
…file

UX: améliore la détection du type de profile utilisé pour la nav bar
  • Loading branch information
colinux authored Sep 16, 2024
2 parents 2406402 + f6744ad commit 58037f2
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 27 deletions.
12 changes: 1 addition & 11 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class ApplicationController < ActionController::Base
include TrustedDeviceConcern
include NavBarProfileConcern
include Pundit::Authorization
include Devise::StoreLocationExtension
include ApplicationController::LongLivedAuthenticityToken
Expand Down Expand Up @@ -422,17 +423,6 @@ def set_customizable_view_path
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
Expand Down
44 changes: 44 additions & 0 deletions app/controllers/concerns/nav_bar_profile_concern.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 0 additions & 2 deletions app/controllers/errors_controller.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down
12 changes: 12 additions & 0 deletions app/controllers/recherche_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ class RechercheController < ApplicationController
{ "table" => 'procedure', "column" => 'procedure_id' }
]

def nav_bar_profile
return super if request.blank? # Controller introspection does not contains params/request, see NavBarProfileConcern

context_params = params[:context]&.to_sym
case context_params
when :instructeur, :expert
context_params
else
:user
end
end

def index
@search_terms = search_terms
@dossiers_count = 0
Expand Down
2 changes: 0 additions & 2 deletions app/controllers/release_notes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ def index
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
Expand Down
1 change: 1 addition & 0 deletions app/controllers/super_admins/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true

class SuperAdmins::SessionsController < Devise::SessionsController
def nav_bar_profile = :superadmin
end
2 changes: 2 additions & 0 deletions app/controllers/super_admins_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
class SuperAdminsController < ApplicationController
before_action :authenticate_super_admin!

def nav_bar_profile = :superadmin

def edit_otp
end

Expand Down
5 changes: 3 additions & 2 deletions app/views/layouts/_account_dropdown.haml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
- if dossier.present? && dossier&.france_connected_with_one_identity?
%span
&nbsp;via FranceConnect
%span{ class: "fr-badge fr-badge--sm #{color_by_role(nav_bar_profile)}" }
= t("layouts.#{nav_bar_profile}")
- if nav_bar_profile != :guest # don't confuse user with unknown profile
%span{ class: "fr-badge fr-badge--sm #{color_by_role(nav_bar_profile)}" }
= t("layouts.#{nav_bar_profile}")
#account.fr-collapse.fr-menu
%ul.fr-menu__list.max-content
- if multiple_devise_profile_connect?
Expand Down
14 changes: 7 additions & 7 deletions app/views/layouts/_header.haml
Original file line number Diff line number Diff line change
@@ -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?
Expand Down Expand Up @@ -61,13 +61,13 @@
%li= render partial: 'layouts/locale_dropdown'


- if params[:controller] == 'recherche'
= render partial: 'layouts/search_dossiers_form'

- if is_instructeur_context
= render partial: 'layouts/search_dossiers_form'
= render partial: 'layouts/search_dossiers_form', locals: { context: :instructeur }

- elsif is_expert_context
= render partial: 'layouts/search_dossiers_form', locals: { context: :expert }

- if is_expert_context
- elsif params[:controller] == 'recherche'
= render partial: 'layouts/search_dossiers_form'

= render SwitchDomainBannerComponent.new(user: current_user)
Expand Down
1 change: 1 addition & 0 deletions app/views/layouts/_search_dossiers_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
%button.fr-btn--close.fr-btn{ "aria-controls" => "search-modal", :title => t('close_modal', scope: [:layouts, :header]) }= t('close_modal', scope: [:layouts, :header])
#search-473.fr-search-bar.fr-search-bar--lg
= form_tag recherche_index_path, method: :get, :role => "search", class: "flex width-100" do
= hidden_field_tag :context, local_assigns[:context]
= label_tag "q", t('views.users.dossiers.search.search_file'), class: 'sr-only'
= text_field_tag "q", "#{@search_terms if @search_terms.present?}", placeholder: t('views.users.dossiers.search.search_file'), class: "fr-input"
%button.fr-btn
Expand Down
37 changes: 34 additions & 3 deletions spec/controllers/recherche_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,43 @@
context 'with no query param it does not crash' do
subject { get :index, params: {} }

it { is_expected.to have_http_status(200) }

it 'returns 0 dossier' do
subject
expect(subject).to have_http_status(200)
expect(assigns(:projected_dossiers).count).to eq(0)
end
end

context 'nav bar profile in user context' do
subject { get(:index, params: {}).body }
render_views

it 'define user nav' do
expect(subject).to include "Mes dossiers"
expect(subject).to include "usager"
end
end

context 'nav bar profile in instructeur context' do
subject { get(:index, params: { context: :instructeur }).body }
render_views

it 'define instructeur nav' do
expect(subject).to include "Démarches"
expect(subject).to include "instructeur"
expect(subject).not_to include "Mes dossiers"
end
end

context 'nav bar profile in expert context' do
before { user.create_expert }
subject { get(:index, params: { context: :expert }).body }
render_views

it 'define expert nav' do
expect(subject).to include "Avis"
expect(subject).to include "expert"
expect(subject).not_to include "Mes dossiers"
end
end
end
end

0 comments on commit 58037f2

Please sign in to comment.