diff --git a/app/controllers/api/v0/dmpopidor/madmp_fragments_controller.rb b/app/controllers/api/v0/dmpopidor/madmp_fragments_controller.rb new file mode 100644 index 0000000..887f254 --- /dev/null +++ b/app/controllers/api/v0/dmpopidor/madmp_fragments_controller.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true +require 'jsonpath' + +class Api::V0::Dmpopidor::MadmpFragmentsController < Api::V0::BaseController + before_action :authenticate + + def show + @fragment = MadmpFragment.find(params[:id]) + # check if the user has permissions to use the templates API + unless Api::V0::Dmpopidor::MadmpFragmentPolicy.new(@user, @fragment).show? + raise Pundit::NotAuthorizedError + end + + fragment_data = nil + if query_params[:mode] == "slim" + fragment_data = @fragment.data + else + fragment_data = @fragment.get_full_fragment + end + + fragment_data = select_property(fragment_data, query_params[:property]) + + respond_with fragment_data + end + + + private + + def select_property(fragment_data, property_name) + if property_name.present? + fragment_data = JsonPath.on(fragment_data, "$..#{property_name}") + end + fragment_data + end + + def query_params + params.permit(:mode, :property) + end +end \ No newline at end of file diff --git a/app/controllers/api/v0/dmpopidor/plans_controller.rb b/app/controllers/api/v0/dmpopidor/plans_controller.rb new file mode 100644 index 0000000..2427fc5 --- /dev/null +++ b/app/controllers/api/v0/dmpopidor/plans_controller.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +class Api::V0::Dmpopidor::PlansController < Api::V0::BaseController + before_action :authenticate + + def show + @plan = Plan.find(params[:id]) + @plan_fragment = @plan.json_fragment.dup + research_output_id = query_params[:research_output_id] ? query_params[:research_output_id].to_i : nil + # check if the user has permissions to use the API + unless Api::V0::Dmpopidor::PlanPolicy.new(@user, @plan).show? + raise Pundit::NotAuthorizedError + end + @plan_fragment = select_research_output(@plan_fragment, research_output_id) + if query_params[:mode] == "slim" + respond_with @plan_fragment.data + else + respond_with @plan_fragment.get_full_fragment + end + ends + + private + + def select_research_output(plan_fragment, research_output_id) + if research_output_id.present? + plan_fragment.data["research_outputs"] = plan_fragment.data["research_outputs"].select { |r| r == { "dbid" => research_output_id } } + end + plan_fragment + end + + def query_params + params.permit(:mode, :research_output_id) + end +end \ No newline at end of file diff --git a/app/models/fragment/meta.rb b/app/models/fragment/meta.rb index 858fada..ac08c25 100644 --- a/app/models/fragment/meta.rb +++ b/app/models/fragment/meta.rb @@ -58,4 +58,4 @@ "meta" end -end \ No newline at end of file +end diff --git a/app/models/fragment/project.rb b/app/models/fragment/project.rb index 341d930..f6759bc 100644 --- a/app/models/fragment/project.rb +++ b/app/models/fragment/project.rb @@ -54,4 +54,4 @@ "project" end -end \ No newline at end of file +end diff --git a/app/models/fragment/research_output.rb b/app/models/fragment/research_output.rb index 16b2632..428d923 100644 --- a/app/models/fragment/research_output.rb +++ b/app/models/fragment/research_output.rb @@ -86,4 +86,4 @@ "research_output" end -end \ No newline at end of file +end diff --git a/app/models/madmp_fragment.rb b/app/models/madmp_fragment.rb index d88a3af..04c3177 100644 --- a/app/models/madmp_fragment.rb +++ b/app/models/madmp_fragment.rb @@ -87,11 +87,10 @@ # ================= def plan - plan = nil - if self.answer.nil? - self.dmp.plan + if self.dmp.nil? + Plan.find(data["plan_id"]) else - plan = self.answer.plan + self.dmp.plan end end @@ -106,20 +105,21 @@ # Returns a human readable version of the structured answer def to_s - displayable = "" - if json_schema["to_string"] - json_schema["to_string"].each do |pattern| - # if it's a JsonPath pattern - if pattern.first == "$" - displayable += JsonPath.on(self.data, pattern).first - else - displayable += pattern - end - end - else - displayable = self.data.to_s - end - displayable + # displayable = "" + # if json_schema["to_string"] + # json_schema["to_string"].each do |pattern| + # # if it's a JsonPath pattern + # if pattern.first == "$" + # displayable += JsonPath.on(self.data, pattern).first + # else + # displayable += pattern + # end + # end + # else + # displayable = self.data.to_s + # end + # displayable + self.data.to_s end # This method generates references to the child fragments in the parent fragment @@ -137,17 +137,61 @@ classified_children.each do |classname, children| if children.count >= 2 # if there is more than 1 child, should pluralize the classname - parent_data[classname.pluralize(children.count)] = children.map { |c| { "dbId" => c.id } } - parent_data.delete(classname) if parent_data[classname] + parent_data = parent_data.merge( { + classname.pluralize(2) => children.map { |c| { "dbid" => c.id } } + } ) + parent_data.delete(classname) if parent_data[classname] && classname != "meta" else - parent_data[classname] = { "dbId" => children.first.id } - parent_data.delete(classname.pluralize(2)) if parent_data[classname.pluralize(2)] + parent_data = parent_data.merge( { + classname => { "dbid" => children.first.id } + } ) + parent_data.delete(classname.pluralize(2)) if parent_data[classname.pluralize(2)] && classname != "meta" end end self.parent.update(data: parent_data) end end + # This method return the fragment full record + # It integrates its children into the JSON + def get_full_fragment + children = self.children + editable_data = self.data + editable_data.each do |prop, value| + case value + when Hash + if value["dbid"].present? + child_data = children.exists?(value["dbid"]) ? children.find(value["dbid"]) : MadmpFragment.find(value["dbid"]) + editable_data = editable_data.merge( + { + prop => child_data.get_full_fragment() + } + ) + end + when Array + unless value.length == 0 + fragment_tab = Array.new + value.each do |v| + next if v.nil? + + if v.instance_of?(Hash) && v["dbid"].present? + child_data = children.exists?(v["dbid"]) ? children.find(v["dbid"]) : MadmpFragment.find(v["dbid"]) + fragment_tab.push(child_data.get_full_fragment()) + else + fragment_tab.push(v) + end + end + editable_data = editable_data.merge( + { + prop => fragment_tab + } + ) + end + end + end + editable_data + end + # Saves (and creates, if needed) the structured answer ("fragment") def self.save_madmp_fragment(answer, data, schema, parent_id = nil) # Extract the form data corresponding to the schema of the structured question @@ -195,7 +239,7 @@ schema_prop = schema_properties[prop] if !schema_prop.nil? && schema_prop['type'].eql?('object') sub_schema = MadmpSchema.find(schema_prop['schema_id']) - sub_fragment_id = previous_data[prop]['dbId'] if previous_data + sub_fragment_id = previous_data[prop]['dbid'] if previous_data if sub_fragment_id.nil? sub_fragment = MadmpFragment.new else @@ -210,7 +254,7 @@ ) sub_fragment.classname = sub_schema.classname sub_fragment.save_as_multifrag(nil) #TODO: pass the real value - data[prop] = { "dbId": sub_fragment.id } + data[prop] = { "dbid": sub_fragment_id } end end save diff --git a/app/models/research_output.rb b/app/models/research_output.rb index 2a9a137..e6af090 100644 --- a/app/models/research_output.rb +++ b/app/models/research_output.rb @@ -129,10 +129,10 @@ fragment_description.save! end else - data = fragment.description.data.merge({ + data = fragment.research_output_description.data.merge({ "title" => self.fullname }) - fragment.description.update(data: data) + fragment.research_output_description.update(data: data) end end diff --git a/app/policies/api/v0/dmpopidor/madmp_fragment_policy.rb b/app/policies/api/v0/dmpopidor/madmp_fragment_policy.rb new file mode 100644 index 0000000..e7fe1f1 --- /dev/null +++ b/app/policies/api/v0/dmpopidor/madmp_fragment_policy.rb @@ -0,0 +1,21 @@ +module Api + module V0 + module Dmpopidor + class MadmpFragmentPolicy < ApplicationPolicy + attr_reader :user + attr_reader :madmp_fragment + + def initialize(user, madmp_fragment) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + @user = user + @fragment = madmp_fragment + end + + def show? + plan = @fragment.plan + plan.readable_by?(@user.id) + end + end + end + end +end diff --git a/app/policies/api/v0/dmpopidor/plan_policy.rb b/app/policies/api/v0/dmpopidor/plan_policy.rb new file mode 100644 index 0000000..e085d05 --- /dev/null +++ b/app/policies/api/v0/dmpopidor/plan_policy.rb @@ -0,0 +1,20 @@ +module Api + module V0 + module Dmpopidor + class PlanPolicy < ApplicationPolicy + attr_reader :user + attr_reader :plan + + def initialize(user, plan) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + @user = user + @plan = plan + end + + def show? + @plan.readable_by?(@user.id) + end + end + end + end +end diff --git a/app/views/branded/phases/_edit_plan_answers.html.erb b/app/views/branded/phases/_edit_plan_answers.html.erb index 0d1b6b4..dcc7993 100644 --- a/app/views/branded/phases/_edit_plan_answers.html.erb +++ b/app/views/branded/phases/_edit_plan_answers.html.erb @@ -55,7 +55,7 @@