DEV: Migrate associate-account-confirm to the new modal API (#24138)

(+ glimmer)
This commit is contained in:
Jarek Radosz 2023-10-31 11:45:14 +01:00 committed by GitHub
parent c80b5b718c
commit bbcf8e421c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 159 additions and 99 deletions

View File

@ -0,0 +1,46 @@
<DModal
@title={{i18n
"user.associated_accounts.confirm_modal_title"
provider=(i18n (concat "login." @model.provider_name ".name"))
}}
@closeModal={{@closeModal}}
@flash={{this.flash}}
@flashType="error"
>
<:body>
{{#if @model.existing_account_description}}
<p>
{{i18n
"user.associated_accounts.confirm_description.disconnect"
provider=(i18n (concat "login." @model.provider_name ".name"))
account_description=@model.existing_account_description
}}
</p>
{{/if}}
<p>
{{#if @model.account_description}}
{{i18n
"user.associated_accounts.confirm_description.account_specific"
provider=(i18n (concat "login." @model.provider_name ".name"))
account_description=@model.account_description
}}
{{else}}
{{i18n
"user.associated_accounts.confirm_description.generic"
provider=(i18n (concat "login." @model.provider_name ".name"))
}}
{{/if}}
</p>
</:body>
<:footer>
<DButton
@label="user.associated_accounts.connect"
@action={{this.finishConnect}}
@icon="plug"
class="btn-primary"
/>
<DButton @label="user.associated_accounts.cancel" @action={{@closeModal}} />
</:footer>
</DModal>

View File

@ -0,0 +1,35 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
export default class AssociateAccountConfirm extends Component {
@service router;
@service currentUser;
@tracked flash;
@action
async finishConnect() {
try {
const result = await ajax({
url: `/associate/${encodeURIComponent(this.args.model.token)}`,
type: "POST",
});
if (result.success) {
this.router.transitionTo(
"preferences.account",
this.currentUser.findDetails()
);
this.args.closeModal();
} else {
this.flash = result.error;
}
} catch (e) {
popupAjaxError(e);
}
}
}

View File

@ -1,31 +0,0 @@
import Controller from "@ember/controller";
import { inject as service } from "@ember/service";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import ModalFunctionality from "discourse/mixins/modal-functionality";
export default Controller.extend(ModalFunctionality, {
router: service(),
currentUser: service(),
actions: {
finishConnect() {
ajax({
url: `/associate/${encodeURIComponent(this.model.token)}`,
type: "POST",
})
.then((result) => {
if (result.success) {
this.router.transitionTo(
"preferences.account",
this.currentUser.findDetails()
);
this.send("closeModal");
} else {
this.set("model.error", result.error);
}
})
.catch(popupAjaxError);
},
},
});

View File

@ -1,15 +1,16 @@
import { action } from "@ember/object";
import { next } from "@ember/runloop";
import { inject as service } from "@ember/service";
import AssociateAccountConfirm from "discourse/components/modal/associate-account-confirm";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import cookie from "discourse/lib/cookie";
import showModal from "discourse/lib/show-modal";
import DiscourseRoute from "discourse/routes/discourse";
export default DiscourseRoute.extend({
router: service(),
currentUser: service(),
modal: service(),
beforeModel(transition) {
if (!this.currentUser) {
@ -34,7 +35,7 @@ export default DiscourseRoute.extend({
const model = await ajax(
`/associate/${encodeURIComponent(params.token)}.json`
);
showModal("associate-account-confirm", { model });
this.modal.show(AssociateAccountConfirm, { model });
} catch (e) {
popupAjaxError(e);
}

View File

@ -14,7 +14,6 @@ import I18n from "discourse-i18n";
// Known legacy modals in core. Silence deprecation warnings for these so the messages
// don't cause unnecessary noise.
const KNOWN_LEGACY_MODALS = [
"associate-account-confirm",
"avatar-selector",
"change-owner",
"change-post-notice",

View File

@ -1,50 +0,0 @@
<DModalBody
@rawTitle={{i18n
"user.associated_accounts.confirm_modal_title"
provider=(i18n (concat "login." this.model.provider_name ".name"))
}}
>
{{#if this.model.error}}
<div class="alert alert-error">
{{this.model.error}}
</div>
{{/if}}
{{#if this.model.existing_account_description}}
<p>
{{i18n
"user.associated_accounts.confirm_description.disconnect"
provider=(i18n (concat "login." this.model.provider_name ".name"))
account_description=this.model.existing_account_description
}}
</p>
{{/if}}
<p>
{{#if this.model.account_description}}
{{i18n
"user.associated_accounts.confirm_description.account_specific"
provider=(i18n (concat "login." this.model.provider_name ".name"))
account_description=this.model.account_description
}}
{{else}}
{{i18n
"user.associated_accounts.confirm_description.generic"
provider=(i18n (concat "login." this.model.provider_name ".name"))
}}
{{/if}}
</p>
</DModalBody>
<div class="modal-footer">
<DButton
@label="user.associated_accounts.connect"
@action={{action "finishConnect"}}
@icon="plug"
class="btn-primary"
/>
<DButton
@label="user.associated_accounts.cancel"
@action={{action "closeModal"}}
/>
</div>

View File

@ -1,6 +1,7 @@
import { click, fillIn, visit } from "@ember/test-helpers";
import { click, currentURL, fillIn, visit } from "@ember/test-helpers";
import { test } from "qunit";
import PreloadStore from "discourse/lib/preload-store";
import pretender, { response } from "discourse/tests/helpers/create-pretender";
import {
acceptance,
exists,
@ -504,3 +505,76 @@ acceptance(
});
}
);
acceptance("Associate link", function (needs) {
needs.user();
needs.settings({ enable_local_logins: false });
setAuthenticationData(needs.hooks, {
auth_provider: "facebook",
email: "blah@example.com",
email_valid: true,
username: "foobar",
name: "barfoo",
associate_url: "/associate/abcde",
});
test("associates the account", async function (assert) {
preloadInvite({ link: true });
pretender.get("/associate/abcde.json", () => {
return response({
token: "abcde",
provider_name: "facebook",
});
});
pretender.post("/associate/abcde", () => {
return response({ success: true });
});
await visit("/invites/my-valid-invite-token");
assert
.dom(".create-account-associate-link")
.exists("shows the associate account link");
await click(".create-account-associate-link a");
assert.dom(".d-modal").exists();
await click(".d-modal .btn-primary");
assert.strictEqual(currentURL(), "/u/eviltrout/preferences/account");
});
});
acceptance("Associate link, with an error", function (needs) {
needs.user();
needs.settings({ enable_local_logins: false });
setAuthenticationData(needs.hooks, {
auth_provider: "facebook",
email: "blah@example.com",
email_valid: true,
username: "foobar",
name: "barfoo",
associate_url: "/associate/abcde",
});
test("shows the error", async function (assert) {
preloadInvite({ link: true });
pretender.get("/associate/abcde.json", () => {
return response({
token: "abcde",
provider_name: "facebook",
});
});
pretender.post("/associate/abcde", () => {
return response({ error: "sorry, no" });
});
await visit("/invites/my-valid-invite-token");
await click(".create-account-associate-link a");
await click(".d-modal .btn-primary");
assert.dom(".d-modal .alert").hasText("sorry, no");
});
});

View File

@ -1,14 +0,0 @@
import { click, tab, visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Modal - Login", function () {
test("You can tab to the login button", async function (assert) {
await visit("/");
await click("header .login-button");
// you have to press the tab key twice to get to the login button
await tab({ unRestrainTabIndex: true });
await tab({ unRestrainTabIndex: true });
assert.dom(".modal-footer #login-button").isFocused();
});
});