commit
d7f4860256
14 changed files with 146 additions and 15 deletions
|
@ -52,5 +52,10 @@
|
|||
color: rgba(0, 0, 0, 0.6);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.notifications {
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
|
||||
i.folder {
|
||||
margin-right: $default-spacer;
|
||||
position: relative;
|
||||
|
||||
.notifications {
|
||||
top: 0px;
|
||||
right: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
border-left: 1px solid $border-grey;
|
||||
width: 90px;
|
||||
position: relative;
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid $border-grey;
|
||||
|
@ -60,5 +61,10 @@
|
|||
color: $grey;
|
||||
}
|
||||
}
|
||||
|
||||
.notifications {
|
||||
top: 3px;
|
||||
right: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,14 +6,17 @@ module NewGestionnaire
|
|||
|
||||
def show
|
||||
@dossier = dossier
|
||||
dossier.notifications.demande.mark_as_read
|
||||
end
|
||||
|
||||
def messagerie
|
||||
@dossier = dossier
|
||||
dossier.notifications.messagerie.mark_as_read
|
||||
end
|
||||
|
||||
def instruction
|
||||
@dossier = dossier
|
||||
dossier.notifications.instruction.mark_as_read
|
||||
end
|
||||
|
||||
def follow
|
||||
|
|
|
@ -18,6 +18,8 @@ module NewGestionnaire
|
|||
.group(:procedure_id)
|
||||
.reorder(nil)
|
||||
.count
|
||||
|
||||
@notifications_count_per_procedure = current_gestionnaire.notifications_count_per_procedure
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -31,7 +33,7 @@ module NewGestionnaire
|
|||
|
||||
@followed_dossiers = current_gestionnaire
|
||||
.followed_dossiers
|
||||
.includes(:user)
|
||||
.includes(:user, :notifications)
|
||||
.where(procedure: @procedure)
|
||||
.en_cours
|
||||
|
||||
|
|
|
@ -64,16 +64,17 @@ class Dossier < ActiveRecord::Base
|
|||
|
||||
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 :nouveaux, -> { not_archived.state_nouveaux.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_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 :termine, -> { not_archived.state_termine.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 :without_followers, -> { includes(:follows).where(follows: { id: nil }) }
|
||||
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 :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_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 :termine, -> { not_archived.state_termine.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 :without_followers, -> { includes(:follows).where(follows: { id: nil }) }
|
||||
scope :with_unread_notifications, -> { where(notifications: { already_read: false }) }
|
||||
|
||||
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
|
||||
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)
|
||||
pieces_justificatives.where(type_de_piece_justificative_id: type).last
|
||||
end
|
||||
|
|
|
@ -93,6 +93,14 @@ class Gestionnaire < ActiveRecord::Base
|
|||
Notification.unread.where(dossier_id: followed_dossiers_id).select(:dossier_id).distinct(:dossier_id).count
|
||||
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
|
||||
notifications.pluck(:dossier_id).uniq.count
|
||||
end
|
||||
|
|
|
@ -8,7 +8,27 @@ class Notification < ActiveRecord::Base
|
|||
avis: 'avis'
|
||||
}
|
||||
|
||||
DEMANDE = %w(cerfa piece_justificative champs submitted)
|
||||
INSTRUCTION = %w(avis)
|
||||
MESSAGERIE = %w(commentaire)
|
||||
|
||||
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
|
||||
|
|
|
@ -6,11 +6,18 @@
|
|||
%li
|
||||
= "Dossier n° #{dossier.id}"
|
||||
%ul.tabs
|
||||
- notifications_summary = dossier.notifications_summary
|
||||
%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)
|
||||
%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)
|
||||
%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)
|
||||
%li
|
||||
= link_to "Historique", "#"
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
.stats-legend
|
||||
à suivre
|
||||
%li
|
||||
- if @notifications_count_per_procedure[p.id].present?
|
||||
%span.notifications{ 'aria-label': "notifications" }
|
||||
- followed_count = @followed_dossiers_count_per_procedure[p.id] || 0
|
||||
.stats-number
|
||||
= followed_count
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
%span.badge= @a_suivre_dossiers.count
|
||||
|
||||
%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
|
||||
= t('pluralize.followed', count: @followed_dossiers.count)
|
||||
%span.badge= @followed_dossiers.count
|
||||
|
@ -23,6 +25,8 @@
|
|||
%span.badge= @termines_dossiers.count
|
||||
|
||||
%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
|
||||
tous les dossiers
|
||||
%span.badge= @all_state_dossiers.count
|
||||
|
@ -47,6 +51,8 @@
|
|||
%td.number-col
|
||||
= link_to(dossier_path(@procedure, dossier), class: 'cell-link') do
|
||||
%i.folder
|
||||
- if @followed_dossiers.with_unread_notifications.include?(dossier)
|
||||
%span.notifications{ 'aria-label': 'notifications' }
|
||||
= dossier.id
|
||||
%td= link_to(dossier.user.email, dossier_path(@procedure, dossier), class: 'cell-link')
|
||||
%td.status-col
|
||||
|
|
|
@ -72,10 +72,30 @@ describe NewGestionnaire::DossiersController, type: :controller do
|
|||
it { expect(response).to redirect_to(procedures_url) }
|
||||
end
|
||||
|
||||
describe "#show" do
|
||||
before { get :show, params: { procedure_id: procedure.id, dossier_id: dossier.id } }
|
||||
describe '#show #messagerie #instruction' do
|
||||
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
|
||||
|
||||
describe "#create_commentaire" do
|
||||
|
|
|
@ -356,4 +356,30 @@ describe Gestionnaire, type: :model do
|
|||
it { expect(subject).to be false }
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue