window.onload = () => { const table_elem = document.getElementById("table"); const last_change = document.getElementById("last_change"); const last_ping = document.getElementById("last_ping"); const connected = document.getElementById("connected"); const free_ports = document.getElementById("free_ports"); const timeout_duration = 10*1000; const retry_timeout = 5*1000; let reconnect_timeout; let ping_timeout; let evtSource; let table = []; let direction = -1; let oldkey = "last_change"; table_elem.firstChild.firstChild.lastChild.className = "sort sort-down"; console.log(oldkey, direction); sort = (element, key) => { console.log(key, oldkey, direction); if (key == oldkey) { direction *= -1; } else { oldkey = key; direction = -1; } for (let child of table_elem.firstChild.firstChild.children) { console.log(child); child.className = "" }; element.className = `sort ${direction > 0 ? "sort-up" : "sort-down"}`; do_sort(oldkey, direction); }; let do_sort = (key, direction) => { let is_number = !!~(["port", "number", "last_change"].indexOf(key)); console.log("is number:", is_number); table = table.sort((a, b) => (direction * ( is_number ? a[key] - b[key] : ('' +a[key]).localeCompare(b[key], "de-DE") ))); print_table(); console.log(table); }; let format_date = date => date.toLocaleDateString("de-DE") + ' ' + date.toLocaleTimeString("de-DE"); let print_table = () => { while(table_elem.children.length > 1) { table_elem.removeChild(table_elem.lastChild); } for (let row of table) { let tr = document.createElement("tr"); let values = [ row.number, row.port, row.status, row.name || "?", row.rejector || "", format_date(row.last_change) ]; for(let value of values) { let td = document.createElement("td"); td.innerText = value; td.className = Number.isInteger(value) ? "number" : "text"; tr.appendChild(td); } table_elem.appendChild(tr) } }; let update_table = data => { console.log(data); const allowed_ports = data.allowed_ports.map(x => x.end - x.start + 1).reduce((a,b) => a + b, 0); free_ports.innerText = `Freie Ports: ${allowed_ports - Object.keys(data.allocated_ports).length - data.errored_ports.length}`; last_change.innerHTML = `Letzte Änderung: ${format_date(new Date(+data.last_update * 1000))}`; table = []; for(let number in data.allocated_ports) { let port = data.allocated_ports[number]; number = +number; let {status, last_change} = data.port_state[port]; let rejector = data.rejectors[port] || null; if (rejector && rejector instanceof Array) { rejector = rejector.map(x => "0x"+x.toString(16).padStart(2, 0)).join(" ") } last_change = new Date(last_change * 1000); let name = data.names[number] || null; switch(status) { case "disconnected": status = "getrennt"; break; case "idle": status = "bereit"; break; case "in_call": status = "anruf"; break; } table.push({port, number, status, last_change, rejector, name}) } for (let [timestamp, port] of data.errored_ports) { table.push({port, number: null, status: "Fehler", last_change: new Date(timestamp * 1000), rejector: null, name: null}) } console.log(table); do_sort(oldkey, direction); print_table(); }; let format_event = event => format_date(new Date(+event.data * 1000)); let connect_event_source = () => { clearTimeout(reconnect_timeout); clearTimeout(ping_timeout); ping_timeout = setTimeout(connect_event_source, timeout_duration); evtSource && evtSource.close && evtSource.close(); evtSource = new EventSource("/events"); evtSource.addEventListener("change", event => { last_ping.innerText = `Letzter Serverkontakt: ${format_event(event)}`; fetch("/data") .then(res => res.json()) .then(update_table); }); evtSource.addEventListener("ping", event => { clearTimeout(ping_timeout); ping_timeout = setTimeout(connect_event_source, timeout_duration); last_ping.innerText = `Letzter Serverkontakt: ${format_event(event)}`; connected.className = "visible"; setTimeout(() => connected.className = "hidden", 1000); }); evtSource.onerror = () => { clearTimeout(reconnect_timeout); reconnect_timeout = setTimeout(connect_event_source, retry_timeout); }; } connect_event_source(); };