feat: remove_gestionnaire

This commit is contained in:
seb-by-ouidou 2023-08-29 17:08:27 +00:00 committed by seb-by-ouidou
parent b100c8380e
commit d5637ac7aa
55 changed files with 400 additions and 537 deletions

View file

@ -1,9 +0,0 @@
module AdminsGroupManagers
class AdminsGroupManagerController < ApplicationController
before_action :authenticate_admins_group_manager!
def nav_bar_profile
:admins_group_manager
end
end
end

View file

@ -1,14 +0,0 @@
module AdminsGroupManagers
class AdminsGroupsController < AdminsGroupManagerController
def index
@admins_groups = admins_groups
end
private
def admins_groups
admins_group_ids = current_admins_group_manager.admins_group_ids
AdminsGroup.where(id: admins_group_ids.compact.uniq)
end
end
end

View file

@ -1,4 +0,0 @@
module Manager
class AdminsGroupManagersController < Manager::ApplicationController
end
end

View file

@ -1,32 +0,0 @@
module Manager
class AdminsGroupsController < Manager::ApplicationController
def add_admins_group_manager
emails = (params['emails'].presence || '').split(',').to_json
emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
admins_group_managers, invalid_emails = admins_group.add_admins_group_managers(emails:)
if invalid_emails.present?
flash[:alert] = t('.wrong_address',
count: invalid_emails.size,
emails: invalid_emails)
end
if admins_group_managers.present?
flash[:notice] = "Les gestionnaires ont bien été affectés au groupe d'administrateurs"
AdminsGroupMailer
.notify_added_admins_group_managers(admins_group, admins_group_managers, current_super_admin.email)
.deliver_later
end
redirect_to manager_admins_groups_path(admins_group)
end
private
def admins_group
@admins_group ||= AdminsGroup.find(params[:id])
end
end
end

View file

@ -20,7 +20,25 @@ module Manager
.deliver_later
end
redirect_to manager_groupe_gestionnaires_path(groupe_gestionnaire)
redirect_to manager_groupe_gestionnaire_path(groupe_gestionnaire)
end
def remove_gestionnaire
if !groupe_gestionnaire.root_groupe_gestionnaire? || groupe_gestionnaire.gestionnaires.one?
flash[:alert] = "Suppression impossible : il doit y avoir au moins un gestionnaire dans le groupe racine"
else
gestionnaire = Gestionnaire.find(gestionnaire_id)
if groupe_gestionnaire.remove(gestionnaire)
flash[:notice] = "Le gestionnaire « #{gestionnaire.email} » a été retiré du groupe."
GroupeGestionnaireMailer
.notify_removed_gestionnaire(groupe_gestionnaire, gestionnaire, current_super_admin.email)
.deliver_later
else
flash[:alert] = "Le gestionnaire « #{gestionnaire.email} » nest pas dans le groupe."
end
end
redirect_to manager_groupe_gestionnaire_path(groupe_gestionnaire)
end
private
@ -28,5 +46,9 @@ module Manager
def groupe_gestionnaire
@groupe_gestionnaire ||= GroupeGestionnaire.find(params[:id])
end
def gestionnaire_id
params[:gestionnaire][:id]
end
end
end

View file

