Skip to content

Commit

Permalink
feat(announces): show Nouveautés link in main navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
colinux committed Nov 13, 2023
1 parent dca7abf commit 2a26ee1
Show file tree
Hide file tree
Showing 14 changed files with 232 additions and 11 deletions.
11 changes: 11 additions & 0 deletions app/assets/stylesheets/notifications.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,14 @@ span.notifications {
border-radius: 4px;
background-color: $orange;
}

.fr-nav {
&__notifiable {
position: relative;
}

.notifications {
top: 1rem;
right: 0.25rem;
}
}
27 changes: 27 additions & 0 deletions app/components/main_navigation/announces_link_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

class MainNavigation::AnnouncesLinkComponent < ApplicationComponent
def render?
@most_recent_released_on = load_most_recent_released_on
return false if @most_recent_released_on.nil?

# also see app/controllers/release_notes_controller.rb#ensure_access_allowed!
return true if helpers.instructeur_signed_in?
return true if helpers.administrateur_signed_in?
return true if helpers.expert_signed_in?

false
end

def something_new?
return true if current_user.announces_seen_at.nil?

@most_recent_released_on.after? current_user.announces_seen_at
end

def load_most_recent_released_on
categories = helpers.infer_default_announce_categories

ReleaseNote.most_recent_announce_date_for_categories(categories)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
en:
news: News
something_new: New informations about the website may be of interest to you.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
fr:
news: Nouveautés
something_new: De nouvelles informations à propos du site pourraient vous intéresser.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
%li.fr-nav__item.fr-nav__notifiable
= link_to t('.news'), release_notes_path, class: "fr-nav__link",'aria-current': current_page?(release_notes_path) ? 'page' : nil
- if something_new?
%span.notifications{ 'aria-label': t('.something_new') }
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@
= Avis.model_name.plural.capitalize
- if helpers.current_expert.avis_summary[:unanswered] > 0
%span.badge.warning= helpers.current_expert.avis_summary[:unanswered]
= render MainNavigation::AnnouncesLinkComponent.new
31 changes: 20 additions & 11 deletions app/controllers/release_notes_controller.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class ReleaseNotesController < ApplicationController
before_action :ensure_access_allowed!
after_action :touch_default_categories_seen_at

def index
@categories = params[:categories].presence || infer_default_categories
@categories = params[:categories].presence || helpers.infer_default_announce_categories

# Paginate per group of dates, then show all announces for theses dates
@paginated_groups = ReleaseNote.published
Expand All @@ -20,18 +21,26 @@ def index
render "scrollable_list" if params[:page].present?
end

def nav_bar_profile
# detect context from referer, simple (no detection when refreshing the page)
params = Rails.application.routes.recognize_path(request&.referer)

controller_class = "#{params[:controller].camelize}Controller".safe_constantize
return if controller_class.nil?

controller_instance = controller_class.new
controller_instance.try(:nav_bar_profile)
end

private

def infer_default_categories
if administrateur_signed_in?
['administrateur', 'usager', current_administrateur.api_tokens.exists? ? 'api' : nil]
elsif instructeur_signed_in?
['instructeur', 'expert']
elsif expert_signed_in?
['expert']
else
['usager']
end
def touch_default_categories_seen_at
return if params[:categories].present? || params[:page].present?
return if current_user.blank?

return if current_user.announces_seen_at&.after?(@announces.max_by(&:released_on).released_on)

current_user.touch(:announces_seen_at)
end

def ensure_access_allowed!
Expand Down
12 changes: 12 additions & 0 deletions app/helpers/release_notes_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,16 @@ def announce_category_badge(category)

content_tag(:span, ReleaseNote.human_attribute_name("categories.#{category}"), class: "fr-badge #{color_class}")
end

def infer_default_announce_categories
if administrateur_signed_in?
ReleaseNote.default_categories_for_role(:administrateur, current_administrateur)
elsif instructeur_signed_in?
ReleaseNote.default_categories_for_role(:instructeur, current_instructeur)
elsif expert_signed_in?
ReleaseNote.default_categories_for_role(:expert, current_expert)
else
ReleaseNote.default_categories_for_role(:usager)
end
end
end
17 changes: 17 additions & 0 deletions app/models/release_note.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,21 @@ class ReleaseNote < ApplicationRecord

scope :published, -> { where(published: true, released_on: ..Date.current) }
scope :for_categories, -> (categories) { where("categories && ARRAY[?]::varchar[]", categories) }

def self.default_categories_for_role(role, instance = nil)
case role
when :administrateur
['administrateur', 'usager', instance.api_tokens.exists? ? 'api' : nil]
when :instructeur
['instructeur', instance.user.expert? ? 'expert' : nil]
when :expert
['expert', instance.user.instructeur? ? 'instructeur' : nil]
else
['usager']
end
end

