DEV: Migrate forgot-password to the new modal api (#23041)

This commit is contained in:
Jarek Radosz 2023-08-10 00:45:06 +02:00 committed by GitHub
parent e835a91199
commit 2a7eb3d5b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 171 additions and 173 deletions

View File

@ -0,0 +1,66 @@
<DModal
@title={{i18n "forgot_password.title"}}
@closeModal={{@closeModal}}
@flash={{this.flash}}
@flashType="error"
class="forgot-password-modal"
>
<:body>
{{#if this.offerHelp}}
{{html-safe this.offerHelp}}
{{else if this.siteSettings.hide_email_address_taken}}
<label for="username-or-email">
{{i18n "forgot_password.invite_no_username"}}
</label>
<input
{{on "input" this.updateEmailOrUsername}}
value={{this.emailOrUsername}}
placeholder={{i18n "email"}}
type="text"
id="username-or-email"
autocorrect="off"
autocapitalize="off"
/>
{{else}}
<label for="username-or-email">
{{i18n "forgot_password.invite"}}
</label>
<input
{{on "input" this.updateEmailOrUsername}}
value={{this.emailOrUsername}}
placeholder={{i18n "login.email_placeholder"}}
type="text"
id="username-or-email"
autocorrect="off"
autocapitalize="off"
/>
{{/if}}
</:body>
<:footer>
{{#if this.offerHelp}}
<DButton
@action={{@closeModal}}
@label="forgot_password.button_ok"
type="submit"
class="btn-large btn-primary"
/>
{{#unless this.helpSeen}}
<DButton
@action={{this.help}}
@label="forgot_password.button_help"
@icon="question-circle"
class="btn-large"
/>
{{/unless}}
{{else}}
<DButton
@action={{this.resetPassword}}
@disabled={{this.submitDisabled}}
@label="forgot_password.reset"
type="submit"
class="btn-primary forgot-password-reset"
/>
{{/if}}
</:footer>
</DModal>

View File

@ -0,0 +1,90 @@
import Component from "@glimmer/component";
import { inject as service } from "@ember/service";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import I18n from "I18n";
import { ajax } from "discourse/lib/ajax";
import cookie from "discourse/lib/cookie";
import { escapeExpression } from "discourse/lib/utilities";
import { extractError } from "discourse/lib/ajax-error";
import getURL from "discourse-common/lib/get-url";
import { isEmpty } from "@ember/utils";
import { htmlSafe } from "@ember/template";
export default class ForgotPassword extends Component {
@service siteSettings;
@tracked emailOrUsername = cookie("email") || this.args.model.emailOrUsername;
@tracked disabled = false;
@tracked helpSeen = false;
@tracked offerHelp;
@tracked flash;
get submitDisabled() {
if (this.disabled) {
return true;
} else if (this.siteSettings.hide_email_address_taken) {
return !(this.emailOrUsername || "").includes("@");
} else {
return isEmpty((this.emailOrUsername || "").trim());
}
}
@action
updateEmailOrUsername(event) {
this.emailOrUsername = event.target.value;
}
@action
help() {
this.offerHelp = I18n.t("forgot_password.help", { basePath: getURL("") });
this.helpSeen = true;
}
@action
async resetPassword() {
if (this.submitDisabled) {
return false;
}
this.disabled = true;
this.flash = null;
try {
const data = await ajax("/session/forgot_password", {
data: { login: this.emailOrUsername.trim() },
type: "POST",
});
const emailOrUsername = escapeExpression(this.emailOrUsername);
let key = "forgot_password.complete";
key += emailOrUsername.match(/@/) ? "_email" : "_username";
if (data.user_found === false) {
key += "_not_found";
this.flash = htmlSafe(
I18n.t(key, {
email: emailOrUsername,
username: emailOrUsername,
})
);
} else {
key += data.user_found ? "_found" : "";
this.emailOrUsername = "";
this.offerHelp = I18n.t(key, {
email: emailOrUsername,
username: emailOrUsername,
});
this.helpSeen = !data.user_found;
}
} catch (error) {
this.flash = extractError(error);
} finally {
this.disabled = false;
}
}
}

View File

@ -1,104 +0,0 @@
import Controller from "@ember/controller";
import I18n from "I18n";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { ajax } from "discourse/lib/ajax";
import cookie from "discourse/lib/cookie";
import discourseComputed from "discourse-common/utils/decorators";
import { escapeExpression } from "discourse/lib/utilities";
import { flashAjaxError } from "discourse/lib/ajax-error";
import getURL from "discourse-common/lib/get-url";
import { isEmpty } from "@ember/utils";
import { htmlSafe } from "@ember/template";
export default Controller.extend(ModalFunctionality, {
offerHelp: null,
helpSeen: false,
@discourseComputed("accountEmailOrUsername", "disabled")
submitDisabled(accountEmailOrUsername, disabled) {
if (disabled) {
return true;
}
if (this.siteSettings.hide_email_address_taken) {
return !(accountEmailOrUsername || "").includes("@");
} else {
return isEmpty((accountEmailOrUsername || "").trim());
}
},
onShow() {
if (cookie("email")) {
this.set("accountEmailOrUsername", cookie("email"));
}
},
actions: {
ok() {
this.send("closeModal");
},
help() {
this.setProperties({
offerHelp: I18n.t("forgot_password.help", {
basePath: getURL(""),
}),
helpSeen: true,
});
},
resetPassword() {
if (this.submitDisabled) {
return false;
}
this.set("disabled", true);
this.clearFlash();
ajax("/session/forgot_password", {
data: { login: this.accountEmailOrUsername.trim() },
type: "POST",
})
.then((data) => {
const accountEmailOrUsername = escapeExpression(
this.accountEmailOrUsername
);
let key = "forgot_password.complete";
key += accountEmailOrUsername.match(/@/) ? "_email" : "_username";
if (data.user_found === false) {
key += "_not_found";
this.flash(
htmlSafe(
I18n.t(key, {
email: accountEmailOrUsername,
username: accountEmailOrUsername,
})
),
"error"
);
} else {
key += data.user_found ? "_found" : "";
this.set("accountEmailOrUsername", "");
this.set(
"offerHelp",
I18n.t(key, {
email: accountEmailOrUsername,
username: accountEmailOrUsername,
})
);
this.set("helpSeen", !data.user_found);
}
})
.catch(flashAjaxError(this))
.finally(() => {
this.set("disabled", false);
});
return false;
},
},
});

View File

@ -20,6 +20,7 @@ import showModal from "discourse/lib/show-modal";
import { wavingHandURL } from "discourse/lib/waving-hand-url";
import { inject as service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import ForgotPassword from "discourse/components/modal/forgot-password";
// This is happening outside of the app via popup
const AuthErrors = [
@ -32,7 +33,6 @@ const AuthErrors = [
export default Controller.extend(ModalFunctionality, {
createAccount: controller(),
forgotPassword: controller(),
application: controller(),
dialog: service(),
@ -190,11 +190,12 @@ export default Controller.extend(ModalFunctionality, {
@action
handleForgotPassword(event) {
event?.preventDefault();
const forgotPasswordController = this.forgotPassword;
if (forgotPasswordController) {
forgotPasswordController.set("accountEmailOrUsername", this.loginName);
}
this.send("showForgotPassword");
this.modal.show(ForgotPassword, {
model: {
emailOrUsername: this.loginName,
},
});
},
@action

View File

@ -16,6 +16,7 @@ import showModal from "discourse/lib/show-modal";
import { action } from "@ember/object";
import KeyboardShortcutsHelp from "discourse/components/modal/keyboard-shortcuts-help";
import NotActivatedModal from "../components/modal/not-activated";
import ForgotPassword from "discourse/components/modal/forgot-password";
function unlessReadOnly(method, message) {
return function () {
@ -148,11 +149,7 @@ const ApplicationRoute = DiscourseRoute.extend(OpenComposer, {
),
showForgotPassword() {
getOwner(this).lookup("controller:forgot-password").setProperties({
offerHelp: null,
helpSeen: false,
});
showModal("forgot-password", { title: "forgot_password.title" });
this.modal.show(ForgotPassword);
},
showNotActivated(props) {

View File

@ -1,15 +1,19 @@
import DiscourseRoute from "discourse/routes/discourse";
import { inject as service } from "@ember/service";
import { defaultHomepage } from "discourse/lib/utilities";
import { next } from "@ember/runloop";
import ForgotPassword from "discourse/components/modal/forgot-password";
export default class ForgotPasswordRoute extends DiscourseRoute {
@service modal;
async beforeModel() {
const { loginRequired } = this.controllerFor("application");
const e = await this.replaceWith(
await this.replaceWith(
loginRequired ? "login" : `discovery.${defaultHomepage()}`
);
next(() => e.send("showForgotPassword"));
next(() => this.modal.show(ForgotPassword));
}
}

View File

@ -28,7 +28,6 @@ const KNOWN_LEGACY_MODALS = [
"feature-topic-on-profile",
"feature-topic",
"flag",
"forgot-password",
"grant-badge",
"group-default-notifications",
"history",

View File

@ -1,55 +0,0 @@
<form>
<DModalBody @class="forgot-password-modal">
{{#if this.offerHelp}}
{{html-safe this.offerHelp}}
{{else}}
{{#if this.siteSettings.hide_email_address_taken}}
<label for="username-or-email">{{i18n
"forgot_password.invite_no_username"
}}</label>
<TextField
@value={{this.accountEmailOrUsername}}
@placeholderKey="email"
@id="username-or-email"
@autocorrect="off"
@autocapitalize="off"
/>
{{else}}
<label for="username-or-email">{{i18n "forgot_password.invite"}}</label>
<TextField
@value={{this.accountEmailOrUsername}}
@placeholderKey="login.email_placeholder"
@id="username-or-email"
@autocorrect="off"
@autocapitalize="off"
/>
{{/if}}
{{/if}}
</DModalBody>
<div class="modal-footer">
{{#if this.offerHelp}}
<DButton
@class="btn-large btn-primary"
@label="forgot_password.button_ok"
@type="submit"
@action={{action "ok"}}
/>
{{#unless this.helpSeen}}
<DButton
@class="btn-large"
@label="forgot_password.button_help"
@icon="question-circle"
@action={{action "help"}}
/>
{{/unless}}
{{else}}
<DButton
@action={{action "resetPassword"}}
@label="forgot_password.reset"
@disabled={{this.submitDisabled}}
@class="btn-primary forgot-password-reset"
@type="submit"
/>
{{/if}}
</div>
</form>