Skip to content

Commit

Permalink
Merge pull request #618 from cedarcode/jt--show_password
Browse files Browse the repository at this point in the history
Add button to show password on password fields
  • Loading branch information
joaquintomas2003 authored Jan 14, 2025
2 parents aa94e7b + bac4ed1 commit 0cf0e3b
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 57 deletions.
4 changes: 4 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,7 @@ body {
#butInstall {
padding-left: 0px;
}

.show-password-button {
margin-right: -20px;
}
15 changes: 15 additions & 0 deletions app/javascript/controllers/show_password_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
static targets = ["password", "icon"];

toggle() {
if (this.passwordTarget.type === "password") {
this.passwordTarget.type = "text";
this.iconTarget.innerHTML = "visibility_off";
} else {
this.passwordTarget.type = "password";
this.iconTarget.innerHTML = "visibility";
}
}
}
10 changes: 2 additions & 8 deletions app/views/devise/passwords/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,8 @@
<%= f.hidden_field :reset_password_token %>

<li class="form-input-container">
<div class="mdc-text-field mdc-text-field--filled <%='mdc-text-field--invalid mdc-text-field--with-trailing-icon' if resource.errors[:password].any? %>" data-controller="textfield">
<span class="mdc-text-field__ripple"></span>
<%= f.label :password, "Nueva contraseña", class: "mdc-floating-label" %>
<%= f.password_field :password, class: "mdc-text-field__input", autofocus: true %>
<%= render 'shared/invalid_icon', resource: resource, field: :password %>
<div class="mdc-line-ripple"></div>
</div>
<%= render 'shared/info_and_errors', resource: resource, field: :password, text: "#{@minimum_password_length} caracteres mínimo" %>
<%= render 'shared/password_field', f:, resource:, field: :password, label_text: "Nueva contraseña", autocomplete: "new-password", required: false %>
<%= render 'shared/info_and_errors', resource:, field: :password, text: "#{@minimum_password_length} caracteres mínimo" %>
</li>

<li class="form-input-container sign-in">
Expand Down
30 changes: 6 additions & 24 deletions app/views/devise/registrations/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,16 @@
"" %>
</li>
<li class="form-input-container">
<div class="mdc-text-field mdc-text-field--filled <%='mdc-text-field--invalid mdc-text-field--with-trailing-icon' if resource.errors[:password].any? %>" data-controller="textfield">
<span class="mdc-text-field__ripple"></span>
<%= f.label :password, "Nueva contraseña", class: "mdc-floating-label" %>
<%= f.password_field :password, class: "mdc-text-field__input", autofocus: true, autocomplete: "new-password" %>
<%= render 'shared/invalid_icon', resource: resource, field: :password %>
<div class="mdc-line-ripple"></div>
</div>
<%= render 'shared/info_and_errors', resource: resource, field: :password, text: "#{@minimum_password_length} caracteres mínimo. Dejar en blanco si no lo quieres cambiar." %>
<%= render 'shared/password_field', f:, resource:, field: :password, label_text: "Nueva contraseña", autocomplete: "new-password", required: false %>
<%= render 'shared/info_and_errors', resource:, field: :password, text: "#{@minimum_password_length} caracteres mínimo. Dejar en blanco si no lo quieres cambiar." %>
</li>
<li class="form-input-container">
<div class="mdc-text-field mdc-text-field--filled <%='mdc-text-field--invalid mdc-text-field--with-trailing-icon' if resource.errors[:password_confirmation].any? %>" data-controller="textfield">
<span class="mdc-text-field__ripple"></span>
<%= f.label :password_confirmation, "Confirma tu nueva contraseña", class: "mdc-floating-label" %>
<%= f.password_field :password_confirmation, class: "mdc-text-field__input", autofocus: true, autocomplete: "new-password" %>
<%= render 'shared/invalid_icon', resource: resource, field: :password_confirmation %>
<div class="mdc-line-ripple"></div>
</div>
<%= render 'shared/info_and_errors', resource: resource, field: :password_confirmation, text: '' %>
<%= render 'shared/password_field', f:, resource:, field: :password_confirmation, label_text: "Confirma tu nueva contraseña", autocomplete: "new-password", required: false %>
<%= render 'shared/info_and_errors', resource:, field: :password_confirmation, text: '' %>
</li>
<li class="form-input-container">
<div class="mdc-text-field mdc-text-field--filled <%='mdc-text-field--invalid mdc-text-field--with-trailing-icon' if resource.errors[:current_password].any? %>" data-controller="textfield">
<span class="mdc-text-field__ripple"></span>
<%= f.label :current_password, "Contraseña actual", class: "mdc-floating-label" %>
<%= f.password_field :current_password, class: "mdc-text-field__input", required: true, autofocus: true, autocomplete: 'current-password' %>
<%= render 'shared/invalid_icon', resource: resource, field: :current_password %>
<div class="mdc-line-ripple"></div>
</div>
<%= render 'shared/info_and_errors', resource: resource, field: :current_password, text: 'Necesitamos tu contraseña actual para validar los cambios' %>
<%= render 'shared/password_field', f:, resource:, field: :current_password, label_text: "Contraseña actual", autocomplete: "current-password", required: true %>
<%= render 'shared/info_and_errors', resource:, field: :current_password, text: 'Necesitamos tu contraseña actual para validar los cambios' %>
</li>

