DEV: refactor bootbox alerts (#18292)
This commit is contained in:
parent
5dea425ee9
commit
cc4af80c7d
|
@ -1,12 +1,13 @@
|
|||
import Component from "@ember/component";
|
||||
import { alias, equal } from "@ember/object/computed";
|
||||
import bootbox from "bootbox";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { action } from "@ember/object";
|
||||
import I18n from "I18n";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Component.extend({
|
||||
classNames: ["watched-word"],
|
||||
dialog: service(),
|
||||
|
||||
isReplace: equal("actionKey", "replace"),
|
||||
isTag: equal("actionKey", "tag"),
|
||||
|
@ -26,7 +27,7 @@ export default Component.extend({
|
|||
this.action(this.word);
|
||||
})
|
||||
.catch((e) => {
|
||||
bootbox.alert(
|
||||
this.dialog.alert(
|
||||
I18n.t("generic_error_with_reason", {
|
||||
error: `http: ${e.status} - ${e.body}`,
|
||||
})
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import Component from "@ember/component";
|
||||
import I18n from "I18n";
|
||||
import Permalink from "admin/models/permalink";
|
||||
import bootbox from "bootbox";
|
||||
import discourseComputed, { bind } from "discourse-common/utils/decorators";
|
||||
import { fmt } from "discourse/lib/computed";
|
||||
import { schedule } from "@ember/runloop";
|
||||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Component.extend({
|
||||
tagName: "",
|
||||
dialog: service(),
|
||||
formSubmitted: false,
|
||||
permalinkType: "topic_id",
|
||||
permalinkTypePlaceholder: fmt("permalinkType", "admin.permalink.%@"),
|
||||
|
@ -29,7 +30,7 @@ export default Component.extend({
|
|||
@bind
|
||||
focusPermalink() {
|
||||
schedule("afterRender", () =>
|
||||
this.element.querySelector(".permalink-url")?.focus()
|
||||
document.querySelector(".permalink-url")?.focus()
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -74,7 +75,12 @@ export default Component.extend({
|
|||
} else {
|
||||
error = I18n.t("generic_error");
|
||||
}
|
||||
bootbox.alert(error, this.focusPermalink);
|
||||
|
||||
this.dialog.alert({
|
||||
message: error,
|
||||
didConfirm: () => this.focusPermalink(),
|
||||
didCancel: () => this.focusPermalink(),
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ import discourseComputed from "discourse-common/utils/decorators";
|
|||
import Component from "@ember/component";
|
||||
import I18n from "I18n";
|
||||
import ScreenedIpAddress from "admin/models/screened-ip-address";
|
||||
import bootbox from "bootbox";
|
||||
import { schedule } from "@ember/runloop";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
/**
|
||||
A form to create an IP address that will be blocked or allowed.
|
||||
|
@ -18,6 +18,7 @@ import { schedule } from "@ember/runloop";
|
|||
|
||||
export default Component.extend({
|
||||
tagName: "form",
|
||||
dialog: service(),
|
||||
classNames: ["screened-ip-address-form", "inline-form"],
|
||||
formSubmitted: false,
|
||||
actionName: "block",
|
||||
|
@ -47,6 +48,12 @@ export default Component.extend({
|
|||
}
|
||||
},
|
||||
|
||||
focusInput() {
|
||||
schedule("afterRender", () => {
|
||||
this.element.querySelector("input").focus();
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
submit() {
|
||||
if (!this.formSubmitted) {
|
||||
|
@ -60,22 +67,20 @@ export default Component.extend({
|
|||
.then((result) => {
|
||||
this.setProperties({ ip_address: "", formSubmitted: false });
|
||||
this.action(ScreenedIpAddress.create(result.screened_ip_address));
|
||||
schedule("afterRender", () =>
|
||||
this.element.querySelector("input").focus()
|
||||
);
|
||||
this.focusInput();
|
||||
})
|
||||
.catch((e) => {
|
||||
this.set("formSubmitted", false);
|
||||
const msg = e.jqXHR.responseJSON?.errors
|
||||
const message = e.jqXHR.responseJSON?.errors
|
||||
? I18n.t("generic_error_with_reason", {
|
||||
error: e.jqXHR.responseJSON.errors.join(". "),
|
||||
})
|
||||
: I18n.t("generic_error");
|
||||
bootbox.alert(msg, () =>
|
||||
schedule("afterRender", () =>
|
||||
this.element.querySelector("input").focus()
|
||||
)
|
||||
);
|
||||
this.dialog.alert({
|
||||
message,
|
||||
didConfirm: () => this.focusInput(),
|
||||
didCancel: () => this.focusInput(),
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -2,10 +2,11 @@ import Component from "@ember/component";
|
|||
import I18n from "I18n";
|
||||
import UppyUploadMixin from "discourse/mixins/uppy-upload";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import bootbox from "bootbox";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Component.extend(UppyUploadMixin, {
|
||||
type: "csv",
|
||||
dialog: service(),
|
||||
uploadUrl: "/tags/upload",
|
||||
addDisabled: alias("uploading"),
|
||||
elementId: "tag-uploader",
|
||||
|
@ -16,9 +17,8 @@ export default Component.extend(UppyUploadMixin, {
|
|||
},
|
||||
|
||||
uploadDone() {
|
||||
bootbox.alert(I18n.t("tagging.upload_successful"), () => {
|
||||
this.refresh();
|
||||
this.closeModal();
|
||||
});
|
||||
this.closeModal();
|
||||
this.refresh();
|
||||
this.dialog.alert(I18n.t("tagging.upload_successful"));
|
||||
},
|
||||
});
|
||||
|
|
|
@ -2,13 +2,14 @@ import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
|||
import Component from "@ember/component";
|
||||
import I18n from "I18n";
|
||||
import WatchedWord from "admin/models/watched-word";
|
||||
import bootbox from "bootbox";
|
||||
import { equal } from "@ember/object/computed";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { schedule } from "@ember/runloop";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Component.extend({
|
||||
tagName: "form",
|
||||
dialog: service(),
|
||||
classNames: ["watched-word-form"],
|
||||
formSubmitted: false,
|
||||
actionKey: null,
|
||||
|
@ -55,6 +56,10 @@ export default Component.extend({
|
|||
});
|
||||
},
|
||||
|
||||
focusInput() {
|
||||
schedule("afterRender", () => this.element.querySelector("input").focus());
|
||||
},
|
||||
|
||||
actions: {
|
||||
changeSelectedTags(tags) {
|
||||
this.setProperties({
|
||||
|
@ -98,22 +103,20 @@ export default Component.extend({
|
|||
isCaseSensitive: false,
|
||||
});
|
||||
this.action(WatchedWord.create(result));
|
||||
schedule("afterRender", () =>
|
||||
this.element.querySelector("input").focus()
|
||||
);
|
||||
this.focusInput();
|
||||
})
|
||||
.catch((e) => {
|
||||
this.set("formSubmitted", false);
|
||||
const msg = e.jqXHR.responseJSON?.errors
|
||||
const message = e.jqXHR.responseJSON?.errors
|
||||
? I18n.t("generic_error_with_reason", {
|
||||
error: e.jqXHR.responseJSON.errors.join(". "),
|
||||
})
|
||||
: I18n.t("generic_error");
|
||||
bootbox.alert(msg, () =>
|
||||
schedule("afterRender", () =>
|
||||
this.element.querySelector("input").focus()
|
||||
)
|
||||
);
|
||||
this.dialog.alert({
|
||||
message,
|
||||
didConfirm: () => this.focusInput(),
|
||||
didCancel: () => this.focusInput(),
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -2,7 +2,7 @@ import Component from "@ember/component";
|
|||
import I18n from "I18n";
|
||||
import UppyUploadMixin from "discourse/mixins/uppy-upload";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import bootbox from "bootbox";
|
||||
import { dialog } from "discourse/lib/uploads";
|
||||
|
||||
export default Component.extend(UppyUploadMixin, {
|
||||
type: "txt",
|
||||
|
@ -21,7 +21,7 @@ export default Component.extend(UppyUploadMixin, {
|
|||
|
||||
uploadDone() {
|
||||
if (this) {
|
||||
bootbox.alert(I18n.t("admin.watched_words.form.upload_successful"));
|
||||
dialog.alert(I18n.t("admin.watched_words.form.upload_successful"));
|
||||
this.done();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import Controller from "@ember/controller";
|
||||
import I18n from "I18n";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import { extractError } from "discourse/lib/ajax-error";
|
||||
import { action } from "@ember/object";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default class AdminBadgesAwardController extends Controller {
|
||||
@service dialog;
|
||||
@tracked saving = false;
|
||||
@tracked replaceBadgeOwners = false;
|
||||
@tracked grantExistingHolders = false;
|
||||
|
@ -84,7 +85,7 @@ export default class AdminBadgesAwardController extends Controller {
|
|||
})
|
||||
.finally(() => (this.saving = false));
|
||||
} else {
|
||||
bootbox.alert(I18n.t("admin.badges.mass_award.aborted"));
|
||||
this.dialog.alert(I18n.t("admin.badges.mass_award.aborted"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import Controller from "@ember/controller";
|
||||
import I18n from "I18n";
|
||||
import bootbox from "bootbox";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Controller.extend({
|
||||
dialog: service(),
|
||||
|
||||
@discourseComputed("model.isSaving")
|
||||
saveButtonText(isSaving) {
|
||||
return isSaving ? I18n.t("saving") : I18n.t("admin.customize.save");
|
||||
|
@ -27,7 +29,7 @@ export default Controller.extend({
|
|||
error: e.jqXHR.responseJSON.errors.join(". "),
|
||||
})
|
||||
: I18n.t("generic_error");
|
||||
bootbox.alert(msg);
|
||||
this.dialog.alert(msg);
|
||||
})
|
||||
.finally(() => this.set("model.changed", false));
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { empty, notEmpty, or } from "@ember/object/computed";
|
||||
import Controller from "@ember/controller";
|
||||
import EmailPreview from "admin/models/email-preview";
|
||||
import bootbox from "bootbox";
|
||||
import { get } from "@ember/object";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Controller.extend({
|
||||
dialog: service(),
|
||||
username: null,
|
||||
lastSeen: null,
|
||||
|
||||
emailEmpty: empty("email"),
|
||||
sendEmailDisabled: or("emailEmpty", "sendingEmail"),
|
||||
showSendEmailForm: notEmpty("model.html_content"),
|
||||
|
@ -50,7 +50,7 @@ export default Controller.extend({
|
|||
EmailPreview.sendDigest(this.username, this.lastSeen, this.email)
|
||||
.then((result) => {
|
||||
if (result.errors) {
|
||||
bootbox.alert(result.errors);
|
||||
this.dialog.alert(result.errors);
|
||||
} else {
|
||||
this.set("sentEmail", true);
|
||||
}
|
||||
|
|
|
@ -3,10 +3,12 @@ import Controller from "@ember/controller";
|
|||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
dialog: service(),
|
||||
|
||||
@observes("model")
|
||||
modelChanged() {
|
||||
const model = this.model;
|
||||
|
@ -78,7 +80,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
this.setProperties({ model: null, workingCopy: null });
|
||||
this.send("closeModal");
|
||||
},
|
||||
() => bootbox.alert(I18n.t("generic_error"))
|
||||
() => this.dialog.alert(I18n.t("generic_error"))
|
||||
);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -2,9 +2,10 @@ import Controller from "@ember/controller";
|
|||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
dialog: service(),
|
||||
loading: true,
|
||||
reseeding: false,
|
||||
categories: null,
|
||||
|
@ -35,11 +36,11 @@ export default Controller.extend(ModalFunctionality, {
|
|||
},
|
||||
type: "POST",
|
||||
})
|
||||
.then(
|
||||
() => this.send("closeModal"),
|
||||
() => bootbox.alert(I18n.t("generic_error"))
|
||||
)
|
||||
.finally(() => this.set("reseeding", false));
|
||||
.catch(() => this.dialog.alert(I18n.t("generic_error")))
|
||||
.finally(() => {
|
||||
this.set("reseeding", false);
|
||||
this.send("closeModal");
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -2,11 +2,13 @@ import Badge from "discourse/models/badge";
|
|||
import I18n from "I18n";
|
||||
import Route from "@ember/routing/route";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import { action, get } from "@ember/object";
|
||||
import showModal from "discourse/lib/show-modal";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default class AdminBadgesShowRoute extends Route {
|
||||
@service dialog;
|
||||
|
||||
serialize(m) {
|
||||
return { badge_id: get(m, "id") || "new" };
|
||||
}
|
||||
|
@ -58,7 +60,7 @@ export default class AdminBadgesShowRoute extends Route {
|
|||
badge.set("preview_loading", false);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
bootbox.alert("Network error");
|
||||
this.dialog.alert("Network error");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import AdminUser from "admin/models/admin-user";
|
||||
import I18n from "I18n";
|
||||
import { Promise } from "rsvp";
|
||||
import Service from "@ember/service";
|
||||
import Service, { inject as service } from "@ember/service";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
|
@ -12,6 +12,8 @@ import showModal from "discourse/lib/show-modal";
|
|||
// and the admin application. Use this if you need front end code to access admin
|
||||
// modules. Inject it optionally, and if it exists go to town!
|
||||
export default Service.extend({
|
||||
dialog: service(),
|
||||
|
||||
showActionLogs(target, filters) {
|
||||
const controller = getOwner(target).lookup(
|
||||
"controller:adminLogs.staffActionLogs"
|
||||
|
@ -120,7 +122,7 @@ export default Service.extend({
|
|||
}
|
||||
})
|
||||
.catch(() => {
|
||||
bootbox.alert(I18n.t("admin.user.delete_failed"));
|
||||
this.dialog.alert(I18n.t("admin.user.delete_failed"));
|
||||
reject();
|
||||
});
|
||||
},
|
||||
|
|
|
@ -2,13 +2,12 @@ import Component from "@ember/component";
|
|||
import { action } from "@ember/object";
|
||||
import I18n from "I18n";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Component.extend({
|
||||
dialog: service(),
|
||||
tagName: "",
|
||||
|
||||
selectableUserBadges: null,
|
||||
|
||||
_selectedUserBadgeId: null,
|
||||
_isSaved: false,
|
||||
_isSaving: false,
|
||||
|
@ -42,7 +41,7 @@ export default Component.extend({
|
|||
this.currentUser.set("title", selectedUserBadge?.badge?.name || "");
|
||||
},
|
||||
() => {
|
||||
bootbox.alert(I18n.t("generic_error"));
|
||||
this.dialog.alert(I18n.t("generic_error"));
|
||||
}
|
||||
)
|
||||
.finally(() => this.set("_isSaving", false));
|
||||
|
|
|
@ -18,14 +18,16 @@ import { and, notEmpty } from "@ember/object/computed";
|
|||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import discourseLater from "discourse-common/lib/later";
|
||||
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
const BOOKMARK_BINDINGS = {
|
||||
enter: { handler: "saveAndClose" },
|
||||
"d d": { handler: "delete" },
|
||||
};
|
||||
|
||||
export default Component.extend({
|
||||
dialog: service(),
|
||||
tagName: "",
|
||||
|
||||
errorMessage: null,
|
||||
selectedReminderType: null,
|
||||
_closeWithoutSaving: null,
|
||||
|
@ -227,7 +229,7 @@ export default Component.extend({
|
|||
_handleSaveError(e) {
|
||||
this._savingBookmarkManually = false;
|
||||
if (typeof e === "string") {
|
||||
bootbox.alert(e);
|
||||
this.dialog.alert(e);
|
||||
} else {
|
||||
popupAjaxError(e);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import Component from "@ember/component";
|
||||
import FilterModeMixin from "discourse/mixins/filter-mode";
|
||||
import NavItem from "discourse/models/nav-item";
|
||||
import bootbox from "bootbox";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { NotificationLevels } from "discourse/lib/notification-levels";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
|
@ -9,7 +8,7 @@ import { inject as service } from "@ember/service";
|
|||
|
||||
export default Component.extend(FilterModeMixin, {
|
||||
router: service(),
|
||||
|
||||
dialog: service(),
|
||||
tagName: "",
|
||||
|
||||
// Should be a `readOnly` instead but some themes/plugins still pass
|
||||
|
@ -158,7 +157,7 @@ export default Component.extend(FilterModeMixin, {
|
|||
|
||||
clickCreateTopicButton() {
|
||||
if (this.categoryReadOnlyBanner && !this.hasDraft) {
|
||||
bootbox.alert(this.categoryReadOnlyBanner);
|
||||
this.dialog.alert(this.categoryReadOnlyBanner);
|
||||
} else {
|
||||
this.createTopic();
|
||||
}
|
||||
|
|
|
@ -2,11 +2,12 @@ import Component from "@ember/component";
|
|||
import { isEmpty } from "@ember/utils";
|
||||
import discourseComputed, { on } from "discourse-common/utils/decorators";
|
||||
import I18n from "I18n";
|
||||
import bootbox from "bootbox";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { action } from "@ember/object";
|
||||
|
||||
export default Component.extend({
|
||||
tagName: "",
|
||||
dialog: service(),
|
||||
|
||||
imapSettingsValid: false,
|
||||
smtpSettingsValid: false,
|
||||
|
@ -71,16 +72,11 @@ export default Component.extend({
|
|||
this.group.smtp_enabled &&
|
||||
this._anySmtpFieldsFilled()
|
||||
) {
|
||||
bootbox.confirm(
|
||||
I18n.t("groups.manage.email.smtp_disable_confirm"),
|
||||
(result) => {
|
||||
if (!result) {
|
||||
this.group.set("smtp_enabled", true);
|
||||
} else {
|
||||
this.group.set("imap_enabled", false);
|
||||
}
|
||||
}
|
||||
);
|
||||
this.dialog.confirm({
|
||||
message: I18n.t("groups.manage.email.smtp_disable_confirm"),
|
||||
didConfirm: () => this.group.set("smtp_enabled", true),
|
||||
didCancel: () => this.group.set("imap_enabled", false),
|
||||
});
|
||||
}
|
||||
|
||||
this.group.set("smtp_enabled", event.target.checked);
|
||||
|
@ -93,14 +89,10 @@ export default Component.extend({
|
|||
this.group.imap_enabled &&
|
||||
this._anyImapFieldsFilled()
|
||||
) {
|
||||
bootbox.confirm(
|
||||
I18n.t("groups.manage.email.imap_disable_confirm"),
|
||||
(result) => {
|
||||
if (!result) {
|
||||
this.group.set("imap_enabled", true);
|
||||
}
|
||||
}
|
||||
);
|
||||
this.dialog.confirm({
|
||||
message: I18n.t("groups.manage.email.imap_disable_confirm"),
|
||||
didConfirm: () => this.group.set("imap_enabled", true),
|
||||
});
|
||||
}
|
||||
|
||||
this.group.set("imap_enabled", event.target.checked);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import Component from "@ember/component";
|
||||
import bootbox from "bootbox";
|
||||
import { isBlank } from "@ember/utils";
|
||||
import {
|
||||
authorizedExtensions,
|
||||
|
@ -8,6 +7,7 @@ import {
|
|||
import { action } from "@ember/object";
|
||||
import discourseComputed, { bind } from "discourse-common/utils/decorators";
|
||||
import I18n from "I18n";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
// This picker is intended to be used with UppyUploadMixin or with
|
||||
// ComposerUploadUppy, which is why there are no change events registered
|
||||
|
@ -18,6 +18,7 @@ import I18n from "I18n";
|
|||
// is sometimes useful if you need to do something outside the uppy upload with
|
||||
// the file, such as directly using JSON or CSV data from a file in JS.
|
||||
export default Component.extend({
|
||||
dialog: service(),
|
||||
fileInputId: null,
|
||||
fileInputClass: null,
|
||||
fileInputDisabled: false,
|
||||
|
@ -87,7 +88,7 @@ export default Component.extend({
|
|||
const message = I18n.t("pick_files_button.unsupported_file_picked", {
|
||||
types: this.acceptedFileTypesString,
|
||||
});
|
||||
bootbox.alert(message);
|
||||
this.dialog.alert(message);
|
||||
return;
|
||||
}
|
||||
this.onFilesPicked(files);
|
||||
|
|
|
@ -9,6 +9,7 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
|
|||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Component.extend({
|
||||
dialog: service(),
|
||||
tagName: "",
|
||||
loading: false,
|
||||
tagInfo: null,
|
||||
|
@ -159,13 +160,13 @@ export default Component.extend({
|
|||
this.set("newSynonyms", null);
|
||||
this.loadTagInfo();
|
||||
} else if (response.failed_tags) {
|
||||
bootbox.alert(
|
||||
this.dialog.alert(
|
||||
I18n.t("tagging.add_synonyms_failed", {
|
||||
tag_names: Object.keys(response.failed_tags).join(", "),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
bootbox.alert(I18n.t("generic_error"));
|
||||
this.dialog.alert(I18n.t("generic_error"));
|
||||
}
|
||||
})
|
||||
.catch(popupAjaxError);
|
||||
|
|
|
@ -2,9 +2,9 @@ import Controller from "@ember/controller";
|
|||
import I18n from "I18n";
|
||||
import { action } from "@ember/object";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export function popupAutomaticMembershipAlert(group_id, email_domains) {
|
||||
if (!email_domains) {
|
||||
|
@ -25,7 +25,7 @@ export function popupAutomaticMembershipAlert(group_id, email_domains) {
|
|||
const count = result.user_count;
|
||||
|
||||
if (count > 0) {
|
||||
bootbox.alert(
|
||||
this.dialog.alert(
|
||||
I18n.t(
|
||||
"admin.groups.manage.membership.automatic_membership_user_count",
|
||||
{ count }
|
||||
|
@ -36,6 +36,7 @@ export function popupAutomaticMembershipAlert(group_id, email_domains) {
|
|||
}
|
||||
|
||||
export default Controller.extend({
|
||||
dialog: service(),
|
||||
saving: null,
|
||||
|
||||
@discourseComputed("model.ownerUsernames")
|
||||
|
|
|
@ -9,10 +9,10 @@ import Controller from "@ember/controller";
|
|||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import Post from "discourse/models/post";
|
||||
import bootbox from "bootbox";
|
||||
import { categoryBadgeHTML } from "discourse/helpers/category-link";
|
||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||
import { sanitizeAsync } from "discourse/lib/text";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
function customTagArray(val) {
|
||||
if (!val) {
|
||||
|
@ -26,6 +26,7 @@ function customTagArray(val) {
|
|||
|
||||
// This controller handles displaying of history
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
dialog: service(),
|
||||
loading: true,
|
||||
viewMode: "side_by_side",
|
||||
|
||||
|
@ -139,7 +140,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
e.jqXHR.responseJSON.errors &&
|
||||
e.jqXHR.responseJSON.errors[0]
|
||||
) {
|
||||
bootbox.alert(e.jqXHR.responseJSON.errors[0]);
|
||||
this.dialog.alert(e.jqXHR.responseJSON.errors[0]);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -8,7 +8,6 @@ import I18n from "I18n";
|
|||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { escape } from "pretty-text/sanitizer";
|
||||
import { extractError } from "discourse/lib/ajax-error";
|
||||
|
@ -19,6 +18,7 @@ import { isEmpty } from "@ember/utils";
|
|||
import { setting } from "discourse/lib/computed";
|
||||
import showModal from "discourse/lib/show-modal";
|
||||
import { wavingHandURL } from "discourse/lib/waving-hand-url";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
// This is happening outside of the app via popup
|
||||
const AuthErrors = [
|
||||
|
@ -33,6 +33,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
createAccount: controller(),
|
||||
forgotPassword: controller(),
|
||||
application: controller(),
|
||||
dialog: service(),
|
||||
|
||||
loggingIn: false,
|
||||
loggedIn: false,
|
||||
|
@ -199,7 +200,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
});
|
||||
} else if (result.reason === "suspended") {
|
||||
this.send("closeModal");
|
||||
bootbox.alert(result.error);
|
||||
this.dialog.alert(result.error);
|
||||
} else {
|
||||
this.flash(result.error, "error");
|
||||
}
|
||||
|
|
|
@ -10,12 +10,14 @@ import { readOnly } from "@ember/object/computed";
|
|||
import bootbox from "bootbox";
|
||||
import { endWith } from "discourse/lib/computed";
|
||||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default DiscoverySortableController.extend(
|
||||
BulkTopicSelection,
|
||||
FilterModeMixin,
|
||||
{
|
||||
application: controller(),
|
||||
dialog: service(),
|
||||
|
||||
tag: null,
|
||||
additionalTags: null,
|
||||
|
@ -172,7 +174,7 @@ export default DiscoverySortableController.extend(
|
|||
this.tag
|
||||
.destroyRecord()
|
||||
.then(() => this.transitionToRoute("tags.index"))
|
||||
.catch(() => bootbox.alert(I18n.t("generic_error")));
|
||||
.catch(() => this.dialog.alert(I18n.t("generic_error")));
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -7,10 +7,12 @@ import discourseComputed from "discourse-common/utils/decorators";
|
|||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import showModal from "discourse/lib/show-modal";
|
||||
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Controller.extend({
|
||||
dialog: service(),
|
||||
sortedByCount: true,
|
||||
sortedByName: false,
|
||||
|
||||
canAdminTags: alias("currentUser.staff"),
|
||||
groupedByCategory: notEmpty("model.extras.categories"),
|
||||
groupedByTagGroup: notEmpty("model.extras.tag_groups"),
|
||||
|
@ -67,7 +69,7 @@ export default Controller.extend({
|
|||
const tags = result["tags"];
|
||||
|
||||
if (tags.length === 0) {
|
||||
bootbox.alert(I18n.t("tagging.delete_no_unused_tags"));
|
||||
this.dialog.alert(I18n.t("tagging.delete_no_unused_tags"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import { Promise } from "rsvp";
|
|||
import Topic from "discourse/models/topic";
|
||||
import bootbox from "bootbox";
|
||||
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
const _buttons = [];
|
||||
|
||||
const alwaysTrue = () => true;
|
||||
|
@ -118,7 +120,7 @@ addBulkButton("deleteTopics", "delete", {
|
|||
// Modal for performing bulk actions on topics
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
userPrivateMessages: controller("user-private-messages"),
|
||||
|
||||
dialog: service(),
|
||||
tags: null,
|
||||
emptyTags: empty("tags"),
|
||||
categoryId: alias("model.category.id"),
|
||||
|
@ -151,7 +153,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
|
||||
return this._processChunks(operation)
|
||||
.catch(() => {
|
||||
bootbox.alert(I18n.t("generic_error"));
|
||||
this.dialog.alert(I18n.t("generic_error"));
|
||||
})
|
||||
.finally(() => {
|
||||
this.set("loading", false);
|
||||
|
|
|
@ -3,7 +3,6 @@ import ModalFunctionality from "discourse/mixins/modal-functionality";
|
|||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import bootbox from "bootbox";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import ItsATrap from "@discourse/itsatrap";
|
||||
import {
|
||||
|
@ -90,7 +89,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
|
||||
_handleError(e) {
|
||||
if (typeof e === "string") {
|
||||
bootbox.alert(e);
|
||||
this.dialog.alert(e);
|
||||
} else {
|
||||
popupAjaxError(e);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import I18n from "I18n";
|
||||
import bootbox from "bootbox";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
|
||||
export function extractError(error, defaultMessage) {
|
||||
if (error instanceof Error) {
|
||||
|
@ -64,5 +64,6 @@ export function throwAjaxError(undoCallback) {
|
|||
}
|
||||
|
||||
export function popupAjaxError(error) {
|
||||
bootbox.alert(extractError(error));
|
||||
const dialog = getOwner(this).lookup("service:dialog");
|
||||
dialog.alert(extractError(error));
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ import I18n from "I18n";
|
|||
import { Promise } from "rsvp";
|
||||
import User from "discourse/models/user";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import getURL, { samePrefix } from "discourse-common/lib/get-url";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
import discourseLater from "discourse-common/lib/later";
|
||||
import { selectedText } from "discourse/lib/utilities";
|
||||
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
||||
import deprecated from "discourse-common/lib/deprecated";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
|
||||
export function isValidLink(link) {
|
||||
// eslint-disable-next-line no-undef
|
||||
|
@ -121,7 +121,8 @@ export default {
|
|||
siteSettings?.prevent_anons_from_downloading_files &&
|
||||
!User.current()
|
||||
) {
|
||||
bootbox.alert(I18n.t("post.errors.attachment_download_requires_login"));
|
||||
const dialog = getOwner(this).lookup("service:dialog");
|
||||
dialog.alert(I18n.t("post.errors.attachment_download_requires_login"));
|
||||
} else if (wantsNewWindow(e)) {
|
||||
const newWindow = window.open(href, "_blank");
|
||||
newWindow.opener = null;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import I18n from "I18n";
|
||||
import bootbox from "bootbox";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
|
||||
export function outputExportResult(result) {
|
||||
const dialog = getOwner(this).lookup("service:dialog");
|
||||
|
||||
if (result.success) {
|
||||
bootbox.alert(I18n.t("admin.export_csv.success"));
|
||||
dialog.alert(I18n.t("admin.export_csv.success"));
|
||||
} else {
|
||||
bootbox.alert(I18n.t("admin.export_csv.failed"));
|
||||
dialog.alert(I18n.t("admin.export_csv.failed"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import I18n from "I18n";
|
||||
import deprecated from "discourse-common/lib/deprecated";
|
||||
import bootbox from "bootbox";
|
||||
import { isAppleDevice } from "discourse/lib/utilities";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
|
||||
function isGUID(value) {
|
||||
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
|
||||
|
@ -9,6 +9,14 @@ function isGUID(value) {
|
|||
);
|
||||
}
|
||||
|
||||
// This wrapper simplifies unit testing the dialog service
|
||||
export const dialog = {
|
||||
alert(msg) {
|
||||
const dg = getOwner(this).lookup("service:dialog");
|
||||
dg.alert(msg);
|
||||
},
|
||||
};
|
||||
|
||||
export function markdownNameFromFileName(fileName) {
|
||||
let name = fileName.slice(0, fileName.lastIndexOf("."));
|
||||
|
||||
|
@ -25,7 +33,7 @@ export function validateUploadedFiles(files, opts) {
|
|||
}
|
||||
|
||||
if (files.length > 1) {
|
||||
bootbox.alert(I18n.t("post.errors.too_many_uploads"));
|
||||
dialog.alert(I18n.t("post.errors.too_many_uploads"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -74,7 +82,7 @@ export function validateUploadedFile(file, opts) {
|
|||
|
||||
if (opts.imagesOnly) {
|
||||
if (!isImage(name) && !isAuthorizedImage(name, staff, opts.siteSettings)) {
|
||||
bootbox.alert(
|
||||
dialog.alert(
|
||||
I18n.t("post.errors.upload_not_authorized", {
|
||||
authorized_extensions: authorizedImagesExtensions(
|
||||
staff,
|
||||
|
@ -86,7 +94,7 @@ export function validateUploadedFile(file, opts) {
|
|||
}
|
||||
} else if (opts.csvOnly) {
|
||||
if (!/\.csv$/i.test(name)) {
|
||||
bootbox.alert(I18n.t("user.invited.bulk_invite.error"));
|
||||
dialog.alert(I18n.t("user.invited.bulk_invite.error"));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -94,7 +102,7 @@ export function validateUploadedFile(file, opts) {
|
|||
!authorizesAllExtensions(staff, opts.siteSettings) &&
|
||||
!isAuthorizedFile(name, staff, opts.siteSettings)
|
||||
) {
|
||||
bootbox.alert(
|
||||
dialog.alert(
|
||||
I18n.t("post.errors.upload_not_authorized", {
|
||||
authorized_extensions: authorizedExtensions(
|
||||
staff,
|
||||
|
@ -109,7 +117,7 @@ export function validateUploadedFile(file, opts) {
|
|||
if (!opts.bypassNewUserRestriction) {
|
||||
// ensures that new users can upload a file
|
||||
if (user && !user.isAllowedToUploadAFile(opts.type)) {
|
||||
bootbox.alert(
|
||||
dialog.alert(
|
||||
I18n.t(`post.errors.${opts.type}_upload_not_allowed_for_new_user`)
|
||||
);
|
||||
return false;
|
||||
|
@ -119,7 +127,7 @@ export function validateUploadedFile(file, opts) {
|
|||
if (file.size === 0) {
|
||||
/* eslint-disable no-console */
|
||||
console.warn("File with a 0 byte size detected, cancelling upload.", file);
|
||||
bootbox.alert(I18n.t("post.errors.file_size_zero"));
|
||||
dialog.alert(I18n.t("post.errors.file_size_zero"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -321,26 +329,26 @@ export function displayErrorForUpload(data, siteSettings, fileName) {
|
|||
return;
|
||||
}
|
||||
} else if (data.errors && data.errors.length > 0) {
|
||||
bootbox.alert(data.errors.join("\n"));
|
||||
dialog.alert(data.errors.join("\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, display a generic error message
|
||||
bootbox.alert(I18n.t("post.errors.upload"));
|
||||
dialog.alert(I18n.t("post.errors.upload"));
|
||||
}
|
||||
|
||||
function displayErrorByResponseStatus(status, body, fileName, siteSettings) {
|
||||
switch (status) {
|
||||
// didn't get headers from server, or browser refuses to tell us
|
||||
case 0:
|
||||
bootbox.alert(I18n.t("post.errors.upload"));
|
||||
dialog.alert(I18n.t("post.errors.upload"));
|
||||
return true;
|
||||
|
||||
// entity too large, usually returned from the web server
|
||||
case 413:
|
||||
const type = uploadTypeFromFileName(fileName);
|
||||
const max_size_kb = siteSettings[`max_${type}_size_kb`];
|
||||
bootbox.alert(
|
||||
dialog.alert(
|
||||
I18n.t("post.errors.file_too_large_humanized", {
|
||||
max_size: I18n.toHumanSize(max_size_kb * 1024),
|
||||
})
|
||||
|
@ -350,9 +358,9 @@ function displayErrorByResponseStatus(status, body, fileName, siteSettings) {
|
|||
// the error message is provided by the server
|
||||
case 422:
|
||||
if (body.message) {
|
||||
bootbox.alert(body.message);
|
||||
dialog.alert(body.message);
|
||||
} else {
|
||||
bootbox.alert(body.errors.join("\n"));
|
||||
dialog.alert(body.errors.join("\n"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
validateUploadedFile,
|
||||
} from "discourse/lib/uploads";
|
||||
import { cacheShortUploadUrl } from "pretty-text/upload-short-url";
|
||||
import bootbox from "bootbox";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { run } from "@ember/runloop";
|
||||
import escapeRegExp from "discourse-common/utils/escape-regexp";
|
||||
|
||||
|
@ -36,6 +36,7 @@ import escapeRegExp from "discourse-common/utils/escape-regexp";
|
|||
// functionality and event binding.
|
||||
//
|
||||
export default Mixin.create(ExtendableUploader, UppyS3Multipart, {
|
||||
dialog: service(),
|
||||
uploadRootPath: "/uploads",
|
||||
uploadTargetBound: false,
|
||||
useUploadPlaceholders: true,
|
||||
|
@ -186,7 +187,7 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, {
|
|||
// _not_ been handled by an upload handler.
|
||||
const fileCount = Object.keys(unhandledFiles).length;
|
||||
if (maxFiles > 0 && fileCount > maxFiles) {
|
||||
bootbox.alert(
|
||||
this.dialog.alert(
|
||||
I18n.t("post.errors.too_many_dragged_and_dropped_files", {
|
||||
count: maxFiles,
|
||||
})
|
||||
|
|
|
@ -21,11 +21,12 @@ import UppyS3Multipart from "discourse/mixins/uppy-s3-multipart";
|
|||
import UppyChunkedUploader from "discourse/lib/uppy-chunked-uploader-plugin";
|
||||
import { bind, on } from "discourse-common/utils/decorators";
|
||||
import { warn } from "@ember/debug";
|
||||
import bootbox from "bootbox";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export const HUGE_FILE_THRESHOLD_BYTES = 104_857_600; // 100MB
|
||||
|
||||
export default Mixin.create(UppyS3Multipart, ExtendableUploader, {
|
||||
dialog: service(),
|
||||
uploading: false,
|
||||
uploadProgress: 0,
|
||||
_uppyInstance: null,
|
||||
|
@ -130,7 +131,7 @@ export default Mixin.create(UppyS3Multipart, ExtendableUploader, {
|
|||
}
|
||||
|
||||
if (tooMany) {
|
||||
bootbox.alert(
|
||||
this.dialog.alert(
|
||||
I18n.t("post.errors.too_many_dragged_and_dropped_files", {
|
||||
count: this.allowMultipleFiles ? maxFiles : 1,
|
||||
})
|
||||
|
|
|
@ -5,7 +5,6 @@ import DiscourseRoute from "discourse/routes/discourse";
|
|||
import I18n from "I18n";
|
||||
import OpenComposer from "discourse/mixins/open-composer";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import { findAll } from "discourse/models/login-method";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
|
@ -18,7 +17,7 @@ import showModal from "discourse/lib/show-modal";
|
|||
function unlessReadOnly(method, message) {
|
||||
return function () {
|
||||
if (this.site.isReadOnly) {
|
||||
bootbox.alert(message);
|
||||
this.dialog.alert(message);
|
||||
} else {
|
||||
this[method]();
|
||||
}
|
||||
|
@ -28,7 +27,7 @@ function unlessReadOnly(method, message) {
|
|||
function unlessStrictlyReadOnly(method, message) {
|
||||
return function () {
|
||||
if (this.site.isReadOnly && !this.site.isStaffWritesOnly) {
|
||||
bootbox.alert(message);
|
||||
this.dialog.alert(message);
|
||||
} else {
|
||||
this[method]();
|
||||
}
|
||||
|
@ -39,6 +38,7 @@ const ApplicationRoute = DiscourseRoute.extend(OpenComposer, {
|
|||
siteTitle: setting("title"),
|
||||
shortSiteDescription: setting("short_site_description"),
|
||||
documentTitle: service(),
|
||||
dialog: service(),
|
||||
|
||||
actions: {
|
||||
toggleAnonymous() {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import Group from "discourse/models/group";
|
||||
import I18n from "I18n";
|
||||
import bootbox from "bootbox";
|
||||
import cookie from "discourse/lib/cookie";
|
||||
import { next } from "@ember/runloop";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default DiscourseRoute.extend({
|
||||
dialog: service(),
|
||||
|
||||
beforeModel(transition) {
|
||||
const params = transition.to.queryParams;
|
||||
|
||||
|
@ -32,12 +34,12 @@ export default DiscourseRoute.extend({
|
|||
})
|
||||
);
|
||||
} else {
|
||||
bootbox.alert(
|
||||
this.dialog.alert(
|
||||
I18n.t("composer.cant_send_pm", { username: groupName })
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => bootbox.alert(I18n.t("generic_error")));
|
||||
.catch(() => this.dialog.alert(I18n.t("generic_error")));
|
||||
} else {
|
||||
e.send("createNewMessageViaParams", {
|
||||
topicTitle: params.title,
|
||||
|
|
|
@ -11,7 +11,6 @@ import I18n from "I18n";
|
|||
import PostCooked from "discourse/widgets/post-cooked";
|
||||
import { Promise } from "rsvp";
|
||||
import RawHtml from "discourse/widgets/raw-html";
|
||||
import bootbox from "bootbox";
|
||||
import { dateNode } from "discourse/helpers/node";
|
||||
import { h } from "virtual-dom";
|
||||
import hbs from "discourse/widgets/hbs-compiler";
|
||||
|
@ -814,6 +813,7 @@ export function addPostClassesCallback(callback) {
|
|||
|
||||
export default createWidget("post", {
|
||||
buildKey: (attrs) => `post-${attrs.id}`,
|
||||
services: ["dialog"],
|
||||
shadowTree: true,
|
||||
|
||||
buildAttributes(attrs) {
|
||||
|
@ -918,7 +918,7 @@ export default createWidget("post", {
|
|||
const { remaining, max } = result;
|
||||
const threshold = Math.ceil(max * 0.1);
|
||||
if (remaining === threshold) {
|
||||
bootbox.alert(I18n.t("post.few_likes_left"));
|
||||
this.dialog.alert(I18n.t("post.few_likes_left"));
|
||||
kvs.set({ key: "lastWarnedLikes", value: Date.now() });
|
||||
}
|
||||
},
|
||||
|
|
|
@ -44,7 +44,7 @@ acceptance("Category Banners", function (needs) {
|
|||
await visit("/c/test-read-only-without-banner");
|
||||
|
||||
await click("#create-topic");
|
||||
assert.ok(!visible(".bootbox.modal"), "it does not pop up a modal");
|
||||
assert.ok(!visible(".dialog-body"), "it does not pop up a modal");
|
||||
assert.ok(
|
||||
!visible(".category-read-only-banner"),
|
||||
"it does not show a banner"
|
||||
|
@ -55,10 +55,10 @@ acceptance("Category Banners", function (needs) {
|
|||
await visit("/c/test-read-only-with-banner");
|
||||
|
||||
await click("#create-topic");
|
||||
assert.ok(visible(".bootbox.modal"), "it pops up a modal");
|
||||
assert.ok(visible(".dialog-body"), "it pops up a modal");
|
||||
|
||||
await click(".modal-footer>.btn-primary");
|
||||
assert.ok(!visible(".bootbox.modal"), "it closes the modal");
|
||||
await click(".dialog-footer .btn-primary");
|
||||
assert.ok(!visible(".dialog-body"), "it closes the modal");
|
||||
assert.ok(visible(".category-read-only-banner"), "it shows a banner");
|
||||
assert.strictEqual(
|
||||
count(".category-read-only-banner .inner"),
|
||||
|
|
|
@ -6,8 +6,7 @@ import {
|
|||
query,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import bootbox from "bootbox";
|
||||
import { authorizedExtensions } from "discourse/lib/uploads";
|
||||
import { authorizedExtensions, dialog } from "discourse/lib/uploads";
|
||||
import { click, fillIn, settled, visit } from "@ember/test-helpers";
|
||||
import I18n from "I18n";
|
||||
import { skip, test } from "qunit";
|
||||
|
@ -125,15 +124,16 @@ acceptance("Uppy Composer Attachment - Upload Placeholder", function (needs) {
|
|||
const image2 = createFile("avatar2.png");
|
||||
const done = assert.async();
|
||||
appEvents.on("composer:uploads-aborted", async () => {
|
||||
await settled();
|
||||
assert.strictEqual(
|
||||
query(".bootbox .modal-body").innerHTML,
|
||||
query(".dialog-body").textContent.trim(),
|
||||
I18n.t("post.errors.too_many_dragged_and_dropped_files", {
|
||||
count: 2,
|
||||
}),
|
||||
"it should warn about too many files added"
|
||||
);
|
||||
|
||||
await click(".modal-footer .btn-primary");
|
||||
await click(".dialog-footer .btn-primary");
|
||||
|
||||
done();
|
||||
});
|
||||
|
@ -149,8 +149,9 @@ acceptance("Uppy Composer Attachment - Upload Placeholder", function (needs) {
|
|||
const done = assert.async();
|
||||
|
||||
appEvents.on("composer:uploads-aborted", async () => {
|
||||
await settled();
|
||||
assert.strictEqual(
|
||||
query(".bootbox .modal-body").innerHTML,
|
||||
query(".dialog-body").textContent.trim(),
|
||||
I18n.t("post.errors.upload_not_authorized", {
|
||||
authorized_extensions: authorizedExtensions(
|
||||
false,
|
||||
|
@ -160,7 +161,7 @@ acceptance("Uppy Composer Attachment - Upload Placeholder", function (needs) {
|
|||
"it should warn about unauthorized extensions"
|
||||
);
|
||||
|
||||
await click(".modal-footer .btn-primary");
|
||||
await click(".dialog-footer .btn-primary");
|
||||
|
||||
done();
|
||||
});
|
||||
|
@ -438,14 +439,14 @@ acceptance("Uppy Composer Attachment - Upload Error", function (needs) {
|
|||
|
||||
appEvents.on("composer:upload-error", async () => {
|
||||
sinon.assert.calledOnce(stub);
|
||||
await settled();
|
||||
assert.strictEqual(
|
||||
query(".bootbox .modal-body").innerHTML,
|
||||
query(".dialog-body").textContent.trim(),
|
||||
"There was an error uploading the file, the gif was way too cool.",
|
||||
"it should show the error message from the server"
|
||||
);
|
||||
|
||||
await click(".modal-footer .btn-primary");
|
||||
|
||||
await click(".dialog-footer .btn-primary");
|
||||
done();
|
||||
});
|
||||
|
||||
|
@ -465,7 +466,7 @@ acceptance("Uppy Composer Attachment - Upload Handler", function (needs) {
|
|||
api.addComposerUploadHandler(["png"], (files) => {
|
||||
const file = files[0];
|
||||
const isNativeFile = file instanceof File ? "WAS" : "WAS NOT";
|
||||
bootbox.alert(
|
||||
dialog.alert(
|
||||
`This is an upload handler test for ${file.name}. The file ${isNativeFile} a native file object.`
|
||||
);
|
||||
});
|
||||
|
@ -480,12 +481,13 @@ acceptance("Uppy Composer Attachment - Upload Handler", function (needs) {
|
|||
const done = assert.async();
|
||||
|
||||
appEvents.on("composer:uploads-aborted", async () => {
|
||||
await settled();
|
||||
assert.strictEqual(
|
||||
query(".bootbox .modal-body").innerHTML,
|
||||
query(".dialog-body").textContent.trim(),
|
||||
"This is an upload handler test for handler-test.png. The file WAS a native file object.",
|
||||
"it should show the bootbox triggered by the upload handler"
|
||||
"it should show the dialog triggered by the upload handler"
|
||||
);
|
||||
await click(".modal-footer .btn");
|
||||
await click(".dialog-footer .btn-primary");
|
||||
done();
|
||||
});
|
||||
|
||||
|
|
|
@ -126,12 +126,12 @@ acceptance(
|
|||
|
||||
await click("#enable_smtp");
|
||||
assert.strictEqual(
|
||||
query(".modal-body").innerText,
|
||||
query(".dialog-body").innerText.trim(),
|
||||
I18n.t("groups.manage.email.smtp_disable_confirm"),
|
||||
"shows a confirm dialogue warning SMTP settings will be wiped"
|
||||
);
|
||||
|
||||
await click(".modal-footer .btn.btn-primary");
|
||||
await click(".dialog-footer .btn-primary");
|
||||
});
|
||||
|
||||
test("enabling IMAP, testing, and saving", async function (assert) {
|
||||
|
@ -202,11 +202,11 @@ acceptance(
|
|||
|
||||
await click("#enable_imap");
|
||||
assert.strictEqual(
|
||||
query(".modal-body").innerText,
|
||||
query(".dialog-body").innerText.trim(),
|
||||
I18n.t("groups.manage.email.imap_disable_confirm"),
|
||||
"shows a confirm dialogue warning IMAP settings will be wiped"
|
||||
);
|
||||
await click(".modal-footer .btn.btn-primary");
|
||||
await click(".dialog-footer .btn-primary");
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -362,11 +362,11 @@ acceptance(
|
|||
await click(".test-smtp-settings");
|
||||
|
||||
assert.strictEqual(
|
||||
query(".modal-body").innerText,
|
||||
query(".dialog-body").innerText.trim(),
|
||||
"There was an issue with the SMTP credentials provided, check the username and password and try again.",
|
||||
"shows a dialogue with the error message from the server"
|
||||
);
|
||||
await click(".modal-footer .btn.btn-primary");
|
||||
await click(".dialog-footer .btn-primary");
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -84,9 +84,9 @@ acceptance("User Preferences - Sidebar", function (needs) {
|
|||
"contains the right request body to update user's sidebar category links"
|
||||
);
|
||||
|
||||
assert.ok(exists(".modal-body"), "error message is displayed");
|
||||
assert.ok(exists(".dialog-body"), "error message is displayed");
|
||||
|
||||
await click(".modal .d-button-label");
|
||||
await click(".dialog-footer .btn-primary");
|
||||
|
||||
assert.ok(
|
||||
!exists(".sidebar-section-categories .sidebar-section-link-howto"),
|
||||
|
@ -152,9 +152,9 @@ acceptance("User Preferences - Sidebar", function (needs) {
|
|||
"contains the right request body to update user's sidebar tag links"
|
||||
);
|
||||
|
||||
assert.ok(exists(".modal-body"), "error message is displayed");
|
||||
assert.ok(exists(".dialog-body"), "error message is displayed");
|
||||
|
||||
await click(".modal .d-button-label");
|
||||
await click(".dialog-footer .btn-primary");
|
||||
|
||||
assert.ok(
|
||||
!exists(".sidebar-section-tags .sidebar-section-link-gazelle"),
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import { module, test } from "qunit";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
import { click, render, waitFor } from "@ember/test-helpers";
|
||||
import { render } from "@ember/test-helpers";
|
||||
import { createFile } from "discourse/tests/helpers/qunit-helpers";
|
||||
import { hbs } from "ember-cli-htmlbars";
|
||||
import pretender, { response } from "discourse/tests/helpers/create-pretender";
|
||||
import sinon from "sinon";
|
||||
import I18n from "I18n";
|
||||
import { dialog } from "discourse/lib/uploads";
|
||||
|
||||
module("Integration | Component | watched-word-uploader", function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
@ -15,6 +18,8 @@ module("Integration | Component | watched-word-uploader", function (hooks) {
|
|||
});
|
||||
|
||||
test("sets the proper action key on uploads", async function (assert) {
|
||||
sinon.stub(dialog, "alert");
|
||||
|
||||
const done = assert.async();
|
||||
this.set("actionNameKey", "flag");
|
||||
this.set("doneUpload", function () {
|
||||
|
@ -23,6 +28,12 @@ module("Integration | Component | watched-word-uploader", function (hooks) {
|
|||
.action_key,
|
||||
"flag"
|
||||
);
|
||||
assert.ok(
|
||||
dialog.alert.calledWith(
|
||||
I18n.t("admin.watched_words.form.upload_successful")
|
||||
),
|
||||
"alert shown"
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
|
@ -38,8 +49,5 @@ module("Integration | Component | watched-word-uploader", function (hooks) {
|
|||
await this.container
|
||||
.lookup("service:app-events")
|
||||
.trigger("upload-mixin:watched-word-uploader:add-files", words);
|
||||
await waitFor(".bootbox span.d-button-label");
|
||||
|
||||
await click(".bootbox span.d-button-label");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
allowsAttachments,
|
||||
allowsImages,
|
||||
authorizedExtensions,
|
||||
dialog,
|
||||
displayErrorForUpload,
|
||||
getUploadMarkdown,
|
||||
isImage,
|
||||
|
@ -10,7 +11,6 @@ import {
|
|||
} from "discourse/lib/uploads";
|
||||
import I18n from "I18n";
|
||||
import User from "discourse/models/user";
|
||||
import bootbox from "bootbox";
|
||||
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
|
||||
import sinon from "sinon";
|
||||
import { test } from "qunit";
|
||||
|
@ -32,17 +32,17 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
});
|
||||
|
||||
test("uploading one file", function (assert) {
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
|
||||
assert.notOk(
|
||||
validateUploadedFiles([1, 2], { siteSettings: this.siteSettings })
|
||||
);
|
||||
assert.ok(bootbox.alert.calledWith(I18n.t("post.errors.too_many_uploads")));
|
||||
assert.ok(dialog.alert.calledWith(I18n.t("post.errors.too_many_uploads")));
|
||||
});
|
||||
|
||||
test("new user cannot upload images", function (assert) {
|
||||
this.siteSettings.newuser_max_embedded_media = 0;
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
|
||||
assert.notOk(
|
||||
validateUploadedFiles([{ name: "image.png" }], {
|
||||
|
@ -52,7 +52,7 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
"the upload is not valid"
|
||||
);
|
||||
assert.ok(
|
||||
bootbox.alert.calledWith(
|
||||
dialog.alert.calledWith(
|
||||
I18n.t("post.errors.image_upload_not_allowed_for_new_user")
|
||||
),
|
||||
"the alert is called"
|
||||
|
@ -62,7 +62,7 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
test("new user can upload images if allowed", function (assert) {
|
||||
this.siteSettings.newuser_max_embedded_media = 1;
|
||||
this.siteSettings.default_trust_level = 0;
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
|
||||
assert.ok(
|
||||
validateUploadedFiles([{ name: "image.png" }], {
|
||||
|
@ -74,7 +74,7 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
|
||||
test("TL1 can upload images", function (assert) {
|
||||
this.siteSettings.newuser_max_embedded_media = 0;
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
|
||||
assert.ok(
|
||||
validateUploadedFiles([{ name: "image.png" }], {
|
||||
|
@ -86,7 +86,7 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
|
||||
test("new user cannot upload attachments", function (assert) {
|
||||
this.siteSettings.newuser_max_attachments = 0;
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
|
||||
assert.notOk(
|
||||
validateUploadedFiles([{ name: "roman.txt" }], {
|
||||
|
@ -95,21 +95,21 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
})
|
||||
);
|
||||
assert.ok(
|
||||
bootbox.alert.calledWith(
|
||||
dialog.alert.calledWith(
|
||||
I18n.t("post.errors.attachment_upload_not_allowed_for_new_user")
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
test("ensures an authorized upload", function (assert) {
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
assert.notOk(
|
||||
validateUploadedFiles([{ name: "unauthorized.html" }], {
|
||||
siteSettings: this.siteSettings,
|
||||
})
|
||||
);
|
||||
assert.ok(
|
||||
bootbox.alert.calledWith(
|
||||
dialog.alert.calledWith(
|
||||
I18n.t("post.errors.upload_not_authorized", {
|
||||
authorized_extensions: authorizedExtensions(
|
||||
false,
|
||||
|
@ -122,7 +122,7 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
|
||||
test("skipping validation works", function (assert) {
|
||||
const files = [{ name: "backup.tar.gz" }];
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
|
||||
assert.notOk(
|
||||
validateUploadedFiles(files, {
|
||||
|
@ -141,7 +141,7 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
test("staff can upload anything in PM", function (assert) {
|
||||
const files = [{ name: "some.docx" }];
|
||||
this.siteSettings.authorized_extensions = "jpeg";
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
|
||||
let user = User.create({ moderator: true });
|
||||
assert.notOk(
|
||||
|
@ -175,7 +175,7 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
};
|
||||
|
||||
test("allows valid uploads to go through", function (assert) {
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
|
||||
let user = User.create({ trust_level: 1 });
|
||||
|
||||
|
@ -193,7 +193,7 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
})
|
||||
);
|
||||
|
||||
assert.notOk(bootbox.alert.calledOnce);
|
||||
assert.notOk(dialog.alert.calledOnce);
|
||||
});
|
||||
|
||||
test("isImage", function (assert) {
|
||||
|
@ -315,7 +315,7 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
});
|
||||
|
||||
test("displayErrorForUpload - jquery file upload - jqXHR present", function (assert) {
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
displayErrorForUpload(
|
||||
{
|
||||
jqXHR: { status: 422, responseJSON: { message: "upload failed" } },
|
||||
|
@ -323,11 +323,11 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
{ max_attachment_size_kb: 1024, max_image_size_kb: 1024 },
|
||||
"test.png"
|
||||
);
|
||||
assert.ok(bootbox.alert.calledWith("upload failed"), "the alert is called");
|
||||
assert.ok(dialog.alert.calledWith("upload failed"), "the alert is called");
|
||||
});
|
||||
|
||||
test("displayErrorForUpload - jquery file upload - jqXHR missing, errors present", function (assert) {
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
displayErrorForUpload(
|
||||
{
|
||||
errors: ["upload failed"],
|
||||
|
@ -335,11 +335,11 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
{ max_attachment_size_kb: 1024, max_image_size_kb: 1024 },
|
||||
"test.png"
|
||||
);
|
||||
assert.ok(bootbox.alert.calledWith("upload failed"), "the alert is called");
|
||||
assert.ok(dialog.alert.calledWith("upload failed"), "the alert is called");
|
||||
});
|
||||
|
||||
test("displayErrorForUpload - jquery file upload - no errors", function (assert) {
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
displayErrorForUpload(
|
||||
{},
|
||||
{
|
||||
|
@ -349,13 +349,13 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
"test.png"
|
||||
);
|
||||
assert.ok(
|
||||
bootbox.alert.calledWith(I18n.t("post.errors.upload")),
|
||||
dialog.alert.calledWith(I18n.t("post.errors.upload")),
|
||||
"the alert is called"
|
||||
);
|
||||
});
|
||||
|
||||
test("displayErrorForUpload - uppy - with response status and body", function (assert) {
|
||||
sinon.stub(bootbox, "alert");
|
||||
sinon.stub(dialog, "alert");
|
||||
displayErrorForUpload(
|
||||
{
|
||||
status: 422,
|
||||
|
@ -364,6 +364,6 @@ discourseModule("Unit | Utility | uploads", function () {
|
|||
"test.png",
|
||||
{ max_attachment_size_kb: 1024, max_image_size_kb: 1024 }
|
||||
);
|
||||
assert.ok(bootbox.alert.calledWith("upload failed"), "the alert is called");
|
||||
assert.ok(dialog.alert.calledWith("upload failed"), "the alert is called");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,9 +8,11 @@ import getUrl from "discourse-common/lib/get-url";
|
|||
import Uppy from "@uppy/core";
|
||||
import DropTarget from "@uppy/drop-target";
|
||||
import XHRUpload from "@uppy/xhr-upload";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Component.extend({
|
||||
classNames: ["wizard-container__image-upload"],
|
||||
dialog: service(),
|
||||
uploading: false,
|
||||
|
||||
@discourseComputed("field.id")
|
||||
|
@ -57,7 +59,7 @@ export default Component.extend({
|
|||
message = response.body.errors.join("\n");
|
||||
}
|
||||
|
||||
window.bootbox.alert(message);
|
||||
this.dialog.alert(message);
|
||||
this.set("uploading", false);
|
||||
});
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
}
|
||||
|
||||
.dialog-container {
|
||||
z-index: z("modal", "overlay");
|
||||
z-index: z("modal", "dialog");
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ $line-height-large: var(--line-height-large) !default;
|
|||
$z-layers: (
|
||||
"max": 9999,
|
||||
"modal": (
|
||||
"dialog": 1700,
|
||||
"tooltip": 1600,
|
||||
"popover": 1500,
|
||||
"dropdown": 1400,
|
||||
|
|
|
@ -8,9 +8,10 @@ import discourseComputed from "discourse-common/utils/decorators";
|
|||
import { htmlSafe } from "@ember/template";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import bootbox from "bootbox";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
dialog: service(),
|
||||
model: null,
|
||||
charts: null,
|
||||
groupedBy: null,
|
||||
|
@ -64,7 +65,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
if (error) {
|
||||
popupAjaxError(error);
|
||||
} else {
|
||||
bootbox.alert(I18n.t("poll.error_while_fetching_voters"));
|
||||
this.dialog.alert(I18n.t("poll.error_while_fetching_voters"));
|
||||
}
|
||||
})
|
||||
.then((result) => {
|
||||
|
|
Loading…
Reference in New Issue