Skip to content

Commit 0cf0e3b

Browse files
Merge pull request #618 from cedarcode/jt--show_password
Add button to show password on password fields
2 parents aa94e7b + bac4ed1 commit 0cf0e3b

File tree

10 files changed

+65
-57
lines changed

10 files changed

+65
-57
lines changed

app/assets/stylesheets/application.scss

+4
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,7 @@ body {
221221
#butInstall {
222222
padding-left: 0px;
223223
}
224+
225+
.show-password-button {
226+
margin-right: -20px;
227+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Controller } from "@hotwired/stimulus";
2+
3+
export default class extends Controller {
4+
static targets = ["password", "icon"];
5+
6+
toggle() {
7+
if (this.passwordTarget.type === "password") {
8+
this.passwordTarget.type = "text";
9+
this.iconTarget.innerHTML = "visibility_off";
10+
} else {
11+
this.passwordTarget.type = "password";
12+
this.iconTarget.innerHTML = "visibility";
13+
}
14+
}
15+
}

app/views/devise/passwords/edit.html.erb

+2-8
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,8 @@
66
<%= f.hidden_field :reset_password_token %>
77

88
<li class="form-input-container">
9-
<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">
10-
<span class="mdc-text-field__ripple"></span>
11-
<%= f.label :password, "Nueva contraseña", class: "mdc-floating-label" %>
12-
<%= f.password_field :password, class: "mdc-text-field__input", autofocus: true %>
13-
<%= render 'shared/invalid_icon', resource: resource, field: :password %>
14-
<div class="mdc-line-ripple"></div>
15-
</div>
16-
<%= render 'shared/info_and_errors', resource: resource, field: :password, text: "#{@minimum_password_length} caracteres mínimo" %>
9+
<%= render 'shared/password_field', f:, resource:, field: :password, label_text: "Nueva contraseña", autocomplete: "new-password", required: false %>
10+
<%= render 'shared/info_and_errors', resource:, field: :password, text: "#{@minimum_password_length} caracteres mínimo" %>
1711
</li>
1812

1913
<li class="form-input-container sign-in">

app/views/devise/registrations/edit.html.erb

+6-24
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,16 @@
1717
"" %>
1818
</li>
1919
<li class="form-input-container">
20-
<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">
21-
<span class="mdc-text-field__ripple"></span>
22-
<%= f.label :password, "Nueva contraseña", class: "mdc-floating-label" %>
23-
<%= f.password_field :password, class: "mdc-text-field__input", autofocus: true, autocomplete: "new-password" %>
24-
<%= render 'shared/invalid_icon', resource: resource, field: :password %>
25-
<div class="mdc-line-ripple"></div>
26-
</div>
27-
<%= render 'shared/info_and_errors', resource: resource, field: :password, text: "#{@minimum_password_length} caracteres mínimo. Dejar en blanco si no lo quieres cambiar." %>
20+
<%= render 'shared/password_field', f:, resource:, field: :password, label_text: "Nueva contraseña", autocomplete: "new-password", required: false %>
21+
<%= render 'shared/info_and_errors', resource:, field: :password, text: "#{@minimum_password_length} caracteres mínimo. Dejar en blanco si no lo quieres cambiar." %>
2822
</li>
2923
<li class="form-input-container">
30-
<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">
31-
<span class="mdc-text-field__ripple"></span>
32-
<%= f.label :password_confirmation, "Confirma tu nueva contraseña", class: "mdc-floating-label" %>
33-
<%= f.password_field :password_confirmation, class: "mdc-text-field__input", autofocus: true, autocomplete: "new-password" %>
34-
<%= render 'shared/invalid_icon', resource: resource, field: :password_confirmation %>
35-
<div class="mdc-line-ripple"></div>
36-
</div>
37-
<%= render 'shared/info_and_errors', resource: resource, field: :password_confirmation, text: '' %>
24+
<%= render 'shared/password_field', f:, resource:, field: :password_confirmation, label_text: "Confirma tu nueva contraseña", autocomplete: "new-password", required: false %>
25+
<%= render 'shared/info_and_errors', resource:, field: :password_confirmation, text: '' %>
3826
</li>
3927
<li class="form-input-container">
40-
<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">
41-
<span class="mdc-text-field__ripple"></span>
42-
<%= f.label :current_password, "Contraseña actual", class: "mdc-floating-label" %>
43-
<%= f.password_field :current_password, class: "mdc-text-field__input", required: true, autofocus: true, autocomplete: 'current-password' %>
44-
<%= render 'shared/invalid_icon', resource: resource, field: :current_password %>
45-
<div class="mdc-line-ripple"></div>
46-
</div>
47-
<%= render 'shared/info_and_errors', resource: resource, field: :current_password, text: 'Necesitamos tu contraseña actual para validar los cambios' %>
28+
<%= render 'shared/password_field', f:, resource:, field: :current_password, label_text: "Contraseña actual", autocomplete: "current-password", required: true %>
29+
<%= render 'shared/info_and_errors', resource:, field: :current_password, text: 'Necesitamos tu contraseña actual para validar los cambios' %>
4830
</li>
4931

