74 lines
3.1 KiB
JavaScript
74 lines
3.1 KiB
JavaScript
(() => {
|
|
"use strict";
|
|
|
|
const activeDialogs = [];
|
|
|
|
const ensureDialog = () => {
|
|
const element = document.createElement("div");
|
|
element.id = `matrixFrameDialog${activeDialogs.length + 1}`;
|
|
element.className = "modal fade matrix-frame-dialog";
|
|
element.tabIndex = -1;
|
|
element.setAttribute("aria-hidden", "true");
|
|
element.innerHTML = `
|
|
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h2 class="modal-title fs-6">Report</h2>
|
|
<button type="button" class="btn-close matrix-frame-dialog__close" data-bs-dismiss="modal" aria-label="Close report"></button>
|
|
</div>
|
|
<div class="modal-body p-0">
|
|
<div class="matrix-frame-dialog__loading" role="status">Loading report…</div>
|
|
<iframe title="Report editor" class="matrix-frame-dialog__frame"></iframe>
|
|
</div>
|
|
</div>
|
|
</div>`;
|
|
document.body.appendChild(element);
|
|
return element;
|
|
};
|
|
|
|
const finish = (current, result) => {
|
|
if (!current) return;
|
|
const index = activeDialogs.indexOf(current);
|
|
if (index >= 0) activeDialogs.splice(index, 1);
|
|
current.frame.removeAttribute("src");
|
|
current.element.remove();
|
|
current.resolve(result ?? 0);
|
|
};
|
|
|
|
window.addEventListener("message", (event) => {
|
|
const activeDialog = activeDialogs.find((dialog) => event.source === dialog.frame.contentWindow);
|
|
if (event.origin !== window.location.origin || !activeDialog) return;
|
|
if (event.data?.type === "matrix-dialog-close") {
|
|
activeDialog.result = event.data.result;
|
|
activeDialog.modal.hide();
|
|
}
|
|
});
|
|
|
|
window.MatrixFrameDialog = {
|
|
open(url, title = "Report", options = {}) {
|
|
const element = ensureDialog();
|
|
const frame = element.querySelector("iframe");
|
|
const loading = element.querySelector(".matrix-frame-dialog__loading");
|
|
element.style.setProperty("--matrix-dialog-width", options.width || "1180px");
|
|
element.style.setProperty("--matrix-dialog-height", options.height || "min(880px, calc(100vh - 24px))");
|
|
element.querySelector(".modal-title").textContent = title;
|
|
loading.hidden = false;
|
|
frame.hidden = true;
|
|
|
|
const modal = bootstrap.Modal.getOrCreateInstance(element, {backdrop: "static", keyboard: true});
|
|
frame.onload = () => {
|
|
loading.hidden = true;
|
|
frame.hidden = false;
|
|
};
|
|
|
|
return new Promise((resolve) => {
|
|
const activeDialog = {element, modal, frame, resolve, result: 0};
|
|
activeDialogs.push(activeDialog);
|
|
element.addEventListener("hidden.bs.modal", () => finish(activeDialog, activeDialog.result), {once: true});
|
|
frame.src = url;
|
|
modal.show();
|
|
});
|
|
}
|
|
};
|
|
})();
|