@ -1,54 +0,0 @@
require "administrate/base_dashboard"
class AdminsGroupDashboard < Administrate::BaseDashboard
# ATTRIBUTE_TYPES
# a hash that describes the type of each of the model's fields.
#
# Each different type represents an Administrate::Field object,
# which determines how the attribute is displayed
# on pages throughout the dashboard.
ATTRIBUTE_TYPES = {
id: Field::Number,
name: Field::String,
created_at: Field::DateTime,
updated_at: Field::DateTime,
admins_group_managers: Field::HasMany,
administrateurs: Field::HasMany
}.freeze
# COLLECTION_ATTRIBUTES
# an array of attributes that will be displayed on the model's index page.
#
# By default, it's limited to four items to reduce clutter on index pages.
# Feel free to add, remove, or rearrange items.
COLLECTION_ATTRIBUTES = [
:id,
:created_at,
:name,
:admins_group_managers,
:administrateurs
].freeze
# SHOW_PAGE_ATTRIBUTES
# an array of attributes that will be displayed on the model's show page.
SHOW_PAGE_ATTRIBUTES = [
:admins_group_managers,
:administrateurs,
:id,
:created_at
].freeze
# FORM_ATTRIBUTES
# an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [
:name
].freeze
# Overwrite this method to customize how users are displayed
# across all pages of the admin dashboard.
#
def display_resource(admins_group)
admins_group.name
end
end

View file

@ -1,57 +0,0 @@
require "administrate/base_dashboard"
class AdminsGroupManagerDashboard < Administrate::BaseDashboard
# ATTRIBUTE_TYPES
# a hash that describes the type of each of the model's fields.
#
# Each different type represents an Administrate::Field object,
# which determines how the attribute is displayed
# on pages throughout the dashboard.
ATTRIBUTE_TYPES = {
id: Field::Number,
user: Field::HasOne.with_options(searchable: true, searchable_field: 'email'),
created_at: Field::DateTime,
updated_at: Field::DateTime,
admins_groups: Field::HasMany.with_options(limit: 20),
registration_state: Field::String.with_options(searchable: false),
email: Field::Email.with_options(searchable: false)
}.freeze
# COLLECTION_ATTRIBUTES
# an array of attributes that will be displayed on the model's index page.
#
# By default, it's limited to four items to reduce clutter on index pages.
# Feel free to add, remove, or rearrange items.
COLLECTION_ATTRIBUTES = [
:id,
:user,
:created_at,
:admins_groups,
:registration_state
].freeze
# SHOW_PAGE_ATTRIBUTES
# an array of attributes that will be displayed on the model's show page.
SHOW_PAGE_ATTRIBUTES = [
:id,
:user,
:created_at,
:updated_at,
:registration_state,
:admins_groups
].freeze
# FORM_ATTRIBUTES
# an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [
:email
].freeze
# Overwrite this method to customize how users are displayed
# across all pages of the admin dashboard.
#
def display_resource(admins_group_manager)
admins_group_manager.email
end
end

View file

@ -1,13 +0,0 @@
class AdminsGroupMailer < ApplicationMailer
layout 'mailers/layout'
def notify_added_admins_group_managers(admins_group, added_admins_group_managers, current_super_admin_email)
added_admins_group_manager_emails = added_admins_group_managers.map(&:email)
@admins_group = admins_group
@current_super_admin_email = current_super_admin_email
subject = "Vous avez été ajouté(e) en tant que gestionnaire du groupe d'administrateur \"#{admins_group.name}\""
mail(bcc: added_admins_group_manager_emails, subject: subject)
end
end

View file

@ -1,6 +1,14 @@
class GroupeGestionnaireMailer < ApplicationMailer
layout 'mailers/layout'
def notify_removed_gestionnaire(groupe_gestionnaire, removed_gestionnaire, current_super_admin_email)
@groupe_gestionnaire = groupe_gestionnaire
@current_super_admin_email = current_super_admin_email
subject = "Vous avez été retiré(e) du groupe d'administrateur \"#{groupe_gestionnaire.name}\""
mail(to: removed_gestionnaire.email, subject: subject)
end
def notify_added_gestionnaires(groupe_gestionnaire, added_gestionnaires, current_super_admin_email)
added_gestionnaire_emails = added_gestionnaires.map(&:email)
@groupe_gestionnaire = groupe_gestionnaire

View file

