// app_status.js const socket = io(); // ── Socket events ───────────────────────────────────────────────────────────── socket.on("connect", () => { console.log("Connected to server"); refreshStatus(); }); socket.on("connect_error", (err) => { console.error("Connection error:", err); setStatus("Connection error. Please reload.", false); }); socket.on("status_data", function(data) { renderStatusList(data.statuses || []); setStatus("", null); setRefreshEnabled(true); }); socket.on("status_response", function(data) { setStatus(data.message, data.success); setRefreshEnabled(true); }); // ── Actions ─────────────────────────────────────────────────────────────────── function refreshStatus() { setStatus("Loading ticket statuses...", null); setRefreshEnabled(false); socket.emit("get_ticket_statuses", {}); } function saveSelection() { const checkboxes = document.querySelectorAll(".status-checkbox"); const selected = Array.from(checkboxes).map(cb => ({ id: parseInt(cb.dataset.id), subType: cb.dataset.subtype, selected: cb.checked ? 1 : 0 })); if (selected.length === 0) { setStatus("No statuses to save.", false); return; } setStatus("Saving...", null); socket.emit("save_ticket_statuses", { statuses: selected }); } function selectAll() { document.querySelectorAll(".status-checkbox").forEach(cb => cb.checked = true); } function selectNone() { document.querySelectorAll(".status-checkbox").forEach(cb => cb.checked = false); } function invertSelection() { document.querySelectorAll(".status-checkbox").forEach(cb => cb.checked = !cb.checked); } // ── Rendering ───────────────────────────────────────────────────────────────── function renderStatusList(statuses) { const container = document.getElementById("statusList"); if (statuses.length === 0) { container.innerHTML = '
No ticket statuses found.
'; return; } container.innerHTML = statuses.map(s => `
`).join(""); } function toggleCheckbox(id) { const cb = document.getElementById(id); if (cb) cb.checked = !cb.checked; } // ── Helpers ─────────────────────────────────────────────────────────────────── function setStatus(message, success) { const el = document.getElementById("statusMessage"); el.innerText = message; if (success === true) el.style.color = "#4db6ac"; else if (success === false) el.style.color = "#e57373"; else el.style.color = "#bb86fc"; } function setRefreshEnabled(enabled) { document.getElementById("btnRefresh").disabled = !enabled; } function escapeHtml(str) { return String(str) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """); } function escapeAttr(str) { return String(str).replace(/[^a-zA-Z0-9_-]/g, "_"); } // ── Status Reference Resolution ─────────────────────────────────────────────── const SUB_TYPES = ["INCIDENT", "REQUEST", "CHANGE", "PROBLEM", "RELEASE"]; function renderResolveList() { const container = document.getElementById("resolveList"); container.innerHTML = SUB_TYPES.map(sub => `
`).join(""); } function resolveStatus(subType) { const input = document.getElementById(`resolve_input_${subType}`); const btn = document.getElementById(`resolve_btn_${subType}`); const result = document.getElementById(`resolve_result_${subType}`); const ticketId = parseInt(input.value); if (!ticketId || ticketId < 1) { input.classList.add("error"); result.textContent = "Invalid ID"; result.style.color = "#e57373"; return; } input.classList.remove("resolved", "error"); result.textContent = "Resolving..."; result.style.color = "#bb86fc"; btn.disabled = true; socket.emit("resolve_status_reference", { ticket_id: ticketId, sub_type: subType }); } socket.on("status_resolve_response", function(data) { const subType = data.sub_type; const input = document.getElementById(`resolve_input_${subType}`); const btn = document.getElementById(`resolve_btn_${subType}`); const result = document.getElementById(`resolve_result_${subType}`); btn.disabled = false; if (data.success) { input.classList.add("resolved"); input.classList.remove("error"); result.textContent = data.reference; result.style.color = "#4db6ac"; // Refresh the status list to reflect the newly resolved entry refreshStatus(); } else { input.classList.add("error"); input.classList.remove("resolved"); result.textContent = data.message; result.style.color = "#e57373"; } }); // Render resolve list on page load document.addEventListener("DOMContentLoaded", renderResolveList);