Merge pull request #8865 from aignatov-bio/ai-sci-12333-add-result-content-observer

Add result contents observer [SCI-12333]
This commit is contained in:
aignatov-bio 2025-09-11 13:06:32 +02:00 committed by GitHub
commit 90d746679b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 65 additions and 12 deletions

View file

@ -52,13 +52,13 @@ class ResultsController < ApplicationController
end
def create
result = @my_module.results.create!(user: current_user)
result = @my_module.results.create!(user: current_user, last_modified_by: current_user)
log_activity(:add_result, { result: result })
render json: result
end
def update
@result.update!(result_params)
@result.update!(result_params.merge(last_modified_by: current_user))
log_activity(:edit_result, { result: @result })
render json: @result
end

View file

@ -6,6 +6,7 @@ module ObservableModel
included do
after_create :notify_observers_on_create
after_update :notify_observers_on_update
after_destroy :notify_observers_on_destroy
end
private
@ -25,4 +26,10 @@ module ObservableModel
Extends::TEAM_AUTOMATIONS_OBSERVERS_CONFIG[self.class.base_class.name].each { |observer| observer.constantize.on_update(self, changed_by) }
end
def notify_observers_on_destroy
return if Current.team.blank?
Extends::TEAM_AUTOMATIONS_OBSERVERS_CONFIG[self.class.base_class.name].each { |observer| observer.constantize.on_destroy(self, changed_by) }
end
end

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true
class ResultComment < Comment
include ObservableModel
before_create :fill_unseen_by
belongs_to :result, foreign_key: :associated_id, inverse_of: :result_comments
@ -16,4 +18,9 @@ class ResultComment < Comment
def fill_unseen_by
self.unseen_by += result.my_module.experiment.project.users.where.not(id: user.id).pluck(:id)
end
# Override for ObservableModel
def changed_by
last_modified_by || user
end
end

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true
class ResultOrderableElement < ApplicationRecord
include ObservableModel
validates :position, uniqueness: { scope: :result }
validate :check_result_relations
@ -26,4 +28,9 @@ class ResultOrderableElement < ApplicationRecord
result.normalize_elements_position
end
end
# Override for ObservableModel
def changed_by
result.last_modified_by || result.user
end
end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
class ResultTable < ApplicationRecord
belongs_to :result, inverse_of: :result_tables
belongs_to :result, inverse_of: :result_tables, touch: true
belongs_to :table, inverse_of: :result_table, dependent: :destroy, touch: true
has_one :result_orderable_element, as: :orderable, dependent: :destroy
end

View file

@ -3,6 +3,7 @@
class ResultText < ApplicationRecord
include TinyMceImages
include SearchableModel
include ObservableModel
include ActionView::Helpers::TextHelper
SEARCHABLE_ATTRIBUTES = ['result_texts.name', 'result_texts.text'].freeze
@ -35,4 +36,11 @@ class ResultText < ApplicationRecord
new_result_text
end
end
private
# Override for ObservableModel
def changed_by
result.last_modified_by || result.user
end
end

View file

@ -5,5 +5,7 @@ module AutomationObservers
def self.on_create(object, user); end
def self.on_update(object, user); end
def self.on_destroy(object, user); end
end
end

View file

@ -1,9 +1,23 @@
# frozen_string_literal: true
module AutomationObservers
class ResultCreateObserver < BaseObserver
def self.on_create(result, user)
return unless Current.team.settings.dig('team_automation_settings', 'tasks', 'task_status_in_progress', 'on_added_result')
class ResultContentChangeObserver < BaseObserver
def self.on_create(element, user)
on_update(element, user)
end
def self.on_update(element, user)
return unless Current.team.settings.dig('team_automation_settings', 'tasks', 'task_status_in_progress', 'on_result_created_or_changed')
result = case element.class.name
when 'Result'
element
else
element.result
end
return if result.blank?
return if result.archived_previously_changed?
return unless result.my_module.my_module_status.initial_status?
my_module = result.my_module
@ -22,5 +36,9 @@ module AutomationObservers
my_module_status_new: my_module.my_module_status.id
})
end
def self.on_destroy(element, user)
on_update(element, user)
end
end
end

View file

@ -812,7 +812,7 @@ class Extends
task_status_in_progress: %I[
on_protocol_content_change
on_step_completion
on_added_result
on_result_created_or_changed
],
task_status_completed: %I[
on_all_steps_completion
@ -840,16 +840,20 @@ class Extends
'Experiment' => ['AutomationObservers::AllExperimentsDoneObserver', 'AutomationObservers::ExperimentStatusChangeObserver'],
'MyModule' => ['AutomationObservers::AllTasksDoneObserver', 'AutomationObservers::TaskStatusChangeObserver'],
'Protocol' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'Asset' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'Table' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'Comment' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'Asset' => ['AutomationObservers::TaskProtocolContentChangeObserver', 'AutomationObservers::ResultContentChangeObserver'],
'Table' => ['AutomationObservers::TaskProtocolContentChangeObserver', 'AutomationObservers::ResultContentChangeObserver'],
'Comment' => ['AutomationObservers::TaskProtocolContentChangeObserver', 'AutomationObservers::ResultContentChangeObserver'],
'ChecklistItem' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'Checklist' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'FormFieldValue' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'StepOrderableElement' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'StepComment' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'StepText' => ['AutomationObservers::TaskProtocolContentChangeObserver'],
'Step' => ['AutomationObservers::AllStepsCompletionObserver', 'AutomationObservers::StepCompletionObserver', 'AutomationObservers::TaskProtocolContentChangeObserver'],
'Result' => ['AutomationObservers::ResultCreateObserver']
'Result' => ['AutomationObservers::ResultContentChangeObserver'],
'ResultText' => ['AutomationObservers::ResultContentChangeObserver'],
'ResultComment' => ['AutomationObservers::ResultContentChangeObserver'],
'ResultOrderableElement' => ['AutomationObservers::ResultContentChangeObserver']
}
DEFAULT_TEAM_SETTINGS = {}

View file

@ -4344,7 +4344,7 @@ en:
sub_group_element:
on_protocol_content_change: 'Protocol content is added (including step comments)'
on_step_completion: 'At least one step is marked as completed'
on_added_result: 'Task result is added'
on_result_created_or_changed: 'Task result is added or modified (including result comments)'
on_task_in_progress: 'At least one task moves from "Not started" to "In progress" or other status'
on_all_tasks_done: 'All tasks inside reach their final status.'
on_experiment_in_progress: 'At least one experiment moves to "In progress" or "Done"'