92 lines
3.7 KiB
JavaScript
92 lines
3.7 KiB
JavaScript
// Modais de confirmação/aviso genéricos, no padrão visual do Portal —
|
|
// substituem window.confirm()/window.alert() nativos do navegador (pedido
|
|
// explícito do usuário: nenhum popup deve usar o diálogo nativo do browser,
|
|
// sempre um modal dentro do próprio Portal).
|
|
//
|
|
// `pidConfirm(mensagem, opcoes)` devolve uma Promise<boolean> (true se
|
|
// confirmado, false se cancelado ou fechado clicando fora) — chame com
|
|
// `await` no lugar de `window.confirm(...)`.
|
|
//
|
|
// `pidAlert(mensagem, opcoes)` devolve uma Promise<void>, resolvida quando o
|
|
// usuário fecha o aviso (um único botão, sem "Cancelar") — chame com
|
|
// `await` no lugar de `window.alert(...)`.
|
|
//
|
|
// `opcoes` (todas opcionais): { titulo, textoConfirmar, textoCancelar,
|
|
// perigoso } — `perigoso: true` troca o botão de ação pra
|
|
// `.btn-danger-outline` (mesmo estilo já usado em ações destrutivas como
|
|
// "Excluir selecionadas"), em vez do `.btn-solid` padrão. Em `pidAlert`,
|
|
// `textoConfirmar` é o texto do único botão (default "OK").
|
|
//
|
|
// Único modal, compartilhado pelos dois, criado sob demanda e empilhado por
|
|
// cima de qualquer modal já aberto (`.modal-overlay--top`, z-index maior) —
|
|
// não fecha o modal por trás, só pergunta/avisa e devolve a resposta.
|
|
|
|
function pidConfirmModal() {
|
|
let modal = document.getElementById("pid-confirm-modal");
|
|
if (modal) return modal;
|
|
|
|
modal = document.createElement("div");
|
|
modal.className = "modal-overlay modal-overlay--top";
|
|
modal.id = "pid-confirm-modal";
|
|
modal.hidden = true;
|
|
modal.innerHTML = `
|
|
<div class="modal-card">
|
|
<h2 class="modal-card__title confirm-modal__titulo"></h2>
|
|
<p class="modal-card__subtitle confirm-modal__mensagem"></p>
|
|
<div class="modal-actions">
|
|
<button type="button" class="btn-outline confirm-modal__cancelar-btn"></button>
|
|
<button type="button" class="confirm-modal__confirmar-btn"></button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
document.body.appendChild(modal);
|
|
return modal;
|
|
}
|
|
|
|
function pidConfirmOuAlerta(mensagem, opcoes, modoAlerta) {
|
|
const modal = pidConfirmModal();
|
|
const titulo = modal.querySelector(".confirm-modal__titulo");
|
|
const mensagemEl = modal.querySelector(".confirm-modal__mensagem");
|
|
const cancelarBtn = modal.querySelector(".confirm-modal__cancelar-btn");
|
|
const confirmarBtn = modal.querySelector(".confirm-modal__confirmar-btn");
|
|
|
|
titulo.textContent = opcoes.titulo || (modoAlerta ? "Aviso" : "Confirmar ação");
|
|
mensagemEl.textContent = mensagem;
|
|
cancelarBtn.hidden = modoAlerta;
|
|
cancelarBtn.textContent = opcoes.textoCancelar || "Cancelar";
|
|
confirmarBtn.textContent = opcoes.textoConfirmar || (modoAlerta ? "OK" : "Confirmar");
|
|
confirmarBtn.className = `confirm-modal__confirmar-btn ${opcoes.perigoso ? "btn-danger-outline" : "btn-solid"}`;
|
|
|
|
modal.hidden = false;
|
|
|
|
return new Promise((resolve) => {
|
|
function finalizar(resultado) {
|
|
modal.hidden = true;
|
|
cancelarBtn.removeEventListener("click", onCancelar);
|
|
confirmarBtn.removeEventListener("click", onConfirmar);
|
|
modal.removeEventListener("click", onOverlayClick);
|
|
resolve(resultado);
|
|
}
|
|
function onCancelar() {
|
|
finalizar(false);
|
|
}
|
|
function onConfirmar() {
|
|
finalizar(true);
|
|
}
|
|
function onOverlayClick(event) {
|
|
if (event.target === modal) finalizar(false);
|
|
}
|
|
cancelarBtn.addEventListener("click", onCancelar);
|
|
confirmarBtn.addEventListener("click", onConfirmar);
|
|
modal.addEventListener("click", onOverlayClick);
|
|
});
|
|
}
|
|
|
|
function pidConfirm(mensagem, opcoes = {}) {
|
|
return pidConfirmOuAlerta(mensagem, opcoes, false);
|
|
}
|
|
|
|
function pidAlert(mensagem, opcoes = {}) {
|
|
return pidConfirmOuAlerta(mensagem, opcoes, true).then(() => undefined);
|
|
}
|