@ -1,30 +0,0 @@
class AdminsGroup < ApplicationRecord
belongs_to :admins_group, optional: true # parent
has_many :children, class_name: "AdminsGroup", inverse_of: :admins_group
has_many :administrateurs
has_and_belongs_to_many :admins_group_managers
def add(admins_group_manager)
admins_group_managers << admins_group_manager
end
def add_admins_group_managers(ids: [], emails: [])
admins_group_managers_to_add, valid_emails, invalid_emails = AdminsGroupManager.find_all_by_identifier_with_emails(ids:, emails:)
not_found_emails = valid_emails - admins_group_managers_to_add.map(&:email)
# Send invitations to users without account
if not_found_emails.present?
admins_group_managers_to_add += not_found_emails.map do |email|
user = User.create_or_promote_to_admins_group_manager(email, SecureRandom.hex)
user.invite_admins_group_manager!(self)
user.admins_group_manager
end
end
# We dont't want to assign a user to an admins_group if they are already assigned to it
admins_group_managers_to_add -= admins_group_managers
admins_group_managers_to_add.each { add(_1) }
[admins_group_managers_to_add, invalid_emails]
end
end

View file

@ -1,41 +0,0 @@
class AdminsGroupManager < ApplicationRecord
has_and_belongs_to_many :admins_groups
belongs_to :user
delegate :email, to: :user
default_scope { eager_load(:user) }
def self.by_email(email)
find_by(users: { email: email })
end
def self.find_all_by_identifier(ids: [], emails: [])
find_all_by_identifier_with_emails(ids:, emails:).first
end
def self.find_all_by_identifier_with_emails(ids: [], emails: [])
valid_emails, invalid_emails = emails.partition { URI::MailTo::EMAIL_REGEXP.match?(_1) }
[
where(id: ids).or(where(users: { email: valid_emails })).distinct(:id),
valid_emails,
invalid_emails
]
end
def can_be_deleted?
!(root_admins_group = admins_groups.where(admins_group: nil).first) || root_admins_group.admins_group_managers.size > 1
end
def registration_state
if user.active?
'Actif'
elsif user.reset_password_period_valid?
'En attente'
else
'Expiré'
end
end
end

View file

@ -4,10 +4,24 @@ class GroupeGestionnaire < ApplicationRecord
has_many :administrateurs
has_and_belongs_to_many :gestionnaires
def root_groupe_gestionnaire?
groupe_gestionnaire.nil?
end
def add(gestionnaire)
return if gestionnaire.nil?
return if in?(gestionnaire.groupe_gestionnaires)
gestionnaires << gestionnaire
end
def remove(gestionnaire)
return if gestionnaire.nil?
return if !in?(gestionnaire.groupe_gestionnaires)
gestionnaire.groupe_gestionnaires.destroy(self)
end
def add_gestionnaires(ids: [], emails: [])
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)

View file

@ -1,6 +0,0 @@
%p= t(:hello, scope: [:views, :shared, :greetings])
%p
= t(".email_body", admins_group_name: @admins_group.name, email: @current_super_admin_email, application_name: APPLICATION_NAME)
= render partial: "layouts/mailers/signature"

View file

@ -1,17 +0,0 @@
= render partial: 'admins_group_managers/breadcrumbs',
locals: { steps: [['Groupes d\'administrateurs', admins_group_manager_admins_groups_path]] }
#admins_groups-index.container
%h1.fr-h1 Liste des groupes d'administrateurs
%table.fr-table.width-100.mt-3
%thead
%tr
%th{ scope: "col" }
Nom
%tbody
- @admins_groups.each do |admins_group|
%tr
%td
= admins_group.name

View file

@ -0,0 +1,17 @@
= render partial: 'gestionnaires/breadcrumbs',
locals: { steps: [['Groupes d\'administrateurs', gestionnaire_groupe_gestionnaires_path]] }
#groupe_gestionnaires-index.container
%h1.fr-h1 Liste des groupes d'administrateurs
%table.fr-table.width-100.mt-3
%thead
%tr
%th{ scope: "col" }
Nom
%tbody
- @groupe_gestionnaires.each do |groupe_gestionnaire|
%tr
%td
= groupe_gestionnaire.name

