portal_publico/static/js/ramais.js

835 lines
32 KiB
JavaScript

const PID_RAMAL_CHAMADO_URL =
"https://depaula-tvcorporativa.lovable.app/chamar?token=4d23bd63-24ff-4d49-9ae9-c87919a71262";
async function pidFetchRamais() {
return (await pidApiRequest("/ramais/")) || [];
}
async function pidFetchUsuariosDisponiveisParaRamal() {
return (await pidApiRequest("/ramais/usuarios/")) || [];
}
async function pidCreateRamal(payload) {
return pidApiRequest("/ramais/", { method: "POST", body: payload });
}
async function pidUpdateRamal(id, payload) {
return pidApiRequest(`/ramais/${id}/`, { method: "PATCH", body: payload });
}
async function pidUpdateRamalUsuario(usuarioId, numero) {
return pidApiRequest(`/ramais/usuarios/${usuarioId}/`, { method: "PATCH", body: { numero } });
}
async function pidDeleteRamal(id) {
return pidApiRequest(`/ramais/${id}/`, { method: "DELETE" });
}
async function pidCreateRamalAusencia(payload) {
return pidApiRequest("/ramais-ausencias/", { method: "POST", body: payload });
}
async function pidFetchRamalAusencia(id) {
return pidApiRequest(`/ramais-ausencias/${id}/`);
}
async function pidUpdateRamalAusencia(id, payload) {
return pidApiRequest(`/ramais-ausencias/${id}/`, { method: "PATCH", body: payload });
}
async function pidDeleteRamalAusencia(id) {
return pidApiRequest(`/ramais-ausencias/${id}/`, { method: "DELETE" });
}
async function pidFetchTelefonesExternos() {
return (await pidApiRequest("/telefones-externos/")) || [];
}
async function pidCreateTelefoneExterno(payload) {
return pidApiRequest("/telefones-externos/", { method: "POST", body: payload });
}
async function pidUpdateTelefoneExterno(id, payload) {
return pidApiRequest(`/telefones-externos/${id}/`, { method: "PATCH", body: payload });
}
async function pidDeleteTelefoneExterno(id) {
return pidApiRequest(`/telefones-externos/${id}/`, { method: "DELETE" });
}
async function pidFetchFuncoesTelefonia() {
return (await pidApiRequest("/funcoes-telefonia/")) || [];
}
async function pidCreateFuncaoTelefonia(payload) {
return pidApiRequest("/funcoes-telefonia/", { method: "POST", body: payload });
}
async function pidUpdateFuncaoTelefonia(id, payload) {
return pidApiRequest(`/funcoes-telefonia/${id}/`, { method: "PATCH", body: payload });
}
async function pidDeleteFuncaoTelefonia(id) {
return pidApiRequest(`/funcoes-telefonia/${id}/`, { method: "DELETE" });
}
document.addEventListener("DOMContentLoaded", async () => {
const tableBody = document.getElementById("ram-table-body");
if (!tableBody) return;
const me = await pidGetMe();
if (!me) return;
// Cada subtela (aba) de Ramais tem sua própria permissão dedicada — só as 3 com
// conteúdo administrável (Ramais, Telefones Externos, Funções de Telefonia) têm
// "editar"; Responsável no Tareffa/Férias só têm "visualizar" (são placeholders).
const ramalApps = (me.permissoes_efetivas && me.permissoes_efetivas["ramais"] && me.permissoes_efetivas["ramais"].apps) || {};
const ramaisCanView = !!ramalApps["ramais-visualizar"];
const ramaisCanManage = !!ramalApps["ramais-editar"];
const responsavelTareffaCanView = !!ramalApps["responsavel-tareffa-visualizar"];
const telCanView = !!ramalApps["telefones-externos-visualizar"];
const telCanManage = !!ramalApps["telefones-externos-editar"];
const feriasCanView = !!ramalApps["ferias-visualizar"];
const funCanView = !!ramalApps["funcoes-telefonia-visualizar"];
const funCanManage = !!ramalApps["funcoes-telefonia-editar"];
const RAM_TAB_ORDER = ["ramais", "responsavel-tareffa", "telefones-externos", "ferias", "funcoes-telefonia"];
const ramTabViewPerms = {
ramais: ramaisCanView,
"responsavel-tareffa": responsavelTareffaCanView,
"telefones-externos": telCanView,
ferias: feriasCanView,
"funcoes-telefonia": funCanView,
};
const canViewAnyRamTab = RAM_TAB_ORDER.some((key) => ramTabViewPerms[key]);
const noAccessEl = document.getElementById("ramais-no-access");
const contentEl = document.getElementById("ramais-content");
if (noAccessEl) noAccessEl.hidden = canViewAnyRamTab;
if (contentEl) contentEl.hidden = !canViewAnyRamTab;
if (!canViewAnyRamTab) return;
const searchNomeInput = document.getElementById("ram-search-nome");
const searchDepartamentoInput = document.getElementById("ram-search-departamento");
const footerCount = document.getElementById("ram-footer-count");
const addBtn = document.getElementById("ram-add-btn");
const ausenciaBtn = document.getElementById("ram-ausencia-btn");
const chamadoBtn = document.getElementById("ram-chamado-btn");
if (addBtn) addBtn.hidden = !ramaisCanManage;
if (ausenciaBtn) ausenciaBtn.hidden = !ramaisCanManage;
let activeRamTab = RAM_TAB_ORDER.find((key) => ramTabViewPerms[key]) || "ramais";
function renderRamTabs() {
document.querySelectorAll("[data-ram-tab]").forEach((tab) => {
const key = tab.getAttribute("data-ram-tab");
tab.hidden = !ramTabViewPerms[key];
tab.classList.toggle("is-active", key === activeRamTab);
});
document.querySelectorAll("[data-ram-tab-panel]").forEach((panel) => {
panel.hidden = panel.getAttribute("data-ram-tab-panel") !== activeRamTab;
});
}
document.querySelectorAll("[data-ram-tab]").forEach((tab) => {
tab.addEventListener("click", () => {
activeRamTab = tab.getAttribute("data-ram-tab");
renderRamTabs();
});
});
// Telefones Externos
const telSearchNomeInput = document.getElementById("ram-tel-search-nome");
const telSearchObsInput = document.getElementById("ram-tel-search-obs");
const telFooterCount = document.getElementById("ram-tel-footer-count");
const telTableBody = document.getElementById("ram-tel-table-body");
const telAddBtn = document.getElementById("ram-tel-add-btn");
if (telAddBtn) telAddBtn.hidden = !telCanManage;
const telFormModal = document.getElementById("telefone-externo-form-modal");
const telFormTitle = document.getElementById("tel-form-title");
const telFormNome = document.getElementById("tel-form-nome");
const telFormRamal = document.getElementById("tel-form-ramal");
const telFormTelefone = document.getElementById("tel-form-telefone");
const telFormObservacoes = document.getElementById("tel-form-observacoes");
const telFormError = document.getElementById("tel-form-error");
const telFormSaveBtn = document.getElementById("tel-form-save-btn");
const telFormCancelBtn = document.getElementById("tel-form-cancel-btn");
let telefonesExternos = [];
let editingTelefoneId = null;
// Funções de Telefonia
const funTableBody = document.getElementById("ram-fun-table-body");
const funFooterCount = document.getElementById("ram-fun-footer-count");
const funAddBtn = document.getElementById("ram-fun-add-btn");
if (funAddBtn) funAddBtn.hidden = !funCanManage;
const funFormModal = document.getElementById("funcao-telefonia-form-modal");
const funFormTitle = document.getElementById("fun-form-title");
const funFormComando = document.getElementById("fun-form-comando");
const funFormFuncao = document.getElementById("fun-form-funcao");
const funFormResumo = document.getElementById("fun-form-resumo");
const funFormError = document.getElementById("fun-form-error");
const funFormSaveBtn = document.getElementById("fun-form-save-btn");
const funFormCancelBtn = document.getElementById("fun-form-cancel-btn");
let funcoesTelefonia = [];
let editingFuncaoId = null;
const formModal = document.getElementById("ramal-form-modal");
const formTitle = document.getElementById("ram-form-title");
const formSubtitle = document.getElementById("ram-form-subtitle");
const formNumero = document.getElementById("ram-form-numero");
const formNome = document.getElementById("ram-form-nome");
const formDepartamento = document.getElementById("ram-form-departamento");
const formError = document.getElementById("ram-form-error");
const formSaveBtn = document.getElementById("ram-form-save-btn");
const formCancelBtn = document.getElementById("ram-form-cancel-btn");
const ausenciaModal = document.getElementById("ramal-ausencia-modal");
const ausUsuario = document.getElementById("ram-aus-usuario");
const ausDataInicio = document.getElementById("ram-aus-data-inicio");
const ausHoraInicio = document.getElementById("ram-aus-hora-inicio");
const ausDataFim = document.getElementById("ram-aus-data-fim");
const ausHoraVolta = document.getElementById("ram-aus-hora-volta");
const ausTipo = document.getElementById("ram-aus-tipo");
const ausObservacoes = document.getElementById("ram-aus-observacoes");
const ausError = document.getElementById("ram-aus-error");
const ausSaveBtn = document.getElementById("ram-aus-save-btn");
const ausCancelBtn = document.getElementById("ram-aus-cancel-btn");
const ausViewModal = document.getElementById("ramal-ausencia-view-modal");
const ausViewTitle = document.getElementById("ram-aus-view-title");
const ausViewCloseBtn = document.getElementById("ram-aus-view-close-btn");
const ausViewUsuario = document.getElementById("ram-aus-view-usuario");
const ausViewDataInicio = document.getElementById("ram-aus-view-data-inicio");
const ausViewHoraInicio = document.getElementById("ram-aus-view-hora-inicio");
const ausViewDataFim = document.getElementById("ram-aus-view-data-fim");
const ausViewHoraVolta = document.getElementById("ram-aus-view-hora-volta");
const ausViewTipo = document.getElementById("ram-aus-view-tipo");
const ausViewObservacoes = document.getElementById("ram-aus-view-observacoes");
const ausViewError = document.getElementById("ram-aus-view-error");
const ausViewActions = document.getElementById("ram-aus-view-actions");
const ausEditActions = document.getElementById("ram-aus-edit-actions");
const ausViewEditBtn = document.getElementById("ram-aus-view-edit-btn");
const ausViewDeleteBtn = document.getElementById("ram-aus-view-delete-btn");
const ausViewCancelEditBtn = document.getElementById("ram-aus-view-cancel-edit-btn");
const ausViewSaveBtn = document.getElementById("ram-aus-view-save-btn");
const chamadoModal = document.getElementById("ramal-chamado-modal");
const chamadoIframe = document.getElementById("ram-chamado-iframe");
const chamadoCloseBtn = document.getElementById("ram-chamado-close-btn");
let ramais = [];
let usuariosDisponiveis = [];
let viewingAusencia = null;
let viewingRamalContext = null;
// "create" (avulso novo) | "avulso" (editando Ramal existente) | "usuario" (só ajusta o número em Usuario.ramal)
let editingMode = "create";
let editingId = null;
function usuarioOptionsHtml() {
return usuariosDisponiveis.map((u) => `<option value="${u.id}">${u.nome}</option>`).join("");
}
function rowHtml(ramal) {
const ausente = ramal.usuario_ausente;
const aniversario = ramal.usuario_aniversariante;
const rowClass = aniversario ? "ram-row--aniversario" : ausente ? "ram-row--ausente" : "";
const nomeHtml = aniversario
? `${ramal.nome_exibicao} <span class="ram-badge ram-badge--aniversario">🎉 Feliz Aniversário</span>`
: ramal.nome_exibicao;
const numeroHtml = ramal.numero_exibicao
? ramal.numero_exibicao
: `<span class="ram-badge ram-badge--pendente">Pendente</span>`;
const ausenteBadgeHtml = ausente
? `<br/><button type="button" class="ram-badge ram-badge--ausente" data-ram-ver-ausencia="${ramal.usuario_ausencia_ativa_id}">(AUSENTE)</button>`
: "";
const ramalHtml = `${numeroHtml}${ausenteBadgeHtml}`;
const editBtnHtml = ramaisCanManage
? `
<button type="button" class="icon-btn" data-ram-edit="${ramal.id}" aria-label="Editar ramal">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9" stroke-linecap="round"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z" stroke-linejoin="round"/></svg>
</button>`
: "";
const deleteBtnHtml =
ramaisCanManage && ramal.tipo === "avulso"
? `
<button type="button" class="icon-btn" data-ram-delete="${ramal.avulso_id}" aria-label="Excluir ramal">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 7h16M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2m-8 0 1 12a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1l1-12" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>`
: "";
return `
<tr class="${rowClass}">
<td>${nomeHtml}</td>
<td>${ramal.departamento_exibicao || "—"}</td>
<td>${ramalHtml}</td>
<td><div class="pa-row-actions">${editBtnHtml}${deleteBtnHtml}</div></td>
</tr>`;
}
function render() {
const termNome = searchNomeInput.value.trim().toLowerCase();
const termDepartamento = searchDepartamentoInput.value.trim().toLowerCase();
const rows = ramais.filter((r) => {
const nome = (r.nome_exibicao || "").toLowerCase();
const departamento = (r.departamento_exibicao || "").toLowerCase();
return (!termNome || nome.includes(termNome)) && (!termDepartamento || departamento.includes(termDepartamento));
});
tableBody.innerHTML = rows.length
? rows.map(rowHtml).join("")
: `<tr class="pa-empty-row"><td colspan="4">Nenhum ramal cadastrado ainda.</td></tr>`;
if (footerCount) footerCount.textContent = `${rows.length} ${rows.length === 1 ? "item" : "itens"}`;
}
async function refresh() {
const tasks = [pidFetchRamais()];
if (ramaisCanManage) tasks.push(pidFetchUsuariosDisponiveisParaRamal());
const results = await Promise.all(tasks);
ramais = results[0] || [];
if (ramaisCanManage) usuariosDisponiveis = results[1] || [];
render();
}
function telefoneRowHtml(tel) {
const editBtnHtml = telCanManage
? `
<button type="button" class="icon-btn" data-tel-edit="${tel.id}" aria-label="Editar telefone">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9" stroke-linecap="round"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z" stroke-linejoin="round"/></svg>
</button>`
: "";
const deleteBtnHtml = telCanManage
? `
<button type="button" class="icon-btn" data-tel-delete="${tel.id}" aria-label="Excluir telefone">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 7h16M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2m-8 0 1 12a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1l1-12" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>`
: "";
return `
<tr>
<td>${tel.nome}</td>
<td>${tel.ramal || "—"}</td>
<td>${tel.telefone || "—"}</td>
<td>${tel.observacoes || "—"}</td>
<td><div class="pa-row-actions">${editBtnHtml}${deleteBtnHtml}</div></td>
</tr>`;
}
function renderTelefonesExternos() {
const termNome = telSearchNomeInput.value.trim().toLowerCase();
const termObs = telSearchObsInput.value.trim().toLowerCase();
const rows = telefonesExternos.filter((tel) => {
const nome = (tel.nome || "").toLowerCase();
const obs = (tel.observacoes || "").toLowerCase();
return (!termNome || nome.includes(termNome)) && (!termObs || obs.includes(termObs));
});
telTableBody.innerHTML = rows.length
? rows.map(telefoneRowHtml).join("")
: `<tr class="pa-empty-row"><td colspan="5">Nenhum telefone externo cadastrado ainda.</td></tr>`;
if (telFooterCount) telFooterCount.textContent = `${rows.length} ${rows.length === 1 ? "item" : "itens"}`;
}
async function refreshTelefonesExternos() {
telefonesExternos = await pidFetchTelefonesExternos();
renderTelefonesExternos();
}
function openTelefoneModal(tel) {
telFormError.textContent = "";
editingTelefoneId = tel ? tel.id : null;
telFormTitle.textContent = tel ? "Editar Telefone Externo" : "Adicionar Telefone Externo";
telFormSaveBtn.textContent = tel ? "Salvar" : "Adicionar";
telFormNome.value = tel ? tel.nome || "" : "";
telFormRamal.value = tel ? tel.ramal || "" : "";
telFormTelefone.value = tel ? tel.telefone || "" : "";
telFormObservacoes.value = tel ? tel.observacoes || "" : "";
telFormModal.hidden = false;
}
function closeTelefoneModal() {
telFormModal.hidden = true;
editingTelefoneId = null;
}
function funcaoRowHtml(fun) {
const editBtnHtml = funCanManage
? `
<button type="button" class="icon-btn" data-fun-edit="${fun.id}" aria-label="Editar função">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9" stroke-linecap="round"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z" stroke-linejoin="round"/></svg>
</button>`
: "";
const deleteBtnHtml = funCanManage
? `
<button type="button" class="icon-btn" data-fun-delete="${fun.id}" aria-label="Excluir função">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 7h16M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2m-8 0 1 12a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1l1-12" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>`
: "";
return `
<tr>
<td>${fun.comando}</td>
<td>${fun.funcao}</td>
<td>${fun.resumo || "—"}</td>
<td><div class="pa-row-actions">${editBtnHtml}${deleteBtnHtml}</div></td>
</tr>`;
}
function renderFuncoesTelefonia() {
funTableBody.innerHTML = funcoesTelefonia.length
? funcoesTelefonia.map(funcaoRowHtml).join("")
: `<tr class="pa-empty-row"><td colspan="4">Nenhuma função cadastrada ainda.</td></tr>`;
if (funFooterCount) {
funFooterCount.textContent = `${funcoesTelefonia.length} ${funcoesTelefonia.length === 1 ? "item" : "itens"}`;
}
}
async function refreshFuncoesTelefonia() {
funcoesTelefonia = await pidFetchFuncoesTelefonia();
renderFuncoesTelefonia();
}
function openFuncaoModal(fun) {
funFormError.textContent = "";
editingFuncaoId = fun ? fun.id : null;
funFormTitle.textContent = fun ? "Editar Função de Telefonia" : "Adicionar Função de Telefonia";
funFormSaveBtn.textContent = fun ? "Salvar" : "Adicionar";
funFormComando.value = fun ? fun.comando || "" : "";
funFormFuncao.value = fun ? fun.funcao || "" : "";
funFormResumo.value = fun ? fun.resumo || "" : "";
funFormModal.hidden = false;
}
function closeFuncaoModal() {
funFormModal.hidden = true;
editingFuncaoId = null;
}
function openFormModal(ramal) {
formError.textContent = "";
if (!ramal) {
editingMode = "create";
editingId = null;
formTitle.textContent = "Adicionar um Novo Ramal";
formSubtitle.hidden = true;
formSaveBtn.textContent = "Adicionar";
formNome.value = "";
formDepartamento.value = "";
formNumero.value = "";
formNome.disabled = false;
formDepartamento.disabled = false;
} else if (ramal.tipo === "usuario") {
editingMode = "usuario";
editingId = ramal.usuario_id;
formTitle.textContent = "Editar Ramal";
formSubtitle.hidden = false;
formSaveBtn.textContent = "Salvar";
formNome.value = ramal.nome_exibicao || "";
formDepartamento.value = ramal.departamento_exibicao || "";
formNumero.value = ramal.numero_exibicao || "";
formNome.disabled = true;
formDepartamento.disabled = true;
} else {
editingMode = "avulso";
editingId = ramal.avulso_id;
formTitle.textContent = "Editar Ramal";
formSubtitle.hidden = true;
formSaveBtn.textContent = "Salvar";
formNome.value = ramal.nome_exibicao || "";
formDepartamento.value = ramal.departamento_exibicao || "";
formNumero.value = ramal.numero_exibicao || "";
formNome.disabled = false;
formDepartamento.disabled = false;
}
formModal.hidden = false;
}
function closeFormModal() {
formModal.hidden = true;
editingId = null;
}
function openAusenciaModal() {
ausError.textContent = "";
ausUsuario.innerHTML = usuarioOptionsHtml();
ausDataInicio.value = "";
ausHoraInicio.value = "";
ausDataFim.value = "";
ausHoraVolta.value = "";
ausTipo.value = "Ausência";
ausObservacoes.value = "";
ausenciaModal.hidden = false;
}
function closeAusenciaModal() {
ausenciaModal.hidden = true;
}
function fillAusenciaViewFields(ausencia, ramal) {
ausViewUsuario.innerHTML = `<option>${ramal.nome_exibicao} - ${ramal.departamento_exibicao || "—"} / Ramal: ${ramal.numero_exibicao || "—"}</option>`;
ausViewDataInicio.value = ausencia.data_inicio || "";
ausViewHoraInicio.value = ausencia.hora_inicio ? ausencia.hora_inicio.slice(0, 5) : "";
ausViewDataFim.value = ausencia.data_fim || "";
ausViewHoraVolta.value = ausencia.hora_volta ? ausencia.hora_volta.slice(0, 5) : "";
ausViewTipo.value = ausencia.tipo || "";
ausViewObservacoes.value = ausencia.observacoes || "";
}
function setAusenciaViewMode(mode) {
const editing = mode === "edit";
ausViewDataInicio.disabled = !editing;
ausViewHoraInicio.disabled = !editing;
ausViewDataFim.disabled = !editing;
ausViewHoraVolta.disabled = !editing;
ausViewTipo.disabled = !editing;
ausViewObservacoes.disabled = !editing;
ausViewTitle.textContent = editing ? "Editar Ausência" : "Visualizar Ausência";
ausViewActions.hidden = editing;
ausEditActions.hidden = !editing;
}
async function openAusenciaViewModal(ramal) {
ausViewError.textContent = "";
try {
viewingAusencia = await pidFetchRamalAusencia(ramal.usuario_ausencia_ativa_id);
} catch (e) {
window.alert(e.message);
return;
}
viewingRamalContext = ramal;
fillAusenciaViewFields(viewingAusencia, ramal);
if (ausViewEditBtn) ausViewEditBtn.hidden = !ramaisCanManage;
if (ausViewDeleteBtn) ausViewDeleteBtn.hidden = !ramaisCanManage;
setAusenciaViewMode("view");
ausViewModal.hidden = false;
}
function closeAusenciaViewModal() {
ausViewModal.hidden = true;
viewingAusencia = null;
viewingRamalContext = null;
}
function openChamadoModal() {
chamadoIframe.src = PID_RAMAL_CHAMADO_URL;
chamadoModal.hidden = false;
}
function closeChamadoModal() {
chamadoModal.hidden = true;
chamadoIframe.src = "about:blank";
}
if (searchNomeInput) searchNomeInput.addEventListener("input", render);
if (searchDepartamentoInput) searchDepartamentoInput.addEventListener("input", render);
if (telSearchNomeInput) telSearchNomeInput.addEventListener("input", renderTelefonesExternos);
if (telSearchObsInput) telSearchObsInput.addEventListener("input", renderTelefonesExternos);
if (telAddBtn) telAddBtn.addEventListener("click", () => openTelefoneModal(null));
if (telFormCancelBtn) telFormCancelBtn.addEventListener("click", closeTelefoneModal);
if (telFormModal) {
telFormModal.addEventListener("click", (event) => {
if (event.target === telFormModal) closeTelefoneModal();
});
}
if (telFormSaveBtn) {
telFormSaveBtn.addEventListener("click", async () => {
const nome = telFormNome.value.trim();
if (!nome) {
telFormError.textContent = "Informe o nome.";
return;
}
telFormError.textContent = "";
const payload = {
nome,
ramal: telFormRamal.value.trim(),
telefone: telFormTelefone.value.trim(),
observacoes: telFormObservacoes.value.trim(),
};
try {
if (editingTelefoneId) {
await pidUpdateTelefoneExterno(editingTelefoneId, payload);
} else {
await pidCreateTelefoneExterno(payload);
}
closeTelefoneModal();
await refreshTelefonesExternos();
} catch (e) {
telFormError.textContent = e.message;
}
});
}
if (telTableBody) {
telTableBody.addEventListener("click", async (event) => {
const editBtn = event.target.closest("[data-tel-edit]");
if (editBtn) {
const id = Number(editBtn.getAttribute("data-tel-edit"));
const tel = telefonesExternos.find((t) => t.id === id);
if (tel) openTelefoneModal(tel);
return;
}
const deleteBtn = event.target.closest("[data-tel-delete]");
if (deleteBtn) {
const id = Number(deleteBtn.getAttribute("data-tel-delete"));
const tel = telefonesExternos.find((t) => t.id === id);
if (tel && window.confirm(`Remover o telefone de "${tel.nome}"?`)) {
await pidDeleteTelefoneExterno(id);
await refreshTelefonesExternos();
}
}
});
}
if (funAddBtn) funAddBtn.addEventListener("click", () => openFuncaoModal(null));
if (funFormCancelBtn) funFormCancelBtn.addEventListener("click", closeFuncaoModal);
if (funFormModal) {
funFormModal.addEventListener("click", (event) => {
if (event.target === funFormModal) closeFuncaoModal();
});
}
if (funFormSaveBtn) {
funFormSaveBtn.addEventListener("click", async () => {
const comando = funFormComando.value.trim();
if (!comando) {
funFormError.textContent = "Informe o comando.";
return;
}
funFormError.textContent = "";
const payload = {
comando,
funcao: funFormFuncao.value.trim(),
resumo: funFormResumo.value.trim(),
};
try {
if (editingFuncaoId) {
await pidUpdateFuncaoTelefonia(editingFuncaoId, payload);
} else {
await pidCreateFuncaoTelefonia(payload);
}
closeFuncaoModal();
await refreshFuncoesTelefonia();
} catch (e) {
funFormError.textContent = e.message;
}
});
}
if (funTableBody) {
funTableBody.addEventListener("click", async (event) => {
const editBtn = event.target.closest("[data-fun-edit]");
if (editBtn) {
const id = Number(editBtn.getAttribute("data-fun-edit"));
const fun = funcoesTelefonia.find((f) => f.id === id);
if (fun) openFuncaoModal(fun);
return;
}
const deleteBtn = event.target.closest("[data-fun-delete]");
if (deleteBtn) {
const id = Number(deleteBtn.getAttribute("data-fun-delete"));
const fun = funcoesTelefonia.find((f) => f.id === id);
if (fun && window.confirm(`Remover a função "${fun.comando}"?`)) {
await pidDeleteFuncaoTelefonia(id);
await refreshFuncoesTelefonia();
}
}
});
}
if (addBtn) addBtn.addEventListener("click", () => openFormModal(null));
if (formCancelBtn) formCancelBtn.addEventListener("click", closeFormModal);
if (formModal) {
formModal.addEventListener("click", (event) => {
if (event.target === formModal) closeFormModal();
});
}
if (formSaveBtn) {
formSaveBtn.addEventListener("click", async () => {
const nome = formNome.value.trim();
const departamento = formDepartamento.value.trim();
const numero = formNumero.value.trim();
if (editingMode !== "usuario" && !nome) {
formError.textContent = "Informe o nome.";
return;
}
formError.textContent = "";
try {
if (editingMode === "usuario") {
await pidUpdateRamalUsuario(editingId, numero);
} else if (editingMode === "avulso") {
await pidUpdateRamal(editingId, { nome, departamento, numero });
} else {
await pidCreateRamal({ nome, departamento, numero });
}
closeFormModal();
await refresh();
} catch (e) {
formError.textContent = e.message;
}
});
}
if (ausenciaBtn) ausenciaBtn.addEventListener("click", openAusenciaModal);
if (ausCancelBtn) ausCancelBtn.addEventListener("click", closeAusenciaModal);
if (ausenciaModal) {
ausenciaModal.addEventListener("click", (event) => {
if (event.target === ausenciaModal) closeAusenciaModal();
});
}
if (ausSaveBtn) {
ausSaveBtn.addEventListener("click", async () => {
const usuarioId = ausUsuario.value ? Number(ausUsuario.value) : null;
const dataInicio = ausDataInicio.value;
const dataFim = ausDataFim.value;
if (!usuarioId || !dataInicio || !dataFim) {
ausError.textContent = "Selecione o usuário e as datas inicial e final.";
return;
}
ausError.textContent = "";
const payload = {
usuario: usuarioId,
data_inicio: dataInicio,
hora_inicio: ausHoraInicio.value || null,
data_fim: dataFim,
hora_volta: ausHoraVolta.value || null,
tipo: ausTipo.value.trim() || "Ausência",
observacoes: ausObservacoes.value.trim(),
};
try {
await pidCreateRamalAusencia(payload);
closeAusenciaModal();
await refresh();
} catch (e) {
ausError.textContent = e.message;
}
});
}
if (ausViewCloseBtn) ausViewCloseBtn.addEventListener("click", closeAusenciaViewModal);
if (ausViewModal) {
ausViewModal.addEventListener("click", (event) => {
if (event.target === ausViewModal) closeAusenciaViewModal();
});
}
if (ausViewEditBtn) ausViewEditBtn.addEventListener("click", () => setAusenciaViewMode("edit"));
if (ausViewCancelEditBtn) {
ausViewCancelEditBtn.addEventListener("click", () => {
fillAusenciaViewFields(viewingAusencia, viewingRamalContext);
setAusenciaViewMode("view");
});
}
if (ausViewSaveBtn) {
ausViewSaveBtn.addEventListener("click", async () => {
const dataInicio = ausViewDataInicio.value;
const dataFim = ausViewDataFim.value;
if (!dataInicio || !dataFim) {
ausViewError.textContent = "Informe as datas inicial e final.";
return;
}
ausViewError.textContent = "";
const payload = {
data_inicio: dataInicio,
hora_inicio: ausViewHoraInicio.value || null,
data_fim: dataFim,
hora_volta: ausViewHoraVolta.value || null,
tipo: ausViewTipo.value.trim() || "Ausência",
observacoes: ausViewObservacoes.value.trim(),
};
try {
await pidUpdateRamalAusencia(viewingAusencia.id, payload);
closeAusenciaViewModal();
await refresh();
} catch (e) {
ausViewError.textContent = e.message;
}
});
}
if (ausViewDeleteBtn) {
ausViewDeleteBtn.addEventListener("click", async () => {
if (!window.confirm("Deletar esta ausência?")) return;
try {
await pidDeleteRamalAusencia(viewingAusencia.id);
closeAusenciaViewModal();
await refresh();
} catch (e) {
window.alert(e.message);
}
});
}
if (chamadoBtn) chamadoBtn.addEventListener("click", openChamadoModal);
if (chamadoCloseBtn) chamadoCloseBtn.addEventListener("click", closeChamadoModal);
if (chamadoModal) {
chamadoModal.addEventListener("click", (event) => {
if (event.target === chamadoModal) closeChamadoModal();
});
}
tableBody.addEventListener("click", async (event) => {
const editBtn = event.target.closest("[data-ram-edit]");
if (editBtn) {
const id = editBtn.getAttribute("data-ram-edit");
const ramal = ramais.find((r) => r.id === id);
if (ramal) openFormModal(ramal);
return;
}
const deleteBtn = event.target.closest("[data-ram-delete]");
if (deleteBtn) {
const avulsoId = Number(deleteBtn.getAttribute("data-ram-delete"));
const ramal = ramais.find((r) => r.avulso_id === avulsoId);
if (ramal && window.confirm(`Remover o ramal de "${ramal.nome_exibicao}"?`)) {
await pidDeleteRamal(avulsoId);
await refresh();
}
return;
}
const verAusenciaBtn = event.target.closest("[data-ram-ver-ausencia]");
if (verAusenciaBtn) {
const id = Number(verAusenciaBtn.getAttribute("data-ram-ver-ausencia"));
const ramal = ramais.find((r) => r.usuario_ausencia_ativa_id === id);
if (ramal) await openAusenciaViewModal(ramal);
}
});
renderRamTabs();
await Promise.all([refresh(), refreshTelefonesExternos(), refreshFuncoesTelefonia()]);
});