mirror of
https://github.com/discourse/discourse.git
synced 2024-12-02 11:03:48 +08:00
b8ee52c4cb
Previously, focus wasn't being applied correctly on dialogs using named components. This was because the A11YDialog was being invoked before the component was completely rendered. The long-term plan is to move away from A11YDialog doing the rendering here, but for now this should do.
198 lines
3.9 KiB
JavaScript
198 lines
3.9 KiB
JavaScript
import { schedule } from "@ember/runloop";
|
|
import Service from "@ember/service";
|
|
import A11yDialog from "a11y-dialog";
|
|
import { bind } from "discourse-common/utils/decorators";
|
|
|
|
export default class DialogService extends Service {
|
|
dialogInstance = null;
|
|
message = null;
|
|
title = null;
|
|
titleElementId = null;
|
|
type = null;
|
|
|
|
bodyComponent = null;
|
|
bodyComponentModel = null;
|
|
|
|
confirmButtonIcon = null;
|
|
confirmButtonLabel = null;
|
|
confirmButtonClass = null;
|
|
confirmButtonDisabled = false;
|
|
cancelButtonLabel = null;
|
|
cancelButtonClass = null;
|
|
shouldDisplayCancel = null;
|
|
|
|
didConfirm = null;
|
|
didCancel = null;
|
|
buttons = null;
|
|
class = null;
|
|
_confirming = false;
|
|
|
|
async dialog(params) {
|
|
const {
|
|
message,
|
|
bodyComponent,
|
|
bodyComponentModel,
|
|
type,
|
|
title,
|
|
|
|
confirmButtonClass = "btn-primary",
|
|
confirmButtonIcon,
|
|
confirmButtonLabel = "ok_value",
|
|
confirmButtonDisabled = false,
|
|
|
|
cancelButtonClass = "btn-default",
|
|
cancelButtonLabel = "cancel_value",
|
|
shouldDisplayCancel,
|
|
|
|
didConfirm,
|
|
didCancel,
|
|
buttons,
|
|
} = params;
|
|
|
|
this.setProperties({
|
|
message,
|
|
bodyComponent,
|
|
bodyComponentModel,
|
|
type,
|
|
|
|
title,
|
|
titleElementId: title !== null ? "dialog-title" : null,
|
|
|
|
confirmButtonClass,
|
|
confirmButtonDisabled,
|
|
confirmButtonIcon,
|
|
confirmButtonLabel,
|
|
|
|
cancelButtonClass,
|
|
cancelButtonLabel,
|
|
shouldDisplayCancel,
|
|
|
|
didConfirm,
|
|
didCancel,
|
|
buttons,
|
|
class: params.class,
|
|
});
|
|
|
|
await new Promise((resolve) => schedule("afterRender", resolve));
|
|
const element = document.getElementById("dialog-holder");
|
|
|
|
if (!element) {
|
|
const msg =
|
|
"dialog-holder wrapper element not found. Unable to render dialog";
|
|
// eslint-disable-next-line no-console
|
|
console.error(msg, params);
|
|
throw new Error(msg);
|
|
}
|
|
|
|
this.dialogInstance = new A11yDialog(element);
|
|
this.dialogInstance.show();
|
|
|
|
this.dialogInstance.on("hide", () => {
|
|
if (!this._confirming && this.didCancel) {
|
|
this.didCancel();
|
|
}
|
|
|
|
this.reset();
|
|
});
|
|
}
|
|
|
|
alert(params) {
|
|
// support string param for easier porting of bootbox.alert
|
|
if (typeof params === "string") {
|
|
return this.dialog({
|
|
message: params,
|
|
type: "alert",
|
|
});
|
|
}
|
|
|
|
return this.dialog({
|
|
...params,
|
|
type: "alert",
|
|
});
|
|
}
|
|
|
|
confirm(params) {
|
|
return this.dialog({
|
|
...params,
|
|
shouldDisplayCancel: true,
|
|
buttons: null,
|
|
type: "confirm",
|
|
});
|
|
}
|
|
|
|
notice(message) {
|
|
return this.dialog({
|
|
message,
|
|
type: "notice",
|
|
});
|
|
}
|
|
|
|
yesNoConfirm(params) {
|
|
return this.confirm({
|
|
...params,
|
|
confirmButtonLabel: "yes_value",
|
|
cancelButtonLabel: "no_value",
|
|
});
|
|
}
|
|
|
|
deleteConfirm(params) {
|
|
return this.confirm({
|
|
...params,
|
|
confirmButtonClass: "btn-danger",
|
|
confirmButtonLabel: params.confirmButtonLabel || "delete",
|
|
});
|
|
}
|
|
|
|
reset() {
|
|
this.setProperties({
|
|
message: null,
|
|
bodyComponent: null,
|
|
bodyComponentModel: null,
|
|
type: null,
|
|
dialogInstance: null,
|
|
|
|
title: null,
|
|
titleElementId: null,
|
|
|
|
confirmButtonDisabled: false,
|
|
confirmButtonIcon: null,
|
|
confirmButtonLabel: null,
|
|
|
|
cancelButtonClass: null,
|
|
cancelButtonLabel: null,
|
|
shouldDisplayCancel: null,
|
|
|
|
didConfirm: null,
|
|
didCancel: null,
|
|
buttons: null,
|
|
class: null,
|
|
|
|
_confirming: false,
|
|
});
|
|
}
|
|
|
|
willDestroy() {
|
|
this.dialogInstance?.destroy();
|
|
this.reset();
|
|
}
|
|
|
|
@bind
|
|
didConfirmWrapped() {
|
|
if (this.didConfirm) {
|
|
this.didConfirm();
|
|
}
|
|
this._confirming = true;
|
|
this.dialogInstance.hide();
|
|
}
|
|
|
|
@bind
|
|
cancel() {
|
|
this.dialogInstance.hide();
|
|
}
|
|
|
|
@bind
|
|
enableConfirmButton() {
|
|
this.set("confirmButtonDisabled", false);
|
|
}
|
|
}
|