Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ETQ gestionnaire, j'ai un suivi des messages au sein de mes groupes #9664

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/assets/stylesheets/groupe_gestionnaire_cards.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.fr-groupe_gestionnaire_cards {
.fr-h6 {
padding-left: 20px;
padding-right: 20px;
position: relative;
}

.notifications {
top: 3px;
right: 3px;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class GroupeGestionnaire::Card::AdministrateursComponent < ApplicationComponent
def initialize(groupe_gestionnaire:, path:)
def initialize(groupe_gestionnaire:, path:, is_gestionnaire: true)
@groupe_gestionnaire = groupe_gestionnaire
@path = path
@is_gestionnaire = is_gestionnaire
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
%p.fr-tag= @groupe_gestionnaire.administrateurs.size
%h3.fr-h6
= t('.title', count: @groupe_gestionnaire.administrateurs.size)
%p.fr-btn.fr-btn--tertiary= t('views.shared.actions.edit')
%p.fr-btn.fr-btn--tertiary= @is_gestionnaire ? t('views.shared.actions.edit') : t('views.shared.actions.see')
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class GroupeGestionnaire::Card::CommentairesComponent < ApplicationComponent
def initialize(groupe_gestionnaire:, administrateur:, path:)
def initialize(groupe_gestionnaire:, administrateur:, path:, unread_commentaires: nil)
@groupe_gestionnaire = groupe_gestionnaire
@administrateur = administrateur
@path = path
@unread_commentaires = unread_commentaires
end

def number_commentaires
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
.fr-col-6.fr-col-md-4.fr-col-lg-3
= link_to @path, id: 'administrateurs', class: 'fr-tile fr-enlarge-link' do
= link_to @path, id: 'commentaires', class: 'fr-tile fr-enlarge-link' do
.fr-tile__body.flex.column.align-center.justify-between
%p.fr-badge.fr-badge--success Validé
%div
.line-count.fr-my-1w
%p.fr-tag= number_commentaires
%h3.fr-h6
- if @unread_commentaires
%span.notifications{ 'aria-label': 'notifications' }
= t('.title', count: number_commentaires)
%p.fr-btn.fr-btn--tertiary= t('views.shared.actions.see')
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class GroupeGestionnaire::Card::GestionnairesComponent < ApplicationComponent
def initialize(groupe_gestionnaire:, path:)
def initialize(groupe_gestionnaire:, path:, is_gestionnaire: true)
@groupe_gestionnaire = groupe_gestionnaire
@path = path
@is_gestionnaire = is_gestionnaire
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
%p.fr-tag= @groupe_gestionnaire.gestionnaires.size
%h3.fr-h6
= t('.title', count: @groupe_gestionnaire.gestionnaires.size)
%p.fr-btn.fr-btn--tertiary= t('views.shared.actions.edit')
%p.fr-btn.fr-btn--tertiary= @is_gestionnaire ? t('views.shared.actions.edit') : t('views.shared.actions.see')
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
class GroupeGestionnaire::GroupeGestionnaireCommentaires::CommentaireComponent < ApplicationComponent
include ApplicationHelper

def initialize(commentaire:, connected_user:, is_gestionnaire: true)
def initialize(commentaire:, connected_user:, commentaire_seen_at: nil, is_gestionnaire: true)
@commentaire = commentaire
@connected_user = connected_user
@is_gestionnaire = is_gestionnaire
@groupe_gestionnaire = commentaire.groupe_gestionnaire
@commentaire_seen_at = commentaire_seen_at
end

private

def highlight_if_unseen_class
if highlight?
'highlighted'
end
end

def scroll_to_target
if highlight?
{ scroll_to_target: 'to' }
end
end

def commentaire_issuer
if @commentaire.sent_by?(@connected_user)
t('.you')
Expand All @@ -22,4 +35,8 @@ def commentaire_date
is_current_year = (@commentaire.created_at.year == Time.zone.today.year)
l(@commentaire.created_at, format: is_current_year ? :message_date : :message_date_with_year)
end

def highlight?
@commentaire.persisted? && (@commentaire_seen_at.nil? || @commentaire_seen_at < @commentaire.created_at)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
%span.mail
= commentaire_issuer

%span.date{ class: ["fr-text--xs", "fr-text-mention--grey", "font-weight-normal"] }
%span.date{ class: ["fr-text--xs", "fr-text-mention--grey", "font-weight-normal", highlight_if_unseen_class], data: scroll_to_target }
= commentaire_date
.rich-text
- if @commentaire.discarded?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ def see_button
gestionnaire_groupe_gestionnaire_commentaire_path(@groupe_gestionnaire, @commentaire),
class: 'button'
end

def highlight?
commentaire_seen_at = current_gestionnaire.commentaire_seen_at(@groupe_gestionnaire, @commentaire.sender)
commentaire_seen_at.nil? || commentaire_seen_at < @commentaire.created_at
end
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
%tr{ id: dom_id(@commentaire) }
%td= email
%td
= email
- if highlight?
%span.notifications{ 'aria-label': 'notifications' }
%td= created_at
%td= see_button
4 changes: 2 additions & 2 deletions app/controllers/administrateurs/activate_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ def create
reset_password_token: update_administrateur_params[:reset_password_token]
})