<li class="form-input-container sign-in">
Expand Down
22 changes: 5 additions & 17 deletions app/views/devise/registrations/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,19 @@
<div class="mdc-text-field mdc-text-field--filled <%='mdc-text-field--invalid mdc-text-field--with-trailing-icon' if resource.errors[:email].any? %>" data-controller="textfield">
<span class="mdc-text-field__ripple"></span>
<%= f.label :email, "Correo electrónico", class: "mdc-floating-label" %>
<%= f.email_field :email, class: "mdc-text-field__input", required: true %>
<%= f.email_field :email, class: "mdc-text-field__input", required: true, autofocus: true %>
<%= render 'shared/invalid_icon', resource: resource, field: :email %>
<div class="mdc-line-ripple"></div>
</div>
<%= render 'shared/info_and_errors', resource: resource, field: :email, text: '' %>
</li>
<li class="form-input-container">
<div class="mdc-text-field mdc-text-field--filled <%='mdc-text-field--invalid mdc-text-field--with-trailing-icon' if resource.errors[:password].any? %>" data-controller="textfield">
<span class="mdc-text-field__ripple"></span>
<%= f.label :password, "Nueva contraseña", class: "mdc-floating-label" %>
<%= f.password_field :password, class: "mdc-text-field__input", required: true, autocomplete: "new-password" %>
<%= render 'shared/invalid_icon', resource: resource, field: :password %>
<div class="mdc-line-ripple"></div>
</div>
<%= render 'shared/info_and_errors', resource: resource, field: :password, text: "#{@minimum_password_length} caracteres mínimo." %>
<%= render 'shared/password_field', f:, resource:, field: :password, label_text: "Nueva contraseña", autocomplete: "new-password", required: true %>
<%= render 'shared/info_and_errors', resource:, field: :password, text: "#{@minimum_password_length} caracteres mínimo." %>
</li>
<li class="form-input-container">
<div class="mdc-text-field mdc-text-field--filled <%='mdc-text-field--invalid mdc-text-field--with-trailing-icon' if resource.errors[:password_confirmation].any? %>" data-controller="textfield">
<span class="mdc-text-field__ripple"></span>
<%= f.label :password_confirmation, "Confirma tu nueva contraseña", class: "mdc-floating-label" %>
<%= f.password_field :password_confirmation, class: "mdc-text-field__input", required: true, autocomplete: "new-password" %>
<%= render 'shared/invalid_icon', resource: resource, field: :password_confirmation %>
<div class="mdc-line-ripple"></div>
</div>
<%= render 'shared/info_and_errors', resource: resource, field: :password_confirmation, text: '' %>
<%= render 'shared/password_field', f:, resource:, field: :password_confirmation, label_text: "Confirma tu nueva contraseña", autocomplete: "new-password", required: true %>
<%= render 'shared/info_and_errors', resource:, field: :password_confirmation, text: '' %>
</li>

