From e459f68ddbda25cd6120db5af50533fd430452ab Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Tue, 19 Nov 2024 13:18:55 +0100 Subject: [PATCH] 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