96 lines
3.6 KiB
JavaScript
96 lines
3.6 KiB
JavaScript
(function (window, document) {
|
|
"use strict";
|
|
|
|
const DEFAULT_DURATION = 7000;
|
|
const VALID_TYPES = new Set(["success", "info", "warning", "danger"]);
|
|
|
|
function getHost() {
|
|
let host = document.getElementById("cygnus-notifications");
|
|
if (!host) {
|
|
host = document.createElement("div");
|
|
host.id = "cygnus-notifications";
|
|
host.className = "position-fixed top-0 start-50 translate-middle-x p-3";
|
|
host.style.cssText = "z-index:1085;max-width:720px;width:calc(100% - 2rem)";
|
|
host.setAttribute("aria-live", "polite");
|
|
host.setAttribute("aria-atomic", "true");
|
|
document.body.append(host);
|
|
}
|
|
return host;
|
|
}
|
|
|
|
function dismiss(alert) {
|
|
const bootstrapAlert = window.bootstrap?.Alert;
|
|
if (bootstrapAlert) {
|
|
bootstrapAlert.getOrCreateInstance(alert).close();
|
|
} else {
|
|
alert.remove();
|
|
}
|
|
}
|
|
|
|
function show(options) {
|
|
const settings = options || {};
|
|
const type = VALID_TYPES.has(settings.type) ? settings.type : "info";
|
|
const host = getHost();
|
|
const alert = document.createElement("div");
|
|
alert.className = `alert alert-${type} alert-dismissible fade show shadow-sm`;
|
|
alert.setAttribute("role", type === "danger" ? "alert" : "status");
|
|
|
|
if (settings.code) {
|
|
const code = document.createElement("strong");
|
|
code.textContent = `${settings.code}: `;
|
|
alert.append(code);
|
|
}
|
|
alert.append(document.createTextNode(settings.message || ""));
|
|
|
|
if (settings.referenceId) {
|
|
const reference = document.createElement("small");
|
|
reference.className = "d-block mt-1";
|
|
reference.textContent = `Reference: ${settings.referenceId}`;
|
|
alert.append(reference);
|
|
}
|
|
|
|
if (settings.dismissible !== false) {
|
|
const close = document.createElement("button");
|
|
close.type = "button";
|
|
close.className = "btn-close";
|
|
close.setAttribute("aria-label", "Close");
|
|
close.addEventListener("click", () => dismiss(alert));
|
|
alert.append(close);
|
|
}
|
|
|
|
if (settings.stack === true) host.append(alert);
|
|
else host.replaceChildren(alert);
|
|
|
|
const duration = settings.duration === undefined ? DEFAULT_DURATION : settings.duration;
|
|
if (Number.isFinite(duration) && duration > 0) {
|
|
window.setTimeout(() => {
|
|
if (alert.isConnected) dismiss(alert);
|
|
}, duration);
|
|
}
|
|
return alert;
|
|
}
|
|
|
|
function clear() {
|
|
document.getElementById("cygnus-notifications")?.replaceChildren();
|
|
}
|
|
|
|
function showLegacy(serialized, options) {
|
|
const text = String(serialized || "");
|
|
const firstSeparator = text.indexOf(":");
|
|
const secondSeparator = firstSeparator < 0 ? -1 : text.indexOf(":", firstSeparator + 1);
|
|
const settings = Object.assign({}, options);
|
|
if (secondSeparator > firstSeparator) {
|
|
settings.code = text.slice(0, firstSeparator);
|
|
const legacyType = text.slice(firstSeparator + 1, secondSeparator).toLowerCase();
|
|
settings.type = legacyType === "error" ? "danger" : legacyType;
|
|
settings.message = text.slice(secondSeparator + 1);
|
|
} else {
|
|
settings.type = settings.type || "danger";
|
|
settings.message = text;
|
|
}
|
|
return show(settings);
|
|
}
|
|
|
|
window.CygnusNotifications = Object.freeze({ show, showLegacy, clear });
|
|
}(window, document));
|