5032
<li class="form-input-container sign-in">

app/views/devise/registrations/new.html.erb

+5-17
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,19 @@
2424
<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">
2525
<span class="mdc-text-field__ripple"></span>
2626
<%= f.label :email, "Correo electrónico", class: "mdc-floating-label" %>
27-
<%= f.email_field :email, class: "mdc-text-field__input", required: true %>
27+
<%= f.email_field :email, class: "mdc-text-field__input", required: true, autofocus: true %>
2828
<%= render 'shared/invalid_icon', resource: resource, field: :email %>
2929
<div class="mdc-line-ripple"></div>
3030
</div>
3131
<%= render 'shared/info_and_errors', resource: resource, field: :email, text: '' %>
3232
</li>
3333
<li class="form-input-container">
34-
<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">
35-
<span class="mdc-text-field__ripple"></span>
36-
<%= f.label :password, "Nueva contraseña", class: "mdc-floating-label" %>
37-
<%= f.password_field :password, class: "mdc-text-field__input", required: true, autocomplete: "new-password" %>
38-
<%= render 'shared/invalid_icon', resource: resource, field: :password %>
39-
<div class="mdc-line-ripple"></div>
40-
</div>
41-
<%= render 'shared/info_and_errors', resource: resource, field: :password, text: "#{@minimum_password_length} caracteres mínimo." %>
34+
<%= render 'shared/password_field', f:, resource:, field: :password, label_text: "Nueva contraseña", autocomplete: "new-password", required: true %>
35+
<%= render 'shared/info_and_errors', resource:, field: :password, text: "#{@minimum_password_length} caracteres mínimo." %>
4236
</li>
4337
<li class="form-input-container">
44-
<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">
45-
<span class="mdc-text-field__ripple"></span>
46-
<%= f.label :password_confirmation, "Confirma tu nueva contraseña", class: "mdc-floating-label" %>
47-
<%= f.password_field :password_confirmation, class: "mdc-text-field__input", required: true, autocomplete: "new-password" %>
48-
<%= render 'shared/invalid_icon', resource: resource, field: :password_confirmation %>
49-
<div class="mdc-line-ripple"></div>
50-
</div>
51-
<%= render 'shared/info_and_errors', resource: resource, field: :password_confirmation, text: '' %>
38+
<%= render 'shared/password_field', f:, resource:, field: :password_confirmation, label_text: "Confirma tu nueva contraseña", autocomplete: "new-password", required: true %>
39+
<%= render 'shared/info_and_errors', resource:, field: :password_confirmation, text: '' %>
5240
</li>
5341

5442
<li class="form-input-container sign-in">

app/views/devise/sessions/new.html.erb

