user setting: Move password change flow in UI into modal.

Thanks to @brokwhittaker for his significant chagnes in
password modal design.
This commit is contained in:
YJDave 2017-12-24 23:30:29 +05:30 committed by Steve Howell
parent 849d63dd1c
commit 2ca0fb4128
5 changed files with 138 additions and 64 deletions

View File

@ -85,9 +85,10 @@ exports.set_up = function () {
clear_password_change();
$('#pw_change_link').on('click', function (e) {
$('#change_password').on('click', function (e) {
e.preventDefault();
$('#pw_change_link').hide();
e.stopPropagation();
overlays.open_modal('change_password_modal');
$('#pw_change_controls').show();
if (page_params.realm_password_auth_enabled !== false) {
// zxcvbn.js is pretty big, and is only needed on password
@ -104,6 +105,57 @@ exports.set_up = function () {
}
});
$('#change_password_button').on('click', function (e) {
e.preventDefault();
e.stopPropagation();
var change_password_info = $('#change_password_modal').find(".change_password_info").expectOne();
var data = {
old_password: $('#old_password').val(),
new_password: $('#new_password').val(),
confirm_password: $('#confirm_password').val(),
};
channel.patch({
url: "/json/settings",
data: data,
beforeSubmit: function () {
if (page_params.realm_password_auth_enabled !== false) {
// FIXME: Check that the two password fields match
// FIXME: Use the same jQuery validation plugin as the signup form?
var field = $('#new_password');
var new_pw = $('#new_password').val();
if (new_pw !== '') {
var password_ok = common.password_quality(new_pw, undefined, field);
if (password_ok === undefined) {
// zxcvbn.js didn't load, for whatever reason.
settings_change_error(
'An internal error occurred; try reloading the page. ' +
'Sorry for the trouble!');
return false;
} else if (!password_ok) {
settings_change_error(i18n.t('New password is too weak'));
return false;
}
}
}
return true;
},
success: function () {
settings_change_success(i18n.t("Updated settings!"));
overlays.close_modal('change_password_modal');
},
complete: function () {
// Whether successful or not, clear the password boxes.
// TODO: Clear these earlier, while the request is still pending.
clear_password_change();
},
error: function (xhr) {
ui_report.error(i18n.t("Failed"), xhr, change_password_info);
},
});
});
$('#new_password').on('change keyup', function () {
var field = $('#new_password');
common.password_quality(field.val(), $('#pw_strength .bar'), field);
@ -111,39 +163,12 @@ exports.set_up = function () {
$("form.your-account-settings").ajaxForm({
dataType: 'json', // This seems to be ignored. We still get back an xhr.
beforeSubmit: function () {
if (page_params.realm_password_auth_enabled !== false) {
// FIXME: Check that the two password fields match
// FIXME: Use the same jQuery validation plugin as the signup form?
var field = $('#new_password');
var new_pw = $('#new_password').val();
if (new_pw !== '') {
var password_ok = common.password_quality(new_pw, undefined, field);
if (password_ok === undefined) {
// zxcvbn.js didn't load, for whatever reason.
settings_change_error(
'An internal error occurred; try reloading the page. ' +
'Sorry for the trouble!');
return false;
} else if (!password_ok) {
settings_change_error(i18n.t('New password is too weak'));
return false;
}
}
}
return true;
},
success: function () {
settings_change_success(i18n.t("Updated settings!"));
},
error: function (xhr) {
settings_change_error(i18n.t("Error changing settings"), xhr);
},
complete: function () {
// Whether successful or not, clear the password boxes.
// TODO: Clear these earlier, while the request is still pending.
clear_password_change();
},
});
$('#change_email_button').on('click', function (e) {

View File

@ -73,3 +73,31 @@ a.no-underline:hover {
.ps:hover.ps--in-scrolling.ps--y > .ps__scrollbar-y-rail > .ps__scrollbar-y {
background-color: #606060;
}
/* -- flex forms -- */
.flex-row * {
box-sizing: border-box;
}
.flex-row input[type=text],
.flex-row input[type=password] {
height: auto;
width: 100%;
}
.flex-row {
display: flex;
}
.flex-row.normal {
width: 500px;
}
.flex-row .field {
margin: 10px 10px;
width: 100%;
}
.flex-row .field + .field {
margin-left: 10px;
}

View File

@ -1092,6 +1092,14 @@ input[type=checkbox].inline-block {
cursor: pointer;
}
#settings_page #change_password_modal {
width: auto;
}
#settings_page #change_password_modal .change_password_info {
margin: 10px;
}
#deactivation_user_modal.fade.in {
top: calc(50% - 120px);
}

View File

@ -2359,8 +2359,8 @@ button.topic_edit_cancel {
/* FIXME: Combine this rule with the one in portico.css somehow? */
#pw_strength {
width: 220px;
height: 25px;
width: 100%;
height: 10px;
margin-bottom: 0px;
}

View File

@ -39,49 +39,62 @@
</div>
</form>
<form action="/json/settings" method="patch"
class="form-horizontal your-account-settings">
<form class="password-change-form grid">
<div class="input-group user-name-section">
<label class="inline-block title">{{t "Password" }}</label>
<a id="change_password" {{#if page_params.realm_email_auth_enabled}}href="#change_password"{{/if}}>
{{#if page_params.realm_email_auth_enabled}}
<div class="input-group inline-block" id="pw_change_link">
<button type="button" class="change_password_button button rounded inline-block input-size" data-dismiss="modal">{{t "Change password" }}</button>
</div>
{{/if}}
</a>
</div>
<div class="inline-block grid user-name-parent">
<div id="change_password_modal" class="modal hide" tabindex="-1" role="dialog"
aria-labelledby="change_password_modal_label" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="{{t 'Close' }}"><span aria-hidden="true">&times;</span></button>
<h3 id="change_password_modal_label">{{t "Change password" }}</h3>
</div>
<div class="flex-row normal">
<div class="field">
<label for="old_password" class="title">{{t "Old password" }}</label>
<input type="password" autocomplete="off" name="old_password" id="old_password" class="w-200 inline-block" value="" />
<div class="info">
<a href="/accounts/password/reset/" class="sea-green" target="_blank">{{t "Forgotten it?" }}</a>
</div>
</div>
<div class="field">
<label for="new_password" class="title">{{t "New password" }}</label>
<input type="password" autocomplete="off" name="new_password" id="new_password" class="w-200 inline-block" value=""
data-min-length="{{ page_params.password_min_length }}" data-min-guesses="{{ page_params.password_min_guesses }}" />
<div class="progress inline-block" id="pw_strength">
<div class="bar bar-danger fade" style="width: 10%;"></div>
</div>
</div>
</div>
<div class="alert change_password_info"></div>
<div class="modal-footer">
<button class="button white rounded" data-dismiss="modal">{{t "Cancel" }}</button>
<button id='change_password_button' class="button rounded sea-green" data-dismiss="modal">{{t "Change" }}</button>
</div>
</div>
</form>
<form class="form-horizontal your-account-settings">
<div class=inline-block grid user-name-parent">
<div class="user-name-section inline-block">
<div class="input-group" id="name_change_container">
<label for="full_name" class="inline-block title">{{t "Full name" }}</label>
<input type="text" name="full_name" id="full_name" class="w-200 inline-block" value="{{ page_params.full_name }}" {{#if page_params.realm_name_changes_disabled}}disabled="disabled" {{/if}}/>
<i class="icon-vector-question-sign settings-info-icon change_name_tooltip" data-toggle="tooltip"
<i class="icon-vector-question-sign change_name_tooltip" data-toggle="tooltip"
{{#unless page_params.realm_name_changes_disabled}}style="display:none" {{/unless}}
title="{{t 'Changing your name has been disabled by your Zulip organization administrators. Contact an administrator for help.' }}"/>
<div class="warning"></div>
</div>
<!-- password start -->
{{#if page_params.realm_email_auth_enabled}}
<div class="input-group" id="pw_change_link">
<label for="change_password_button" class="inline-block title">{{t "Password" }}</label>
<button class="change_password_button button rounded inline-block input-size" data-dismiss="modal">{{t "Change password" }}</button>
</div>
<div id="pw_change_controls">
<div class="input-group">
<label for="old_password" class="inline-block title">{{t "Old password" }}</label>
<input type="password" autocomplete="off" name="old_password" id="old_password" class="w-200 inline-block" value="" />
<div class="warning">
<a href="/accounts/password/reset/" class="sea-green" target="_blank">{{t "Forgotten it?" }}</a>
</div>
</div>
<div class="input-group">
<label for="new_password" class="inline-block title">{{t "New password" }}</label>
<input type="password" autocomplete="off" name="new_password" id="new_password" class="w-200 inline-block" value=""
data-min-length="{{ page_params.password_min_length }}" data-min-guesses="{{ page_params.password_min_guesses }}" />
<div class="warning">
<div class="progress inline-block" id="pw_strength">
<div class="bar bar-danger fade" style="width: 10%;"></div>
</div>
</div>
</div>
</div>
{{/if}}
<div class="input-group no-border">
<label for="" class="inline-block"></label>
<button type="submit" class="button rounded w-200 sea-green input-size" name="change_settings">