diff --git a/app/controllers/annotations_controller.rb b/app/controllers/annotations_controller.rb index a262cb3..e83366b 100644 --- a/app/controllers/annotations_controller.rb +++ b/app/controllers/annotations_controller.rb @@ -4,18 +4,36 @@ #create annotations def admin_create - @example_answer = Annotation.new(params[:annotation]) - authorize @example_answer - if @example_answer.save - redirect_to admin_show_phase_path(id: @example_answer.question.section.phase_id, section_id: @example_answer.question.section_id, question_id: @example_answer.question.id, edit: 'true'), notice: _('Information was successfully created.') + # authorize the question (includes to reduce queries) + @question = Question.includes(section: { phase: :template}).find(params[:question_id]) + authorize @question + if params[:example_answer_text].present? + example_answer = init_annotation(params[:example_answer_text], @question, current_user.org, Annotation.types[:example_answer]) + end + if params[:guidance_text].present? + guidance = init_annotation(params[:guidance_text], @question, current_user.org, Annotation.types[:guidance]) + end + # if they dont exist, no requirement for them to be saved + ex_save = example_answer.present? ? example_answer.save : true + guid_save = guidance.present? ? guidance.save : true + + if ex_save && guid_save + redirect_to admin_show_phase_path(id: @question.section.phase_id, section_id: @question.section_id, question_id: @question.id, edit: 'true'), notice: _('Information was successfully created.') else - @section = @example_answer.question.section + @section = @question.section @phase = @section.phase @open = true @sections = @phase.sections @section_id = @section.id @question_id = @example_answer.question - flash[:notice] = failed_create_error(@example_answer, _('example answer')) + if !ex_save && !guid_save + flash[:notice] = failed_create_error(example_answer, _('example answer')) + '\n' + + failed_create_error(gudiance, _('guidance')) + elsif !guid_save + flash[:notice] = failed_create_error(gudiance, _('guidance')) + elsif !ex_save + flash[:notice] = failed_create_error(example_answer, _('example answer')) + end render "phases/admin_show" end end @@ -23,15 +41,49 @@ #update a example answer of a template def admin_update - @example_answer = Annotation.includes(question: { section: {phase: :template}}).find(params[:id]) - authorize @example_answer #.question.section.phase.template - @question = @example_answer.question + @question = Question.includes(section: { phase: :template}).find(params[:question_id]) + if params[:guidance_id].present? + guidance = Annotation.includes(question: {section: {phase: :template}}).find(params[:guidance_id]) + authorize guidance + end + if params[:example_answer_id].present? + example_answer = Annotation.includes(question: {section: {phase: :template}}).find(params[:example_answer_id]) + authorize example_answer + end + verify_authorized + # if guidance present, update + if params[:guidance_text].present? + if guidance.present? + guidance.text = params[:guidance_text] + else + guidance = init_annotation(params[:guidance_text], @question, current_user.org, Annotation.types[:guidance]) + end + end + # if example answer present, update + if params[:example_answer_text].present? + if example_answer.present? + example_answer.text = params[:example_answer_text] + else + example_answer = init_annotation(params[:example_answer_text], @question, current_user.org, Annotation.types[:example_answer]) + end + end + # only required to save if we updated/created one + ex_save = example_answer.present? ? example_answer.save : true + guid_save = guidance.present? ? guidance.save : true + @section = @question.section @phase = @section.phase - if @example_answer.update_attributes(params[:annotation]) + if ex_save && guid_save redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id, question_id: @question.id, edit: 'true'), notice: _('Information was successfully updated.') else - flash[:notice] = failed_update_error(@example_answer, _('example answer')) + if !ex_save && !guid_save + flash[:notice] = failed_create_error(example_answer, _('example answer')) + '\n' + + failed_create_error(gudiance, _('guidance')) + elsif !guid_save + flash[:notice] = failed_create_error(gudiance, _('guidance')) + elsif !ex_save + flash[:notice] = failed_create_error(example_answer, _('example answer')) + end render action: "phases/admin_show" end end @@ -50,4 +102,15 @@ end end + private + + def init_annotation(text, question, org, type) + annotation = Annotation.new + annotation.org = org + annotation.question = question + annotation.text = text + annotation.type = type + return annotation + end + end \ No newline at end of file diff --git a/app/controllers/answers_controller.rb b/app/controllers/answers_controller.rb index 51f76b2..7d48ddf 100644 --- a/app/controllers/answers_controller.rb +++ b/app/controllers/answers_controller.rb @@ -2,95 +2,54 @@ after_action :verify_authorized respond_to :html - # PUT/PATCH /[:locale]/answer/[:id] + # PUT/PATCH /answers/[:id] def update - question_id = params[:answer][:question_id] - plan_id = params[:answer][:plan_id] - @question = Question.find(question_id); - # If an answer id is present load that answer otherwise load by plan/question - @answer = Answer.find_by(plan_id: plan_id, question_id: question_id) - - @old_answer = nil - @timestamp = nil - - if @answer.nil? # If there is no answer for plan/question - @answer = Answer.new(permitted_params) - @answer.text = params["answer-text-#{@answer.question_id}".to_sym] - - authorize @answer - - if @answer.save - @timestamp = @answer.updated_at.iso8601 - end - @lock_version = @answer.lock_version - elsif params[:answer][:id].blank? # Someone else already added an answer while the user was working - @old_answer = Marshal::load(Marshal.dump(@answer)) - @answer.text = params["answer-text-#{@answer.question_id}".to_sym] - - authorize @answer - - @lock_version = @answer.lock_version - else # We're about updating an answer (let ActiveRecord check for a race condition) - @old_answer = Marshal::load(Marshal.dump(@answer)) - @answer.text = params["answer-text-#{@answer.question_id}".to_sym] - - authorize @answer - - if @answer.update(permitted_params) - @answer.touch # Saves the record with the updated_at set to the current time. Needed if only answer.question_options is updated - @timestamp = @answer.updated_at.iso8601 - end - @lock_version = @answer.lock_version - @old_answer = nil - end - - @section_id = @answer.question.section.id - @username = @answer.user.name - - @nquestions = 0 - @nanswers = 0 - @n_section_questions = 0 - @n_section_answers = 0 - - plan = Plan.find(plan_id) - # Problem of N+1 queries below - plan.template.phases.each do |phase| - phase.sections.each do |section| - section.questions.each do |question| - @nquestions += 1 - if section.id == @section_id - @n_section_questions += 1 - end - question.answers = question.answers.to_a.select {|answer| answer.plan_id == plan.id} - if question.answers.present? && question.answers.first.text.present? - @nanswers += 1 - if section.id == @section_id - @n_section_answers += 1 - end - end + p_params = permitted_params() + @answer = Answer.find_by({plan_id: p_params[:plan_id], question_id: p_params[:question_id], }) + begin + if @answer + authorize @answer + @answer.update(p_params) + if p_params[:question_option_ids].present? + @answer.touch() # Saves the record with the updated_at set to the current time. Needed if only answer.question_options is updated end + else + @answer = Answer.new(p_params) + @answer.lock_version = 1 + authorize @answer + @answer.save() # NOTE, there is a chance to create multiple answer associated for a plan/question (IF any concurrent thread) INSERTS an answer after checking the existence of an answer (Line 8) + # In order to avoid that edge-case, it is recommended to create answers whenever a new plan is created (e.g. after_create callback) end + rescue ActiveRecord::StaleObjectError + @stale_answer = @answer + @answer = Answer.find_by({plan_id: p_params[:plan_id], question_id: p_params[:question_id]}) end + + @plan = Plan.includes({ + sections: { + questions: [ + :answers, + :question_format + ] + } + }).find(p_params[:plan_id]) + @question = @answer.question + @section = @plan.get_section(@question.section_id) respond_to do |format| format.js {} end - - rescue ActiveRecord::StaleObjectError - @username = @old_answer.user.name - @lock_version = @old_answer.lock_version - respond_to do |format| - format.js {} - end - end # End update private def permitted_params - permitted = params.require(:answer).permit(:id, :plan_id, :user_id, :question_id, :lock_version, :question_option_ids => []) - if !permitted[:question_option_ids].present? #If question_option_ids has been filtered out because it was a scalar value (e.g. radiobutton answer) + permitted = params.require(:answer).permit(:id, :text, :plan_id, :user_id, :question_id, :lock_version, :question_option_ids => []) + if !params[:answer][:question_option_ids].nil? && !permitted[:question_option_ids].present? #If question_option_ids has been filtered out because it was a scalar value (e.g. radiobutton answer) permitted[:question_option_ids] = [params[:answer][:question_option_ids]] # then convert to an Array end + if !permitted[:id].present? + permitted.delete(:id) + end return permitted end # End permitted_params end diff --git a/app/controllers/phases_controller.rb b/app/controllers/phases_controller.rb index 99406e9..b9d9685 100644 --- a/app/controllers/phases_controller.rb +++ b/app/controllers/phases_controller.rb @@ -15,24 +15,6 @@ @phase = @plan.template.phases.select {|p| p.id == phase_id}.first @readonly = !@plan.editable_by?(current_user.id) - # the eager_load pulls in ALL answers - # need to restrict to just ones for this plan - # at the same time count the questions and answers for the status - @nquestions = 0 - @nanswers = 0 - - @plan.template.phases.each do |phase| - phase.sections.each do |section| - section.questions.each do |question| - @nquestions += 1 - question.answers = question.answers.to_a.select {|answer| answer.plan_id == @plan.id} - if question.answers.present? && question.answers.first.text.present? - @nanswers += 1 - end - end - end - end - # Now we need to get all the themed guidance for the plan. # TODO: think this through again, there may be a better way to do this. # diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index b17e7b7..b0f3465 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -18,7 +18,7 @@ authorize @plan # Get all of the available funders and non-funder orgs - @funders = Org.funders.sort{|x,y| x.name <=> y.name } + @funders = Org.funders.joins(:templates).where(templates: {published: true}).uniq.sort{|x,y| x.name <=> y.name } @orgs = (Org.institutions + Org.managing_orgs).flatten.uniq.sort{|x,y| x.name <=> y.name } # Get the current user's org @@ -125,7 +125,7 @@ @all_ggs_grouped_by_org = @all_ggs_grouped_by_org.sort_by {|org,gg| org.name} @selected_guidance_groups = @plan.guidance_groups.pluck(:id) - @based_on = (@plan.template.customization_of.nil? ? @plan.template : Template.live(@plan.template.customization_of)) + @based_on = (@plan.template.customization_of.nil? ? @plan.template : Template.where(dmptemplate: @plan.template.customization_of).first) respond_to :html end diff --git a/app/controllers/questions_controller.rb b/app/controllers/questions_controller.rb index 14a6d21..2beb963 100644 --- a/app/controllers/questions_controller.rb +++ b/app/controllers/questions_controller.rb @@ -4,38 +4,36 @@ #create a question def admin_create - @question = Question.new(params[:question]) - authorize @question - example = @question.annotations.first - if example.present? - example.org_id = current_user.org_id - example.example_answer! - end - if params["new-question-guidance"].present? - guidance = @question.annotations.build - guidance.text = params["new-question-guidance"] - guidance.org_id = current_user.org_id - guidance.guidance! - guidance.save - end - @question.default_value = params["new-question-default-value"] - @question.modifiable = true - if @question.save - @question.section.phase.template.dirty = true - @question.section.phase.template.save! + begin + @question = Question.new(question_params) + authorize @question + @question.modifiable = true + if @question.save + @question.section.phase.template.dirty = true + @question.section.phase.template.save! + if params[:example_answer].present? + example_answer = Annotation.new({question_id: @question.id, org_id: current_user.org_id, text: params[:example_answer], type: Annotation.types[:example_answer]}) + example_answer.save + end + if params[:guidance].present? + guidance = Annotation.new({question_id: @question.id, org_id: current_user.org_id, text: params[:guidance], type: Annotation.types[:guidance]}) + guidance.save + end + redirect_to admin_show_phase_path(id: @question.section.phase_id, section_id: @question.section_id, question_id: @question.id, edit: 'true'), notice: _('Information was successfully created.') + else + @edit = (@question.section.phase.template.org == current_user.org) + @open = true + @phase = @question.section.phase + @section = @question.section + @sections = @phase.sections + @section_id = @question.section.id + @question_id = @question.id - redirect_to admin_show_phase_path(id: @question.section.phase_id, section_id: @question.section_id, question_id: @question.id, edit: 'true'), notice: _('Information was successfully created.') - else - @edit = (@question.section.phase.template.org == current_user.org) - @open = true - @phase = @question.section.phase - @section = @question.section - @sections = @phase.sections - @section_id = @question.section.id - @question_id = @question.id - - flash[:notice] = failed_create_error(@question, _('question')) - render template: 'phases/admin_show' + flash[:notice] = failed_create_error(@question, _('question')) + render template: 'phases/admin_show' + end + rescue ActionController::ParameterMissing => e + flash[:notice] = e.message end end @@ -89,4 +87,18 @@ end end + private + # Filters the valid attributes for a question according to each type. + # Note, that params[:question] and params[:question][:question_format_id] are required and their absence raises ActionController::ParameterMissing + def question_params + permitted = params.require(:question).except(:created_at, :updated_at).tap do |question_params| + question_params.require(:question_format_id) + q_format = QuestionFormat.find(question_params[:question_format_id]) + if q_format.option_based + question_params.delete(:default_value) + else + question_params.delete(:question_options_attributes) + end + end + end end \ No newline at end of file diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index bcaf9b9..a628929 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -72,6 +72,7 @@ def update if user_signed_in? then @orgs = Org.where(parent_id: nil).order("name") + @default_org = current_user.org @other_organisations = Org.where(parent_id: nil, is_other: true).pluck(:id) @identifier_schemes = IdentifierScheme.where(active: true).order(:name) @languages = Language.sorted_by_abbreviation @@ -91,30 +92,53 @@ end def do_update(require_password = true, confirm = false) - if require_password # user is changing email or password - if current_user.email != params[:user][:email] # if user is changing email - if params[:user][:current_password].blank? # password needs to be present - message = _('Please enter your password to change email address.') - successfully_updated = false - else + mandatory_params = true + message = _('Save Unsuccessful.') + ' ' # added to by below, overwritten otherwise + # ensure that the required fields are present + if params[:user][:email].blank? + message +=_('Please enter an email address.') + ' ' + mandatory_params &&= false + end + if params[:user][:firstname].blank? + message +=_('Please enter a First name.') + ' ' + mandatory_params &&= false + end + if params[:user][:surname].blank? + message +=_('Please enter a Last name.') + ' ' + mandatory_params &&= false + end + if params[:user][:org_id].blank? + message += _('Please select an organisation, or select Other.') + mandatory_params &&= false + end + if mandatory_params # has the user entered all the details + if require_password # user is changing email or password + if current_user.email != params[:user][:email] # if user is changing email + if params[:user][:current_password].blank? # password needs to be present + message = _('Please enter your password to change email address.') + successfully_updated = false + else + successfully_updated = current_user.update_with_password(password_update) + end + elsif params[:user][:password].present? # if user is changing password + successfully_updated = false # shared across first 3 conditions + if params[:user][:current_password].blank? + message = _('Please enter your current password') + elsif params[:user][:password_confirmation].blank? + message = _('Please enter a password confirmation') + elsif params[:user][:password] != params[:user][:password_confirmation] + message = _('Password and comfirmation must match') + else + successfully_updated = current_user.update_with_password(password_update) + end + else # potentially unreachable... but I dont like to leave off the else successfully_updated = current_user.update_with_password(password_update) end - elsif params[:user][:password].present? # if user is changing password - successfully_updated = false # shared across first 3 conditions - if params[:user][:current_password].blank? - message = _('Please enter your current password') - elsif params[:user][:password_confirmation].blank? - message = _('Please enter a password confirmation') - elsif params[:user][:password] != params[:user][:password_confirmation] - message = _('Password and comfirmation must match') - else - successfully_updated = current_user.update_with_password(password_update) - end - else # potentially unreachable... but I dont like to leave off the else - successfully_updated = current_user.update_with_password(password_update) + else # password not required + successfully_updated = current_user.update_without_password(update_params) end - else # password not required - successfully_updated = current_user.update_without_password(update_params) + else + successfully_updated = false end #unlink shibboleth from user's details diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index 76d55a5..c1ea7e8 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -50,7 +50,7 @@ } end - # PUT /org/admin/templates/:id/admin_customize + # GET /org/admin/templates/:id/admin_customize # ----------------------------------------------------- def admin_customize @template = Template.find(params[:id]) diff --git a/app/models/answer.rb b/app/models/answer.rb index 8267948..d46ad59 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -42,4 +42,18 @@ def has_question_option(option_id) self.question_option_ids.include?(option_id) end + + # Returns true if the answer is valid and false otherwise. If the answer's question is option_based, it is checked if exist + # any question_option selected. For non option_based (e.g. textarea or textfield), it is checked the presence of text + def is_valid? + if self.question.present? + if self.question.question_format.option_based? + return !self.question_options.empty? + else # (e.g. textarea or textfield question formats) + return self.text.present? + end + else + return false + end + end end diff --git a/app/models/org.rb b/app/models/org.rb index 348a7d1..bb45c32 100644 --- a/app/models/org.rb +++ b/app/models/org.rb @@ -22,11 +22,11 @@ ## # Possibly needed for active_admin # -relies on protected_attributes gem as syntax depricated in rails 4.2 -# attr_accessible :abbreviation, :banner_text, :logo, :remove_logo, -# :logo_file_name, :name, :target_url, -# :organisation_type_id, :wayfless_entity, :parent_id, :sort_name, -# :token_permission_type_ids, :language_id, :contact_email, -# :language, :org_type, :region, :token_permission_types + attr_accessible :abbreviation, :banner_text, :logo, :remove_logo, + :logo_file_name, :name, :target_url, + :organisation_type_id, :wayfless_entity, :parent_id, :sort_name, + :token_permission_type_ids, :language_id, :contact_email, + :language, :org_type, :region, :token_permission_types ## # Validators diff --git a/app/models/phase.rb b/app/models/phase.rb index a316416..5c2323f 100644 --- a/app/models/phase.rb +++ b/app/models/phase.rb @@ -4,6 +4,12 @@ # [+Created:+] 03/09/2014 # [+Copyright:+] Digital Curation Centre and University of California Curation Center class Phase < ActiveRecord::Base + + ## + # Sort order: Number ASC + default_scope { order(number: :asc) } + + # extend FriendlyId ## # Associations diff --git a/app/models/plan.rb b/app/models/plan.rb index 549b4fe..5db4cde 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -949,8 +949,29 @@ end =end + # Returns the number of answered questions from the entire plan + def num_answered_questions + n = 0 + self.sections.each do |s| + n+= s.num_answered_questions(self.id) + end + return n + end + # Returns a section given its id or nil if does not exist for the current plan + def get_section(section_id) + self.sections.find { |s| s.id == section_id } + end + # Returns the number of questions for a plan. Note, this method becomes useful + # for when sections and their questions are eager loaded so that avoids SQL queries. + def num_questions + n = 0 + self.sections.each do |s| + n+= s.questions.size() + end + return n + end # the following two methods are for eager loading. One gets used for the plan/show # page and the oter for the plan/edit. The difference is just that one pulls in more than # the other. diff --git a/app/models/question.rb b/app/models/question.rb index 10efc8b..0a3e947 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -1,8 +1,13 @@ class Question < ActiveRecord::Base + + ## + # Sort order: Number ASC + default_scope { order(number: :asc) } + ## # Associations has_many :answers, :dependent => :destroy - has_many :question_options, :dependent => :destroy + has_many :question_options, :dependent => :destroy, :inverse_of => :question # inverse_of needed for nester forms has_many :annotations, :dependent => :destroy has_and_belongs_to_many :themes, join_table: "questions_themes" belongs_to :section diff --git a/app/models/question_format.rb b/app/models/question_format.rb index 061961a..b7d6afc 100644 --- a/app/models/question_format.rb +++ b/app/models/question_format.rb @@ -14,6 +14,9 @@ # -relies on protected_attributes gem as syntax depricated in rails 4.2 attr_accessible :title, :description, :option_based, :questions, :as => [:default, :admin] + # Retrieves the id for a given formattype passed + scope :id_for, -> (formattype) { where(formattype: formattype).pluck(:id).first } + ## # Define Bit Field Values so we can test a format without doing string comps # Column type diff --git a/app/models/section.rb b/app/models/section.rb index abf1327..4d4562b 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -23,10 +23,11 @@ "#{title}" end + # Returns the number of answered questions for a given plan id def num_answered_questions(plan_id) n = 0 self.questions.each do |question| - n += question.plan_answers(plan_id).select{|answer| answer.text.present?}.count + n += question.plan_answers(plan_id).select{|answer| answer.is_valid?}.count end return n end diff --git a/app/models/template.rb b/app/models/template.rb index b10daa4..f0fdc00 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -19,7 +19,7 @@ # -relies on protected_attributes gem as syntax depricated in rails 4.2 attr_accessible :id, :org_id, :description, :published, :title, :locale, :customization_of, :is_default, :guidance_group_ids, :org, :plans, :phases, :dmptemplate_id, - :version, :visibility, :published, :as => [:default, :admin] + :migrated, :version, :visibility, :published, :as => [:default, :admin] # defines the export setting for a template object has_settings :export, class_name: 'Settings::Template' do |s| diff --git a/app/models/user.rb b/app/models/user.rb index 8ea0608..c1350f6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -263,6 +263,14 @@ end end + ## + # Override devise_invitable email title + # -------------------------------------------------------------- + def deliver_invitation(options = {}) + super(options.merge(subject: _('A Data Management Plan in %{application_name} has been shared with you') % {application_name: Rails.configuration.branding[:application][:name]})) + end + + # TODO: Remove this, its never called. # this generates a reset password link for a given user # which can then be sent to them with the appropriate host diff --git a/app/policies/annotation_policy.rb b/app/policies/annotation_policy.rb index cf63f42..a426546 100644 --- a/app/policies/annotation_policy.rb +++ b/app/policies/annotation_policy.rb @@ -14,11 +14,12 @@ ## def admin_create? - user.can_modify_templates? && (annotation.question.section.phase.template.org_id == user.org_id) + # here we pass through a question instead of an annotation object + user.can_modify_templates? && (annotation.section.phase.template.org_id == user.org_id) end def admin_update? - user.can_modify_templates? && (annotation.question.section.phase.template.org_id == user.org_id) + user.can_modify_templates? && (annotation.question.section.phase.template.org_id == user.org_id) && annotation.org_id == user.org_id end def admin_destroy? diff --git a/app/views/annotations/_add_annotation.html.erb b/app/views/annotations/_add_annotation.html.erb index 8cf9113..8add942 100644 --- a/app/views/annotations/_add_annotation.html.erb +++ b/app/views/annotations/_add_annotation.html.erb @@ -1,15 +1,21 @@ -<%= form_for :annotation, url: admin_create_annotation_path do |f| %> - <%= f.hidden_field :org_id, value: current_user.org_id %> - <%= f.hidden_field :question_id, value: question.id %> - <%= f.hidden_field :type, value: Annotation.types[:example_answer] %> - +
| <%= _('Example Answer')%> |
|
+ |||||||||||
| <%= _('Guidance')%> | +
+
|
@@ -19,7 +25,8 @@
| <%= _('Example of Answer')%> | +<%= _('Example Answer')%> |
|
+
| <%= _('Guidance')%> | +
+
|
| - <%= _('Example of answer')%> - | -<%= raw annotation.text %> | -
| + <%= _('Example Answer')%> + | +<%= raw example_answer.text %> | +
| + <%= _('Guidance')%> + | +<%= raw guidance.text %> | +
<%= _('The following answer cannot be saved') %>
+ <%= render partial: '/answers/new_edit', locals: { question: question, answer: answer, readonly: true } %> +<%= _('since %{name} saved the answer below while you were editing. Please, combine your changes and then save the answer again.') % { name: user.name} %>
+<%= _("While you were editing ") + answer.user.name + _(" saved the following answer:") %>
- -<%= semantic_form_for answer, :url => {:controller => :answers, :action => :update }, :remote => true do |af| %> - <%= af.inputs do %> - - - <% if question.option_based? %> - <% options = question.options.order("number") %> - - - <% if qformat.checkbox? %> - <%= af.input :options, - :as => :check_boxes, - :collection => options, - :label => false, - :input_html => { :disabled => :true } - %> - <% elsif qformat.multiselectbox? %> - <%= af.input :options, - :as => :select, - :collection => options, - :label => false, - :input_html => { :multiple => true , :disabled => :true } %> - <% elsif qformat.radiobuttons?%> -<%= _('Combine their changes with your answer below and then save the answer again.') %>
<%= _('The edits in the box below will overwrite the existing answer from ') + answer.user.name + _(' once you click save!')%>
<%= comments_label_with_count %>
+<%= comments_label_with_count %>
<% else %> -<%= _('Share note') %>
+<%= _('Share note') %>
<% end %><% if based_on.org != plan.template.org %> - <%= _('A version of ') %> "<%= based_on.title %>" <%= based_on.title.downcase.include?(_('template')) ? '' : _('template') %><%= _(' that has been customised by ') %> <%= plan.template.org.name %> + <%= _('A version of ') %> "<%= based_on.title %>" <%= based_on.title.downcase.include?(_('template')) ? '' : _('template') %><%= _(' that has been customised by ') %> <%= plan.template.org.name %>. <% else %> - <%= _('The')%> "<%= plan.template.title %>" <%= (plan.template.is_default ? _('generic template') : plan.template.title.downcase.include?(_('template')) ? '' : _('template')) %> <%= _(' provided by ') %><%= plan.template.org.name %> + <%= _('The')%> "<%= plan.template.title %>" <%= (plan.template.is_default ? _('generic template') : plan.template.title.downcase.include?(_('template')) ? '' : _('template')) %> <%= _(' provided by ') %><%= plan.template.org.name %>. <% end %>
@@ -231,6 +231,9 @@ <% phases = plan.template.phases %> <% if phases.count == 1 %> +