// 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);