diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 2709f2816..fe614c295 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -86,7 +86,7 @@ class CommentsController < ApplicationController notifiable = comment.reply? ? comment.parent : comment.commentable notifiable_author_id = notifiable.try(:author_id) if notifiable_author_id.present? && notifiable_author_id != comment.author_id - Notification.add(notifiable.author_id, notifiable) + Notification.add(notifiable.author, notifiable) end end diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 7d833f6a1..588f2ed6b 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -2,28 +2,40 @@ class NotificationsController < ApplicationController include CustomUrlsHelper before_action :authenticate_user! - after_action :mark_as_read, only: :show skip_authorization_check + respond_to :html, :js + def index - @notifications = current_user.notifications.unread.recent.for_render + @notifications = current_user.notifications.unread end def show @notification = current_user.notifications.find(params[:id]) + @notification.mark_as_read redirect_to linkable_resource_path(@notification) end + def read + @notifications = current_user.notifications.read + end + def mark_all_as_read - current_user.notifications.each { |notification| notification.mark_as_read } + current_user.notifications.unread.each { |notification| notification.mark_as_read } redirect_to notifications_path end - private + def mark_as_read + @notification = current_user.notifications.find(params[:id]) + @notification.mark_as_read + end - def mark_as_read - @notification.mark_as_read - end + def mark_as_unread + @notification = current_user.notifications.find(params[:id]) + @notification.mark_as_unread + end + + private def linkable_resource_path(notification) case notification.linkable_resource.class.name diff --git a/app/controllers/proposal_notifications_controller.rb b/app/controllers/proposal_notifications_controller.rb index dfad56945..5c81a34ef 100644 --- a/app/controllers/proposal_notifications_controller.rb +++ b/app/controllers/proposal_notifications_controller.rb @@ -12,7 +12,7 @@ class ProposalNotificationsController < ApplicationController @proposal = Proposal.find(proposal_notification_params[:proposal_id]) if @notification.save @proposal.users_to_notify.each do |user| - Notification.add(user.id, @notification) + Notification.add(user, @notification) end redirect_to @notification, notice: I18n.t("flash.actions.create.proposal_notification") else diff --git a/app/models/notification.rb b/app/models/notification.rb index de0e7c645..33bf7701c 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -3,30 +3,48 @@ class Notification < ActiveRecord::Base belongs_to :user, counter_cache: true belongs_to :notifiable, polymorphic: true - scope :unread, -> { all } - scope :recent, -> { order(id: :desc) } + validates :user, presence: true + + scope :read, -> { where.not(read_at: nil).recent.for_render } + scope :unread, -> { where(read_at: nil).recent.for_render } scope :not_emailed, -> { where(emailed_at: nil) } + scope :recent, -> { order(id: :desc) } scope :for_render, -> { includes(:notifiable) } - delegate :notifiable_title, :notifiable_available?, :check_availability, :linkable_resource, - to: :notifiable, allow_nil: true + delegate :notifiable_title, :notifiable_available?, :check_availability, + :linkable_resource, to: :notifiable, allow_nil: true + + def mark_as_read + update(read_at: Time.current) + end + + def mark_as_unread + update(read_at: nil) + end + + def read? + read_at.present? + end + + def unread? + read_at.nil? + end def timestamp notifiable.created_at end - def mark_as_read - destroy + def self.add(user, notifiable) + notification = Notification.existent(user, notifiable) + if notification.present? + increment_counter(:counter, notification.id) + else + create!(user: user, notifiable: notifiable) + end end - def self.add(user_id, notifiable) - notification = Notification.find_by(user_id: user_id, notifiable: notifiable) - - if notification.present? - Notification.increment_counter(:counter, notification.id) - else - Notification.create!(user_id: user_id, notifiable: notifiable) - end + def self.existent(user, notifiable) + unread.where(user: user, notifiable: notifiable).first end def notifiable_action diff --git a/app/views/devise/menu/_login_items.html.erb b/app/views/devise/menu/_login_items.html.erb index f74aede44..e34e96230 100644 --- a/app/views/devise/menu/_login_items.html.erb +++ b/app/views/devise/menu/_login_items.html.erb @@ -1,22 +1,11 @@ <% if user_signed_in? %> -
  • - <%= link_to notifications_path, rel: "nofollow", class: "notifications" do %> - <%= t("layouts.header.notifications") %> - <% if current_user.notifications_count > 0 %> - - - - <%= t('layouts.header.new_notifications', count: current_user.notifications_count).html_safe %> - - <% else %> - - - <%= t('layouts.header.no_notifications') %> - - <% end %> - <% end %> -
  • + <% if current_budget %> +
  • + <%= link_to(t("layouts.header.delegation"), + new_budget_recommendation_path(budget_id: current_budget.slug), + accesskey: "d") %> +
  • + <% end %>
  • <%= layout_menu_link_to t("layouts.header.my_activity_link"), user_path(current_user), diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index 487707079..a73a99509 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -30,6 +30,7 @@
    diff --git a/app/views/layouts/_notification_item.html.erb b/app/views/layouts/_notification_item.html.erb new file mode 100644 index 000000000..034726ea9 --- /dev/null +++ b/app/views/layouts/_notification_item.html.erb @@ -0,0 +1,30 @@ +<% 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).html_safe %> + + <% else %> + + + <%= t('layouts.header.notification_item.no_notifications') %> + + <% end %> + + <% end %> +
  • +<% end %> \ No newline at end of file diff --git a/app/views/notifications/_notification.html.erb b/app/views/notifications/_notification.html.erb index a5c69550c..654006fad 100644 --- a/app/views/notifications/_notification.html.erb +++ b/app/views/notifications/_notification.html.erb @@ -3,19 +3,37 @@ <%= link_to notification do %>

    - <%= t("notifications.index.#{notification.notifiable_action}", + <%= t("notifications.notification.action.#{notification.notifiable_action}", count: notification.counter) %> - <%= notification.notifiable_title %> + + <%= notification.notifiable_title %> +

    -

    <%= l notification.timestamp, format: :datetime %>

    +

    + <%= l notification.timestamp, format: :datetime %> +

    <% end %> <% else %>

    - <%= t("notifications.index.notifiable_hidden") %> + <%= t("notifications.notification.notifiable_hidden") %>

    <% end %> + +
    + <% if notification.unread? %> + <%= link_to t("notifications.notification.mark_as_read"), + mark_as_read_notification_path(notification), + method: :put, + remote: true %> + <% else %> + <%= link_to t("notifications.notification.mark_as_unread"), + mark_as_unread_notification_path(notification), + method: :put, + remote: true %> + <% end %> +
    \ No newline at end of file diff --git a/app/views/notifications/index.html.erb b/app/views/notifications/index.html.erb index 889e5395d..646b0c7a0 100644 --- a/app/views/notifications/index.html.erb +++ b/app/views/notifications/index.html.erb @@ -3,15 +3,22 @@

    <%= t("notifications.index.title") %>

    +

    + <%= link_to t("notifications.index.unread"), notifications_path %> + <%= link_to t("notifications.index.read"), read_notifications_path %> +

    + <% if @notifications.empty? %>
    <%= t("notifications.index.empty_notifications") %>
    <% else %> -
    - <%= link_to t("notifications.index.mark_all_as_read"), - mark_all_as_read_notifications_path, method: :put %> -
    + <% if action_name == "index" %> +
    + <%= link_to t("notifications.index.mark_all_as_read"), + mark_all_as_read_notifications_path, method: :put %> +
    + <% end %>