# frozen_string_literal: true
class MadmpFragmentsController < ApplicationController
after_action :verify_authorized
include DynamicFormHelper
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
# rubocop:disable Metrics/MethodLength
def create
p_params = permitted_params
@schemas = MadmpSchema.all
schema = @schemas.find(p_params[:schema_id])
source = p_params[:source]
classname = schema.classname
parent_id = p_params[:parent_id] unless classname.eql?("person")
@fragment = MadmpFragment.new(
dmp_id: p_params[:dmp_id],
parent_id: parent_id,
madmp_schema: schema,
additional_info: {
"property_name" => p_params[:property_name]
}
)
@fragment.classname = classname
authorize @fragment
if source.eql?("form")
@fragment.answer = Answer.create!(
research_output_id: p_params[:answer][:research_output_id],
plan_id: p_params[:answer][:plan_id],
question_id: p_params[:answer][:question_id],
lock_version: p_params[:answer][:lock_version],
is_common: p_params[:answer][:is_common],
user_id: current_user.id
)
@fragment.instantiate
else
data = data_reformater(
schema.schema,
schema_params(schema)
)
if MadmpFragment.fragment_exists?(data, schema, p_params[:dmp_id], parent_id)
render json: {
"error" => d_("dmpopidor", "Element is already present in your plan.")
}, status: 409
return
end
additional_info = @fragment.additional_info.merge(
"validations" => MadmpFragment.validate_data(data, schema.schema)
)
@fragment.assign_attributes(
additional_info: additional_info
)
@fragment.instantiate
@fragment.save_form_fragment(data, schema)
end
return unless @fragment.present?
if source.eql?("list-modal")
property_name = @fragment.additional_info["property_name"]
render json: {
"fragment_id" => @fragment.parent_id,
"source" => source,
"html" => render_fragment_list(
@fragment.dmp_id,
parent_id,
schema.id,
property_name,
p_params[:template_locale],
p_params[:query_id]
)
}.to_json
elsif source.eql?("select-modal")
render json: {
"fragment_id" => @fragment.id,
"source" => source,
"html" => render_fragment_select(@fragment)
}.to_json
else
render json: render_fragment_form(@fragment, @stale_fragment)
end
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
def load_form
@fragment = MadmpFragment.find(params[:id])
@schemas = MadmpSchema.all
authorize @fragment
return unless @fragment.present?
render json: render_fragment_form(@fragment, @stale_fragment)
end
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def update
p_params = permitted_params
@schemas = MadmpSchema.all
schema = @schemas.find(p_params[:schema_id])
source = p_params[:source]
data = data_reformater(
schema.schema,
schema_params(schema)
)
# rubocop:disable Metrics/BlockLength
Answer.transaction do
begin
@fragment = MadmpFragment.find_by(
id: params[:id],
dmp_id: p_params[:dmp_id]
)
authorize @fragment
if MadmpFragment.fragment_exists?(
data, schema, p_params[:dmp_id], @fragment.parent_id, params[:id]
)
render json: {
"error" => d_("dmpopidor", "Element is already present in your plan.")
}, status: 409
return
end
# data = @fragment.data.merge(data)
additional_info = @fragment.additional_info.merge(
"validations" => MadmpFragment.validate_data(data, schema.schema)
)
@fragment.assign_attributes(
# data: data,
additional_info: additional_info,
madmp_schema_id: schema.id
)
if p_params[:source].eql?("form") && @fragment.answer.present?
@fragment.answer.update!(
lock_version: p_params[:answer][:lock_version],
is_common: p_params[:answer][:is_common],
user_id: current_user.id
)
end
# @fragment.save!
@fragment.save_form_fragment(data, schema)
rescue ActiveRecord::StaleObjectError
@stale_fragment = @fragment
@fragment = MadmpFragment.find_by(
id: params[:id],
dmp_id: p_params[:dmp_id]
)
end
# rubocop:enable Metrics/BlockLength
end
return unless @fragment.present?
if source.eql?("list-modal")
property_name = @fragment.additional_info["property_name"]
render json: {
"fragment_id" => @fragment.parent_id,
"source" => source,
"html" => render_fragment_list(
@fragment.dmp_id,
@fragment.parent_id,
schema.id,
property_name,
p_params[:template_locale],
p_params[:query_id]
)
}.to_json
elsif source.eql?("select-modal")
render json: {
"fragment_id" => @fragment.id,
"source" => source,
"html" => render_fragment_select(@fragment)
}.to_json
else
render json: render_fragment_form(@fragment, @stale_fragment)
end
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize
def change_schema
@fragment = MadmpFragment.find(params[:id])
@schemas = MadmpSchema.all
target_schema = @schemas.find(params[:schema_id])
authorize @fragment
return unless @fragment.present? && @fragment.schema_conversion(target_schema)
render json: render_fragment_form(@fragment, @stale_fragment)
end
def new_edit_linked
@schemas = MadmpSchema.all
@schema = @schemas.find(params[:schema_id])
@parent_fragment = MadmpFragment.find(params[:parent_id])
@classname = @schema.classname
@readonly = false
@template_locale = params[:template_locale]
@source = params[:source]
@property_name = params[:property_name]
@query_id = params[:query_id]
dmp_id = @parent_fragment.classname == "dmp" ? @parent_fragment.id : @parent_fragment.dmp_id
if params[:fragment_id].present?
@fragment = MadmpFragment.find(params[:fragment_id])
else
parent_id = @parent_fragment.id unless @classname.eql?("person")
@fragment = MadmpFragment.new(
dmp_id: dmp_id,
parent_id: parent_id,
additional_info: {
"property_name" => params[:property_name]
}
)
end
authorize @fragment
respond_to do |format|
format.html
format.js { render partial: "shared/dynamic_form/linked_fragment" }
end
end
def show_linked
@fragment = MadmpFragment.find(params[:fragment_id])
@schemas = MadmpSchema.all
@schema = @fragment.madmp_schema
@classname = @fragment.classname
@parent_fragment = @fragment.parent
@readonly = true
@template_locale = params[:template_locale]
authorize @fragment
respond_to do |format|
format.html
format.js { render partial: "shared/dynamic_form/linked_fragment" }
end
end
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def create_from_registry_value
parent_fragment = MadmpFragment.find(params[:parent_id])
schema = MadmpSchema.find(params[:schema_id])
template_locale = params[:locale]
query_id = params[:query_id]
readonly = params[:readonly] == "true"
is_custom = params[:custom_value].present? ? true : false
@fragment = MadmpFragment.new(
dmp_id: parent_fragment.dmp_id,
parent_id: parent_fragment.id,
madmp_schema: schema,
data: {},
additional_info: {
"property_name" => params[:property_name]
}
)
@fragment.classname = schema.classname
authorize @fragment
if is_custom
@fragment.additional_info = @fragment.additional_info.merge("custom_value" => params[:custom_value])
@fragment.save!
else
@registry_value = RegistryValue.find(params[:registry_value_id])
if MadmpFragment.fragment_exists?(
@registry_value.data, schema, parent_fragment.dmp_id, parent_fragment.id
)
render json: {
"error" => d_("dmpopidor", "Element is already present in your plan.")
}, status: 409
return
end
@fragment.save_form_fragment(@registry_value.data, schema)
end
render json: {
"fragment_id" => parent_fragment.id,
"query_id" => query_id,
"html" => render_fragment_list(
@fragment.dmp_id,
parent_fragment.id,
@fragment.madmp_schema_id,
params[:property_name],
template_locale,
query_id,
readonly
)
}
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize
def create_contributor
parent_fragment = MadmpFragment.find(params[:parent_id])
schema = MadmpSchema.find(params[:schema_id])
template_locale = params[:locale]
query_id = params[:query_id]
person_id = params[:person_id]
@contributor = MadmpFragment.new(
dmp_id: parent_fragment.dmp_id,
parent_id: parent_fragment.id,
madmp_schema: schema,
data: {
"person" => { "dbid" => person_id.to_i },
"role" => params[:role]
},
additional_info: {
"property_name" => params[:property_name]
}
)
@contributor.classname = schema.classname
authorize @contributor
return unless @contributor.save!
render json: {
"fragment_id" => parent_fragment.id,
"query_id" => query_id,
"html" => render_fragment_list(
@contributor.dmp_id,
parent_fragment.id,
@contributor.madmp_schema_id,
params[:property_name],
template_locale,
query_id,
true
)
}
end
def destroy
@fragment = MadmpFragment.find(params[:id])
query_id = params[:query_id]
readonly = params[:readonly] == "true"
parent_id = @fragment.parent_id
dmp_id = @fragment.dmp_id
property_name = @fragment.additional_info["property_name"]
authorize @fragment
return unless @fragment.destroy
MadmpFragment.find(parent_id).update_children_references if parent_id.present?
render json: {
"fragment_id" => parent_id,
"query_id" => query_id,
"html" => render_fragment_list(
dmp_id, parent_id, @fragment.madmp_schema_id,
property_name, params[:template_locale], query_id, readonly
)
}
end
def load_fragments
@dmp_fragment = MadmpFragment.find(params[:dmp_id])
search_term = params[:term] || ""
fragment_list = MadmpFragment.where(
dmp_id: @dmp_fragment.id,
madmp_schema_id: params[:schema_id]
)
formatted_list = fragment_list.select { |f| f.to_s.downcase.include?(search_term) }
.map { |f| { "id" => f.id, "text" => f.to_s } }
authorize @dmp_fragment
render json: {
"results" => formatted_list
}
end
private
def render_fragment_list(dmp_id, parent_id, schema_id, property_name, template_locale, query_id = nil, readonly = false)
schema = MadmpSchema.find(schema_id)
case schema.classname
when "research_output"
@plan = Fragment::Dmp.where(id: dmp_id).first.plan
render_to_string(
partial: "research_outputs/list",
locals: {
plan: @plan,
research_outputs: @plan.research_outputs,
readonly: readonly
}
)
else
obj_list = MadmpFragment.where(
dmp_id: dmp_id,
parent_id: parent_id
).where("additional_info->>'property_name' = ?", property_name)
render_to_string(
partial: "shared/dynamic_form/linked_fragment/list",
locals: {
parent_id: parent_id,
obj_list: obj_list,
schema_id: schema_id,
readonly: readonly,
deletable: true,
template_locale: template_locale,
query_id: query_id
}
)
end
end
def render_fragment_select(fragment)
select_values = MadmpFragment.where(
dmp_id: fragment.dmp_id,
madmp_schema_id: fragment.madmp_schema_id
)
render_to_string(
partial: "shared/dynamic_form/linked_fragment/select_options",
locals: {
selected_value: fragment.id,
select_values: select_values
}
)
end
def render_fragment_form(fragment, stale_fragment = nil)
answer = fragment.answer
question = answer&.question
research_output = answer&.research_output
section = question&.section
plan = fragment.plan
template = plan.template
run_parameters = fragment.madmp_schema.extract_run_parameters
return {
"fragment_id" => fragment.id,
"answer" => {
"id" => answer&.id
},
"question" => {
"id" => question&.id,
"answer_lock_version" => answer&.lock_version,
"locking" => stale_fragment ?
render_to_string(partial: "madmp_fragments/locking", locals: {
question: question,
answer: answer,
fragment: stale_fragment,
research_output: research_output,
user: answer&.user
}, formats: [:html]) :
nil,
"form" => render_to_string(partial: "madmp_fragments/edit", locals: {
template: template,
question: question,
answer: answer,
fragment: fragment,
madmp_schema: fragment.madmp_schema,
research_output: research_output,
dmp_id: fragment.dmp_id,
parent_id: fragment.parent_id,
pickable_schemas: MadmpSchema.where(classname: fragment.classname).order(:label),
readonly: false,
base_template_org: template.base_org
}, formats: [:html]),
"form_run" => run_parameters.present? ?
render_to_string(partial: "shared/dynamic_form/codebase/show", locals: {
fragment: fragment,
parameters: run_parameters,
template_locale: template.locale
}, formats: [:html]) : nil,
"answer_status" => answer.present? ?
render_to_string(partial: "answers/status", locals: {
answer: answer
}, formats: [:html]) :
nil
},
"section" => {
"id" => section&.id
},
"plan" => {
"id" => plan.id,
"progress" => section.present? ?
render_to_string(partial: "plans/progress", locals: {
plan: plan,
current_phase: section.phase
}, formats: [:html]) :
nil
},
"research_output" => {
"id" => research_output&.id
}
}.to_json
end
# Get the parameters conresponding to the schema
def schema_params(schema, flat = false)
s_params = schema.generate_strong_params(flat)
params.require(:madmp_fragment).permit(s_params)
end
def permitted_params
permit_arr = [:id, :dmp_id, :parent_id, :schema_id, :source, :template_locale,
:property_name, :query_id, answer: %i[id plan_id research_output_id
question_id lock_version is_common]
]
params.require(:madmp_fragment).permit(permit_arr)
end
end