if user&.administrateur&.errors&.empty?
if user&.errors&.empty?
sign_in(user, scope: :user)

flash.notice = "Mot de passe enregistré"
redirect_to admin_procedures_path
else
flash.alert = user.administrateur.errors.full_messages
flash.alert = user.errors.full_messages
redirect_to admin_activate_path(token: update_administrateur_params[:reset_password_token])
end
end
Expand Down
52 changes: 52 additions & 0 deletions app/controllers/gestionnaires/activate_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
class Gestionnaires::ActivateController < ApplicationController
include TrustedDeviceConcern

def new
@token = params[:token]

user = User.with_reset_password_token(@token)
@gestionnaire = user&.gestionnaire

if @gestionnaire
# the gestionnaire activates its account from an email
trust_device(Time.zone.now)
else
flash.alert = "Le lien de validation de gestionnaire a expiré, #{helpers.contact_link('contactez-nous', tags: 'lien expiré')} pour obtenir un nouveau lien."
redirect_to root_path
end
end

def create
password = update_gestionnaire_params[:password]

user = User.reset_password_by_token({
password: password,
password_confirmation: password,
reset_password_token: update_gestionnaire_params[:reset_password_token]
})

if user&.errors&.empty?
sign_in(user, scope: :user)

flash.notice = "Mot de passe enregistré"
redirect_to gestionnaire_groupe_gestionnaires_path
else
flash.alert = user.errors.full_messages
redirect_to gestionnaires_activate_path(token: update_gestionnaire_params[:reset_password_token])
end
end

private

def update_gestionnaire_params
params.require(:gestionnaire).permit(:reset_password_token, :password)
end

def try_to_authenticate(klass, email, password)
resource = klass.find_for_database_authentication(email: email)

if resource&.valid_password?(password)
sign_in resource
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ def index
end

def show
@commentaire_seen_at = current_gestionnaire.commentaire_seen_at(@groupe_gestionnaire, @last_commentaire.sender)
@commentaire = CommentaireGroupeGestionnaire.new
current_gestionnaire.mark_commentaire_as_seen(@groupe_gestionnaire, @last_commentaire.sender)
end

def create
Expand All @@ -30,7 +32,6 @@ def destroy
else
flash.alert = t('.alert_acl')
end
# redirect_to gestionnaire_groupe_gestionnaire_commentaire_path(@groupe_gestionnaire, @last_commentaire)
rescue Discard::RecordNotDiscarded
flash.alert = t('.alert_already_discarded')
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ def index
end

def show
@unread_commentaires = current_gestionnaire.unread_commentaires?(@groupe_gestionnaire)
end

def edit
Expand Down
7 changes: 7 additions & 0 deletions app/models/follow_commentaire_groupe_gestionnaire.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class FollowCommentaireGroupeGestionnaire < ApplicationRecord
belongs_to :gestionnaire
belongs_to :groupe_gestionnaire
belongs_to :sender, polymorphic: true, optional: true

validates :gestionnaire_id, uniqueness: { scope: [:groupe_gestionnaire_id, :sender_id, :sender_type, :unfollowed_at] }
end
24 changes: 24 additions & 0 deletions app/models/gestionnaire.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ class Gestionnaire < ApplicationRecord
include UserFindByConcern
has_and_belongs_to_many :groupe_gestionnaires
has_many :commentaire_groupe_gestionnaires
has_many :follow_commentaire_groupe_gestionnaires

belongs_to :user

Expand Down Expand Up @@ -33,4 +34,27 @@ def registration_state
'Expiré'
end
end

def unread_commentaires?(groupe_gestionnaire)
CommentaireGroupeGestionnaire
.joins(:groupe_gestionnaire)
.joins("LEFT JOIN follow_commentaire_groupe_gestionnaires ON follow_commentaire_groupe_gestionnaires.groupe_gestionnaire_id = commentaire_groupe_gestionnaires.groupe_gestionnaire_id AND follow_commentaire_groupe_gestionnaires.sender_id = commentaire_groupe_gestionnaires.sender_id AND follow_commentaire_groupe_gestionnaires.sender_type = commentaire_groupe_gestionnaires.sender_type AND follow_commentaire_groupe_gestionnaires.gestionnaire_id = #{self.id}")
.where(groupe_gestionnaire: groupe_gestionnaire)
.where('follow_commentaire_groupe_gestionnaires.commentaire_seen_at IS NULL OR follow_commentaire_groupe_gestionnaires.commentaire_seen_at < commentaire_groupe_gestionnaires.created_at')
.exists?
end

