From e459f68ddbda25cd6120db5af50533fd430452ab Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Tue, 19 Nov 2024 13:18:55 +0100 Subject: [PATCH 1/3] refactor: account dropdown as component --- app/components/account_dropdown_component.rb | 24 ++++++++ .../account_dropdown_component.en.yml | 11 ++++ .../account_dropdown_component.fr.yml | 11 ++++ .../account_dropdown_component.html.haml} | 33 ++++++----- app/views/layouts/_header.haml | 2 +- config/locales/en.yml | 1 + config/locales/fr.yml | 1 + config/locales/layouts.en.yml | 9 +++ config/locales/layouts.fr.yml | 9 +++ .../views/layouts/_account_dropdown.en.yml | 21 ------- .../views/layouts/_account_dropdown.fr.yml | 21 ------- .../account_dropdown_component_spec.rb | 58 +++++++++++++++++++ 12 files changed, 142 insertions(+), 59 deletions(-) create mode 100644 app/components/account_dropdown_component.rb create mode 100644 app/components/account_dropdown_component/account_dropdown_component.en.yml create mode 100644 app/components/account_dropdown_component/account_dropdown_component.fr.yml rename app/{views/layouts/_account_dropdown.haml => components/account_dropdown_component/account_dropdown_component.html.haml} (67%) create mode 100644 config/locales/layouts.en.yml create mode 100644 config/locales/layouts.fr.yml delete mode 100644 config/locales/views/layouts/_account_dropdown.en.yml delete mode 100644 config/locales/views/layouts/_account_dropdown.fr.yml create mode 100644 spec/components/account_dropdown_component_spec.rb diff --git a/app/components/account_dropdown_component.rb b/app/components/account_dropdown_component.rb new file mode 100644 index 000000000..9c99f1ab5 --- /dev/null +++ b/app/components/account_dropdown_component.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class AccountDropdownComponent < ViewComponent::Base + attr_reader :dossier + attr_reader :nav_bar_profile + + delegate :current_email, :color_by_role, :multiple_devise_profile_connect?, + :user_signed_in?, :instructeur_signed_in?, :expert_signed_in?, + :administrateur_signed_in?, :gestionnaire_signed_in?, :super_admin_signed_in?, + to: :helpers + + def initialize(dossier:, nav_bar_profile:) + @dossier = dossier + @nav_bar_profile = nav_bar_profile + end + + def france_connected? + dossier&.france_connected_with_one_identity? + end + + def show_profile_badge? + nav_bar_profile != :guest + end +end diff --git a/app/components/account_dropdown_component/account_dropdown_component.en.yml b/app/components/account_dropdown_component/account_dropdown_component.en.yml new file mode 100644 index 000000000..faa86f7ec --- /dev/null +++ b/app/components/account_dropdown_component/account_dropdown_component.en.yml @@ -0,0 +1,11 @@ +en: + go_superadmin: 'Switch to super-admin' + go_user: 'Switch to user' + go_instructor: 'Switch to instructor' + go_expert: 'Switch to expert' + go_admin: 'Switch to administrator' + go_gestionnaire: 'Switch to admins group manager' + profile: 'See my profile' + logout: 'Log out' + my_account: 'My profile' + connected_as: 'connected as %{profile}' diff --git a/app/components/account_dropdown_component/account_dropdown_component.fr.yml b/app/components/account_dropdown_component/account_dropdown_component.fr.yml new file mode 100644 index 000000000..75e4844f8 --- /dev/null +++ b/app/components/account_dropdown_component/account_dropdown_component.fr.yml @@ -0,0 +1,11 @@ +fr: + go_superadmin: 'Passer en super-admin' + go_user: 'Passer en usager' + go_instructor: 'Passer en instructeur' + go_expert: 'Passer en expert' + go_admin: 'Passer en administrateur' + go_gestionnaire: 'Passer en gestionnaire' + profile: 'Voir mon profil' + logout: 'Se déconnecter' + my_account: 'Mon profil' + connected_as: 'connecté en tant qu’%{profile}' diff --git a/app/views/layouts/_account_dropdown.haml b/app/components/account_dropdown_component/account_dropdown_component.html.haml similarity index 67% rename from app/views/layouts/_account_dropdown.haml rename to app/components/account_dropdown_component/account_dropdown_component.html.haml index a9279b58f..71f71ea17 100644 --- a/app/views/layouts/_account_dropdown.haml +++ b/app/components/account_dropdown_component/account_dropdown_component.html.haml @@ -1,57 +1,58 @@ -%nav.fr-translate.fr-nav{ role: "navigation", "aria-label"=> t('my_account', scope: [:layouts]) } +%nav.fr-translate.fr-nav{ role: "navigation", "aria-label" => t('.my_account') } .fr-nav__item - %button.account-btn.fr-translate__btn.fr-btn{ "aria-controls" => "account", "aria-expanded" => "false", :title => t('my_account', scope: [:layouts]) } + %button.account-btn.fr-translate__btn.fr-btn{ "aria-controls" => "account", "aria-expanded" => "false", title: t('.my_account') } %span.fr-mr-1w= current_email - - if dossier.present? && dossier&.france_connected_with_one_identity? - %span -  via FranceConnect - - if nav_bar_profile != :guest # don't confuse user with unknown profile + - if france_connected? + %span  via FranceConnect + + - if show_profile_badge? %span{ class: "fr-badge fr-badge--sm #{color_by_role(nav_bar_profile)}" } - = t("layouts.#{nav_bar_profile}") + = t(nav_bar_profile, scope: :layouts) + #account.fr-collapse.fr-menu %ul.fr-menu__list.max-content - if multiple_devise_profile_connect? %li = link_to "#", class: "fr-nav__link", "aria-current" => "true" do - = t('layouts.connected_as', profile: t("layouts.#{nav_bar_profile}")) + = t('.connected_as', profile: t(nav_bar_profile, scope: :layouts)) - if user_signed_in? && nav_bar_profile != :user %li = link_to dossiers_path, class: "fr-nav__link" do %span.fr-icon-refresh-line.fr-icon--sm - = t('go_user', scope: [:layouts]) + = t('.go_user') - if instructeur_signed_in? && nav_bar_profile != :instructeur %li = link_to instructeur_procedures_path, class: "fr-nav__link" do %span.fr-icon-refresh-line.fr-icon--sm - = t('go_instructor', scope: [:layouts]) + = t('.go_instructor') - if expert_signed_in? && nav_bar_profile != :expert %li = link_to expert_all_avis_path, class: "fr-nav__link" do %span.fr-icon-refresh-line.fr-icon--sm - = t('go_expert', scope: [:layouts]) + = t('.go_expert') - if administrateur_signed_in? && nav_bar_profile != :administrateur %li = link_to admin_procedures_path, class: "fr-nav__link" do %span.fr-icon-refresh-line.fr-icon--sm - = t('go_admin', scope: [:layouts]) + = t('.go_admin') - if gestionnaire_signed_in? && nav_bar_profile != :gestionnaire %li = link_to gestionnaire_groupe_gestionnaires_path, class: "fr-nav__link" do %span.fr-icon-refresh-line.fr-icon--sm - = t('go_gestionnaire', scope: [:layouts]) + = t('.go_gestionnaire') - if super_admin_signed_in? && nav_bar_profile != :superadmin %li = link_to manager_root_path, class: "fr-nav__link" do %span.fr-icon-shield-line.fr-icon--sm - = t('go_superadmin', scope: [:layouts]) + = t('.go_superadmin') %li = link_to profil_path, class: "fr-nav__link" do %span.fr-icon-user-line.fr-icon--sm - = t('profile', scope: [:layouts]) + = t('.profile') %li = link_to destroy_user_session_path, method: :delete, class: "fr-nav__link" do %span.fr-icon-logout-box-r-line.fr-icon--sm - = t('logout', scope: [:layouts]) + = t('.logout') diff --git a/app/views/layouts/_header.haml b/app/views/layouts/_header.haml index d65475e72..7e3be7648 100644 --- a/app/views/layouts/_header.haml +++ b/app/views/layouts/_header.haml @@ -35,7 +35,7 @@ %ul.fr-btns-group.flex.align-center - if instructeur_signed_in? || user_signed_in? %li - = render partial: 'layouts/account_dropdown', locals: { nav_bar_profile: nav_bar_profile, dossier: dossier } + = render AccountDropdownComponent.new(dossier: @dossier, nav_bar_profile:) - elsif (request.path != new_user_session_path && request.path !=agent_connect_path) - if request.path == new_user_registration_path %li.fr-hidden-sm.fr-unhidden-lg.fr-link--sm.fr-mb-2w.fr-mr-1v= t('views.shared.account.already_user_question') diff --git a/config/locales/en.yml b/config/locales/en.yml index 0a7bf8a67..ce49adc4c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -84,6 +84,7 @@ en: back: "Back" back_title: "Back to my administration's website" main_menu: "Main menu" + files: "My files" locale_dropdown: select_locale: "Choose a language" locale_name: "English" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 1d512a13f..e2695a7d6 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -75,6 +75,7 @@ fr: back: "Revenir en arrière" back_title: "Revenir en arrière, sur le site de mon administration" main_menu: "Menu principal" + files: "Mes dossiers" locale_dropdown: select_locale: "Sélectionner une langue" locale_name: "Français" diff --git a/config/locales/layouts.en.yml b/config/locales/layouts.en.yml new file mode 100644 index 000000000..94c8abf29 --- /dev/null +++ b/config/locales/layouts.en.yml @@ -0,0 +1,9 @@ +en: + layouts: + instructeur: instructor + administrateur: admin + gestionnaire: admins group manager + superadmin: super-admin + expert: expert + user: user + guest: guest diff --git a/config/locales/layouts.fr.yml b/config/locales/layouts.fr.yml new file mode 100644 index 000000000..0e3206dc1 --- /dev/null +++ b/config/locales/layouts.fr.yml @@ -0,0 +1,9 @@ +fr: + layouts: + instructeur: instructeur + administrateur: administrateur + gestionnaire: gestionnaire + superadmin: super-admin + expert: expert + user: usager + guest: invité diff --git a/config/locales/views/layouts/_account_dropdown.en.yml b/config/locales/views/layouts/_account_dropdown.en.yml deleted file mode 100644 index 38307477f..000000000 --- a/config/locales/views/layouts/_account_dropdown.en.yml +++ /dev/null @@ -1,21 +0,0 @@ -en: - layouts: - header: - files: My files - go_superadmin: "Switch to super-admin" - go_user: "Switch to user" - go_instructor: "Switch to instructor" - go_expert: "Switch to expert" - go_admin: "Switch to administrator" - go_gestionnaire: "Switch to admins group manager" - profile: "See my profile" - logout: "Log out" - my_account: "My profile" - connected_as: "connected as %{profile}" - instructeur: instructor - administrateur: admin - gestionnaire: admins group manager - superadmin: super-admin - expert: expert - user: user - guest: guest diff --git a/config/locales/views/layouts/_account_dropdown.fr.yml b/config/locales/views/layouts/_account_dropdown.fr.yml deleted file mode 100644 index 6f0b6a4f5..000000000 --- a/config/locales/views/layouts/_account_dropdown.fr.yml +++ /dev/null @@ -1,21 +0,0 @@ -fr: - layouts: - header: - files: Mes dossiers - go_superadmin: "Passer en super-admin" - go_user: "Passer en usager" - go_instructor: "Passer en instructeur" - go_expert: "Passer en expert" - go_admin: "Passer en administrateur" - go_gestionnaire: "Passer en gestionnaire" - profile: "Voir mon profil" - logout: "Se déconnecter" - my_account: "Mon profil" - connected_as: "connecté en tant qu’%{profile}" - instructeur: instructeur - administrateur: administrateur - gestionnaire: gestionnaire - superadmin: super-admin - expert: expert - user: usager - guest: invité diff --git a/spec/components/account_dropdown_component_spec.rb b/spec/components/account_dropdown_component_spec.rb new file mode 100644 index 000000000..bd3ef8862 --- /dev/null +++ b/spec/components/account_dropdown_component_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +describe AccountDropdownComponent, type: :component do + let(:component) { described_class.new(dossier:, nav_bar_profile:) } + let(:dossier) { nil } + let(:nav_bar_profile) { :user } + let(:user) { build(:user) } + + subject { render_inline(component) } + + before do + allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(user) + allow_any_instance_of(ApplicationController).to receive(:super_admin_signed_in?).and_return(false) + end + + describe 'basic display' do + it 'shows user email' do + expect(subject).to have_text(user.email) + end + + context 'when guest profile' do + let(:nav_bar_profile) { :guest } + let(:user) { nil } + + it 'does not show profile badge' do + expect(subject).not_to have_css('.fr-badge') + end + end + end + + describe 'profile switching' do + context 'when user profile' do + let(:nav_bar_profile) { :user } + + before do + allow_any_instance_of(ApplicationController).to receive(:instructeur_signed_in?).and_return(true) + end + + it 'shows instructor switch option' do + expect(subject).to have_link('Passer en instructeur') + expect(subject).not_to have_link('Passer en usager') + end + end + + context 'when instructor profile' do + let(:nav_bar_profile) { :instructeur } + + before do + allow_any_instance_of(ApplicationController).to receive(:instructeur_signed_in?).and_return(true) + end + + it 'shows user switch option' do + expect(subject).to have_link('Passer en usager') + expect(subject).not_to have_link('Passer en instructeur') + end + end + end +end From c541ed7c9315e62ac35926219ccf447d495f7591 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Tue, 19 Nov 2024 14:50:19 +0100 Subject: [PATCH 2/3] feat(profile): keep procedure id context between admin & instructeur profile --- app/components/account_dropdown_component.rb | 18 ++++++++++++++++++ .../account_dropdown_component.html.haml | 4 ++-- .../account_dropdown_component_spec.rb | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/app/components/account_dropdown_component.rb b/app/components/account_dropdown_component.rb index 9c99f1ab5..0556acca3 100644 --- a/app/components/account_dropdown_component.rb +++ b/app/components/account_dropdown_component.rb @@ -21,4 +21,22 @@ class AccountDropdownComponent < ViewComponent::Base def show_profile_badge? nav_bar_profile != :guest end + + def instructeur_path + if controller_name == "procedures" && params[:id].present? + instructeur_procedure_path(params[:id]) + elsif params[:procedure_id].present? + instructeur_procedure_path(params[:procedure_id]) + else + instructeur_procedures_path + end + end + + def admin_path + if params[:procedure_id].present? + admin_procedure_path(params[:procedure_id]) + else + admin_procedures_path + end + end end diff --git a/app/components/account_dropdown_component/account_dropdown_component.html.haml b/app/components/account_dropdown_component/account_dropdown_component.html.haml index 71f71ea17..a8ee015c8 100644 --- a/app/components/account_dropdown_component/account_dropdown_component.html.haml +++ b/app/components/account_dropdown_component/account_dropdown_component.html.haml @@ -23,7 +23,7 @@ = t('.go_user') - if instructeur_signed_in? && nav_bar_profile != :instructeur %li - = link_to instructeur_procedures_path, class: "fr-nav__link" do + = link_to instructeur_path, class: "fr-nav__link" do %span.fr-icon-refresh-line.fr-icon--sm = t('.go_instructor') - if expert_signed_in? && nav_bar_profile != :expert @@ -33,7 +33,7 @@ = t('.go_expert') - if administrateur_signed_in? && nav_bar_profile != :administrateur %li - = link_to admin_procedures_path, class: "fr-nav__link" do + = link_to admin_path, class: "fr-nav__link" do %span.fr-icon-refresh-line.fr-icon--sm = t('.go_admin') - if gestionnaire_signed_in? && nav_bar_profile != :gestionnaire diff --git a/spec/components/account_dropdown_component_spec.rb b/spec/components/account_dropdown_component_spec.rb index bd3ef8862..786154ea5 100644 --- a/spec/components/account_dropdown_component_spec.rb +++ b/spec/components/account_dropdown_component_spec.rb @@ -55,4 +55,22 @@ describe AccountDropdownComponent, type: :component do end end end + + context 'when in procedures controller' do + before do + allow_any_instance_of(ApplicationController).to receive(:instructeur_signed_in?).and_return(true) + allow_any_instance_of(ApplicationController).to receive(:controller_name).and_return('procedures') + end + + context 'with procedure id' do + before do + allow_any_instance_of(ApplicationController).to receive(:params) + .and_return({ id: '123' }) + end + + it 'links to specific procedure for instructor' do + expect(subject.to_html).to include('/procedures/123') + end + end + end end From f25b1361eebe1d88902ab616b55c82047e983ee7 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Tue, 19 Nov 2024 15:51:11 +0100 Subject: [PATCH 3/3] fix(profile): senticify profiles list --- app/controllers/users/sessions_controller.rb | 2 +- spec/system/experts/expert_spec.rb | 2 +- spec/system/sessions/sign_in_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index 7b764fbff..e45f22ae0 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -20,7 +20,7 @@ class Users::SessionsController < Devise::SessionsController super if current_account.count > 1 - flash[:notice] = t("devise.sessions.signed_in_multiple_profile", roles: current_account.keys.map { |role| t("layouts.#{role}") }.join(', ')) + flash[:notice] = t("devise.sessions.signed_in_multiple_profile", roles: current_account.keys.map { |role| t("layouts.#{role}") }.to_sentence) end end diff --git a/spec/system/experts/expert_spec.rb b/spec/system/experts/expert_spec.rb index 433bead97..352c7947c 100644 --- a/spec/system/experts/expert_spec.rb +++ b/spec/system/experts/expert_spec.rb @@ -40,7 +40,7 @@ describe 'Inviting an expert:', js: true do visit new_user_session_path sign_in_with avis.expert.email, password - expect(page).to have_content('Vous pouvez à tout moment alterner entre vos différents profils : expert, usager.') + expect(page).to have_content('Vous pouvez à tout moment alterner entre vos différents profils : expert et usager.') expect(page).to have_current_path(expert_all_avis_path) end end diff --git a/spec/system/sessions/sign_in_spec.rb b/spec/system/sessions/sign_in_spec.rb index 2b76affa5..f4aa98da3 100644 --- a/spec/system/sessions/sign_in_spec.rb +++ b/spec/system/sessions/sign_in_spec.rb @@ -28,7 +28,7 @@ describe 'Signin in:' do sign_in_with user.email, password expect(page).to have_current_path admin_procedures_path - expect(page).to have_content('Vous êtes connecté(e) ! Vous pouvez à tout moment alterner entre vos différents profils : administrateur, instructeur, usager.') + expect(page).to have_content('Vous êtes connecté(e) ! Vous pouvez à tout moment alterner entre vos différents profils : administrateur, instructeur et usager.') end end