View file

@ -0,0 +1,6 @@
%p= t(:hello, scope: [:views, :shared, :greetings])
%p
= t(".email_body", groupe_gestionnaire_name: @groupe_gestionnaire.name, email: @current_super_admin_email, application_name: APPLICATION_NAME)
= render partial: "layouts/mailers/signature"

View file

@ -0,0 +1,17 @@
<% if existing_action?(collection_presenter.resource_name, :edit) %>
<td><%= link_to(
t("administrate.actions.edit"),
[:edit, namespace, resource],
class: "action-edit",
) if accessible_action?(resource, :edit) %></td>
<% end %>
<% if existing_action?(collection_presenter.resource_name, :destroy) %>
<td><%= link_to(
t("administrate.actions.destroy"),
[namespace, resource],
class: "text-color-red",
method: :delete,
data: { confirm: t("administrate.actions.confirm") }
) if accessible_action?(resource, :destroy) %></td>
<% end %>

View file

@ -0,0 +1,27 @@
<% content_for(:title) do %>
<%= display_resource_name(page.resource_name) %>
<% end %>
<header class="main-content__header">
<h1 class="main-content__page-title" id="page-title">
<%= content_for(:title) %>
</h1>
<% if show_search_bar %>
<%= render(
"search",
search_term: search_term,
resource_name: display_resource_name(page.resource_name)
) %>
<% end %>
<div>
<%= link_to(
t(
"manager.gestionnaires.manage_root_groupe_gestionnaire"
),
manager_groupe_gestionnaires_path,
class: "button",
) %>
</div>
</header>

View file

@ -0,0 +1,81 @@
<% if attribute.resources.any? %>
<% order = attribute.order_from_params(params.fetch(attribute.name, {})) %>
<% page_number = params.fetch(attribute.name, {}).fetch(:page, nil) %>
<table aria-labelledby="<%= attribute.name %>">
<thead>
<tr>
<% attribute.associated_collection(order).attribute_types.select{ |attr_name, attr_type| [:id, :user].include?(attr_name) }.each do |attr_name, attr_type| %>
<th class="cell-label
cell-label--<%= attr_type.html_class %>
cell-label--<%= attribute.associated_collection(order).ordered_html_class(attr_name) %>
cell-label--<%= "#{attribute.associated_collection(order).resource_name}_#{attr_name}" %>"
scope="col"
aria-sort="<%= sort_order(attribute.associated_collection(order).ordered_html_class(attr_name)) %>">
<%= link_to(sanitized_order_params(page, attribute.name).merge(
attribute.associated_collection(order).order_params_for(attr_name, key: attribute.name)
)) do %>
<%= t(
"helpers.label.#{attribute.associated_collection(order).resource_name}.#{attr_name}",
default: attribute.associated_class.human_attribute_name(attr_name).titleize,
) %>
<% if attribute.associated_collection(order).ordered_by?(attr_name) %>
<span class="cell-label__sort-indicator cell-label__sort-indicator--<%= attribute.associated_collection(order).ordered_html_class(attr_name) %>">
<svg aria-hidden="true">
<use xlink:href="#icon-up-caret" />
</svg>
</span>
<% end %>
<% end %>
</th>
<% end %>
<% [false && existing_action?(attribute.associated_collection(order).resource_name, :edit),
existing_action?(attribute.associated_collection(order).resource_name, :destroy)].count(true).times do %>
<th scope="col"></th>
<% end %>
</tr>
</thead>
<tbody>
<% attribute.resources(page_number, order).each do |resource| %>
<tr class="js-table-row">
<% attribute.associated_collection(order).attributes_for(resource).select{ |field| ["id", "user"].include?(field.name) }.each do |field| %>
<td class="cell-data cell-data--<%= field.html_class %>">
<%= render_field field %>
</td>
<% end %>
<% if false %>
<td><%= link_to(
t("administrate.actions.edit"),
[:edit, namespace, resource],
class: "action-edit",
) if accessible_action?(resource, :edit) %></td>
<% end %>
<% if existing_action?(attribute.associated_collection(order).resource_name, :destroy) %>
<td class="actions"><%= button_to 'Retirer',
{ action: :remove_gestionnaire, id: page.resource.id },
{ method: :delete,
data: { confirm: t("administrate.actions.confirm") },
params: { gestionnaire: { id: resource.id }},
class: 'fr-btn fr-btn--secondary' }
%></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<% if attribute.more_than_limit? %>
<%= render("pagination", resources: attribute.resources(page_number), param_name: "#{attribute.name}[page]") %>
<% end %>
<% else %>
<%= t("administrate.fields.has_many.none", default: "") %>
<% end %>
<%= form_tag(add_gestionnaire_manager_groupe_gestionnaire_path(page.resource), style: 'margin-top: 1rem;') do %>
<%= email_field_tag(:emails, '', placeholder: 'Emails', autocapitalize: 'off', autocorrect: 'off', spellcheck: 'false', style: 'margin-bottom: 1rem;width:24rem;') %>
<button>Ajouter un gestionnaire</button>
<% end %>

