DEV: Refactor composer and logout dialogs (#18156)

This commit is contained in:
Penar Musaraj 2022-09-13 12:30:52 -04:00 committed by GitHub
parent 08cb9ecca4
commit b8adb70973
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 136 additions and 111 deletions

View File

@ -18,9 +18,7 @@ import discourseComputed, {
import DiscourseURL from "discourse/lib/url";
import Draft from "discourse/models/draft";
import I18n from "I18n";
import { iconHTML } from "discourse-common/lib/icon-library";
import { Promise } from "rsvp";
import bootbox from "bootbox";
import { buildQuote } from "discourse/lib/quote";
import deprecated from "discourse-common/lib/deprecated";
import discourseDebounce from "discourse-common/lib/debounce";
@ -87,6 +85,7 @@ export function addPopupMenuOptionsCallback(callback) {
export default Controller.extend({
topicController: controller("topic"),
router: service(),
dialog: service(),
checkedMessages: false,
messageCount: null,
@ -858,7 +857,7 @@ export default Controller.extend({
timeLeft: durationTextFromSeconds(timeLeft),
});
bootbox.alert(message);
this.dialog.alert(message);
return;
} else {
// Edge case where the user tries to post again immediately.
@ -885,40 +884,37 @@ export default Controller.extend({
currentTopic.id !== composer.get("topic.id") &&
(this.isStaffUser || !currentTopic.closed)
) {
const message =
"<h1>" + I18n.t("composer.posting_not_on_topic") + "</h1>";
let buttons = [
this.dialog.alert({
title: I18n.t("composer.posting_not_on_topic"),
buttons: [
{
label: I18n.t("composer.cancel"),
class: "btn-flat btn-text btn-reply-where-cancel",
},
];
buttons.push({
label:
I18n.t("composer.reply_here") +
"<br/><div class='topic-title overflow-ellipsis'>" +
currentTopic.get("fancyTitle") +
"</div>",
class: "btn-reply-here",
callback: () => {
composer.setProperties({ topic: currentTopic, post: null });
this.save(true);
},
});
buttons.push({
label:
I18n.t("composer.reply_original") +
"<br/><div class='topic-title overflow-ellipsis'>" +
this.get("model.topic.fancyTitle") +
"</div>",
class: "btn-primary btn-reply-on-original",
callback: () => this.save(true),
action: () => this.save(true),
},
{
label:
I18n.t("composer.reply_here") +
"<br/><div class='topic-title overflow-ellipsis'>" +
currentTopic.get("fancyTitle") +
"</div>",
class: "btn-reply-here",
action: () => {
composer.setProperties({ topic: currentTopic, post: null });
this.save(true);
},
},
{
label: I18n.t("composer.cancel"),
class: "btn-flat btn-text btn-reply-where-cancel",
},
],
class: "reply-where-modal",
});
bootbox.dialog(message, buttons, { classes: "reply-where-modal" });
return;
}
}
@ -987,8 +983,11 @@ export default Controller.extend({
// TODO: await this:
this.destroyDraft();
if (result.responseJson.message) {
return bootbox.alert(result.responseJson.message, () => {
return this.dialog.alert({
message: result.responseJson.message,
didConfirm: () => {
DiscourseURL.routeTo(result.responseJson.route_to);
},
});
}
return DiscourseURL.routeTo(result.responseJson.route_to);
@ -1010,7 +1009,9 @@ export default Controller.extend({
.catch((error) => {
composer.set("disableDrafts", false);
if (error) {
this.appEvents.one("composer:will-open", () => bootbox.alert(error));
this.appEvents.one("composer:will-open", () =>
this.dialog.alert(error)
);
}
});
@ -1295,23 +1296,27 @@ export default Controller.extend({
}
return new Promise((resolve) => {
bootbox.dialog(I18n.t("drafts.abandon.confirm"), [
{
label: I18n.t("drafts.abandon.no_value"),
callback: () => resolve(data),
},
this.dialog.alert({
message: I18n.t("drafts.abandon.confirm"),
buttons: [
{
label: I18n.t("drafts.abandon.yes_value"),
class: "btn-danger",
icon: iconHTML("far-trash-alt"),
callback: () => {
icon: "far-trash-alt",
action: () => {
this.destroyDraft(data.draft_sequence).finally(() => {
data.draft = null;
resolve(data);
});
},
},
]);
{
label: I18n.t("drafts.abandon.no_value"),
class: "btn-resume-editing",
action: () => resolve(data),
},
],
});
});
},

View File

@ -1,5 +1,4 @@
import I18n from "I18n";
import bootbox from "bootbox";
import logout from "discourse/lib/logout";
let _showingLogout = false;
@ -10,25 +9,27 @@ export default {
after: "message-bus",
initialize(container) {
const messageBus = container.lookup("service:message-bus");
messageBus.subscribe("/logout", () => {
if (_showingLogout) {
const messageBus = container.lookup("service:message-bus"),
dialog = container.lookup("service:dialog");
if (!messageBus) {
return;
}
messageBus.subscribe("/logout", function () {
if (!_showingLogout) {
_showingLogout = true;
bootbox.dialog(
I18n.t("logout"),
{
label: I18n.t("home"),
callback: logout,
},
{
onEscape: logout,
backdrop: "static",
dialog.alert({
message: I18n.t("logout"),
confirmButtonLabel: "home",
didConfirm: logout,
didCancel: logout,
shouldDisplayCancel: false,
});
}
);
_showingLogout = true;
});
},
};

View File

@ -18,7 +18,7 @@ import RestModel from "discourse/models/rest";
import Site from "discourse/models/site";
import Topic from "discourse/models/topic";
import User from "discourse/models/user";
import bootbox from "bootbox";
import { inject as service } from "@ember/service";
import deprecated from "discourse-common/lib/deprecated";
import { isEmpty } from "@ember/utils";
import { propertyNotEqual } from "discourse/lib/computed";
@ -119,6 +119,7 @@ export const SAVE_ICONS = {
};
const Composer = RestModel.extend({
dialog: service(),
_categoryId: null,
unlistTopic: false,
noBump: false,
@ -453,7 +454,9 @@ const Composer = RestModel.extend({
const category = this.category;
if (category && category.topic_template) {
if (this.reply.trim() === category.topic_template.trim()) {
bootbox.alert(I18n.t("composer.error.topic_template_not_modified"));
this.dialog.alert(
I18n.t("composer.error.topic_template_not_modified")
);
return true;
}
}
@ -1277,28 +1280,23 @@ const Composer = RestModel.extend({
) {
const json = e.jqXHR.responseJSON;
draftStatus = json.errors[0];
if (json.extras && json.extras.description) {
const buttons = [];
// ignore and force save draft
buttons.push({
if (json.extras?.description) {
this.dialog.alert({
message: json.extras.description,
buttons: [
{
label: I18n.t("composer.reload"),
class: "btn-primary",
action: () => window.location.reload(),
},
{
label: I18n.t("composer.ignore"),
class: "btn",
callback: () => {
this.set("draftForceSave", true);
action: () => this.set("draftForceSave", true),
},
],
});
// reload
buttons.push({
label: I18n.t("composer.reload"),
class: "btn btn-primary",
callback: () => {
window.location.reload();
},
});
bootbox.dialog(json.extras.description, buttons);
}
}
this.setProperties({

View File

@ -182,9 +182,9 @@ acceptance("Composer", function (needs) {
await fillIn("#reply-title", "this title triggers an error");
await fillIn(".d-editor-input", "this is the *content* of a post");
await click("#reply-control button.create");
assert.ok(exists(".bootbox.modal"), "it pops up an error message");
await click(".bootbox.modal a.btn-primary");
assert.ok(!exists(".bootbox.modal"), "it dismisses the error");
assert.ok(exists(".dialog-body"), "it pops up an error message");
await click(".dialog-footer .btn-primary");
assert.ok(!exists(".dialog-body"), "it dismisses the error");
assert.ok(exists(".d-editor-input"), "the composer input is visible");
});
@ -223,13 +223,14 @@ acceptance("Composer", function (needs) {
await fillIn("#reply-title", "This title doesn't matter");
await fillIn(".d-editor-input", "custom message");
await click("#reply-control button.create");
assert.strictEqual(
query(".bootbox .modal-body").innerText,
query("#dialog-holder .dialog-body").innerText,
"This is a custom response"
);
assert.strictEqual(currentURL(), "/", "it doesn't change routes");
await click(".bootbox .btn-primary");
await click(".dialog-footer .btn-primary");
assert.strictEqual(
currentURL(),
"/faq",
@ -764,11 +765,11 @@ acceptance("Composer", function (needs) {
await click(".topic-post:nth-of-type(1) button.edit");
assert.strictEqual(
query(".modal-body").innerText,
query(".dialog-body").innerText,
I18n.t("drafts.abandon.confirm")
);
await click(".modal-footer .btn.btn-default");
await click(".dialog-footer .btn-resume-editing");
});
test("Can switch states without abandon popup", async function (assert) {
@ -826,7 +827,7 @@ acceptance("Composer", function (needs) {
await visit("/u/charlie");
await click("button.compose-pm");
await click(".modal .btn-default");
await click(".dialog-footer .btn-resume-editing");
const privateMessageUsers = selectKit("#private-message-users");
assert.strictEqual(privateMessageUsers.header().value(), "codinghorror");

View File

@ -1,3 +1,4 @@
import I18n from "I18n";
import EmberObject from "@ember/object";
import User from "discourse/models/user";
import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -6,10 +7,12 @@ import userFixtures from "discourse/tests/fixtures/user-fixtures";
import {
acceptance,
exists,
publishToMessageBus,
query,
queryAll,
updateCurrentUser,
} from "discourse/tests/helpers/qunit-helpers";
import * as logout from "discourse/lib/logout";
import { click, currentRouteName, visit } from "@ember/test-helpers";
import { cloneJSON } from "discourse-common/lib/object";
import { test } from "qunit";
@ -305,3 +308,27 @@ acceptance(
});
}
);
acceptance("User - Logout", function (needs) {
needs.user({ username: "eviltrout" });
test("Dialog works", async function (assert) {
sinon.stub(logout, "default");
await visit("/u/eviltrout");
await publishToMessageBus("/logout");
assert.ok(exists(".dialog-body"));
assert.ok(
!exists(".dialog-footer .btn-default"),
"no cancel button present"
);
assert.strictEqual(
query(".dialog-footer .btn-primary").innerText,
I18n.t("home"),
"primary dialog button is present"
);
await click(".dialog-overlay");
assert.ok(logout.default.called, "logout helper was called");
});
});

View File

@ -59,6 +59,7 @@
.dialog-close {
margin-left: auto;
flex-basis: content;
.d-icon {
color: var(--primary-high);
}

View File

@ -278,15 +278,7 @@
}
}
.bootbox.modal.reply-where-modal {
max-width: 400px;
margin-left: -200px;
h1 {
margin: 0;
font-size: var(--font-up-2);
}
.reply-where-modal {
.btn {
display: block;
text-align: left;