From 62374bee0aa7e22ddb4982b1649d0e05fef69460 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Mon, 30 Nov 2020 15:55:20 +0100 Subject: [PATCH] Implement the 'seen comments' functionality (red dot) for the comments [SCI-5253] --- app/helpers/comment_helper.rb | 4 ++++ app/models/comment.rb | 6 ++++++ app/models/my_module.rb | 2 +- app/models/project.rb | 2 +- app/models/project_comment.rb | 8 ++++++++ app/models/result.rb | 2 +- app/models/result_comment.rb | 8 ++++++++ app/models/step.rb | 2 +- app/models/step_comment.rb | 8 ++++++++ app/models/task_comment.rb | 8 ++++++++ .../projects/index/_project_actions_dropdown.html.erb | 2 +- app/views/shared/comments/_comments.html.erb | 11 ++++++----- .../20201126203713_add_unseen_by_to_comments.rb | 7 +++++++ db/structure.sql | 6 ++++-- 14 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 db/migrate/20201126203713_add_unseen_by_to_comments.rb diff --git a/app/helpers/comment_helper.rb b/app/helpers/comment_helper.rb index 837f0ac50..24c272117 100644 --- a/app/helpers/comment_helper.rb +++ b/app/helpers/comment_helper.rb @@ -254,4 +254,8 @@ module CommentHelper project: result.my_module.experiment.project, message_items: { result: result.id }) end + + def has_unseen_comments?(commentable) + commentable.comments.where('? = ANY (unseen_by)', current_user.id).any? + end end diff --git a/app/models/comment.rb b/app/models/comment.rb index 74a646961..70e3c68cd 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -60,4 +60,10 @@ class Comment < ApplicationRecord .offset((page - 1) * Constants::SEARCH_LIMIT) end end + + def self.mark_as_seen_by(user) + # rubocop:disable Rails/SkipsModelValidations + all.where('? = ANY (unseen_by)', user.id).update_all("unseen_by = array_remove(unseen_by, #{user.id.to_i}::bigint)") + # rubocop:enable Rails/SkipsModelValidations + end end diff --git a/app/models/my_module.rb b/app/models/my_module.rb index 2e70fba2d..b9ae4cc57 100644 --- a/app/models/my_module.rb +++ b/app/models/my_module.rb @@ -249,7 +249,7 @@ class MyModule < ApplicationRecord .where('comments.id < ?', last_id) .order(created_at: :desc) .limit(per_page) - comments.reverse + TaskComment.from(comments, :comments).order(created_at: :asc) end def last_activities(last_id = 1, diff --git a/app/models/project.rb b/app/models/project.rb index 9315332e2..4613d7def 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -164,7 +164,7 @@ class Project < ApplicationRecord .where('comments.id < ?', last_id) .order(created_at: :desc) .limit(per_page) - comments.reverse + ProjectComment.from(comments, :comments).order(created_at: :asc) end def unassigned_users diff --git a/app/models/project_comment.rb b/app/models/project_comment.rb index c92f770d9..b159bb333 100644 --- a/app/models/project_comment.rb +++ b/app/models/project_comment.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class ProjectComment < Comment + before_create :fill_unseen_by + belongs_to :project, foreign_key: :associated_id, inverse_of: :project_comments, touch: true validates :project, presence: true @@ -8,4 +10,10 @@ class ProjectComment < Comment def commentable project end + + private + + def fill_unseen_by + self.unseen_by += project.users.where.not(id: user.id).pluck(:id) + end end diff --git a/app/models/result.rb b/app/models/result.rb index 7af2454bf..f364ea4b8 100644 --- a/app/models/result.rb +++ b/app/models/result.rb @@ -76,7 +76,7 @@ class Result < ApplicationRecord .where('comments.id < ?', last_id) .order(created_at: :desc) .limit(per_page) - comments.reverse + ResultComment.from(comments, :comments).order(created_at: :asc) end def is_text diff --git a/app/models/result_comment.rb b/app/models/result_comment.rb index be32285fe..e373f7886 100644 --- a/app/models/result_comment.rb +++ b/app/models/result_comment.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class ResultComment < Comment + before_create :fill_unseen_by + belongs_to :result, foreign_key: :associated_id, inverse_of: :result_comments, touch: true validates :result, presence: true @@ -8,4 +10,10 @@ class ResultComment < Comment def commentable result end + + private + + def fill_unseen_by + self.unseen_by += result.my_module.experiment.project.users.where.not(id: user.id).pluck(:id) + end end diff --git a/app/models/step.rb b/app/models/step.rb index d0c08317c..fe5fd0fbb 100644 --- a/app/models/step.rb +++ b/app/models/step.rb @@ -102,7 +102,7 @@ class Step < ApplicationRecord .where('comments.id < ?', last_id) .order(created_at: :desc) .limit(per_page) - comments.reverse + StepComment.from(comments, :comments).order(created_at: :asc) end def save(current_user=nil) diff --git a/app/models/step_comment.rb b/app/models/step_comment.rb index 445a54504..b6a5793ff 100644 --- a/app/models/step_comment.rb +++ b/app/models/step_comment.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class StepComment < Comment + before_create :fill_unseen_by + belongs_to :step, foreign_key: :associated_id, inverse_of: :step_comments, touch: true validates :step, presence: true @@ -8,4 +10,10 @@ class StepComment < Comment def commentable step end + + private + + def fill_unseen_by + self.unseen_by += step.protocol.my_module.experiment.project.users.where.not(id: user.id).pluck(:id) + end end diff --git a/app/models/task_comment.rb b/app/models/task_comment.rb index 00d0368dd..3c7ff127c 100644 --- a/app/models/task_comment.rb +++ b/app/models/task_comment.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class TaskComment < Comment + before_create :fill_unseen_by + belongs_to :my_module, foreign_key: :associated_id, inverse_of: :task_comments validates :my_module, presence: true @@ -8,4 +10,10 @@ class TaskComment < Comment def commentable my_module end + + private + + def fill_unseen_by + self.unseen_by += my_module.experiment.project.users.where.not(id: user.id).pluck(:id) + end end diff --git a/app/views/projects/index/_project_actions_dropdown.html.erb b/app/views/projects/index/_project_actions_dropdown.html.erb index 546c414af..bf32371a2 100644 --- a/app/views/projects/index/_project_actions_dropdown.html.erb +++ b/app/views/projects/index/_project_actions_dropdown.html.erb @@ -1,7 +1,7 @@ <% cache [current_user, project] do %> <% active = !project.archived %> <% if (active && (can_manage_project?(project) || can_archive_project?(project))) || (!active && can_restore_project?(project)) %> -