From d331911ffe64c1889f0ef73516ce8c73f5377dfa Mon Sep 17 00:00:00 2001 From: zmagod Date: Thu, 6 Apr 2017 08:42:16 +0200 Subject: [PATCH] completed step annotations --- app/controllers/step_comments_controller.rb | 39 ++- app/controllers/steps_controller.rb | 297 +++++++++++++++++++- app/helpers/application_helper.rb | 25 +- config/locales/en.yml | 10 +- 4 files changed, 332 insertions(+), 39 deletions(-) diff --git a/app/controllers/step_comments_controller.rb b/app/controllers/step_comments_controller.rb index 2e985e3bf..fc81c9b95 100644 --- a/app/controllers/step_comments_controller.rb +++ b/app/controllers/step_comments_controller.rb @@ -48,19 +48,8 @@ class StepCommentsController < ApplicationController respond_to do |format| if @comment.save - smart_annotation_notification( - comment_params[:message], - t('notifications.comment_annotation_title', - step: @step.name, - user: current_user.full_name), - t('notifications.step_comment_annotation_message_html', - project: link_to(@step.my_module.experiment.project.name, - project_url(@step.my_module.experiment.project)), - my_module: link_to(@step.my_module.name, - protocols_my_module_url(@step.my_module)), - step: link_to(@step.name, - protocols_my_module_url(@step.my_module))) - ) + + step_comment_annotation_notification # Generate activity (this can only occur in module, # but nonetheless check if my module is not nil) if @protocol.in_module? @@ -115,10 +104,13 @@ class StepCommentsController < ApplicationController end def update + old_text = @comment.message @comment.message = comment_params[:message] respond_to do |format| format.json do if @comment.save + + step_comment_annotation_notification(old_text) # Generate activity if @protocol.in_module? Activity.create( @@ -212,4 +204,25 @@ class StepCommentsController < ApplicationController def comment_params params.require(:comment).permit(:message) end + + def step_comment_annotation_notification(old_text = nil) + smart_annotation_notification( + old_text: (old_text if old_text), + new_text: comment_params[:message], + title: t('notifications.comment_annotation_title', + step: @step.name, + user: current_user.full_name), + message: t('notifications.step_annotation_message_html', + project: link_to(@step.my_module.experiment.project.name, + project_url(@step.my_module + .experiment + .project)), + my_module: link_to(@step.my_module.name, + protocols_my_module_url( + @step.my_module + )), + step: link_to(@step.name, + protocols_my_module_url(@step.my_module))) + ) + end end diff --git a/app/controllers/steps_controller.rb b/app/controllers/steps_controller.rb index f60ebb6d7..7179be67a 100644 --- a/app/controllers/steps_controller.rb +++ b/app/controllers/steps_controller.rb @@ -44,13 +44,7 @@ class StepsController < ApplicationController # Update default checked state @step.checklists.each do |checklist| - smart_annotation_notification(checklist.name, - t('notifications.checklist_title'), - t('notifications.checklist_message')) checklist.checklist_items.each do |checklist_item| - smart_annotation_notification(checklist_item.text, - t('notifications.checklist_item_title'), - t('notifications.checklist_item_message')) checklist_item.checked = false end end @@ -136,6 +130,9 @@ class StepsController < ApplicationController def update respond_to do |format| + old_description = @step.description + old_checklists = fetch_old_checklists_data(@step) + new_checklists = fetch_new_checklists_data previous_size = @step.space_taken step_params_all = step_params @@ -163,6 +160,12 @@ class StepsController < ApplicationController if @step.save @step.reload + # generates notification on step upadate + update_annotation_notification(@step, + old_description, + new_checklists, + old_checklists) + # Release team's space taken team = @protocol.team team.release_space(previous_size) @@ -688,24 +691,288 @@ class StepsController < ApplicationController def create_annotation_notification(step) # step description smart_annotation_notification( - step.description, - t('notifications.step_description_title'), - t('notifications.step_description_message') + new_text: step.description, + title: t('notifications.step_description_title', + user: current_user.full_name, + step: step.name), + message: t('notifications.step_annotation_message_html', + project: link_to( + step.my_module.experiment.project.name, + project_url(step.my_module.experiment.project) + ), + my_module: link_to( + step.my_module.name, + protocols_my_module_url(step.my_module) + ), + step: link_to( + step.name, + protocols_my_module_url(step.my_module) + )) ) # checklists step.checklists.each do |checklist| smart_annotation_notification( - checklist.name, - t('notifications.checklist_title'), - t('notifications.checklist_message') + new_text: checklist.name, + title: t('notifications.checklist_title', + user: current_user.full_name, + step: step.name), + message: t('notifications.step_annotation_message_html', + project: link_to( + step.my_module.experiment.project.name, + project_url(step.my_module.experiment.project) + ), + my_module: link_to( + step.my_module.name, + protocols_my_module_url(step.my_module) + ), + step: link_to( + step.name, + protocols_my_module_url(step.my_module) + )) ) checklist.checklist_items.each do |checklist_item| smart_annotation_notification( - checklist_item.text, - t('notifications.checklist_item_title'), - t('notifications.checklist_item_message') + new_text: checklist_item.text, + title: t('notifications.checklist_title', + user: current_user.full_name, + step: step.name), + message: t('notifications.step_annotation_message_html', + project: link_to( + step.my_module.experiment.project.name, + project_url(step.my_module.experiment.project) + ), + my_module: link_to( + step.my_module.name, + protocols_my_module_url(step.my_module) + ), + step: link_to( + step.name, + protocols_my_module_url(step.my_module) + )) ) end end end + + def fetch_new_checklists_data + checklists = [] + new_checklists = step_params[:checklists_attributes] + + if new_checklists + new_checklists.each do |e| + list = PreviouseChecklist.new( + e.second[:id].to_i, + e.second[:name] + ) + if e.second[:checklist_items_attributes] + e.second[:checklist_items_attributes].each do |el| + list.add_checklist( + PreviouseChecklistItem.new(el.second[:id].to_i, el.second[:text]) + ) + end + end + checklists << list + end + end + checklists + end + + def fetch_old_checklists_data(step) + checklists = [] + if step.checklists + step.checklists.each do |e| + list = PreviouseChecklist.new( + e.id, + e.name + ) + e.checklist_items.each do |el| + list.add_checklist( + PreviouseChecklistItem.new(el.id, el.text) + ) + end + checklists << list + end + end + checklists + end + + def update_annotation_notification(step, + old_description, + new_checklists, + old_checklists) + smart_annotation_notification( + old_text: old_description, + new_text: step.description, + title: t('notifications.step_description_title', + user: current_user.full_name, + step: step.name), + message: t('notifications.step_annotation_message_html', + project: link_to( + step.my_module.experiment.project.name, + project_url(step.my_module.experiment.project) + ), + my_module: link_to( + step.my_module.name, + protocols_my_module_url(step.my_module) + ), + step: link_to( + step.name, + protocols_my_module_url(step.my_module) + )) + ) + + new_checklists.each do |e| + # generates smart annotaion if the checklist is new + add_new_checklist(step, e) if e.id.zero? + smart_annotation_notification( + new_text: e.name, + title: t('notifications.checklist_title', + user: current_user.full_name, + step: step.name), + message: t('notifications.step_annotation_message_html', + project: link_to( + step.my_module.experiment.project.name, + project_url(step.my_module.experiment.project) + ), + my_module: link_to( + step.my_module.name, + protocols_my_module_url(step.my_module) + ), + step: link_to( + step.name, + protocols_my_module_url(step.my_module) + )) + ) unless e.id + # else check if checklist is not deleted and generates + # new notifications + next unless old_checklists.map(&:id).include?(e.id) + old_checklist = old_checklists.select { |i| i.id == e.id }.first + smart_annotation_notification( + old_text: (old_checklist.name if old_checklist), + new_text: e.name, + title: t('notifications.checklist_title', + user: current_user.full_name, + step: step.name), + message: t('notifications.step_annotation_message_html', + project: link_to( + step.my_module.experiment.project.name, + project_url(step.my_module.experiment.project) + ), + my_module: link_to( + step.my_module.name, + protocols_my_module_url(step.my_module) + ), + step: link_to( + step.name, + protocols_my_module_url(step.my_module) + )) + ) + e.items.each do |ci| + old_list = old_checklists.select { |i| i.id == e.id }.first + old_item = old_list.items.select { |i| i.id == ci.id }.first if old_list + + smart_annotation_notification( + old_text: (old_item.text if old_item), + new_text: ci.text, + title: t('notifications.checklist_title', + user: current_user.full_name, + step: step.name), + message: t('notifications.step_annotation_message_html', + project: link_to( + step.my_module.experiment.project.name, + project_url(step.my_module.experiment.project) + ), + my_module: link_to( + step.my_module.name, + protocols_my_module_url(step.my_module) + ), + step: link_to( + step.name, + protocols_my_module_url(step.my_module) + )) + ) + end + end + end + + def add_new_checklist(step, checklist) + smart_annotation_notification( + new_text: checklist.name, + title: t('notifications.checklist_title', + user: current_user.full_name, + step: step.name), + message: t('notifications.step_annotation_message_html', + project: link_to( + step.my_module.experiment.project.name, + project_url(step.my_module.experiment.project) + ), + my_module: link_to( + step.my_module.name, + protocols_my_module_url(step.my_module) + ), + step: link_to( + step.name, + protocols_my_module_url(step.my_module) + )) + ) + + checklist.items.each do |ci| + smart_annotation_notification( + new_text: ci.text, + title: t('notifications.checklist_title', + user: current_user.full_name, + step: step.name), + message: t('notifications.step_annotation_message_html', + project: link_to( + step.my_module.experiment.project.name, + project_url(step.my_module.experiment.project) + ), + my_module: link_to( + step.my_module.name, + protocols_my_module_url(step.my_module) + ), + step: link_to( + step.name, + protocols_my_module_url(step.my_module) + )) + ) + end + end + + PreviouseChecklistItem = Struct.new(:id, :text) + PreviouseChecklist = Struct.new(:id, :name, :items) do + def initialize(id, name, items = []) + super(id, name, items) + end + + def add_checklist(item) + items << item + end + end + + # def update_annotation_notification(step, updated_step) + # # step description + # smart_annotation_notification( + # old_text: + # new_text: updated_step.description, + # title: t('notifications.step_description_title'), + # message: t('notifications.step_description_message') + # ) + # # checklists + # updated_step.checklists.each do |checklist| + # smart_annotation_notification( + # + # new_text: checklist.name, + # title: t('notifications.checklist_title'), + # message: t('notifications.checklist_message') + # ) + # checklist.checklist_items.each do |checklist_item| + # smart_annotation_notification( + # new_text: checklist_item.text, + # title: t('notifications.checklist_item_title'), + # message: t('notifications.checklist_item_message') + # ) + # end + # end + # end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d2626cd2a..27519828c 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -58,13 +58,30 @@ module ApplicationHelper !@experiment.nil? end - def smart_annotation_notification(text, title, message) + def smart_annotation_notification(options = {}) + title = options.fetch(:title) { :title_must_be_present } + message = options.fetch(:message) { :message_must_be_present } + new_text = options.fetch(:new_text) { :new_text_must_be_present } + old_text = options[:old_text] || '' sa_user = /\[\@(.*?)~([0-9a-zA-Z]+)\]/ - annotated_users = [] - text.gsub(sa_user) do |el| + + old_user_ids = [] + old_text.gsub(sa_user) do |el| match = el.match(sa_user) - annotated_users << match[2].base62_decode + old_user_ids << match[2].base62_decode end + + new_user_ids = [] + new_text.gsub(sa_user) do |el| + match = el.match(sa_user) + new_user_ids << match[2].base62_decode + end + + annotated_users = [] + new_user_ids.each do |el| + annotated_users << el unless old_user_ids.include?(el) + end + annotated_users.uniq.each do |user_id| target_user = User.find_by_id(user_id) next unless target_user diff --git a/config/locales/en.yml b/config/locales/en.yml index 0da9d54e3..dd59cd876 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1517,13 +1517,9 @@ en: system_message: "sciNote system message" deliver: 'Exportable content' comment_annotation_title: "%{user} mentioned you %{step} step comment." - step_description_title: - step_description_message: - checklist_title: - checklist_message: - checklist_item_title: - checklist_item_message: - step_comment_annotation_message_html: "Project: %{project} | Task: %{my_module} | Step: %{step}" + step_description_title: "%{user} mentioned you %{step} step description." + checklist_title: "%{user} mentioned you %{step} step checklist." + step_annotation_message_html: "Project: %{project} | Task: %{my_module} | Step: %{step}" email_title: "You've received a sciNote notification!" assign_user_to_team: "%{assigned_user} was added as %{role} to team %{team} by %{assigned_by_user}." unassign_user_from_team: "%{unassigned_user} was removed from team %{team} by %{unassigned_by_user}."