View file

@ -15,8 +15,8 @@ as well as a link to its edit page.
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Show
%>
<% content_for(:title) { t("administrate.actions.show_resource", name: page.page_title) } %>
<% admins_group = page.resource %>
<header class="main-content__header" role="banner">
<h1 class="main-content__page-title">
@ -28,9 +28,16 @@ as well as a link to its edit page.
t("administrate.actions.edit_resource", name: page.page_title),
[:edit, namespace, page.resource],
class: "button",
) if valid_action? :edit %>
</div>
) if accessible_action?(page.resource, :edit) %>
<%= link_to(
t("administrate.actions.destroy"),
[namespace, page.resource],
class: "button button--danger",
method: :delete,
data: { confirm: t("administrate.actions.confirm") }
) if accessible_action?(page.resource, :destroy) %>
</div>
</header>
<section class="main-content__body">
@ -39,18 +46,21 @@ as well as a link to its edit page.
<dt class="attribute-label" id="<%= attribute.name %>">
<%= t(
"helpers.label.#{resource_name}.#{attribute.name}",
default: attribute.name.titleize,
default: page.resource.class.human_attribute_name(attribute.name),
) %>
</dt>
<dd class="attribute-data attribute-data--<%=attribute.html_class%>">
<%= render_field attribute, page: page %>
<% if attribute.name == 'admins_group_managers' %>
<%= form_tag(add_admins_group_manager_manager_admins_group_path(admins_group), style: 'margin-top: 1rem;') do %>
<%= email_field_tag(:emails, '', placeholder: 'Emails', autocapitalize: 'off', autocorrect: 'off', spellcheck: 'false', style: 'margin-bottom: 1rem;width:24rem;') %>
<button>Ajouter un gestionnaire</button>
<% if attribute.name == 'gestionnaires' %>
<%= render(
"collection_gestionnaires",
page: page,
attribute: attribute
) %>
<% else %>
<%= render_field attribute, page: page %>
<% end %>
<% end %>
</dd>
<% end %>
</dl>

View file

@ -1,13 +0,0 @@
- content_for(:title, 'Activation de votre compte gestionnaire')
%p
Bonjour,
%p
Vous venez dêtre nommé gestionnaire du groupe #{@admins_group.name} sur #{APPLICATION_NAME}.
%p
Votre compte a été créé pour l'adresse email #{@user.email}. Pour lactiver, nous vous invitons à cliquer sur le lien suivant : 
= link_to(users_activate_url(token: @reset_password_token), users_activate_url(token: @reset_password_token))
= render partial: "layouts/mailers/signature"