diff --git a/app/components/groupe_gestionnaire/groupe_gestionnaire_administrateurs/administrateur_component.rb b/app/components/groupe_gestionnaire/groupe_gestionnaire_administrateurs/administrateur_component.rb index 88cb19a0f..dce02837b 100644 --- a/app/components/groupe_gestionnaire/groupe_gestionnaire_administrateurs/administrateur_component.rb +++ b/app/components/groupe_gestionnaire/groupe_gestionnaire_administrateurs/administrateur_component.rb @@ -25,10 +25,20 @@ class GroupeGestionnaire::GroupeGestionnaireAdministrateurs::AdministrateurCompo def remove_button if is_there_at_least_another_active_admin? button_to 'Retirer', + remove_gestionnaire_groupe_gestionnaire_administrateur_path(@groupe_gestionnaire, @administrateur), + method: :delete, + class: 'fr-btn fr-btn--sm fr-btn--tertiary', + form: { data: { turbo: true, turbo_confirm: "Retirer « #{@administrateur.email} » des administrateurs de « #{@groupe_gestionnaire.name} » ?" } } + end + end + + def destroy_button + if is_there_at_least_another_active_admin? + button_to 'Supprimer', gestionnaire_groupe_gestionnaire_administrateur_path(@groupe_gestionnaire, @administrateur), method: :delete, - class: 'button', - form: { data: { turbo: true, turbo_confirm: "Retirer « #{@administrateur.email} » des administrateurs de « #{@groupe_gestionnaire.name} » ?" } } + class: 'fr-btn fr-btn--sm fr-btn--tertiary', + form: { data: { turbo: true, turbo_confirm: "Supprimer « #{@administrateur.email} » en tant qu'administrateurs ?" } } end end diff --git a/app/components/groupe_gestionnaire/groupe_gestionnaire_administrateurs/administrateur_component/administrateur_component.html.haml b/app/components/groupe_gestionnaire/groupe_gestionnaire_administrateurs/administrateur_component/administrateur_component.html.haml index 9678adb08..85fa63ecd 100644 --- a/app/components/groupe_gestionnaire/groupe_gestionnaire_administrateurs/administrateur_component/administrateur_component.html.haml +++ b/app/components/groupe_gestionnaire/groupe_gestionnaire_administrateurs/administrateur_component/administrateur_component.html.haml @@ -3,3 +3,4 @@ %td= created_at %td= registration_state %td= remove_button + %td= destroy_button diff --git a/app/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller.rb b/app/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller.rb index f45f7220b..d32d8783c 100644 --- a/app/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller.rb +++ b/app/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller.rb @@ -1,17 +1,99 @@ module Gestionnaires class GroupeGestionnaireAdministrateursController < GestionnaireController - before_action :retrieve_groupe_gestionnaire, except: [:new] + before_action :retrieve_groupe_gestionnaire def index end def create - administrateurs, flash[:alert], flash[:notice] = @groupe_gestionnaire.add_administrateurs(emails: [params.require(:administrateur)[:email]], current_user: current_gestionnaire) - @administrateur = administrateurs[0] + emails = [params.require(:administrateur)[:email]].to_json + emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) } + + administrateurs_to_add, valid_emails, invalid_emails = Administrateur.find_all_by_identifier_with_emails(emails:) + not_found_emails = valid_emails - administrateurs_to_add.map(&:email) + + # Send invitations to users without account + if not_found_emails.present? + administrateurs_to_add += not_found_emails.map do |email| + user = User.create_or_promote_to_administrateur(email, SecureRandom.hex) + user.invite_administrateur!(@groupe_gestionnaire) + user.administrateur + end + end + administrateurs_already_in_groupe_gestionnaire = [] + # We dont't want to assign a user to an groupe_gestionnaire if they are already assigned to it + administrateurs_duplicate = administrateurs_to_add & @groupe_gestionnaire.administrateurs + administrateurs_to_add -= @groupe_gestionnaire.administrateurs + administrateurs_to_add.each do |administrateur| + # We don't change administrateur.groupe_gestionnaire_id is administrateur already in another groupe_gestionnaire for which current_gestionnaire is not a gestionnaire or if current_gestionnaire is not a superAdmin + if !current_gestionnaire.is_a?(SuperAdmin) && + administrateur.groupe_gestionnaire_id && + ((administrateur.groupe_gestionnaire.ancestor_ids + [administrateur.groupe_gestionnaire_id]) & current_gestionnaire.groupe_gestionnaire_ids).empty? + administrateurs_already_in_groupe_gestionnaire << administrateur + next + end + @groupe_gestionnaire.add_administrateur(administrateur) + end + + if administrateurs_already_in_groupe_gestionnaire.present? + flash[:alert] = I18n.t('activerecord.errors.administrateurs_already_in_groupe_gestionnaire', + count: administrateurs_already_in_groupe_gestionnaire.size, + emails: administrateurs_already_in_groupe_gestionnaire) + end + + if invalid_emails.present? + flash[:alert] = I18n.t('activerecord.wrong_address', + count: invalid_emails.size, + emails: invalid_emails.join(', ')) + end + if administrateurs_duplicate.present? + flash[:alert] = I18n.t('activerecord.errors.duplicate_email', + count: invalid_emails.size, + emails: administrateurs_duplicate.map(&:email).join(', ')) + end + + if administrateurs_to_add.present? + flash[:notice] = I18n.t('groupe_gestionnaires.flash.notice.groupe_gestionnaire_administrateur.create') + + GroupeGestionnaireMailer + .notify_added_administrateurs(@groupe_gestionnaire, administrateurs_to_add, current_gestionnaire.email) + .deliver_later + end + + @administrateur = administrateurs_to_add[0] end def destroy - @administrateur, flash[:alert], flash[:notice] = @groupe_gestionnaire.remove_administrateur(params[:id], current_gestionnaire) + @administrateur = Administrateur.find(params[:id]) + if @groupe_gestionnaire.id != @administrateur.groupe_gestionnaire_id + flash[:alert] = I18n.t('groupe_gestionnaires.flash.alert.groupe_gestionnaire_administrateur.not_in_groupe_gestionnaire', email: @administrateur.email) + else + result = AdministrateurDeletionService.new(current_gestionnaire, @administrateur).call + + case result + in Dry::Monads::Result::Success + logger.info("L'administrateur #{@administrateur.id} est supprimé par le gestionnaire #{current_gestionnaire.id} depuis le groupe gestionnaire #{@groupe_gestionnaire.id}") + flash[:notice] = I18n.t('groupe_gestionnaires.flash.notice.groupe_gestionnaire_administrateur.destroy', email: @administrateur.email) + GroupeGestionnaireMailer + .notify_removed_administrateur(@groupe_gestionnaire, @administrateur.email, current_gestionnaire.email) + .deliver_later + in Dry::Monads::Result::Failure(reason) + flash[:alert] = I18n.t('groupe_gestionnaires.flash.alert.groupe_gestionnaire_administrateur.cannot_be_deleted', email: @administrateur.email) + end + end + end + + def remove + @administrateur = Administrateur.find(params[:id]) + if @groupe_gestionnaire.id != @administrateur.groupe_gestionnaire_id + flash[:alert] = I18n.t('groupe_gestionnaires.flash.alert.groupe_gestionnaire_administrateur.not_in_groupe_gestionnaire', email: @administrateur.email) + else + @administrateur.update(groupe_gestionnaire_id: nil) + flash[:notice] = I18n.t('groupe_gestionnaires.flash.notice.groupe_gestionnaire_administrateur.remove', email: @administrateur.email) + GroupeGestionnaireMailer + .notify_removed_administrateur(@groupe_gestionnaire, @administrateur.email, current_gestionnaire.email) + .deliver_later + end end end end diff --git a/app/controllers/gestionnaires/groupe_gestionnaire_children_controller.rb b/app/controllers/gestionnaires/groupe_gestionnaire_children_controller.rb index 081d48aaa..7ccdd1a5f 100644 --- a/app/controllers/gestionnaires/groupe_gestionnaire_children_controller.rb +++ b/app/controllers/gestionnaires/groupe_gestionnaire_children_controller.rb @@ -1,6 +1,6 @@ module Gestionnaires class GroupeGestionnaireChildrenController < GestionnaireController - before_action :retrieve_groupe_gestionnaire, except: [:new] + before_action :retrieve_groupe_gestionnaire def index end diff --git a/app/controllers/gestionnaires/groupe_gestionnaire_gestionnaires_controller.rb b/app/controllers/gestionnaires/groupe_gestionnaire_gestionnaires_controller.rb index d19366c35..dc129140e 100644 --- a/app/controllers/gestionnaires/groupe_gestionnaire_gestionnaires_controller.rb +++ b/app/controllers/gestionnaires/groupe_gestionnaire_gestionnaires_controller.rb @@ -1,17 +1,71 @@ module Gestionnaires class GroupeGestionnaireGestionnairesController < GestionnaireController - before_action :retrieve_groupe_gestionnaire, except: [:new] + before_action :retrieve_groupe_gestionnaire def index end def create - gestionnaires, flash[:alert], flash[:notice] = @groupe_gestionnaire.add_gestionnaires(emails: [params.require(:gestionnaire)[:email]], current_user: current_gestionnaire) - @gestionnaire = gestionnaires[0] + emails = [params.require(:gestionnaire)[:email]].to_json + emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) } + + gestionnaires_to_add, valid_emails, invalid_emails = Gestionnaire.find_all_by_identifier_with_emails(emails:) + not_found_emails = valid_emails - gestionnaires_to_add.map(&:email) + + # Send invitations to users without account + if not_found_emails.present? + gestionnaires_to_add += not_found_emails.map do |email| + user = User.create_or_promote_to_gestionnaire(email, SecureRandom.hex) + user.invite_gestionnaire!(@groupe_gestionnaire) + user.gestionnaire + end + end + + # We dont't want to assign a user to an groupe_gestionnaire if they are already assigned to it + gestionnaires_duplicate = gestionnaires_to_add & @groupe_gestionnaire.gestionnaires + gestionnaires_to_add -= @groupe_gestionnaire.gestionnaires + gestionnaires_to_add.each { @groupe_gestionnaire.add_gestionnaire(_1) } + + if invalid_emails.present? + flash[:alert] = I18n.t('activerecord.wrong_address', + count: invalid_emails.size, + emails: invalid_emails.join(', ')) + end + if gestionnaires_duplicate.present? + flash[:alert] = I18n.t('activerecord.errors.duplicate_email', + count: invalid_emails.size, + emails: gestionnaires_duplicate.map(&:email).join(', ')) + end + + if gestionnaires_to_add.present? + flash[:notice] = I18n.t('groupe_gestionnaires.flash.notice.groupe_gestionnaire_gestionnaire.create') + + GroupeGestionnaireMailer + .notify_added_gestionnaires(@groupe_gestionnaire, gestionnaires_to_add, current_gestionnaire.email) + .deliver_later + end + + @gestionnaire = gestionnaires_to_add[0] end def destroy - @gestionnaire, flash[:alert], flash[:notice] = @groupe_gestionnaire.remove_gestionnaire(params[:id], current_gestionnaire) + if !@groupe_gestionnaire.is_root? || @groupe_gestionnaire.gestionnaires.one? + flash[:alert] = I18n.t('groupe_gestionnaires.flash.alert.groupe_gestionnaire_gestionnaire.destroy_at_least_one') + else + @gestionnaire = Gestionnaire.find(params[:id]) + + if !@groupe_gestionnaire.in?(@gestionnaire.groupe_gestionnaires) || !@gestionnaire.groupe_gestionnaires.destroy(@groupe_gestionnaire) + flash[:alert] = I18n.t('groupe_gestionnaires.flash.alert.groupe_gestionnaire_gestionnaire.not_in_groupe_gestionnaire', email: @gestionnaire.email) + else + if @gestionnaire.groupe_gestionnaires.empty? + @gestionnaire.destroy + end + flash[:notice] = I18n.t('groupe_gestionnaires.flash.notice.groupe_gestionnaire_gestionnaire.destroy', email: @gestionnaire.email) + GroupeGestionnaireMailer + .notify_removed_gestionnaire(@groupe_gestionnaire, @gestionnaire.email, current_gestionnaire.email) + .deliver_later + end + end end end end diff --git a/app/controllers/manager/groupe_gestionnaires_controller.rb b/app/controllers/manager/groupe_gestionnaires_controller.rb index 3f41d93c5..1bc4922aa 100644 --- a/app/controllers/manager/groupe_gestionnaires_controller.rb +++ b/app/controllers/manager/groupe_gestionnaires_controller.rb @@ -1,25 +1,70 @@ module Manager class GroupeGestionnairesController < Manager::ApplicationController def add_gestionnaire - _gestionnaires, flash[:alert], flash[:notice] = groupe_gestionnaire.add_gestionnaires(emails: (params['emails'].presence || '').split(','), current_user: current_super_admin) + groupe_gestionnaire = GroupeGestionnaire.find(params[:id]) + emails = [params['emails'].presence || ''].to_json + emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) } + + gestionnaires_to_add, valid_emails, invalid_emails = Gestionnaire.find_all_by_identifier_with_emails(emails:) + not_found_emails = valid_emails - gestionnaires_to_add.map(&:email) + + # Send invitations to users without account + if not_found_emails.present? + gestionnaires_to_add += not_found_emails.map do |email| + user = User.create_or_promote_to_gestionnaire(email, SecureRandom.hex) + user.invite_gestionnaire!(groupe_gestionnaire) + user.gestionnaire + end + end + + # We dont't want to assign a user to an groupe_gestionnaire if they are already assigned to it + gestionnaires_duplicate = gestionnaires_to_add & groupe_gestionnaire.gestionnaires + gestionnaires_to_add -= groupe_gestionnaire.gestionnaires + gestionnaires_to_add.each { groupe_gestionnaire.add_gestionnaire(_1) } + + if invalid_emails.present? + flash[:alert] = I18n.t('activerecord.wrong_address', + count: invalid_emails.size, + emails: invalid_emails.join(', ')) + end + if gestionnaires_duplicate.present? + flash[:alert] = I18n.t('activerecord.errors.duplicate_email', + count: invalid_emails.size, + emails: gestionnaires_duplicate.map(&:email).join(', ')) + end + + if gestionnaires_to_add.present? + flash[:notice] = I18n.t('groupe_gestionnaires.flash.notice.groupe_gestionnaire_gestionnaire.create') + + GroupeGestionnaireMailer + .notify_added_gestionnaires(groupe_gestionnaire, gestionnaires_to_add, current_super_admin.email) + .deliver_later + end redirect_to manager_groupe_gestionnaire_path(groupe_gestionnaire) end def remove_gestionnaire - _gestionnaire, flash[:alert], flash[:notice] = groupe_gestionnaire.remove_gestionnaire(gestionnaire_id, current_super_admin) + groupe_gestionnaire = GroupeGestionnaire.find(params[:id]) + if !groupe_gestionnaire.is_root? || groupe_gestionnaire.gestionnaires.one? + flash[:alert] = I18n.t('groupe_gestionnaires.flash.alert.groupe_gestionnaire_gestionnaire.destroy_at_least_one') + else + gestionnaire = Gestionnaire.find(params[:gestionnaire][:id]) + + if !groupe_gestionnaire.in?(gestionnaire.groupe_gestionnaires) || !gestionnaire.groupe_gestionnaires.destroy(groupe_gestionnaire) + flash[:alert] = I18n.t('groupe_gestionnaires.flash.alert.groupe_gestionnaire_gestionnaire.not_in_groupe_gestionnaire', email: gestionnaire.email) + else + if gestionnaire.groupe_gestionnaires.empty? + gestionnaire.destroy + end + flash[:notice] = I18n.t('groupe_gestionnaires.flash.notice.groupe_gestionnaire_gestionnaire.destroy', email: gestionnaire.email) + GroupeGestionnaireMailer + .notify_removed_gestionnaire(groupe_gestionnaire, gestionnaire.email, current_super_admin.email) + .deliver_later + end + end redirect_to manager_groupe_gestionnaire_path(groupe_gestionnaire) end - - private - - def groupe_gestionnaire - @groupe_gestionnaire ||= GroupeGestionnaire.find(params[:id]) - end - - def gestionnaire_id - params[:gestionnaire][:id] - end end end diff --git a/app/models/concerns/user_find_by_concern.rb b/app/models/concerns/user_find_by_concern.rb index cb52c3b4e..1a1836607 100644 --- a/app/models/concerns/user_find_by_concern.rb +++ b/app/models/concerns/user_find_by_concern.rb @@ -1,7 +1,3 @@ -# Request a watermark on files attached to a `Champs::TitreIdentiteChamp`. -# -# We're using a class extension here, but we could as well have a periodic -# job that watermarks relevant attachments. module UserFindByConcern extend ActiveSupport::Concern @@ -15,7 +11,7 @@ module UserFindByConcern end def self.find_all_by_identifier_with_emails(ids: [], emails: []) - valid_emails, invalid_emails = emails.partition { URI::MailTo::EMAIL_REGEXP.match?(_1) } + valid_emails, invalid_emails = emails.partition { Devise.email_regexp.match?(_1) } [ where(id: ids).or(where(users: { email: valid_emails })).distinct(:id), diff --git a/app/models/groupe_gestionnaire.rb b/app/models/groupe_gestionnaire.rb index 57c8d40e5..2c44cf903 100644 --- a/app/models/groupe_gestionnaire.rb +++ b/app/models/groupe_gestionnaire.rb @@ -11,70 +11,6 @@ class GroupeGestionnaire < ApplicationRecord gestionnaires << gestionnaire end - def remove_gestionnaire(gestionnaire_id, current_user) - if !self.is_root? || self.gestionnaires.one? - alert = "Suppression impossible : il doit y avoir au moins un gestionnaire dans le groupe racine" - else - gestionnaire = Gestionnaire.find(gestionnaire_id) - - if !in?(gestionnaire.groupe_gestionnaires) || !gestionnaire.groupe_gestionnaires.destroy(self) - alert = "Le gestionnaire « #{gestionnaire.email} » n’est pas dans le groupe gestionnaire." - else - if gestionnaire.groupe_gestionnaires.empty? - gestionnaire.destroy - end - notice = "Le gestionnaire « #{gestionnaire.email} » a été retiré du groupe gestionnaire." - GroupeGestionnaireMailer - .notify_removed_gestionnaire(self, gestionnaire.email, current_user.email) - .deliver_later - end - end - [gestionnaire, alert, notice] - end - - def add_gestionnaires(ids: [], emails: [], current_user: nil) - emails = emails.to_json - emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) } - - gestionnaires_to_add, valid_emails, invalid_emails = Gestionnaire.find_all_by_identifier_with_emails(ids:, emails:) - not_found_emails = valid_emails - gestionnaires_to_add.map(&:email) - - # Send invitations to users without account - if not_found_emails.present? - gestionnaires_to_add += not_found_emails.map do |email| - user = User.create_or_promote_to_gestionnaire(email, SecureRandom.hex) - user.invite_gestionnaire!(self) - user.gestionnaire - end - end - - # We dont't want to assign a user to an groupe_gestionnaire if they are already assigned to it - gestionnaires_duplicate = gestionnaires_to_add & gestionnaires - gestionnaires_to_add -= gestionnaires - gestionnaires_to_add.each { add_gestionnaire(_1) } - - if invalid_emails.present? - alert = I18n.t('activerecord.wrong_address', - count: invalid_emails.size, - emails: invalid_emails) - end - if gestionnaires_duplicate.present? - alert = I18n.t('activerecord.errors.duplicate_email', - count: invalid_emails.size, - emails: gestionnaires_duplicate.map(&:email)) - end - - if gestionnaires_to_add.present? - notice = "Les gestionnaires ont bien été affectés au groupe gestionnaire" - - GroupeGestionnaireMailer - .notify_added_gestionnaires(self, gestionnaires_to_add, current_user.email) - .deliver_later - end - - [gestionnaires_to_add, alert, notice] - end - def add_administrateur(administrateur) return if administrateur.nil? return if id == administrateur.groupe_gestionnaire_id @@ -82,76 +18,6 @@ class GroupeGestionnaire < ApplicationRecord administrateurs << administrateur end - def remove_administrateur(administrateur_id, current_user) - administrateur = Administrateur.find(administrateur_id) - - if id != administrateur.groupe_gestionnaire_id - alert = "L'administrateur « #{administrateur.email} » n’est pas dans le groupe gestionnaire." - else - administrateur.destroy - notice = "L'administrateur « #{administrateur.email} » a été retiré du groupe gestionnaire." - GroupeGestionnaireMailer - .notify_removed_administrateur(self, administrateur.email, current_user.email) - .deliver_later - end - [administrateur, alert, notice] - end - - def add_administrateurs(ids: [], emails: [], current_user: nil) - emails = emails.to_json - emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) } - - administrateurs_to_add, valid_emails, invalid_emails = Administrateur.find_all_by_identifier_with_emails(ids:, emails:) - not_found_emails = valid_emails - administrateurs_to_add.map(&:email) - - # Send invitations to users without account - if not_found_emails.present? - administrateurs_to_add += not_found_emails.map do |email| - user = User.create_or_promote_to_administrateur(email, SecureRandom.hex) - user.invite_administrateur!(self) - user.administrateur - end - end - administrateurs_already_in_groupe_gestionnaire = [] - # We dont't want to assign a user to an groupe_gestionnaire if they are already assigned to it - administrateurs_duplicate = administrateurs_to_add & administrateurs - administrateurs_to_add -= administrateurs - administrateurs_to_add.each do |administrateur| - if !current_user.is_a?(SuperAdmin) && administrateur.groupe_gestionnaire_id && ((administrateur.groupe_gestionnaire.ancestor_ids + [administrateur.groupe_gestionnaire_id]) & current_user.groupe_gestionnaire_ids).empty? - administrateurs_already_in_groupe_gestionnaire << administrateur - next - end - add_administrateur(administrateur) - end - - if administrateurs_already_in_groupe_gestionnaire.present? - alert = I18n.t('activerecord.errors.administrateurs_already_in_groupe_gestionnaire', - count: administrateurs_already_in_groupe_gestionnaire.size, - emails: administrateurs_already_in_groupe_gestionnaire) - end - - if invalid_emails.present? - alert = I18n.t('activerecord.wrong_address', - count: invalid_emails.size, - emails: invalid_emails) - end - if administrateurs_duplicate.present? - alert = I18n.t('activerecord.errors.duplicate_email', - count: invalid_emails.size, - emails: administrateurs_duplicate.map(&:email)) - end - - if administrateurs_to_add.present? - notice = "Les administrateurs ont bien été affectés au groupe gestionnaire" - - GroupeGestionnaireMailer - .notify_added_administrateurs(self, administrateurs_to_add, current_user.email) - .deliver_later - end - - [administrateurs_to_add, alert, notice] - end - def can_be_deleted?(current_user) (gestionnaires.empty? || (gestionnaires == [current_user])) && administrateurs.empty? && children.empty? end diff --git a/app/views/gestionnaires/groupe_gestionnaire_administrateurs/index.html.haml b/app/views/gestionnaires/groupe_gestionnaire_administrateurs/index.html.haml index f2796c906..20e0a06c8 100644 --- a/app/views/gestionnaires/groupe_gestionnaire_administrateurs/index.html.haml +++ b/app/views/gestionnaires/groupe_gestionnaire_administrateurs/index.html.haml @@ -13,6 +13,7 @@ %th= 'Enregistré le' %th= 'État' %th + %th %tbody#administrateurs = render(GroupeGestionnaire::GroupeGestionnaireAdministrateurs::AdministrateurComponent.with_collection(@groupe_gestionnaire.administrateurs.order('users.email'), groupe_gestionnaire: @groupe_gestionnaire)) diff --git a/app/views/gestionnaires/groupe_gestionnaire_administrateurs/remove.turbo_stream.haml b/app/views/gestionnaires/groupe_gestionnaire_administrateurs/remove.turbo_stream.haml new file mode 100644 index 000000000..b72211119 --- /dev/null +++ b/app/views/gestionnaires/groupe_gestionnaire_administrateurs/remove.turbo_stream.haml @@ -0,0 +1,6 @@ += turbo_stream.update 'administrateurs' do + = render GroupeGestionnaire::GroupeGestionnaireAdministrateurs::AdministrateurComponent.with_collection(@groupe_gestionnaire.administrateurs.order('users.email'), groupe_gestionnaire: @groupe_gestionnaire) +- if @groupe_gestionnaire.administrateurs.one? + = turbo_stream.focus 'administrateur_email' +- else + = turbo_stream.focus_all '#administrateurs tr:first-child input[type="submit"]' diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 9502183c4..43edf443b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -886,6 +886,23 @@ fr: invalid_password: "Mauvais mot de passe" connection_done: "Les comptes FranceConnect et %{application_name} sont à présent fusionnés" merger_token_expired: "Le délai pour fusionner les comptes FranceConnect et %{application_name} est expirée. Veuillez recommencer la procédure pour vous fusionner les comptes." + groupe_gestionnaires: + flash: + alert: + groupe_gestionnaire_administrateur: + cannot_be_deleted: "L'administrateur « %{email} » ne peut pas être supprimé du groupe gestionnaire." + not_in_groupe_gestionnaire: "L'administrateur « %{email} » n’est pas dans le groupe gestionnaire." + groupe_gestionnaire_gestionnaire: + destroy_at_least_one: "Suppression impossible : il doit y avoir au moins un gestionnaire dans le groupe racine" + not_in_groupe_gestionnaire: "Le gestionnaire « %{email} » n’est pas dans le groupe gestionnaire." + notice: + groupe_gestionnaire_administrateur: + create: "Les administrateurs ont bien été affectés au groupe gestionnaire" + destroy: "L'administrateur « %{email} » a été supprimé." + remove: "L'administrateur « %{email} » a été retiré du groupe gestionnaire." + groupe_gestionnaire_gestionnaire: + create: "Les gestionnaires ont bien été affectés au groupe gestionnaire" + destroy: "Le gestionnaire « %{email} » a été retiré du groupe gestionnaire." shared: procedures: no_siret: "Vous n’avez pas renseigné le siret du service pour certaines de vos démarches. Merci de les modifier." diff --git a/config/locales/models/groupe_gestionnaire/fr.yml b/config/locales/models/groupe_gestionnaire/fr.yml index 211b5bb2e..6acbe8923 100644 --- a/config/locales/models/groupe_gestionnaire/fr.yml +++ b/config/locales/models/groupe_gestionnaire/fr.yml @@ -17,3 +17,6 @@ fr: wrong_address: one: "%{emails} n’est pas une adresse email valide" other: "%{emails} ne sont pas des adresses emails valides" + not_found: + one: "%{emails} n'a pas encore de compte." + other: "%{emails} n'ont pas encore de compte." diff --git a/config/routes.rb b/config/routes.rb index 82e55eec0..4aceb9f48 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -506,7 +506,9 @@ Rails.application.routes.draw do scope module: 'gestionnaires', as: 'gestionnaire' do resources :groupe_gestionnaires, path: 'groupes', only: [:index, :show, :create, :edit, :update, :destroy] do resources :gestionnaires, controller: 'groupe_gestionnaire_gestionnaires', only: [:index, :create, :destroy] - resources :administrateurs, controller: 'groupe_gestionnaire_administrateurs', only: [:index, :create, :destroy] + resources :administrateurs, controller: 'groupe_gestionnaire_administrateurs', only: [:index, :create, :destroy] do + delete :remove, on: :member + end resources :children, controller: 'groupe_gestionnaire_children', only: [:index, :create, :destroy] end end diff --git a/spec/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller_spec.rb b/spec/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller_spec.rb index 55f034f65..c5491297f 100644 --- a/spec/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller_spec.rb +++ b/spec/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller_spec.rb @@ -30,7 +30,7 @@ describe Gestionnaires::GroupeGestionnaireAdministrateursController, type: :cont groupe_gestionnaire.administrateurs << new_administrateur end - def remove_administrateur(administrateur) + def destroy(administrateur) delete :destroy, params: { groupe_gestionnaire_id: groupe_gestionnaire.id, @@ -39,11 +39,64 @@ describe Gestionnaires::GroupeGestionnaireAdministrateursController, type: :cont format: :turbo_stream end - context 'when there are many administrateurs' do - before { remove_administrateur(new_administrateur) } + context 'when administrateur is in the groupe_gestionnaire' do + before { destroy(new_administrateur) } + + it { expect(groupe_gestionnaire.reload.administrateurs.count).to eq(0) } + it { expect(flash.notice).to eq("L'administrateur « #{new_administrateur.email} » a été supprimé.") } + end + + context 'when administrateur has some procedure' do + let(:administrateur_with_procedure) { create(:administrateur) } + let!(:procedure) { create(:procedure_with_dossiers, administrateur: administrateur_with_procedure) } + before do + groupe_gestionnaire.administrateurs << administrateur_with_procedure + destroy(administrateur_with_procedure) + end + + it { expect(groupe_gestionnaire.reload.administrateurs.count).to eq(2) } + it { expect(flash.alert).to eq("L'administrateur « #{administrateur_with_procedure.email} » ne peut pas être supprimé du groupe gestionnaire.") } + end + + context 'when administrateur is not in the groupe_gestionnaire' do + let(:other_administrateur) { create(:administrateur) } + before { destroy(other_administrateur) } + + it { expect(groupe_gestionnaire.reload.administrateurs.count).to eq(1) } + it { expect(flash.alert).to eq("L'administrateur « #{other_administrateur.email} » n’est pas dans le groupe gestionnaire.") } + end + end + + describe '#remove' do + let(:gestionnaire) { create(:gestionnaire) } + let(:new_administrateur) { create(:administrateur) } + + before do + groupe_gestionnaire.administrateurs << new_administrateur + end + + def remove(administrateur) + delete :remove, + params: { + groupe_gestionnaire_id: groupe_gestionnaire.id, + id: administrateur.id + }, + format: :turbo_stream + end + + context 'when administrateur is in the groupe_gestionnaire' do + before { remove(new_administrateur) } it { expect(groupe_gestionnaire.reload.administrateurs.count).to eq(0) } it { expect(flash.notice).to eq("L'administrateur « #{new_administrateur.email} » a été retiré du groupe gestionnaire.") } end + + context 'when administrateur is not in the groupe_gestionnaire' do + let(:other_administrateur) { create(:administrateur) } + before { remove(other_administrateur) } + + it { expect(groupe_gestionnaire.reload.administrateurs.count).to eq(1) } + it { expect(flash.alert).to eq("L'administrateur « #{other_administrateur.email} » n’est pas dans le groupe gestionnaire.") } + end end end diff --git a/spec/models/groupe_gestionnaire_spec.rb b/spec/models/groupe_gestionnaire_spec.rb index d3f29b7c4..604ac9a29 100644 --- a/spec/models/groupe_gestionnaire_spec.rb +++ b/spec/models/groupe_gestionnaire_spec.rb @@ -16,27 +16,6 @@ describe GroupeGestionnaire, type: :model do end end - describe "#add_gestionnaires" do - let(:groupe_gestionnaire) { create(:groupe_gestionnaire) } - let(:gestionnaire) { create(:gestionnaire) } - let(:gestionnaire_to_add) { create(:gestionnaire) } - - it 'adds the gestionnaire by id' do - groupe_gestionnaire.add_gestionnaires(ids: [gestionnaire_to_add.id], current_user: gestionnaire) - expect(groupe_gestionnaire.reload.gestionnaires).to include(gestionnaire_to_add) - end - - it 'adds the existing gestionnaire by email' do - groupe_gestionnaire.add_gestionnaires(emails: [gestionnaire_to_add.email], current_user: gestionnaire) - expect(groupe_gestionnaire.reload.gestionnaires).to include(gestionnaire_to_add) - end - - it 'adds the new gestionnaire by email' do - groupe_gestionnaire.add_gestionnaires(emails: ['new_gestionnaire@ds.fr'], current_user: gestionnaire) - expect(groupe_gestionnaire.reload.gestionnaires.last.email).to eq('new_gestionnaire@ds.fr') - end - end - describe "#add_administrateur" do let(:groupe_gestionnaire) { create(:groupe_gestionnaire) } let(:gestionnaire) { create(:gestionnaire) } @@ -49,47 +28,4 @@ describe GroupeGestionnaire, type: :model do expect(groupe_gestionnaire.reload.administrateurs).to include(administrateur) end end - - describe "#add_administrateurs" do - let(:gestionnaire) { create(:gestionnaire) } - let(:groupe_gestionnaire) { create(:groupe_gestionnaire, gestionnaires: [gestionnaire]) } - let(:administrateur) { create(:administrateur) } - - it 'adds the administrateur by id' do - groupe_gestionnaire.add_administrateurs(ids: [administrateur.id], current_user: gestionnaire) - expect(groupe_gestionnaire.reload.administrateurs).to include(administrateur) - end - - it 'adds the existing administrateur by email' do - groupe_gestionnaire.add_administrateurs(emails: [administrateur.email], current_user: gestionnaire) - expect(groupe_gestionnaire.reload.administrateurs).to include(administrateur) - end - - context "when administrateurs_already_in_groupe_gestionnaire" do - let(:other_groupe_gestionnaire) { create(:groupe_gestionnaire) } - let(:administrateur) { create(:administrateur, groupe_gestionnaire_id: other_groupe_gestionnaire.id) } - it 'does not add the existing administrateur by email' do - groupe_gestionnaire.add_administrateurs(emails: [administrateur.email], current_user: gestionnaire) - expect(groupe_gestionnaire.reload.administrateurs).not_to include(administrateur) - end - end - - it 'adds the new administrateur by email' do - groupe_gestionnaire.add_administrateurs(emails: ['new_administrateur@ds.fr'], current_user: gestionnaire) - expect(groupe_gestionnaire.reload.administrateurs.last.email).to eq('new_administrateur@ds.fr') - end - end - - describe "#remove_administrateur" do - let(:gestionnaire) { create(:gestionnaire) } - let(:groupe_gestionnaire) { create(:groupe_gestionnaire, gestionnaires: [gestionnaire]) } - let!(:administrateur) { create(:administrateur, groupe_gestionnaire_id: groupe_gestionnaire.id) } - - it 'removes the administrateur by id' do - expect(groupe_gestionnaire.reload.administrateurs.size).to eq(1) - groupe_gestionnaire.remove_administrateur(administrateur.id, gestionnaire) - expect(groupe_gestionnaire.reload.administrateurs).not_to include(administrateur) - expect(groupe_gestionnaire.reload.administrateurs.size).to eq(0) - end - end end