diff --git a/app/controllers/answers_controller.rb b/app/controllers/answers_controller.rb index 8ef2500..b590d41 100644 --- a/app/controllers/answers_controller.rb +++ b/app/controllers/answers_controller.rb @@ -9,42 +9,43 @@ ans_params = params[:answer] plan_id = ans_params[:plan_id] + phase_id = ans_params[:phase_id] user_id = ans_params[:user_id] + lock_version = ans_params[:lock_version] question_id = ans_params[:question_id] + @question = Question.find(question_id); @answer = Answer.find_by( plan_id: plan_id, user_id: user_id, question_id: question_id) + + @old_answer = nil + if @answer.nil? @answer = Answer.new(params[:answer]) + authorize @answer + @answer.save + else + # if you do the obvious clone here it will overwrite the old_answer text + # in the next line + #@old_answer = @answer.clone + @old_answer = Marshal::load(Marshal.dump(@answer)) + @answer.text = params["answer-text-#{@answer.question_id}".to_sym] + authorize @answer + @answer.update(params[:answer]) end - authorize @answer + respond_to do |format| + # pass new lock_version back to the client or they'll never save again + @lock_version = @answer.lock_version + @old_answer = nil + format.js {} + end -puts params.inspect - - @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 - end + rescue ActiveRecord::StaleObjectError + @lock_version = @old_answer.lock_version + respond_to do |format| + format.js {} + end + end end diff --git a/app/controllers/api/v0/base_controller.rb b/app/controllers/api/v0/base_controller.rb index 631983e..c8edddd 100644 --- a/app/controllers/api/v0/base_controller.rb +++ b/app/controllers/api/v0/base_controller.rb @@ -117,31 +117,9 @@ def render_bad_credentials self.headers['WWW-Authenticate'] = "Token realm=\"\"" - render json: I18n.t("api.bad_credentials"), status: 401 + render json: _("Bad Credentials"), status: 401 end - def has_auth (auth_type) - #auth = false - # not sure if initial if is necissary, but it works with it there... refactor later? - # if !TokenPermission.where(api_token: @token).nil? - # TokenPermission.where(api_token: @token).find_each do |permission| - # if permission.token_permission_type.token_type == auth_type - # auth = true - # logger.info "we have auth" - # end - # end - # end - - #OrgTokenPermission.where(org_id: @user.org_id).find_each do |org_token_permission| - # logger.debug "#{org_token_permission.token_permission_type.token_type}" - # if org_token_permission.token_permission_type.token_type == auth_type - # auth= true - # end - #end - #return auth - tpt = TokenPermissionType.find_by(token_type: auth) - org.token_permission_types.include?(tpt) - end end end diff --git a/app/controllers/api/v0/guidance_groups_controller.rb b/app/controllers/api/v0/guidance_groups_controller.rb index d300b39..1336f55 100644 --- a/app/controllers/api/v0/guidance_groups_controller.rb +++ b/app/controllers/api/v0/guidance_groups_controller.rb @@ -2,29 +2,22 @@ module V0 class GuidanceGroupsController < Api::V0::BaseController before_action :authenticate + #after_action :verify_authorized def show - # check if the user has permission to use the guidances api - if has_auth(constant("token_permission_types.guidances")) - # determine if they have authorization to view this guidance group - if GuidanceGroup.can_view?(@user, params[:id]) - respond_with get_resource - else - render json: I18n.t("api.bad_resource"), status: 401 - end - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 - end + @guidance_group = GuidanceGroup.find(params[:id]) + raise Pundit::NotAuthorizedError unless Api::V0::GuidanceGroupPolicy.new(@user, @guidance_group).show? + respond_with @guidance_group end def index - if has_auth(constant("token_permission_types.guidances")) - @all_viewable_groups = GuidanceGroup.all_viewable(@user) - respond_with @all_viewable_groups - else - #render unauthorised - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 - end + raise Pundit::NotAuthorizedError unless Api::V0::GuidanceGroupPolicy.new(@user, :guidance_group).index? + @all_viewable_groups = GuidanceGroup.all_viewable(@user) + respond_with @all_viewable_groups + end + + def pundit_user + return @user end diff --git a/app/controllers/api/v0/guidances_controller.rb b/app/controllers/api/v0/guidances_controller.rb index 2803ea6..b6866d2 100644 --- a/app/controllers/api/v0/guidances_controller.rb +++ b/app/controllers/api/v0/guidances_controller.rb @@ -2,51 +2,28 @@ module V0 class GuidancesController < Api::V0::BaseController before_action :authenticate + #after_action :verify_authorized - swagger_controller :guidances, 'Guidances' - - swagger_api :show do - summary 'Returns a single guidance item' - notes 'Notes...' - param :path, :id, :integer, :required, "Guidance Id" - param :header, 'Authentication-Token', :string, :required, 'Authentication-Token' - response :ok, "success", :Guidance - response :unauthorized - response :not_found - end - - # TODO: impliment auth on show/index - # for both, first validate that the user has the permission to use this api - # then for show, display iff they have permissions for that resource - # for index, compile the list of all groups they have permissions to view, then return - + ## + # returns the specified guidance def show - # ensure use has auth for guidances api - if has_auth("guidance") - if Guidance.can_view?(@user, params[:id]) - respond_with get_resource - else - render json: I18n.t("api.bad_resource"), status: 401 - end - else - render I18n.t("api.no_auth_for_endpoint"), status: 401 - end + @guidance = Guidance.find(params[:id]) + raise Pundit::NotAuthorizedError unless Api::V0::GuidancePolicy.new(@user, @guidance).show? + respond_with get_resource end - swagger_api :index do - summary 'Returns a list of all viewable guidances' - notes 'Notes...' - param :header, 'Authentication-Token', :string, :required, 'Authentication-Token' - response :unauthorized - end - + ## + # returns all guidances viewable to a user def index - if has_auth("guidance") - @all_viewable_guidances = Guidance.all_viewable(@user) - respond_with @all_viewable_guidances - else - render json I18n.t("api.no_auth_for_endpoint"), status: 401 - end + authorize Guidance + raise Pundit::NotAuthorizedError unless Api::V0::GuidancePolicy.new(@user, :guidance).index? + respond_with @all_viewable_guidances + end + + ## + # defines the default pundit user (overwrites current_user) + def pundit_user + @user end diff --git a/app/controllers/api/v0/plans_controller.rb b/app/controllers/api/v0/plans_controller.rb index c96d174..ac2f1b4 100644 --- a/app/controllers/api/v0/plans_controller.rb +++ b/app/controllers/api/v0/plans_controller.rb @@ -37,15 +37,15 @@ template = org.templates.find_by title: params[:template][:name] # else error: organization has more than one template and template name unspecified else - render json: I18n.t("api.org_multiple_templates"), status: 400 and return + render json: _('{"Error":"Organisation has more than one template and template name unspecified or invalid"}'), status: 400 and return end # else error: organization specified is not a funder else - render json: I18n.t("api.org_not_funder"), status: 400 and return + render json: _('{"Error":"Organisation specified is not a funder"}'), status: 400 and return end # else error: organization does not exist else - render json: I18n.t("api.org_dosent_exist"), status: 400 and return + render json: _('{"Error":"Organisation does not exist"}'), status: 400 and return end all_groups = [] @@ -90,7 +90,7 @@ end else - render json: I18n.t("api.no_auth_for_endpoint"), status: 400 and return + render json: _('{"Error":"You do not have authorisation to view this endpoint"}'), status: 400 and return end end diff --git a/app/controllers/api/v0/statistics_controller.rb b/app/controllers/api/v0/statistics_controller.rb index a09bec3..6ef0540 100644 --- a/app/controllers/api/v0/statistics_controller.rb +++ b/app/controllers/api/v0/statistics_controller.rb @@ -8,19 +8,16 @@ # @return a count of users who joined DMPonline between the optional specified dates # users are scoped to the organisation of the user initiating the call def users_joined - if has_auth(constant("token_permission_types.statistics")) - users = restrict_date_range(@user.org.users) - confirmed_users = [] - users.each do |user| - unless user.confirmed_at.blank? - confirmed_users += [user] - end + raise Pundit::NotAuthorizedError unless Api::V0::StatisticsPolicy.new(@user, :statistics).users_joined? + users = restrict_date_range(@user.org.users) + confirmed_users = [] + users.each do |user| + unless user.confirmed_at.blank? + confirmed_users += [user] end - @users_count = confirmed_users.count - respond_with @users_count - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 end + @users_count = confirmed_users.count + respond_with @users_count end @@ -29,17 +26,10 @@ # @return the number of DMPs using the specified template between the optional specified dates # ensures that the template is owned/created by the caller's organisation def using_template - if has_auth(constant("token_permission_types.statistics")) - template = Dmptemplate.find(params[:id]) - if template.org == @user.org - @template_count = restrict_date_range(template.plans).count - respond_with @template_count - else - #no auth to view statistics for this template - end - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 - end + template = Template.find(params[:id]) + raise Pundit::NotAuthorizedError unless Api::V0::StatisticsPolicy.new(@user, template).using_template? + @template_count = restrict_date_range(template.plans).count + respond_with @template_count end ## @@ -48,20 +38,17 @@ # the uses are restricted to DMPs created by users of the same organisation # as the user who ititiated the call def plans_by_template - if has_auth(constant("token_permission_types.statistics")) - @org_projects = [] - @user.org.users.each do |user| - user.plans.each do |plan| - unless @org_projects.include? plan - @org_projects += [plan] - end + raise Pundit::NotAuthorizedError unless Api::V0::StatisticsPolicy.new(@user, :statistics).plans_by_template? + @org_projects = [] + @user.org.users.each do |user| + user.plans.each do |plan| + unless @org_projects.include? plan + @org_projects += [plan] end end - @org_projects = restrict_date_range(@org_projects) - respond_with @org_projects - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 end + @org_projects = restrict_date_range(@org_projects) + respond_with @org_projects end ## @@ -70,20 +57,17 @@ # DMPs must be owned by a user who's organisation is the same as the user # who generates the call def plans - if has_auth(constant("token_permission_types.statistics")) - @org_projects = [] - @user.org.users.each do |user| - user.plans.each do |plan| - unless @org_projects.include? plan - @org_projects += [plan] - end + raise Pundit::NotAuthorizedError unless Api::V0::StatisticsPolicy.new(@user, :statistics).plans? + @org_plans = [] + @user.org.users.each do |user| + user.plans.each do |plan| + unless @org_plans.include? plan + @org_plans += [plan] end end - @org_projects = restrict_date_range(@org_projects) - respond_with @org_projects - else - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 end + @org_plans = restrict_date_range(@org_plans) + respond_with @org_plans end diff --git a/app/controllers/api/v0/templates_controller.rb b/app/controllers/api/v0/templates_controller.rb index 3ab1207..dfe78da 100644 --- a/app/controllers/api/v0/templates_controller.rb +++ b/app/controllers/api/v0/templates_controller.rb @@ -9,26 +9,21 @@ # @return a list of templates ordered by organisation def index # check if the user has permissions to use the templates API - if has_auth(constant("api_endpoint_types.templates")) - @org_templates = {} - published_templates = Template.includes(:org).where(customization_of: nil, published: true).order(:org_id, :version) - published_templates.all.each do |temp| - if @org_templates[temp.org].present? - if @org_templates[temp.org][temp.dmptemplate_id].nil? - @org_templates[temp.org][temp.dmptemplate_id] = temp - end - else - @org_templates[temp.org] = {} + raise Pundit::NotAuthorizedError unless Api::V0::TemplatePolicy.new(@user, :guidance_group).index? + @org_templates = {} + published_templates = Template.includes(:org).where(customization_of: nil, published: true).order(:org_id, :version) + published_templates.all.each do |temp| + if @org_templates[temp.org].present? + if @org_templates[temp.org][temp.dmptemplate_id].nil? @org_templates[temp.org][temp.dmptemplate_id] = temp end + else + @org_templates[temp.org] = {} + @org_templates[temp.org][temp.dmptemplate_id] = temp end - respond_with @org_templates - else - #render unauthorised - render json: I18n.t("api.no_auth_for_endpoint"), status: 401 end - - end + respond_with @org_templates + end end end end \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a02811c..d04b380 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,29 +14,24 @@ rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized def user_not_authorized - redirect_to root_url, alert: I18n.t('unauthorized') + redirect_to root_url, alert: _('You need to sign in or sign up before continuing.') end before_filter :set_gettext_locale after_filter :store_location + # Sets FastGettext locale for every request made def set_gettext_locale - if params[:locale] and FastGettext.default_available_locales.include?(params[:locale]) - FastGettext.locale = params[:locale] - elsif user_signed_in? and !current_user[:language_id].nil? - FastGettext.locale = Language.find_by_id(current_user[:language_id]).abbreviation #Relies on successful db call - elsif user_signed_in? and current_user.org.present? and !current_user.org[:language_id].nil? - FastGettext.locale = Language.find_by_id(current_user.org[:language_id]).abbreviation #Relies on successful db call - else - FastGettext.locale = FastGettext.default_locale - end - puts 'FastGettext.locale = '+FastGettext.locale + FastGettext.locale = session[:locale] || FastGettext.default_locale end - # Added setting for passing local params across pages - def default_url_options(options = {}) - { locale: I18n.locale }.merge options + # PATCH /locale/:locale REST method + def set_locale_session + if FastGettext.default_available_locales.include?(params[:locale]) + session[:locale] = params[:locale] + end + redirect_to root_path end def store_location diff --git a/app/controllers/guidance_groups_controller.rb b/app/controllers/guidance_groups_controller.rb index 3729dd7..585f32c 100644 --- a/app/controllers/guidance_groups_controller.rb +++ b/app/controllers/guidance_groups_controller.rb @@ -27,7 +27,7 @@ end if @guidance_group.save - redirect_to admin_index_guidance_path, notice: I18n.t('org_admin.guidance_group.created_message') + redirect_to admin_index_guidance_path, notice: _('Guidance group was successfully created.') else render action: "new" end @@ -48,7 +48,7 @@ @guidance_group.org_id = current_user.org_id if @guidance_group.update_attributes(params[:guidance_group]) - redirect_to admin_index_guidance_path(params[:guidance_group]), notice: I18n.t('org_admin.guidance_group.updated_message') + redirect_to admin_index_guidance_path(params[:guidance_group]), notice: _('Guidance group was successfully updated.') else render action: "edit" end @@ -63,7 +63,7 @@ @guidance_group.published = true if @guidance_group.update_attributes(params[:guidance_group]) - redirect_to admin_index_guidance_path(params[:guidance_group]), notice: I18n.t('org_admin.guidance_group.updated_message') + redirect_to admin_index_guidance_path(params[:guidance_group]), notice: _('Guidance group was successfully updated.') else render action: "edit" end @@ -77,7 +77,7 @@ authorize @guidance_group @guidance_group.destroy - redirect_to admin_index_guidance_path, notice: I18n.t('org_admin.guidance_group.destroyed_message') + redirect_to admin_index_guidance_path, notice: _('Guidance group was successfully deleted.') end end \ No newline at end of file diff --git a/app/controllers/guidances_controller.rb b/app/controllers/guidances_controller.rb index 75c0808..674e0f6 100644 --- a/app/controllers/guidances_controller.rb +++ b/app/controllers/guidances_controller.rb @@ -59,10 +59,10 @@ # updates phases, versions, sections and questions based on template selected dmptemplate = Template.find(params[:dmptemplate_id]) # map to title and id for use in our options_for_select - @phases = dmptemplate.phases.map{|a| [a.title, a.id]}.insert(0, I18n.t('helpers.select_phase')) - @versions = dmptemplate.versions.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_version')) - @sections = dmptemplate.sections.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_section')) - @questions = dmptemplate.questions.map{|s| [s.text, s.id]}.insert(0, I18n.t('helpers.select_question')) + @phases = dmptemplate.phases.map{|a| [a.title, a.id]}.insert(0, _('Select a phase')) + @versions = dmptemplate.versions.map{|s| [s.title, s.id]}.insert(0, _('Select a version')) + @sections = dmptemplate.sections.map{|s| [s.title, s.id]}.insert(0, _('Select a section')) + @questions = dmptemplate.questions.map{|s| [s.text, s.id]}.insert(0, _('Select a question')) end def update_versions @@ -70,9 +70,9 @@ # updates versions, sections and questions based on phase selected phase = Phase.find(params[:phase_id]) # map to name and id for use in our options_for_select - @versions = phase.versions.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_version')) - @sections = phase.sections.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_section')) - @questions = phase.questions.map{|s| [s.text, s.id]}.insert(0, I18n.t('helpers.select_question')) + @versions = phase.versions.map{|s| [s.title, s.id]}.insert(0, _('Select a version')) + @sections = phase.sections.map{|s| [s.title, s.id]}.insert(0, _('Select a section')) + @questions = phase.questions.map{|s| [s.text, s.id]}.insert(0, _('Select a question')) end def update_sections @@ -80,15 +80,15 @@ # updates sections and questions based on version selected version = Version.find(params[:version_id]) # map to name and id for use in our options_for_select - @sections = version.sections.map{|s| [s.title, s.id]}.insert(0, I18n.t('helpers.select_section')) - @questions = version.questions.map{|s| [s.text, s.id]}.insert(0, I18n.t('helpers.select_question')) + @sections = version.sections.map{|s| [s.title, s.id]}.insert(0, _('Select a section')) + @questions = version.questions.map{|s| [s.text, s.id]}.insert(0, _('Select a question')) end def update_questions authorize Guidance # updates songs based on artist selected section = Section.find(params[:section_id]) - @questions = section.questions.map{|s| [s.text, s.id]}.insert(0, I18n.t('helpers.select_question')) + @questions = section.questions.map{|s| [s.text, s.id]}.insert(0, _('Select a question')) end ## @@ -116,7 +116,7 @@ end if @guidance.save - redirect_to admin_show_guidance_path(@guidance), notice: I18n.t('org_admin.guidance.created_message') + redirect_to admin_show_guidance_path(@guidance), notice: _('Guidance was successfully created.') else render action: "new" end @@ -131,7 +131,7 @@ @guidance.question_id = params["question_id"] if @guidance.update_attributes(params[:guidance]) - redirect_to admin_show_guidance_path(params[:guidance]), notice: I18n.t('org_admin.guidance.updated_message') + redirect_to admin_show_guidance_path(params[:guidance]), notice: _('Guidance was successfully updated.') else render action: "edit" end diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index 8a400f6..40f5e32 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -32,7 +32,7 @@ if @note.save session[:question_id_notes] = answer.question_id - redirect_to edit_plan_phase_path(@plan, @phase), status: :found, notice: I18n.t("helpers.comments.note_created") + redirect_to edit_plan_phase_path(@plan, @phase), status: :found, notice: _('Comment was successfully created.') end end @@ -48,7 +48,7 @@ if @note.update_attributes(params[:note]) session[:question_id_notes] = @note.question_id - redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: I18n.t("helpers.comments.note_updated") + redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: _('Comment was successfully updated.') end end @@ -65,7 +65,7 @@ if @note.update_attributes(params[:note]) session[:question_id_notes] = @note.question_id - redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: I18n.t("helpers.comments.note_removed") + redirect_to edit_project_plan_path(@project, @plan), status: :found, notice: _('Comment has been removed.') end end end diff --git a/app/controllers/orgs_controller.rb b/app/controllers/orgs_controller.rb index 4b796cc..395f419 100644 --- a/app/controllers/orgs_controller.rb +++ b/app/controllers/orgs_controller.rb @@ -30,7 +30,7 @@ begin if @org.update_attributes(assign_params) - redirect_to admin_show_org_path(params[:id]), notice: I18n.t("admin.org_updated_message") + redirect_to admin_show_org_path(params[:id]), notice: _('Organisation was successfully updated.') else # For some reason our custom validator returns as a string and not a hash like normal activerecord # errors. We followed the example provided in the Rails guides when building the validator so @@ -41,7 +41,7 @@ render action: "admin_edit" end rescue Dragonfly::Job::Fetch::NotFound => dflye - flash[:notice] = I18n.t("admin.org_bad_logo") + flash[:notice] = _('There seems to be a problem with your logo. Please upload it again.') render action: "admin_edit" end end diff --git a/app/controllers/phases_controller.rb b/app/controllers/phases_controller.rb index b65f33f..2303795 100644 --- a/app/controllers/phases_controller.rb +++ b/app/controllers/phases_controller.rb @@ -3,31 +3,75 @@ after_action :verify_authorized - 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 - - # GET /plans/PLANID/phases/PHASEID/edit - def edit - - @textarea = TEXTAREA - @textfield = TEXTFIELD - @radio = RADIO - @checkbox = CHECKBOX - @dropdown = DROPDOWN - @multi = MULTI - @plan = Plan.find(params[:plan_id]) + # GET /plans/:plan_id/phases/:id/edit + def edit + + @plan = Plan.eager_load2(params[:plan_id]) authorize @plan - @plan_data = @plan.to_hash - phase_id = params[:id].to_i - @phase = Phase.find(phase_id) - @phase_data = @plan_data["template"]["phases"].select {|p| p["id"] == phase_id}.first + @phase = @plan.template.phases.select {|p| p.id == phase_id}.first + + # the eager_load pulls in ALL answers + # need to restrict to just ones for this plan + @plan.template.phases.each do |phase| + phase.sections do |section| + section.questions.each do |question| + question.answers = question.answers.to_a.select {|answer| answer.plan_id == @plan.id} + 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. + # + # Ultimately we are heading to a map from question id to theme to guidance. + # + # get the ids of the dynamically selected guidance groups + # and keep a map of them so we can extract the names later + guidance_groups_ids = @plan.plan_guidance_groups.select{|pgg| pgg.selected}.map{|pgg| pgg.guidance_group.id} + guidance_groups = GuidanceGroup.includes({guidances: :themes}).find(guidance_groups_ids) + + # create a map from theme to array of guidances + # where guidance is a hash with the text and the org name + theme_guidance = {} + + guidance_groups.each do |guidance_group| + guidance_group.guidances.each do |guidance| + guidance.themes.each do |theme| + title = theme.title + if !theme_guidance.has_key?(title) + theme_guidance[title] = Array.new + end + theme_guidance[title] << { + text: guidance.text, + org: guidance_group.name + } + end + end + end + + # create hash from question id to theme to guidance array + # so when we arerendering a question we can grab the guidance out of this + # + # question_guidance = { + # question.id => { + # theme => [ {text: "......", org: "....."} ] + # } + # } + @question_guidance = {} + @plan.questions.each do |question| + qg = {} + question.themes.each do |t| + title = t.title + qg[title] = theme_guidance[title] if theme_guidance.has_key?(title) + end + if !@question_guidance.has_key?(question.id) + @question_guidance[question.id] = Array.new + end + @question_guidance[question.id] = qg + end if !user_signed_in? then respond_to do |format| @@ -36,11 +80,11 @@ end end - - + + # GET /plans/PLANID/phases/PHASEID/status.json def status - @plan = Plan.find(params[:plan_id]) + @plan = Plan.eager_load(params[:plan_id]) authorize @plan if user_signed_in? && @plan.readable_by?(current_user.id) then respond_to do |format| @@ -52,4 +96,88 @@ end + + #show and edit a phase of the template + def admin_show + @phase = Phase.eager_load(params[:id]) + authorize @phase + @edit = params[:edit] == "true" ? true : false + #verify if there are any sections if not create one + @sections = @phase.sections + if !@sections.any?() || @sections.count == 0 + @section = @phase.sections.build + @section.phase = @phase + @section.title = '' + @section.number = 1 + @section.published = true + @section.modifiable = true + @section.save + @new_sec = true + end + #verify if section_id has been passed, if so then open that section + if params.has_key?(:section_id) + @open = true + @section_id = params[:section_id].to_i + end + if params.has_key?(:question_id) + @question_id = params[:question_id].to_i + end + end + + + #preview a phase + def admin_preview + @phase = Phase.find(params[:id]) + authorize @phase + @template = @phase.template + end + + + #add a new phase to a passed template + def admin_add + @template = Template.find(params[:id]) + @phase = Phase.new + phase.template = @template + authorize @phase + @phase.number = @template.phases.count + 1 + end + + + #create a phase + def admin_create + @phase = Phase.new(params[:phase]) + authorize @phase + @phase.description = params["phase-desc"] + @phase.modifiable = true + if @phase.save + redirect_to admin_show_phase_path(id: @phase.id, edit: 'true'), notice: _('Information was successfully created.') + else + render action: "admin_show" + end + end + + + #update a phase of a template + def admin_update + @phase = Phase.find(params[:id]) + authorize @phase + @phase.description = params["phase-desc"] + if @phase.update_attributes(params[:phase]) + redirect_to admin_show_phase_path(@phase), notice: _('Information was successfully updated.') + else + render action: "admin_show" + end + end + + #delete a phase + def admin_destroy + @phase = Phase.find(params[:phase_id]) + authorize @phase + @template = @phase.template + @phase.destroy + redirect_to admin_template_template_path(@template), notice: _('Information was successfully deleted.') + end + + + end diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index edae8f5..905ca3c 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -1,17 +1,12 @@ class PlansController < ApplicationController require 'pp' + helper SettingsTemplateHelper #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 # before_filter :get_plan_list_columns, only: %i( index ) after_action :verify_authorized - 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 @@ -83,7 +78,7 @@ @plan.principal_investigator = current_user.name - @plan.title = I18n.t('helpers.project.my_project_name')+' ('+@plan.template.title+')' + @plan.title = _('My plan')+' ('+@plan.template.title+')' # We should use interpolated string since the order of the words from this message could vary among languages @plan.assign_creator(current_user.id) @@ -95,9 +90,9 @@ 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')}) } + format.html { redirect_to({:action => "show", :id => @plan.id, :editing => true }, {:notice => _('Plan was successfully created.')}) } else - @error = "Something went wrong" + @error = "Something went wrong" format.html { render action: "new" } end end @@ -110,15 +105,13 @@ # GET /plans/show def show - @plan = Plan.find(params[:id]) + @plan = Plan.eager_load(params[:id]) authorize @plan - @plan_data = @plan.to_hash - @editing = params[:editing] && @plan.administerable_by?(current_user.id) @selected_guidance_groups = [] - all_guidance_groups = @plan_data["plan_guidance_groups"] - @selected_guidance_groups = all_guidance_groups.map{ |pgg| [ pgg["guidance_group"]["name"], pgg["guidance_group"]["id"], :checked => pgg["selected"] ] } + all_guidance_groups = @plan.plan_guidance_groups + @selected_guidance_groups = all_guidance_groups.map{ |pgg| [ pgg.guidance_group.name, pgg.guidance_group.id, :checked => pgg.selected ] } @selected_guidance_groups.sort! if user_signed_in? && @plan.readable_by?(current_user.id) then @@ -127,7 +120,7 @@ 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') } + format.html { redirect_to projects_url, notice: _('This account does not have access to that plan.') } end else respond_to do |format| @@ -148,12 +141,6 @@ # # GET /plans/1/edit def edit - @textarea = TEXTAREA - @textfield = TEXTFIELD - @radio = RADIO - @checkbox = CHECKBOX - @dropdown = DROPDOWN - @multi = MULTI @plan = Plan.find(params[:id]) @@ -170,7 +157,7 @@ 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') } + format.html { redirect_to projects_url, notice: _('This account does not have access to that plan.') } end end end @@ -183,7 +170,7 @@ 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.html { redirect_to @plan, :editing => false, notice: _('Plan was successfully updated.') } format.json { head :no_content } else format.html { render action: "edit" } @@ -225,7 +212,7 @@ end elsif !@plan.editable_by?(current_user.id) then respond_to do |format| - format.html { redirect_to plans_url, notice: I18n.t('helpers.settings.plans.errors.no_access_account') } + format.html { redirect_to plans_url, notice: _('This account does not have access to that plan.') } end end end @@ -406,7 +393,7 @@ 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') } + format.html { redirect_to projects_url, notice: _('This account does not have access to that plan.') } end end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 0a56bd7..80f7a59 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -9,7 +9,9 @@ ## 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 + flash.notice = ActionController::Base.helpers.link_to( + _('Link your %{application_name} account to your institutional credentials (UK users only)' % { :application_name => Rails.configuration.branding[:application][:name]}, + user_omniauth_shibboleth_path)).html_safe() end @projects = current_user.projects.filter(params[:filter]) @@ -40,7 +42,7 @@ 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') } + format.html { redirect_to projects_url, notice: _('This account does not have access to that plan.') } end else respond_to do |format| @@ -77,7 +79,7 @@ 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') } + format.html { redirect_to projects_url, notice: _('This account does not have access to that plan.') } end end end @@ -91,7 +93,7 @@ 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') } + format.html { redirect_to projects_url, notice: _('This account does not have access to that plan.') } end end end @@ -131,11 +133,11 @@ end @project.principal_investigator = current_user.name(false) - @project.title = I18n.t('helpers.project.my_project_name')+' ('+@project.dmptemplate.title+')' + @project.title = _('My plan')+' ('+@project.dmptemplate.title+')' # We should use interpolated string since the order of the words from this message could vary among languages @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')}) } + format.html { redirect_to({:action => "show", :id => @project.slug, :show_form => "yes"}, {:notice => _('Plan was successfully created.')}) } else format.html { render action: "new" } end @@ -153,7 +155,7 @@ 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: _('Plan was successfully updated.') }) } end else respond_to do |format| diff --git a/app/controllers/questions_controller.rb b/app/controllers/questions_controller.rb new file mode 100644 index 0000000..803479f --- /dev/null +++ b/app/controllers/questions_controller.rb @@ -0,0 +1,43 @@ +class QuestionsController < ApplicationController + respond_to :html + after_action :verify_authorized + + #create a question + def admin_create + @question = Question.new(params[:question]) + authorize @question + @question.guidance = params["new-question-guidance"] + @question.default_value = params["new-question-default-value"] + if @question.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 + render action: "phases/admin_show" + end + end + + #update a question of a template + def admin_update + @question = Question.find(params[:id]) + authorize @question + @question.guidance = params["question-guidance-#{params[:id]}"] + @question.default_value = params["question-default-value-#{params[:id]}"] + @section = @question.section + @phase = @section.phase + if @question.update_attributes(params[:question]) + 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 + render action: "phases/admin_show" + end + end + + #delete question + def admin_destroy + @question = Question.find(params[:question_id]) + authorize @question + @section = @question.section + @phase = @section.phase + @question.destroy + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id, edit: 'true'), notice: _('Information was successfully deleted.') + end + +end \ No newline at end of file diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 6f32f1f..b7b3d51 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -36,7 +36,7 @@ def create #logger.debug "#{sign_up_params}" if sign_up_params[:accept_terms] != "1" then - redirect_to after_sign_up_error_path_for(resource), alert: I18n.t('helpers.you_must_accept') + redirect_to after_sign_up_error_path_for(resource), alert: _('You must accept the terms and conditions to register.') else existing_user = User.find_by_email(sign_up_params[:email]) if !existing_user.nil? then @@ -44,7 +44,7 @@ @user = existing_user do_update(false, true) else - redirect_to after_sign_up_error_path_for(resource), alert: I18n.t('helpers.email_already_registered') + redirect_to after_sign_up_error_path_for(resource), alert: _('That email address is already registered.') end else build_resource(sign_up_params) @@ -60,7 +60,7 @@ end else clean_up_passwords resource - redirect_to after_sign_up_error_path_for(resource), alert: I18n.t('helpers.error_registration_check') + redirect_to after_sign_up_error_path_for(resource), alert: _('Error processing registration. Please check that you have entered a valid email address and that your chosen password is at least 8 characters long.') end end end @@ -69,12 +69,10 @@ def update if user_signed_in? then - @user = User.find(current_user.id) @orgs = Org.where(parent_id: nil).order("name") @other_organisations = Org.where(parent_id: nil, is_other: true).pluck(:id) - @languages = Language.order("name") @identifier_schemes = IdentifierScheme.where(active: true).order(:name) - + @languages = Language.sorted_by_abbreviation do_update else render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false) @@ -92,44 +90,34 @@ def do_update(require_password = true, confirm = false) if require_password then - successfully_updated = if needs_password?(@user, params) - @user.update_with_password(params[:user]) + successfully_updated = if needs_password?(current_user, params) + current_user.update_with_password(params[:user]) else # remove the virtual current_password attribute update_without_password # doesn't know how to ignore it params[:user].delete(:current_password) - @user.update_without_password(params[:user]) + current_user.update_without_password(params[:user]) end else - @user.update_attributes(password: params[:user][:password], password_confirmation: params[:user][:password_confirmation]) - successfully_updated = @user.update_without_password(params[:user]) - end - - # If the user selected a new language setting, go ahead and reset the locale - if params[:user][:language_id] - if @user.language_id != params[:user][:language_id] - params[:locale] = Language.find(params[:user][:language_id]).abbreviation - set_locale - end + current_user.update_attributes(password: params[:user][:password], password_confirmation: params[:user][:password_confirmation]) + successfully_updated = current_user.update_without_password(params[:user]) end #unlink shibboleth from user's details if params[:unlink_flag] == 'true' then - @user.update_attributes(shibboleth_id: "") + current_user.update_attributes(shibboleth_id: "") end if successfully_updated if confirm then - @user.skip_confirmation! - @user.save! + current_user.skip_confirmation! + current_user.save! end + session[:locale] = current_user.get_locale unless current_user.get_locale.nil? + set_gettext_locale #Method defined at controllers/application_controller.rb set_flash_message :notice, :updated - # Sign in the user bypassing validation in case his password changed - - sign_in @user, bypass_sign_in: true - - redirect_to({:controller => "registrations", :action => "edit"}, {:notice => I18n.t('helpers.project.details_update_success')}) - + sign_in current_user, bypass_sign_in: true # Sign in the user bypassing validation in case his password changed + redirect_to({:controller => "registrations", :action => "edit"}, {:notice => _('Details successfully updated.')}) else render "edit" end diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index d4e4072..8b2b71c 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -7,12 +7,12 @@ authorize @role @role.access_level = params[:role][:access_level].to_i if params[:role][:email].present? - message = I18n.t('helpers.project.user_added') + message = _('User added to project') if @role.save if @role.user.nil? then if User.find_by_email(params[:role][:email]).nil? then User.invite!(email: params[:role][:email]) - message = I18n.t('helpers.project.invitation_success') + message = _('Invitation issued successfully.') @role.user = User.find_by_email(params[:role][:email]) @role.save else @@ -29,7 +29,7 @@ render action: "new" end else - flash[:notice] = I18n.t('helpers.project.enter_email') + flash[:notice] = _('Please enter an email address') redirect_to controller: 'plans', action: 'share', id: @role.plan.slug end end @@ -39,7 +39,7 @@ authorize @role @role.access_level = params[:role][:access_level].to_i if @role.update_attributes(params[:role]) - flash[:notice] = I18n.t('helpers.project.sharing_updated') + flash[:notice] = _('Sharing details successfully updated.') UserMailer.permissions_change_notification(@role).deliver redirect_to controller: 'plans', action: 'share', id: @role.plan.slug else @@ -54,7 +54,7 @@ plan = @role.plan @role.destroy - flash[:notice] = I18n.t('helpers.project.access_removed') + flash[:notice] = _('Access removed') UserMailer.project_access_removed_notification(user, plan).deliver redirect_to controller: 'plans', action: 'share', id: @role.plan.slug end diff --git a/app/controllers/sections_controller.rb b/app/controllers/sections_controller.rb new file mode 100644 index 0000000..9670c84 --- /dev/null +++ b/app/controllers/sections_controller.rb @@ -0,0 +1,44 @@ +class SectionsController < ApplicationController + respond_to :html + after_action :verify_authorized + + #create a section + def admin_create + @section = Section.new(params[:section]) + authorize @section + @section.description = params["section-desc"] + @section.modifiable = true + @phase = section.phase + if @section.save + redirect_to admin_show_phase_template_path(id: @section.phase_id, + :section_id => @section.id, edit: 'true'), notice: _('Information was successfully created.') + else + render action: "phases/admin_show" + end + end + + + #update a section of a template + def admin_update + @section = Section.includes(phase: :template).find(params[:id]) + authorize @section + @section.description = params["section-desc-#{params[:id]}"] + @phase = @section.phase + if @section.update_attributes(params[:section]) + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id , edit: 'true'), notice: _('Information was successfully updated.') + else + render action: "phases/admin_show" + end + end + + + #delete a section and questions + def admin_destroy + @section = Section.includes(phase: :template).find(params[:section_id]) + authorize @section + @phase = @section.phase + @section.destroy + redirect_to admin_show_phase_path(id: @phase.id, edit: 'true' ), notice: _('Information was successfully deleted.') + end + +end \ No newline at end of file diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 89a5f44..06bdd83 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -16,13 +16,20 @@ # --------------------------------------------------------------------- def create existing_user = User.find_by(email: params[:user][:email]) - - if !existing_user.nil? && !params[:shibboleth_data].nil? then - #after authentication verify if session[:shibboleth] exists - existing_user.update_attributes(shibboleth_id: session[:shibboleth_data][:uid]) + if !existing_user.nil? + if !params[:shibboleth_data].nil? + #after authentication verify if session[:shibboleth] exists + existing_user.update_attributes(shibboleth_id: session[:shibboleth_data][:uid]) + end + session[:locale] = existing_user.get_locale unless existing_user.get_locale.nil? + set_gettext_locale #Method defined at controllers/application_controller.rb end - super end + def destroy + super + session[:locale] = nil + set_gettext_locale #Method defined at controllers/application_controller.rb + end end \ No newline at end of file diff --git a/app/controllers/static_pages_controller.rb b/app/controllers/static_pages_controller.rb index cded887..6f38009 100644 --- a/app/controllers/static_pages_controller.rb +++ b/app/controllers/static_pages_controller.rb @@ -13,61 +13,61 @@ end def roadmap + end - # GET /plans/publicly_available - # ----------------------------------------------------------- def public_plans - @plans = Plan.where(visibility: :publicly_visible).order(title: :asc) + @plans = Plan.publicly_visible end # GET /plans/[:plan_slug]/public_export # ------------------------------------------------------------- def public_export - @plan = Plan.find(params[:id]) + redirect_to public_plans_path, notice: _('Exporting public plan is under development. Apologies for any inconvience.') + #@plan = Plan.find(params[:id]) # Force PDF response - request.format = :pdf + #request.format = :pdf # if the project is designated as public - if @plan.visibility == :publicly_visible - if !@plan.nil? - @exported_plan = ExportedPlan.new.tap do |ep| - ep.plan = @plan - ep.user = current_user ||= nil - #ep.format = request.format.try(:symbol) - ep.format = request.format.to_sym - plan_settings = @plan.settings(:export) + #if @plan.visibility == :publicly_visible + # if !@plan.nil? + # @exported_plan = ExportedPlan.new.tap do |ep| + # ep.plan = @plan + # ep.user = current_user ||= nil + # #ep.format = request.format.try(:symbol) + # ep.format = request.format.to_sym + # 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.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 + # respond_to do |format| + # 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 - else + # else # the project has no plans for some reason - redirect_to public_plans_path, notice: I18n.t('helpers.settings.projects.errors.no_plan') - end - else + # redirect_to public_plans_path, notice: _('The plan is incomplete.') + # end + #else # Otherwise redirect to the home page with an unauthorized message - redirect_to public_plans_path, notice: I18n.t('helpers.settings.plans.errors.no_access_account') - end + # redirect_to public_plans_path, notice: _('This account does not have access to that plan.') + #end end end \ No newline at end of file diff --git a/app/controllers/suggested_answers_controller.rb b/app/controllers/suggested_answers_controller.rb new file mode 100644 index 0000000..bb53c6a --- /dev/null +++ b/app/controllers/suggested_answers_controller.rb @@ -0,0 +1,42 @@ +class SuggestedAnswersController < ApplicationController + respond_to :html + after_action :verify_authorized + + #create suggested answers + def admin_create + @suggested_answer = SuggestedAnswer.new(params[:suggested_answer]) + authorize @suggested_answer + if @suggested_answer.save + redirect_to admin_show_phase_path(id: @suggested_answer.question.section.phase_id, section_id: @suggested_answer.question.section_id, question_id: @suggested_answer.question.id, edit: 'true'), notice: _('Information was successfully created.') + else + render action: "phases/admin_show" + end + end + + + #update a suggested answer of a template + def admin_update + @suggested_answer = SuggestedAnswer.includes(question: { section: {phase: :template}}).find(params[:id]) + authorize @suggested_answer.question.section.phase.template + @question = @suggested_answer + @section = @question.section + @phase = @section.phase + if @suggested_answer.update_attributes(params[:suggested_answer]) + 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 + render action: "phases/admin_show" + end + end + + #delete a suggested answer + def admin_destroy + @suggested_answer = SuggestedAnswer.includes(question: { section: {phase: :template}}).find(params[:id]) + authorize @suggested_answer + @question = @suggested_answer.question + @section = @question.section + @phase = @section.phase + @suggested_answer.destroy + redirect_to admin_show_phase_path(id: @phase.id, section_id: @section.id, edit: 'true'), notice: _('Information was successfully deleted.') + end + +end \ No newline at end of file diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index 50f3c60..a0521c9 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -51,7 +51,8 @@ # GET /dmptemplates/1 def admin_template - @template = Template.find(params[:id]) + @template = Template.includes(:org, phases: [sections: [questions: [:question_options, :question_format, + :suggested_answers]]]).find(params[:id]) # check to see if this is a funder template needing customized if @template.org_id != current_user.org_id # definitely need to deep_copy the given template @@ -72,7 +73,7 @@ end end end - customizations = Template.includes(phases: [sections: [questions: :suggested_answers ]]).where(org_id: current_user.org_id, customization_of: @template.dmptemplate_id).order(version: :desc) + customizations = Template.includes(:org, phases: [sections: [questions: :suggested_answers ]]).where(org_id: current_user.org_id, customization_of: @template.dmptemplate_id).order(version: :desc) if customizations.present? # existing customization to port over max_version = customizations.first @@ -145,6 +146,8 @@ @template = new_version end authorize @template + # once the correct template has been generated, we convert it to hash + @hash = @template.to_hash end @@ -154,7 +157,7 @@ authorize @template if @template.published? # published templates cannot be edited - redirect_to admin_template_template_path(@template), notice: I18n.t('org_admin.templates.read_only') and return + redirect_to admin_template_template_path(@template), notice: _('Published templates cannot be edited.') and return end @template.description = params["template-desc"] if @template.update_attributes(params[:template]) @@ -165,7 +168,7 @@ new_version.published = false new_version.save! end - redirect_to admin_index_template_path(), notice: I18n.t('org_admin.templates.updated_message') + redirect_to admin_index_template_path(), notice: _('Information was successfully updated.') else render action: "edit" end @@ -192,8 +195,8 @@ break random unless Template.exists?(dmptemplate_id: random) end authorize @template - if @template.save - redirect_to admin_template_template_path(@template), notice: I18n.t('org_admin.templates.created_message') + if @template.save! + redirect_to admin_template_template_path(@template), notice: _('Information was successfully created.') else render action: "admin_new" end @@ -215,207 +218,4 @@ @templates = Template.where(dmptemplate_id: @template.dmptemplate_id).order(:version) end - - - # PHASES - - #show and edit a phase of the template - def admin_phase - @phase = Phase.find(params[:id]) - authorize @phase.template - @edit = params[:edit] == "true" ? true : false - #verify if there are any sections if not create one - @sections = @phase.sections - if !@sections.any?() || @sections.count == 0 - @section = @phase.sections.build - @section.phase = @phase - @section.title = '' - @section.number = 1 - @section.published = true - @section.modifiable = true - @section.save - @new_sec = true - end - #verify if section_id has been passed, if so then open that section - if params.has_key?(:section_id) - @open = true - @section_id = params[:section_id].to_i - end - if params.has_key?(:question_id) - @question_id = params[:question_id].to_i - end - end - - - #preview a phase - def admin_previewphase - @phase = Phase.find(params[:id]) - authorize @phase.template - @template = @phase.template - end - - - #add a new phase to a template - def admin_addphase - @template = Template.find(params[:id]) - @phase = Phase.new - authorize @template - @phase.number = @template.phases.count + 1 - end - - - #create a phase - def admin_createphase - @phase = Phase.new(params[:phase]) - authorize @phase.template - @phase.description = params["phase-desc"] - @phase.modifiable = true - if @phase.save - redirect_to admin_phase_template_path(id: @phase.id, edit: 'true'), notice: I18n.t('org_admin.templates.created_message') - else - render action: "admin_phase" - end - end - - - #update a phase of a template - def admin_updatephase - @phase = Phase.find(params[:id]) - authorize @phase.template - @phase.description = params["phase-desc"] - if @phase.update_attributes(params[:phase]) - redirect_to admin_phase_template_path(@phase), notice: I18n.t('org_admin.templates.updated_message') - else - render action: "admin_phase" - end - end - - #delete a phase - def admin_destroyphase - @phase = Phase.find(params[:phase_id]) - authorize @phase.template - @template = @phase.template - @phase.destroy - redirect_to admin_template_template_path(@template), notice: I18n.t('org_admin.templates.destroyed_message') - end - -# SECTIONS - #create a section - def admin_createsection - @section = Section.new(params[:section]) - authorize @section.phase.template - @section.description = params["section-desc"] - @section.modifiable = true - if @section.save - redirect_to admin_phase_template_path(id: @section.phase_id, - :section_id => @section.id, edit: 'true'), notice: I18n.t('org_admin.templates.created_message') - else - render action: "admin_phase" - end - end - - - #update a section of a template - def admin_updatesection - @section = Section.find(params[:id]) - authorize @section.phase.template - @section.description = params["section-desc-#{params[:id]}"] - @phase = @section.phase - if @section.update_attributes(params[:section]) - redirect_to admin_phase_template_path(id: @phase.id, section_id: @section.id , edit: 'true'), notice: I18n.t('org_admin.templates.updated_message') - else - render action: "admin_phase" - end - end - - - #delete a section and questions - def admin_destroysection - @section = Section.find(params[:section_id]) - authorize @section.phase.template - @phase = @section.phase - @section.destroy - redirect_to admin_phase_template_path(id: @phase.id, edit: 'true' ), notice: I18n.t('org_admin.templates.destroyed_message') - end - - -# QUESTIONS - - #create a question - def admin_createquestion - @question = Question.new(params[:question]) - authorize @question.section.phase.template - @question.guidance = params["new-question-guidance"] - @question.default_value = params["new-question-default-value"] - if @question.save! - redirect_to admin_phase_template_path(id: @question.section.phase_id, section_id: @question.section_id, question_id: @question.id, edit: 'true'), notice: I18n.t('org_admin.templates.created_message') - else - render action: "admin_phase" - end - end - - #update a question of a template - def admin_updatequestion - @question = Question.find(params[:id]) - authorize @question.section.phase.template - @question.guidance = params["question-guidance-#{params[:id]}"] - @question.default_value = params["question-default-value-#{params[:id]}"] - @section = @question.section - @phase = @section.phase - if @question.update_attributes(params[:question]) - redirect_to admin_phase_template_path(id: @phase.id, section_id: @section.id, question_id: @question.id, edit: 'true'), notice: I18n.t('org_admin.templates.updated_message') - else - render action: "admin_phase" - end - end - - #delete question - def admin_destroyquestion - @question = Question.find(params[:question_id]) - authorize @question.section.phase.template - @section = @question.section - @phase = @section.phase - @question.destroy - redirect_to admin_phase_template_path(id: @phase.id, section_id: @section.id, edit: 'true'), notice: I18n.t('org_admin.templates.destroyed_message') - end - - - #SUGGESTED ANSWERS - #create suggested answers - def admin_createsuggestedanswer - @suggested_answer = SuggestedAnswer.new(params[:suggested_answer]) - authorize @suggested_answer.question.section.phase.template - if @suggested_answer.save - redirect_to admin_phase_template_path(id: @suggested_answer.question.section.phase_id, section_id: @suggested_answer.question.section_id, question_id: @suggested_answer.question.id, edit: 'true'), notice: I18n.t('org_admin.templates.created_message') - else - render action: "admin_phase" - end - end - - - #update a suggested answer of a template - def admin_updatesuggestedanswer - @suggested_answer = SuggestedAnswer.find(params[:id]) - authorize @suggested_answer.question.section.phase.template - @question = @suggested_answer.question - @section = @question.section - @phase = @section.phase - if @suggested_answer.update_attributes(params[:suggested_answer]) - redirect_to admin_phase_template_path(id: @phase.id, section_id: @section.id, question_id: @question.id, edit: 'true'), notice: I18n.t('org_admin.templates.updated_message') - else - render action: "admin_phase" - end - end - - #delete a suggested answer - def admin_destroysuggestedanswer - @suggested_answer = SuggestedAnswer.find(params[:suggested_answer]) - authorize @suggested_answer.question.section.phase.template - @question = @suggested_answer.question - @section = @question.section - @phase = @section.phase - @suggested_answer.destroy - redirect_to admin_phase_template_path(id: @phase.id, section_id: @section.id, edit: 'true'), notice: I18n.t('org_admin.templates.destroyed_message') - end - end \ No newline at end of file diff --git a/app/controllers/user_identifiers_controller.rb b/app/controllers/user_identifiers_controller.rb index 040a50b..70297f5 100644 --- a/app/controllers/user_identifiers_controller.rb +++ b/app/controllers/user_identifiers_controller.rb @@ -12,7 +12,6 @@ identifier.destroy! flash[:notice] = t('identifier_schemes.disconnect_success', scheme: identifier.identifier_scheme.name) - else flash[:notice] = t('identifier_schemes.disconnect_failure', scheme: identifier.identifier_scheme.name) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6ca0cd7..98b9c59 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -18,12 +18,13 @@ @user = User.includes(:perms).find(params[:id]) authorize @user user_perms = current_user.perms - @perms = user_perms & Perm.where(name: [constant("user_role_types.change_org_details"),constant("user_role_types.use_api"), constant("user_role_types.modify_guidance"), constant("user_role_types.modify_templates"), constant("user_role_types.grant_permissions")]) + @perms = user_perms & [Perm::GRANT_PERMISSIONS, Perm::MODIFY_TEMPLATES, Perm::MODIFY_GUIDANCE, Perm::USE_API, Perm::CHANGE_ORG_DETAILS] end ## # POST - updates the permissions for a user # redirects to the admin_index action + # should add validation that the perms given are current perms of the current_user def admin_update_permissions @user = User.includes(:perms).find(params[:id]) authorize @user @@ -33,21 +34,21 @@ if @user.perms.include? perm if ! perms.include? perm @user.perms.delete(perm) - if perm.name == constant("user_role_types.use_api") + if perm.id == Perm::USE_API.id @user.remove_token! end end else if perms.include? perm @user.perms << perm - if perm.name == constant("user_role_types.use_api") + if perm.name == Perm::USE_API.id @user.keep_or_generate_token! end end end end @user.save! - redirect_to({controller: 'users', action: 'admin_index'}, {notice: I18n.t('helpers.success')}) + redirect_to({controller: 'users', action: 'admin_index'}, {notice: _('Information was successfully updated.')}) # helpers.success key does not exist, replaced with a generic string end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0d8de1a..8c37586 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -29,4 +29,5 @@ def isActivePage(path) return request.fullpath() == path end + end diff --git a/app/helpers/plans_helper.rb b/app/helpers/plans_helper.rb index 8cdd5d9..cf5a0c6 100644 --- a/app/helpers/plans_helper.rb +++ b/app/helpers/plans_helper.rb @@ -4,18 +4,18 @@ # -------------------------------------------------------- def plan_list_column_heading(column) if column.kind_of?(Array) - heading = (column.first.kind_of?(String) ? column.first : t("helpers.project.columns.unknown")) + heading = (column.first.kind_of?(String) ? column.first : _(' - ')) elsif column.kind_of?(String) heading = column else - heading = t("helpers.project.columns.unknown") + heading = _(' - ') end klass = (['name', 'description'].include?(heading) ? :dmp_th_big : :dmp_th_small) - content_tag(:th, t("helpers.project.columns.#{heading}"), class: klass) + content_tag(:th, t("helpers.project.columns.#{heading}"), class: klass) # parametrised YAML keys are no longer possible with gettext, TODO end # Populate a variable column for the project list @@ -26,15 +26,13 @@ klass, content = case col when 'name' - [ "dmp_td_big", link_to(plan.title, plan_path(I18n.locale, plan), class: "dmp_table_link") ] - + [ "dmp_td_big", link_to(plan.title, plan_path(plan), class: "dmp_table_link") ] when 'owner' user = plan.owner - text = if user.nil? - t("helpers.project.columns.unknown") + _(' - ') elsif user == current_user - t("helpers.me") + _('Me') else user.name end @@ -42,24 +40,32 @@ [ "tmp_td_small", text ] when 'shared' shared_num = plan.users.count - 1 - text = shared_num > 0 ? (t("helpers.yes_label") + " (with #{shared_num} people) ") : t("helpers.no_label") + text = shared_num > 0 ? (_('Yes') + " (with #{shared_num} people) ") : _('No') # Hardcoded strings are not internationalised [ "dmp_td_small", text ] when 'visibility' - ["dmp_td_small", (plan.visibility.nil? ? I18n.t("helpers.project.visibilities.labels.organisationally_visible") : I18n.t("helpers.project.visibilities.labels.#{plan.visibility}"))] + text = if plan.visibility == 'organisationally_visible' + _('Organisational') + elsif plan.visibility == 'publicly_visible' + _('Public') + elsif plan.visibility == 'is_test' + _('Test/Practice') + elsif plan.visibility == 'privately_visible' + _('Private') + end + ["dmp_td_small", text ] when 'last_edited' [ "dmp_td_small", l(plan.latest_update.to_date, formats: :short) ] when 'description' - [ "dmp_td_medium", (plan.try(col) || t("helpers.settings.unknown")) ] + [ "dmp_td_medium", (plan.try(col) || _(' - ')) ] when 'non_link_name' [ "dmp_td_big", plan.title ] when 'template' ["dmp_td_big", plan.template.title] when 'organisation' - ["dmp_td_medium", (plan.owner.org.nil? ? t("helpers.settings.unknown") : plan.owner.org.name) ] + ["dmp_td_medium", plan.template.org.name] # This will trigger 2 queries for each function call, i.e. one for templates and another for orgs tables else - [ "dmp_td_small", (plan.try(col) || t("helpers.settings.unknown")) ] + [ "dmp_td_small", (plan.try(col) || _(' - ')) ] end - content_tag(:td, content, class: klass) end diff --git a/app/helpers/settings_template_helper.rb b/app/helpers/settings_template_helper.rb new file mode 100644 index 0000000..255c95e --- /dev/null +++ b/app/helpers/settings_template_helper.rb @@ -0,0 +1,27 @@ +module SettingsTemplateHelper + # Retrieves an msgstr for a given admin_field + def admin_field_t(admin_field) + if Settings::Template::VALID_ADMIN_FIELDS.include?(admin_field) + if admin_field == 'project_name' + return _('Plan Name') + elsif admin_field == 'project_identifier' + return _('Plan ID') + elsif admin_field == 'grant_title' + return _('Grant number') + elsif admin_field == 'principal_investigator' + return _('Principal Investigator / Researcher') + elsif admin_field == 'project_data_contact' + return _('Plan Data Contact') + elsif admin_field == 'project_description' + return _('Plan Description') + elsif admin_field == 'funder' + return _('Funder') + elsif admin_field == 'institution' + return _('Institution') + elsif admin_field == 'orcid' + return _('Your ORCID') + end + end + return _('Unknown column name.') + end +end \ No newline at end of file diff --git a/app/models/answer.rb b/app/models/answer.rb index 35e0c2d..b84aeba 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -13,7 +13,7 @@ ## # Possibly needed for active_admin # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :text, :plan_id, :question_id, :user_id, :question_option_ids, + attr_accessible :text, :plan_id, :lock_version, :question_id, :user_id, :question_option_ids, :question, :user, :plan, :question_options, :notes, :note_ids, :as => [:default, :admin] diff --git a/app/models/exported_plan.rb b/app/models/exported_plan.rb index 4045298..ae52513 100644 --- a/app/models/exported_plan.rb +++ b/app/models/exported_plan.rb @@ -10,7 +10,12 @@ VALID_FORMATS = ['csv', 'html', 'json', 'pdf', 'text', 'xml', 'docx'] - validates :format, inclusion: { in: VALID_FORMATS, message: I18n.t('helpers.plan.export.not_valid_format') } + validates :format, inclusion: { + in: VALID_FORMATS, + message: -> (object, data) do + _('%{value} is not a valid format') % { :value => data[:value] } + end + } validates :plan, :format, presence: true # Store settings with the exported plan so it can be recreated later @@ -50,6 +55,10 @@ self.plan.description end + def owner + self.plan.roles.to_a.select{ |role| role.creator? }.first.user + end + def funder org = self.plan.template.try(:org) org.name if org.present? && org.funder? @@ -73,7 +82,7 @@ # sections taken from fields settings def sections # TODO: How do we know which phase to use here!? - sections = self.template.phases.first.sections + sections = self.plan.template.phases.first.sections return [] if questions.empty? @@ -124,7 +133,7 @@ answer = self.plan.answer(question.id, false) if answer.nil? || answer.text.nil? then - output += I18n.t('helpers.plan.export.pdf.question_not_answered')+ "\n" + output += _('Question not answered.')+ "\n" else output += answer.options.collect {|o| o.text}.join("\n") if question.option_comment_display == true then diff --git a/app/models/guidance.rb b/app/models/guidance.rb index 3b15e2a..26a83ff 100644 --- a/app/models/guidance.rb +++ b/app/models/guidance.rb @@ -91,7 +91,7 @@ unless guidance.nil? unless guidance.guidance_group.nil? - # guidances are viewable if they are owned by any of the user's organisations + # guidances are viewable if they are owned by the user's org if guidance.guidance_group.org == user.org viewable = true end @@ -99,14 +99,14 @@ if Org.managing_orgs.include?(guidance.guidance_group.org) viewable = true end - + # guidance groups are viewable if they are owned by a funder if Org.funders.include?(guidance.guidance_group.org) viewable = true end end end - + return viewable end @@ -120,24 +120,17 @@ # @param user [User] a user object # @return [Array] a list of all "viewable" guidances to a user def self.all_viewable(user) - managing_groups = Org.managing_orgs.collect{|o| o.guidance_groups} + managing_groups = Org.includes(guidance_groups: :guidances).managing_orgs.collect{|o| o.guidance_groups} # find all groups owned by a Funder organisation - funder_groups = [] - funders = Org.funders - funders.each do |funder| - funder_groups += funder.guidance_groups - end + funder_groups = Org.includes(guidance_groups: :guidances).funders.collect{|org| org.guidance_groups} # find all groups owned by any of the user's organisations organisation_groups = user.org.guidance_groups - + # find all guidances belonging to any of the viewable groups - all_viewable_guidances = [] - all_viewable_groups = managing_groups + funder_groups + organisation_groups - all_viewable_groups.flatten.each do |group| - all_viewable_guidances += group.guidances - end + all_viewable_groups = (managing_groups + funder_groups + organisation_groups).flatten + all_viewable_guidances = all_viewable_groups.collect{|group| group.guidances} # pass the list of viewable guidances to the view - return all_viewable_guidances + return all_viewable_guidances.flatten end end diff --git a/app/models/guidance_group.rb b/app/models/guidance_group.rb index 71535c3..9686c27 100644 --- a/app/models/guidance_group.rb +++ b/app/models/guidance_group.rb @@ -70,22 +70,20 @@ # @param id [Integer] the integer id for a guidance group # @param user [User] a user object # @return [Boolean] true if the specified user can view the specified guidance group, false otherwise - def self.can_view?(user, id) - guidance_group = GuidanceGroup.find_by(id: id) + def self.can_view?(user, guidance_group) viewable = false - # groups are viewable if they are owned by any of the user's organisations if guidance_group.org == user.org viewable = true end # groups are viewable if they are owned by the managing curation center - Org.where( name: GlobalHelpers.constant("organisation_types.managing_organisation")).find_each do |managing_group| + Org.managing_orgs.each do |managing_group| if guidance_group.org.id == managing_group.id viewable = true end end # groups are viewable if they are owned by a funder - if guidance_group.org.org_type == 2 + if guidance_group.org.funder? viewable = true end @@ -103,17 +101,11 @@ # @return [Array] a list of all "viewable" guidance groups to a user def self.all_viewable(user) # first find all groups owned by the Managing Curation Center - managing_org_groups = [] - Org.where(name: GlobalHelpers.constant("organisation_types.managing_organisation")).find_each do |managing_org| - managing_org_groups = managing_org_groups + managing_org.guidance_groups - end + managing_org_groups = Org.includes(:guidance_groups).managing_orgs.collect{|org| org.guidance_groups} # find all groups owned by a Funder organisation - funder_groups = [] - funders = Org.where(org_type: 2) - funders.each do |funder| - funder_groups = funder_groups + funder.guidance_groups - end + funder_groups = Org.includes(:guidance_groups).funders.collect{|org| org.guidance_groups} + organisation_groups = [user.org.guidance_groups] # pass this organisation guidance groups to the view with respond_with @all_viewable_groups diff --git a/app/models/language.rb b/app/models/language.rb index 0bb5a35..3e5e3bd 100644 --- a/app/models/language.rb +++ b/app/models/language.rb @@ -7,4 +7,7 @@ ## # Validations validates :abbreviation, presence: true, uniqueness: true + + scope :sorted_by_abbreviation, -> { all.order(:abbreviation) } + scope :default, -> { where(default_language: true).first } end \ No newline at end of file diff --git a/app/models/org.rb b/app/models/org.rb index 15dcd92..2696852 100644 --- a/app/models/org.rb +++ b/app/models/org.rb @@ -56,6 +56,15 @@ # # What do they do? do they do it efficiently, and do we need them? + # Determines the locale set for the organisation + # @return String or nil + def get_locale + if !self.language.nil? + return self.language.abbreviation + else + return nil + end + end # TODO: Should these be hardcoded? Also, an Org can currently be multiple org_types at one time. # For example you can do: funder = true; project = true; school = true diff --git a/app/models/perm.rb b/app/models/perm.rb index 114c0f0..0db316b 100644 --- a/app/models/perm.rb +++ b/app/models/perm.rb @@ -7,6 +7,17 @@ # Possibly needed for active_admin # -relies on protected_attributes gem as syntax depricated in rails 4.2 attr_accessible :name, :as => [:default, :admin] - + validates :name, presence: true, uniqueness: true + + ## + # Constant perms + ADD_ORGS = Perm.where(name: 'add_organisations').first.freeze + CHANGE_AFFILIATION = Perm.where(name: 'change_org_affiliation').first.freeze + GRANT_PERMISSIONS = Perm.where(name: 'grant_permissions').first.freeze + MODIFY_TEMPLATES = Perm.where(name: 'modify_templates').first.freeze + MODIFY_GUIDANCE = Perm.where(name: 'modify_guidance').first.freeze + USE_API = Perm.where(name: 'use_api').first.freeze + CHANGE_ORG_DETAILS = Perm.where(name: 'change_org_details').first.freeze + GRANT_API = Perm.where(name: 'grant_api_to_orgs').first.freeze end diff --git a/app/models/plan.rb b/app/models/plan.rb index a32b171..30ce215 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -17,6 +17,8 @@ has_many :exported_plans has_many :roles + + # COMMENTED OUT THE DIRECT CONNECTION HERE TO Users to prevent assignment of users without an access_level specified (currently defaults to creator) # has_many :users, through: :roles @@ -46,6 +48,10 @@ FONT_HEIGHT_CONVERSION_FACTOR = 0.35278 #convert font point size to mm FONT_WIDTH_HEIGHT_RATIO = 0.4 #Assume glyph width averages 2/5 the height + # Scope queries + # Note that in ActiveRecord::Enum the mappings are exposed through a class method with the pluralized attribute name (e.g visibilities rather than visibility) + scope :publicly_visible, -> { where(:visibility => visibilities[:publicly_visible]).order(:title => :asc) } + ## # Settings for the template has_settings :export, class_name: 'Settings::Template' do |s| @@ -247,65 +253,140 @@ ## # defines and returns the status of the plan # status consists of a hash of the num_questions, num_answers, sections, questions, and spaced used. - # For each section, it contains theid's of each of the questions + # For each section, it contains the id's of each of the questions # for each question, it contains the answer_id, answer_created_by, answer_text, answer_options_id, aand answered_by # # @return [Status] - def status - status = { - "num_questions" => 0, - "num_answers" => 0, - "sections" => {}, - "questions" => {}, - "space_used" => 0 # percentage of available space in pdf used - } - space_used = height_of_text(self.title, 2, 2) + def status + status = { + "num_questions" => 0, + "num_answers" => 0, + "sections" => {}, + "questions" => {}, + "space_used" => 0 # percentage of available space in pdf used + } - sections.each do |s| - space_used += height_of_text(s.title, 1, 1) - section_questions = 0 - section_answers = 0 - status["sections"][s.id] = {} - status["sections"][s.id]["questions"] = Array.new - s.questions.each do |q| - status["num_questions"] += 1 - section_questions += 1 - status["sections"][s.id]["questions"] << q.id - status["questions"][q.id] = {} - answer = answer(q.id, false) + space_used = height_of_text(self.title, 2, 2) - space_used += height_of_text(q.text) unless q.text == s.title - space_used += height_of_text(answer.try(:text) || I18n.t('helpers.plan.export.pdf.question_not_answered')) + section_ids = sections.map {|s| s.id} - if ! answer.nil? then - status["questions"][q.id] = { - "answer_id" => answer.id, - "answer_created_at" => answer.created_at.to_i, - "answer_text" => answer.text, - "answer_option_ids" => answer.question_options.pluck(:id), - "answered_by" => answer.user.name - } - q_format = q.question_format - status["num_answers"] += 1 if (q_format.title == I18n.t("helpers.checkbox") || q_format.title == I18n.t("helpers.multi_select_box") || - q_format.title == I18n.t("helpers.radio_buttons") || q_format.title == I18n.t("helpers.dropdown")) || answer.text.present? - section_answers += 1 - #TODO: include selected options in space estimate - else - status["questions"][q.id] = { - "answer_id" => nil, - "answer_created_at" => nil, - "answer_text" => nil, - "answer_option_ids" => nil, - "answered_by" => nil - } - end - status["sections"][s.id]["num_questions"] = section_questions - status["sections"][s.id]["num_answers"] = section_answers + # we retrieve this is 2 joins: + # 1. sections and questions + # 2. questions and answers + # why? because Rails 4 doesn't have any sensible left outer join. + # when we change to RAILS 5 it is meant to have so this can be fixed then + + records = Section.joins(questions: :question_format) + .select('sections.id as sectionid, + sections.title as stitle, + questions.id as questionid, + questions.text as questiontext, + question_formats.title as qformat') + .where("sections.id in (?) ", section_ids) + .to_a + + # extract question ids to get answers + question_ids = records.map {|r| r.questionid}.uniq + status["num_questions"] = question_ids.count + + arecords = Question.joins(answers: :user) + .select('questions.id as questionid, + answers.id as answerid, + answers.plan_id as plan_id, + answers.text as answertext, + answers.updated_at as updated, + users.email as username') + .where("questions.id in (?) and answers.plan_id = ?",question_ids, self.id) + .to_a + + # we want answerids to extract options later + answer_ids = arecords.map {|r| r.answerid}.uniq + status["num_answers"] = answer_ids.count + + # create map from questionid to answer structure + qa_map = {} + arecords.each do |rec| + qa_map[rec.questionid] = { + plan: rec.plan_id, + id: rec.answerid, + text: rec.answertext, + updated: rec.updated, + user: rec.username + } + end + + + # build main status structure + records.each do |rec| + sid = rec.sectionid + stitle = rec.stitle + qid = rec.questionid + qtext = rec.questiontext + format = rec.qformat + + answer = nil + if qa_map.has_key?(qid) + answer = qa_map[qid] end + + aid = answer.nil? ? nil : answer[:id] + atext = answer.nil? ? nil : answer[:text] + updated = answer.nil? ? nil : answer[:updated] + uname = answer.nil? ? nil : answer[:user] + + space_used += height_of_text(stitle, 1, 1) + + shash = status["sections"] + if !shash.has_key?(sid) + shash[sid] = {} + shash[sid]["num_questions"] = 0 + shash[sid]["num_answers"] = 0 + shash[sid]["questions"] = Array.new + end + + shash[sid]["questions"] << qid + shash[sid]["num_questions"] += 1 + + space_used += height_of_text(qtext) unless qtext == stitle + if atext.present? + space_used += height_of_text(atext) + else + space_used += height_of_text(_('Question not answered.')) + end + + if answer.present? then + shash[sid]["num_answers"] += 1 + end + + status["questions"][qid] = { + "format" => format, + "answer_id" => aid, + "answer_updated_at" => updated.to_i, + "answer_text" => atext, + "answered_by" => uname + } + + end + + records = Answer.joins(:question_options).select('answers.id as answerid, question_options.id as optid').where(id: answer_ids).to_a + opt_hash = {} + records.each do |rec| + aid = rec.answerid + optid = rec.optid + if !opt_hash.has_key?(aid) + opt_hash[aid] = Array.new + end + opt_hash[aid] << optid + end + + status["questions"].each_key do |questionid| + answerid = status["questions"][questionid]["answer_id"] + status["questions"][questionid]["answer_option_ids"] = opt_hash[answerid] end status['space_used'] = estimate_space_used(space_used) + return status end @@ -587,6 +668,7 @@ end end end +=end ## # returns the funder id for the plan @@ -598,7 +680,6 @@ end return self.template.org end -=end ## # returns the funder organisation for the project or nil if none is specified @@ -848,6 +929,10 @@ :plan_guidance_groups, :guidance_groups] ) + # serializable_hash only works over one level so we still need to go and extract + # the deeper levels and knit them in. + # + # want hash of questions by id to add in suggested answers and question_formats question_hash = {} plan_data["questions"].each do |q| @@ -856,40 +941,49 @@ question_ids = question_hash.keys + # pull out suggested answers suggested_answers = SuggestedAnswer.where(question_id: question_ids).where.not(text: '') suggested_answers.each do |sa| question_hash[sa.question_id]["suggested_answer"] = sa.serializable_hash end + # pull out question_formats qf_hash = {} QuestionFormat.all.each do |qf| qf_hash[qf.id] = qf.serializable_hash end + # add question _formats to questions question_hash.values.each do |q| q["question_format"] = qf_hash[q["question_format_id"]] end + # get the ids of the dynamically selected guidance groups + # and keep a map of them so we can extract the name later gg_ids = plan_data["plan_guidance_groups"].select{|pgg| pgg["selected"]}.map{|pgg| pgg["guidance_group_id"]} gg_hash = {} - - theme_guidance = {} - ggs = GuidanceGroup.find(gg_ids).each do |gg| gg_hash[gg.id] = gg.serializable_hash end - guidances = Guidance.joins(:themes).select('guidances.guidance_group_id, guidances.text, themes.title').where(guidance_group: gg_ids).to_a + # create a map from theme to array of guidances + theme_guidance = {} + guidances = Guidance.joins(:themes) + .select('guidances.guidance_group_id, guidances.text, themes.title') + .where(guidance_group: gg_ids) + .to_a + guidances.each do |g| title = g.title if !theme_guidance.has_key?(title) theme_guidance[title] = Array.new end - theme_guidance[title] << { - "text" => g.text, - "org" => gg_hash[g.guidance_group_id]["name"] - } + theme_guidance[title] << { + "text" => g.text, + "org" => gg_hash[g.guidance_group_id]["name"] + } end + # link the guidance to the questions plan_data["questions"].each do |q| qg = {} if q.has_key?("themes") @@ -907,6 +1001,35 @@ 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. + # TODO: revisit this and work out for sure that maintaining the difference is worthwhile. + # it may not be. Also make sure nether is doing more thanit needs to. + # + def self.eager_load(id) + Plan.includes( + [{template: [ + {phases: {sections: {questions: :answers}}}, + {customizations: :org} + ]}, + {plan_guidance_groups: {guidance_group: :guidances}} + ]).find(id) + end + + def self.eager_load2(id) + Plan.includes( + [{template: [ + {phases: {sections: {questions: [{answers: :notes}, :suggested_answers, :question_format, :themes]}}}, + {customizations: :org}, + :org + ]}, + {plan_guidance_groups: {guidance_group: {guidances: :themes}}}, + {questions: :themes} + ]).find(id) + end + + private @@ -930,6 +1053,7 @@ def fixup_hash(plan) # sort out guidance first so we can add it to the questions # before rolling up + # ghash = {} plan["guidance_groups"].map{|g| ghash[g["id"]] = g} plan["plan_guidance_groups"].each do |pgg| @@ -959,7 +1083,6 @@ section["nanswers"] = nanswers end end - end diff --git a/app/models/question.rb b/app/models/question.rb index 61eddd1..4c0efdc 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -44,6 +44,16 @@ "#{text}" end + + def option_based? + format = self.question_format + return format.option_based + end + + def plan_answers(plan_id) + return self.answers.to_a.select{|ans| ans.plan_id == plan_id} + end + ## # deep copy the given question and all it's associations # @@ -82,7 +92,7 @@ group.guidances.each do |g| g.themes.each do |theme| if theme_ids.include? theme.id - guidances["#{group.name} " + I18n.t('admin.guidance_lowercase_on') + " #{theme.title}"] = g + guidances["#{group.name} " + _('guidance on') + " #{theme.title}"] = g end end end diff --git a/app/models/question_format.rb b/app/models/question_format.rb index 7f1a900..3a08be8 100644 --- a/app/models/question_format.rb +++ b/app/models/question_format.rb @@ -3,6 +3,9 @@ ## # Associations has_many :questions + + enum formattype: [ :textarea, :textfield, :radiobuttons, :checkbox, :dropdown, :multiselectbox, :date ] + attr_accessible :formattype validates :title, presence: true, uniqueness: true @@ -11,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] + ## + # Define Bit Field Values so we can test a format without doing string comps + # Column type # EVALUATE CLASS AND INSTANCE METHODS BELOW # @@ -25,4 +31,4 @@ "#{title}" end -end \ No newline at end of file +end diff --git a/app/models/section.rb b/app/models/section.rb index 87e98b6..b88ee79 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -24,6 +24,14 @@ "#{title}" end + 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 + end + return n + end + ## # deep copy of the given section and all it's associations # diff --git a/app/models/settings/plan_list.rb b/app/models/settings/plan_list.rb index 26f6ed5..01d5c88 100644 --- a/app/models/settings/plan_list.rb +++ b/app/models/settings/plan_list.rb @@ -12,9 +12,9 @@ cols = value["columns"] if cols.present? # columns can be empty, in which case they revert to defaults - errors.add(:columns, I18n.t("helpers.settings.projects.errors.no_name")) unless cols.member?("name") - errors.add(:columns, I18n.t("helpers.settings.projects.errors.duplicate")) unless cols.keys.uniq == cols.keys - errors.add(:columns, I18n.t("helpers.settings.projects.errors.unknown")) unless (cols.keys.uniq & ALL_COLUMNS) == cols.keys.uniq + errors.add(:columns, _("'name' must be included in column list.")) unless cols.member?("name") + errors.add(:columns, _('Duplicate column name. Please only include each column once.')) unless cols.keys.uniq == cols.keys + errors.add(:columns, _('Unknown column name.')) unless (cols.keys.uniq & ALL_COLUMNS) == cols.keys.uniq end end end diff --git a/app/models/settings/template.rb b/app/models/settings/template.rb index 2956eac..59ac3de 100644 --- a/app/models/settings/template.rb +++ b/app/models/settings/template.rb @@ -59,13 +59,27 @@ end errs.map do |key| - errors.add(:formatting, I18n.t("helpers.settings.plans.errors.#{key}")) + if key == :missing_key + errors.add(:formatting, _('A required setting has not been provided')) + elsif key == :invalid_margin + errors.add(:formatting, _('Margin value is invalid')) + elsif key == :negative_margin + errors.add(:formatting, _('Margin cannot be negative')) + elsif key == :unknown_margin + errors.add(:formatting, _("Unknown margin. Can only be 'top', 'bottom', 'left' or 'right'")) + elsif key == :invalid_font_size + errors.add(:formatting, _('Invalid font size')) + elsif key == :invalid_font_face + errors.add(:formatting, _('Invalid font face')) + elsif key == :unknown_key + errors.add(:formatting, _('Unknown formatting setting')) + end end end if max_pages.present? && (!max_pages.is_a?(Integer) || max_pages <= 0) - errors.add(:max_pages, I18n.t('helpers.settings.plans.errors.invalid_max_pages')) + errors.add(:max_pages, _('Invalid maximum pages')) end end diff --git a/app/models/template.rb b/app/models/template.rb index 9c59637..16b7ac4 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -48,95 +48,47 @@ end ## - # takes a type or organisation and returns all published templates from - # organisations of that type + # convert the given template to a hash and return with all it's associations + # to use, please pre-fetch org, phases, section, questions, suggested_answers, + # question_options, question_formats, + # TODO: Themes & guidance? # - # @param ot [String] name of an organisation type e.g. founder - # @return [Array] list of published dmptemplates -=begin - def self.templates_org_type(ot) - # DISCUSS - This function other than the check for the template being published - # is a superclass for the below funders_templates - new_org_obejcts = OrganisationType.find_by( name: ot ).organisations - - org_templates = Array.new - new_org_obejcts.each do |neworg| - org_templates += neworg.dmptemplates.where("published = ?", true) + # @return [hash] hash of template, phases, sections, questions, question_options, suggested_answers + def to_hash + hash = {} + hash[:template] = {} + hash[:template][:data] = self + hash[:template][:org] = self.org + phases = {} + hash[:template][:phases] = phases + self.phases.each do |phase| + phases[phase.number] = {} + phases[phase.number][:data] = phase + phases[phase.number][:sections] = {} + phase.sections.each do |section| + phases[phase.number][:sections][section.number] = {} + phases[phase.number][:sections][section.number][:data] = section + phases[phase.number][:sections][section.number][:questions] = {} + section.questions.each do |question| + phases[phase.number][:sections][section.number][:questions][question.number] = {} + phases[phase.number][:sections][section.number][:questions][question.number][:data] = question + phases[phase.number][:sections][section.number][:questions][question.number][:suggested_answers] = {} + question.suggested_answers.each do |suggested_answer| + phases[phase.number][:sections][section.number][:questions][question.number][:suggested_answers][suggested_answer.id] = {} + phases[phase.number][:sections][section.number][:questions][question.number][:suggested_answers][suggested_answer.id][:data] = suggested_answer + end + phases[phase.number][:sections][section.number][:questions][question.number][:question_options] = {} + question.question_options.each do |question_option| + phases[phase.number][:sections][section.number][:questions][question.number][:question_options][:data] = question_option + phases[phase.number][:sections][section.number][:questions][question.number][:question_format] = question.question_format + end + end + end end - - return org_templates + return hash end - ## - # returns all templates from all organisations of the Organisation_Type funder - # - # @return [Array] all templates from funder organisations - def self.funders_templates - funder_orgs = Org.includes(:templates).funder - org_templates = Array.new - - funder_orgs.each do |neworg| - org_templates += neworg.templates - end - - return org_templates - end - - ## - # returns all institutional templates bellowing to the given organisation - # - # @param org_id [integer] the integer id for an organisation - # @return [Array] all templates from a user's organisation - def self.own_institutional_templates(org_id) - # DISCUSS - Why is this done by scanning organisation_id's from the templates - # yet all other calls are done by finding an organisation, and using the - # has_many relationship to find the dmptemplates? - # - A possible answer is that there may be deleted organisations which we are - # serching for templates for. - # - A standardised behavior on querries, wether through active reccord or the - # where, should maybe be thought of/decided upon - new_templates = self.where("org_id = ?", org_id) - return new_templates - end - - ## - # returns an array with all funders and of the given organisations's - # institutional templates - # - # @param org_id [integer] the integer id for an organisation - # @return [Array] all templates from the template's organisation - # or from a funder organisation - def self.funders_and_own_templates(org_id) - funders_templates = self.funders_templates - - #verify if org type is not a funder - current_org = Org.find(org_id) - if !current_org.funder? then - own_institutional_templates = self.own_institutional_templates(org_id) - else - own_institutional_templates = [] - end - - templates_list = Array.new - templates_list += own_institutional_templates - templates_list += funders_templates - templates_list = templates_list.sort_by { |f| f['title'].downcase } - - return templates_list - end - - ## - # Returns the string name of the organisation type of the organisation who - # owns this dmptemplate - # - # @return [string] the string name of an organisation type - def org_type - org_type = org.organisation_type - return org_type - end -=end - -# TODO: Why are we passing in an org and template here? +# TODO: Why are we passing in an org and template here? ## # Verify if a template has customisation by given organisation # @@ -149,33 +101,6 @@ modifiable = modifiable && phase.modifiable end return !modifiable - # if temp.org_id != org_id then - # temp.phases.each do |phase| - # phase.versions.each do |version| - # version.sections.each do |section| - # return true if section.organisation_id == org_id - # end - # end - # return false - # end - # else - # return false - # end end -=begin - ## - # verify if there are any publish version for the template - # - # @return [Boolean] true if there is a published version for the template - def has_published_versions? - phases.each do |phase| - return true if !phase.latest_published_version.nil? - end - return false - end -=end - - # OLD CODE STARTS HERE - end diff --git a/app/models/token_permission_type.rb b/app/models/token_permission_type.rb index 71f8186..71d4acb 100644 --- a/app/models/token_permission_type.rb +++ b/app/models/token_permission_type.rb @@ -14,11 +14,12 @@ # Validators validates :token_type, presence: true, uniqueness: true - - # EVALUATE CLASS AND INSTANCE METHODS BELOW - # - # What do they do? do they do it efficiently, and do we need them? - + ## + # Constant Token Permission Types + GUIDANCES = TokenPermissionType.where(token_type: 'guidances').first.freeze + PLANS = TokenPermissionType.where(token_type: 'plans').first.freeze + TEMPLATES = TokenPermissionType.where(token_type: 'templates').first.freeze + STATISTICS = TokenPermissionType.where(token_type: 'statistics').first.freeze ## diff --git a/app/models/user.rb b/app/models/user.rb index 4cf42a2..30f3699 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -59,6 +59,9 @@ s.key :plan_list, defaults: { columns: Settings::PlanList::DEFAULT_COLUMNS } end + ## + # Scopes + default_scope { includes(:org, :perms, :plans) } @@ -66,8 +69,17 @@ # # What do they do? do they do it efficiently, and do we need them? - - + # Determines the locale set for the user or the organisation he/she belongs + # @return String or nil + def get_locale + if !self.language.nil? + return self.language.abbreviation + elsif !self.org.nil? + return self.org.get_locale + else + return nil + end + end ## @@ -151,7 +163,7 @@ # # @return [Boolean] true if the user can add new organisations def can_add_orgs? - perms.include? Perm.find_by(name: constant("roles.add_organisations")) + perms.include? Perm::ADD_ORGS end ## @@ -159,7 +171,7 @@ # # @return [Boolean] true if the user can change their organisation affiliations def can_change_org? - perms.include? Perm.find_by(name: constant("roles.change_org_affiliation")) + perms.include? Perm::CHANGE_AFFILIATION end ## @@ -167,7 +179,7 @@ # # @return [Boolean] true if the user can grant their permissions to others def can_grant_permissions? - perms.include? Perm.find_by(name: constant("roles.grant_permissions")) + perms.include? Perm::GRANT_PERMISSIONS end ## @@ -175,7 +187,7 @@ # # @return [Boolean] true if the user can modify organisation templates def can_modify_templates? - perms.include? Perm.find_by(name: constant("roles.modify_templates")) + perms.include? Perm::MODIFY_TEMPLATES end ## @@ -183,7 +195,7 @@ # # @return [Boolean] true if the user can modify organistion guidance def can_modify_guidance? - perms.include? Perm.find_by(name: constant("roles.modify_guidance")) + perms.include? Perm::MODIFY_GUIDANCE end ## @@ -191,7 +203,7 @@ # # @return [Boolean] true if the user can use the api def can_use_api? - perms.include? Perm.find_by(name: constant("roles.use_api")) + perms.include? Perm::USE_API end ## @@ -199,7 +211,7 @@ # # @return [Boolean] true if the user can modify the org's details def can_modify_org_details? - perms.include? Perm.find_by(name: constant("roles.change_org_details")) + perms.include? Perm::CHANGE_ORG_DETAILS end @@ -208,7 +220,7 @@ # # @return [Boolean] true if the user can grant api permissions to organisations def can_grant_api_to_orgs? - perms.include? Perm.find_by(name: constant('roles.grant_api_to_orgs')) + perms.include? Perm::GRANT_API end ## diff --git a/app/policies/api/v0/guidance_group_policy.rb b/app/policies/api/v0/guidance_group_policy.rb new file mode 100644 index 0000000..1ea52f4 --- /dev/null +++ b/app/policies/api/v0/guidance_group_policy.rb @@ -0,0 +1,29 @@ +module Api + module V0 + class GuidanceGroupPolicy < ApplicationPolicy + attr_reader :user, :guidance_group + + def initialize(user, guidance_group) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + unless user.org.token_permission_types.include? TokenPermissionType::GUIDANCES + raise Pundit::NotAuthorizedError, _("must have access to guidances api") + end + @user = user + @guidance_group = guidance_group + end + + ## + # is the plan editable by the user + def show? + GuidanceGroup.can_view?(@user, @guidance_group) + end + + ## + # always allowed as index chooses which guidances to display + def index? + true + end + + end + end +end \ No newline at end of file diff --git a/app/policies/api/v0/guidance_policy.rb b/app/policies/api/v0/guidance_policy.rb new file mode 100644 index 0000000..fd17c4e --- /dev/null +++ b/app/policies/api/v0/guidance_policy.rb @@ -0,0 +1,29 @@ +module Api + module V0 + class GuidancePolicy < ApplicationPolicy + attr_reader :user + attr_reader :guidance + + def initialize(user, guidance) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + unless user.org.token_permission_types.include? TokenPermissionType::GUIDANCES + raise Pundit::NotAuthorizedError, _("must have access to guidances api") + end + @user = user + @guidance = guidance + end + + ## + # is the plan editable by the user + def show? + Guidance.can_view(@user, @guidance.id) + end + + ## + # always allowed as index chooses which guidances to display + def index? + true + end + end + end +end \ No newline at end of file diff --git a/app/policies/api/v0/statistics_policy.rb b/app/policies/api/v0/statistics_policy.rb new file mode 100644 index 0000000..155a3da --- /dev/null +++ b/app/policies/api/v0/statistics_policy.rb @@ -0,0 +1,41 @@ +module Api + module V0 + class StatisticsPolicy < ApplicationPolicy + attr_reader :user + + def initialize(user, statistic) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + unless user.org.token_permission_types.include? TokenPermissionType::STATISTICS + raise Pundit::NotAuthorizedError, _("must have access to guidances api") + end + @user = user + @statistic = statistic + end + + ## + # always allowed to see how many users joined your org within a date range + def users_joined? + true + end + + ## + # need to check if your org owns this template + def using_template? + @statistic.org_id == @user.org_id + end + + ## + # always allowed to get plans by template + def plans_by_template? + true + end + + ## + # always allowed to get plans + def plans? + true + end + + end + end +end \ No newline at end of file diff --git a/app/policies/api/v0/template_policy.rb b/app/policies/api/v0/template_policy.rb new file mode 100644 index 0000000..7ec770b --- /dev/null +++ b/app/policies/api/v0/template_policy.rb @@ -0,0 +1,23 @@ +module Api + module V0 + class TemplatePolicy < ApplicationPolicy + attr_reader :user, :template + + def initialize(user, template) + raise Pundit::NotAuthorizedError, _("must be logged in") unless user + unless user.org.token_permission_types.include? TokenPermissionType::TEMPLATES + raise Pundit::NotAuthorizedError, _("must have access to guidances api") + end + @user = user + @template = template + end + + ## + # always allowed as index chooses which guidances to display + def index? + true + end + + end + end +end \ No newline at end of file diff --git a/app/policies/phase_policy.rb b/app/policies/phase_policy.rb new file mode 100644 index 0000000..5d43a7e --- /dev/null +++ b/app/policies/phase_policy.rb @@ -0,0 +1,40 @@ +class PhasePolicy < ApplicationPolicy + attr_reader :user, :phase + + def initialize(user, phase) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @phase = phase + end + + ## + # Users can modify phases if: + # - They can modify templates + # - The template which they are modifying belongs to their org + ## + + def admin_show? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_preview? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_update? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_add? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_create? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + + def admin_destroy? + user.can_modify_templates? && (phase.template.org_id == user.org_id) + end + +end \ No newline at end of file diff --git a/app/policies/question_policy.rb b/app/policies/question_policy.rb new file mode 100644 index 0000000..5ea487c --- /dev/null +++ b/app/policies/question_policy.rb @@ -0,0 +1,28 @@ +class QuestionPolicy < ApplicationPolicy + attr_reader :user, :question + + def initialize(user, question) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @question = question + end + + ## + # Users can modify questions if: + # - They can modify templates + # - The template which they are modifying belongs to their org + ## + + def admin_create? + user.can_modify_templates? && (question.section.phase.template.org_id == user.org_id) + end + + def admin_update? + user.can_modify_templates? && (question.section.phase.template.org_id == user.org_id) + end + + def admin_destroy? + user.can_modify_templates? && (question.section.phase.template.org_id == user.org_id) + end + +end \ No newline at end of file diff --git a/app/policies/section_policy.rb b/app/policies/section_policy.rb new file mode 100644 index 0000000..6effdbe --- /dev/null +++ b/app/policies/section_policy.rb @@ -0,0 +1,28 @@ +class SectionPolicy < ApplicationPolicy + attr_reader :user, :section + + def initialize(user, section) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @section = section + end + + ## + # Users can modify sections if: + # - They can modify templates + # - The template which they are modifying belongs to their org + ## + + def admin_create? + user.can_modify_templates? && (section.phase.template.org_id == user.org_id) + end + + def admin_update? + user.can_modify_templates? && (section.phase.template.org_id == user.org_id) + end + + def admin_destroy? + user.can_modify_templates? && (section.phase.template.org_id == user.org_id) + end + +end \ No newline at end of file diff --git a/app/policies/suggested_answer_policy.rb b/app/policies/suggested_answer_policy.rb new file mode 100644 index 0000000..e6cd49c --- /dev/null +++ b/app/policies/suggested_answer_policy.rb @@ -0,0 +1,28 @@ +class SuggestedAnswerPolicy < ApplicationPolicy + attr_reader :user, :suggested_answer + + def initialize(user, suggested_answer) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @suggested_answer = suggested_answer + end + + ## + # Users can modify suggested answers if: + # - They can modify templates + # - The template which they are modifying belongs to their org + ## + + def admin_create? + user.can_modify_templates? && (suggested_answer.question.section.phase.template.org_id == user.org_id) + end + + def admin_update? + user.can_modify_templates? && (suggested_answer.question.section.phase.template.org_id == user.org_id) + end + + def admin_destroy? + user.can_modify_templates? && (suggested_answer.question.section.phase.template.org_id == user.org_id) + end + +end \ No newline at end of file diff --git a/app/policies/template_policy.rb b/app/policies/template_policy.rb index 1fd64f5..41e1f7c 100644 --- a/app/policies/template_policy.rb +++ b/app/policies/template_policy.rb @@ -7,6 +7,12 @@ @template = template end + ## + # Users can modify templates if: + # - They can modify templates + # - The template which they are modifying belongs to their org + ## + def admin_index? user.can_modify_templates? end @@ -35,89 +41,6 @@ user.can_modify_templates? && (template.org_id == user.org_id) end - def admin_phase? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_previewphase? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_addphase? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_createphase? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_updatephase? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_destroyphase? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_updateversion? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_cloneversion? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_destroyversion? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_createsection? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_updatesection? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_destroysection? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_createquestion? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_updatequestion? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_destroyquestion? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_createsuggestedanswer? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_updatesuggestedanswer? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_destroysuggestedanswer? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_createguidance? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_updateguidance? - user.can_modify_templates? && (template.org_id == user.org_id) - end - - def admin_destroyguidance? - user.can_modify_templates? && (template.org_id == user.org_id) - end class Scope < Scope def resolve diff --git a/app/views/admin/dmptemplates/settings.html.erb b/app/views/admin/dmptemplates/settings.html.erb index c955083..df9557e 100644 --- a/app/views/admin/dmptemplates/settings.html.erb +++ b/app/views/admin/dmptemplates/settings.html.erb @@ -13,10 +13,14 @@
  • <%= f.label(_('Margin')) %> - <% ["top", "bottom", "left", "right"].each do |pos| %> - <%= t("helpers.settings.plans.margins.#{pos}") -%> - <%= select_tag("settings[export][formatting][margin][#{pos}]", options_for_select((0..100).to_a, @settings.formatting[:margin][pos])) %> - <% end %> + <%= _('Top') -%> + <%= select_tag("settings[export][formatting][margin][top]", options_for_select((0..100).to_a, @settings.formatting[:margin][:top])) %> + <%= _('Bottom') -%> + <%= select_tag("settings[export][formatting][margin][bottom]", options_for_select((0..100).to_a, @settings.formatting[:margin][:bottom])) %> + <%= _('Left') -%> + <%= select_tag("settings[export][formatting][margin][left]", options_for_select((0..100).to_a, @settings.formatting[:margin][:left])) %> + <%= _('Right') -%> + <%= select_tag("settings[export][formatting][margin][right]", options_for_select((0..100).to_a, @settings.formatting[:margin][:right])) %>
  • diff --git a/app/views/answers/update.js.erb b/app/views/answers/update.js.erb new file mode 100644 index 0000000..1ffdc73 --- /dev/null +++ b/app/views/answers/update.js.erb @@ -0,0 +1,22 @@ +// after saving the answer (and possibly getting a conflict) +// set the message div about the answer. +// On success this will be "" on error it will be the +// conflicting answer + +//$("#answer_notice").html("<%= raw @message %>"); + +<%if @message %> + $("#answer_notice-<%=@question.id%>").html(<%= @message %>) %>"); +<% end %> + +<% if @old_answer %> + $("#answer_notice_<%=@question.id%>").html("<%= escape_javascript(render partial: '/phases/answer', locals: { question: @question, answer: @old_answer}) %>"); +<% else %> + $("#answer_notice_<%=@question.id%>").html(""); +<% end %> + +// have to update the lock_version on success or failure +// so that the next save can work. If you don't do +// this it will fail forever. + +$("#answer_lock_version").val(<%= @lock_version %>); diff --git a/app/views/api/v0/guidance_groups/index.json.jbuilder b/app/views/api/v0/guidance_groups/index.json.jbuilder index 908b19d..8d283d3 100644 --- a/app/views/api/v0/guidance_groups/index.json.jbuilder +++ b/app/views/api/v0/guidance_groups/index.json.jbuilder @@ -5,17 +5,6 @@ json.name guidance_group.name json.id guidance_group.id - # for each template associated with the guidance group, list the template name - @templates = guidance_group.dmptemplates - # if the template is empty, instead use all avalable templates - if @templates.empty? - @templates = Dmptemplate.all - end - json.templates @templates do |template| - json.title template.title - json.id template.id - end - json.optional guidance_group.optional_subset json.updated guidance_group.updated_at end diff --git a/app/views/api/v0/guidance_groups/show.json.jbuilder b/app/views/api/v0/guidance_groups/show.json.jbuilder index 1a412db..d1b0a2e 100644 --- a/app/views/api/v0/guidance_groups/show.json.jbuilder +++ b/app/views/api/v0/guidance_groups/show.json.jbuilder @@ -5,17 +5,6 @@ json.name @guidance_group.name json.id @guidance_group.id - # for each template associated with the guidance group, list the template name - @templates = @guidance_group.dmptemplates - # if the template is empty, instead use all avalable templates - if @templates.empty? - @templates = Dmptemplate.all - end - json.templates @templates do |template| - json.title template.title - json.id template.id - end - json.guidances @guidance_group.guidances do |guidance| json.text guidance.text json.id guidance.id diff --git a/app/views/api/v0/guidances/index.json.jbuilder b/app/views/api/v0/guidances/index.json.jbuilder index 82edd20..ac98f0a 100644 --- a/app/views/api/v0/guidances/index.json.jbuilder +++ b/app/views/api/v0/guidances/index.json.jbuilder @@ -8,22 +8,15 @@ json.updated_at guidance.updated_at # each guidance may be associated with many guidance groups - @guidance_groups = guidance.guidance_groups - json.guidance_groups @guidance_groups do |guidance_group| - json.name guidance_group.name - json.id guidance_group.id + guidance_group = guidance.guidance_group + unless guidance_group.nil? + json.guidance_group do + json.name guidance_group.name + json.id guidance_group.id - # for each template associated with the guidance group, list the template name - @templates = guidance_group.dmptemplates - # if the template is empty, instead use all avalable templates - if @templates.empty? - @templates = Dmptemplate.all + json.optional guidance_group.optional_subset + json.updated guidance_group.updated_at end - json.templates @templates do |template| - json.title template.title - end - json.optional guidance_group.optional_subset - json.updated guidance_group.updated_at end end diff --git a/app/views/api/v0/guidances/show.json.jbuilder b/app/views/api/v0/guidances/show.json.jbuilder index be04df7..67d3385 100644 --- a/app/views/api/v0/guidances/show.json.jbuilder +++ b/app/views/api/v0/guidances/show.json.jbuilder @@ -7,22 +7,14 @@ json.text @guidance.text json.updated_at @guidance.updated_at - # each guidance may be associated with many guidance groups - @guidance_groups = @guidance.guidance_groups - unless @guidance_groups.empty? - json.guidance_groups @guidance_groups do |guidance_group| + # each guidance may be associated with one guidance group + guidance_group = @guidance.guidance_group + + unless guidance_group.nil? + json.guidance_group do json.name guidance_group.name json.id guidance_group.id - # for each template associated with the guidance group, list the template name - @templates = guidance_group.dmptemplates - # if the template is empty, instead use all avalable templates - if @templates.empty? - @templates = Dmptemplate.all - end - json.templates @templates do |template| - json.title template.title - end json.optional guidance_group.optional_subset json.updated guidance_group.updated_at end diff --git a/app/views/api/v0/statistics/plans.json.jbuilder b/app/views/api/v0/statistics/plans.json.jbuilder index fe85ca8..a2ca5c1 100644 --- a/app/views/api/v0/statistics/plans.json.jbuilder +++ b/app/views/api/v0/statistics/plans.json.jbuilder @@ -1,9 +1,9 @@ json.prettify! -json.plans @org_projects.each do |plan| +json.plans @org_plans.each do |plan| json.id plan.id json.grant_number plan.grant_number - json.org_id plan.creator.org.id + json.org_id plan.owner.org.id json.template do json.title plan.template.title json.id plan.template.id @@ -12,7 +12,7 @@ json.title plan.title end json.funder do - json.name (plan.template.org.funder? ? plan.org.name : '') + json.name (plan.template.org.funder? ? plan.template.org.name : '') end json.principal_investigator do json.name plan.principal_investigator diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index ae0c08c..71f1e7b 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -1,6 +1,5 @@ -

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

    - -<%= raw t("helpers.user_details_text_html") %> +

    <%= _('Edit profile') %>

    +<%= raw _('

    Please note that your email address is used as your username. If you change this, remember to use your new email address on sign in.

    ') %>
    <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {method: :put}) do |f| %> @@ -8,55 +7,57 @@
    -

    <%= raw t("helpers.user_details_paragraph_html") %>

    +

    <%= raw _('You can edit any of the details below.') %>

    - + - + + "title" => _('Please enter your first name.') %> - + + "title" => _('Please enter your surname or family name.') %> - + "> - + + class: "text_field has-tooltip reg-input", "data-toggle" => "tooltip", "data-container" => "body", "title" => _('Please enter the name of your organisation.') %> - + @@ -74,12 +75,12 @@ <% unless @user.api_token.blank? %> - + - - + + <% end %>
    <%= (t("helpers.email") + " *") %><%= (_('Email') + " *") %> <%= f.email_field :email, as: :email %>
    <%= t("helpers.first_name") %><%= _('First name') %> <%= f.text_field :firstname, as: :string, id: "first_time_login_firstname", autofocus: true, class: "text_field has-tooltip", "data-toggle" => "tooltip", "data-trigger" => "focus" , - "title" => t("helpers.first_name_help_text") %>
    <%= t("helpers.last_name") %><%= _('Last name') %> <%= f.text_field :surname, as: :string, id: "first_time_login_surname", class: "text_field has-tooltip", "data-toggle" => "tooltip", "data-trigger" => "focus" , - "title" => t("helpers.surname_help_text") %>
    <%= t("helpers.org_type.organisation") %><%= _('Organisation') %> <%= collection_select(:user, :org_id, @orgs, - :id, :name, {include_blank: constant("organisation_types.organisation")}, + :id, :name, {include_blank: _('Select Organisation')}, { class: "typeahead org_sign_up" }) %>
    <%= t('helpers.user_details_language') %><%= _('Language') %> + <% locale = current_user.get_locale(); %> -
    <%= t("helpers.api_token") %><%= _('API token') %> <%= @user.api_token %>
    <%= t("helpers.api_info") %><%= link_to( t("helpers.api_use"), controller: "token_permission_types", action: "index")%><%= _('API Information') %><%= link_to( _('How to use the API'), controller: "token_permission_types", action: "index")%>
    @@ -87,11 +88,11 @@

    <% if Rails.application.config.shibboleth_enabled %> <% if resource.shibboleth_id.nil? || resource.shibboleth_id.length == 0 then %> - <%= link_to t("helpers.shibboleth_to_link_text"), user_omniauth_shibboleth_path, class: "a-orange" %> + <%= link_to _('Link your %{application_name} account to your institutional credentials (UK users only)') % { :application_name => user_omniauth_shibboleth_path }, class: "a-orange" %> <% else %> - <%= t("helpers.shibboleth_linked_text") %> + <%= _('Your account is linked to your institutional credentials.') %> - <%= t("helpers.shibboleth_unlink_label")%> + <%= _('Unlink your institutional credentials')%> <% end %> <% end %> @@ -100,31 +101,31 @@

    - <%= raw t("helpers.edit_password_info")%> + <%= _('If you would like to change your password please complete the following fields.') %>

    <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
    <%= t('custom_devise.waiting_for_confirmation') %><%= resource.unconfirmed_email %>
    <% end %> - + - + - +
    <%= t("helpers.current_password") %><%= _('Current password') %> <%= f.password_field :current_password, as: :password %>
    <%= t("helpers.new_password") %><%= _('New password') %> <%= f.password_field :password, as: :password, autocomplete: "off" %>
    <%= t("helpers.password_conf") %><%= _('Password confirmation') %> <%= f.password_field :password_confirmation, as: :password, autocomplete: "off" %>
    - <%= f.submit t("helpers.submit.save"), class: "btn btn-primary" %> - <%= link_to t("helpers.submit.cancel"), :back, class: "btn btn-primary" %> + <%= f.submit _('Save'), class: "btn btn-primary" %> + <%= link_to _('Cancel'), :back, class: "btn btn-primary" %>
    <% end %>
    @@ -134,13 +135,13 @@ diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index 95c5cf1..90556a7 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -1,15 +1,15 @@ -

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

    +

    <%= _('Sign in') %>

    <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
    - + - + @@ -24,7 +24,7 @@
    <%= t("helpers.email") %><%= _('Email') %> <%= f.email_field :email, :autofocus => true %>
    <%= t("helpers.password") %><%= _('Password') %> <%= f.password_field :password %>
    - <%= f.submit t("helpers.sign_in"), :class => "btn btn-primary" %> + <%= f.submit _('Sign in'), :class => "btn btn-primary" %>
    <% end %> diff --git a/app/views/devise/shared/_links.erb b/app/views/devise/shared/_links.erb index 44a1965..3469473 100644 --- a/app/views/devise/shared/_links.erb +++ b/app/views/devise/shared/_links.erb @@ -1,13 +1,13 @@ <%- if devise_mapping.recoverable? && controller_name != 'passwords' %> - <%= link_to t('helpers.forgot_password'), new_password_path(resource_name), :class => "a-orange"%>
    + <%= link_to _('Forgot your password?'), new_password_path(resource_name), :class => "a-orange"%>
    <% end -%> <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> - <%= link_to t('helpers.no_pass_instructions'), new_confirmation_path(resource_name), :class => "a-orange"%>
    + <%= link_to _("Didn't receive confirmation instructions?"), new_confirmation_path(resource_name), :class => "a-orange"%>
    <% end -%> <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> - <%= link_to t('helpers.no_unlock_instructions'), new_unlock_path(resource_name), :class => "a-orange" %>
    + <%= link_to _("Didn't receive unlock instructions?"), new_unlock_path(resource_name), :class => "a-orange" %>
    <% end -%> <%#- if devise_mapping.omniauthable? %> diff --git a/app/views/guidance_groups/admin_edit.html.erb b/app/views/guidance_groups/admin_edit.html.erb index f81dbfc..006318b 100644 --- a/app/views/guidance_groups/admin_edit.html.erb +++ b/app/views/guidance_groups/admin_edit.html.erb @@ -2,10 +2,10 @@ <% javascript 'admin.js' %>

    - <%= t('org_admin.guidance.guidance_group_label') %> + <%= _('Guidance group') %>
    - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, class: 'btn btn-primary' %>
    @@ -20,7 +20,7 @@ - + <% if @guidance_group.published == true then %> - + <% end %> - + @@ -65,11 +65,11 @@
    - <%= f.submit t('helpers.submit.save'), class: 'btn btn-primary' %> + <%= f.submit _('Save'), class: 'btn btn-primary' %> <% if @guidance_group.published == false then %> - <%= f.submit t('helpers.submit.publish'), name: "save_publish", class: "btn btn-primary" %> + <%= f.submit _('Publish'), name: "save_publish", class: "btn btn-primary" %> <% end %> - <%= link_to t('helpers.submit.cancel'), :back, class: 'btn cancel' %> + <%= link_to _('Cancel'), :back, class: 'btn cancel' %>

    diff --git a/app/views/guidance_groups/admin_new.html.erb b/app/views/guidance_groups/admin_new.html.erb index 712cf83..faf81f8 100644 --- a/app/views/guidance_groups/admin_new.html.erb +++ b/app/views/guidance_groups/admin_new.html.erb @@ -2,10 +2,10 @@ <% javascript 'admin.js' %>

    - <%= t("org_admin.guidance.guidance_group_label") %> + <%= _('Guidance group') %>
    - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, class: "btn btn-primary" %>
    @@ -20,22 +20,22 @@

    <%= t('org_admin.guidance_group.name_label') %><%= _('Name') %>
    <%= f.text_field :name, @@ -29,33 +29,33 @@
    - <%= link_to(image_tag('help_button.png'), '#', class: 'guidance_group_title_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance_group.title_help_text_html')) %> + <%= link_to(image_tag('help_button.png'), '#', class: 'guidance_group_title_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("Add an appropriate name for your guidance group e.g. Glasgow guidance. This name will be used to tell the end user where the guidance has come from e.g. 'Glasgow Guidance on Metadata'")) %>
    <%= t('org_admin.templates.published_label') %><%= _('Published') %>
    <%= f.check_box :published %>
    - +
    <%= t('org_admin.guidance_group.subset') %><%= _('Optional subset') %>
    - <%= f.check_box :optional_subset %> <%= t('org_admin.guidance_group.subset_eg') %> + <%= f.check_box :optional_subset %> <%= _('e.g. School/ Department') %>
    - <%= link_to(image_tag('help_button.png'), '#', class: 'guidance_group_subset_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance_group.subset_option_help_text')) %> + <%= link_to(image_tag('help_button.png'), '#', class: 'guidance_group_subset_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard.")) %>
    - + - + @@ -43,8 +43,8 @@
    - <%= f.submit t("helpers.submit.save"), name: "draft", class: "btn btn-primary" %> - <%= link_to t("helpers.submit.cancel"), :back, class: "btn cancel btn-secondary" %> + <%= f.submit _('Save'), name: "draft", class: "btn btn-primary" %> + <%= link_to _('Cancel'), :back, class: "btn cancel btn-secondary" %>

    <% end %> diff --git a/app/views/guidance_groups/admin_show.html.erb b/app/views/guidance_groups/admin_show.html.erb index fba06cc..d73054d 100644 --- a/app/views/guidance_groups/admin_show.html.erb +++ b/app/views/guidance_groups/admin_show.html.erb @@ -1,11 +1,11 @@ <%= stylesheet_link_tag "admin" %>

    - <%= t("org_admin.guidance.guidance_group_label") %> + <%= _('Guidance group') %>
    - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, class: "btn btn-primary" %>
    @@ -19,43 +19,43 @@

    <%= t('org_admin.guidance_group.name_label') %><%= _('Name') %>
    <%= f.text_field :name, as: :string, class: "text_field" %>
    - <%= link_to( image_tag("help_button.png"), "#", class: 'guidance_group_title_popover', rel: "popover", 'data-html' => "true", 'data-content' => t("org_admin.guidance_group.title_help_text_html"))%> + <%= link_to( image_tag("help_button.png"), "#", class: 'guidance_group_title_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("Add an appropriate name for your guidance group e.g. Glasgow guidance. This name will be used to tell the end user where the guidance has come from e.g. 'Glasgow Guidance on Metadata'"))%>
    <%= t('org_admin.guidance_group.subset') %><%= _('Optional subset') %>
    - <%= f.check_box :optional_subset %> <%= t('org_admin.guidance_group.subset_eg') %> + <%= f.check_box :optional_subset %> <%= _('e.g. School/ Department') %>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_subset_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance_group.subset_option_help_text'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_subset_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("If the guidance is only meant for a subset of users e.g. those in a specific college or institute, check this box. Users will be able to select to display this subset guidance when answering questions in the 'create plan' wizard."))%>
    - + - + - + - + - +
    <%= t("org_admin.guidance_group.name_label") %><%= _('Name') %> <%= raw @guidance_group.name %>
    <%= t('org_admin.templates.published_label') %><%= _('Published') %> <% if @guidance_group.published.nil? || !@guidance_group.published then %> - <%= t("helpers.no_label") %> + <%= _('No') %> <% else %> - <%= t("helpers.yes_label") %> + <%= _('Yes') %> <% end %>
    <%= t("org_admin.guidance_group.subset") %><%= _('Optional subset') %> <% if @guidance_group.optional_subset.nil? || !@guidance_group.optional_subset then %> - <%= t('helpers.no_label') %> + <%= _('No') %> <% else %> - <%= t('helpers.yes_label') %> + <%= _('Yes') %> <% end %>
    <%= t("org_admin.guidance.created") %><%= _('Created') %> <%= l @guidance_group.created_at.to_date, formats: :short %>
    <%= t("org_admin.guidance.last_updated") %><%= _('Last updated') %> <%= l @guidance_group.updated_at.to_date, formats: :short %>
    - <%= link_to t("helpers.submit.edit"), admin_edit_guidance_group_path(@guidance_group.id), class: "btn btn-primary" %> - <%= link_to t("helpers.submit.back"), :back, class: "btn cancel" %> + <%= link_to _('Edit'), admin_edit_guidance_group_path(@guidance_group.id), class: "btn btn-primary" %> + <%= link_to _('Back'), :back, class: "btn cancel" %>

    diff --git a/app/views/guidances/_add_guidance.html.erb b/app/views/guidances/_add_guidance.html.erb new file mode 100644 index 0000000..19579e5 --- /dev/null +++ b/app/views/guidances/_add_guidance.html.erb @@ -0,0 +1,93 @@ + +
    + <%= form_for :guidance, url: {action: "admin_create"}, html: {id: "new_guidance_form"} do |f| %> + + + + + + + + + + + + + + + + + +
    <%= _('Text') %> +
    + <%= text_area_tag("guidance-text", "", class: "tinymce") %> +
    +
    + <%= link_to( image_tag("help_button.png"), "#", class: "guidance_text_popover", rel: "popover", "data-html" => "true", "data-content" => _('Enter your guidance here. You can include links where needed.'))%> +
    +
    +
    <%= _('Should this guidance apply:') %> +
    + <%= select_tag "g_options", options_for_select([[_('by themes'), 1], + [_('by question'), 2]]) %> +
    +
    + <%= link_to( image_tag("help_button.png"), "#", class: "guidance_apply_to_popover", rel: "popover", "data-html" => "true", "data-content" => _('Decide whether your guidance should display by themes (default) or if it only pertains to a specific question in one of the funder templates.'))%> +
    +
    + + +
    <%= _('Published') %> +
    + <%= f.check_box :published , as: :check_boxes %> +
    +
    <%= _('Guidance group') %> +
    + <%= f.collection_select(:guidance_group_ids, + GuidanceGroup.where(org_id: current_user.org_id).order("name ASC"), + :id, :name, {prompt: false, include_blank: _('None')}, {multiple: false})%> +
    +
    + <%= link_to( image_tag("help_button.png"), "#", class: "guidance_group_select_popover", rel: "popover", "data-html" => "true", "data-content" => _('Select which group this guidance relates to.'))%> +
    +
    +
    + + + +
    + <%= _('Save')%> + + <%= link_to _('Cancel'), :back, class: "btn cancel" %> +
    + +
    + <%= tinymce content_css: asset_path("application.css") %> + <% end %> +
    + + + + + \ No newline at end of file diff --git a/app/views/guidances/_edit_guidance.html.erb b/app/views/guidances/_edit_guidance.html.erb new file mode 100644 index 0000000..36fe926 --- /dev/null +++ b/app/views/guidances/_edit_guidance.html.erb @@ -0,0 +1,26 @@ + +<%= form_for(suggested_answer, url: admin_update_suggested_answer_path(suggested_answer), html: { method: :put}) do |f| %> + <%= f.hidden_field :org_id, value: current_user.org_id %> + + + + + + +
    <%= _('Suggested answer/ Example')%> +
      +
    • <%= f.select :is_example, {_('Example of answer') => true, _('Suggested answer') => false} %>
    • +
    • <%= f.text_area :text, rows: 5 %>
    • +
    +
    +
    + + +
    + <%= f.submit _('Save'), class: "btn btn-primary" %> + <%= link_to _('Delete'), admin_destroy_suggested_answer_path(id: suggested_answer.id), + confirm: _("You are about to delete a suggested answer/ example for '%{question_text}'. Are you sure?") % { :question_text => question.text }, method: :delete, class: "btn btn-primary"%> + <%= hidden_field_tag :question_id, question.id, class: "question_id" %> + <%= link_to _('Cancel'), "#", class: "btn cancel cancel_edit_suggested_answer" %> +
    +<%end%> diff --git a/app/views/guidances/_guidance_display.html.erb b/app/views/guidances/_guidance_display.html.erb new file mode 100644 index 0000000..bb7ade9 --- /dev/null +++ b/app/views/guidances/_guidance_display.html.erb @@ -0,0 +1,36 @@ + + +
    +
    + <% if !question.guidance.nil? && question.guidance != "" %> + + <% end %> + + <% question.guidance_for_org(current_user.org).each_pair do |title,guidance| %> +
    + +
    +
    <%= raw guidance.text %>
    +
    +
    + <% end %> +
    + +
    \ No newline at end of file diff --git a/app/views/guidances/admin_edit.html.erb b/app/views/guidances/admin_edit.html.erb index 055334d..5851286 100644 --- a/app/views/guidances/admin_edit.html.erb +++ b/app/views/guidances/admin_edit.html.erb @@ -2,13 +2,13 @@ <% javascript 'admin.js' %>

    - <%= t('org_admin.guidance_label') %> + <%= _('Guidance') %>
    - <%= link_to t("org_admin.guidance.add_guidance"), + <%= link_to _('Add guidance'), admin_new_guidance_path, class: 'btn btn-primary' %> - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, class: 'btn btn-primary' %>
    @@ -23,18 +23,18 @@ - + - + - + - +
    <%= t('org_admin.guidance.text_label') %><%= _('Text') %>
    <%= text_area_tag("guidance-text", @guidance.text, class: "tinymce") %>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_text_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.text_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_text_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Enter your guidance here. You can include links where needed.'))%>
    <%= t('org_admin.guidance.by_theme_or_by_question') %><%= _('Should this guidance apply:') %>
    <% if !@guidance.question_id.nil? then %> <% select_op = 2 %> @@ -43,11 +43,11 @@ <% end %> <%= hidden_field 'select_op', value: select_op, id: 'edit_guid_ques_flag' %> - <%= select_tag "g_options", options_for_select({t('org_admin.guidance.by_themes_label') => 1, - t('org_admin.guidance.by_question_label') => 2}, select_op) %> + <%= select_tag "g_options", options_for_select({_('by themes') => 1, + _('by question') => 2}, select_op) %>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_apply_to_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.apply_to_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_apply_to_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Decide whether your guidance should display by themes (default) or if it only pertains to a specific question in one of the funder templates.'))%>
    @@ -57,7 +57,7 @@ {prompt: false, include_blank: 'None'}, {multiple: true})%>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_by_themes_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.by_themes_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_by_themes_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Select which theme(s) this guidance relates to.'))%>
    @@ -66,21 +66,21 @@
    <%= t('org_admin.guidance.published') %><%= _('Published') %>
    <%= f.check_box :published , as: :check_boxes%>
    <%= t('org_admin.guidance.guidance_group_label') %><%= _('Guidance group') %>
    <%= f.collection_select(:guidance_group_id, @guidance_groups, :id, :name, {prompt: false, include_blank: 'None'}, {multiple: false})%>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_select_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.guidance_group_select_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_select_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Select which group this guidance relates to.'))%>
    @@ -92,8 +92,8 @@
    - <%= t('helpers.submit.save')%> - <%= link_to t('helpers.submit.cancel'), :back, class: 'btn cancel' %> + <%= _('Save')%> + <%= link_to _('Cancel'), :back, class: 'btn cancel' %>

    @@ -106,12 +106,12 @@ diff --git a/app/views/guidances/admin_index.html.erb b/app/views/guidances/admin_index.html.erb index a660213..406b45f 100644 --- a/app/views/guidances/admin_index.html.erb +++ b/app/views/guidances/admin_index.html.erb @@ -3,15 +3,15 @@

    - <%= t("org_admin.guidance_group.guidance_group_list") %> + <%= _('Guidance group list') %>

    - <%= raw t("org_admin.guidance_group.guidance_group_text_html")%> + <%= raw _("

    First create a guidance group. This could be institution wide or a subset e.g. a particular College / School, Institute or department. When you create guidance you'll be asked to assign it to a guidance group.

    ")%>
    - <%= link_to t("org_admin.guidance_group.add_guidance_group"), admin_new_guidance_group_path(), class: "btn btn-primary" %> + <%= link_to _('Add guidance group'), admin_new_guidance_group_path(), class: "btn btn-primary" %>
    @@ -20,11 +20,11 @@ - - - - - + + + + + @@ -35,16 +35,16 @@ @@ -52,9 +52,9 @@ <%= l guidance_gr.updated_at.to_date, formats: :short %> <% end %> @@ -66,16 +66,16 @@

    - <%= t("org_admin.guidance.guidance_list") %> + <%= _('Guidance list') %>

    - <%= raw t("org_admin.guidance.guidance_text_html")%> + <%= raw _('

    You can write pieces of guidance to be displayed by theme (e.g. generic guidance on storage and backup that should present across the board) or you can write guidance for specific questions. Writing generic guidance by theme saves you time and effort as your advice will be automatically displayed across all templates rather than having to write guidance to accompany each.

    You will usually want your guidance to display on all templates, however there may be cases where you only want it to show for specific funders e.g. if you have specific instructions for applicants to BBSRC for example. This can be set too if needed.

    ')%>
    - <%= link_to t("org_admin.guidance.add_guidance"), + <%= link_to _('Add guidance'), admin_new_guidance_path(), class: "btn btn-primary" %>
    @@ -88,12 +88,12 @@
    <%= t("org_admin.guidance_group.name_label") %><%= t("org_admin.guidance.published") %><%= t("org_admin.guidance_group.subset") %><%= t("org_admin.guidance.last_updated") %><%= t("org_admin.guidance.actions") %><%= _('Name') %><%= _('Published') %><%= _('Optional subset') %><%= _('Last updated') %><%= _('Actions') %>
    <% if guidance_gr.published.nil? || guidance_gr.published == false then%> - <%= t("helpers.no_label")%> + <%= _('No')%> <% else %> - <%= t("helpers.yes_label")%> + <%= _('Yes')%> <% end %> <% if guidance_gr.optional_subset.nil? || guidance_gr.optional_subset == false then%> - <%= t("helpers.no_label")%> + <%= _('No')%> <% else %> - <%= t("helpers.yes_label")%> + <%= _('Yes')%> <% end %> - <%= link_to t("helpers.view"), admin_show_guidance_group_path(guidance_gr), class: "dmp_table_link"%>
    - <%= link_to t("helpers.submit.edit"), admin_edit_guidance_group_path(guidance_gr), class: "dmp_table_link"%>
    - <%= link_to t("helpers.submit.delete"), admin_destroy_guidance_group_path(guidance_gr), data: {confirm: t("org_admin.guidance_group.delete_message", guidance_group_name: guidance_gr.name )}, method: :delete, class: "dmp_table_link"%> + <%= link_to _('View'), admin_show_guidance_group_path(guidance_gr), class: "dmp_table_link"%>
    + <%= link_to _('Edit'), admin_edit_guidance_group_path(guidance_gr), class: "dmp_table_link"%>
    + <%= link_to _('Delete'), admin_destroy_guidance_group_path(guidance_gr), data: {confirm: _("You are about to delete '%{guidance_group_name}'. This will affect guidance. Are you sure?") % { :guidance_group_name => guidance_gr.name }}, method: :delete, class: "dmp_table_link"%>
    - - - - - - + + + + + + @@ -116,7 +116,7 @@ <% end %> <% if !guidance.question_id.nil? then %> <% else %> <% end %> diff --git a/app/views/guidances/admin_new.html.erb b/app/views/guidances/admin_new.html.erb index 43e620c..cdbb0a0 100644 --- a/app/views/guidances/admin_new.html.erb +++ b/app/views/guidances/admin_new.html.erb @@ -2,10 +2,10 @@ <% javascript 'admin.js' %>

    - <%= t('org_admin.guidance.new_label') %> + <%= _('New guidance') %>
    - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, class: 'btn btn-primary' %>
    @@ -18,24 +18,24 @@ <%= form_for :guidance, url: {action: 'admin_create'}, html: {id: 'new_guidance_form'} do |f| %>

    <%= t("org_admin.guidance.text_label") %><%= t("org_admin.guidance.themes_label") %><%= t("org_admin.guidance.question_label") %><%= t("org_admin.guidance.guidance_group_label") %><%= t("org_admin.guidance.last_updated") %><%= t("org_admin.guidance.actions") %><%= _('Text') %><%= _('Themes') %><%= _('Question') %><%= _('Guidance group') %><%= _('Last updated') %><%= _('Actions') %>
    - <%= raw guidance.question.text.truncate(70, omission: t('helpers.truncate_continued')) %> + <%= raw guidance.question.text.truncate(70, omission: _('... (continued)')) %> @@ -136,10 +136,10 @@ <%= l guidance.updated_at.to_date, formats: :short %> - <%= link_to t("helpers.view"), admin_show_guidance_path(guidance), class: "dmp_table_link"%>
    - <%= link_to t("helpers.submit.edit"), admin_edit_guidance_path(guidance), class: "dmp_table_link"%>
    - <%= link_to t("helpers.submit.delete"), admin_destroy_guidance_path(guidance), - data: {confirm: t("org_admin.guidance.delete_message_html", guidance_summary: truncate(sanitize(guidance.text,tags: %w(br a)), length: 20 , omission: t('helpers.truncate_continued')) )}, method: :delete, class: "dmp_table_link"%> + <%= link_to _('View'), admin_show_guidance_path(guidance), class: "dmp_table_link"%>
    + <%= link_to _('Edit'), admin_edit_guidance_path(guidance), class: "dmp_table_link"%>
    + <%= link_to _('Delete'), admin_destroy_guidance_path(guidance), + data: {confirm: _("You are about to delete '%{guidance_summary}'. Are you sure?") % { :guidance_summary => truncate(sanitize(guidance.text,tags: %w(br a)), length: 20 , omission: _('... (continued)'))} }, method: :delete, class: "dmp_table_link"%>
    - + - + - + - +
    <%= t('org_admin.guidance.text_label') %><%= _('Text') %>
    <%= text_area_tag("guidance-text", "", class: "tinymce") %>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_text_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.text_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_text_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Enter your guidance here. You can include links where needed.'))%>
    <%= t('org_admin.guidance.by_theme_or_by_question') %><%= _('Should this guidance apply:') %>
    - <%= select_tag "g_options", options_for_select([[t('org_admin.guidance.by_themes_label'), 1], - [t('org_admin.guidance.by_question_label'), 2]]) %> + <%= select_tag "g_options", options_for_select([[_('by themes'), 1], + [_('by question'), 2]]) %>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_apply_to_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.apply_to_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_apply_to_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Decide whether your guidance should display by themes (default) or if it only pertains to a specific question in one of the funder templates.'))%>
    @@ -45,24 +45,24 @@ :id, :title, {prompt: false, include_blank: 'None'}, {multiple: true})%>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_by_themes_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.by_themes_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_by_themes_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Select which theme(s) this guidance relates to.'))%>
    <%= t('org_admin.guidance.published') %><%= _('Published') %>
    <%= f.check_box :published , as: :check_boxes%>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_subset_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.guidance_group_published_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_subset_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("Check this box when you are ready for this guidance to appear on user's plans."))%>
    <%= t('org_admin.guidance.guidance_group_label') %><%= _('Guidance group') %>
    <%= f.collection_select(:guidance_group_id, @guidance_groups, :id, :name, {prompt: false, include_blank: 'None'}, {multiple: false})%>
    - <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_select_popover', rel: "popover", 'data-html' => "true", 'data-content' => t('org_admin.guidance.guidance_group_select_help_text_html'))%> + <%= link_to( image_tag('help_button.png'), '#', class: 'guidance_group_select_popover', rel: "popover", 'data-html' => "true", 'data-content' => _('Select which group this guidance relates to.'))%>
    @@ -97,9 +97,9 @@
    - <%= t("helpers.submit.save")%> + <%= _('Save')%> - <%= link_to t('helpers.submit.cancel'), :back, class: 'btn cancel' %> + <%= link_to _('Cancel'), :back, class: 'btn cancel' %>

    @@ -112,12 +112,12 @@ \ No newline at end of file diff --git a/app/views/guidances/admin_show.html.erb b/app/views/guidances/admin_show.html.erb index 14356f8..59de8ba 100644 --- a/app/views/guidances/admin_show.html.erb +++ b/app/views/guidances/admin_show.html.erb @@ -1,14 +1,14 @@ <%= stylesheet_link_tag "admin" %>

    - <%= t("org_admin.guidance_label") %> + <%= _('Guidance') %>
    - <%= link_to t("org_admin.guidance.add_guidance"), + <%= link_to _('Add guidance'), admin_new_guidance_path, class: "btn btn-primary" %> - <%= link_to t("org_admin.guidance.view_all_guidance"), + <%= link_to _('View all guidance'), admin_index_guidance_path, class: "btn btn-primary" %>
    @@ -22,12 +22,12 @@ - + <% if @guidance.themes !=[] then %> - + - + <% end %> - + - + - + - +
    <%= t("org_admin.guidance.text_label") %><%= _('Text') %> <%= raw @guidance.text %>
    <%= t("org_admin.guidance.themes_label") %><%= _('Themes') %> <% @guidance.themes.each do |th|%> <%= th.title %> <% end %> @@ -36,38 +36,38 @@ <% end %> <% if !@guidance.question_id.nil? %>
    <%= t("org_admin.guidance.question_label") %><%= _('Question') %> <%= raw @guidance.question.text %>
    <%= t("org_admin.guidance.guidance_group_label") %><%= _('Guidance group') %> <%= @guidance.guidance_group.name %>
    <%= t("org_admin.guidance.published") %><%= _('Published') %> <%if @guidance.published == false || @guidance.published.nil? then%> - <%= t("helpers.no_label")%> + <%= _('No')%> <% else %> - <%= t("helpers.yes_label")%> + <%= _('Yes')%> <% end %>
    <%= t("org_admin.guidance.created") %><%= _('Created') %> <%= l @guidance.created_at.to_date, formats: :short %>
    <%= t("org_admin.guidance.last_updated") %><%= _('Last updated') %> <%= l @guidance.updated_at.to_date, formats: :short %>
    - <%= link_to t("helpers.submit.edit"), admin_edit_guidance_path(@guidance.id), class: "btn btn-primary"%> - <%= link_to t("helpers.submit.back"), :back, class: "btn cancel" %> + <%= link_to _('Edit'), admin_edit_guidance_path(@guidance.id), class: "btn btn-primary"%> + <%= link_to _('Back'), :back, class: "btn cancel" %>

    diff --git a/app/views/layouts/_navigation.html.erb b/app/views/layouts/_navigation.html.erb index b7bd219..4ed662d 100644 --- a/app/views/layouts/_navigation.html.erb +++ b/app/views/layouts/_navigation.html.erb @@ -1,4 +1,3 @@ - diff --git a/app/views/orgs/admin_edit.html.erb b/app/views/orgs/admin_edit.html.erb index 67030c7..5d4da43 100644 --- a/app/views/orgs/admin_edit.html.erb +++ b/app/views/orgs/admin_edit.html.erb @@ -2,7 +2,7 @@ <% javascript 'admin.js' %>

    - <%= t('org_admin.org_details_label') %> + <%= _('Organisation details') %>

    @@ -13,12 +13,12 @@ - - + + - + - + - + <%end%> - + - + - - + + - - + + - +
    <%= t('org_admin.org_name') %><%= f.text_field :name, as: :string, class: 'text_field has-tooltip', data_toggle: "tooltip", title: t('org_admin.name_help_text') %><%= _('Name') %><%= f.text_field :name, as: :string, class: 'text_field has-tooltip', data_toggle: "tooltip", title: _("Please enter your organisation's name.") %>
    <%= t('org_admin.org_abbr') %><%= _('Abbreviation') %>
    <%= f.text_field :abbreviation, as: :string, class: 'text_field' %> @@ -30,39 +30,39 @@ <% if @org.logo.present? %>
    <%= t('org_admin.org_logo') %><%= _('Logo') %> <%= image_tag @org.logo.url %>
    <%= f.check_box :remove_logo %>   <%= t('org_admin.remove_logo') %><%= f.check_box :remove_logo %>   <%= _('If you decide to use the default DMPRoadmap logo, please check this box to remove your current logo.') %>
    <%= t('org_admin.new_org_logo') %><%= _('Upload a new logo file') %> <%= f.file_field :logo %>
    <%= t('org_admin.org_banner_text') %><%= _('Top banner text') %> <%= text_area_tag("org_banner_text", @org.banner_text, class: "tinymce") %>
    <%= t('org_admin.org_target_url') %><%= f.text_field :target_url, as: :string, class: 'text_field has-tooltip', data_toggle: "tooltip", title: t('org_admin.target_url_help_text') %><%= _('Website') %><%= f.text_field :target_url, as: :string, class: 'text_field has-tooltip', data_toggle: "tooltip", title: _('Please enter a valid web address.') %>
    <%= t('org_admin.org_contact_email') %><%= f.text_field :contact_email, as: :string, class: 'text_field has-tooltip', data_toggle: "tooltip", title: t('org_admin.org_contact_email_help_text') %><%= _('Contact Email') %><%= f.text_field :contact_email, as: :string, class: 'text_field has-tooltip', data_toggle: "tooltip", title: _('The email address of an administrator at your organisation. Your users will use this address if they have questions.') %>
    <%= t('org_admin.org_type') %><%= _('Organisation type') %> <%= @org.organisation_type %>
    @@ -71,8 +71,8 @@
    - <%= f.submit t('helpers.submit.save'), class: 'btn btn-primary' %> - <%= link_to t('helpers.submit.cancel'), :back, class: 'btn btn-primary' %> + <%= f.submit _('Save'), class: 'btn btn-primary' %> + <%= link_to _('Cancel'), :back, class: 'btn btn-primary' %>
    <% end %> diff --git a/app/views/orgs/admin_show.html.erb b/app/views/orgs/admin_show.html.erb index 55ed7b1..fe91c9c 100644 --- a/app/views/orgs/admin_show.html.erb +++ b/app/views/orgs/admin_show.html.erb @@ -1,9 +1,9 @@ <%= stylesheet_link_tag "admin" %>

    - <%= t('org_admin.org_details_label') %> + <%= _('Organisation details') %>

    -<%= t('org_admin.org_text')%> +<%= _('These are the basic details for your organisation.')%>
    @@ -14,7 +14,7 @@ <% if @org.name.present? then %> - + <% if @org.logo.present? then %> @@ -25,48 +25,48 @@ <% if @org.abbreviation.present? then %> - + <% end %> <% if @org.banner_text.present? then %> - + <% end %> <% if @org.target_url.present? then %> - + <% end %> <% if @org.contact_email.present? then %> - + <% end %> <% if @org.org_type != 0 then %> - + <% end %> <% if @org.parent_id.present? then %> - + <% end %> - +
    <%= t('org_admin.org_name') %><%= _('Name') %> <%= @org.name %>
    <%= t('org_admin.org_abbr') %><%= _('Abbreviation') %> <%= @org.abbreviation %>
    <%= t('org_admin.org_banner_text') %><%= _('Top banner text') %> <%= raw @org.banner_text %>
    <%= t('org_admin.org_target_url') %><%= _('Website') %> <%= @org.target_url %>
    <%= t('org_admin.org_contact_email') %><%= _('Contact Email') %> <%= @org.contact_email %>
    <%= t('org_admin.org_type') %><%= _('Organisation type') %> <%= @org.organisation_type %>
    <%= t('org_admin.parent_org') %><%= _('Main organisation') %> <%= @org.parent.name %>
    <%= t('org_admin.last_updated') %><%= _('Last updated') %> <%= l @org.updated_at.to_date, formats: :short %>
    @@ -75,7 +75,7 @@
    - <%= link_to t("helpers.submit.edit"), admin_edit_org_path(current_user.org), class: 'btn btn-primary'%> + <%= link_to _('Edit'), admin_edit_org_path(current_user.org), class: 'btn btn-primary'%>

    diff --git a/app/views/phases/_add_note.html.erb b/app/views/phases/_add_note.html.erb index 41d72f5..190f89b 100644 --- a/app/views/phases/_add_note.html.erb +++ b/app/views/phases/_add_note.html.erb @@ -1,12 +1,9 @@ -<% new_note = Note.new - if !answer.nil? - answerid = answer["id"] - else - answerid = answer_obj.id - end +<% + new_note = Note.new + answerid = answer.id %> <%= form_for :new_note, @@ -14,15 +11,15 @@ :html=>{:method=>:post, :id => "new_note_form_#{answerid}", :class => "add_note_form"} do |f| %> <%= f.hidden_field :user_id, :value => current_user.id %> <%= f.hidden_field :answer_id, :value => answerid %> - <%= f.hidden_field :question_id, :value => question["id"] %> - <%= f.hidden_field :plan_id, :value => plan_data["id"] %> + <%= f.hidden_field :question_id, :value => question.id %> + <%= f.hidden_field :plan_id, :value => plan_id %> <%= text_area_tag("#{answerid}new_note_text".to_sym, "" , class: "tinymce") %>
    - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary new_comment_submit_button" %> + <%= f.submit _('Save'), :class => "btn btn-primary new_comment_submit_button" %>

    <%end%> diff --git a/app/views/phases/_answer.html.erb b/app/views/phases/_answer.html.erb new file mode 100644 index 0000000..3383519 --- /dev/null +++ b/app/views/phases/_answer.html.erb @@ -0,0 +1,77 @@ + + +<% qformat = question.question_format %> + + + +

    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?%> +
      + <% options.each do |op| %> +
    1. + <% checked = (answer.option_ids[0] == op.id) %> + <%= af.radio_button :option_ids, op.id, :checked => checked, id: "answer_option_ids_#{op.id}"%> + <%= raw op.text %> +
    2. + <% end %> +
    + <% elsif qformat.dropdown? %> + <%= af.input :options, + :as => :select, + :collection => options, + :label => false, + :input_html => { :multiple => false, :disabled => :true } + %> + <% end %> + + + <% if question.option_comment_display %> + <%= label_tag("answer-text-Ans#{question.id}".to_sym, _('Comment')) %> + <%= text_area_tag("answer-text-Ans#{question.id}".to_sym, answer.text, class: "tinymce") %> + <%end%> + <% end %> + + <% if qformat.textfield? %> + <%= text_field_tag("answer-text-Ans#{question.id}".to_sym, strip_tags(answer.text), class: "question_text_field") %> + <% elsif qformat.textarea? %> + <%= text_area_tag("answer-text-Ans#{question["id"]}".to_sym, strip_tags(answer.text), class: "tinymce") %> + <% end %> + + <% end %> +<% end %> + +

    Combine with your answer and save.

    + + diff --git a/app/views/phases/_answer_form.html.erb b/app/views/phases/_answer_form.html.erb index 74ae43a..763735b 100644 --- a/app/views/phases/_answer_form.html.erb +++ b/app/views/phases/_answer_form.html.erb @@ -8,59 +8,63 @@
    <% - q_format = question["question_format"] - answer = nil - answer_obj = nil - if question.has_key?("answers") - answer = question["answers"].first - answer_obj = Answer.find(answer["id"]) + answers = question.plan_answers(plan.id) + if answers.present? + answer = answers.first else - answer_obj = Answer.new + answer = Answer.new end - question_obj = Question.find(question["id"]) + question_id = question.id + q_format = question.question_format %> -
    " class="question-form"> - <%= semantic_form_for answer_obj, :url => {:controller => :answers, :action => :update }, :html=>{:method=>:put}, :remote => true do |f| %> +
    + <%= semantic_form_for answer, :url => {:controller => :answers, :action => :update }, :remote => true do |f| %> <%= f.inputs do %> - <%= f.input :plan_id, :as => :hidden, :input_html => { :value => @plan_data["id"] } %> + <%= f.input :plan_id, :as => :hidden, :input_html => { :value => @plan.id } %> <%= f.input :user_id, :as => :hidden, :input_html => { :value => current_user.id } %> - <%= f.input :question_id, :as => :hidden, :input_html => { :value => question["id"], :class => "question_id" } %> + <%= f.input :question_id, :as => :hidden, :input_html => { :value => question_id, :class => "question_id" } %> + <%= f.hidden_field :lock_version %> - <%= raw question["text"] %> + <%= raw question.text %> - <% if question.has_key?("suggested_answer") && question["suggested_answer"]["text"].present? %> - <% suggested_answer = question["suggested_answer"] %> -
    - - <% if suggested_answer["is_example"] then %> - <%= t("org_admin.questions.example_answer_label")%> - <%else%> - <%= t("org_admin.questions.suggested_answer_label")%> - <%end%> - + <% if question.suggested_answers.any? %> + <% suggested_answer = question.suggested_answers.first %> + <% if suggested_answer.text.present? %> +
    + + <% if suggested_answer.is_example? then %> + <%= _('Example of answer')%> + <%else%> + <%= _('Suggested answer')%> + <%end%> + -
    -

    - <%= raw suggested_answer["text"] %> -

    +
    +

    + <%= raw suggested_answer.text %> +

    +
    -
    + <% end %> <% end %> + +
    + - <% if [ @checkbox, @multi, @radio, @dropdown ].include?( q_format["id"] ) %> + <% if question.option_based? %> <% options = question.options.order("number") %> - <% if q_format.id == @checkbox %> + <% if q_format.checkbox? %> <%= f.input :options, :as => :check_boxes, :collection => options, :label => false, :input_html => { :id => "options-#{question.id}" } %> - <% elsif q_format.id == @multi %> + <% elsif q_format.multiselectbox? %> <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => true , :id => "options-#{question.id}" } %> - <% elsif q_format.id == @radio %> + <% elsif q_format.radiobuttons? %>
      <% options.each do |op| %>
    1. @@ -72,63 +76,63 @@ <%= raw op.text %>
    2. <% end %>
    - <% elsif q_format.id == @dropdown %> + <% elsif q_format.dropdown? %> <%= f.input :options, :as => :select, :collection => options, :label => false, :input_html => { :multiple => false, :id => "options-#{question.id}" } %> <% end %> <% if question.option_comment_display == true %> - <%= label_tag("answer-text-#{question.id}".to_sym, t("helpers.comment")) %> + <%= label_tag("answer-text-#{question.id}".to_sym, _('Comment')) %> <%= text_area_tag("answer-text-#{question.id}".to_sym, answer.text, class: "tinymce") %> <%end%> <% end %> - <% if q_format["id"] == @textfield %> - <%= text_field_tag("answer-text-#{question.id}".to_sym, strip_tags(answer.text), class: "question_text_field") %> - <% elsif q_format["id"] == @textarea %> - <%= text_area_tag("answer-text-#{question["id"]}".to_sym, answer_obj.text, class: "tinymce") %> + <% if q_format.textfield? %> + <%= text_field_tag("answer-text-#{question_id}".to_sym, strip_tags(answer.text), class: "question_text_field") %> + <% elsif q_format.textarea? %> + <%= text_area_tag("answer-text-#{question_id}".to_sym, answer.text, class: "tinymce") %> <% end %> <% end %> <%= f.actions do %> - <%= f.action :submit, :label => t("helpers.save"), :button_html => { :class => "btn btn-primary"} %> -
  • " class="saving-message" style="display:none;"><%= t("helpers.saving")%>
  • + <%= f.action :submit, :label => _('Save'), :button_html => { :class => "btn btn-primary"} %> + <% end %> <% end %>
    - <% if answer.nil? || !answer.has_key?("created_at") || answer["created_at"].nil? %> - -status" class="label label-warning answer-status"><%= t("helpers.notanswered") %> + <% if answer.nil? || answer.created_at.nil? %> + <%= _('Not answered yet') %> <% else %> - -status" class="label label-info answer-status"><%= t("helpers.answered_by")%><%= answer_obj.created_at %><%= t("helpers.answered_by_part2")%><%= answer_obj.user.name %> + <%= _('Answered')%><%= answer.created_at %><%= _(' by')%><%= answer.user.name %> <% end %>
    --unsaved" class="label label-inverse answer-unsaved" style="display:none;"><%= t("helpers.unsaved") %> +
    -
    " class="question_right_column_nav"> - <% comments = answer_obj.notes.all %> - <%= hidden_field_tag :question_id, question["id"], :class => "question_id" %> +
    + <% comments = answer.notes.all %> + <%= hidden_field_tag :question_id, question_id, :class => "question_id" %>
      - <% if (!question["guidance"].nil? && question["guidance"] != "") || question.has_key?("theme_guidance") then %> + <% if question.guidance.present? || question_guidances[question_id] %> <% css_style_comment_div = "display: none;"%> <% css_style_guidance_div = ""%>
    • - <%= link_to t("helpers.guidance_accordion_label"), "#", :class => "guidance_accordion_button" %> + <%= link_to _('Guidance'), "#", :class => "guidance_accordion_button" %>
    • <% if comments.count > 0 then%> - <% comments_label_with_count = "#{t("helpers.comment_accordion_label")} (#{comments.count})"%> + <% comments_label_with_count = "#{_('Notes')} (#{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" %> + <%= link_to _('Share note'), "#", :class => "comments_accordion_button" %> <%end%>
    • <%else%> @@ -137,10 +141,10 @@ <% 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 = "#{_('Notes')} (#{comments.count})"%>

      <%= comments_label_with_count %>

      <%else%> -

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

      +

      <%= _('Share note') %>

      <%end%>
    • <%end%> @@ -149,74 +153,62 @@ -
      " style="<%= css_style_guidance_div%>" > -
      -guidance"> +
      +
      - <% if question["guidance"].present? %> + <% if question.guidance.present? %>
      -
      " class="guidance-accordion-body collapse"> -
      <%= raw question["guidance"] %>
      +
      +
      <%= raw question.guidance %>
      <% end %> - - <% gnum = 0 %> - <% if question.has_key?("theme_guidance") %> - <% question["theme_guidance"].each_key do |theme| %> - <% question["theme_guidance"][theme].each do |guidance| %> - <% - orgname = guidance["org"] - gnum = gnum + 1 - text = guidance["text"] - %> - -
      - - -
      - -guidance" href="#collapse-guidance-<%= gnum %>-<%= question["id"] %>"> -
      - <%= orgname %> guidance on <%= theme %> -
      -
      + <% guidance_accordion_id = 0 %> + <% question_guidances.each_pair do |theme, group| %> + <% group.each do |gobj| %> +
      + +
      +
      <%= raw gobj[:text] %>
      +
      + <% guidance_accordion_id += 1 %>
      - - -
      " class="guidance-accordion-body collapse"> -
      <%= raw text %>
      -
      -
      - <% end %> - <% end %> - <% end %> + <% end %> + <% end %>
      -
      " style="<%= css_style_comment_div%>"> - <%= render :partial => "note", locals: {question: question, answer_obj: answer_obj, answer: answer, plan: plan, plan_data: plan_data}%> +
      + <%= render :partial => "note", locals: {question: question, answer: answer, plan: plan }%>
      -<% if last_question_id == question["id"] then %> +<% if last_question_id == question_id then %>
      <% else %>
      diff --git a/app/views/phases/_answer_form_ro.html.erb b/app/views/phases/_answer_form_ro.html.erb index 64a0fb0..674cc29 100644 --- a/app/views/phases/_answer_form_ro.html.erb +++ b/app/views/phases/_answer_form_ro.html.erb @@ -28,9 +28,9 @@
      <% if suggested_answer.is_example? then %> - <%= t("org_admin.questions.example_answer_label")%> + <%= _('Example of answer')%> <%else%> - <%= t("org_admin.questions.suggested_answer_label")%> + <%= _('Suggested answer')%> <%end%>
      @@ -42,24 +42,24 @@ <% 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%> + <% if q_format.title == _('Check box') || q_format.title == _('Multi select box') || q_format.title == _('Radio buttons') || q_format.title == _('helpers.dropdown') then%> <% options = question.options.order("number") %> - <% if q_format.title == t("helpers.checkbox") then %> + <% if q_format.title == _('Check box') 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 %> + <% elsif q_format.title == _('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%> + <% elsif q_format.title == _('Radio buttons') then%>
        <% options.each do |op| %>
      1. @@ -80,7 +80,7 @@ <% end %>
      - <% elsif q_format.title == t("helpers.dropdown") then%> + <% elsif q_format.title == _('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 %> @@ -89,15 +89,15 @@ <% end %> <% if question.option_comment_display == true then%> - <%= label_tag("answer-text-#{question.id}".to_sym, t("helpers.comment")) %> + <%= label_tag("answer-text-#{question.id}".to_sym, _('Comment')) %> <%= text_area_tag("answer-text-#{question.id}".to_sym, answer.text, class: "tinymce") %> <%end%> - <% elsif q_format.title == t("helpers.text_field") then %> + <% elsif q_format.title == _('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%> + <% elsif q_format.title == _('Text area') then%> <%= text_area_tag("answer-text-#{question.id}".to_sym, answer.text, class: "tinymce") %> <% end %> @@ -106,11 +106,11 @@ <%= f.actions do %> <% if readonly then %> - <%= f.action :submit, :label => t("helpers.save"), :button_html => { :class => "btn btn-primary"}, :input_html => { :disabled => true } %> + <%= f.action :submit, :label => _('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"} %> + <%= f.action :submit, :label => _('Save'), :button_html => { :class => "btn btn-primary"} %> <% end %> - + <% end %> <% end %>
      @@ -119,7 +119,7 @@
      >

      <%= 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 q_format.title == _('Check box') || q_format.title == _('Multi select box') || q_format.title == _('Radio buttons') || q_format.title == _('Dropdown') %>
        <% if answer.options.is_a? Option then %>
      • <%= answer.options.text %>
      • @@ -136,11 +136,11 @@
      <% if answer.created_at.nil? then %> - <%= t("helpers.notanswered") %> + <%= _('Not answered yet') %> <% else %> - <%= t("helpers.answered_by")%><%= answer.created_at %><%= t("helpers.answered_by_part2")%><%= answer.user.name %> + <%= _('Answered')%><%= answer.created_at %><%= _(' by')%><%= answer.user.name %> <% end %> - +
      @@ -149,21 +149,22 @@
      <% @comments = Notes.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 %> + + <% if (!question.guidance.nil? && question.guidance != "") || !question_guidances.empty? then %> <% css_style_comment_div = "display: none;"%> <% css_style_guidance_div = ""%>
      • - <%= link_to t("helpers.guidance_accordion_label"), "#", :class => "guidance_accordion_button" %> + <%= link_to _('Guidance'), "#", :class => "guidance_accordion_button" %>
      • <% if @comments.count > 0 then%> - <% comments_label_with_count = "#{t("helpers.comment_accordion_label")} (#{@comments.count})"%> + <% comments_label_with_count = "#{_('Notes')} (#{@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" %> + <%= link_to _('Share note'), "#", :class => "comments_accordion_button" %> <%end%>
      • <%else%> @@ -172,10 +173,10 @@ <% 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 = "#{_('Notes')} (#{@comments.count})"%>

        <%= comments_label_with_count %>

        <%else%> -

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

        +

        <%= _('Share note') %>

        <%end%>
      • <%end%> @@ -194,9 +195,9 @@
        <%= question.section.organisation.abbreviation %> <%if question.section.organisation.abbreviation == "EPSRC" then %> - <%= t("helpers.policy_expectations")%> + <%= _('Policy Expectations')%> <%else%> - <%= t("helpers.guidance")%> + <%= _('Guidance')%> <%end%>
        @@ -206,28 +207,25 @@
      <% end %> - - <% @question_guidances.each_pair do |group,themes| %> - <% themes.each_pair do |theme,guidances| %> - <% guidances.each do |guidance| %> + + <% guidance_accordion_id = 1 %> + <% question_guidances.each_pair do |theme, group| %> + <% group.each do |gobj| %>
      diff --git a/app/views/phases/_archive_note.html.erb b/app/views/phases/_archive_note.html.erb index daee904..26e87e3 100644 --- a/app/views/phases/_archive_note.html.erb +++ b/app/views/phases/_archive_note.html.erb @@ -6,18 +6,18 @@ <%= 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") %> + <%= _('helpers.notes.archive_own_note_question')%> + <% button_label = _('helpers.notes.archive_own_comment_button_label') %> <% else%> - <%= t("helpers.notes.archive_note_question")%> - <% button_label = t("helpers.notes.archive_comment_button_label") %> + <%= _('helpers.notes.archive_note_question')%> + <% button_label = _('helpers.notes.archive_comment_button_label') %> <%end%>
      <%= hidden_field_tag :note_id, note["id"], :class => "comment_id" %> <%= f.submit button_label, :class => "btn btn-primary archive_comment_submit_button" %> - <%= link_to t("helpers.submit.cancel"), "#", :class => "cancel_archive_comment btn cancel" %> + <%= link_to _('Cancel'), "#", :class => "cancel_archive_comment btn cancel" %>

      <%end%> diff --git a/app/views/phases/_edit_note.html.erb b/app/views/phases/_edit_note.html.erb index 366945f..cc482cc 100644 --- a/app/views/phases/_edit_note.html.erb +++ b/app/views/phases/_edit_note.html.erb @@ -10,7 +10,7 @@
      <%= hidden_field_tag :answer, note["answer_id"], :class => "answer_id" %> <%= hidden_field_tag :note_id, note["id"], :class => "note_id" %> - <%= f.submit t("helpers.submit.save"), :class => "btn btn-primary edit_note_submit_button" %> + <%= f.submit _('Save'), :class => "btn btn-primary edit_note_submit_button" %>

      <%end%> diff --git a/app/views/phases/_edit_phase.html.erb b/app/views/phases/_edit_phase.html.erb new file mode 100644 index 0000000..edbfd90 --- /dev/null +++ b/app/views/phases/_edit_phase.html.erb @@ -0,0 +1,45 @@ + + +<%= form_for(phase, url: admin_update_phase_path(phase.id), html: { method: :put}) do |f| %> + +

      + <%= _('Phase details')%> +

      +
      + <%= raw _("

      Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

      ")%> +

      +
      +
      + + + + + + + + + + + + + + +
      <%= _('Title') %><%= f.text_field :title, + as: :string, + class: 'text_field has-tooltip', 'data-toggle' => "tooltip", 'title' => _('Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP') %>
      <%= _('Order of display') %><%= f.number_field :number, in: 0..5, class: "number_field has-tooltip", 'data-toggle' => "tooltip", 'title' => _('This allows you to order the phases of your template.') %>
      <%= _('Description') %> +
      + <%= text_area_tag("phase-desc", phase.description, class: "tinymce") %> +
      +
      + <%= link_to( image_tag('help_button.png'), '#', class: 'phase_desc_popover', rel: "popover", 'data-html' => "true", 'data-content' => _("Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer."))%> +
      +
      +
      + + +
      + <%= f.submit _('Save'), class: 'btn btn-primary' %> + <%= link_to _('Cancel'), admin_show_phase_path(phase), class: 'btn cancel' %> +
      + +<% end %> \ No newline at end of file diff --git a/app/views/phases/_list_notes.html.erb b/app/views/phases/_list_notes.html.erb index 7d6315a..bd2ae70 100644 --- a/app/views/phases/_list_notes.html.erb +++ b/app/views/phases/_list_notes.html.erb @@ -6,47 +6,43 @@ <% style_to_add = "" %> <%end%> - -<% notes.sort! {|x,y| y["updated_at"] <=> x["updated_at"] } %> -
      - <% notes.each do |c|%> + <% notes.each do |note|%>
      - <% user = c["user"] %> - <% user = User.find(c["user_id"]) %> - <%= user["name"] %>
      - (<%= l c["updated_at"], format: :custom %>) + <% user = note.user.name %> + <%= user %>
      + (<%= l note.updated_at, format: :custom %>)
      - <% if c["archived"] %> + <% if note.archived %> - <% if c["archived_by"] == current_user.id %> - <%= t("helpers.comments.retracted")%> + <% if note.archived_by == current_user.id %> + <%= _('Note removed by you')%> <% else %> - <% archived_by_user = User.find(c["archived_by"]) %> - <%= t("helpers.comments.clear_by")%> <%= archived_by_user.name %> + <% archived_by_user = User.find(note.archived_by) %> + <%= _('Note removed 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" %> + <%= link_to _('View'),"#", :class => "dmp_table_link view_comment_button" %> + <%= hidden_field_tag :note_id, note.id, :class => "comment_id" %> - <% if current_user.id == c["user_id"] %> - <%= 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" %> + <% if current_user.id == note.user_id %> + <%= link_to _('Edit'),"#", :class => "dmp_table_link edit_comment_button" %> + <%= hidden_field_tag :note_id, note.id, :class => "comment_id" %> + <%= link_to _('Remove'),"#", :class => "dmp_table_link archive_comment_button" %> <% end%> - <% if plan.administerable_by?(current_user.id) && current_user.id != c["user_id"] %> - <%= hidden_field_tag :note_id, c["id"], :class => "comment_id" %> - <%= link_to t("helpers.comments.clear_label"),"#", :class => "dmp_table_link archive_comment_button" %> + <% if plan.administerable_by?(current_user.id) && current_user.id != note.user_id %> + <%= hidden_field_tag :note_id, note.id, :class => "comment_id" %> + <%= link_to _('Remove'),"#", :class => "dmp_table_link archive_comment_button" %> <% end%> <%end%> @@ -60,10 +56,10 @@
      -<% notes_not_archived = notes.select { |n| n["archived"].nil? } %> -<% latest_note = notes_not_archived.sort { |x,y| y["updated_at"] <=> x["updated_at"] }.first %> +<% notes_not_archived = notes.select { |n| n.archived.nil? } %> +<% latest_note = notes_not_archived.sort { |x,y| y.updated_at <=> x.updated_at }.first %> <% if !latest_note.nil? then%> -
      " class ="view_comment_class"> +
      <%= render :partial => "view_note", locals: {note: latest_note} %>
      diff --git a/app/views/phases/_note.html.erb b/app/views/phases/_note.html.erb index 659738a..ce15d4c 100644 --- a/app/views/phases/_note.html.erb +++ b/app/views/phases/_note.html.erb @@ -1,36 +1,36 @@ - <% if answer.present? && answer.has_key?("notes") %> - <% notes = answer["notes"] %> - <% answerid = answer["id"] %> - <%= hidden_field_tag :answer_id, answer["id"] %> + <% if answer.present? && answer.notes.any? %> + <% notes = answer.notes.all.to_a.sort! {|x,y| y["updated_at"] <=> x["updated_at"] } %> + <% answerid = answer.id %> + <%= hidden_field_tag :answer_id, answer.id %>
      - <%= link_to t("helpers.comments.add_comment_label"),'#', :class => "btn btn-primary add_comment_button" %> + <%= link_to _('Add note'),'#', :class => "btn btn-primary add_comment_button" %>
      - <%= render :partial => "list_notes", locals: {question: question, notes: notes, plan:plan} %> + <%= render :partial => "list_notes", locals: {question_id: question.id, notes: notes, plan: plan} %>
      - <%= link_to t("helpers.comments.add_comment_label"),'#', :class => "btn btn-primary add_comment_button" %> + <%= link_to _('Add note'),'#', :class => "btn btn-primary add_comment_button" %>
      <% else%> - <%= t("helpers.comments.add_comment_text")%> - <%= render :partial => "add_note", locals: {answer: answer, answer_obj: answer_obj, question: question, plan_data: plan_data}%> + <%= _('Share note with collaborators')%> + <%= render :partial => "add_note", locals: {answer: answer, question: question, plan_id: plan.id }%> <% end%> diff --git a/app/views/phases/_show_phase.html.erb b/app/views/phases/_show_phase.html.erb new file mode 100644 index 0000000..0fb55d0 --- /dev/null +++ b/app/views/phases/_show_phase.html.erb @@ -0,0 +1,37 @@ + + +

      + <%= _('Phase details')%> + + + <% if @phase.modifiable %> +
      + <%= link_to _('Edit phase details'), '#', class: "btn btn-primary", id: "edit_phase_button"%> +
      + <% end %> +

      + +<% if @phase.template.org.not_funder %> +
      + <%= raw _('

      Here you set the title that users will see. If you intend to have multiple phases for you DMP, this should be clear in the title and description.

      ')%> +

      +<% end %> + +
      +
      + + + + + + + + + + + + + + +
      <%= _('Title') %><%= @phase.title %>
      <%= _('Order of display') %><%= @phase.number %>
      <%= _('Description') %><%= raw @phase.description %>
      +
      diff --git a/app/views/phases/_view_note.html.erb b/app/views/phases/_view_note.html.erb index 2a1d14a..2e60684 100644 --- a/app/views/phases/_view_note.html.erb +++ b/app/views/phases/_view_note.html.erb @@ -4,7 +4,7 @@
        -
      • <%= t("helpers.comments.commented_by")%>

      • +
      • <%= _('Noted by:')%>

      • <%= user.name%> (<%= l note["updated_at"], format: :custom %>)
      • <%= raw note["text"] %>
      diff --git a/app/views/phases/admin_add.html.erb b/app/views/phases/admin_add.html.erb new file mode 100644 index 0000000..ce326b8 --- /dev/null +++ b/app/views/phases/admin_add.html.erb @@ -0,0 +1,75 @@ +<%- model_class = Phase -%> +<%= stylesheet_link_tag "admin" %> +<% javascript "admin.js" %> + +

      + <%= @template.title %> + +
      + <%= link_to _('View all templates'), + admin_index_template_path, + class: "btn btn-primary" %> +
      +

      + +
      + + +<%= render partial: "templates/admin_nav_tabs", locals: {template: @template, active: "add_plan"} %> + + +
      +
      + + +
      +
      + + + <%= form_for :phase, url: { admin_create_phase_path} do |f| %> +

      + <%= _('Phase details')%> +

      + <%= raw _('When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions.')%> +
      +
      + <%= f.hidden_field :template_id, value: @template.id%> + + + + + + + + + + + + + +
      <%= _('Title') %><%= f.text_field :title, + as: :string, + class: "text_field has-tooltip", "data-toggle" => "tooltip", "title" => _('Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP') %>
      <%= _('Order of display') %><%= f.number_field :number, in: 1..5, class: "number_field has-tooltip", "data-toggle" => "tooltip", title: _('This allows you to order the phases of your template.') %>
      <%= _('Description') %> +
      + <%= text_area_tag("phase-desc","" , class: "tinymce") %> +
      +
      + <%= link_to( image_tag("help_button.png"), "#", class: "phase_desc_popover", rel: "popover", "data-html" => "true", "data-content" => _("Enter a basic description. This will be presented to users on the 'Admin Plan' tab, above the summary of the sections and questions which they will be asked to answer."))%> +
      +
      +
      +
      + + +
      + <%= f.submit _('Save'), class: "btn btn-primary" %> + <%= link_to _('Cancel'), admin_template_template_path(@template), class: "btn cancel" %> +
      + + <%end%> +
      +
      +
      +
      + +<%= tinymce content_css: asset_path("application.css") %> \ No newline at end of file diff --git a/app/views/phases/admin_preview.html.erb b/app/views/phases/admin_preview.html.erb new file mode 100644 index 0000000..1f87258 --- /dev/null +++ b/app/views/phases/admin_preview.html.erb @@ -0,0 +1,59 @@ +<%- model_class = Phase -%> +<%= stylesheet_link_tag "admin" %> + +

      + <%= @template.title %> + +
      + <%= link_to _('Back to edit view'), + admin_show_phase_path(id: @phase.id, edit: "true"), + class: 'btn btn-primary' %> + <%= link_to _('View all templates'), + admin_index_template_path, + class: 'btn btn-primary' %> +
      +

      + +
      + + +<%= render partial: "templates/admin_nav_tabs", locals: {template: @template, active: @phase.id} %> + + +
      +
      + <% sections = @phase.sections %> + <% sections.order(:number).each do |section| %> +
      + +
      +
      + <%= raw section.description %> +
      +
      + <% last_question_id = section.questions.order("number DESC").first.id%> + + <% section.questions.order("number").each do |question| %> + + <%= render partial: 'question/preview_question', locals: {question: question}%> + <% if last_question_id == question.id then %> +
      + <% else %> +
      + <% end %> + + <% end %> +
      +
      +
      + <% end %> +
      +
      \ No newline at end of file diff --git a/app/views/phases/admin_show.html.erb b/app/views/phases/admin_show.html.erb new file mode 100644 index 0000000..8763623 --- /dev/null +++ b/app/views/phases/admin_show.html.erb @@ -0,0 +1,69 @@ +<%- model_class = Phase -%> +<%= stylesheet_link_tag "admin" %> +<% javascript 'admin.js' %> + +<%= tinymce content_css: asset_path('application.css') %> + +

      + <%= @phase.template.title %> + +
      + <%= link_to _('View all templates'), + admin_index_template_path, + class: 'btn btn-primary' %> +
      +

      + +
      + + +<%= render partial: "templates/admin_nav_tabs", locals: {template: @phase.template, active: @phase.id} %> + + +
      +
      + + +
      +
      + + +
      + <%= render partial: "show_phase", locals: {phase: @phase}%> +
      + <% if @phase.modifiable && @edit %> + + <% end %> +
      +
      + + + <% @sections.order("number ASC").each do |section| %> + <% if @edit && section.modifiable %> + <%= render partial: 'sections/edit_section', locals: {section: section, edit: @edit, phase: @phase} %> + <% else %> + <%= render partial: 'sections/show_section', locals: {section: section}%> + <% end %> + <% end %> + +
      +
      + + +<% if @edit || @phase.template.customization_of.present? %> + + + + +
      +
      + <%= link_to _('Add section'),'#', id: 'add_section_button', class: 'btn btn-primary' %> +
      +
      +<% end %> + + diff --git a/app/views/phases/edit.html.erb b/app/views/phases/edit.html.erb index 9b98568..3dbdc34 100644 --- a/app/views/phases/edit.html.erb +++ b/app/views/phases/edit.html.erb @@ -6,20 +6,19 @@ so if we come this way then we are editing a phase --> - -<%= render :partial => "/plans/plan_title", locals: {plan: @plan, plan_data: @plan_data} %> +<%= render :partial => "/plans/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.template.settings(:export).max_pages) + space_title = _('approx. %{space_used}%% of available space used (max %{num_pages} pages)') % { 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")%> - ;" title="<%= answered -%> <%= t("helpers.project.questions_answered")%>"> + <%= answered -%> <%= _('questions answered')%> + ;" title="<%= answered -%> <%= _('questions answered')%>">

      @@ -30,18 +29,16 @@
      - -<%= render :partial => "/plans/plan_nav_tabs", locals: {plan: @plan, plan_data: @plan_data, active: @phase.title } %> - +<%= render :partial => "/plans/plan_nav_tabs", locals: {plan: @plan, active: @phase.title} %>
      - <% @phase_data["sections"].each do |section| %> + <% @phase.sections.each do |section| %> - <% sectionid = section["id"] %> + <% sectionid = section.id %> <% if session[:question_id_comments].to_i != 0 then %> @@ -51,13 +48,11 @@ <%end%> <% end%> - -
      - <% num_section_questions = section["questions"].count %> - <% num_section_answers = section["nanswers"] %> + <% num_section_questions = section.questions.to_a.count %> + <% num_section_answers = section.num_answered_questions(@plan.id) %> <% question_word = "questions" %> <% if num_section_questions == 1 then %> <% question_word = "question" %> @@ -66,9 +61,9 @@
      - "> -
      "> - <%= section["title"] %> + +
      + <%= section.title %> <% if num_section_questions.to_i > num_section_answers.to_i then %> (<%= section_status %>) <% else %> @@ -84,7 +79,7 @@
      - <%= raw section["description"] %> + <%= raw section.description %>
      <%= render :partial => "plans/export", locals: {plan: @plan, plan_data: @plan_data} %> diff --git a/app/views/plans/_answer_form.html.erb b/app/views/plans/_answer_form.html.erb index dd256e4..1d17c20 100644 --- a/app/views/plans/_answer_form.html.erb +++ b/app/views/plans/_answer_form.html.erb @@ -33,9 +33,9 @@
      <% if suggested_answer.is_example? then %> - <%= t("org_admin.questions.example_answer_label")%> + <%= _('Example of answer')%> <%else%> - <%= t("org_admin.questions.suggested_answer_label")%> + <%= _('Suggested answer')%> <%end%>
      @@ -97,7 +97,7 @@ <% end %> <% if question.option_comment_display == true then%> - <%= label_tag("answer-text-#{question.id}".to_sym, t("helpers.comment")) %> + <%= label_tag("answer-text-#{question.id}".to_sym, _('Comment')) %> <%= text_area_tag("answer-text-#{question.id}".to_sym, answer.text, class: "tinymce") %> <%end%> @@ -114,12 +114,12 @@ <%= f.actions do %> <% if readonly then %> - <%= f.action :submit, :label => t("helpers.save"), :button_html => { :class => "btn btn-primary"}, :input_html => { :disabled => true } %> + <%= f.action :submit, :label => _('Save'), :button_html => { :class => "btn btn-primary"}, :input_html => { :disabled => true } %> <% else %> - + <% end %> - + <% end %> <% end %>
      @@ -148,11 +148,11 @@
      <% if answer.created_at.nil? then %> - <%= t("helpers.notanswered") %> + <%= _('Not answered yet') %> <% else %> - <%= t("helpers.answered_by")%><%= answer.created_at %><%= t("helpers.answered_by_part2")%><%= answer.user.name %> + <%= _('Answered')%><%= answer.created_at %><%= _(' by')%><%= answer.user.name %> <% end %> - +
      @@ -168,14 +168,14 @@ <% css_style_comment_div = "display: none;"%> <% css_style_guidance_div = ""%>
    • - <%= link_to t("helpers.guidance_accordion_label"), "#", :class => "guidance_accordion_button" %> + <%= link_to _('Guidance'), "#", :class => "guidance_accordion_button" %>
    • <% if @comments.count > 0 then%> - <% comments_label_with_count = "#{t("helpers.comment_accordion_label")} (#{@comments.count})"%> + <% comments_label_with_count = "#{_('Notes')} (#{@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" %> + <%= link_to _('Share note'), "#", :class => "comments_accordion_button" %> <%end%>
    • <%else%> @@ -184,10 +184,10 @@ <% 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 = "#{_('Notes')} (#{@comments.count})"%>

      <%= comments_label_with_count %>

      <%else%> -

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

      +

      <%= _('Share note') %>

      <%end%>
    • <%end%> @@ -206,9 +206,9 @@
      <%= question.section.organisation.abbreviation %> <%if question.section.organisation.abbreviation == "EPSRC" then %> - <%= t("helpers.policy_expectations")%> + <%= _('Policy Expectations')%> <%else%> - <%= t("helpers.guidance")%> + <%= _('Guidance')%> <%end%>
      diff --git a/app/views/plans/_dropdowns_new_plan.html.erb b/app/views/plans/_dropdowns_new_plan.html.erb index 5413579..1fb8708 100644 --- a/app/views/plans/_dropdowns_new_plan.html.erb +++ b/app/views/plans/_dropdowns_new_plan.html.erb @@ -5,9 +5,9 @@ <%= hidden_field_tag :default_tag, "false" ,:id => "default_tag" %>
      -

      <%= t('helpers.project.create_page.title') %>

      +

      <%= _('Create a new plan') %>

      -

      <%= raw t('helpers.project.create_page.desc_html')%>

      +

      <%= raw _("

      Please select from the following drop-downs so we can determine what questions and guidance should be displayed in your plan.

      If you aren't responding to specific requirements from a funder or an institution, select here to write a generic DMP based on the most common themes.

      ")%>

      @@ -19,9 +19,9 @@ <%= f.input :funder_id, :as => :select, :collection => @funders, - :label => t('helpers.project.create_page.funders_question'), + :label => _('If applying for funding, select your research funder.'), :input_html => { :multiple => false, :class => ["select2", "select2-container"] }, - :include_blank => constant("organisation_types.funder") %> + :include_blank => _('Select Funder') %>
      @@ -35,7 +35,7 @@ <%= f.action :submit, :as => :button, :input_html => { :id => "create-plan-button", :class => "btn btn-primary"}, - :label => t('helpers.project.create') %> + :label => _('Create plan') %> <% end %> <% end %> diff --git a/app/views/plans/_export.html.erb b/app/views/plans/_export.html.erb index 876ab64..2d53826 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/_form.html.erb b/app/views/plans/_form.html.erb index b7424e0..4c4404a 100644 --- a/app/views/plans/_form.html.erb +++ b/app/views/plans/_form.html.erb @@ -26,7 +26,7 @@
      <%= f.submit nil, :class => 'btn btn-primary' %> - <%= link_to t('.cancel', :default => t("helpers.links.cancel")), - plans_path, :class => 'btn' %> + <%= link_to _('helpers.links.cancel'), + plans_path, :class => 'btn' %>
      <% end %> diff --git a/app/views/plans/_guidance_settings.html.erb b/app/views/plans/_guidance_settings.html.erb index 946c2e7..7b48331 100644 --- a/app/views/plans/_guidance_settings.html.erb +++ b/app/views/plans/_guidance_settings.html.erb @@ -1,7 +1,7 @@