mirror of
https://github.com/discourse/discourse.git
synced 2025-02-02 20:59:46 +08:00
UX: refactor password reset page (#30323)
This commit is contained in:
parent
af8c98217a
commit
8f26ae7b7d
|
@ -29,6 +29,7 @@ export default class PasswordResetController extends Controller.extend(
|
||||||
requiresApproval = false;
|
requiresApproval = false;
|
||||||
redirected = false;
|
redirected = false;
|
||||||
maskPassword = true;
|
maskPassword = true;
|
||||||
|
passwordValidationVisible = false;
|
||||||
|
|
||||||
lockImageUrl = getURL("/images/lock.svg");
|
lockImageUrl = getURL("/images/lock.svg");
|
||||||
|
|
||||||
|
@ -65,6 +66,30 @@ export default class PasswordResetController extends Controller.extend(
|
||||||
return getURL(redirectTo || "/");
|
return getURL(redirectTo || "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@discourseComputed(
|
||||||
|
"passwordValidation.ok",
|
||||||
|
"passwordValidation.reason",
|
||||||
|
"passwordValidationVisible"
|
||||||
|
)
|
||||||
|
showPasswordValidation(
|
||||||
|
passwordValidationOk,
|
||||||
|
passwordValidationReason,
|
||||||
|
passwordValidationVisible
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
passwordValidationOk ||
|
||||||
|
(passwordValidationReason && passwordValidationVisible)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
togglePasswordValidation() {
|
||||||
|
this.set(
|
||||||
|
"passwordValidationVisible",
|
||||||
|
Boolean(this.passwordValidation.reason)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
done(event) {
|
done(event) {
|
||||||
if (wantsNewWindow(event)) {
|
if (wantsNewWindow(event)) {
|
||||||
|
|
|
@ -2,11 +2,7 @@
|
||||||
{{hide-application-sidebar}}
|
{{hide-application-sidebar}}
|
||||||
{{hide-application-header-buttons "search" "login" "signup" "menu"}}
|
{{hide-application-header-buttons "search" "login" "signup" "menu"}}
|
||||||
<div class="container password-reset clearfix">
|
<div class="container password-reset clearfix">
|
||||||
<div class="pull-left col-image">
|
<form class="change-password-form login-left-side">
|
||||||
<img src={{this.lockImageUrl}} class="password-reset-img" alt="" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pull-left col-form">
|
|
||||||
{{#if this.successMessage}}
|
{{#if this.successMessage}}
|
||||||
<p>{{this.successMessage}}</p>
|
<p>{{this.successMessage}}</p>
|
||||||
|
|
||||||
|
@ -22,7 +18,6 @@
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<form class="change-password-form">
|
|
||||||
{{#if this.securityKeyOrSecondFactorRequired}}
|
{{#if this.securityKeyOrSecondFactorRequired}}
|
||||||
<h2>{{i18n "user.change_password.title"}}</h2>
|
<h2>{{i18n "user.change_password.title"}}</h2>
|
||||||
<p>
|
<p>
|
||||||
|
@ -35,9 +30,7 @@
|
||||||
|
|
||||||
{{#if this.displaySecurityKeyForm}}
|
{{#if this.displaySecurityKeyForm}}
|
||||||
<SecurityKeyForm
|
<SecurityKeyForm
|
||||||
@setSecondFactorMethod={{fn
|
@setSecondFactorMethod={{fn (mut this.selectedSecondFactorMethod)}}
|
||||||
(mut this.selectedSecondFactorMethod)
|
|
||||||
}}
|
|
||||||
@backupEnabled={{this.backupEnabled}}
|
@backupEnabled={{this.backupEnabled}}
|
||||||
@totpEnabled={{this.secondFactorRequired}}
|
@totpEnabled={{this.secondFactorRequired}}
|
||||||
@otherMethodAllowed={{this.otherMethodAllowed}}
|
@otherMethodAllowed={{this.otherMethodAllowed}}
|
||||||
|
@ -72,7 +65,7 @@
|
||||||
/>
|
/>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<h2>{{i18n "user.change_password.choose"}}</h2>
|
<h2>{{i18n "user.change_password.choose_new"}}</h2>
|
||||||
{{#if this.errorMessage}}
|
{{#if this.errorMessage}}
|
||||||
<div class="alert alert-error">{{this.errorMessage}}</div>
|
<div class="alert alert-error">{{this.errorMessage}}</div>
|
||||||
<br />
|
<br />
|
||||||
|
@ -81,24 +74,31 @@
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<PasswordField
|
<PasswordField
|
||||||
@value={{this.accountPassword}}
|
@value={{this.accountPassword}}
|
||||||
|
{{on "focusout" this.togglePasswordValidation}}
|
||||||
@capsLockOn={{this.capsLockOn}}
|
@capsLockOn={{this.capsLockOn}}
|
||||||
type={{if this.maskPassword "password" "text"}}
|
type={{if this.maskPassword "password" "text"}}
|
||||||
autofocus="autofocus"
|
autofocus="autofocus"
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
id="new-account-password"
|
id="new-account-password"
|
||||||
/>
|
/>
|
||||||
<TogglePasswordMask
|
<div class="change-password__password-info">
|
||||||
@maskPassword={{this.maskPassword}}
|
<div class="change-password_tip-validation">
|
||||||
@togglePasswordMask={{this.togglePasswordMask}}
|
{{#if this.showPasswordValidation}}
|
||||||
/>
|
<InputTip @validation={{this.passwordValidation}} />
|
||||||
|
{{/if}}
|
||||||
<div class="caps-lock-warning {{unless this.capsLockOn 'hidden'}}">
|
<div
|
||||||
|
class="caps-lock-warning {{unless this.capsLockOn 'hidden'}}"
|
||||||
|
>
|
||||||
{{d-icon "triangle-exclamation"}}
|
{{d-icon "triangle-exclamation"}}
|
||||||
{{i18n "login.caps_lock_warning"}}
|
{{i18n "login.caps_lock_warning"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<TogglePasswordMask
|
||||||
<InputTip @validation={{this.passwordValidation}} />
|
@maskPassword={{this.maskPassword}}
|
||||||
|
@togglePasswordMask={{this.togglePasswordMask}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<DButton
|
<DButton
|
||||||
@action={{action "submit"}}
|
@action={{action "submit"}}
|
||||||
|
@ -107,7 +107,6 @@
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</form>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
|
@ -1,4 +1,4 @@
|
||||||
import { click, fillIn, visit } from "@ember/test-helpers";
|
import { blur, click, fillIn, visit } from "@ember/test-helpers";
|
||||||
import { test } from "qunit";
|
import { test } from "qunit";
|
||||||
import sinon from "sinon";
|
import sinon from "sinon";
|
||||||
import PreloadStore from "discourse/lib/preload-store";
|
import PreloadStore from "discourse/lib/preload-store";
|
||||||
|
@ -71,6 +71,8 @@ acceptance("Password Reset", function (needs) {
|
||||||
assert.dom(".password-reset .tip.good").exists("input looks good");
|
assert.dom(".password-reset .tip.good").exists("input looks good");
|
||||||
|
|
||||||
await fillIn(".password-reset input", "123");
|
await fillIn(".password-reset input", "123");
|
||||||
|
await blur(".password-reset input");
|
||||||
|
|
||||||
assert.dom(".password-reset .tip.bad").exists("input is not valid");
|
assert.dom(".password-reset .tip.bad").exists("input is not valid");
|
||||||
assert.dom(".password-reset .tip.bad").includesHtml(
|
assert.dom(".password-reset .tip.bad").includesHtml(
|
||||||
i18n("user.password.too_short", {
|
i18n("user.password.too_short", {
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
|
|
||||||
body.login-page,
|
body.login-page,
|
||||||
body.signup-page,
|
body.signup-page,
|
||||||
body.invite-page {
|
body.invite-page,
|
||||||
|
body.password-reset-page {
|
||||||
& ~ .powered-by-discourse,
|
& ~ .powered-by-discourse,
|
||||||
.above-main-container-outlet {
|
.above-main-container-outlet {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -25,7 +26,8 @@ body.signup-page {
|
||||||
|
|
||||||
.login-fullpage,
|
.login-fullpage,
|
||||||
.signup-fullpage,
|
.signup-fullpage,
|
||||||
.invites-show {
|
.invites-show,
|
||||||
|
.password-reset-page {
|
||||||
.signup-body,
|
.signup-body,
|
||||||
.login-body {
|
.login-body {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -241,8 +243,6 @@ body.signup-page {
|
||||||
.caps-lock-warning {
|
.caps-lock-warning {
|
||||||
color: var(--danger);
|
color: var(--danger);
|
||||||
font-size: var(--font-down-1);
|
font-size: var(--font-down-1);
|
||||||
font-weight: bold;
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-account__password-info {
|
.create-account__password-info {
|
||||||
|
|
|
@ -33,28 +33,22 @@ body.invite-page {
|
||||||
// the second button can wrap in some locales, and this helps alignment
|
// the second button can wrap in some locales, and this helps alignment
|
||||||
}
|
}
|
||||||
|
|
||||||
.password-reset {
|
|
||||||
.instructions {
|
|
||||||
label {
|
|
||||||
color: var(--primary-medium);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#new-account-password {
|
|
||||||
width: 15em;
|
|
||||||
}
|
|
||||||
.tip {
|
|
||||||
margin: 0 0 0.5em;
|
|
||||||
}
|
|
||||||
.toggle-password-mask {
|
|
||||||
margin-left: 0.25em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.password-reset-page {
|
.password-reset-page {
|
||||||
.caps-lock-warning {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.change-password-form {
|
.change-password-form {
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 400px;
|
||||||
|
input {
|
||||||
|
padding: 0.75em 0.77em;
|
||||||
|
min-width: 250px;
|
||||||
|
margin-bottom: 0.25em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.input {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
.tip {
|
.tip {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user