commit
d7f4860256
14 changed files with 146 additions and 15 deletions
|
@ -52,5 +52,10 @@
|
||||||
color: rgba(0, 0, 0, 0.6);
|
color: rgba(0, 0, 0, 0.6);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notifications {
|
||||||
|
top: 3px;
|
||||||
|
right: 3px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
|
|
||||||
i.folder {
|
i.folder {
|
||||||
margin-right: $default-spacer;
|
margin-right: $default-spacer;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.notifications {
|
||||||
|
top: 0px;
|
||||||
|
right: -10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.number-col,
|
.number-col,
|
||||||
|
|
9
app/assets/stylesheets/new_design/notifications.scss
Normal file
9
app/assets/stylesheets/new_design/notifications.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
@import "colors";
|
||||||
|
|
||||||
|
span.notifications {
|
||||||
|
position: absolute;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: $orange;
|
||||||
|
}
|
|
@ -40,6 +40,7 @@
|
||||||
min-height: 36px;
|
min-height: 36px;
|
||||||
border-left: 1px solid $border-grey;
|
border-left: 1px solid $border-grey;
|
||||||
width: 90px;
|
width: 90px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border-right: 1px solid $border-grey;
|
border-right: 1px solid $border-grey;
|
||||||
|
@ -60,5 +61,10 @@
|
||||||
color: $grey;
|
color: $grey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notifications {
|
||||||
|
top: 3px;
|
||||||
|
right: 18px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,17 @@ module NewGestionnaire
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
|
dossier.notifications.demande.mark_as_read
|
||||||
end
|
end
|
||||||
|
|
||||||
def messagerie
|
def messagerie
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
|
dossier.notifications.messagerie.mark_as_read
|
||||||
end
|
end
|
||||||
|
|
||||||
def instruction
|
def instruction
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
|
dossier.notifications.instruction.mark_as_read
|
||||||
end
|
end
|
||||||
|
|
||||||
def follow
|
def follow
|
||||||
|
|
|
@ -18,6 +18,8 @@ module NewGestionnaire
|
||||||
.group(:procedure_id)
|
.group(:procedure_id)
|
||||||
.reorder(nil)
|
.reorder(nil)
|
||||||
.count
|
.count
|
||||||
|
|
||||||
|
@notifications_count_per_procedure = current_gestionnaire.notifications_count_per_procedure
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -31,7 +33,7 @@ module NewGestionnaire
|
||||||
|
|
||||||
@followed_dossiers = current_gestionnaire
|
@followed_dossiers = current_gestionnaire
|
||||||
.followed_dossiers
|
.followed_dossiers
|
||||||
.includes(:user)
|
.includes(:user, :notifications)
|
||||||
.where(procedure: @procedure)
|
.where(procedure: @procedure)
|
||||||
.en_cours
|
.en_cours
|
||||||
|
|
||||||
|
|
|
@ -64,16 +64,17 @@ class Dossier < ActiveRecord::Base
|
||||||
|
|
||||||
scope :order_by_updated_at, -> (order = :desc) { order(updated_at: order) }
|
scope :order_by_updated_at, -> (order = :desc) { order(updated_at: order) }
|
||||||
|
|
||||||
scope :all_state, -> { not_archived.state_not_brouillon.order_by_updated_at(:asc) }
|
scope :all_state, -> { not_archived.state_not_brouillon.order_by_updated_at(:asc) }
|
||||||
scope :nouveaux, -> { not_archived.state_nouveaux.order_by_updated_at(:asc) }
|
scope :nouveaux, -> { not_archived.state_nouveaux.order_by_updated_at(:asc) }
|
||||||
scope :ouvert, -> { not_archived.state_ouvert.order_by_updated_at(:asc) }
|
scope :ouvert, -> { not_archived.state_ouvert.order_by_updated_at(:asc) }
|
||||||
scope :waiting_for_gestionnaire, -> { not_archived.state_waiting_for_gestionnaire.order_by_updated_at(:asc) }
|
scope :waiting_for_gestionnaire, -> { not_archived.state_waiting_for_gestionnaire.order_by_updated_at(:asc) }
|
||||||
scope :waiting_for_user, -> { not_archived.state_waiting_for_user.order_by_updated_at(:asc) }
|
scope :waiting_for_user, -> { not_archived.state_waiting_for_user.order_by_updated_at(:asc) }
|
||||||
scope :a_instruire, -> { not_archived.state_a_instruire.order_by_updated_at(:asc) }
|
scope :a_instruire, -> { not_archived.state_a_instruire.order_by_updated_at(:asc) }
|
||||||
scope :termine, -> { not_archived.state_termine.order_by_updated_at(:asc) }
|
scope :termine, -> { not_archived.state_termine.order_by_updated_at(:asc) }
|
||||||
scope :downloadable, -> { state_not_brouillon.order_by_updated_at(:asc) }
|
scope :downloadable, -> { state_not_brouillon.order_by_updated_at(:asc) }
|
||||||
scope :en_cours, -> { not_archived.state_en_construction_ou_instruction.order_by_updated_at(:asc) }
|
scope :en_cours, -> { not_archived.state_en_construction_ou_instruction.order_by_updated_at(:asc) }
|
||||||
scope :without_followers, -> { includes(:follows).where(follows: { id: nil }) }
|
scope :without_followers, -> { includes(:follows).where(follows: { id: nil }) }
|
||||||
|
scope :with_unread_notifications, -> { where(notifications: { already_read: false }) }
|
||||||
|
|
||||||
accepts_nested_attributes_for :individual
|
accepts_nested_attributes_for :individual
|
||||||
|
|
||||||
|
@ -103,6 +104,16 @@ class Dossier < ActiveRecord::Base
|
||||||
pieces_justificatives.where(type_de_piece_justificative_id: type_id).count > 0
|
pieces_justificatives.where(type_de_piece_justificative_id: type_id).count > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def notifications_summary
|
||||||
|
unread_notifications = notifications.unread
|
||||||
|
|
||||||
|
{
|
||||||
|
demande: unread_notifications.select(&:demande?).present?,
|
||||||
|
instruction: unread_notifications.select(&:instruction?).present?,
|
||||||
|
messagerie: unread_notifications.select(&:messagerie?).present?
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def retrieve_last_piece_justificative_by_type(type)
|
def retrieve_last_piece_justificative_by_type(type)
|
||||||
pieces_justificatives.where(type_de_piece_justificative_id: type).last
|
pieces_justificatives.where(type_de_piece_justificative_id: type).last
|
||||||
end
|
end
|
||||||
|
|
|
@ -93,6 +93,14 @@ class Gestionnaire < ActiveRecord::Base
|
||||||
Notification.unread.where(dossier_id: followed_dossiers_id).select(:dossier_id).distinct(:dossier_id).count
|
Notification.unread.where(dossier_id: followed_dossiers_id).select(:dossier_id).distinct(:dossier_id).count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def notifications_count_per_procedure
|
||||||
|
followed_dossiers
|
||||||
|
.joins(:notifications)
|
||||||
|
.where(notifications: { already_read: false })
|
||||||
|
.group('procedure_id')
|
||||||
|
.count
|
||||||
|
end
|
||||||
|
|
||||||
def dossiers_with_notifications_count
|
def dossiers_with_notifications_count
|
||||||
notifications.pluck(:dossier_id).uniq.count
|
notifications.pluck(:dossier_id).uniq.count
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,27 @@ class Notification < ActiveRecord::Base
|
||||||
avis: 'avis'
|
avis: 'avis'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEMANDE = %w(cerfa piece_justificative champs submitted)
|
||||||
|
INSTRUCTION = %w(avis)
|
||||||
|
MESSAGERIE = %w(commentaire)
|
||||||
|
|
||||||
belongs_to :dossier
|
belongs_to :dossier
|
||||||
|
|
||||||
scope :unread, -> { where(already_read: false) }
|
scope :unread, -> { where(already_read: false) }
|
||||||
|
scope :demande, -> { where(type_notif: DEMANDE) }
|
||||||
|
scope :instruction, -> { where(type_notif: INSTRUCTION) }
|
||||||
|
scope :messagerie, -> { where(type_notif: MESSAGERIE) }
|
||||||
|
scope :mark_as_read, -> { update_all(already_read: true) }
|
||||||
|
|
||||||
|
def demande?
|
||||||
|
Notification::DEMANDE.include?(type_notif)
|
||||||
|
end
|
||||||
|
|
||||||
|
def instruction?
|
||||||
|
Notification::INSTRUCTION.include?(type_notif)
|
||||||
|
end
|
||||||
|
|
||||||
|
def messagerie?
|
||||||
|
Notification::MESSAGERIE.include?(type_notif)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,11 +6,18 @@
|
||||||
%li
|
%li
|
||||||
= "Dossier n° #{dossier.id}"
|
= "Dossier n° #{dossier.id}"
|
||||||
%ul.tabs
|
%ul.tabs
|
||||||
|
- notifications_summary = dossier.notifications_summary
|
||||||
%li{ class: current_page?(dossier_path(dossier.procedure, dossier)) ? 'active' : nil }
|
%li{ class: current_page?(dossier_path(dossier.procedure, dossier)) ? 'active' : nil }
|
||||||
|
- if notifications_summary[:demande]
|
||||||
|
%span.notifications{ 'aria-label': 'notifications' }
|
||||||
= link_to "Demande", dossier_path(dossier.procedure, dossier)
|
= link_to "Demande", dossier_path(dossier.procedure, dossier)
|
||||||
%li{ class: current_page?(instruction_dossier_path(dossier.procedure, dossier)) ? 'active' : nil }
|
%li{ class: current_page?(instruction_dossier_path(dossier.procedure, dossier)) ? 'active' : nil }
|
||||||
|
- if notifications_summary[:instruction]
|
||||||
|
%span.notifications{ 'aria-label': 'notifications' }
|
||||||
= link_to "Instruction", instruction_dossier_path(dossier.procedure, dossier)
|
= link_to "Instruction", instruction_dossier_path(dossier.procedure, dossier)
|
||||||
%li{ class: current_page?(messagerie_dossier_path(dossier.procedure, dossier)) ? 'active' : nil }
|
%li{ class: current_page?(messagerie_dossier_path(dossier.procedure, dossier)) ? 'active' : nil }
|
||||||
|
- if notifications_summary[:messagerie]
|
||||||
|
%span.notifications{ 'aria-label': 'notifications' }
|
||||||
= link_to "Messagerie", messagerie_dossier_path(dossier.procedure, dossier)
|
= link_to "Messagerie", messagerie_dossier_path(dossier.procedure, dossier)
|
||||||
%li
|
%li
|
||||||
= link_to "Historique", "#"
|
= link_to "Historique", "#"
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
.stats-legend
|
.stats-legend
|
||||||
à suivre
|
à suivre
|
||||||
%li
|
%li
|
||||||
|
- if @notifications_count_per_procedure[p.id].present?
|
||||||
|
%span.notifications{ 'aria-label': "notifications" }
|
||||||
- followed_count = @followed_dossiers_count_per_procedure[p.id] || 0
|
- followed_count = @followed_dossiers_count_per_procedure[p.id] || 0
|
||||||
.stats-number
|
.stats-number
|
||||||
= followed_count
|
= followed_count
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
%span.badge= @a_suivre_dossiers.count
|
%span.badge= @a_suivre_dossiers.count
|
||||||
|
|
||||||
%li{ class: (@statut == 'suivis') ? 'active' : nil }>
|
%li{ class: (@statut == 'suivis') ? 'active' : nil }>
|
||||||
|
- if @followed_dossiers.with_unread_notifications.present?
|
||||||
|
%span.notifications{ 'aria-label': 'notifications' }
|
||||||
= link_to(procedure_path(@procedure, statut: 'suivis')) do
|
= link_to(procedure_path(@procedure, statut: 'suivis')) do
|
||||||
= t('pluralize.followed', count: @followed_dossiers.count)
|
= t('pluralize.followed', count: @followed_dossiers.count)
|
||||||
%span.badge= @followed_dossiers.count
|
%span.badge= @followed_dossiers.count
|
||||||
|
@ -23,6 +25,8 @@
|
||||||
%span.badge= @termines_dossiers.count
|
%span.badge= @termines_dossiers.count
|
||||||
|
|
||||||
%li{ class: (@statut == 'tous') ? 'active' : nil }>
|
%li{ class: (@statut == 'tous') ? 'active' : nil }>
|
||||||
|
- if @followed_dossiers.with_unread_notifications.present?
|
||||||
|
%span.notifications{ 'aria-label': 'notifications' }
|
||||||
= link_to(procedure_path(@procedure, statut: 'tous')) do
|
= link_to(procedure_path(@procedure, statut: 'tous')) do
|
||||||
tous les dossiers
|
tous les dossiers
|
||||||
%span.badge= @all_state_dossiers.count
|
%span.badge= @all_state_dossiers.count
|
||||||
|
@ -47,6 +51,8 @@
|
||||||
%td.number-col
|
%td.number-col
|
||||||
= link_to(dossier_path(@procedure, dossier), class: 'cell-link') do
|
= link_to(dossier_path(@procedure, dossier), class: 'cell-link') do
|
||||||
%i.folder
|
%i.folder
|
||||||
|
- if @followed_dossiers.with_unread_notifications.include?(dossier)
|
||||||
|
%span.notifications{ 'aria-label': 'notifications' }
|
||||||
= dossier.id
|
= dossier.id
|
||||||
%td= link_to(dossier.user.email, dossier_path(@procedure, dossier), class: 'cell-link')
|
%td= link_to(dossier.user.email, dossier_path(@procedure, dossier), class: 'cell-link')
|
||||||
%td.status-col
|
%td.status-col
|
||||||
|
|
|
@ -72,10 +72,30 @@ describe NewGestionnaire::DossiersController, type: :controller do
|
||||||
it { expect(response).to redirect_to(procedures_url) }
|
it { expect(response).to redirect_to(procedures_url) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#show" do
|
describe '#show #messagerie #instruction' do
|
||||||
before { get :show, params: { procedure_id: procedure.id, dossier_id: dossier.id } }
|
before do
|
||||||
|
dossier.notifications = %w(champs avis commentaire).map{ |type| Notification.create!(type_notif: type) }
|
||||||
|
get method, params: { procedure_id: procedure.id, dossier_id: dossier.id }
|
||||||
|
dossier.notifications.each(&:reload)
|
||||||
|
end
|
||||||
|
|
||||||
it { expect(response).to have_http_status(:success) }
|
context '#show' do
|
||||||
|
let(:method) { :show }
|
||||||
|
it { expect(dossier.notifications.map(&:already_read)).to match([true, false, false]) }
|
||||||
|
it { expect(response).to have_http_status(:success) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#instruction' do
|
||||||
|
let(:method) { :instruction }
|
||||||
|
it { expect(dossier.notifications.map(&:already_read)).to match([false, true, false]) }
|
||||||
|
it { expect(response).to have_http_status(:success) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#messagerie' do
|
||||||
|
let(:method) { :messagerie }
|
||||||
|
it { expect(dossier.notifications.map(&:already_read)).to match([false, false, true]) }
|
||||||
|
it { expect(response).to have_http_status(:success) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#create_commentaire" do
|
describe "#create_commentaire" do
|
||||||
|
|
|
@ -356,4 +356,30 @@ describe Gestionnaire, type: :model do
|
||||||
it { expect(subject).to be false }
|
it { expect(subject).to be false }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#notifications_count_per_procedure' do
|
||||||
|
subject { gestionnaire.notifications_count_per_procedure }
|
||||||
|
|
||||||
|
let(:dossier_with_unread_notification) do
|
||||||
|
create(:dossier, notifications: [Notification.create(type_notif: 'champs', already_read: false)])
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:dossier_with_no_unread_notification) do
|
||||||
|
create(:dossier, notifications: [Notification.create(type_notif: 'champs', already_read: true)])
|
||||||
|
end
|
||||||
|
|
||||||
|
before { gestionnaire.followed_dossiers << followed_dossier }
|
||||||
|
|
||||||
|
context 'when a followed dossier has unread notification' do
|
||||||
|
let(:followed_dossier) { dossier_with_unread_notification }
|
||||||
|
|
||||||
|
it { is_expected.to eq({ dossier_with_unread_notification.procedure.id => 1 }) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a followed dossier has unread notification' do
|
||||||
|
let(:followed_dossier) { dossier_with_no_unread_notification }
|
||||||
|
|
||||||
|
it { is_expected.to eq({ }) }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue