diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index 40441b0..d1d3284 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -1,56 +1,45 @@ -
-
-
- -

<%= _('Welcome.')%>

- <%= raw _('

%{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

') % {:application_name => Rails.configuration.branding[:application][:name], :organisation_name => Rails.configuration.branding[:organisation][:name]} %> -
-

<%= _('Screencast on how to use %{application_name}') % {:application_name => Rails.configuration.branding[:application][:name]} %>

-
- -
-
-
-
-
-
- -
-
- <%= render :partial => 'shared/login_form' %> -
-
-
-
-
- - <%= _('Sign up') %> -

- <%= _('New to %{application_name}? Sign up today.') % {:application_name => Rails.configuration.branding[:application][:name]} %> -

- -
-
-
- <%= render :partial => 'shared/register_form', locals: {extended: false} %> -
-
-
-
-
-
-
\ No newline at end of file +<%= javascript 'registrations/sign_in_sign_up.js' %> + +

<%= _('Welcome.')%>

+ +
+
+ <%= raw _('

%{application_name} has been jointly developed by the %{organisation_name} to help you write data management plans.

') % {:application_name => Rails.configuration.branding[:application][:name], :organisation_name => Rails.configuration.branding[:organisation][:name]} %> +
+

<%= _('Screencast on how to use %{application_name}') % {:application_name => Rails.configuration.branding[:application][:name]} %>

+
+ +
+
+ +
+
+ + +
+
+ <%= render :partial => 'shared/login_form' %> +
+ + +
+
+
+
+
diff --git a/app/views/shared/_accessible_input_email.html.erb b/app/views/shared/_accessible_input_email.html.erb new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/views/shared/_accessible_input_email.html.erb diff --git a/app/views/shared/_accessible_submit_button.html.erb b/app/views/shared/_accessible_submit_button.html.erb index 2966a91..b4f9b73 100644 --- a/app/views/shared/_accessible_submit_button.html.erb +++ b/app/views/shared/_accessible_submit_button.html.erb @@ -1,6 +1,6 @@ diff --git a/app/views/shared/_login_form.html.erb b/app/views/shared/_login_form.html.erb index 5bf1449..8a899b2 100644 --- a/app/views/shared/_login_form.html.erb +++ b/app/views/shared/_login_form.html.erb @@ -1,36 +1,53 @@ -<%= form_for(resource, :as => "user", :url => user_session_path) do |f| %> - -<% end %> +

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

+ + + <% if Rails.application.config.shibboleth_enabled %> + <% if request.fullpath != "/users/sign_up?nosplash=true" && session[:shibboleth_data].nil? then%> + + <%else%> + <%= f.hidden_field :shibboleth_id, :value => session[:shibboleth_data][:uid] %> + <%end%> + <% end %> + + +

- <%= _('or') %> -

+ +<%= form_for resource, as: 'user', url: user_session_path, html: {class: "roadmap-form"} do |f| %> + <%= devise_error_messages! %> +
+
+ <%= f.label :email, _('Email') %> +
+ <%= _('Invalid email address') %> +
+ <%= f.email_field :email, as: :email, class: 'input-medium left-indent' %> +
+ +
+ <%= f.label :password, _('Password') %> +
+ <%= _('Passwords must be at least 8 characters') %> +
+ <%= f.password_field :password, as: :password, class: 'input-medium left-indent' %> +
+ +
+ <%= f.check_box :remember_me %> + <%= f.label :remember_me, _('Remember me'), class: "remember_div checkbox-label" %> + +
+ <%= render partial: 'shared/accessible_submit_button', + locals: {id: 'sign-in-button', + val: 'Sign In', + disabled_initially: true, + classes: 'small-input-button', + tooltip: _('Enter your email and password.')} %> + + +
+ +<% end %> \ No newline at end of file diff --git a/app/views/shared/_register_form.html.erb b/app/views/shared/_register_form.html.erb index b1188d4..96ffa9a 100644 --- a/app/views/shared/_register_form.html.erb +++ b/app/views/shared/_register_form.html.erb @@ -1,65 +1,36 @@ -<% javascript "shared/register_form.js" %> - -<%= form_for(resource, :as => "user", :url => registration_path("user"), :htmlb => {:autocomplete =>"off"}, :html => {class: "roadmap-form"}) do |f| %> - + classes: 'small-input-button', + tooltip: _('Enter your name, email and password.')} %> + <% end %> diff --git a/config/application.rb b/config/application.rb index 5693427..12d93d4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -78,8 +78,10 @@ config.assets.precompile += %w(admin.js) config.assets.precompile += %w(admin.css) + config.assets.precompile += %w(roadmap.js) config.assets.precompile += %w(roadmap-form.scss) config.assets.precompile += %w(plans/new_plan.js) + config.assets.precompile += %w(registrations/sign_in_sign_up.js) config.assets.precompile += %w(contacts/new_contact.js) config.assets.precompile += %w(shared/register_form.js) config.assets.precompile += %w(answers/status.js) diff --git a/db/migrate/20170516184429_add_recovery_email_to_users.rb b/db/migrate/20170516184429_add_recovery_email_to_users.rb new file mode 100644 index 0000000..09034ac --- /dev/null +++ b/db/migrate/20170516184429_add_recovery_email_to_users.rb @@ -0,0 +1,5 @@ +class AddRecoveryEmailToUsers < ActiveRecord::Migration + def change + add_column :users, :recovery_email, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index fd97cce..c139826 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,10 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170428083711) do - - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" +ActiveRecord::Schema.define(version: 20170516184429) do create_table "annotations", force: :cascade do |t| t.integer "question_id" @@ -40,8 +37,8 @@ t.integer "question_option_id", null: false end - add_index "answers_question_options", ["answer_id", "question_option_id"], name: "answer_question_option_index", using: :btree - add_index "answers_question_options", ["question_option_id", "answer_id"], name: "question_option_answer_index", using: :btree + add_index "answers_question_options", ["answer_id", "question_option_id"], name: "answer_question_option_index" + add_index "answers_question_options", ["question_option_id", "answer_id"], name: "question_option_answer_index" create_table "exported_plans", force: :cascade do |t| t.integer "plan_id" @@ -74,15 +71,15 @@ end create_table "friendly_id_slugs", force: :cascade do |t| - t.string "slug", null: false - t.integer "sluggable_id", null: false - t.string "sluggable_type", limit: 40 + t.string "slug", null: false + t.integer "sluggable_id", null: false + t.string "sluggable_type" t.datetime "created_at" end - add_index "friendly_id_slugs", ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type", unique: true, using: :btree - add_index "friendly_id_slugs", ["sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_id", using: :btree - add_index "friendly_id_slugs", ["sluggable_type"], name: "index_friendly_id_slugs_on_sluggable_type", using: :btree + add_index "friendly_id_slugs", ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type", unique: true + add_index "friendly_id_slugs", ["sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_id" + add_index "friendly_id_slugs", ["sluggable_type"], name: "index_friendly_id_slugs_on_sluggable_type" create_table "guidance_groups", force: :cascade do |t| t.string "name" @@ -103,8 +100,8 @@ end create_table "identifier_schemes", force: :cascade do |t| - t.string "name" - t.string "description" + t.string "name", limit: 255 + t.string "description", limit: 255 t.boolean "active" t.datetime "created_at" t.datetime "updated_at" @@ -162,8 +159,8 @@ t.datetime "updated_at", null: false end - add_index "perms", ["name"], name: "index_perms_on_name", using: :btree - add_index "perms", ["name"], name: "index_roles_on_name_and_resource_type_and_resource_id", using: :btree + add_index "perms", ["name"], name: "index_perms_on_name" + add_index "perms", ["name"], name: "index_roles_on_name_and_resource_type_and_resource_id" create_table "phases", force: :cascade do |t| t.string "title" @@ -238,8 +235,8 @@ t.integer "theme_id", null: false end - add_index "questions_themes", ["question_id", "theme_id"], name: "question_theme_index", using: :btree - add_index "questions_themes", ["theme_id", "question_id"], name: "theme_question_index", using: :btree + add_index "questions_themes", ["question_id", "theme_id"], name: "question_theme_index" + add_index "questions_themes", ["theme_id", "question_id"], name: "theme_question_index" create_table "regions", force: :cascade do |t| t.string "abbreviation" @@ -278,7 +275,7 @@ t.datetime "updated_at", null: false end - add_index "settings", ["target_type", "target_id", "var"], name: "index_settings_on_target_type_and_target_id_and_var", unique: true, using: :btree + add_index "settings", ["target_type", "target_id", "var"], name: "index_settings_on_target_type_and_target_id_and_var", unique: true create_table "splash_logs", force: :cascade do |t| t.string "destination" @@ -365,12 +362,13 @@ t.integer "invited_by_id" t.string "invited_by_type" t.integer "language_id" + t.string "recovery_email" end - add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree - add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree - add_index "users", ["invitation_token"], name: "index_users_on_invitation_token", unique: true, using: :btree - add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree + add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true + add_index "users", ["email"], name: "index_users_on_email", unique: true + add_index "users", ["invitation_token"], name: "index_users_on_invitation_token", unique: true + add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true create_table "users_perms", id: false, force: :cascade do |t| t.integer "user_id" diff --git a/lib/assets/javascripts/application.js b/lib/assets/javascripts/application.js index 3f45565..d433315 100644 --- a/lib/assets/javascripts/application.js +++ b/lib/assets/javascripts/application.js @@ -22,7 +22,7 @@ //= require_tree ./locale //= require gettext/all //= require jquery-accessible-autocomplet-list-aria.js - +//= require roadmap.js $( document ).ready(function() { diff --git a/lib/assets/javascripts/registrations/sign_in_sign_up.js b/lib/assets/javascripts/registrations/sign_in_sign_up.js new file mode 100644 index 0000000..c6b55ae --- /dev/null +++ b/lib/assets/javascripts/registrations/sign_in_sign_up.js @@ -0,0 +1,66 @@ +$(document).ready(function(){ + + $(".tab-panels div.tab-panel:not(.active)").hide(); + + $(".tabs li a").click(function(e){ + e.preventDefault(); + + // Make the clicked tab the active tab + $(this).parent().addClass('active'); + $(this).attr('aria-selected', 'true'); + $.each($(this).parent().siblings(), function(i, sib){ + $(sib).removeClass('active'); + $(sib).find('> a').attr('aria-selected', 'false'); + }); + + // Make the corresponding panel visible and the others hidden + let panel = $($(this).attr("href")); + panel.show().attr("aria-hidden", 'false'); + $.each($(panel).siblings(), function(i, p){ + $(p).hide().attr("aria-hidden", 'true'); + }); + }); + + // If the hidden valid-form field is set to true then enable the submit button + $("#valid-form").change(function(){ + $(this).siblings(".form-submit").attr('aria-disabled', $(this).val() != "true"); + }); + +/* $("input[type='email']").change(function(){ + toggleError(this, validateEmail($(this).val().trim())); + }); +*/ + $("input[name*='password']").change(function(){ + toggleError(this, validatePassword($(this).val().trim())); + }); + + $("input[class='required']").change(function(){ + toggleSubmit(); + }) +}); + +function toggleError(input, valid){ + if(valid){ + $(input).siblings('.' + $(input).attr('id') + '-error').hide(); + $(input).removeClass('red-border'); + }else{ + $(input).siblings('.' + $(input).attr('id') + '-error').show(); + $(input).addClass('red-border'); + } +} + +function toggleSignInSubmit(){ + let disabled = ($("#user_email").val().trim().length <= 0 || + $("#user_password").val().trim().length <= 0); + $("#sign-in-button").attr('aria-disabled', disabled); +} + +function toggleRegisterSubmit(){ + let disabled = ($("#user_firstname").val().trim().length <= 0 || + $("#user_surname").val().trim().length <= 0 || + $("#user_email").val().trim().length <= 0 || + $("#user_recovery_email").val().trim().length <= 0 || + $("#user_password").val().trim().length <= 0 || + $("#user_email").val() === $("#user_recovery_email").val()); + $("#register-button").attr('aria-disabled', disabled); +} \ No newline at end of file diff --git a/lib/assets/javascripts/roadmap.js b/lib/assets/javascripts/roadmap.js new file mode 100644 index 0000000..82f0d15 --- /dev/null +++ b/lib/assets/javascripts/roadmap.js @@ -0,0 +1,29 @@ +$(document).ready(function(){ + + $('input[type="email"]').on('change', function(){ + if(!validateEmail($(this).val().trim())){ + $("#" + $(this).attr('id') + "_tip").attr('role', 'tooltip'); + }else{ + $("#" + $(this).attr('id') + "_tip").attr('role', ''); + } + }); + + $('input[name*="password"]').on('change', function(){ + if(!validatePassword($(this).val().trim())){ + $("#" + $(this).attr('id') + "_tip").attr('role', 'tooltip'); + }else{ + $("#" + $(this).attr('id') + "_tip").attr('role', ''); + } + }); +}); + + +// --------------------------------------------------------------------------- +function validatePassword(sPassword) { + if (sPassword.trim().length >= 8 && sPassword.trim().length <= 128){ + return true; + } + else { + return false; + } +} \ No newline at end of file diff --git a/lib/assets/stylesheets/roadmap-form.scss b/lib/assets/stylesheets/roadmap-form.scss index 5a860ae..e53bdd4 100644 --- a/lib/assets/stylesheets/roadmap-form.scss +++ b/lib/assets/stylesheets/roadmap-form.scss @@ -4,7 +4,10 @@ $header-font: "GillSansLight"; $white: #FFF; +$error-color: #CC0000; +$error-background: #FFE6E6; $dark-grey: #333; +$light-grey: #CCC; $primary-color: #F49700; $primary-admin-color: #0057A7; @@ -18,6 +21,25 @@ @extend .fa-#{$icon}:before; } +/* ========================================================= */ +/* NULL OUT OLD BOOTSTRAP_AND_OVERRIDES STYLING */ +/* ========================================================= */ +#new_user input { + width: 350px; +} +#new_user input[type="checkbox"]{ + width: auto; +} +#new_user input[type="submit"] { + width: 150px; + margin-left: 15px; +} +/* ========================================================= */ + +.primary-color { + color: $primary-color; +} + .arrow-left { display: inline-block; width: 0; @@ -31,18 +53,107 @@ margin-bottom: 20px; } -.content-box { +.content-two-column { + width: 98%; + .column-left { + display: inline-block; + width: 55%; + } + .column-right { + display: inline-block; + width: 40%; + margin-left: 35px; + vertical-align: top; + } } +.inline { + display: inline-block; +} +.centered { + text-align: center; +} + +/* Roadmap Tab Styling */ +/* ------------------------------------------------ */ +.tabs { + list-style: none; + margin: 0; + + li { + display: inline; + + a { + position: relative; + float: left; + display: block; + padding: 10px 35px; + margin-left: -1px; + left: 1px; + color: $white; + background-color: $primary-color; + text-decoration: none; + font-weight: bold; + } + } + li a:hover, + li.active a, + li.active a:hover { + color: $primary-color; + background-color: $white; + } +} +.tabs:after { + visibility: hidden; + display: block; + font-size: 0; + content: ""; + clear: both; + height: 0; +} +.tab-panels { + position: relative; + min-height: 250px; +} +.tabbed-area div.tab-panel { + background: white; + padding: 20px; + min-height: 250px; + position: absolute; + top: -1px; + left: 0; + width: 100%; +} +.tab-panel div.active { + z-index: 1; +} + + /* Roadmap Form Styling */ /* ------------------------------------------------ */ form.roadmap-form { + text-align: left; fieldset.padded { padding: 10px 10px 25px 10px; } + .red-border { + border: 1px solid $error-color; + } + span[class*='error'] { + float: right; + background-color: $error-background; + color: $error-color; + padding: 5px; + margin-bottom: 5px; + + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + } + /* Fieldset with labels over inputs */ fieldset.standard { padding: 5px; @@ -151,9 +262,10 @@ input.form-submit { background-color: $primary-color; color: $reverse-text; - font-size: 14px; padding: 4px 12px; - + font-size: 14px; + margin-top: 15px; + -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; @@ -171,8 +283,8 @@ button.form-cancel { background-color: $cancel-button-color; color: $reverse-text; - font-size: 14px; padding: 4px 12px; + font-size: 14px; -webkit-border-radius: 5px; -moz-border-radius: 5px; @@ -196,6 +308,24 @@ border-radius: 5px; } } + input.small-input-button { + width: 250px; + } + + div.form-input { + position: relative; + } + .error-tooltip { + display: none; + position: absolute; + top: 0; + right: 0; + z-index: 1; + } + .error-tooltip[role='tooltip'] { + display: inline-block; + } + } /* Accessible JQuery combobox */ @@ -256,4 +386,55 @@ /* http://geektnt.com/how-to-remove-x-from-search-input-field-on-chrome-and-ie.html */ .js-combobox[type=text]::-ms-clear { display: none; width: 0; height: 0; } -.js-combobox[type=text]::-ms-reveal { display: none; width: 0; height: 0; } \ No newline at end of file +.js-combobox[type=text]::-ms-reveal { display: none; width: 0; height: 0; } + + + +/* ------------------------------------------------ */ +/* ------------------------------------------------ */ +/* Page specific styling */ +/* ------------------------------------------------ */ +/* ------------------------------------------------ */ + +/* Login form */ +/* ------------------------------------------------ */ +.omniauth-options { + display: block; + width: 100%; + + .omniauth-login { + width: 410px; + padding: 4px 12px; + background-color: $primary-color; + color: $white; + margin: 0 auto 10px auto; + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + } +} +#new_user fieldset { + input[type="password"], + input[type="email"] { + width: 392px; + } +} +#new_user.user-registration { + #user_firstname, + #user_surname { + width: 150px; + } + input[type="password"], + input[type="email"] { + width: 332px; + } +} +div#forgot-password-link { + vertical-align: bottom; + margin-bottom: 5px; + + a:hover { + color: $primary-color !important; /* Remove the important once the bootstrap_and_overrides css is gone */ + } +} \ No newline at end of file