<li class="form-input-container sign-in">
Expand Down
10 changes: 2 additions & 8 deletions app/views/devise/sessions/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,8 @@
<%= render 'shared/info_and_errors', resource: resource, field: :email, text: '' %>
</li>
<li class="form-input-container">
<div class="mdc-text-field mdc-text-field--filled <%='mdc-text-field--invalid mdc-text-field--with-trailing-icon' if resource.errors[:password].any? %>" data-controller="textfield">
<span class="mdc-text-field__ripple"></span>
<%= f.label :password, "Contraseña", class: "mdc-floating-label" %>
<%= f.password_field :password, class: "mdc-text-field__input", required: true, autofocus: true, autocomplete: "current-password" %>
<%= render 'shared/invalid_icon', resource: resource, field: :password %>
<div class="mdc-line-ripple"></div>
</div>
<%= render 'shared/info_and_errors', resource: resource, field: :password, text: '' %>
<%= render 'shared/password_field', f:, resource:, field: :password, label_text: "Contraseña", autocomplete: "current-password", required: true %>
<%= render 'shared/info_and_errors', resource:, field: :password, text: '' %>
</li>
<li class="form-input-container sign-in">
<%= f.button class: "mdc-button mdc-button--raised" do %>
Expand Down
10 changes: 10 additions & 0 deletions app/views/shared/_password_field.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="mdc-text-field mdc-text-field--filled <%='mdc-text-field--invalid mdc-text-field--with-trailing-icon' if resource.errors[field].any? %>" data-controller="textfield show-password">
<span class="mdc-text-field__ripple"></span>
<%= f.label field, label_text, class: "mdc-floating-label" %>
<%= f.password_field field, class: "mdc-text-field__input", required:, autofocus: true, autocomplete:, data: { show_password_target: "password" } %>
<button type="button" class="mdc-button show-password-button" data-action="show-password#toggle">
<span class="material-icons" data-show-password-target="icon">visibility</span>
</button>
<%= render 'shared/invalid_icon', resource:, field: %>
<div class="mdc-line-ripple"></div>
</div>
12 changes: 12 additions & 0 deletions test/support/password_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module PasswordHelpers
def password_visibility_toggle_test(label_text)
container = find("li", text: label_text, match: :prefer_exact)

within(container) do
find(".show-password-button").click
assert_selector "input[type='text']"
find(".show-password-button").click
assert_selector "input[type='password']"
end
end
end
8 changes: 8 additions & 0 deletions test/system/user_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class UserTest < ApplicationSystemTestCase
include ActionMailer::TestHelper
include PasswordHelpers

test "can sign up" do
user = create :user
Expand Down Expand Up @@ -34,6 +35,8 @@ class UserTest < ApplicationSystemTestCase
fill_in "Correo electrónico", with: '[email protected]'
fill_in "Nueva contraseña", with: 'alice123'
fill_in "Confirma tu nueva contraseña", with: 'alice123'
password_visibility_toggle_test("Nueva contraseña")
password_visibility_toggle_test("Confirma tu nueva contraseña")
click_on "Registrarte"

assert_current_path root_path
Expand Down Expand Up @@ -70,6 +73,7 @@ class UserTest < ApplicationSystemTestCase
visit edit_user_password_path(reset_password_token: user.send_reset_password_instructions)

fill_in "Nueva contraseña", with: "new_password"
password_visibility_toggle_test("Nueva contraseña")
click_on "Restablecer contraseña"
assert_text 'Tu contraseña fue modificada correctamente. Has iniciado sesión.'

Expand Down Expand Up @@ -103,6 +107,7 @@ class UserTest < ApplicationSystemTestCase

fill_in "Correo electrónico", with: user.email
fill_in "Contraseña", with: user.password
password_visibility_toggle_test("Contraseña")
click_on "Ingresar"

assert_current_path(root_path)
Expand Down Expand Up @@ -155,6 +160,9 @@ class UserTest < ApplicationSystemTestCase
fill_in "Nueva contraseña", with: "new_password"
fill_in "Confirma tu nueva contraseña", with: "new_password"
fill_in "Contraseña actual", with: user.password
password_visibility_toggle_test("Nueva contraseña")
password_visibility_toggle_test("Confirma tu nueva contraseña")
password_visibility_toggle_test("Contraseña actual")
fill_in "Correo electrónico", with: "new_#{user.email}"
click_on "Guardar"
assert_text "Actualizaste tu cuenta correctamente."
Expand Down
1 change: 1 addition & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require_relative '../config/environment'
require 'rails/test_help'
require 'minitest/mock'
Dir[Rails.root.join("test/support/*")].each { |f| require f }

class ActiveSupport::TestCase
include FactoryBot::Syntax::Methods
Expand Down

0 comments on commit 0cf0e3b

Please sign in to comment.