diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 51a554038..c67de27e5 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -99,7 +99,7 @@ $sidebar-active: #f4fcd0; } } - [class^="icon-"]:not(.icon-circle) { + [class^="icon-"] { font-size: $base-font-size; } } @@ -156,7 +156,7 @@ $sidebar-active: #f4fcd0; } } - .notifications .icon-circle { + .notifications.unread-notifications::after { color: $admin-color; } diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index ffb1517de..44dc26563 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -15,6 +15,7 @@ @import "legislation"; @import "legislation_process"; @import "legislation_process_form"; +@import "notification_item"; @import "community"; @import "stats"; @import "custom"; diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index d993372ab..cc2d92de1 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -1345,32 +1345,6 @@ form { } } -.notifications { - position: relative; - - &:hover { - text-decoration: none; - } - - [class^="icon-"] { - font-size: rem-calc(19); - vertical-align: middle; - } - - .icon-circle { - color: #ecf00b; - font-size: rem-calc(10); - position: absolute; - left: 12px; - top: 6px; - - @include breakpoint(medium) { - left: auto; - right: 8px; - } - } -} - .notifications-list { position: relative; diff --git a/app/assets/stylesheets/mixins.scss b/app/assets/stylesheets/mixins.scss index bad75babd..f6a5bef0e 100644 --- a/app/assets/stylesheets/mixins.scss +++ b/app/assets/stylesheets/mixins.scss @@ -163,11 +163,11 @@ margin-right: rem-calc(10); } -@mixin has-fa-icon($icon, $style) { - @extend .fa-#{$icon}; +@mixin has-fa-icon($icon, $style, $position: "before") { - &::before { + &::#{$position} { @extend %font-icon; + @extend .fa-#{$icon}:before; @if $style == "solid" { font-weight: bold; @@ -182,7 +182,7 @@ @supports (mask-image: url()) { - &::before { + &::#{$position} { @extend %svg-icon; mask-image: image-url("fontawesome/#{$style}/#{$icon}.svg"); } diff --git a/app/assets/stylesheets/notification_item.scss b/app/assets/stylesheets/notification_item.scss new file mode 100644 index 000000000..a6d2ee1e5 --- /dev/null +++ b/app/assets/stylesheets/notification_item.scss @@ -0,0 +1,44 @@ +.notifications { + $notification-icon-size: rem-calc(19); + position: relative; + + &.unread-notifications { + @include has-fa-icon(bell, solid); + @include has-fa-icon(circle, solid, after); + + &::before { + @include breakpoint(medium) { + margin-right: 0; + } + } + + &::after { + $menu-link-top-padding: rem-calc(11); + $circle-icon-size: rem-calc(10); + + color: #ecf00b; + font-size: $circle-icon-size; + margin-right: 0; + position: absolute; + left: $notification-icon-size - rem-calc(5); + top: $menu-link-top-padding - $circle-icon-size / 2; + + @include breakpoint(medium) { + $menu-link-left-padding: rem-calc(16); + left: $notification-icon-size + $menu-link-left-padding; + } + } + } + + &.no-notifications { + @include has-fa-icon(bell, regular); + } + + &::before { + font-size: $notification-icon-size; + } + + &:hover { + text-decoration: none; + } +} diff --git a/app/components/layout/notification_item_component.html.erb b/app/components/layout/notification_item_component.html.erb new file mode 100644 index 000000000..363c2fd2d --- /dev/null +++ b/app/components/layout/notification_item_component.html.erb @@ -0,0 +1,11 @@ +<% if user %> +
  • + <%= link_to notifications_path, rel: "nofollow", title: text, + class: "notifications #{notifications_class}" do %> + + <%= t("layouts.header.notification_item.notifications") %> + + <%= text %> + <% end %> +
  • +<% end %> diff --git a/app/components/layout/notification_item_component.rb b/app/components/layout/notification_item_component.rb new file mode 100644 index 000000000..c620180b0 --- /dev/null +++ b/app/components/layout/notification_item_component.rb @@ -0,0 +1,25 @@ +class Layout::NotificationItemComponent < ApplicationComponent + attr_reader :user + + def initialize(user) + @user = user + end + + private + + def text + t("layouts.header.notification_item.new_notifications", count: unread_notifications.count) + end + + def notifications_class + if unread_notifications.count > 0 + "unread-notifications" + else + "no-notifications" + end + end + + def unread_notifications + user.notifications.unread + end +end diff --git a/app/views/layouts/_notification_item.html.erb b/app/views/layouts/_notification_item.html.erb index c766f862a..2e51085b6 100644 --- a/app/views/layouts/_notification_item.html.erb +++ b/app/views/layouts/_notification_item.html.erb @@ -1,30 +1 @@ -<% if user_signed_in? %> -
  • - <%= link_to notifications_path, rel: "nofollow", - class: "notifications" do %> - - <%= t("layouts.header.notification_item.notifications") %> - - - <% if current_user.notifications.unread.count > 0 %> - - - - <%= t("layouts.header.notification_item.new_notifications", - count: current_user.notifications_count) %> - - <% else %> - - - <%= t("layouts.header.notification_item.no_notifications") %> - - <% end %> - - <% end %> -
  • -<% end %> +<%= render Layout::NotificationItemComponent.new(current_user) %> diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index 6f6672013..450f51b8a 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -249,8 +249,8 @@ en: new_notifications: one: You have a new notification other: You have %{count} new notifications + zero: "You don't have new notifications" notifications: Notifications - no_notifications: "You don't have new notifications" sdg: "SDG" notifications: index: diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index d1fff5341..67bc57a8a 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -249,8 +249,8 @@ es: new_notifications: one: Tienes una nueva notificación other: Tienes %{count} notificaciones nuevas + zero: "No tienes notificaciones nuevas" notifications: Notificaciones - no_notifications: "No tienes notificaciones nuevas" sdg: "ODS" notifications: index: diff --git a/spec/shared/system/notifiable_in_app.rb b/spec/shared/system/notifiable_in_app.rb index afddae9d3..048eb81f0 100644 --- a/spec/shared/system/notifiable_in_app.rb +++ b/spec/shared/system/notifiable_in_app.rb @@ -2,13 +2,15 @@ shared_examples "notifiable in-app" do |factory_name| let(:author) { create(:user, :verified) } let!(:notifiable) { create(factory_name, author: author) } - scenario "Notification icon is shown" do + before { create(:notification, :read, notifiable: notifiable, user: author) } + + scenario "Notification message is shown" do create(:notification, notifiable: notifiable, user: author) login_as author visit root_path - expect(page).to have_css ".icon-notification" + expect(page).to have_link "You have a new notification" end scenario "A user commented on my notifiable", :js do @@ -16,7 +18,8 @@ shared_examples "notifiable in-app" do |factory_name| login_as author visit root_path - find(".icon-notification").click + + click_link "You have a new notification" expect(page).to have_css ".notification", count: 1 expect(page).to have_content "Someone commented on" @@ -108,7 +111,8 @@ shared_examples "notifiable in-app" do |factory_name| end within("#notifications") do - find(".icon-no-notification").click + click_link "You don't have new notifications" + expect(page).to have_css ".notification", count: 0 end end @@ -130,7 +134,8 @@ shared_examples "notifiable in-app" do |factory_name| end within("#notifications") do - find(".icon-no-notification").click + click_link "You don't have new notifications" + expect(page).to have_css ".notification", count: 0 end end diff --git a/spec/system/notifications_spec.rb b/spec/system/notifications_spec.rb index 186727ad2..9dba969ad 100644 --- a/spec/system/notifications_spec.rb +++ b/spec/system/notifications_spec.rb @@ -103,14 +103,14 @@ describe "Notifications" do visit root_path within("#notifications") do - expect(page).to have_css(".icon-circle") + expect(page).to have_css(".unread-notifications") end click_notifications_icon first(".notification a").click within("#notifications") do - expect(page).not_to have_css(".icon-circle") + expect(page).not_to have_css(".unread-notifications") end end diff --git a/spec/system/proposal_notifications_spec.rb b/spec/system/proposal_notifications_spec.rb index 7a9377962..998dd1223 100644 --- a/spec/system/proposal_notifications_spec.rb +++ b/spec/system/proposal_notifications_spec.rb @@ -198,7 +198,7 @@ describe "Proposal Notifications" do login_as user1 visit root_path - find(".icon-notification").click + click_link "You have a new notification" expect(page).to have_css ".notification", count: 1 @@ -210,7 +210,7 @@ describe "Proposal Notifications" do login_as user2 visit root_path - find(".icon-notification").click + click_link "You have a new notification" expect(page).to have_css ".notification", count: 1 @@ -222,7 +222,7 @@ describe "Proposal Notifications" do login_as user3 visit root_path - find(".icon-no-notification").click + click_link "You don't have new notifications" expect(page).to have_css ".notification", count: 0 end @@ -251,7 +251,7 @@ describe "Proposal Notifications" do login_as user1.reload visit root_path - find(".icon-notification").click + click_link "You have a new notification" expect(page).to have_css ".notification", count: 1 @@ -263,7 +263,7 @@ describe "Proposal Notifications" do login_as user2.reload visit root_path - find(".icon-notification").click + click_link "You have a new notification" expect(page).to have_css ".notification", count: 1 @@ -275,7 +275,7 @@ describe "Proposal Notifications" do login_as user3.reload visit root_path - find(".icon-no-notification").click + click_link "You don't have new notifications" expect(page).to have_css ".notification", count: 0 end @@ -303,7 +303,7 @@ describe "Proposal Notifications" do login_as user visit root_path - find(".icon-notification").click + click_link "You have a new notification" expect(page).to have_css ".notification", count: 1 expect(page).to have_content "This resource is not available anymore" @@ -346,8 +346,7 @@ describe "Proposal Notifications" do login_as user.reload visit root_path - within("#notifications") { expect(page).to have_content :all, "You have 3 new notifications" } - find(".icon-notification").click + click_link "You have 3 new notifications" expect(page).to have_css ".notification", count: 3 expect(page).to have_content "There is one new notification on #{proposal.title}", count: 3