def commentaire_seen_at(groupe_gestionnaire, sender)
FollowCommentaireGroupeGestionnaire
.where(gestionnaire: self, groupe_gestionnaire:, sender:)
.order(id: :desc)
.last
&.commentaire_seen_at
end

def mark_commentaire_as_seen(groupe_gestionnaire, sender)
FollowCommentaireGroupeGestionnaire
.where(gestionnaire: self, groupe_gestionnaire: groupe_gestionnaire, sender: sender, unfollowed_at: nil)
.first_or_initialize.update(commentaire_seen_at: Time.zone.now)
end
end
1 change: 1 addition & 0 deletions app/models/groupe_gestionnaire.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class GroupeGestionnaire < ApplicationRecord
has_many :administrateurs
has_many :commentaire_groupe_gestionnaires
has_many :follow_commentaire_groupe_gestionnaires
has_and_belongs_to_many :gestionnaires

has_ancestry
Expand Down
6 changes: 3 additions & 3 deletions app/views/administrateurs/groupe_gestionnaire/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
metadatas: true }

.fr-container
%h2= "Gestion du groupe gestionnaire #{@groupe_gestionnaire.id}"
%h2= "Gestion du groupe gestionnaire \"#{@groupe_gestionnaire.name}\""
.fr-grid-row.fr-grid-row--gutters.fr-mb-5w
= render GroupeGestionnaire::Card::GestionnairesComponent.new(groupe_gestionnaire: @groupe_gestionnaire, path: admin_groupe_gestionnaire_gestionnaires_path)
= render GroupeGestionnaire::Card::AdministrateursComponent.new(groupe_gestionnaire: @groupe_gestionnaire, path: admin_groupe_gestionnaire_administrateurs_path)
= render GroupeGestionnaire::Card::GestionnairesComponent.new(groupe_gestionnaire: @groupe_gestionnaire, path: admin_groupe_gestionnaire_gestionnaires_path, is_gestionnaire: false)
= render GroupeGestionnaire::Card::AdministrateursComponent.new(groupe_gestionnaire: @groupe_gestionnaire, path: admin_groupe_gestionnaire_administrateurs_path, is_gestionnaire: false)
= render GroupeGestionnaire::Card::CommentairesComponent.new(groupe_gestionnaire: @groupe_gestionnaire, administrateur: current_administrateur, path: admin_groupe_gestionnaire_commentaires_path)
26 changes: 26 additions & 0 deletions app/views/gestionnaires/activate/new.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
- content_for(:title, t('.title'))

- content_for :footer do
= render partial: "root/footer"

.fr-container.fr-my-5w
.fr-grid-row.fr-grid-row--center
.fr-col-lg-6
= form_for @gestionnaire, url: { controller: 'gestionnaires/activate', action: :create } do |f|
= f.hidden_field :reset_password_token, value: @token

%fieldset.fr-mb-0.fr-fieldset{ aria: { labelledby: 'edit-password-legend' } }
%legend.fr-fieldset__legend#edit-password-legend
%h1.fr-h2= t('.title')

.fr-fieldset__element
= render Dsfr::InputComponent.new(form: f, attribute: :email, opts: { disabled: true })

.fr-fieldset__element
= render Dsfr::InputComponent.new(form: f, attribute: :password, input_type: :password_field,
opts: { autofocus: 'true', autocomplete: 'new-password', data: { controller: 'turbo-input', turbo_input_url_value: show_password_complexity_path }})

#password_complexity
= render PasswordComplexityComponent.new

= f.submit t('.continue'), id: 'submit-password', class: "fr-btn fr-btn--lg fr-mt-2w", data: { disable_with: t('views.users.passwords.edit.submit_loading') }
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
%ul.messages-list{ data: { controller: 'scroll-to' } }
- @groupe_gestionnaire.commentaire_groupe_gestionnaires.where(sender_id: @last_commentaire.sender_id, sender_type: @last_commentaire.sender_type).each do |commentaire|
%li.message{ class: commentaire_is_from_me_class(commentaire, current_gestionnaire), id: dom_id(commentaire) }
= render(GroupeGestionnaire::GroupeGestionnaireCommentaires::CommentaireComponent.new(commentaire: commentaire, connected_user: current_gestionnaire))
= render(GroupeGestionnaire::GroupeGestionnaireCommentaires::CommentaireComponent.new(commentaire: commentaire, connected_user: current_gestionnaire, commentaire_seen_at: @commentaire_seen_at))
- if @last_commentaire.sender
= render partial: "shared/groupe_gestionnaires/commentaires/form", locals: { commentaire: @commentaire, form_url: gestionnaire_groupe_gestionnaire_commentaires_path(@groupe_gestionnaire) }
6 changes: 3 additions & 3 deletions app/views/gestionnaires/groupe_gestionnaires/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
= t('views.gestionnaires.groupe_gestionnaires.delete')

