835 lines
32 KiB
JavaScript
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()]);
|
|
});
|