diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index e5db539..f844cbd 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -85,15 +85,15 @@ if !default.nil? && default == @plan.template # We used the generic/default template - msg += _('This plan is based on the default template.') + msg += " #{_('This plan is based on the default template.')}" elsif !@plan.template.customization_of.nil? # We used a customized version of the the funder template - msg += "#{_('This plan is based on the')} #{plan_params[:funder_name]} #{_('template with customisations by the')} #{plan_params[:org_name]}" + msg += " #{_('This plan is based on the')} #{plan_params[:funder_name]} #{_('template with customisations by the')} #{plan_params[:org_name]}" else # We used the specified org's or funder's template - msg += "#{_('This plan is based on the')} #{@plan.template.org.name} template." + msg += " #{_('This plan is based on the')} #{@plan.template.org.name} template." end flash[:notice] = msg @@ -208,6 +208,8 @@ authorize @plan attrs = plan_params +# attrs[:visibility] = attrs[:visibility].to_sym + # Save the guidance group selections guidance_group_ids = params[:guidance_group_ids].blank? ? [] : params[:guidance_group_ids].map(&:to_i) save_guidance_selections(guidance_group_ids) @@ -239,6 +241,7 @@ @plan = Plan.find(params[:id]) authorize @plan @visibility = @plan.visibility.present? ? @plan.visibility.to_s : Rails.application.config.default_plan_visibility + @allow_visibility = (@plan.num_answered_questions >= 1 && !@plan.is_test?) end @@ -412,6 +415,17 @@ end end + def set_test + plan = Plan.find(params[:id]) + authorize plan + plan.visibility = "#{plan_params[:visibility]}" + if plan.save + render json: {code: 1, msg: (plan.is_test? ? _('Your project is now a test.') : _('Your project is no longer a test.') )} + else + render json: {code: 0, msg: _("Unable to change the plan's test status")} + end + end + private diff --git a/app/helpers/plans_helper.rb b/app/helpers/plans_helper.rb index c4f3af4..d61258d 100644 --- a/app/helpers/plans_helper.rb +++ b/app/helpers/plans_helper.rb @@ -42,8 +42,10 @@ return "#{_('Institution')}" when 'publicly_visible' return "#{_('Public')}" + when 'privately_visible' + return "#{_('Private')}" else - return "#{_('Private')}" # Both Test and Private + return "#{_('N/A')}" # Test Plans end end diff --git a/app/policies/plan_policy.rb b/app/policies/plan_policy.rb index e6d6d15..448a3c4 100644 --- a/app/policies/plan_policy.rb +++ b/app/policies/plan_policy.rb @@ -56,6 +56,10 @@ @plan.administerable_by?(@user.id) end + def set_test? + @plan.administerable_by?(@user.id) + end + # TODO: These routes are no lonmger used =begin def section_answers? diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index db53c0d..86bdedf 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -63,14 +63,17 @@ <%= render "layouts/header" %> -
- <% end %> diff --git a/app/views/plans/share.html.erb b/app/views/plans/share.html.erb index 860300e..c479a9c 100644 --- a/app/views/plans/share.html.erb +++ b/app/views/plans/share.html.erb @@ -37,16 +37,19 @@ <% end %> diff --git a/app/views/shared/_accessible_submit_button.html.erb b/app/views/shared/_accessible_submit_button.html.erb index 497c1e8..7d53835 100644 --- a/app/views/shared/_accessible_submit_button.html.erb +++ b/app/views/shared/_accessible_submit_button.html.erb @@ -14,7 +14,7 @@ $("#<%= id %>").on('click focus', function(e){ if($(this).attr('aria-disabled') == 'true'){ e.preventDefault(); - $(this).siblings(".error-tooltip-right").attr('role', 'tooltip'); + $(this).siblings(".error-tooltip-right").attr('role', 'alert'); }else{ $(this).siblings(".error-tooltip-right").attr('role', ''); } diff --git a/config/routes.rb b/config/routes.rb index 9d0e26f..3343ab9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -215,6 +215,7 @@ get 'export' post 'invite' post 'visibility', constraints: {format: [:json]} + post 'set_test', constraints: {format: [:json]} end collection do diff --git a/lib/assets/javascripts/dmproadmap/forms.js b/lib/assets/javascripts/dmproadmap/forms.js index 228c0ae..afca2cf 100644 --- a/lib/assets/javascripts/dmproadmap/forms.js +++ b/lib/assets/javascripts/dmproadmap/forms.js @@ -1,4 +1,4 @@ -// +// --------------------------------------------------------------------------- function remoteSave(target, method, data){ $("div.roadmap-info-box span:not(.aria-only)").parent().css('visibility', 'hidden').fadeOut() @@ -10,8 +10,9 @@ contentType: 'application/json', accepts: 'application/json' }).done(function(data){ - $("div.roadmap-info-box span:not(.aria-only)").html(data['msg']).css('width', 'auto') + $("#notification-area span:not(.aria-only)").html(data['msg']).css('width', 'auto') .attr('role', (data['code'] === 1 ? 'status' : 'alert')) + .attr('class', (data['code'] === 1 ? 'roadmap-info-box' : 'roadmap-alert-box')) .parent().css('visibility', 'visible').fadeIn(); }); } @@ -37,19 +38,19 @@ } // --------------------------------------------------------------------------- -function toggleInputError(input, errorMessage){ +function toggleInputError(input, errorMessage, allowBlank = true){ var err = $(input).siblings("span.error-tooltip"); if(err.length <= 0){ err = $(input).siblings("span.error-tooltip-right"); } // If an error element is available and the error message is not empty and the field - // is not empty - if(err.length > 0 && (errorMessage === '' || $(input).val().trim().length <= 0)){ + // is not empty (unless its a required field!) + if(err.length > 0 && (errorMessage === '' || (allowBlank && $(input).val().trim().length <= 0))){ err.html('').attr('role', ''); $(input).removeClass('red-border'); }else{ - err.html(errorMessage).attr('role', 'tooltip'); + err.html(errorMessage).attr('role', 'alert'); $(input).addClass('red-border'); } } @@ -69,6 +70,6 @@ if(filter.test(sEmail)){ return ''; }else{ - return __('Invalid Email'); + return __('Invalid email address'); } } \ No newline at end of file diff --git a/lib/assets/javascripts/views/plans/index.js b/lib/assets/javascripts/views/plans/index.js index d6261b5..3488362 100644 --- a/lib/assets/javascripts/views/plans/index.js +++ b/lib/assets/javascripts/views/plans/index.js @@ -1,23 +1,12 @@ $(document).ready(function(){ $("input[type='checkbox']").on('click, change', function(e){ - var self = this; var id = $(this).attr("id").replace("is_test-", ""); var params = {plan: {visibility: $(this).is(':checked') ? 'is_test' : 'privately_visible'}}; - - // Update the visbility to test or private - $.post("/plans/" + id + "/visibility", params, function(data){ - if(data['code'] === 1){ - var msg = ($(self).is(':checked') ? __('The plan is now a test.') : __('The plan is no longer a test.')); - // If the save was successful make sure the Visibility text gets updated to 'Private' - $("div.roadmap-info-box span:not(.aria-only)").html(msg).attr('role', 'status') - .css('width', 'auto').parent().css('visibility', 'visible'); - $(self).parent().siblings("#visibility-" + id).html(__('Private')); - }else{ - // Display an error message - $("div.roadmap-alert-box span:not(.aria-only)").show().html(data['msg']) - .attr('role', 'alert').css('width', 'auto').css('visibility', 'visible'); - e.preventDefault(); - } - }); + remoteSave("/plans/" + id + "/set_test", 'POST', JSON.stringify(params)); + if($(this).is(':checked')){ + $("#visibility-" + id + " span").html(__('N/A')).attr('title', ''); + }else{ + $("#visibility-" + id + " span").html(__('Private')) + } }); }); \ No newline at end of file diff --git a/lib/assets/javascripts/views/plans/show.js b/lib/assets/javascripts/views/plans/show.js index 2018509..157ca48 100644 --- a/lib/assets/javascripts/views/plans/show.js +++ b/lib/assets/javascripts/views/plans/show.js @@ -1,10 +1,25 @@ $(document).ready(function(){ toggleDataContact(); + // Run the input validations when the focus changes + $("input[type='email']").on('blur', function(){ + toggleInputError(this, validateEmail($(this).val().trim())); + }).on('change keyup', function(){ + toggleProjectDetailsSubmit(); + }); + + $("#plan_title").on('blur', function(){ + toggleInputError(this, ($(this).val().trim().length <= 0 ? __('The title cannot be blank') : ''), false); + }); + $("#show-data-contact").click(function(){ toggleDataContact(); }) + $("#is_test").click(function(){ + $("#plan_visibility").val($(this).is(":checked") ? 'is_test' : 'privately_visible'); + }); + $("#show-other-guidance-orgs").click(function(){ if($("#other-guidance-orgs").css('display') === 'block'){ $("#other-guidance-orgs").hide(); @@ -15,6 +30,9 @@ } }); + // Check form validation on page load + toggleProjectDetailsSubmit(); + function toggleDataContact(){ if($("#show-data-contact").is(':checked')){ $(".data-contact-info").hide(); @@ -23,4 +41,19 @@ $(".data-contact-info").show(); } } + + function toggleProjectDetailsSubmit(){ + var piEmail = $("#plan_principal_investigator_email").val(); + var dcEmail = $("#plan_data_contact_email").val(); + var disabled = $("#plan_title").val() == undefined; + + if(piEmail.trim() != '' && !disabled){ + disabled = validateEmail(piEmail) != ''; + } + if(dcEmail.trim() != '' && !disabled){ + disabled = validateEmail(dcEmail) != ''; + } + + $("#save-details-button").attr('aria-disabled', disabled); + } }); \ No newline at end of file diff --git a/lib/assets/stylesheets/dmproadmap.scss b/lib/assets/stylesheets/dmproadmap.scss index 5a89958..14bc085 100644 --- a/lib/assets/stylesheets/dmproadmap.scss +++ b/lib/assets/stylesheets/dmproadmap.scss @@ -19,9 +19,18 @@ $highlight-color: $black; $highlight-background-color: #F36F24; -$error-color: #FFF; -$error-background: #827D7E; -$disabled-button-color: #CCC; +/* MESSAGES */ +$error-color: $white; +$error-background: #990000; + +$notice-color: $white; +$notice-background: #196719; + +$tooltip-color: $white; +$tooltip-background: #333; + +/* BUTTONS */ +$disabled-button-color: #808080; $cancel-button-color: #F17D04; /* HEADER STYLING */ @@ -33,4 +42,6 @@ /* HEADER LOGO POSITIONING */ $header-logo-top-margin: 20px; -$header-logo-left-margin: 10px; \ No newline at end of file +$header-logo-left-margin: 10px; + +$body-background: $light-grey; \ No newline at end of file diff --git a/lib/assets/stylesheets/dmproadmap/base.scss b/lib/assets/stylesheets/dmproadmap/base.scss index 8346ba2..607d53f 100644 --- a/lib/assets/stylesheets/dmproadmap/base.scss +++ b/lib/assets/stylesheets/dmproadmap/base.scss @@ -6,7 +6,7 @@ /* Main page layout: header, content, footer */ body { - background-color: $white; + background: $body-background; color: $black; font-family: $font-family; font-size: 14px; @@ -140,8 +140,8 @@ position: absolute; font-family: $font-family; font-size: 14px; - color: $white; - background-color: $dark-grey; + color: $tooltip-color; + background: $tooltip-background; border-radius: 3px; padding: 15px 20px; z-index: 10; @@ -160,8 +160,8 @@ position: absolute; top: 15px; width: 300px; - background-color: $dark-grey; - color: $white; + background: $tooltip-background; + color: $tooltip-color; padding: 6px 10px; border-radius: 3px; z-index: 9; @@ -357,8 +357,7 @@ position: relative; float: right; margin-top: 10px; - padding: 8px 30px; - border: 1px solid $dark-grey; + padding: 8px 30px 10px 60px; border-radius: 5px; vertical-align: middle; width: auto; @@ -378,17 +377,17 @@ } } div.roadmap-info-box { - color: $black; - background-color: $white; + color: $notice-color; + background: $notice-background; .fa { - color: green; + color: $notice-color; } } div.roadmap-alert-box { - color: $black; - background-color: $white; + color: $error-color; + background: $error-background; .fa { - color: red; + color: $error-color; } } @@ -400,10 +399,13 @@ div.page { position: relative; width: 100%; - background-color: $white; + background: $body-background; border-radius: 3px; div.content { + background-color: $white; + border-radius: 3px; + padding: 10px 15px 25px 15px; /* By default, page content is one column, but use the below styles to create a 2 column style */ div.column-left { diff --git a/lib/assets/stylesheets/dmproadmap/forms.scss b/lib/assets/stylesheets/dmproadmap/forms.scss index d6bbe7e..ce5c7ef 100644 --- a/lib/assets/stylesheets/dmproadmap/forms.scss +++ b/lib/assets/stylesheets/dmproadmap/forms.scss @@ -41,6 +41,10 @@ height: 65px; } +label.disabled { + color: $disabled-button-color; +} + .checkbox-label { display: inline-block; font-size: 1em; @@ -277,43 +281,41 @@ display: none; width: 45%; background: $error-background; - border-radius: 3px; + border-radius: 6px; color: $error-color; - padding: 4px 6px; + padding: 6px 25px 7px 10px; } - .error-tooltip[role='tooltip'], .submit-tooltip[role='tooltip'] { - top: 55px; + .error-tooltip[role='alert'], .submit-tooltip[role='tooltip'] { + top: 65px; left: 0; display: inline; position: absolute; z-index: 9; } - .error-tooltip[role='tooltip']:before, .submit-tooltip[role='tooltip']:before { + .error-tooltip[role='alert']:before, .submit-tooltip[role='tooltip']:before { display: inline; position: absolute; - top: -5px; - width: 0; - height: 0; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-bottom: 5px solid $error-background; + top: -30px; + margin: 0 auto; + @include icon(caret-up); + color: $error-background; + font-size: 44px; } - .error-tooltip-right[role="tooltip"] { + .error-tooltip-right[role="alert"], .error-tooltip-right[role="tooltip"] { top: 0; - left: 500px; + left: 400px; display: inline; } - .error-tooltip-right[role='tooltip']:before { + .error-tooltip-right[role='alert']:before, .error-tooltip-right[role="tooltip"] { display: inline; - position: absolute; - left: -5px; - width: 0; - height: 0; - border-top: 5px solid transparent; - border-right: 5px solid transparent; - border-bottom: 5px solid $error-background; + position: relative; + left: -23px; + top: 11px; + @include icon(caret-left); + color: $error-background; + font-size: 44px; } }