diff --git a/app/controllers/answers_controller.rb b/app/controllers/answers_controller.rb index e16f81b..f85c4dd 100644 --- a/app/controllers/answers_controller.rb +++ b/app/controllers/answers_controller.rb @@ -4,42 +4,50 @@ ## # POST /answers - # current implimentation creates a new answer each time one is submitted - # - # Probably should rename from from create to update - # Maybe better to just update the existing answer rather than generate a new - # one. Especiall since comments connect to answers - def create - # create a new answer based off the passed params - @answer = Answer.new(params[:answer]) - authorize @answer - # find the prevous answer to this question for this plan (created_at: "DESC").first - old_answer = @answer.plan.answer(@answer.question_id, false) - proceed = false - # confused why we are passing the text through like this if we have clearly passed the answer's other attr through plainly - # We can re-name it as it's defined in app/views/plans/_answer_form.html.erb - @answer.text = params["answer-text-#{@answer.question_id}".to_sym] - if (old_answer.nil? && @answer.text != "") || ((!old_answer.nil?) && (old_answer.text != @answer.text)) then - proceed = true - end - # Is this validation necissary? - if (@answer.question.question_format.title == I18n.t("helpers.checkbox") || - @answer.question.question_format.title == I18n.t("helpers.multi_select_box") || - @answer.question.question_format.title == I18n.t("helpers.radio_buttons") || - @answer.question.question_format.title == I18n.t("helpers.dropdown")) then - if (old_answer.nil? && @answer.option_ids.count > 0) || ((!old_answer.nil?) && (old_answer.option_ids - @answer.option_ids).count != 0 && (@answer.option_ids - old_answer.option_ids).count != 0) then - proceed = true - end - end - if proceed + def update + # create a new answer based off the passed params + logger.debug("RAY: update params=") + logger.debug params.inspect + + ans_params = params[:answer] + plan_id = ans_params[:plan_id] + user_id = ans_params[:user_id] + question_id = ans_params[:question_id] + @answer = Answer.find_by( + plan_id: plan_id, + user_id: user_id, + question_id: question_id) + logger.debug "RAY: found answer=#{@answer.inspect}" + if @answer.nil? + @answer = Answer.new(params[:answer]) + logger.debug "RAY: created answer=#{@answer.inspect}" + end + + authorize @answer + + @answer.text = params["answer-text-#{@answer.question_id}".to_sym] + + #TODO: check for optimistic locking + + # Is this validation necessary? +# if (@answer.question.question_format.title == I18n.t("helpers.checkbox") || +# @answer.question.question_format.title == I18n.t("helpers.multi_select_box") || +# @answer.question.question_format.title == I18n.t("helpers.radio_buttons") || +# @answer.question.question_format.title == I18n.t("helpers.dropdown")) then +# if (old_answer.nil? && @answer.option_ids.count > 0) || ((!old_answer.nil?) && (old_answer.option_ids - @answer.option_ids).count != 0 && (@answer.option_ids - old_answer.option_ids).count != 0) then +# proceed = true +# end +# end + +# if proceed if @answer.save redirect_to :back, status: :found, notice: I18n.t('helpers.project.answer_recorded') else redirect_to :back, notice: I18n.t('helpers.project.answer_error') end - else - redirect_to :back, notice: I18n.t('helpers.project.answer_no_change') - end +# else +# redirect_to :back, notice: I18n.t('helpers.project.answer_no_change') +# end end -end \ No newline at end of file +end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 713dda5..a311c09 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -14,7 +14,7 @@ if name.blank? redirect_to edit_user_registration_path else - redirect_to projects_url + redirect_to plans_url end end end diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index 9ebd6d3..d116da0 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -5,19 +5,22 @@ ## # POST /notes def create - @note = Note.new(params[:new_note]) - @note.text = params["#{params[:new_note][:question_id]}new_note_text"] - @note.question_id = params[:new_note][:question_id] + @note = Note.new + logger.debug "RAY: into save note" @note.user_id = params[:new_note][:user_id] - @note.plan_id = params[:new_note][:plan_id] + @note.answer_id = params[:new_note][:answer_id] + @note.text = params["#{params[:new_note][:answer_id]}new_note_text"] + authorize @note - @plan = Plan.find(@note.plan_id) - @project = Project.find(@plan.project_id) + answer = Answer.find(@note.answer_id) + @plan = answer.plan + @phase = answer.question.section.phase + logger.debug "RAY: saving " + @note.inspect if @note.save - session[:question_id_notes] = @note.question_id - redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: I18n.t("helpers.comments.note_created") + session[:question_id_notes] = answer.question_id + redirect_to edit_plan_phase_path(@plan, @phase), status: :found, notice: I18n.t("helpers.comments.note_created") end end diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index 8e8c70d..a64e773 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -1,206 +1,423 @@ class PlansController < ApplicationController - #Uncomment the line below in order to add authentication to this page - users without permission will not be able to add new plans - #load_and_authorize_resource + #Uncomment the line below in order to add authentication to this page - users without permission will not be able to add new plans + #load_and_authorize_resource after_action :verify_authorized - - # GET /plans/1/edit - def edit - @plan = Plan.find(params[:id]) + TEXTAREA = QuestionFormat.where(title: "Text area").first.id + TEXTFIELD = QuestionFormat.where(title: "Text field").first.id + RADIO = QuestionFormat.where(title: "Radio buttons").first.id + CHECKBOX = QuestionFormat.where(title: "Check box").first.id + DROPDOWN = QuestionFormat.where(title: "Dropdown").first.id + MULTI = QuestionFormat.where(title: "Multi select box").first.id + + def index + authorize Plan + @plans = current_user.plans + end + + + + # GET /plans/new + def new + if user_signed_in? then + @plan = Plan.new + authorize @plan + @funders = Org.funder.all + + respond_to do |format| + format.html # new.html.erb + end + else + respond_to do |format| + format.html { redirect_to edit_user_registration_path } + end + end + end + + + def create + if user_signed_in? then + @plan = Plan.new + authorize @plan + @plan.save + + funder_id = params[:plan][:funder_id] + if !funder_id.blank? + # get all funder @templates + funder = Org.find(params[:plan][:funder_id]) + @templates = get_most_recent( funder.templates.all ) + + orgtemplates = current_user.org.templates.all + replacements = [] + + # replace any that are customised by the org + orgtemplates.each do |orgt| + base_template = orgt.customization_of + @templates.delete(base_template) + replacements << orgt + end + @templates + replacements + else + # get all org @templates which are not customisations + @templates = current_user.org.templates.where(customization_of: nil) + + # if none of these get the basic dcc template + if @templates.blank? + @templates = Template.find_by_is_default(true) + end + end + + # if we have more than one template then back to the user + # using the 'create' template + # to choose otherwise just create the plan + # and go to the plan/show template + if @templates.length > 1 + return + end + + @plan.template = @templates[0] + + @plan.principal_investigator = current_user.name + + @plan.title = I18n.t('helpers.project.my_project_name')+' ('+@plan.template.title+')' + + @plan.assign_creator(current_user.id) + + @plan.set_possible_guidance_groups + + @selected_guidance_groups = @plan.guidance_groups.map{ |pgg| [pgg.name, pgg.id, :checked => false] } + @selected_guidance_groups.sort! + + Rails.logger.debug "RAY: {# @plan.inspect }" + + respond_to do |format| + if @plan.save + #format.html { redirect_to({:action => "show", :id => @plan.slug, :show_form => "yes"}, {:notice => I18n.t('helpers.project.success')}) } + format.html { redirect_to({:action => "show", :id => @plan.id, :editing => true }, {:notice => I18n.t('helpers.project.success')}) } + else + @error = "Something went wrong" + format.html { render action: "new" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end + + + + # GET /plans/show + def show + @plan = Plan.find(params[:id]) authorize @plan + logger.debug "RAY: plan = " + @plan.inspect + @editing = params[:editing] && @plan.administerable_by?(current_user.id) + @selected_guidance_groups = [] + @selected_guidance_groups = @plan.plan_guidance_groups.map{ |pgg| [pgg.guidance_group.name, pgg.guidance_group.id, :checked => pgg.selected] } + @selected_guidance_groups.sort! + logger.debug "RAY: SGG = " + @selected_guidance_groups.inspect + + if user_signed_in? && @plan.readable_by?(current_user.id) then + respond_to do |format| + format.html # show.html.erb + end + elsif user_signed_in? then + respond_to do |format| + format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } + end + else + respond_to do |format| + format.html { redirect_to edit_user_registration_path } + end + end + end + + + + # we can go into this with the user able to edit or not able to edit + # the same edit form gets rendered but then different partials get used + # to render the answers depending on whether it is readonly or not + # + # we may or may not have a phase param. + # if we have none then we are editing/displaying the plan details + # if we have a phase then we are editing that phase. + # + # GET /plans/1/edit + def edit + @textarea = TEXTAREA + @textfield = TEXTFIELD + @radio = RADIO + @checkbox = CHECKBOX + @dropdown = DROPDOWN + @multi = MULTI + + @plan = Plan.find(params[:id]) + + @phase = nil + if params[:phase] + @phase = Phase.find(params[:phase]) + end + + authorize @plan + @readonly = @plan.editable_by?(current_user.id) if !user_signed_in? then respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - elsif !@plan.readable_by(current_user.id) then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - end - end + format.html { redirect_to edit_user_registration_path } + end + elsif !@plan.readable_by?(current_user.id) then + respond_to do |format| + format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } + end + end + end - # PUT /plans/1 - # PUT /plans/1.json - def update - @plan = Plan.find(params[:id]) + # PUT /plans/1 + # PUT /plans/1.json + def update + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.update_attributes(params[:plan]) - format.html { redirect_to @plan, notice: I18n.t('helpers.project.success_update') } - format.json { head :no_content } - else - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + if user_signed_in? && @plan.editable_by?(current_user.id) then + respond_to do |format| + if @plan.update_attributes(params[:plan]) + format.html { redirect_to @plan, :editing => false, notice: I18n.t('helpers.project.success_update') } + format.json { head :no_content } + else + format.html { render action: "edit" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end + + + + def update_guidance_choices + logger.debug "RAY: update_guidance_choices with params" + logger.debug params.inspect + + @plan = Plan.find(params[:id]) + authorize @plan + if user_signed_in? && @plan.editable_by?(current_user.id) then + guidance_ids = params[:plan][:guidances] + logger.debug "RAY: guidance ids = " + guidance_ids.inspect + @plan.plan_guidance_groups.each do |pgg| + logger.debug "RAY: looking at pgg = " + pgg.inspect + pgg.selected = guidance_ids.include?(pgg.guidance_group_id.to_s) + logger.debug "RAY: pg now = " + pgg.inspect + pgg.save! + end + @plan.save! + + respond_to do |format| + format.json { head :no_content } + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end + + + + def destroy + @plan = Plan.find(params[:id]) + authorize @plan + if user_signed_in? && @plan.editable_by?(current_user.id) then + @plan.destroy + + respond_to do |format| + format.html { redirect_to plans_url } + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end # GET /status/1.json - # only returns json, why is this here? + # only returns json, why is this here? def status - @plan = Plan.find(params[:id]) - authorize @plan - if user_signed_in? && @plan.readable_by(current_user.id) then - respond_to do |format| - format.json { render json: @plan.status } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - def section_answers - @plan = Plan.find(params[:id]) - authorize @plan - if user_signed_in? && @plan.readable_by(current_user.id) then - respond_to do |format| - format.json { render json: @plan.section_answers(params[:section_id]) } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - def locked - @plan = Plan.find(params[:id]) - authorize @plan - if !@plan.nil? && user_signed_in? && @plan.readable_by(current_user.id) then - respond_to do |format| - format.json { render json: @plan.locked(params[:section_id],current_user.id) } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end - - def delete_recent_locks - @plan = Plan.find(params[:id]) + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.delete_recent_locks(current_user.id) - format.html { render action: "edit" } - else - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + if user_signed_in? && @plan.readable_by(current_user.id) then + respond_to do |format| + format.json { render json: @plan.status } + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - def unlock_all_sections - @plan = Plan.find(params[:id]) + def section_answers + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.unlock_all_sections(current_user.id) - format.html { render action: "edit" } - else - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + if user_signed_in? && @plan.readable_by(current_user.id) then + respond_to do |format| + format.json { render json: @plan.section_answers(params[:section_id]) } + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - def lock_section - @plan = Plan.find(params[:id]) + def locked + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.lock_section(params[:section_id], current_user.id) - format.html { render action: "edit" } - else - format.html { render action: "edit" } - format.json { render json: @plan.errors, status: :unprocessable_entity } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + if !@plan.nil? && user_signed_in? && @plan.readable_by(current_user.id) then + respond_to do |format| + format.json { render json: @plan.locked(params[:section_id],current_user.id) } + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - def unlock_section - @plan = Plan.find(params[:id]) + def delete_recent_locks + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.editable_by(current_user.id) then - respond_to do |format| - if @plan.unlock_section(params[:section_id], current_user.id) - format.html { render action: "edit" } + if user_signed_in? && @plan.editable_by(current_user.id) then + respond_to do |format| + if @plan.delete_recent_locks(current_user.id) + format.html { render action: "edit" } + else + format.html { render action: "edit" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - else - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + def unlock_all_sections + @plan = Plan.find(params[:id]) + authorize @plan + if user_signed_in? && @plan.editable_by(current_user.id) then + respond_to do |format| + if @plan.unlock_all_sections(current_user.id) + format.html { render action: "edit" } + else + format.html { render action: "edit" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - def answer - @plan = Plan.find(params[:id]) - authorize @plan - if user_signed_in? && @plan.readable_by(current_user.id) then - respond_to do |format| - format.json { render json: @plan.answer(params[:q_id], false).to_json(:include => :options) } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + def lock_section + @plan = Plan.find(params[:id]) + authorize @plan + if user_signed_in? && @plan.editable_by(current_user.id) then + respond_to do |format| + if @plan.lock_section(params[:section_id], current_user.id) + format.html { render action: "edit" } + else + format.html { render action: "edit" } + format.json { render json: @plan.errors, status: :unprocessable_entity } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - def export - @plan = Plan.find(params[:id]) + def unlock_section + @plan = Plan.find(params[:id]) + authorize @plan + if user_signed_in? && @plan.editable_by(current_user.id) then + respond_to do |format| + if @plan.unlock_section(params[:section_id], current_user.id) + format.html { render action: "edit" } + + else + format.html { render action: "edit" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end + + def answer + @plan = Plan.find(params[:id]) + authorize @plan + if user_signed_in? && @plan.readable_by(current_user.id) then + respond_to do |format| + format.json { render json: @plan.answer(params[:q_id], false).to_json(:include => :options) } + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end + + def export + @plan = Plan.find(params[:id]) authorize @plan - if user_signed_in? && @plan.readable_by(current_user.id) then - @exported_plan = ExportedPlan.new.tap do |ep| - ep.plan = @plan - ep.user = current_user - #ep.format = request.format.try(:symbol) + if user_signed_in? && @plan.readable_by(current_user.id) then + @exported_plan = ExportedPlan.new.tap do |ep| + ep.plan = @plan + ep.user = current_user + #ep.format = request.format.try(:symbol) ep.format = request.format.to_sym - plan_settings = @plan.settings(:export) + plan_settings = @plan.settings(:export) - Settings::Dmptemplate::DEFAULT_SETTINGS.each do |key, value| - ep.settings(:export).send("#{key}=", plan_settings.send(key)) - end - end + Settings::Dmptemplate::DEFAULT_SETTINGS.each do |key, value| + ep.settings(:export).send("#{key}=", plan_settings.send(key)) + end + end - @exported_plan.save! # FIXME: handle invalid request types without erroring? - file_name = @exported_plan.project_name + @exported_plan.save! # FIXME: handle invalid request types without erroring? + file_name = @exported_plan.project_name - respond_to do |format| - format.html - format.xml - format.json - format.csv { send_data @exported_plan.as_csv, filename: "#{file_name}.csv" } - format.text { send_data @exported_plan.as_txt, filename: "#{file_name}.txt" } - format.docx { headers["Content-Disposition"] = "attachment; filename=\"#{file_name}.docx\""} - format.pdf do - @formatting = @plan.settings(:export).formatting - render pdf: file_name, - margin: @formatting[:margin], - footer: { - center: t('helpers.plan.export.pdf.generated_by'), - font_size: 8, - spacing: (@formatting[:margin][:bottom] / 2) - 4, - right: '[page] of [topage]' - } - end - end - elsif !user_signed_in? then - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - elsif !@plan.editable_by(current_user.id) then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - end - end + respond_to do |format| + format.html + format.xml + format.json + format.csv { send_data @exported_plan.as_csv, filename: "#{file_name}.csv" } + format.text { send_data @exported_plan.as_txt, filename: "#{file_name}.txt" } + format.docx { headers["Content-Disposition"] = "attachment; filename=\"#{file_name}.docx\""} + format.pdf do + @formatting = @plan.settings(:export).formatting + render pdf: file_name, + margin: @formatting[:margin], + footer: { + center: t('helpers.plan.export.pdf.generated_by'), + font_size: 8, + spacing: (@formatting[:margin][:bottom] / 2) - 4, + right: '[page] of [topage]' + } + end + end + elsif !user_signed_in? then + respond_to do |format| + format.html { redirect_to edit_user_registration_path } + end + elsif !@plan.editable_by(current_user.id) then + respond_to do |format| + format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } + end + end + end + + + + private + + + def get_most_recent( templates ) + groups = Hash.new + templates.each do |t| + k = t.dmptemplate_id + if !groups.has_key?(k) + groups[k] =t + else + other = groups[k] + if other.version < t.version + groups[k] = t + end + end + end + groups.values + end + end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index ba7b816..4e6d8e9 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -1,309 +1,288 @@ class ProjectsController < ApplicationController - before_filter :get_plan_list_columns, only: %i( index ) + before_filter :get_plan_list_columns, only: %i( index ) after_action :verify_authorized - # GET /projects - # GET /projects.json - def index + # GET /projects + # GET /projects.json + def index authorize Project ## TODO: Is this A magic String? the "Show_shib_link?" as we define it and users dont see cookies - if user_signed_in? then - if (current_user.shibboleth_id.nil? || current_user.shibboleth_id.length == 0) && !cookies[:show_shib_link].nil? && cookies[:show_shib_link] == "show_shib_link" then - flash.notice = "Would you like to #{view_context.link_to I18n.t('helpers.shibboleth_to_link_text'), user_omniauth_shibboleth_path}".html_safe - end + if user_signed_in? then + if (current_user.shibboleth_id.nil? || current_user.shibboleth_id.length == 0) && !cookies[:show_shib_link].nil? && cookies[:show_shib_link] == "show_shib_link" then + flash.notice = "Would you like to #{view_context.link_to I18n.t('helpers.shibboleth_to_link_text'), user_omniauth_shibboleth_path}".html_safe + end - @projects = current_user.projects.filter(params[:filter]) - @has_projects = current_user.projects.any? # unfiltered count + @projects = current_user.projects.filter(params[:filter]) + @has_projects = current_user.projects.any? # unfiltered count - respond_to do |format| - format.html # index.html.erb - end - else - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - end - end + respond_to do |format| + format.html # index.html.erb + end + else + respond_to do |format| + format.html { redirect_to edit_user_registration_path } + end + end + end - # GET /projects/1 - # GET /projects/1.json - def show - @project = Project.find(params[:id]) + # GET /projects/1 + # GET /projects/1.json + def show + @project = Project.find(params[:id]) authorize @project - @show_form = false - if params[:show_form] == "yes" then - @show_form = true - end - if user_signed_in? && @project.readable_by(current_user.id) then - respond_to do |format| - format.html # show.html.erb - end - elsif user_signed_in? then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - else - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - end - end + @show_form = false + if params[:show_form] == "yes" then + @show_form = true + end + if user_signed_in? && @project.readable_by(current_user.id) then + respond_to do |format| + format.html # show.html.erb + end + elsif user_signed_in? then + respond_to do |format| + format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } + end + else + respond_to do |format| + format.html { redirect_to edit_user_registration_path } + end + end + end - # GET /projects/new - # GET /projects/new.json - def new - if user_signed_in? then - @project = Project.new - authorize @project - @project.organisation = current_user.organisation - @funders = orgs_of_type(constant("organisation_types.funder"), true) - @templates = get_available_templates - @guidance_groups = get_available_guidance - @always_guidance = get_always_available_guidance - @institutions = orgs_of_type(constant("organisation_types.institution")) - - respond_to do |format| - format.html # new.html.erb - end - else - respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - end - end - - # GET /projects/1/edit + + # GET /projects/1/edit # Should this be removed? - def edit - @project = Project.find(params[:id]) + def edit + @project = Project.find(params[:id]) authorize @project - if !user_signed_in? then + if !user_signed_in? then respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - elsif !@project.editable_by(current_user.id) then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - end - end + format.html { redirect_to edit_user_registration_path } + end + elsif !@project.editable_by(current_user.id) then + respond_to do |format| + format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } + end + end + end - def share - @project = Project.find(params[:id]) + def share + @project = Project.find(params[:id]) authorize @project - if !user_signed_in? then + if !user_signed_in? then respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - elsif !@project.editable_by(current_user.id) then - respond_to do |format| - format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } - end - end - end + format.html { redirect_to edit_user_registration_path } + end + elsif !@project.editable_by(current_user.id) then + respond_to do |format| + format.html { redirect_to projects_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } + end + end + end - def export - @project = Project.find(params[:id]) + def export + @project = Project.find(params[:id]) authorize @project - if !user_signed_in? then + if !user_signed_in? then respond_to do |format| - format.html { redirect_to edit_user_registration_path } - end - else - respond_to do |format| - format.html { render action: "export" } + format.html { redirect_to edit_user_registration_path } + end + else + respond_to do |format| + format.html { render action: "export" } - end - end - end + end + end + end - # POST /projects - # POST /projects.json - def create - if user_signed_in? then - @project = Project.new(params[:project]) + # POST /projects + def create + puts params + return + if user_signed_in? then + @plan = Plan.new(params[:plan]) authorize @project - if @project.dmptemplate.nil? && params[:project][:funder_id] != "" then # this shouldn't be necessary - see setter for funder_id in project.rb - funder = Org.find(params[:project][:funder_id]) - if funder.dmptemplates.count == 1 then - @project.dmptemplate = funder.published_templates.first - end - elsif @project.dmptemplate.nil? || params[:default_tag] == 'true' then - if @project.organisation.nil? || params[:default_tag] == 'true' || @project.organisation.published_templates.first.nil? then - @project.dmptemplate = Dmptemplate.find_by_is_default(true) - else - @project.dmptemplate = @project.organisation.published_templates.first - end - end - @project.principal_investigator = current_user.name(false) + if @project.dmptemplate.nil? && params[:project][:funder_id] != "" then # this shouldn't be necessary - see setter for funder_id in project.rb + funder = Org.find(params[:project][:funder_id]) + if funder.dmptemplates.count == 1 then + @project.dmptemplate = funder.published_templates.first + end + elsif @project.dmptemplate.nil? || params[:default_tag] == 'true' then + if @project.organisation.nil? || params[:default_tag] == 'true' || @project.organisation.published_templates.first.nil? then + @project.dmptemplate = Dmptemplate.find_by_is_default(true) + else + @project.dmptemplate = @project.organisation.published_templates.first + end + end + @project.principal_investigator = current_user.name(false) - @project.title = I18n.t('helpers.project.my_project_name')+' ('+@project.dmptemplate.title+')' - @project.assign_creator(current_user.id) - respond_to do |format| - if @project.save - format.html { redirect_to({:action => "show", :id => @project.slug, :show_form => "yes"}, {:notice => I18n.t('helpers.project.success')}) } - else - format.html { render action: "new" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + @project.title = I18n.t('helpers.project.my_project_name')+' ('+@project.dmptemplate.title+')' + @project.assign_creator(current_user.id) + respond_to do |format| + if @project.save + format.html { redirect_to({:action => "show", :id => @project.slug, :show_form => "yes"}, {:notice => I18n.t('helpers.project.success')}) } + else + format.html { render action: "new" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - # PUT /projects/1 - # PUT /projects/1.json - def update - @project = Project.find(params[:id]) + # PUT /projects/1 + # PUT /projects/1.json + def update + @project = Project.find(params[:id]) authorize @project - if user_signed_in? && @project.editable_by(current_user.id) then + if user_signed_in? && @project.editable_by(current_user.id) then if @project.update_attributes(params[:project]) respond_to do |format| - format.html { redirect_to({:action => "show", :id => @project.slug, notice: I18n.t('helpers.project.success_update') }) } + format.html { redirect_to({:action => "show", :id => @project.slug, notice: I18n.t('helpers.project.success_update') }) } end else respond_to do |format| - format.html { render action: "edit" } - end - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + format.html { render action: "edit" } + end + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end - # DELETE /projects/1 - # DELETE /projects/1.json - def destroy - @project = Project.find(params[:id]) + # DELETE /projects/1 + # DELETE /projects/1.json + def destroy + @project = Project.find(params[:id]) authorize @project - if user_signed_in? && @project.editable_by(current_user.id) then - @project.destroy + if user_signed_in? && @project.editable_by(current_user.id) then + @project.destroy - respond_to do |format| - format.html { redirect_to projects_url } - end - else - render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) - end - end + respond_to do |format| + format.html { redirect_to projects_url } + end + else + render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) + end + end # returns to AJAX call from frontend # difficult to secure as it passes through params, and dosent curate data based # on what the user can "view" or is public - # GET /projects/possible_templates.json - def possible_templates - if !params[:funder].nil? && params[:funder] != "" && params[:funder] != "undefined" then - funder = Org.find(params[:funder]) - else - funder = nil - end - if !params[:institution].nil? && params[:institution] != "" && params[:institution] != "undefined" then - institution = Org.find(params[:institution]) - else - institution = nil - end - templates = {} - unless funder.nil? then - funder.published_templates.each do |t| - templates[t.id] = t.title - end - end - if templates.count == 0 && !institution.nil? then - institution.published_templates.each do |t| - templates[t.id] = t.title - end - institution.children.each do |o| - o.published_templates.each do |t| - templates[t.id] = t.title - end - end - end - respond_to do |format| - format.json { render json: templates.to_json } - end - end + # GET /projects/possible_templates.json + def possible_templates + if !params[:funder].nil? && params[:funder] != "" && params[:funder] != "undefined" then + funder = Org.find(params[:funder]) + else + funder = nil + end + if !params[:institution].nil? && params[:institution] != "" && params[:institution] != "undefined" then + institution = Org.find(params[:institution]) + else + institution = nil + end + templates = {} + unless funder.nil? then + funder.published_templates.each do |t| + templates[t.id] = t.title + end + end + if templates.count == 0 && !institution.nil? then + institution.published_templates.each do |t| + templates[t.id] = t.title + end + institution.children.each do |o| + o.published_templates.each do |t| + templates[t.id] = t.title + end + end + end + respond_to do |format| + format.json { render json: templates.to_json } + end + end # returns to AJAX call from frontend - # difficult to secure as it passes through params, and dosent curate data based + # difficult to secure as it passes through params, and dosent curate data based # on what the user can "view" or is public def possible_guidance authorize @project - if !params[:template].nil? && params[:template] != "" && params[:template] != "undefined" then - template = Dmptemplate.find(params[:template]) - else - template = nil - end - if !params[:institution].nil? && params[:institution] != "" && params[:institution] != "undefined" then - institution = Org.find(params[:institution]) - else - institution = nil - end - excluded_orgs = orgs_of_type(constant("organisation_types.funder")) + orgs_of_type(constant("organisation_types.institution")) + Org.orgs_with_parent_of_type(constant("organisation_types.institution")) - guidance_groups = {} - ggs = GuidanceGroup.guidance_groups_excluding(excluded_orgs) + if !params[:template].nil? && params[:template] != "" && params[:template] != "undefined" then + template = Dmptemplate.find(params[:template]) + else + template = nil + end + if !params[:institution].nil? && params[:institution] != "" && params[:institution] != "undefined" then + institution = Org.find(params[:institution]) + else + institution = nil + end + excluded_orgs = orgs_of_type(constant("organisation_types.funder")) + orgs_of_type(constant("organisation_types.institution")) + Org.orgs_with_parent_of_type(constant("organisation_types.institution")) + guidance_groups = {} + ggs = GuidanceGroup.guidance_groups_excluding(excluded_orgs) - ggs.each do |gg| - guidance_groups[gg.id] = gg.name - end + ggs.each do |gg| + guidance_groups[gg.id] = gg.name + end #subset guidance that belong to the institution - unless institution.nil? then + unless institution.nil? then authorize Project - optional_gg = GuidanceGroup.where("optional_subset = ? AND organisation_id = ?", true, institution.id) - optional_gg.each do|optional| - guidance_groups[optional.id] = optional.name - end + optional_gg = GuidanceGroup.where("optional_subset = ? AND organisation_id = ?", true, institution.id) + optional_gg.each do|optional| + guidance_groups[optional.id] = optional.name + end - institution.children.each do |o| - o.guidance_groups.each do |gg| - include = false - gg.guidances.each do |g| - if g.dmptemplate.nil? || g.dmptemplate_id == template.id then - include = true - break - end - end - if include then - guidance_groups[gg.id] = gg.name - end - end - end - end + institution.children.each do |o| + o.guidance_groups.each do |gg| + include = false + gg.guidances.each do |g| + if g.dmptemplate.nil? || g.dmptemplate_id == template.id then + include = true + break + end + end + if include then + guidance_groups[gg.id] = gg.name + end + end + end + end #If template belongs to a funder and that funder has subset guidance display then. if !template.nil? && template.organisation.organisation_type.name == constant("organisation_types.funder") then optional_gg = GuidanceGroup.where("optional_subset = ? AND organisation_id = ?", true, template.organisation_id) - optional_gg.each do|optional| - guidance_groups[optional.id] = optional.name - end + optional_gg.each do|optional| + guidance_groups[optional.id] = optional.name + end end - respond_to do |format| - format.json { render json: guidance_groups.to_json } - end - end + respond_to do |format| + format.json { render json: guidance_groups.to_json } + end + end - private - def orgs_of_type(org_type_name, published_templates = false) - org_type = OrganisationType.find_by_name(org_type_name) - all_such_orgs = org_type.organisations - if published_templates then - with_published = Array.new - all_such_orgs.each do |o| - if o.published_templates.count > 0 then - with_published << o - end - end - return with_published.sort_by {|o| [o.sort_name, o.name] } - else - return all_such_orgs.sort_by {|o| [o.sort_name, o.name] } - end - end + private + def orgs_of_type(org_type_name, published_templates = false) + org_type = OrganisationType.find_by_name(org_type_name) + all_such_orgs = org_type.organisations + if published_templates then + with_published = Array.new + all_such_orgs.each do |o| + if o.published_templates.count > 0 then + with_published << o + end + end + return with_published.sort_by {|o| [o.sort_name, o.name] } + else + return all_such_orgs.sort_by {|o| [o.sort_name, o.name] } + end + end # ----------------------------------------------------------- def get_available_templates - Dmptemplate.where(published: true) + Template.find_by(published: true) end # ----------------------------------------------------------- @@ -315,7 +294,7 @@ # ----------------------------------------------------------- def get_always_available_guidance # Exclude Funders, Institutions, or children of Institutions - excluded_orgs = orgs_of_type(constant("organisation_types.funder")) + + excluded_orgs = orgs_of_type(constant("organisation_types.funder")) + orgs_of_type(constant("organisation_types.institution")) + Org.orgs_with_parent_of_type(constant("organisation_types.institution")) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 4679053..4b326c1 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -60,7 +60,7 @@ # -------------------------------------------------------- def plan_settings_indicator(plan) plan_settings = plan.super_settings(:export) - template_settings = plan.project.dmptemplate.try(:settings, :export) + template_settings = plan.template.try(:settings, :export) key = if plan_settings.try(:value?) plan_settings.formatting == template_settings.formatting ? "template_formatting" : "custom_formatting" diff --git a/app/models/answer.rb b/app/models/answer.rb index 131b67b..02a1533 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -4,6 +4,7 @@ belongs_to :question belongs_to :user belongs_to :plan + has_many :notes, dependent: :destroy has_and_belongs_to_many :question_options, join_table: "answers_question_options" ## diff --git a/app/models/exported_plan.rb b/app/models/exported_plan.rb index 2ea784b..589f096 100644 --- a/app/models/exported_plan.rb +++ b/app/models/exported_plan.rb @@ -14,8 +14,8 @@ # Store settings with the exported plan so it can be recreated later # if necessary (otherwise the settings associated with the plan at a # given time can be lost) - has_settings :export, class_name: 'Settings::Dmptemplate' do |s| - s.key :export, defaults: Settings::Dmptemplate::DEFAULT_SETTINGS + has_settings :export, class_name: 'Settings::Template' do |s| + s.key :export, defaults: Settings::Template::DEFAULT_SETTINGS end # Getters to match Settings::Dmptemplate::VALID_ADMIN_FIELDS diff --git a/app/models/guidance_group.rb b/app/models/guidance_group.rb index b7a2ad0..e56b1cc 100644 --- a/app/models/guidance_group.rb +++ b/app/models/guidance_group.rb @@ -41,10 +41,10 @@ # # @return [String] the display name for the guidance group def display_name - if organisation.guidance_groups.count > 1 - return "#{organisation.name}: #{name}" + if org.guidance_groups.count > 1 + return "#{org.name}: #{name}" else - return organisation.name + return org.name end end diff --git a/app/models/note.rb b/app/models/note.rb index cc2f472..d314d19 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -8,4 +8,5 @@ # Possibly needed for active_admin # -relies on protected_attributes gem as syntax depricated in rails 4.2 attr_accessible :question_id, :text, :user_id, :archived, :plan_id, :archived_by, :as => [:default, :admin] + end diff --git a/app/models/plan.rb b/app/models/plan.rb index 4a76116..ca035d5 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -5,15 +5,21 @@ has_many :phases, through: :template has_many :sections, through: :phases has_many :questions, through: :sections - has_many :answers + has_many :answers, dependent: :destroy has_many :notes, through: :answers + has_many :roles, dependent: :destroy has_many :users, through: :roles + has_many :plan_guidance_groups, dependent: :destroy + has_many :guidance_groups, through: :plan_guidance_groups + + accepts_nested_attributes_for :template ## # Possibly needed for active_admin # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :locked, :project_id, :version_id, :version, :plan_sections, :as => [:default, :admin] - + attr_accessible :title, :identifier, :grant_number, + :principal_investigator, :principal_investigator_identifier, + :data_contact, :description ## # Constants A4_PAGE_HEIGHT = 297 #(in mm) @@ -31,16 +37,21 @@ + def new + if user_signed_in? then + @plan = Plan.new + authorize @plan + @funders = Org.funder.all - - - - # EVALUATE CLASS AND INSTANCE METHODS BELOW - # - # What do they do? do they do it efficiently, and do we need them? - # Special note, these are both the methods in the old plan, and in the old project - - + respond_to do |format| + format.html # new.html.erb + end + else + respond_to do |format| + format.html { redirect_to edit_user_registration_path } + end + end + end @@ -66,25 +77,29 @@ # # @return [Dmptemplate] the template associated with this plan def dmptemplate - self.project.try(:dmptemplate) || Dmptemplate.new + #self.project.try(:dmptemplate) || Dmptemplate.new + self.template end - ## - # returns the title for this project as defined by the settings - # - # @return [String] the title for this project - def title - logger.debug "Title in settings: #{self.settings(:export).title}" - if self.settings(:export).title == "" - if !self.version.nil? && !self.version.phase.nil? && !self.version.phase.title? then - return self.version.phase.title - else - return I18n.t('tool_title2') - end - else - return self.settings(:export).title - end - end +# DON'T THINK WE NEED THIS ANYMORE - DELETE IF YOU ARE READING THIS +# AND IT'S WORKING +# +# ## +# # returns the title for this project as defined by the settings +# # +# # @return [String] the title for this project +# def title +# logger.debug "Title in settings: #{self.settings(:export).title}" +# if self.settings(:export).title == "" +# if !self.version.nil? && !self.version.phase.nil? && !self.version.phase.title? then +# return self.version.phase.title +# else +# return I18n.t('tool_title2') +# end +# else +# return self.settings(:export).title +# end +# end ## # returns the most recent answer to the given question id @@ -102,12 +117,12 @@ answer.question_id = qid answer.text = question.default_value default_options = Array.new - question.options.each do |option| + question.question_options.each do |option| if option.is_default default_options << option end end - answer.options = default_options + answer.question_options = default_options end return answer end @@ -116,55 +131,85 @@ # returns all of the sections for this version of the plan, and for the project's organisation # # @return [Array
,nil] either a list of sections, or nil if none were found - def sections - unless project.organisation.nil? then - sections = version.global_sections + project.organisation.all_sections(version_id) - else - sections = version.global_sections - end - return sections.uniq.sort_by &:number - end +# def sections +# unless plan.organisation.nil? then +# sections = version.global_sections + project.organisation.all_sections(version_id) +# else +# sections = version.global_sections +# end +# return sections.uniq.sort_by &:number +# end + + + def set_possible_guidance_groups + # find all the themes in this plan + # and get the guidance groups they belong to + logger.debug "RAY: set_possible_guidance_groups" + ggroups = [] + self.template.phases.each do |phase| + phase.sections.each do |section| + section.questions.each do |question| + question.themes.each do |theme| + theme.guidances.each do |guidance| + ggroups << guidance.guidance_group + end + end + end + end + end + + self.guidance_groups = ggroups.uniq + end + + + ## # returns the guidances associated with the project's organisation, for a specified question # # @param question [Question] the question to find guidance for - # @return [Array] the list of guidances which pretain to the specified question - def guidance_for_question(question) - guidances = {} - # If project org isn't nil, get guidance by theme from any "non-subset" groups belonging to project org - unless project.organisation.nil? then - project.organisation.guidance_groups.each do |group| - if !group.optional_subset && (group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0) then - group.guidances.each do |guidance| - guidance.themes.where("id IN (?)", question.theme_ids).each do |theme| - guidances = self.add_guidance_to_array(guidances, group, theme, guidance) - end - end - end - end - end - # Get guidance by theme from any guidance groups selected on creation - project.guidance_groups.each do |group| - if group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0 then - group.guidances.each do |guidance| - guidance.themes.where("id IN (?)", question.theme_ids).each do |theme| - guidances = self.add_guidance_to_array(guidances, group, theme, guidance) - end - end - end - end - # Get guidance by question where guidance group was selected on creation or if group is organisation default - question.guidances.each do |guidance| - guidance.guidance_groups.each do |group| - if (group.organisation == project.organisation && !group.optional_subset) || project.guidance_groups.include?(group) then - guidances = self.add_guidance_to_array(guidances, group, nil, guidance) - end + # @return array of hashes with orgname, themes and the guidance itself + def guidance_for_question(question) + guidances = [] + logger.debug "RAY: guidance_for_question" + + # add in the guidance for the template org + unless self.template.org.nil? then + self.template.org.guidance_groups.each do |group| + group.guidances.each do |guidance| + common_themes = guidance.themes.all & question.themes.all + if common_themes.length > 0 + guidances << { orgname: self.template.org.name, theme: common_themes.join(','), guidance: guidance } + end + end end - end - - return guidances - end + end + + # add in the guidance for the user's org + unless self.owner.org.nil? then + self.owner.org.guidance_groups.each do |group| + group.guidances.each do |guidance| + common_themes = guidance.themes.all & question.themes.all + if common_themes.length > 0 + guidances << { orgname: self.template.org.name, theme: common_themes.join(','), guidance: guidance } + end + end + end + end + + # Get guidance by theme from any guidance groups currently selected + self.plan_guidance_groups.where(selected: true).each do |pgg| + group = pgg.guidance_group + group.guidances.each do |guidance| + common_themes = guidance.themes.all & question.themes.all + if common_themes.length > 0 + guidances << { orgname: self.template.org.name, theme: common_themes.join(','), guidance: guidance } + end + end + end + + return guidances + end ## # adds the given guidance to a hash indexed by a passed guidance group and theme @@ -198,36 +243,32 @@ ## # determines if the plan is editable by the specified user - # NOTE: This should be renamed to editable_by? # # @param user_id [Integer] the id for a user # @return [Boolean] true if user can edit the plan - def editable_by(user_id) - return project.editable_by(user_id) + def editable_by?(user_id) + role = roles.where(user_id: user_id).first + return role.present? && role.editor? end ## # determines if the plan is readable by the specified user - # NOTE: This shoudl be renamed to readable_by? # # @param user_id [Integer] the id for a user # @return [Boolean] true if the user can read the plan - def readable_by(user_id) - if project.nil? - return false - else - return project.readable_by(user_id) - end + def readable_by?(user_id) + role = roles.where(user_id: user_id).first + return role.present? && role.editor? end ## # determines if the plan is administerable by the specified user - # NOTE: This should be renamed to administerable_by? # # @param user_id [Integer] the id for the user # @return [Boolean] true if the user can administer the plan - def administerable_by(user_id) - return project.readable_by(user_id) + def administerable_by?(user_id) + role = roles.where(user_id: user_id).first + return role.present? && role.administrator? end @@ -247,7 +288,7 @@ "space_used" => 0 # percentage of available space in pdf used } - space_used = height_of_text(self.project.title, 2, 2) + space_used = height_of_text(self.title, 2, 2) sections.each do |s| space_used += height_of_text(s.title, 1, 1) @@ -270,7 +311,7 @@ "answer_id" => answer.id, "answer_created_at" => answer.created_at.to_i, "answer_text" => answer.text, - "answer_option_ids" => answer.option_ids, + "answer_option_ids" => answer.question_options.pluck(:id), "answered_by" => answer.user.name } q_format = q.question_format @@ -478,66 +519,18 @@ return section_questions end -private + ## - # Based on the height of the text gathered so far and the available vertical - # space of the pdf, estimate a percentage of how much space has been used. - # This is highly dependent on the layout in the pdf. A more accurate approach - # would be to render the pdf and check how much space had been used, but that - # could be very slow. - # NOTE: This is only an estimate, rounded up to the nearest 5%; it is intended - # for guidance when editing plan data, not to be 100% accurate. + # assigns the passed user_id to the creater_role for the project + # gives the user rights to read, edit, administrate, and defines them as creator # - # @param used_height [Integer] an estimate of the height used so far - # @return [Integer] the estimate of space used of an A4 portrain - def estimate_space_used(used_height) - @formatting ||= self.settings(:export).formatting + # @param user_id [Integer] the user to be given priveleges' id + def assign_creator(user_id) + Rails.logger.debug "RAY: assign_creator #{ user_id } to plan #{ self.inspect }" + add_user(user_id, true, true, true) + end - return 0 unless @formatting[:font_size] > 0 - - margin_height = @formatting[:margin][:top].to_i + @formatting[:margin][:bottom].to_i - page_height = A4_PAGE_HEIGHT - margin_height # 297mm for A4 portrait - available_height = page_height * self.dmptemplate.settings(:export).max_pages - - percentage = (used_height / available_height) * 100 - (percentage / ROUNDING).ceil * ROUNDING # round up to nearest five - end - - ## - # Take a guess at the vertical height (in mm) of the given text based on the - # font-size and left/right margins stored in the plan's settings. - # This assumes a fixed-width for each glyph, which is obviously - # incorrect for the font-face choices available; the idea is that - # they'll hopefully average out to that in the long-run. - # Allows for hinting different font sizes (offset from base via font_size_inc) - # and vertical margins (i.e. for heading text) - # - # @param text [String] the text to estimate size of - # @param font_size_inc [Integer] the size of the font of the text, defaults to 0 - # @param vertical_margin [Integer] the top margin above the text, defaults to 0 - def height_of_text(text, font_size_inc = 0, vertical_margin = 0) - @formatting ||= self.settings(:export).formatting - @margin_width ||= @formatting[:margin][:left].to_i + @formatting[:margin][:right].to_i - @base_font_size ||= @formatting[:font_size] - - return 0 unless @base_font_size > 0 - - font_height = FONT_HEIGHT_CONVERSION_FACTOR * (@base_font_size + font_size_inc) - font_width = font_height * FONT_WIDTH_HEIGHT_RATIO # Assume glyph width averages at 2/5s the height - leading = font_height / 2 - - chars_in_line = (A4_PAGE_WIDTH - @margin_width) / font_width # 210mm for A4 portrait - num_lines = (text.length / chars_in_line).ceil - - (num_lines * font_height) + vertical_margin + leading - end - - - - # BEGIN METHODS FROM PROJECT - # - ## @@ -632,11 +625,12 @@ # # @return [Integer, nil] the organisation_id or nil def institution_id - if organisation.nil? - return nil - else - return organisation.root.id - end +# if organisation.nil? +# return nil +# else +# return organisation.root.id +# end + return template.org.id end ## @@ -664,14 +658,6 @@ end end - ## - # assigns the passed user_id to the creater_role for the project - # gives the user rights to read, edit, administrate, and defines them as creator - # - # @param user_id [Integer] the user to be given priveleges' id - def assign_creator(user_id) - add_user(user_id, true, true, true) - end ## # assigns the passed user_id as an editor for the project @@ -701,49 +687,6 @@ end ## - # whether or not the current plan is administrable by the user - # - # @param user_id [Integer] the user to check if has privleges - # @return [Boolean] true if user can administer project, false otherwise - def administerable_by(user_id) - user = project_groups.find_by_user_id(user_id) - if (! user.nil?) && user.project_administrator then - return true - else - return false - end - end - - ## - # whether or not the current plan is editable by the user - # - # @param user_id [Integer] the user to check if has privleges - # @return [Boolean] true if user can edit project, false otherwise - def editable_by(user_id) - user = project_groups.find_by_user_id(user_id) - if (! user.nil?) && user.project_editor then - return true - else - return false - end - end - - ## - # whether or not the current plan is readable by the user - # should be renamed to readable_by? - # - # @param user_id [Integer] the user to check if has privleges - # @return [Boolean] true if user can read project, false otherwise - def readable_by(user_id) - user = project_groups.find_by_user_id(user_id) - if (! user.nil?) then - return true - else - return false - end - end - - ## # returns the projects which the user can atleast read # # @param user_id [Integer] the user to lookup projects for @@ -805,7 +748,12 @@ # # @return [User] the creater of the project def owner - self.project_groups.find_by_project_creator(true).try(:user) + self.roles.each do |role| + if role.creator? + return role.user + end + end + return nil end ## @@ -845,13 +793,24 @@ # @param is_administrator [Boolean] whether or not the user can administrate the project # @param is_creator [Boolean] wheter or not the user created the project # @return [Array] + # + # TODO: change this to specifying uniqueness of user/plan association and handle + # that way + # def add_user(user_id, is_editor = false, is_administrator = false, is_creator = false) - group = ProjectGroup.new - group.user_id = user_id - group.project_creator = is_creator - group.project_editor = is_editor - group.project_administrator = is_administrator - project_groups << group + Role.where(plan_id: self.id, user_id: user_id).each do |r| + r.destroy + end + + role = Role.new + role.user_id = user_id + role.plan_id = id + + role.creator= is_creator + role.editor= is_editor + role.administrator= is_administrator + role.save + Rails.logger.debug("RAY: saved role #{ role.inspect }") end ## @@ -870,4 +829,59 @@ end end + + + ## + # Based on the height of the text gathered so far and the available vertical + # space of the pdf, estimate a percentage of how much space has been used. + # This is highly dependent on the layout in the pdf. A more accurate approach + # would be to render the pdf and check how much space had been used, but that + # could be very slow. + # NOTE: This is only an estimate, rounded up to the nearest 5%; it is intended + # for guidance when editing plan data, not to be 100% accurate. + # + # @param used_height [Integer] an estimate of the height used so far + # @return [Integer] the estimate of space used of an A4 portrain + def estimate_space_used(used_height) + @formatting ||= self.settings(:export).formatting + + return 0 unless @formatting[:font_size] > 0 + + margin_height = @formatting[:margin][:top].to_i + @formatting[:margin][:bottom].to_i + page_height = A4_PAGE_HEIGHT - margin_height # 297mm for A4 portrait + available_height = page_height * self.dmptemplate.settings(:export).max_pages + + percentage = (used_height / available_height) * 100 + (percentage / ROUNDING).ceil * ROUNDING # round up to nearest five + end + + ## + # Take a guess at the vertical height (in mm) of the given text based on the + # font-size and left/right margins stored in the plan's settings. + # This assumes a fixed-width for each glyph, which is obviously + # incorrect for the font-face choices available; the idea is that + # they'll hopefully average out to that in the long-run. + # Allows for hinting different font sizes (offset from base via font_size_inc) + # and vertical margins (i.e. for heading text) + # + # @param text [String] the text to estimate size of + # @param font_size_inc [Integer] the size of the font of the text, defaults to 0 + # @param vertical_margin [Integer] the top margin above the text, defaults to 0 + def height_of_text(text, font_size_inc = 0, vertical_margin = 0) + @formatting ||= self.settings(:export).formatting + @margin_width ||= @formatting[:margin][:left].to_i + @formatting[:margin][:right].to_i + @base_font_size ||= @formatting[:font_size] + + return 0 unless @base_font_size > 0 + + font_height = FONT_HEIGHT_CONVERSION_FACTOR * (@base_font_size + font_size_inc) + font_width = font_height * FONT_WIDTH_HEIGHT_RATIO # Assume glyph width averages at 2/5s the height + leading = font_height / 2 + + chars_in_line = (A4_PAGE_WIDTH - @margin_width) / font_width # 210mm for A4 portrait + num_lines = (text.length / chars_in_line).ceil + + (num_lines * font_height) + vertical_margin + leading + end + end diff --git a/app/models/section.rb b/app/models/section.rb index d487dd9..35d4aef 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -2,7 +2,7 @@ ## # Associations - belongs_to :version + belongs_to :phase belongs_to :organisation has_many :questions, :dependent => :destroy has_many :plan_sections, :dependent => :destroy diff --git a/app/models/user.rb b/app/models/user.rb index f7e35b3..85fcc65 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -16,7 +16,7 @@ has_many :answers has_many :notes has_many :roles, dependent: :destroy - has_many :projects, through: :roles do + has_many :plans, through: :roles do def filter(query) return self unless query.present? t = self.arel_table @@ -68,7 +68,7 @@ # @param user_email [Boolean] defaults to true, allows the use of email if there is no firstname or surname # @return [String] the email or the firstname and surname of the user def name(use_email = true) - if ((firstname.nil? && surname.nil?) || (firstname.strip == "" && surname.strip == "")) && use_email then + if (firstname.blank? && surname.blank?) || use_email then return email else name = "#{firstname} #{surname}" @@ -229,4 +229,18 @@ UserMailer.api_token_granted_notification(self) end end + + + # this generates a reset password link for a given user + # which can then be sent to them with the appropriate host + # prepended. + def reset_password_link + raw, enc = Devise.token_generator.generate(self.class, :reset_password_token) + self.reset_password_token = enc + self.reset_password_sent_at = Time.now.utc + save(validate: false) + + edit_user_password_path + '?reset_password_token=' + raw + end + end diff --git a/app/policies/note_policy.rb b/app/policies/note_policy.rb index 49b9766..8ffe95a 100644 --- a/app/policies/note_policy.rb +++ b/app/policies/note_policy.rb @@ -2,22 +2,22 @@ attr_reader :user attr_reader :note - def initialize(user, comment) + def initialize(user, note) raise Pundit::NotAuthorizedError, "must be logged in" unless user @user = user @note = note end def create? - Plan.find(@note.plan_id).readable_by(@user.id) + @note.answer.plan.readable_by?(@user.id) end def update? - Plan.find(@note.plan_id).readable_by(@user.id) + Plan.find(@note.plan_id).readable_by?(@user.id) end def archive? - Plan.find(@note.plan_id).readable_by(@user.id) + Plan.find(@note.plan_id).readable_by?(@user.id) end -end \ No newline at end of file +end diff --git a/app/policies/plan_policy.rb b/app/policies/plan_policy.rb index 585e2ac..3f5ba9a 100644 --- a/app/policies/plan_policy.rb +++ b/app/policies/plan_policy.rb @@ -7,49 +7,57 @@ @user = user @plan = plan end + + def show? + @plan.readable_by?(@user.id) + end def edit? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) + end + + def update_guidance_choices? + @plan.editable_by?(@user.id) end def export? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) end def update? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end def status? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) end def section_answers? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) end def locked? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) end def delete_recent_locks? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end def unlock_all_sections? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end def lock_section? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end def unlock_section? - @plan.editable_by(@user.id) + @plan.editable_by?(@user.id) end def answer? - @plan.readable_by(@user.id) + @plan.readable_by?(@user.id) end -end \ No newline at end of file +end diff --git a/app/views/layouts/_navigation.html.erb b/app/views/layouts/_navigation.html.erb index 671ab79..42d66cf 100644 --- a/app/views/layouts/_navigation.html.erb +++ b/app/views/layouts/_navigation.html.erb @@ -46,21 +46,21 @@ <% end %> <% else %> <% if user_signed_in? %> - - <% if (namespace == "projects" || namespace == "plans") && current_path != "/projects/new" then %> + + <% if namespace == "plans" && current_path != "/plans/new" then %>
  • <% else %>
  • <% end %> - <%= link_to t("helpers.view_plans_label"), projects_path %> + <%= link_to t("helpers.view_plans_label"), plans_path %>
  • - <% if current_path == "/projects/new" then %> + <% if current_path == "/plans/new" then %>
  • <% else %>
  • <% end %> - <%= link_to t("helpers.create_plan_label"), new_project_path %> + <%= link_to t("helpers.create_plan_label"), new_plan_path %>
  • <% else %> diff --git a/app/views/plans/_add_note.html.erb b/app/views/plans/_add_note.html.erb deleted file mode 100644 index 957e0ef..0000000 --- a/app/views/plans/_add_note.html.erb +++ /dev/null @@ -1,20 +0,0 @@ - - -<% @new_note = Note.new %> - -<%= form_for :new_note, :url => {:controller => :notes, :action => :create } , :html=>{:method=>:post, :id => "new_note_form_#{questionId}", :class => "add_note_form"} do |f| %> - <%= f.hidden_field :user_id, :value => current_user.id %> - <%= f.hidden_field :question_id, :value => questionId %> - <%= f.hidden_field :plan_id, :value => planId %> - - <%= text_area_tag("#{questionId}new_note_text".to_sym, "" , class: "tinymce") %> -
    - <% question = Question.find(questionId)%> - -
    - <%= hidden_field_tag :section_id, question.section_id, :class => "section_id" %> - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary new_comment_submit_button" %> -
    -
    -<%end%> \ No newline at end of file diff --git a/app/views/plans/_answer_form.html.erb b/app/views/plans/_answer_form.html.erb deleted file mode 100644 index 29be29c..0000000 --- a/app/views/plans/_answer_form.html.erb +++ /dev/null @@ -1,253 +0,0 @@ - -<% answer = @plan.answer(question.id) %> - -
    - - <% q_format = question.question_format%> - - <% if readonly != "always" then %> -
    > - <%= semantic_form_for answer, :url => {:controller => :answers, :action => :create }, :html=>{:method=>:post}, :remote => true do |f| %> - <%= f.inputs do %> - <%= f.input :plan_id, :as => :hidden %> - <%= f.input :user_id, :as => :hidden, :input_html => { :value => current_user.id } %> - <%= f.input :question_id, :as => :hidden, :input_html => { :class => "question_id" } %> - - - - <%= raw question.text %> - - - <% suggested_answer = question.suggested_answers.find_by_organisation_id(@plan.project.organisation_id) %> - <% if !suggested_answer.nil? && suggested_answer.text != "" then %> -
    - - <% if suggested_answer.is_example? then %> - <%= t("org_admin.questions.example_answer_label")%> - <%else%> - <%= t("org_admin.questions.suggested_answer_label")%> - <%end%> - -
    -

    - <%= raw suggested_answer.text %> -

    -
    -
    - <% end %> - - - <% if q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown") then%> - <% options = question.options.order("number") %> - - <% if q_format.title == t("helpers.checkbox") then %> - <% if readonly then %> - <%= f.input :options, :as => :check_boxes, :collection => options, :label => false, input_html => { :disabled => true, :id => "options-#{question.id}" } %> - <% else %> - <%= f.input :options, :as => :check_boxes, :collection => options, :label => false, :input_html => { :id => "options-#{question.id}" } %> - <% end %> - - <% elsif q_format.title == t("helpers.multi_select_box") then %> - <% if readonly then %> - <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => true, :disabled => true , :id => "options-#{question.id}" } %> - <% else %> - <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => true , :id => "options-#{question.id}" } %> - <% end %> - - <% elsif q_format.title == t("helpers.radio_buttons") then%> -
      - <% options.each do |op| %> -
    1. - <% if answer.option_ids[0] == op.id then%> - <% if readonly then %> - <%= f.radio_button :option_ids, op.id, :checked => true, disabled: true, id: "answer_option_ids_#{op.id}"%> - <% else %> - <%= f.radio_button :option_ids, op.id, :checked => true, id: "answer_option_ids_#{op.id}"%> - <% end %> - <%else%> - <% if readonly then %> - <%= f.radio_button :option_ids, op.id, :checked => false, disabled: true, id: "answer_option_ids_#{op.id}"%> - <% else %> - <%= f.radio_button :option_ids, op.id, :checked => false, id: "answer_option_ids_#{op.id}"%> - <% end %> - <% end %> - <%= op.text %>
    2. - <% end %> -
    - - <% elsif q_format.title == t("helpers.dropdown") then%> - <% if readonly then %> - <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => false, :disabled => true, :id => "options-#{question.id}" } %> - <% else %> - <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => false, :id => "options-#{question.id}" } %> - <% end %> - <% end %> - - <% if question.option_comment_display == true then%> - <%= label_tag("answer-text-#{question.id}".to_sym, t("helpers.comment")) %> - <%= text_area_tag("answer-text-#{question.id}".to_sym, answer.text, class: "tinymce") %> - <%end%> - - - <% elsif q_format.title == t("helpers.text_field") then %> - <%= text_field_tag("answer-text-#{question.id}".to_sym, strip_tags(answer.text), class: "question_text_field") %> - - <% elsif q_format.title == t("helpers.text_area") then%> - <%= text_area_tag("answer-text-#{question.id}".to_sym, answer.text, class: "tinymce") %> - <% end %> - - <% end %> - - - <%= f.actions do %> - <% if readonly then %> - <%= f.action :submit, :label => t("helpers.save"), :button_html => { :class => "btn btn-primary"}, :input_html => { :disabled => true } %> - <% else %> - <%= f.action :submit, :label => t("helpers.save"), :button_html => { :class => "btn btn-primary"} %> - <% end %> - - <% end %> - <% end %> -
    - <% end %> - -
    > -

    <%= question.text %>

    -
    - <% if q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown") %> -
      - <% if answer.options.is_a? Option then %> -
    • <%= answer.options.text %>
    • - <% else %> - <% answer.options.each do |o| %> -
    • <%= o.text %>
    • - <% end %> - <% end %> -
    - <% end %> -
    - <%= raw answer.text %> -
    -
    -
    - <% if answer.created_at.nil? then %> - <%= t("helpers.notanswered") %> - <% else %> - <%= t("helpers.answered_by")%><%= answer.created_at %><%= t("helpers.answered_by_part2")%><%= answer.user.name %> - <% end %> - -
    - - - -
    -
    - <% @comments = Comment.where("question_id = ? AND plan_id = ?", question.id, answer.plan_id ) %> - <%= hidden_field_tag :question_id, question.id, :class => "question_id" %> - <% @question_guidances = @plan.guidance_for_question(question) %> -
      - <% if (!question.guidance.nil? && question.guidance != "") || @question_guidances.count > 0 then %> - - <% css_style_comment_div = "display: none;"%> - <% css_style_guidance_div = ""%> -
    • - <%= link_to t("helpers.guidance_accordion_label"), "#", :class => "guidance_accordion_button" %> -
    • -
    • - <% if @comments.count > 0 then%> - <% comments_label_with_count = "#{t("helpers.comment_accordion_label")} (#{@comments.count})"%> - <%= link_to comments_label_with_count , "#", :class => "comments_accordion_button" %> - <%else%> - <%= link_to t("helpers.add_comment_accordion_label"), "#", :class => "comments_accordion_button" %> - <%end%> -
    • - <%else%> - - <% css_style_comment_div = ""%> - <% css_style_guidance_div = "display: none;"%> -
    • - <% if @comments.count > 0 then%> - <% comments_label_with_count = "#{t("helpers.comment_accordion_label")} (#{@comments.count})"%> -

      <%= comments_label_with_count %>

      - <%else%> -

      <%= t("helpers.add_comment_accordion_label") %>

      - <%end%> -
    • - <%end%> -
    -
    - - - -
    -
    - - <% if !question.guidance.nil? && question.guidance != "" then %> - - <% end %> - - <% @question_guidances.each_pair do |group,themes| %> - <% themes.each_pair do |theme,guidances| %> - <% guidances.each do |guidance| %> - - <% end %> - <% end %> - <% end %> -
    -
    - - -
    - <%= render :partial => "comments", locals: {questionId: question.id, plan_id: answer.plan_id }%> -
    - - - -
    - -<% if last_question_id == question.id then %> -
    -<% else %> -
    -<% end %> diff --git a/app/views/plans/_archive_note.html.erb b/app/views/plans/_archive_note.html.erb deleted file mode 100644 index a101e30..0000000 --- a/app/views/plans/_archive_note.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - - -<%= form_for(note, :url => {:controller => :notes, :action => :archive } , :html => { :method => :put, :class => "archive_note_form", :id => "archive_note_form_#{note.id}"}) do |f| %> - <%= f.hidden_field :id, :value => note.id %> - <%= f.hidden_field :archived_by, :value => current_user.id %> - - <%= render :partial => "view_note", locals: {note: note} %> - - <% if current_user.id == note.user_id then %> - <%= t('helpers.notes.archive_own_note_question')%> - <% button_label = t("helpers.notes.archive_own_comment_button_label") %> - <% else%> - <%= t("helpers.notes.archive_note_question")%> - <% button_label = t("helpers.notes.archive_comment_button_label") %> - <%end%> - - -
    - <% question = Question.find(note.question_id)%> - <%= hidden_field_tag :plan_id, note.plan_id, :class => "plan_id" %> - <%= hidden_field_tag :note_id, note.id, :class => "comment_id" %> - <%= hidden_field_tag :section_id, question.section_id, :class => "section_id" %> - <%= f.submit button_label, :class => "btn btn-primary archive_comment_submit_button" %> - <%= hidden_field_tag :note_id, note.id, :class => "comment_id" %> - <%= link_to t("helpers.submit.cancel"), "#", :class => "cancel_archive_comment btn cancel" %> -
    -
    -<%end%> \ No newline at end of file diff --git a/app/views/plans/_edit_note.html.erb b/app/views/plans/_edit_note.html.erb deleted file mode 100644 index 6294200..0000000 --- a/app/views/plans/_edit_note.html.erb +++ /dev/null @@ -1,18 +0,0 @@ - - -<%= form_for(note, :url => {:controller => :notes, :action => :update } , :html => { :method => :put, :class => "edit_note_form", :id=> "edit_note_form_#{note.id}"}) do |f| %> - <%= f.hidden_field :id, :value => note.id %> - - <%= text_area_tag("#{note.id}_note_text".to_sym, note.text , class: "tinymce") %> -
    - - -
    - <% question = Question.find(note.question_id)%> - <%= hidden_field_tag :plan_id, note.plan_id, :class => "plan_id" %> - <%= hidden_field_tag :note_id, note.id, :class => "note_id" %> - <%= hidden_field_tag :section_id, question.section_id, :class => "section_id" %> - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary edit_note_submit_button" %> -
    -
    -<%end%> \ No newline at end of file diff --git a/app/views/plans/_export.html.erb b/app/views/plans/_export.html.erb index 6c0e8de..d47ae8d 100644 --- a/app/views/plans/_export.html.erb +++ b/app/views/plans/_export.html.erb @@ -1,9 +1,9 @@ - diff --git a/app/views/plans/_list_notes.html.erb b/app/views/plans/_list_notes.html.erb deleted file mode 100644 index 10a16f0..0000000 --- a/app/views/plans/_list_notes.html.erb +++ /dev/null @@ -1,79 +0,0 @@ - -<% if notes.count > 1 then%> - <% style_to_add = "height:150px; overflow-y:auto;" %> -<%else%> - <% style_to_add = "" %> -<%end%> -
    -
    - - - <% notes.order("updated_at DESC").each do |c|%> - - - - - <%end%> - -
    - <% user = User.find(c.user_id) %> - <%= user.name %>
    - (<%= l c.updated_at, format: :custom %>) -
    - <% if c.archived == true then %> - <% if c.archived_by == current_user.id then%> - <%= t("helpers.comments.retracted")%> - <% else %> - <% archived_by_user = User.find(c.archived_by) %> - <%= t("helpers.comments.clear_by")%> <%= archived_by_user.name %> - <%end%> - <%else%> - <%= link_to t("helpers.comments.view_label"),"#", :class => "dmp_table_link view_comment_button" %> - <%= hidden_field_tag :note_id, c.id, :class => "comment_id" %> - <% if current_user.id == c.user_id then %> - <%= link_to t("helpers.comments.edit_label"),"#", :class => "dmp_table_link edit_comment_button" %> - - <%= hidden_field_tag :note_id, c.id, :class => "comment_id" %> - <%= link_to t("helpers.comments.retract_label"),"#", :class => "dmp_table_link archive_comment_button" %> - <% end%> - <% project_id = Plan.find(c.plan_id).project_id%> - <% if (Project.find(project_id).administerable_by(current_user.id) && current_user.id != c.user_id )then%> - <%= hidden_field_tag :note_id, c.id, :class => "comment_id" %> - <%= link_to t("helpers.comments.clear_label"),"#", :class => "dmp_table_link archive_comment_button" %> - <% end%> - <%end%> -
    -
    - -
    - - -<% notes_not_archived = notes.where("archived IS NULL") %> -<% latest_note = notes_not_archived.order("updated_at DESC").first %> -<% if !latest_note.nil? then%> -
    - <%= render :partial => "view_note", locals: {note: latest_note} %> -
    -
    -<%end%> - -<%notes.order("updated_at DESC").each do |com|%> - - - - - - - - - - <%end%> diff --git a/app/views/plans/_note.html.erb b/app/views/plans/_note.html.erb deleted file mode 100644 index a6ed343..0000000 --- a/app/views/plans/_note.html.erb +++ /dev/null @@ -1,35 +0,0 @@ - - - - -<% @notes = Note.where("question_id = ? AND plan_id = ?", questionId, plan_id) %> -<%= hidden_field_tag :question_id, questionId, :class => "question_id" %> - -<% if @notes.count > 0 then%> - -
    - <%= link_to t("helpers.comments.add_comment_label"),'#', :class => "btn btn-primary add_comment_button" %> - -
    -
    -
    - - <%= render :partial => "list_notes", locals: {notes: @notes}%> -
    -
    - -
    - <%= link_to t("helpers.comments.add_comment_label"),'#', :class => "btn btn-primary add_comment_button" %> -
    -
    -
    - - - -<% else%> - <%= t("helpers.comments.add_comment_text")%> - <%= render :partial => "add_note", locals: {questionId: questionId, planId: plan_id}%> -<% end%> diff --git a/app/views/plans/_view_note.html.erb b/app/views/plans/_view_note.html.erb deleted file mode 100644 index 6b7737f..0000000 --- a/app/views/plans/_view_note.html.erb +++ /dev/null @@ -1,11 +0,0 @@ - -<% user = User.find(note.user_id) %> -
    -
    -
    -
      -
    • <%= t("helpers.comments.commented_by")%>

    • -
    • <%= user.name%> (<%= l note.updated_at, format: :custom %>)
    • -
    • <%= raw note.text %>
    • -
    -
    diff --git a/app/views/plans/edit.html.erb b/app/views/plans/edit.html.erb index 0bd9403..bd3de93 100644 --- a/app/views/plans/edit.html.erb +++ b/app/views/plans/edit.html.erb @@ -1,16 +1,19 @@ <%- model_class = Plan -%> <% javascript "plans.js" %> - + -<%= render :partial => "/projects/project_title", locals: {project: @plan.project} %> +<%= render :partial => "plan_title", locals: {plan: @plan} %> <% status = @plan.status %>
    <%space_used = status["space_used"].to_i - space_title = t("helpers.plan.export.space_used", space_used: space_used, num_pages: @plan.dmptemplate.settings(:export).max_pages) + space_title = t("helpers.plan.export.space_used", space_used: space_used, num_pages: @plan.template.settings(:export).max_pages) answered = %(#{status["num_answers"]}/#{status["num_questions"]})%>
    <%= answered -%> <%= t("helpers.project.questions_answered")%> @@ -23,27 +26,18 @@
    -<% readonly = nil %> -<% if ! @plan.editable_by(current_user.id) then %> - <% readonly = "always" %> -<% end %> - - -<%= render :partial => "/projects/project_nav_tabs", locals: {project: @plan.project, active: @plan.id} %> + +<%= render :partial => "plan_nav_tabs", locals: {plan: @plan, active: @phase.id } %> - +
    - <% sections = @plan.sections %> + <% sections = @phase.sections %> <% sections.each do |section| %> - <% locked = @plan.locked(section.id, current_user.id) %> - <% if readonly == nil && locked["locked"] then %> - <% readonly = "conditional" %> - <% end %> <% if session[:question_id_comments].to_i != 0 then %> @@ -56,59 +50,78 @@
    - <% num_section_questions = @plan.status["sections"][section.id]["num_questions"] %> - <% num_section_answers = @plan.status["sections"][section.id]["num_answers"] %> + + + <% num_section_questions = @section.status["sections"][section.id]["num_questions"] %> + <% num_section_answers = @section.status["sections"][section.id]["num_answers"] %> <% question_word = "questions" %> <% if num_section_questions == 1 then %> <% question_word = "question" %> <% end %> <% section_status = "#{num_section_questions} #{question_word}, #{num_section_answers} answered" %> + + + + -
    +
    + +
    - <%= raw section.description %> -
    + <%= raw section.description %> +
    + +

    <%= t ('helpers.loading')%>

    - -
    - + <% section.questions.order("number").each do |question| %> + <% if question.id == session[:question_id_comments].to_i then id_css = "current_question" end %> +
    + <% partialname = "answer_form" + if @readonly + partialname += "_ro" + end + %> + + <%= render partial: partialname, + locals: { + plan: @plan, + question: question, + last_question_id: section.questions.order("number DESC").first.id + } + %> +
    + <% end %> +
    + + + + + + +