decidim-friendly_signup 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # Decidim::FriendlySignup
2
+
3
+ [![[CI] Test](https://github.com/OpenSourcePolitics/decidim-module-friendly_signup/actions/workflows/test.yml/badge.svg)](https://github.com/OpenSourcePolitics/decidim-module-friendly_signup/actions/workflows/test.yml)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/46c261f70f7f49a8f385/maintainability)](https://codeclimate.com/github/OpenSourcePolitics/decidim-module-friendly_signup/maintainability)
5
+ [![Test Coverage](https://codecov.io/gh/OpenSourcePolitics/decidim-module-friendly_signup/branch/main/graph/badge.svg?token=1lrOiLdy9P)](https://codecov.io/gh/OpenSourcePolitics/decidim-module-friendly_signup)
6
+ ---
7
+ A more user friendly approach for the user registration process.
8
+
9
+ ## Usage
10
+
11
+ This module simply substitutes some pages to ease up the registration process in Decidim.
12
+
13
+ Features:
14
+
15
+ - [x] Simplify the password field and add a button with a "show password". ![Show/hide password](examples/passwords.png)
16
+
17
+ - [ ] Remove the nickname field from the registration process and automatically create one on registering
18
+ - [ ] Instant validate parameters when registering without having to send it for backend validation
19
+ - [ ] Use checkout codes to validate the email instead of a link
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ ```ruby
26
+ gem "decidim-friendly_signup"
27
+ ```
28
+
29
+ For a bleeding edge version (or while developing) please use instead:
30
+
31
+ ```ruby
32
+ gem "decidim-friendly_signup", git: "https://github.com/OpenSourcePolitics/decidim-module-friendly_signup", branch: "main"
33
+ ```
34
+
35
+ And then execute:
36
+
37
+ ```bash
38
+ bundle
39
+ ```
40
+
41
+ ## Configuration
42
+
43
+ Customize your integration by creating an initializer (ie: `config/initializes/friendly_signup.rb`) and set some of the variables:
44
+
45
+ ```ruby
46
+ # config/initializers/friendly_signup.rb
47
+
48
+ Decidim::FriendlySignup.configure do |config|
49
+ # Override password views or leave the originals (default is true):
50
+ config.override_passwords = false
51
+ end
52
+
53
+ ```
54
+
55
+ ## Contributing
56
+
57
+ Bug reports and pull requests are welcome on GitHub at https://github.com/OpenSourcePolitics/decidim-module-friendly_signup.
58
+
59
+ ### Developing
60
+
61
+ To start contributing to this project, first:
62
+
63
+ - Install the basic dependencies (such as Ruby and PostgreSQL)
64
+ - Clone this repository
65
+
66
+ Decidim's main repository also provides a Docker configuration file if you
67
+ prefer to use Docker instead of installing the dependencies locally on your
68
+ machine.
69
+
70
+ You can create the development app by running the following commands after
71
+ cloning this project:
72
+
73
+ ```bash
74
+ $ bundle
75
+ $ DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake development_app
76
+ ```
77
+
78
+ Note that the database user has to have rights to create and drop a database in
79
+ order to create the dummy test app database.
80
+
81
+ Then to test how the module works in Decidim, start the development server:
82
+
83
+ ```bash
84
+ $ cd development_app
85
+ $ DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rails s
86
+ ```
87
+
88
+ In case you are using [rbenv](https://github.com/rbenv/rbenv) and have the
89
+ [rbenv-vars](https://github.com/rbenv/rbenv-vars) plugin installed for it, you
90
+ can add the environment variables to the root directory of the project in a file
91
+ named `.rbenv-vars`. If these are defined for the environment, you can omit
92
+ defining these in the commands shown above.
93
+
94
+ #### Code Styling
95
+
96
+ Please follow the code styling defined by the different linters that ensure we
97
+ are all talking with the same language collaborating on the same project. This
98
+ project is set to follow the same rules that Decidim itself follows.
99
+
100
+ [Rubocop](https://rubocop.readthedocs.io/) linter is used for the Ruby language.
101
+
102
+ You can run the code styling checks by running the following commands from the
103
+ console:
104
+
105
+ ```
106
+ $ bundle exec rubocop
107
+ ```
108
+
109
+ To ease up following the style guide, you should install the plugin to your
110
+ favorite editor, such as:
111
+
112
+ - Sublime Text - [Sublime RuboCop](https://github.com/pderichs/sublime_rubocop)
113
+ - Visual Studio Code - [Rubocop for Visual Studio Code](https://github.com/misogi/vscode-ruby-rubocop)
114
+
115
+ ### Testing
116
+
117
+ To run the tests run the following in the gem development path:
118
+
119
+ ```bash
120
+ $ bundle
121
+ $ DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake test_app
122
+ $ DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rspec
123
+ ```
124
+
125
+ Note that the database user has to have rights to create and drop a database in
126
+ order to create the dummy test app database.
127
+
128
+ In case you are using [rbenv](https://github.com/rbenv/rbenv) and have the
129
+ [rbenv-vars](https://github.com/rbenv/rbenv-vars) plugin installed for it, you
130
+ can add these environment variables to the root directory of the project in a
131
+ file named `.rbenv-vars`. In this case, you can omit defining these in the
132
+ commands shown above.
133
+
134
+ ### Test code coverage
135
+
136
+ If you want to generate the code coverage report for the tests, you can use
137
+ the `SIMPLECOV=1` environment variable in the rspec command as follows:
138
+
139
+ ```bash
140
+ $ SIMPLECOV=1 bundle exec rspec
141
+ ```
142
+
143
+ This will generate a folder named `coverage` in the project root which contains
144
+ the code coverage report.
145
+
146
+ ### Localization
147
+
148
+ If you would like to see this module in your own language, you can help with its
149
+ translation at Crowdin:
150
+
151
+ https://crowdin.com/project/decidim-friendly-signup
152
+
153
+ ## License
154
+
155
+ See [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt).
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/dev/common_rake"
4
+
5
+ desc "Generates a dummy app for testing"
6
+ task test_app: "decidim:generate_external_test_app"
7
+
8
+ desc "Generates a development app."
9
+ task development_app: "decidim:generate_external_development_app"
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module FriendlySignup
7
+ module NeedsHeaderSnippets
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ helper_method :snippets, :friendly_override_activated?
12
+ end
13
+
14
+ def snippets
15
+ @snippets ||= Decidim::Snippets.new
16
+
17
+ unless @snippets.any?(:friendly_signup_snippets)
18
+ @snippets.add(:friendly_signup_snippets, ActionController::Base.helpers.javascript_pack_tag("decidim_friendly_signup"))
19
+ @snippets.add(:friendly_signup_snippets, ActionController::Base.helpers.stylesheet_pack_tag("decidim_friendly_signup"))
20
+ @snippets.add(:head, @snippets.for(:friendly_signup_snippets))
21
+ end
22
+
23
+ @snippets
24
+ end
25
+
26
+ def friendly_override_activated?(type)
27
+ case type
28
+ when :override_passwords
29
+ Decidim::FriendlySignup.override_passwords.present?
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ import "src/decidim/friendly_signup/password_helper"
2
+
3
+ // CSS
4
+ import "entrypoints/decidim_friendly_signup.scss";
5
+
6
+ // Images
7
+ require.context("../images", true)
@@ -0,0 +1,2 @@
1
+ /* css for decidim_friendly_signup */
2
+ @import "stylesheets/decidim/friendly_signup/input-groups";
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 35"><path d="M17.5 35A17.5 17.5 0 1 1 35 17.5 17.52 17.52 0 0 1 17.5 35zm0-33.06A15.56 15.56 0 1 0 33.06 17.5 15.57 15.57 0 0 0 17.5 1.94zm9.5 13.7H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zm0 3.68H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zM22.26 23H8a1 1 0 0 1 0-1.94h14.26a1 1 0 0 1 0 1.94z"/></svg>
@@ -0,0 +1,7 @@
1
+ import PasswordToggler from "src/decidim/friendly_signup/password_toggler";
2
+
3
+ $(() => {
4
+ window.Decidim = window.Decidim || {};
5
+ window.Decidim.passwordToggler = new PasswordToggler($(".user-password"), $(".user-password-confirmation"));
6
+ window.Decidim.passwordToggler.init();
7
+ });
@@ -0,0 +1,85 @@
1
+ import icon from "src/decidim/icon"
2
+
3
+ export default class PasswordToggler {
4
+ constructor($password, $confirmation) {
5
+ this.$password = $password.first();
6
+ this.$confirmation = $confirmation.first();
7
+ this.$input = this.$password.find('input[type="password"]');
8
+ this.$inputConfirmation = this.$confirmation.find('input[type="password"]');
9
+ this.$form = this.$input.closest("form");
10
+ this.texts = {
11
+ showPassword: this.$password.data("showPassword") || "Show password",
12
+ hidePassword: this.$password.data("hidePassword") || "Hide password",
13
+ hiddenPassword: this.$password.data("hiddenPassword") || "Your password is hidden",
14
+ shownPassword: this.$password.data("shownPassword") || "Your password is shown"
15
+ }
16
+ this.icons = {
17
+ show: icon("eye", {title: this.texts.showPassword})
18
+ }
19
+ }
20
+
21
+ // Call init() to hide the password confirmation and add a "view password" inline button
22
+ init() {
23
+ this.createControls();
24
+ this.$confirmation.hide();
25
+ this.$button.on("click.password_toggler", (evt) => this.toggleVisibiliy(evt));
26
+ this.$input.on("change.password_toggler", () => {
27
+ this.$inputConfirmation.val(this.$input.val());
28
+ });
29
+ // to prevent browsers trying to use autocomplete, turn the type back to password before submitting
30
+ this.$form.on("submit.password_toggler", () => {
31
+ this.$inputConfirmation.val(this.$input.val());
32
+ this.hidePassword();
33
+ });
34
+ }
35
+
36
+ // Call destroy() to switch back to the original password/password confirmation boxes
37
+ destroy() {
38
+ this.$button.off("click.password_toggler");
39
+ this.$input.off("change.password_toggler");
40
+ this.$form.off("submit.password_toggler");
41
+ const $input = this.$input.detach();
42
+ this.$inputGroup.replaceWith($input);
43
+ this.$confirmation.show();
44
+ }
45
+
46
+ createControls() {
47
+ this.$button = $(`<button type="button"
48
+ aria-controls="${this.$input.attr("id")}"
49
+ aria-label="${this.texts.showPassword}">${this.icons.show}</button>`);
50
+ this.$buttonGroup = $('<span class="input-group"/>');
51
+ this.$statusText = $(`<span class="show-for-sr" aria-live="polite">${this.texts.hiddenPassword}</span>`);
52
+ // ensure error message is handled by foundation abide
53
+ this.$input.next(".form-error").attr("data-form-error-for", this.$input.attr("id"));
54
+ this.$buttonGroup.html(this.$button);
55
+ this.$input.wrap('<span class="input-inline-group"/>').
56
+ after(this.$statusText).
57
+ after(this.$buttonGroup);
58
+ this.$inputGroup = this.$input.parent();
59
+ }
60
+
61
+ toggleVisibiliy(evt) {
62
+ evt.preventDefault();
63
+ if (this.isText()) {
64
+ this.hidePassword();
65
+ } else {
66
+ this.showPassword();
67
+ }
68
+ }
69
+
70
+ showPassword() {
71
+ this.$statusText.text(this.texts.shownPassword);
72
+ this.$button.attr("aria-label", this.texts.hidePassword).addClass("crossed");
73
+ this.$input.attr("type", "text");
74
+ }
75
+
76
+ hidePassword() {
77
+ this.$statusText.text(this.texts.hiddenPassword);
78
+ this.$button.attr("aria-label", this.texts.showPassword).removeClass("crossed")
79
+ this.$input.attr("type", "password");
80
+ }
81
+
82
+ isText() {
83
+ return this.$input.attr("type") === "text"
84
+ }
85
+ }
@@ -0,0 +1,52 @@
1
+ @import "stylesheets/decidim/variables";
2
+ @import "stylesheets/decidim/utils/settings";
3
+
4
+ .input-inline-group {
5
+ position: relative;
6
+ display: block;
7
+
8
+ .input-group {
9
+ position: absolute;
10
+ top: 0;
11
+ right: 0;
12
+ margin-right: 1em;
13
+ margin-top: .5em;
14
+ width: 1%;
15
+
16
+ button {
17
+ .icon {
18
+ width: 1.125em;
19
+ height: 1.125em;
20
+ margin: 5px;
21
+ color: $black;
22
+ }
23
+
24
+ &.crossed {
25
+ position: relative;
26
+
27
+ &::before {
28
+ content: "";
29
+ position: absolute;
30
+ top: 5px;
31
+ left: 5px;
32
+ background:
33
+ linear-gradient(
34
+ to right bottom,
35
+ transparent calc(50% - 1px),
36
+ black calc(50% - 1px),
37
+ black calc(50% + 1px),
38
+ transparent calc(50% + 1px)
39
+ ) no-repeat 0 0 / 100% 100%;
40
+ width: calc(100% - 10px);
41
+ height: calc(100% - 10px);
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ .register-form {
49
+ .input-group {
50
+ margin-top: .75em;
51
+ }
52
+ }
@@ -0,0 +1,16 @@
1
+ <% if friendly_override_activated?(:override_passwords) %>
2
+ <span class="user-password"
3
+ data-show-password="<%= t "show_password", scope: "decidim.friendly_signup.shared.password_fields" %>"
4
+ data-hide-password="<%= t "hide_password", scope: "decidim.friendly_signup.shared.password_fields" %>"
5
+ data-hidden-password="<%= t "hidden_password", scope: "decidim.friendly_signup.shared.password_fields" %>"
6
+ data-shown-password="<%= t "shown_password", scope: "decidim.friendly_signup.shared.password_fields" %>">
7
+ <%= form.password_field :password, value: form.object.password, autocomplete: "off", help_text: t("devise.passwords.edit.password_help", minimun_characters: ::PasswordValidator::MINIMUM_LENGTH) %>
8
+ </span>
9
+
10
+ <span class="user-password-confirmation">
11
+ <%= form.password_field :password_confirmation, value: form.object.password_confirmation, autocomplete: "off" %>
12
+ </span>
13
+ <% else %>
14
+ <%= form.password_field :password, value: form.object.password, autocomplete: "off", help_text: t("devise.passwords.edit.password_help", minimun_characters: ::PasswordValidator::MINIMUM_LENGTH) %>
15
+ <%= form.password_field :password_confirmation, value: form.object.password_confirmation, autocomplete: "off" %>
16
+ <% end %>
@@ -0,0 +1,76 @@
1
+ <div class="wrapper">
2
+ <div class="row collapse">
3
+ <div class="row collapse">
4
+ <div class="columns large-8 large-centered text-center page-title">
5
+ <h1><%= t "devise.invitations.edit.header" %></h1>
6
+
7
+ <p><%= t("devise.invitations.edit.subtitle").html_safe %></p>
8
+ </div>
9
+ </div>
10
+
11
+ <div class="row">
12
+ <div class="columns large-6 medium-10 medium-centered">
13
+ <%= decidim_form_for resource, namespace: "invitation", as: resource_name, url: invitation_path(resource_name, invite_redirect: params[:invite_redirect]), html: { method: :put, class: "register-form new_user" } do |f| %>
14
+ <div class="card">
15
+ <div class="card__content">
16
+ <legend><%= t("sign_up_as.legend", scope: "decidim.devise.registrations.new") %></legend>
17
+
18
+ <%= form_required_explanation %>
19
+
20
+ <%= f.hidden_field :invitation_token %>
21
+
22
+ <div class="user-nickname">
23
+ <div class="field">
24
+ <%= f.text_field :nickname, help_text: t("devise.invitations.edit.nickname_help", organization: current_organization.name), required: "required", prefix: { value: "@", small: 1, large: 1 } %>
25
+ </div>
26
+ </div>
27
+
28
+ <% if f.object.class.require_password_on_accepting %>
29
+ <%= render("decidim/friendly_signup/shared/password_fields", form: f, options: { required: "required", minlength: ::PasswordValidator::MINIMUM_LENGTH, maxlength: ::PasswordValidator::MAX_LENGTH }) %>
30
+ <% end %>
31
+ </div>
32
+ </div>
33
+
34
+ <div class="card" id="card__tos">
35
+ <div class="card__content">
36
+ <fieldset>
37
+ <legend><%= t("tos_title", scope: "decidim.devise.registrations.new") %></legend>
38
+ <p class="tos-text"><%= strip_tags(translated_attribute(terms_and_conditions_page.content)) %></p>
39
+ </fieldset>
40
+
41
+ <div class="field">
42
+ <% link = link_to t("terms", scope: "decidim.devise.registrations.new"), page_path("terms-and-conditions"), target: "_blank" %>
43
+ <% label = t("tos_agreement", scope: "decidim.devise.registrations.new", link: link) %>
44
+ <%= f.check_box :tos_agreement, label: label, required: "required" %>
45
+ </div>
46
+ </div>
47
+ </div>
48
+
49
+ <div class="card" id="card__newsletter">
50
+ <div class="card__content">
51
+
52
+ <fieldset>
53
+ <legend><%= t("newsletter_title", scope: "decidim.devise.registrations.new") %></legend>
54
+ <div class="field">
55
+ <%= label_tag :"#{resource_name}[newsletter_notifications]" do %>
56
+ <%= check_box_tag :"#{resource_name}[newsletter_notifications]" %>
57
+ <%= t("newsletter", scope: "decidim.devise.registrations.new") %>
58
+ <% end %>
59
+ </div>
60
+ </fieldset>
61
+ </div>
62
+ </div>
63
+
64
+ <div class="card">
65
+ <div class="card__content">
66
+ <div class="actions">
67
+ <%= f.submit t("devise.invitations.edit.submit_button"), class: "button expanded" %>
68
+ </div>
69
+ </div>
70
+ </div>
71
+
72
+ <% end %>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </div>
@@ -0,0 +1,31 @@
1
+ <div class="wrapper">
2
+ <div class="row collapse">
3
+ <div class="row collapse">
4
+ <div class="columns large-8 large-centered text-center page-title">
5
+ <h1><%= t("devise.passwords.edit.change_your_password") %></h1>
6
+ </div>
7
+ </div>
8
+
9
+ <div class="row">
10
+ <div class="columns medium-7 large-5 medium-centered">
11
+ <div class="card">
12
+ <div class="card__content">
13
+ <%= decidim_form_for(resource, namespace: "password", as: resource_name, url: password_path(resource_name), html: { method: :put, class: "register-form new_user" }) do |f| %>
14
+ <%= form_required_explanation %>
15
+
16
+ <%= f.hidden_field :reset_password_token %>
17
+
18
+ <%= render("decidim/friendly_signup/shared/password_fields", form: f, options: { autocomplete: "off", help_text: t("devise.passwords.edit.password_help", minimun_characters: ::PasswordValidator::MINIMUM_LENGTH) }) %>
19
+
20
+ <div class="actions">
21
+ <%= f.submit t("devise.passwords.edit.change_my_password"), class: "button expanded" %>
22
+ </div>
23
+ <% end %>
24
+
25
+ <%= render "decidim/devise/shared/links" %>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </div>
@@ -0,0 +1,91 @@
1
+ <% add_decidim_page_title(t(".sign_up")) %>
2
+
3
+ <% content_for :devise_links do %>
4
+ <%= render "decidim/devise/shared/links" %>
5
+ <% end %>
6
+
7
+ <div class="wrapper">
8
+ <div class="row collapse">
9
+ <div class="row collapse">
10
+ <div class="columns large-8 large-centered text-center page-title">
11
+ <h1><%= t(".sign_up") %></h1>
12
+ <p>
13
+ <%= t(".subtitle") %>
14
+ </p>
15
+ <p>
16
+ <%= t(".already_have_an_account?") %>
17
+ <%= link_to t(".sign_in"), new_user_session_path %>
18
+ </p>
19
+ </div>
20
+ </div>
21
+
22
+ <% cache current_organization do %>
23
+ <%= render "decidim/devise/shared/omniauth_buttons" %>
24
+ <% end %>
25
+
26
+ <div class="row">
27
+ <div class="columns large-6 medium-10 medium-centered">
28
+
29
+ <%= decidim_form_for(@form, namespace: "registration", as: resource_name, url: registration_path(resource_name), html: { class: "register-form new_user", id: "register-form" }) do |f| %>
30
+ <%= invisible_captcha %>
31
+ <div class="card">
32
+ <div class="card__content">
33
+ <%= form_required_explanation %>
34
+
35
+ <div class="user-person">
36
+ <div class="field">
37
+ <%= f.text_field :name, help_text: t(".username_help") %>
38
+ </div>
39
+ </div>
40
+
41
+ <div class="user-nickname">
42
+ <div class="field">
43
+ <%= f.text_field :nickname, help_text: t(".nickname_help", organization: current_organization.name), prefix: { value: "@", small: 1, large: 1 } %>
44
+ </div>
45
+ </div>
46
+
47
+ <div class="field">
48
+ <%= f.email_field :email %>
49
+ </div>
50
+
51
+ <%= render("decidim/friendly_signup/shared/password_fields", form: f, options: { help_text: t(".password_help", minimun_characters: ::PasswordValidator::MINIMUM_LENGTH), autocomplete: "off" }) %>
52
+ </div>
53
+ </div>
54
+
55
+ <div class="card" id="card__tos">
56
+ <div class="card__content">
57
+ <h3><%= t(".tos_title") %></h3>
58
+
59
+ <p class="tos-text">
60
+ <%= strip_tags(translated_attribute(terms_and_conditions_page.content)) %>
61
+ </p>
62
+
63
+ <div class="field">
64
+ <%= f.check_box :tos_agreement, label: t(".tos_agreement", link: link_to(t(".terms"), page_path("terms-and-conditions"))) %>
65
+ </div>
66
+ </div>
67
+ </div>
68
+
69
+ <div class="card" id="card__newsletter">
70
+ <div class="card__content">
71
+ <h3><%= t(".newsletter_title") %></h3>
72
+ <div class="field">
73
+ <%= f.check_box :newsletter, label: t(".newsletter"), checked: @form.newsletter %>
74
+ </div>
75
+ </div>
76
+ </div>
77
+
78
+ <div class="card">
79
+ <div class="card__content">
80
+ <div class="actions">
81
+ <%= f.submit t("devise.registrations.new.sign_up"), class: "button expanded" %>
82
+ </div>
83
+ <%= yield :devise_links %>
84
+ </div>
85
+ </div>
86
+ <% end %>
87
+ </div>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ <%= render "decidim/devise/shared/newsletter_modal" %>
@@ -0,0 +1,25 @@
1
+ <% if friendly_override_activated?(:override_passwords) %>
2
+ <div class="user-password"
3
+ data-show-password="<%= t ".show_password" %>"
4
+ data-hide-password="<%= t ".hide_password" %>"
5
+ data-hidden-password="<%= t ".hidden_password" %>"
6
+ data-shown-password="<%= t ".shown_password" %>">
7
+ <div class="field">
8
+ <%= form.password_field :password, options %>
9
+ </div>
10
+ </div>
11
+
12
+ <div class="user-password-confirmation">
13
+ <div class="field">
14
+ <%= form.password_field :password_confirmation, options.except(:help_text, :autocomplete) %>
15
+ </div>
16
+ </div>
17
+ <% else %>
18
+ <div class="field">
19
+ <%= form.password_field :password, options %>
20
+ </div>
21
+
22
+ <div class="field">
23
+ <%= form.password_field :password_confirmation %>
24
+ </div>
25
+ <% end %>
data/config/assets.rb ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ base_path = File.expand_path("..", __dir__)
4
+
5
+ Decidim::Webpacker.register_path("#{base_path}/app/packs")
6
+ Decidim::Webpacker.register_entrypoints(
7
+ decidim_friendly_signup: "#{base_path}/app/packs/entrypoints/decidim_friendly_signup.js"
8
+ )
@@ -0,0 +1,14 @@
1
+ ---
2
+
3
+ base_locale: en
4
+ locales: [en]
5
+
6
+ data:
7
+ external:
8
+ - "<%= %x[bundle info decidim-core --path].chomp %>/config/locales/%{locale}.yml"
9
+
10
+ ignore_unused:
11
+ - "decidim.components.friendly_signup.name"
12
+
13
+ ignore_missing:
14
+ - decidim.participatory_processes.scopes.global
@@ -0,0 +1,10 @@
1
+ ---
2
+ en:
3
+ decidim:
4
+ friendly_signup:
5
+ shared:
6
+ password_fields:
7
+ hidden_password: Your password is hidden
8
+ hide_password: Hide password
9
+ show_password: Show password
10
+ shown_password: Your password is shown
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails"
4
+ require "decidim/core"
5
+
6
+ module Decidim
7
+ module FriendlySignup
8
+ # This is the engine that runs on the public interface of friendly_signup.
9
+ class Engine < ::Rails::Engine
10
+ isolate_namespace Decidim::FriendlySignup
11
+
12
+ # Prepare a zone to create overrides
13
+ # https://edgeguides.rubyonrails.org/engines.html#overriding-models-and-controllers
14
+ # overrides
15
+ config.after_initialize do
16
+ Decidim::Devise::RegistrationsController.include(Decidim::FriendlySignup::NeedsHeaderSnippets)
17
+ Decidim::Devise::InvitationsController.include(Decidim::FriendlySignup::NeedsHeaderSnippets)
18
+ Decidim::Devise::PasswordsController.include(Decidim::FriendlySignup::NeedsHeaderSnippets)
19
+ Decidim::AccountController.include(Decidim::FriendlySignup::NeedsHeaderSnippets)
20
+ end
21
+
22
+ initializer "FriendlySignup.webpacker.assets_path" do
23
+ Decidim.register_assets_path File.expand_path("app/packs", root)
24
+ end
25
+ end
26
+ end
27
+ end