+2-8
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,8 @@
3131
<%= render 'shared/info_and_errors', resource: resource, field: :email, text: '' %>
3232
</li>
3333
<li class="form-input-container">
34-
<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">
35-
<span class="mdc-text-field__ripple"></span>
36-
<%= f.label :password, "Contraseña", class: "mdc-floating-label" %>
37-
<%= f.password_field :password, class: "mdc-text-field__input", required: true, autofocus: true, autocomplete: "current-password" %>
38-
<%= render 'shared/invalid_icon', resource: resource, field: :password %>
39-
<div class="mdc-line-ripple"></div>
40-
</div>
41-
<%= render 'shared/info_and_errors', resource: resource, field: :password, text: '' %>
34+
<%= render 'shared/password_field', f:, resource:, field: :password, label_text: "Contraseña", autocomplete: "current-password", required: true %>
35+
<%= render 'shared/info_and_errors', resource:, field: :password, text: '' %>
4236
</li>
4337
<li class="form-input-container sign-in">
4438
<%= f.button class: "mdc-button mdc-button--raised" do %>
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<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">
2+
<span class="mdc-text-field__ripple"></span>
3+
<%= f.label field, label_text, class: "mdc-floating-label" %>
4+
<%= f.password_field field, class: "mdc-text-field__input", required:, autofocus: true, autocomplete:, data: { show_password_target: "password" } %>
5+
<button type="button" class="mdc-button show-password-button" data-action="show-password#toggle">
6+
<span class="material-icons" data-show-password-target="icon">visibility</span>
7+
</button>
8+
<%= render 'shared/invalid_icon', resource:, field: %>
9+
<div class="mdc-line-ripple"></div>
10+
</div>

test/support/password_helpers.rb

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module PasswordHelpers
2+
def password_visibility_toggle_test(label_text)
3+
container = find("li", text: label_text, match: :prefer_exact)
4+
5+
within(container) do
6+
find(".show-password-button").click
7+
assert_selector "input[type='text']"
8+
find(".show-password-button").click
9+
assert_selector "input[type='password']"
10+
end
11+
end
12+
end

test/system/user_test.rb

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
class UserTest < ApplicationSystemTestCase
44
include ActionMailer::TestHelper
5+
include PasswordHelpers
56

67
test "can sign up" do
78
user = create :user
@@ -34,6 +35,8 @@ class UserTest < ApplicationSystemTestCase
3435
fill_in "Correo electrónico", with: 'alice@test.com'
3536
fill_in "Nueva contraseña", with: 'alice123'
3637
fill_in "Confirma tu nueva contraseña", with: 'alice123'
38+
password_visibility_toggle_test("Nueva contraseña")
39+
password_visibility_toggle_test("Confirma tu nueva contraseña")
3740
click_on "Registrarte"
3841

3942
assert_current_path root_path
@@ -70,6 +73,7 @@ class UserTest < ApplicationSystemTestCase
7073
visit edit_user_password_path(reset_password_token: user.send_reset_password_instructions)
7174

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

@@ -103,6 +107,7 @@ class UserTest < ApplicationSystemTestCase
103107

104108
fill_in "Correo electrónico", with: user.email
105109
fill_in "Contraseña", with: user.password
110+
password_visibility_toggle_test("Contraseña")
106111
click_on "Ingresar"
107112

108113
assert_current_path(root_path)
@@ -155,6 +160,9 @@ class UserTest < ApplicationSystemTestCase
155160
fill_in "Nueva contraseña", with: "new_password"
156161
fill_in "Confirma tu nueva contraseña", with: "new_password"
157162
fill_in "Contraseña actual", with: user.password
163+
password_visibility_toggle_test("Nueva contraseña")
164+
password_visibility_toggle_test("Confirma tu nueva contraseña")
165+
password_visibility_toggle_test("Contraseña actual")
158166
fill_in "Correo electrónico", with: "new_#{user.email}"
159167
click_on "Guardar"
160168
assert_text "Actualizaste tu cuenta correctamente."

test/test_helper.rb

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require_relative '../config/environment'
33
require 'rails/test_help'
44
require 'minitest/mock'
5+
Dir[Rails.root.join("test/support/*")].each { |f| require f }
56

67
class ActiveSupport::TestCase
78
include FactoryBot::Syntax::Methods

0 commit comments

Comments
 (0)