Add activities for marvinJS [SCI-3630] (#1950)

* Add marvinJs activities to step and results

* Add activities for TinyMCE marvinJS assets

* Fix markup
This commit is contained in:
aignatov-bio 2019-08-09 09:47:07 +02:00 committed by GitHub
parent 4cb4373ae1
commit 6e5f078dea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 282 additions and 21 deletions

View file

@ -595,6 +595,7 @@ var FilePreviewModal = (function() {
ev.preventDefault();
ev.stopPropagation();
modal.modal('hide');
$.post(data['update-url'] + '/start_editing');
MarvinJsEditor.open({
mode: 'edit',
data: data.description,

View file

@ -90,7 +90,7 @@ var MarvinJsEditorApi = (function() {
sketchName.val(config.name);
} else if (config.mode === 'edit-tinymce') {
marvinJsRemoteLastMrv = config.data;
$.get(config.marvinUrl, { object_type: 'TinyMceAsset' }, function(result) {
$.get(config.marvinUrl, { object_type: 'TinyMceAsset', show_action: 'start_edit' }, function(result) {
marvinJsRemoteEditor.importStructure('mrv', result.description);
sketchName.val(result.name);
});
@ -109,7 +109,7 @@ var MarvinJsEditorApi = (function() {
marvin.importStructure('mrv', config.data);
sketchName.val(config.name);
} else if (config.mode === 'edit-tinymce') {
$.get(config.marvinUrl, function(result) {
$.get(config.marvinUrl, { object_type: 'TinyMceAsset', show_action: 'start_edit' }, function(result) {
marvin.importStructure('mrv', result.description);
sketchName.val(result.name);
});

View file

@ -0,0 +1,171 @@
# frozen_string_literal: true
module MarvinJsActions
extend ActiveSupport::Concern
private
def create_edit_marvinjs_activity(asset, current_user, started_editing)
action = if started_editing == :start_editing
t('activities.file_editing.started')
elsif started_editing == :finish_editing
t('activities.file_editing.finished')
end
return unless marvinjs_asset_validation(asset)
marvinjs_find_target_object(asset, current_user, 'edit', action)
end
def create_create_marvinjs_activity(asset, current_user)
return unless marvinjs_asset_validation(asset)
marvinjs_find_target_object(asset, current_user, 'create')
end
def create_delete_marvinjs_activity(asset, current_user)
return unless marvinjs_asset_validation(asset)
marvinjs_find_target_object(asset, current_user, 'delete')
end
def marvinjs_asset_validation(asset)
if asset.class == Asset
asset && asset.file.metadata[:asset_type] == 'marvinjs'
else
asset && asset.image.metadata[:asset_type] == 'marvinjs'
end
end
def marvinjs_asset_type(asset, klass)
if asset.class == Asset
return true if asset.step_asset&.step.class == klass
return true if asset.result_asset&.result.class == klass
elsif asset.object.class == klass
return true
end
false
end
def marvinjs_find_target_object(asset, current_user, activity_type, action = nil)
if marvinjs_asset_type(asset, Step)
marvinjs_step_activity(asset, current_user, activity_type, action)
elsif marvinjs_asset_type(asset, Result) || marvinjs_asset_type(asset, ResultText)
marvinjs_result_activity(asset, current_user, activity_type, action)
elsif marvinjs_asset_type(asset, MyModule)
marvinjs_my_module_activity(asset, current_user, activity_type, action)
elsif marvinjs_asset_type(asset, Protocol)
marvinjs_protocol_activity(asset, current_user, activity_type, action)
end
end
def marvinjs_step_activity(asset, current_user, activity, action = nil)
if asset.class == Asset
step = asset.step_asset&.step
asset_type = 'asset_name'
else
asset_type = 'tiny_mce_asset_name'
end
protocol = step&.protocol
return unless step && protocol
default_step_items =
{ step: step.id,
step_position: { id: step.id, value_for: 'position_plus_one' },
asset_type => { id: asset.id, value_for: 'file_name' } }
default_step_items[:action] = action if action
if protocol.in_module?
project = protocol.my_module.experiment.project
team = project.team
type_of = (activity + '_chemical_structure_on_step').to_sym
message_items = { my_module: protocol.my_module.id }
else
type_of = (activity + '_chemical_structure_on_step_in_repository').to_sym
team = protocol.team
message_items = { protocol: protocol.id }
end
message_items = default_step_items.merge(message_items)
Activities::CreateActivityService
.call(activity_type: type_of,
owner: current_user,
subject: protocol,
team: team,
project: project,
message_items: message_items)
end
def marvinjs_result_activity(asset, current_user, activity, action = nil)
if asset.class == Asset
result = asset.result_asset&.result
asset_type = 'asset_name'
else
result = asset.object&.result
asset_type = 'tiny_mce_asset_name'
end
my_module = result&.my_module
return unless result && my_module
message_items = {
result: result.id,
asset_type => { id: asset.id, value_for: 'file_name' }
}
message_items[:action] = action if action
Activities::CreateActivityService
.call(activity_type: (activity + '_chemical_structure_on_result').to_sym,
owner: current_user,
subject: result,
team: my_module.experiment.project.team,
project: my_module.experiment.project,
message_items: message_items)
end
def marvinjs_my_module_activity(asset, current_user, activity, action = nil)
my_module = asset.object
return unless my_module
message_items = {
my_module: my_module.id,
tiny_mce_asset_name: { id: asset.id, value_for: 'file_name' }
}
message_items[:action] = action if action
Activities::CreateActivityService
.call(activity_type: (activity + '_chemical_structure_on_task').to_sym,
owner: current_user,
subject: my_module,
team: my_module.experiment.project.team,
project: my_module.experiment.project,
message_items: message_items)
end
def marvinjs_protocol_activity(asset, current_user, activity, action = nil)
protocol = asset.object
return unless protocol
default_step_items =
{ tiny_mce_asset_name: { id: asset.id, value_for: 'file_name' } }
default_step_items[:action] = action if action
if protocol.in_module?
project = protocol.my_module.experiment.project
team = project.team
type_of = (activity + '_chemical_structure_on_task_protocol').to_sym
message_items = { my_module: protocol.my_module.id }
else
type_of = (activity + '_chemical_structure_on_protocol').to_sym
team = protocol.team
message_items = { protocol: protocol.id }
end
message_items = default_step_items.merge(message_items)
Activities::CreateActivityService
.call(activity_type: type_of,
owner: current_user,
subject: protocol,
team: team,
project: project,
message_items: message_items)
end
end

View file

@ -1,14 +1,19 @@
# frozen_string_literal: true
class MarvinJsAssetsController < ApplicationController
include MarvinJsActions
before_action :load_vars, except: :create
before_action :load_create_vars, only: :create
before_action :check_read_permission
before_action :check_edit_permission, only: %i(update create)
before_action :check_edit_permission, only: %i(update create start_editing)
def create
result = MarvinJsService.create_sketch(marvin_params, current_user, current_team)
create_create_marvinjs_activity(result[:asset], current_user)
if result[:asset] && marvin_params[:object_type] == 'Step'
render json: {
html: render_to_string(
@ -38,6 +43,9 @@ class MarvinJsAssetsController < ApplicationController
def update
asset = MarvinJsService.update_sketch(marvin_params, current_user, current_team)
create_edit_marvinjs_activity(asset, current_user, :finish_editing)
if asset
render json: { url: rails_representation_url(asset.medium_preview), id: asset.id, file_name: asset.file_name }
else
@ -45,6 +53,10 @@ class MarvinJsAssetsController < ApplicationController
end
end
def start_editing
create_edit_marvinjs_activity(@asset, current_user, :start_editing)
end
private
def load_vars

View file

@ -171,7 +171,7 @@ class MyModulesController < ApplicationController
if saved
if description_changed
log_activity(:change_module_description)
TinyMceAsset.update_images(@my_module, params[:tiny_mce_images])
TinyMceAsset.update_images(@my_module, params[:tiny_mce_images], current_user)
end
if due_date_changes
@ -238,7 +238,7 @@ class MyModulesController < ApplicationController
respond_to do |format|
format.json do
if @my_module.update(description: params.require(:my_module)[:description])
TinyMceAsset.update_images(@my_module, params[:tiny_mce_images])
TinyMceAsset.update_images(@my_module, params[:tiny_mce_images], current_user)
render json: {
html: custom_auto_link(
@my_module.tinymce_render(:description),
@ -260,7 +260,7 @@ class MyModulesController < ApplicationController
respond_to do |format|
format.json do
if protocol.update(description: params.require(:protocol)[:description])
TinyMceAsset.update_images(protocol, params[:tiny_mce_images])
TinyMceAsset.update_images(protocol, params[:tiny_mce_images], current_user)
render json: {
html: custom_auto_link(
protocol.tinymce_render(:description),

View file

@ -232,7 +232,7 @@ class ProtocolsController < ApplicationController
respond_to do |format|
format.json do
if @protocol.update(description: params.require(:protocol)[:description])
TinyMceAsset.update_images(@protocol, params[:tiny_mce_images])
TinyMceAsset.update_images(@protocol, params[:tiny_mce_images], current_user)
render json: {
html: custom_auto_link(
@protocol.tinymce_render(:description),
@ -266,7 +266,7 @@ class ProtocolsController < ApplicationController
log_activity(:create_protocol_in_repository, nil, protocol: @protocol.id)
TinyMceAsset.update_images(@protocol, params[:tiny_mce_images])
TinyMceAsset.update_images(@protocol, params[:tiny_mce_images], current_user)
format.json do
render json: {
url: edit_protocol_path(

View file

@ -42,7 +42,7 @@ class ResultTextsController < ApplicationController
respond_to do |format|
if @result.save && @result_text.save
# link tiny_mce_assets to the text result
TinyMceAsset.update_images(@result_text, params[:tiny_mce_images])
TinyMceAsset.update_images(@result_text, params[:tiny_mce_images], current_user)
result_annotation_notification
log_activity(:add_result)
@ -99,7 +99,7 @@ class ResultTextsController < ApplicationController
log_activity(:archive_result)
TinyMceAsset.update_images(@result_text, params[:tiny_mce_images])
TinyMceAsset.update_images(@result_text, params[:tiny_mce_images], current_user)
end
elsif @result.archived_changed?(from: true, to: false)
@ -111,7 +111,7 @@ class ResultTextsController < ApplicationController
log_activity(:edit_result)
TinyMceAsset.update_images(@result_text, params[:tiny_mce_images])
TinyMceAsset.update_images(@result_text, params[:tiny_mce_images], current_user)
end
end

View file

@ -2,6 +2,7 @@ class StepsController < ApplicationController
include ActionView::Helpers::TextHelper
include ApplicationHelper
include StepsActions
include MarvinJsActions
before_action :load_vars, only: %i(edit update destroy show toggle_step_state checklistitem_state update_view_state)
before_action :load_vars_nested, only: [:new, :create]
@ -60,6 +61,10 @@ class StepsController < ApplicationController
end
end
# link tiny_mce_assets to the step
TinyMceAsset.update_images(@step, params[:tiny_mce_images], current_user)
@step.save!
# Post process all assets
@ -168,7 +173,7 @@ class StepsController < ApplicationController
end
if @step.save
TinyMceAsset.update_images(@step, params[:tiny_mce_images])
TinyMceAsset.update_images(@step, params[:tiny_mce_images], current_user)
@step.reload
# generates notification on step upadate

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true
class TinyMceAssetsController < ApplicationController
include MarvinJsActions
before_action :load_vars, only: %i(marvinjs_show marvinjs_update download)
before_action :check_read_permission, only: %i(marvinjs_show marvinjs_update download)
@ -41,6 +43,8 @@ class TinyMceAssetsController < ApplicationController
asset = current_team.tiny_mce_assets.find_by_id(Base62.decode(params[:id]))
return render_404 unless asset
create_edit_marvinjs_activity(asset, current_user, :start_editing) if params[:show_action] == 'start_edit'
render json: {
name: asset.image.metadata[:name],
description: asset.image.metadata[:description]
@ -65,6 +69,7 @@ class TinyMceAssetsController < ApplicationController
def marvinjs_update
asset = MarvinJsService.update_sketch(marvin_params, current_user, current_team)
if asset
create_edit_marvinjs_activity(asset, current_user, :finish_editing)
render json: { url: rails_representation_url(asset.preview), id: asset.id }
else
render json: { error: t('marvinjs.no_sketches_found') }, status: :unprocessable_entity

View file

@ -214,8 +214,8 @@ module ApplicationHelper
end
def missing_avatar(user, style)
user.avatar(style) == '/images/icon_small/missing.png' ||
user.avatar(style) == '/images/thumb/missing.png'
user.avatar == '/images/icon_small/missing.png' ||
user.avatar == '/images/thumb/missing.png'
end
def wopi_enabled?

View file

@ -3,6 +3,7 @@
class TinyMceAsset < ApplicationRecord
include ActiveStorage::Downloading
extend ProtocolsExporter
extend MarvinJsActions
attr_accessor :reference
before_create :set_reference, optional: true
after_create :calculate_estimated_size, :self_destruct
@ -37,7 +38,7 @@ class TinyMceAsset < ApplicationRecord
# }
validates :estimated_size, presence: true
def self.update_images(object, images)
def self.update_images(object, images, current_user)
images = JSON.parse(images)
current_images = object.tiny_mce_assets.pluck(:id)
images_to_delete = current_images.reject do |x|
@ -48,9 +49,14 @@ class TinyMceAsset < ApplicationRecord
next if image_to_update.object || image_to_update.team_id != Team.find_by_object(object)
image_to_update&.update(object: object, saved: true)
create_create_marvinjs_activity(image_to_update, current_user)
end
where(id: images_to_delete).destroy_all
where(id: images_to_delete).each do |image_to_delete|
create_delete_marvinjs_activity(image_to_delete, current_user)
image_to_delete.destroy
end
object.delay(queue: :assets).copy_unknown_tiny_mce_images
rescue StandardError => e
Rails.logger.error e.message

View file

@ -47,6 +47,9 @@ module Activities
end
const = try_to_constantize k
k = k.to_s.sub('tiny_mce_asset', 'asset').to_sym if k.to_s.include? 'tiny_mce_asset'
if const
if v.is_a?(Hash) # Value is array, so you have getter specified
id = v[:id]

View file

@ -111,7 +111,7 @@ class Extends
}.freeze
ACTIVITY_MESSAGE_ITEMS_TYPES =
ACTIVITY_SUBJECT_TYPES + %w(User Tag RepositoryColumn RepositoryRow Step Asset)
ACTIVITY_SUBJECT_TYPES + %w(User Tag RepositoryColumn RepositoryRow Step Asset TinyMceAsset)
.freeze
ACTIVITY_TYPES = {
@ -222,18 +222,37 @@ class Extends
edit_image_on_result: 110,
edit_image_on_step: 111,
edit_image_on_step_in_repository: 112,
edit_chemical_structure_on_step: 115,
edit_chemical_structure_on_result: 116,
edit_chemical_structure_on_step_in_repository: 117,
edit_chemical_structure_on_task_protocol: 118,
edit_chemical_structure_on_protocol: 119,
edit_chemical_structure_on_task: 120,
create_chemical_structure_on_step: 121,
create_chemical_structure_on_result: 122,
create_chemical_structure_on_step_in_repository: 123,
create_chemical_structure_on_task_protocol: 124,
create_chemical_structure_on_protocol: 125,
create_chemical_structure_on_task: 126,
delete_chemical_structure_on_step: 127,
delete_chemical_structure_on_result: 128,
delete_chemical_structure_on_step_in_repository: 129,
delete_chemical_structure_on_task_protocol: 130,
delete_chemical_structure_on_protocol: 131,
delete_chemical_structure_on_task: 132
}
ACTIVITY_GROUPS = {
projects: [*0..7, 32, 33, 34, 95, 108, 65, 109],
task_results: [23, 26, 25, 42, 24, 40, 41, 99, 110],
task: [8, 58, 9, 59, 10, 11, 12, 13, 14, 35, 36, 37, 53, 54, *60..64, *66..69, 106],
task_protocol: [15, 22, 16, 18, 19, 20, 21, 17, 38, 39, 100, 111, 45, 46, 47],
task_results: [23, 26, 25, 42, 24, 40, 41, 99, 110, 122, 116, 128],
task: [8, 58, 9, 59, 10, 11, 12, 13, 14, 35, 36, 37, 53, 54, *60..64, *66..69, 106, 126, 120, 132],
task_protocol: [15, 22, 16, 18, 19, 20, 21, 17, 38, 39, 100, 111, 45, 46, 47, 121, 124, 115, 118, 127, 130],
task_inventory: [55, 56],
experiment: [*27..31, 57],
reports: [48, 50, 49],
inventories: [70, 71, 105, 72, 73, 74, 102, 75, 76, 77, 78, 96, 107],
protocol_repository: [80, 103, 89, 87, 79, 90, 91, 88, 85, 86, 84, 81, 82, 83, 101, 112],
protocol_repository: [80, 103, 89, 87, 79, 90, 91, 88, 85, 86, 84, 81, 82,
83, 101, 112, 123, 125, 117, 119, 129, 131],
team: [92, 94, 93, 97, 104]
}.freeze
end

View file

@ -134,6 +134,24 @@ en:
edit_image_on_result_html: "%{user} edited image %{asset_name} on result %{result}: %{action}."
edit_image_on_step_html: "%{user} edited image %{asset_name} on protocol's step %{step_position} %{step} on task %{my_module}: %{action}."
edit_image_on_step_in_repository_html: "%{user} edited image %{asset_name} on protocol %{protocol}'s step %{step_position} %{step} in Protocol repository: %{action}."
edit_chemical_structure_on_step_html: "%{user} edited chemical structure %{asset_name} on protocol's step %{step_position} %{step} on task %{my_module}: %{action}."
edit_chemical_structure_on_result_html: "%{user} edited chemical structure %{asset_name} on result %{result}: %{action}."
edit_chemical_structure_on_step_in_repository_html: "%{user} edited chemical structure %{asset_name} on protocol %{protocol}'s step %{step_position} %{step}: %{action}."
edit_chemical_structure_on_task_protocol_html: "%{user} edited chemical structure %{asset_name} on task's protocol %{my_module}: %{action}."
edit_chemical_structure_on_protocol_html: "%{user} edited chemical structure %{asset_name} on protocol %{protocol}: %{action}."
edit_chemical_structure_on_task_html: "%{user} edited chemical structure %{asset_name} on task %{my_module}: %{action}."
create_chemical_structure_on_step_html: "%{user} created chemical structure %{asset_name} on protocol's step %{step_position} %{step} on task %{my_module}."
create_chemical_structure_on_result_html: "%{user} created chemical structure %{asset_name} on result %{result}."
create_chemical_structure_on_step_in_repository_html: "%{user} created chemical structure %{asset_name} on protocol %{protocol}'s step %{step_position} %{step}."
create_chemical_structure_on_task_protocol_html: "%{user} created chemical structure %{asset_name} on task's protocol %{my_module}."
create_chemical_structure_on_protocol_html: "%{user} created chemical structure %{asset_name} on protocol %{protocol}."
create_chemical_structure_on_task_html: "%{user} created chemical structure %{asset_name} on task %{my_module}."
delete_chemical_structure_on_step_html: "%{user} deleted chemical structure %{asset_name} on protocol's step %{step_position} %{step} on task %{my_module}."
delete_chemical_structure_on_result_html: "%{user} deleted chemical structure %{asset_name} on result %{result}."
delete_chemical_structure_on_step_in_repository_html: "%{user} deleted chemical structure %{asset_name} on protocol %{protocol}'s step %{step_position} %{step}."
delete_chemical_structure_on_task_protocol_html: "%{user} deleted chemical structure %{asset_name} on task's protocol %{my_module}."
delete_chemical_structure_on_protocol_html: "%{user} deleted chemical structure %{asset_name} on protocol %{protocol}."
delete_chemical_structure_on_task_html: "%{user} deleted chemical structure %{asset_name} on task %{my_module}."
activity_name:
create_project: "Project created"
@ -239,6 +257,24 @@ en:
edit_image_on_result: "Image on result edited"
edit_image_on_step: "Image on task step edited"
edit_image_on_step_in_repository: "Image on step edited"
edit_chemical_structure_on_step: "Chemical structure on task step edited"
edit_chemical_structure_on_result: "Chemical structure on result edited"
edit_chemical_structure_on_step_in_repository: "Chemical structure on step edited"
edit_chemical_structure_on_task_protocol: "Chemical structure on task protocol edited"
edit_chemical_structure_on_protocol: "Chemical structure on protocol edited"
edit_chemical_structure_on_task: "Chemical structure on task edited"
create_chemical_structure_on_step: "Chemical structure on task step created"
create_chemical_structure_on_result: "Chemical structure on result created"
create_chemical_structure_on_step_in_repository: "Chemical structure on step created"
create_chemical_structure_on_task_protocol: "Chemical structure on task protocol created"
create_chemical_structure_on_protocol: "Chemical structure on protocol created"
create_chemical_structure_on_task: "Chemical structure on task created"
delete_chemical_structure_on_step: "Chemical structure on task step deleted"
delete_chemical_structure_on_result: "Chemical structure on result deleted"
delete_chemical_structure_on_step_in_repository: "Chemical structure on step deleted"
delete_chemical_structure_on_task_protocol: "Chemical structure on task protocol deleted"
delete_chemical_structure_on_protocol: "Chemical structure on protocol deleted"
delete_chemical_structure_on_task: "Chemical structure on task deleted"
activity_group:
projects: "Projects"

View file

@ -692,6 +692,9 @@ Rails.application.routes.draw do
collection do
get :team_sketches
end
member do
post :start_editing
end
end
post 'global_activities', to: 'global_activities#index'