.fr-container
%h2= "Gestion du groupe gestionnaire #{@groupe_gestionnaire.id}"
%h2= "Gestion du groupe gestionnaire \"#{@groupe_gestionnaire.name}\""
- if @groupe_gestionnaire.groupe_gestionnaire_id.present?
%p
groupe parent :
%a{ href: gestionnaire_groupe_gestionnaire_path(@groupe_gestionnaire.groupe_gestionnaire) }= @groupe_gestionnaire.groupe_gestionnaire.name
.fr-grid-row.fr-grid-row--gutters.fr-mb-5w
.fr-grid-row.fr-grid-row--gutters.fr-mb-5w.fr-groupe_gestionnaire_cards
= render GroupeGestionnaire::Card::GestionnairesComponent.new(groupe_gestionnaire: @groupe_gestionnaire, path: gestionnaire_groupe_gestionnaire_gestionnaires_path(@groupe_gestionnaire))
= render GroupeGestionnaire::Card::AdministrateursComponent.new(groupe_gestionnaire: @groupe_gestionnaire, path: gestionnaire_groupe_gestionnaire_administrateurs_path(@groupe_gestionnaire))
= render GroupeGestionnaire::Card::ChildrenComponent.new(groupe_gestionnaire: @groupe_gestionnaire, path: gestionnaire_groupe_gestionnaire_children_path(@groupe_gestionnaire))
= render GroupeGestionnaire::Card::CommentairesComponent.new(groupe_gestionnaire: @groupe_gestionnaire, administrateur: nil, path: gestionnaire_groupe_gestionnaire_commentaires_path(@groupe_gestionnaire))
= render GroupeGestionnaire::Card::CommentairesComponent.new(groupe_gestionnaire: @groupe_gestionnaire, administrateur: nil, path: gestionnaire_groupe_gestionnaire_commentaires_path(@groupe_gestionnaire), unread_commentaires: @unread_commentaires)

2 changes: 1 addition & 1 deletion app/views/user_mailer/invite_gestionnaire.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

%p
Votre compte a été créé pour l'adresse email #{@user.email}. Pour l’activer, nous vous invitons à cliquer sur le lien suivant : 
= link_to(users_activate_url(token: @reset_password_token), users_activate_url(token: @reset_password_token))
= link_to(gestionnaires_activate_url(token: @reset_password_token), gestionnaires_activate_url(token: @reset_password_token))

= render partial: "layouts/mailers/signature"
5 changes: 5 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,11 @@ en:
updated_at: updated at
closed_at: closed at
auto_archive_on: will close at
gestionnaires:
activate:
new:
title: Pick a password
continue: Continue
users:
dossiers:
test_procedure: "This file is submitted on a test procedure. Any modification of the procedure by the administrator (addition of a field, publication of the procedure, etc.) will result in the removal of the file."
Expand Down
5 changes: 5 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,11 @@ fr:
explication_html: "<p>API Particulier facilite l’accès des administrations aux données familiales (CAF), aux données fiscales (DGFiP), au statut pôle-emploi et au statut étudiant d’un citoyen pour simplifier les démarches administratives mises en œuvre par les collectivités et les administrations.<br> Cela permet aux administrations d’accéder à des informations certifiées à la source et ainsi : </p> <ul> <li>de s’affranchir des pièces justificatives lors des démarches en ligne,</li> <li>de réduire le nombre d’erreurs de saisie,</li> <li>d’écarter le risque de fraude documentaire.</li> </ul> <p> <strong>Important&nbsp;:</strong> les disposition de l’article <a href='https://www.legifrance.gouv.fr/affichCodeArticle.do?cidTexte=LEGITEXT000031366350&amp;idArticle=LEGIARTI000031367412&amp;dateTexte=&amp;categorieLien=cid'>L144-8</a> n’autorisent que l’échange des informations strictement nécessaires pour traiter une démarche.<br /><br />En conséquence, ne sélectionnez ici que les données auxquelles vous aurez accès d’un point de vue légal.</p>"
update:
sources_ok: 'Mise à jour effectuée'
gestionnaires:
activate:
new:
title: Choix du mot de passe
continue: Continuer
zones:
ministeres: Ministères
france_connect:
Expand Down
5 changes: 5 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,11 @@
resources :commentaires, controller: 'groupe_gestionnaire_commentaires', only: [:index, :show, :create, :destroy]
end
end

namespace :gestionnaires do
get 'activate' => '/gestionnaires/activate#new'
patch 'activate' => '/gestionnaires/activate#create'
end
end

#
Expand Down
Loading
Loading