UX: add link for email login below username, remove button (#12118)

This commit is contained in:
Kris 2021-02-24 16:30:08 -05:00 committed by GitHub
parent 437c348598
commit 362dd798ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 56 additions and 44 deletions

View File

@ -99,6 +99,7 @@ export default Controller.extend(ModalFunctionality, {
} }
if (hasAtLeastOneLoginButton && !showSecondFactor && !showSecurityKey) { if (hasAtLeastOneLoginButton && !showSecondFactor && !showSecurityKey) {
classes.push("has-alt-auth"); classes.push("has-alt-auth");
document.querySelector("#discourse-modal").classList.add("has-alt-auth");
} }
if (!canLoginLocal) { if (!canLoginLocal) {
classes.push("no-local-login"); classes.push("no-local-login");
@ -114,9 +115,9 @@ export default Controller.extend(ModalFunctionality, {
return showSecondFactor || showSecurityKey; return showSecondFactor || showSecurityKey;
}, },
@discourseComputed("canLoginLocalWithEmail") @discourseComputed()
hasAtLeastOneLoginButton(canLoginLocalWithEmail) { hasAtLeastOneLoginButton() {
return findAll().length > 0 || canLoginLocalWithEmail; return findAll().length > 0;
}, },
@discourseComputed("loggingIn") @discourseComputed("loggingIn")
@ -133,9 +134,9 @@ export default Controller.extend(ModalFunctionality, {
showSpinner: readOnly("loggingIn"), showSpinner: readOnly("loggingIn"),
@discourseComputed("canLoginLocalWithEmail", "processingEmailLink") @discourseComputed("canLoginLocalWithEmail")
showLoginWithEmailLink(canLoginLocalWithEmail, processingEmailLink) { showLoginWithEmailLink(canLoginLocalWithEmail) {
return canLoginLocalWithEmail && !processingEmailLink; return canLoginLocalWithEmail;
}, },
actions: { actions: {

View File

@ -10,12 +10,3 @@
{{b.title}} {{b.title}}
</button> </button>
{{/each}} {{/each}}
{{#if showLoginWithEmailLink}}
{{d-button
action=emailLogin
label="email_login.button_label"
disabled=processingEmailLink
icon="far-envelope"
class="login-with-email-button"}}
{{/if}}

View File

@ -6,11 +6,7 @@
<p class="login-subheader">{{i18n "login.subheader_title"}}</p> <p class="login-subheader">{{i18n "login.subheader_title"}}</p>
</div> </div>
{{#if showLoginButtons}} {{#if showLoginButtons}}
{{login-buttons {{login-buttons externalLogin=(action "externalLogin")}}
showLoginWithEmailLink=showLoginWithEmailLink
processingEmailLink=processingEmailLink
emailLogin=(action "emailLogin")
externalLogin=(action "externalLogin")}}
{{/if}} {{/if}}
{{#if canLoginLocal}} {{#if canLoginLocal}}
@ -19,6 +15,11 @@
<div class="input-group"> <div class="input-group">
{{input value=loginName class=(value-entered loginName)type="email" id="login-account-name" autocorrect="off" autocapitalize="off" disabled=showSecondFactor}} {{input value=loginName class=(value-entered loginName)type="email" id="login-account-name" autocorrect="off" autocapitalize="off" disabled=showSecondFactor}}
<label class="alt-placeholder" for="login-account-name">{{i18n "login.email_placeholder"}}</label> <label class="alt-placeholder" for="login-account-name">{{i18n "login.email_placeholder"}}</label>
{{#if showLoginWithEmailLink}}
<a href id="email-login-link" {{action (unless processingEmailLink "emailLogin")}}>
{{i18n "email_login.login_link"}}
</a>
{{/if}}
</div> </div>
<div class="input-group"> <div class="input-group">
{{input value=loginPassword class=(value-entered loginPassword) type="password" id="login-account-password" maxlength="200" disabled=showSecondFactor}} {{input value=loginPassword class=(value-entered loginPassword) type="password" id="login-account-password" maxlength="200" disabled=showSecondFactor}}

View File

@ -13,6 +13,11 @@
<div class="input-group"> <div class="input-group">
{{input value=loginName type="email" id="login-account-name" class=(value-entered loginName) autocomplete="username" autocorrect="off" autocapitalize="off" disabled=showSecondFactor}} {{input value=loginName type="email" id="login-account-name" class=(value-entered loginName) autocomplete="username" autocorrect="off" autocapitalize="off" disabled=showSecondFactor}}
<label class="alt-placeholder" for="login-account-name">{{i18n "login.email_placeholder"}}</label> <label class="alt-placeholder" for="login-account-name">{{i18n "login.email_placeholder"}}</label>
{{#if showLoginWithEmailLink}}
<a href id="email-login-link" {{action (unless processingEmailLink "emailLogin")}}>
{{i18n "email_login.login_link"}}
</a>
{{/if}}
</div> </div>
<div class="input-group"> <div class="input-group">
{{input value=loginPassword type="password" class=(value-entered loginPassword) id="login-account-password" autocomplete="current-password" maxlength="200" capsLockOn=capsLockOn disabled=disableLoginFields}} {{input value=loginPassword type="password" class=(value-entered loginPassword) id="login-account-password" autocomplete="current-password" maxlength="200" capsLockOn=capsLockOn disabled=disableLoginFields}}
@ -75,11 +80,7 @@
<p class="login-subheader">{{i18n "login.subheader_title"}}</p> <p class="login-subheader">{{i18n "login.subheader_title"}}</p>
</div> </div>
{{/if}} {{/if}}
{{login-buttons {{login-buttons externalLogin=(action "externalLogin")}}
showLoginWithEmailLink=showLoginWithEmailLink
processingEmailLink=processingEmailLink
emailLogin=(action "emailLogin")
externalLogin=(action "externalLogin")}}
</div> </div>
{{/if}} {{/if}}
{{/d-modal-body}} {{/d-modal-body}}

View File

@ -19,7 +19,7 @@ acceptance("Login with email - hide email address taken", function (needs) {
await visit("/"); await visit("/");
await click("header .login-button"); await click("header .login-button");
await fillIn("#login-account-name", "someuser@example.com"); await fillIn("#login-account-name", "someuser@example.com");
await click(".login-with-email-button"); await click("#email-login-link");
assert.equal( assert.equal(
queryAll(".alert-success").html().trim(), queryAll(".alert-success").html().trim(),

View File

@ -15,7 +15,7 @@ acceptance("Login with email - no social logins", function (needs) {
await visit("/"); await visit("/");
await click("header .login-button"); await click("header .login-button");
assert.ok(exists(".login-with-email-button")); assert.ok(exists("#email-login-link"));
}); });
test("with login with email disabled", async function (assert) { test("with login with email disabled", async function (assert) {

View File

@ -18,7 +18,7 @@ acceptance("Login with email disabled", function (needs) {
); );
assert.notOk( assert.notOk(
exists(".login-with-email-button"), exists("#email-login-link"),
"it displays the login with email button" "it displays the login with email button"
); );
}); });

View File

@ -30,12 +30,12 @@ acceptance("Login with email", function (needs) {
); );
assert.ok( assert.ok(
exists(".login-with-email-button"), exists("#email-login-link"),
"it displays the login with email button" "it displays the login with email button"
); );
await fillIn("#login-account-name", "someuser"); await fillIn("#login-account-name", "someuser");
await click(".login-with-email-button"); await click("#email-login-link");
assert.equal( assert.equal(
queryAll(".alert-error").html(), queryAll(".alert-error").html(),
@ -46,7 +46,7 @@ acceptance("Login with email", function (needs) {
); );
await fillIn("#login-account-name", "someuser@gmail.com"); await fillIn("#login-account-name", "someuser@gmail.com");
await click(".login-with-email-button"); await click("#email-login-link");
assert.equal( assert.equal(
queryAll(".alert-error").html(), queryAll(".alert-error").html(),
@ -60,7 +60,7 @@ acceptance("Login with email", function (needs) {
userFound = true; userFound = true;
await click(".login-with-email-button"); await click("#email-login-link");
assert.equal( assert.equal(
queryAll(".alert-success").html().trim(), queryAll(".alert-success").html().trim(),
@ -71,7 +71,7 @@ acceptance("Login with email", function (needs) {
await visit("/"); await visit("/");
await click("header .login-button"); await click("header .login-button");
await fillIn("#login-account-name", "someuser@gmail.com"); await fillIn("#login-account-name", "someuser@gmail.com");
await click(".login-with-email-button"); await click("#email-login-link");
assert.equal( assert.equal(
queryAll(".alert-success").html().trim(), queryAll(".alert-success").html().trim(),

View File

@ -12,6 +12,10 @@
display: none; display: none;
} }
#discourse-modal:not(.has-alt-auth) .modal-inner-container {
max-width: 28em; // prevents long alerts from expanding the modal width
}
.login-modal:not(.hidden).has-alt-auth.no-local-login { .login-modal:not(.hidden).has-alt-auth.no-local-login {
min-width: fit-content; min-width: fit-content;
background: var(--secondary); background: var(--secondary);
@ -107,12 +111,12 @@
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-bottom: 1em; margin-bottom: 0.8em;
&:last-child { &:last-child {
margin-bottom: 2em; margin-bottom: 2em;
} }
input { input {
padding: 0.75em 0.5em; padding: 0.75em 0.77em;
border-radius: 0.25em; border-radius: 0.25em;
min-width: 250px; min-width: 250px;
box-shadow: none; box-shadow: none;
@ -149,6 +153,19 @@
input.alt-placeholder:invalid { input.alt-placeholder:invalid {
color: var(--primary); color: var(--primary);
} }
#email-login-link {
opacity: 0;
}
#forgot-password-link,
#email-login-link {
font-size: $font-down-1;
}
input.value-entered + label.alt-placeholder + #email-login-link {
opacity: 1;
transition: opacity 0.5s;
}
.tip:not(:empty) + label.more-info { .tip:not(:empty) + label.more-info {
display: none; display: none;
} }

View File

@ -51,6 +51,7 @@ $base-font-family: var(--font-family) !default;
$heading-font-family: var(--heading-font-family) !default; $heading-font-family: var(--heading-font-family) !default;
// Font-size defintions, multiplier ^ (step / interval) // Font-size defintions, multiplier ^ (step / interval)
$font-up-7: 2.639em;
$font-up-6: 2.296em; $font-up-6: 2.296em;
$font-up-5: 2em; $font-up-5: 2em;
$font-up-4: 1.7511em; $font-up-4: 1.7511em;
@ -64,6 +65,7 @@ $font-down-3: 0.6599em;
$font-down-4: 0.5745em; $font-down-4: 0.5745em;
$font-down-5: 0.5em; $font-down-5: 0.5em;
$font-down-6: 0.4355em; $font-down-6: 0.4355em;
$font-down-7: 0.3789em;
// inputs/textareas in iOS need to be at least 16px to avoid triggering zoom on focus // inputs/textareas in iOS need to be at least 16px to avoid triggering zoom on focus
// with base at 15px, the below gives 16.05px // with base at 15px, the below gives 16.05px

View File

@ -109,7 +109,7 @@
.login-left-side { .login-left-side {
align-self: stretch; align-self: stretch;
width: calc(60% - 4em); width: calc(60% - 4em);
padding: 1em 2em; padding: 3em 3em 2.5em;
} }
} }
.login-left-side { .login-left-side {
@ -117,10 +117,11 @@
width: calc(100% - 4em); width: calc(100% - 4em);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 1em 4em 1em 2em; padding: 3em 3em 2.5em;
.login-welcome-header { .login-welcome-header {
.login-title { .login-title {
font-size: 2.75em; line-height: $line-height-small;
font-size: $font-up-7;
} }
.login-subheader { .login-subheader {
font-size: 1.125em !important; font-size: 1.125em !important;
@ -132,12 +133,11 @@
align-items: flex-start !important; align-items: flex-start !important;
} }
#login-form { #login-form {
margin: 1.5em 0 0 0; margin: 3em 0 1.25em 0;
} }
.modal-footer { .modal-footer {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between;
width: 100%; width: 100%;
padding: 0; padding: 0;
border: 0; border: 0;
@ -147,7 +147,7 @@
display: none; display: none;
} }
&.has-alt-auth .login-right-side { &.has-alt-auth .login-right-side {
width: 40%; width: 35%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;

View File

@ -141,8 +141,6 @@
} }
#login-form { #login-form {
margin-bottom: 0.75em;
label { label {
float: left; float: left;
display: block; display: block;

View File

@ -1718,6 +1718,7 @@ en:
email_login: email_login:
link_label: "Email me a login link" link_label: "Email me a login link"
button_label: "with email" button_label: "with email"
login_link: "Skip the password; email me a login link"
emoji: "lock emoji" emoji: "lock emoji"
complete_username: "If an account matches the username <b>%{username}</b>, you should receive an email with a login link shortly." complete_username: "If an account matches the username <b>%{username}</b>, you should receive an email with a login link shortly."
complete_email: "If an account matches <b>%{email}</b>, you should receive an email with a login link shortly." complete_email: "If an account matches <b>%{email}</b>, you should receive an email with a login link shortly."