def self.most_recent_announce_date_for_categories(categories)
published.for_categories(categories).maximum(:released_on)
end
end
3 changes: 3 additions & 0 deletions app/views/administrateurs/_main_navigation.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
%li.fr-nav__item= link_to 'Mes démarches', admin_procedures_path, class:'fr-nav__link', 'aria-current': current_page?(controller: 'administrateurs/procedures', action: :index) ? 'true' : nil
- if Rails.application.config.ds_zonage_enabled
%li.fr-nav__item= link_to 'Toutes les démarches', all_admin_procedures_path(zone_ids: current_administrateur.zones), class:'fr-nav__link', 'aria-current': current_page?(all_admin_procedures_path) ? 'page' : nil

= render MainNavigation::AnnouncesLinkComponent.new

87 changes: 87 additions & 0 deletions spec/components/main_navigation/announces_link_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe MainNavigation::AnnouncesLinkComponent, type: :component do
let(:user) { build(:user) }
let!(:admin_release_note) { create(:release_note, released_on: Date.yesterday, categories: ["administrateur"]) }
let!(:instructeur_release_note) { create(:release_note, released_on: Date.yesterday, categories: ["instructeur"]) }
let(:not_published_release_note) { create(:release_note, published: false, released_on: Date.tomorrow) }

let(:as_administrateur) { false }
let(:as_instructeur) { false }

before do
if as_administrateur
user.build_administrateur
end

if as_instructeur
user.build_instructeur
end

allow(controller).to receive(:current_user).and_return(user)
end

subject { render_inline(described_class.new) }

context 'when signed as simple user' do
it 'does not render the announcements link if not signed in' do
expect(subject.to_html).to be_empty
end
end

context 'when no signed in' do
let(:current_user) { nil }

it 'does not render the announcements link if not signed in' do
expect(subject.to_html).to be_empty
end
end

context 'when instructeur signed in' do
let(:as_instructeur) { true }

it 'renders the announcements link' do
expect(subject).to have_link("Nouveautés")
end

context 'when there are new announcements' do
before do
user.announces_seen_at = 5.days.ago
end

it 'does not render the notification badge' do
expect(subject).to have_link("Nouveautés")
expect(subject).to have_css(".notifications")
end
end

context 'when there are no new announcements' do
before do
user.announces_seen_at = 1.minute.ago
end

it 'does not render the notification badge' do
expect(subject).to have_link("Nouveautés")
expect(subject).not_to have_css(".notifications")
end
end

context 'when there are no announcement at all' do
let(:instructeur_release_note) { nil }

it 'does not render anything' do
expect(subject.to_html).to be_empty
end
end
end

context 'when administrateur signed in' do
let(:as_administrateur) { true }

it 'renders the announcements link' do
expect(subject).to have_link("Nouveautés")
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@
expect(subject).not_to have_selector('a[aria-current="page"]', text: 'Avis')
end
end

context 'when there are release notes' do
let!(:release_note) { create(:release_note, categories: ['instructeur']) }

it 'renders a link to Announces page' do
expect(subject).to have_link('Nouveautés')
end
end
end

describe 'when expert is signed in' do
Expand Down
26 changes: 26 additions & 0 deletions spec/controllers/release_notes_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,31 @@
it { is_expected.to be_redirection }
end
end

describe 'touch user announces_seen_at' do
let(:user) { create(:user, administrateur: build(:administrateur)) }

context 'when default categories' do
it 'touch announces_seen_at' do
expect { subject }.to change { user.reload.announces_seen_at }
end

context 'when current announces_seen_at is more recent than last announce' do
before { user.update(announces_seen_at: 1.second.ago) }

it 'does not touch announces_seen_at' do
expect { subject }.not_to change { user.reload.announces_seen_at }
end
end
end

context 'when specific categories' do
subject { get :index, params: { categories: ['administrateur', 'instructeur'] } }

it 'does not touch announces_seen_at' do
expect { subject }.not_to change { user.reload.announces_seen_at }
end
end
end
end
end
7 changes: 7 additions & 0 deletions spec/views/layouts/_header_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
allow(view).to receive(:multiple_devise_profile_connect?).and_return(false)
allow(view).to receive(:instructeur_signed_in?).and_return((profile == :instructeur))
allow(view).to receive(:current_instructeur).and_return(current_instructeur)
allow(view).to receive(:administrateur_signed_in?).and_return(false)
allow(view).to receive(:expert_signed_in?).and_return(false)
allow(view).to receive(:localization_enabled?).and_return(false)

if user
Expand Down Expand Up @@ -57,12 +59,17 @@
let(:user) { instructeur.user }
let(:profile) { :instructeur }
let(:current_instructeur) { instructeur }
let!(:release_note) { create(:release_note, categories: ['instructeur']) }

it { is_expected.to have_css(".fr-header__logo") }
it { is_expected.to have_selector(:button, user.email, class: "account-btn") }

it 'displays the Help dropdown menu' do
expect(subject).to have_css(".help-dropdown")
end

it 'displays the Help dropdown menu' do
expect(subject).to have_link("Nouveautés")
end
end
end

0 comments on commit 2a26ee1

Please sign in to comment.