diff --git a/app/assets/javascripts/sitewide/external_protocols.js b/app/assets/javascripts/sitewide/external_protocols.js
index 79b7a625b..a93395187 100644
--- a/app/assets/javascripts/sitewide/external_protocols.js
+++ b/app/assets/javascripts/sitewide/external_protocols.js
@@ -18,8 +18,8 @@ var ExternalProtocols = (function() {
var msg;
msg = key.charAt(0).toUpperCase() + key.slice(1) + ': ' + errors.protocol[key].join(', ');
if ((input.length > 0) && (errors.protocol[key].length > 0)) {
- input.next('span.help-block').html(msg);
- input.parent().addClass('has-error');
+ input.parent().next('span.help-block').html(msg);
+ input.parent().parent().addClass('has-error');
} else if (errors.protocol[key].length > 0) {
modal.find('.general-error > span').append(msg + '
');
}
@@ -72,7 +72,7 @@ var ExternalProtocols = (function() {
}
function initLoadProtocolModalPreview() {
- var externalProtocols = $('.exteral-proocol-result');
+ var externalProtocols = $('.external-protocol-result');
externalProtocols.on('click', 'a[data-action="external-import"]', function(e) {
var link = $(this);
animateSpinner(null, true);
@@ -120,7 +120,6 @@ var ExternalProtocols = (function() {
function initFormSubmits() {
var modal = $('#protocol-preview-modal');
modal.on('click', 'button[data-action=import_protocol]', function() {
- // console.log('click');
var form = modal.find('form');
var hiddenField = form.find('#protocol_protocol_type');
hiddenField.attr('value', $(this).data('import_type'));
diff --git a/app/assets/stylesheets/protocols/preview_modal.scss b/app/assets/stylesheets/protocols/preview_modal.scss
index baa16c6a9..fadd62730 100644
--- a/app/assets/stylesheets/protocols/preview_modal.scss
+++ b/app/assets/stylesheets/protocols/preview_modal.scss
@@ -15,7 +15,7 @@
}
}
- .general-eror {
+ .general-error {
text-align: center;
}
}
diff --git a/app/controllers/external_protocols_controller.rb b/app/controllers/external_protocols_controller.rb
index 06273d70b..619d7f2f4 100644
--- a/app/controllers/external_protocols_controller.rb
+++ b/app/controllers/external_protocols_controller.rb
@@ -47,23 +47,26 @@ class ExternalProtocolsController < ApplicationController
protocol_source: new_params[:protocol_source],
protocol_client_id: new_params[:protocol_client_id],
user_id: current_user.id,
- team_id: @team.id
+ team_id: @team.id,
+ build_with_assets: false
)
- p = service_call.built_protocol
- p.valid? # Get validations errors here
- @protocol = p
if service_call.succeed?
+ @protocol = service_call.built_protocol
+ @protocol&.valid? # Get validations errors here
+
render json: {
html: render_to_string(
partial: 'protocol_importers/import_form.html.erb',
- locals: { protocol: p, steps_json: service_call.serialized_steps }
+ locals: { protocol: @protocol,
+ steps_json: service_call.serialized_steps,
+ steps_assets: service_call.steps_assets }
),
- title: "Import protocol - #{p.name}",
+ title: t('protocol_importers.new.modal_title', protocol_name: @protocol.name),
footer: render_to_string(
partial: 'protocol_importers/preview_modal_footer.html.erb'
),
- validation_errors: { protocol: p.errors.messages }
+ validation_errors: { protocol: @protocol.errors.messages }
}
else
render json: { errors: service_call.errors }, status: 400
@@ -74,7 +77,7 @@ class ExternalProtocolsController < ApplicationController
def create
service_call = ProtocolImporters::ImportProtocolService.call(
protocol_params: create_protocol_params,
- steps_params: JSON.parse(create_steps_params[:steps]),
+ steps_params_json: create_steps_params[:steps],
user_id: current_user.id,
team_id: @team.id
)
diff --git a/app/services/protocol_importers/build_protocol_from_client_service.rb b/app/services/protocol_importers/build_protocol_from_client_service.rb
index 9d083e25f..fdc863533 100644
--- a/app/services/protocol_importers/build_protocol_from_client_service.rb
+++ b/app/services/protocol_importers/build_protocol_from_client_service.rb
@@ -5,13 +5,15 @@ module ProtocolImporters
extend Service
require 'protocol_importers/protocols_io/v3/errors'
- attr_reader :errors, :built_protocol
+ attr_reader :errors, :built_protocol, :steps_assets
- def initialize(protocol_client_id:, protocol_source:, user_id:, team_id:)
+ def initialize(protocol_client_id:, protocol_source:, user_id:, team_id:, build_with_assets: true)
@id = protocol_client_id
@protocol_source = protocol_source
- @user = User.find user_id
- @team = Team.find team_id
+ @user = User.find_by_id user_id
+ @team = Team.find_by_id team_id
+ @build_with_assets = build_with_assets
+ @steps_assets = {}
@errors = {}
end
@@ -26,11 +28,12 @@ module ProtocolImporters
pio = ProtocolImporters::ProtocolIntermediateObject.new(normalized_json: normalized_hash,
user: @user,
- team: @team)
+ team: @team,
+ build_with_assets: @build_with_assets)
@built_protocol = pio.build
- # Protocol with AR errors should not handled here as someting whats wrong.
- # @errors[:protocol] = pio.protocol.errors unless @built_protocol.valid?
+ @steps_assets = pio.steps_assets unless @build_with_assets
+
self
rescue api_errors => e
@errors[e.error_type] = e.message
@@ -48,14 +51,18 @@ module ProtocolImporters
end
def serialized_steps
+ # Serialize steps with nested attributes for Tables and NOT nasted attributes for Assets
+ # We want to avoid creating (downloading) Assets instances on building first time and again on importing/creating,
+ # when both actions are not in a row.
+ # Also serialization does not work properly with paperclip attrs
return nil unless built_protocol
built_protocol.steps.map do |step|
step_hash = step.attributes.symbolize_keys.slice(:name, :description, :position)
- # if step.assets.any?
- # step_hash[:assets_attributes] = step.assets.map { |a| a.attributes.symbolize_keys.except(:id) }
- # end
+ if !@build_with_assets && @steps_assets[step.position].any?
+ step_hash[:attachments] = @steps_assets[step.position]
+ end
if step.tables.any?
step_hash[:tables_attributes] = step.tables.map { |t| t.attributes.symbolize_keys.slice(:contents) }
diff --git a/app/services/protocol_importers/import_protocol_service.rb b/app/services/protocol_importers/import_protocol_service.rb
index e34dbc9c2..8da08d908 100644
--- a/app/services/protocol_importers/import_protocol_service.rb
+++ b/app/services/protocol_importers/import_protocol_service.rb
@@ -6,11 +6,11 @@ module ProtocolImporters
attr_reader :errors, :protocol
- def initialize(protocol_params:, steps_params:, team_id:, user_id:)
- @user = User.find user_id
- @team = Team.find team_id
+ def initialize(protocol_params:, steps_params_json:, team_id:, user_id:)
+ @user = User.find_by_id user_id
+ @team = Team.find_by_id team_id
@protocol_params = protocol_params
- @steps_params = steps_params
+ @steps_params = JSON.parse(steps_params_json) # catch error here
@errors = {}
end
@@ -18,10 +18,17 @@ module ProtocolImporters
return self unless valid?
@protocol = Protocol.new(@protocol_params.merge!(added_by: @user, team: @team))
- @protocol.steps << @steps_params.collect do |step_params|
- Step.new(step_params.merge(user: @user, completed: false))
- # TODO: Manually create file here. "Accept nasted attributes won't work here"
+ @protocol.steps << @steps_params.map do |step_params|
+ # Create step with nested attributes for tables
+ s = Step.new(step_params
+ .symbolize_keys
+ .slice(:name, :position, :description, :tables_attributes)
+ .merge(user: @user, completed: false))
+
+ # 'Manually' create assets here. "Accept nasted attributes won't work assets"
+ s.assets << AttachmentsBuilder.generate(step_params.deep_symbolize_keys, user: @user, team: @team)
+ s
end
@errors[:protocol] = @protocol.errors.messages unless @protocol.save
diff --git a/app/utilities/protocol_importers/attachments_builder.rb b/app/utilities/protocol_importers/attachments_builder.rb
index 7efcb3c6a..503646e3b 100644
--- a/app/utilities/protocol_importers/attachments_builder.rb
+++ b/app/utilities/protocol_importers/attachments_builder.rb
@@ -2,16 +2,27 @@
module ProtocolImporters
module AttachmentsBuilder
- def self.generate(step_json)
+ def self.generate(step_json, user: nil, team: nil)
return [] unless step_json[:attachments]&.any?
step_json[:attachments].map do |f|
Asset.new(file: URI.parse(f[:url]),
- created_by: @user,
- last_modified_by: @user,
- team: @team,
+ created_by: user,
+ last_modified_by: user,
+ team: team,
file_file_name: f[:name])
end
end
+
+ def self.generate_json(step_json)
+ return [] unless step_json[:attachments]&.any?
+
+ step_json[:attachments].map do |f|
+ {
+ name: f[:name],
+ url: f[:url]
+ }
+ end
+ end
end
end
diff --git a/app/utilities/protocol_importers/protocol_intermediate_object.rb b/app/utilities/protocol_importers/protocol_intermediate_object.rb
index 798420cea..ecddee038 100644
--- a/app/utilities/protocol_importers/protocol_intermediate_object.rb
+++ b/app/utilities/protocol_importers/protocol_intermediate_object.rb
@@ -2,12 +2,14 @@
module ProtocolImporters
class ProtocolIntermediateObject
- attr_accessor :normalized_protocol_data, :user, :team, :protocol
+ attr_reader :normalized_protocol_data, :user, :team, :protocol, :steps_assets, :build_with_assets
- def initialize(normalized_json: {}, user:, team:)
+ def initialize(normalized_json: {}, user:, team:, build_with_assets: true)
@normalized_protocol_data = normalized_json.with_indifferent_access[:protocol] if normalized_json
@user = user
@team = team
+ @steps_assets = {}
+ @build_with_assets = build_with_assets
end
def import
@@ -28,7 +30,11 @@ module ProtocolImporters
def build_steps
@normalized_protocol_data[:steps].map do |s|
step = Step.new(step_attributes(s))
- step.assets << AttachmentsBuilder.generate(s)
+ if @build_with_assets
+ step.assets << AttachmentsBuilder.generate(s, user: user, team: team)
+ else
+ @steps_assets[step.position] = AttachmentsBuilder.generate_json(s)
+ end
step.tables << TablesBuilder.extract_tables_from_html_string(s[:description][:body], true)
step.description = StepDescriptionBuilder.generate(s)
step
diff --git a/app/views/protocol_importers/_import_form.html.erb b/app/views/protocol_importers/_import_form.html.erb
index 73157b1bb..e6b528608 100644
--- a/app/views/protocol_importers/_import_form.html.erb
+++ b/app/views/protocol_importers/_import_form.html.erb
@@ -43,7 +43,7 @@