diff --git a/app/controllers/step_elements/base_controller.rb b/app/controllers/step_elements/base_controller.rb
index 8767fc56d..efbb97548 100644
--- a/app/controllers/step_elements/base_controller.rb
+++ b/app/controllers/step_elements/base_controller.rb
@@ -33,5 +33,23 @@ module StepElements
step_orderable_element = orderable.step_orderable_elements.find_by!(step: @step)
render json: step_orderable_element, serializer: StepOrderableElementSerializer, user: current_user
end
+
+ def log_step_activity(element_type_of, message_items)
+ Activities::CreateActivityService.call(
+ activity_type: "#{@step.protocol.in_module? ? 'protocol_step_' : 'task_step_'}#{element_type_of}",
+ owner: current_user,
+ team: @protocol.in_module? ? @protocol.my_module.experiment.project.team : @protocol.team,
+ project: @protocol.in_module? ? @protocol.my_module.experiment.project : nil,
+ subject: @protocol,
+ message_items: {
+ step: @step.id,
+ step_position: {
+ id: @step.id,
+ value_for: 'position_plus_one'
+ },
+ my_module: @protocol.my_module.id
+ }.merge(message_items)
+ )
+ end
end
end
diff --git a/app/controllers/step_elements/checklist_items_controller.rb b/app/controllers/step_elements/checklist_items_controller.rb
index 94c4b0a43..c8fcd6a55 100644
--- a/app/controllers/step_elements/checklist_items_controller.rb
+++ b/app/controllers/step_elements/checklist_items_controller.rb
@@ -10,7 +10,18 @@ module StepElements
def create
checklist_item = @checklist.checklist_items.build(checklist_item_params.merge!(created_by: current_user))
- checklist_item.save!
+
+ ActiveRecord::Base.transaction do
+ checklist_item.save!
+ log_activity(
+ "#{@step.protocol.in_module? ? :task : :protocol}_step_checklist_item_added",
+ {
+ checklist_item: checklist_item.text,
+ checklist_name: @checklist.name
+ }
+ )
+ end
+
render json: checklist_item, serializer: ChecklistItemSerializer
rescue ActiveRecord::RecordInvalid
render json: checklist_item, serializer: ChecklistItemSerializer, status: :unprocessable_entity
@@ -19,22 +30,27 @@ module StepElements
def update
@checklist_item.assign_attributes(checklist_item_params)
- if @checklist_item.save! && @checklist_item.saved_change_to_attribute?(:checked)
- completed_items = @checklist_item.checklist.checklist_items.where(checked: true).count
- all_items = @checklist_item.checklist.checklist_items.count
- text_activity = smart_annotation_parser(@checklist_item.text).gsub(/\s+/, ' ')
- type_of = if @checklist_item.saved_change_to_attribute(:checked).last
- :check_step_checklist_item
- else
- :uncheck_step_checklist_item
- end
- log_activity(type_of,
- my_module: @step.protocol.my_module.id,
- step: @step.id,
- step_position: { id: @step.id, value_for: 'position_plus_one' },
- checkbox: text_activity,
- num_completed: completed_items.to_s,
- num_all: all_items.to_s)
+ if @checklist_item.save!
+ if @checklist_item.saved_change_to_attribute?(:checked)
+ completed_items = @checklist_item.checklist.checklist_items.where(checked: true).count
+ all_items = @checklist_item.checklist.checklist_items.count
+ text_activity = smart_annotation_parser(@checklist_item.text).gsub(/\s+/, ' ')
+ type_of = if @checklist_item.saved_change_to_attribute(:checked).last
+ :check_step_checklist_item
+ else
+ :uncheck_step_checklist_item
+ end
+ log_activity(type_of,
+ checkbox: text_activity,
+ num_completed: completed_items.to_s,
+ num_all: all_items.to_s)
+ else
+ log_activity(
+ "#{@step.protocol.in_module? ? :task : :protocol}_step_checklist_item_edited",
+ checklist_item: @checklist_item.text,
+ checklist_name: @checklist.name
+ )
+ end
end
render json: @checklist_item, serializer: ChecklistItemSerializer
@@ -44,6 +60,11 @@ module StepElements
def destroy
if @checklist_item.destroy
+ log_activity(
+ "#{@step.protocol.in_module? ? :task : :protocol}_step_checklist_item_deleted",
+ checklist_item: @checklist_item.text,
+ checklist_name: @checklist.name
+ )
render json: @checklist_item, serializer: ChecklistItemSerializer
else
render json: @checklist_item, serializer: ChecklistItemSerializer, status: :unprocessable_entity
@@ -84,15 +105,22 @@ module StepElements
end
def log_activity(type_of, message_items = {})
- default_items = { step: @step.id, step_position: { id: @step.id, value_for: 'position_plus_one' } }
+ default_items = {
+ my_module: (@step.protocol.in_module? ? @step.protocol.my_module.id : nil),
+ step: @step.id,
+ step_position: { id: @step.id, value_for: 'position_plus_one' }
+ }
+
message_items = default_items.merge(message_items)
- Activities::CreateActivityService.call(activity_type: type_of,
- owner: current_user,
- subject: @step.protocol,
- team: @step.protocol.team,
- project: @step.protocol.my_module.experiment.project,
- message_items: message_items)
+ Activities::CreateActivityService.call(
+ activity_type: type_of,
+ owner: current_user,
+ subject: @step.protocol,
+ team: @step.protocol.team,
+ project: @step.protocol.my_module.experiment.project,
+ message_items: message_items
+ )
end
end
end
diff --git a/app/controllers/step_elements/checklists_controller.rb b/app/controllers/step_elements/checklists_controller.rb
index 7cf702590..6df62f5c9 100644
--- a/app/controllers/step_elements/checklists_controller.rb
+++ b/app/controllers/step_elements/checklists_controller.rb
@@ -8,15 +8,21 @@ module StepElements
checklist = @step.checklists.build(
name: t('protocols.steps.checklist.default_name', position: @step.checklists.length + 1)
)
-
- create_in_step!(@step, checklist)
+ ActiveRecord::Base.transaction do
+ create_in_step!(@step, checklist)
+ log_step_activity(:checklist_added, { checklist_name: checklist.name })
+ end
render_step_orderable_element(checklist)
rescue ActiveRecord::RecordInvalid
head :unprocessable_entity
end
def update
- @checklist.update!(checklist_params)
+ ActiveRecord::Base.transaction do
+ @checklist.update!(checklist_params)
+ log_step_activity(:checklist_edited, { checklist_name: @checklist.name })
+ end
+
render json: @checklist, serializer: ChecklistSerializer
rescue ActiveRecord::RecordInvalid
head :unprocessable_entity
@@ -24,6 +30,7 @@ module StepElements
def destroy
if @checklist.destroy
+ log_step_activity(:checklist_deleted, { checklist_name: @checklist.name })
head :ok
else
head :unprocessable_entity
diff --git a/app/controllers/step_elements/tables_controller.rb b/app/controllers/step_elements/tables_controller.rb
index e16e06125..aa3854e5c 100644
--- a/app/controllers/step_elements/tables_controller.rb
+++ b/app/controllers/step_elements/tables_controller.rb
@@ -12,7 +12,10 @@ module StepElements
created_by: current_user
))
- create_in_step!(@step, step_table)
+ ActiveRecord::Base.transaction do
+ create_in_step!(@step, step_table)
+ log_step_activity(:table_added, { table_name: step_table.table.name })
+ end
render_step_orderable_element(step_table)
rescue ActiveRecord::RecordInvalid
@@ -20,7 +23,11 @@ module StepElements
end
def update
- @table.update!(table_params)
+ ActiveRecord::Base.transaction do
+ @table.update!(table_params)
+ log_step_activity(:table_edited, { table_name: @table.name })
+ end
+
render json: @table, serializer: TableSerializer
rescue ActiveRecord::RecordInvalid
head :unprocessable_entity
@@ -28,6 +35,7 @@ module StepElements
def destroy
if @table.destroy
+ log_step_activity(:table_deleted, { table_name: @table.name })
head :ok
else
head :unprocessable_entity
diff --git a/app/controllers/step_elements/texts_controller.rb b/app/controllers/step_elements/texts_controller.rb
index 8e6cdf54a..dad1ca80e 100644
--- a/app/controllers/step_elements/texts_controller.rb
+++ b/app/controllers/step_elements/texts_controller.rb
@@ -6,15 +6,24 @@ module StepElements
def create
step_text = @step.step_texts.build
- create_in_step!(@step, step_text)
+
+ ActiveRecord::Base.transaction do
+ create_in_step!(@step, step_text)
+ log_step_activity(:text_added, { text_name: step_text.name })
+ end
+
render_step_orderable_element(step_text)
rescue ActiveRecord::RecordInvalid
head :unprocessable_entity
end
def update
- @step_text.update!(step_text_params)
- TinyMceAsset.update_images(@step_text, params[:tiny_mce_images], current_user)
+ ActiveRecord::Base.transaction do
+ @step_text.update!(step_text_params)
+ TinyMceAsset.update_images(@step_text, params[:tiny_mce_images], current_user)
+ log_step_activity(:text_edited, { text_name: @step_text.name })
+ end
+
render json: @step_text, serializer: StepTextSerializer
rescue ActiveRecord::RecordInvalid
head :unprocessable_entity
@@ -22,6 +31,7 @@ module StepElements
def destroy
if @step_text.destroy
+ log_step_activity(:text_deleted, { text_name: @step_text.name })
head :ok
else
head :unprocessable_entity
diff --git a/app/javascript/vue/protocol/step_elements/checklist.vue b/app/javascript/vue/protocol/step_elements/checklist.vue
index ff81b8262..18e260263 100644
--- a/app/javascript/vue/protocol/step_elements/checklist.vue
+++ b/app/javascript/vue/protocol/step_elements/checklist.vue
@@ -87,13 +87,13 @@
},
created() {
this.checklistItems = this.element.attributes.orderable.checklist_items.map((item, index) => {
- return { attributes: {...item, position: index + 1 } }
+ return { attributes: {...item, position: index } }
});
},
computed: {
orderedChecklistItems() {
return this.checklistItems.map((item, index) => {
- return { attributes: {...item.attributes, position: index + 1 } }
+ return { attributes: {...item.attributes, position: index } }
});
},
pastingMultiline() {
@@ -114,7 +114,7 @@
postItem(item, callback) {
$.post(this.element.attributes.orderable.urls.create_item_url, item).success((result) => {
this.checklistItems.splice(
- result.data.attributes.position - 1,
+ result.data.attributes.position,
1,
{ attributes: { ...result.data.attributes, id: result.data.id } }
);
@@ -127,7 +127,7 @@
saveItem(item) {
if (item.attributes.id) {
this.checklistItems.splice(
- item.attributes.position - 1, 1, item
+ item.attributes.position, 1, item
);
$.ajax({
url: item.attributes.urls.update_url,
@@ -147,13 +147,13 @@
attributes: {
text: '',
checked: false,
- position: this.checklistItems.length + 1
+ position: this.checklistItems.length
}
}
);
},
- removeItem(item) {
- this.checklistItems.splice(item.attributes.position - 1, 1);
+ removeItem(position) {
+ this.checklistItems.splice(position, 1);
},
startReorder() {
this.reordering = true;
diff --git a/app/javascript/vue/protocol/step_elements/checklistItem.vue b/app/javascript/vue/protocol/step_elements/checklistItem.vue
index 3fbd629b6..68025c371 100644
--- a/app/javascript/vue/protocol/step_elements/checklistItem.vue
+++ b/app/javascript/vue/protocol/step_elements/checklistItem.vue
@@ -66,7 +66,12 @@
},
computed: {
element() { // remap and alias to work with delete mixin
- return { attributes: { orderable: this.checklistItem.attributes } }
+ return({
+ attributes: {
+ orderable: this.checklistItem.attributes,
+ position: this.checklistItem.attributes.position
+ }
+ });
}
},
methods: {
@@ -92,7 +97,7 @@
}
},
removeItem() {
- this.$emit('removeItem', this.checklistItem);
+ this.$emit('removeItem', this.checklistItem.attributes.position);
},
update() {
this.$emit('update', this.checklistItem);
diff --git a/app/models/checklist_item.rb b/app/models/checklist_item.rb
index cf24b3159..9617a60fa 100644
--- a/app/models/checklist_item.rb
+++ b/app/models/checklist_item.rb
@@ -25,7 +25,7 @@ class ChecklistItem < ApplicationRecord
def update_positions
transaction do
checklist.checklist_items.order(position: :asc).each_with_index do |checklist_item, i|
- checklist_item.update!(position: i + 1)
+ checklist_item.update!(position: i)
end
end
end
diff --git a/app/models/step_text.rb b/app/models/step_text.rb
index dff232a91..728f4347b 100644
--- a/app/models/step_text.rb
+++ b/app/models/step_text.rb
@@ -2,10 +2,15 @@
class StepText < ApplicationRecord
include TinyMceImages
+ include ActionView::Helpers::TextHelper
auto_strip_attributes :text, nullify: false
validates :text, length: { maximum: Constants::RICH_TEXT_MAX_LENGTH }
belongs_to :step, inverse_of: :step_texts, touch: true
has_many :step_orderable_elements, as: :orderable, dependent: :destroy
+
+ def name
+ strip_tags(text.truncate(64))
+ end
end
diff --git a/app/serializers/step_text_serializer.rb b/app/serializers/step_text_serializer.rb
index 8d1cfdd4b..61b10723c 100644
--- a/app/serializers/step_text_serializer.rb
+++ b/app/serializers/step_text_serializer.rb
@@ -23,10 +23,6 @@ class StepTextSerializer < ActiveModel::Serializer
sanitize_input(object.tinymce_render('text'))
end
- def name
- strip_tags(object.tinymce_render('text').truncate(62, '...'))
- end
-
def icon
'fa-font'
end
diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb
index 976388b20..7e5025cd1 100644
--- a/config/initializers/extends.rb
+++ b/config/initializers/extends.rb
@@ -391,7 +391,31 @@ class Extends
task_step_file_added: 188,
task_step_file_deleted: 189,
protocol_step_file_added: 190,
- protocol_step_file_deleted: 191
+ protocol_step_file_deleted: 191,
+ task_step_text_added: 192,
+ task_step_text_edited: 193,
+ task_step_text_deleted: 194,
+ task_step_table_added: 195,
+ task_step_table_edited: 196,
+ task_step_table_deleted: 197,
+ task_step_checklist_added: 198,
+ task_step_checklist_edited: 199,
+ task_step_checklist_deleted: 200,
+ task_step_checklist_item_added: 201,
+ task_step_checklist_item_edited: 202,
+ task_step_checklist_item_deleted: 203,
+ protocol_step_text_added: 204,
+ protocol_step_text_edited: 205,
+ protocol_step_text_deleted: 206,
+ protocol_step_table_added: 207,
+ protocol_step_table_edited: 208,
+ protocol_step_table_deleted: 209,
+ protocol_step_checklist_added: 210,
+ protocol_step_checklist_edited: 211,
+ protocol_step_checklist_deleted: 212,
+ protocol_step_checklist_item_added: 213,
+ protocol_step_checklist_item_edited: 214,
+ protocol_step_checklist_item_deleted: 215
}
ACTIVITY_GROUPS = {
@@ -400,7 +424,7 @@ class Extends
task: [8, 58, 9, 59, *10..14, 35, 36, 37, 53, 54, *60..63, 138, 139, 140, 64, 66, 106, 126, 120, 132,
*146..148, 166],
task_protocol: [15, 22, 16, 18, 19, 20, 21, 17, 38, 39, 100, 111, 45, 46, 47, 121, 124, 115, 118, 127, 130, 137,
- 168, 171, 177, 184, 185, 188, 189],
+ 168, 171, 177, 184, 185, 188, 189, *192..203],
task_inventory: [55, 56, 146, 147, 183],
experiment: [*27..31, 57, 141, 165],
reports: [48, 50, 49, 163, 164],
@@ -408,7 +432,7 @@ class Extends
78, 96, 107, 113, 114, *133..136, 180, 181, 182],
protocol_repository: [80, 103, 89, 87, 79, 90, 91, 88, 85, 86, 84, 81, 82,
83, 101, 112, 123, 125, 117, 119, 129, 131, 170, 173, 179, 187, 186,
- 190, 191],
+ 190, 191, *204..215],
team: [92, 94, 93, 97, 104]
}
diff --git a/config/locales/global_activities/en.yml b/config/locales/global_activities/en.yml
index d6d873a7c..218ecbca2 100644
--- a/config/locales/global_activities/en.yml
+++ b/config/locales/global_activities/en.yml
@@ -217,6 +217,30 @@ en:
protocol_step_content_rearranged_html: "%{user} rearranged content of protocol's step %{step_position} %{step} in protocol %{protocol} in Protocol repository"
protocol_step_file_added_html: "%{user} added file %{file} to protocol's step %{step_position} %{step} in Protocol repository"
protocol_step_file_deleted_html: "%{user} deleted file %{file} in protocol's step %{step_position} %{step} in Protocol repository"
+ task_step_text_added_html: "%{user} created text %{text_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_text_edited_html: "%{user} edited text %{text_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_text_deleted_html: "%{user} deleted text %{text_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_table_added_html: "%{user} created table %{table_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_table_edited_html: "%{user} edited table %{table_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_table_deleted_html: "%{user} deleted table %{table_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_checklist_added_html: "%{user} created checklist %{checklist_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_checklist_edited_html: "%{user} edited checklist %{checklist_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_checklist_deleted_html: "%{user} deleted checklist %{checklist_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_checklist_item_added_html: "%{user} created checklist item %{checklist_item} in checklist %{checklist_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_checklist_item_edited_html: "%{user} edited checklist item %{checklist_item} in checklist %{checklist_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ task_step_checklist_item_deleted_html: "%{user} deleted checklist item %{checklist_item} in checklist %{checklist_name} in protocol's step %{step_position} %{step} on task %{my_module}"
+ protocol_step_text_added_html: "%{user} created text %{text_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ protocol_step_text_edited_html: "%{user} edited text %{text_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ protocol_step_text_deleted_html: "%{user} deleted text %{text_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ protocol_step_table_added_html: "%{user} created table %{table_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ protocol_step_table_edited_html: "%{user} edited table %{table_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ protocol_step_table_deleted_html: "%{user} deleted table %{table_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ protocol_step_checklist_added_html: "%{user} created checklist %{checklist_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ protocol_step_checklist_edited_html: "%{user} edited checklist %{checklist_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ protocol_step_checklist_deleted_html: "%{user} deleted checklist %{checklist_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ task_step_checklist_item_added_html: "%{user} created checklist item %{checklist_item} in checklist %{checklist_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ task_step_checklist_item_edited_html: "%{user} edited checklist item %{checklist_item} in checklist %{checklist_name} in protocol's step %{step_position} %{step} in Protocol repository"
+ task_step_checklist_item_deleted_html: "%{user} deleted checklist item %{checklist_item} in checklist %{checklist_name} in protocol's step %{step_position} %{step} in Protocol repository"
activity_name:
create_project: "Project created"
rename_project: "Project renamed"