diff options
Diffstat (limited to 'static/interface-renderer.js')
| -rw-r--r-- | static/interface-renderer.js | 150 |
1 files changed, 131 insertions, 19 deletions
diff --git a/static/interface-renderer.js b/static/interface-renderer.js index 5145cf3..d3478be 100644 --- a/static/interface-renderer.js +++ b/static/interface-renderer.js @@ -1,6 +1,7 @@ /* jshint esversion: 2024, module: true */ import { Utils } from "./utils.js"; +import { InterfaceState } from "./enums.js"; /** * Static Interface Renderer for displaying network interfaces @@ -27,7 +28,7 @@ class InterfaceRenderer { const isActive = iface === currentInterface; return ` - <button class="interface-tab ${isActive ? "active" : ""}" + <button class="interface-tab ${isActive ? "active" : ""}" data-interface="${Utils.sanitizeHTML(iface.Name)}"> ${Utils.sanitizeHTML(iface.Name)} <span class="interface-state ${stateClass}">${Utils.sanitizeHTML(stateText)}</span> @@ -96,7 +97,10 @@ class InterfaceRenderer { "DNS", InterfaceRenderer.renderDNSServerList(iface.DNS), ), - InterfaceRenderer.renderDetailRow("NTP", iface.NTP), + InterfaceRenderer.renderDetailRow( + "NTP", + InterfaceRenderer.renderNTPServerList(iface.NTP), + ), InterfaceRenderer.renderDetailRow( "Activation Policy", iface.ActivationPolicy, @@ -126,7 +130,7 @@ class InterfaceRenderer { * @returns {string} HTML string */ static renderDetailRow(label, value, valueClass = "") { - if (!value) return ""; + if (!value && value !== 0 && value !== false) return ""; const abbreviations = { MTU: "Maximum Transmission Unit", @@ -145,15 +149,74 @@ class InterfaceRenderer { ? `<abbr title="${abbreviations[label]}">${label}</abbr>` : label; + // Handle different value types + let displayValue; + if (typeof value === "string") { + displayValue = Utils.sanitizeHTML(value); + } else if (typeof value === "object") { + // Handle object rendering + displayValue = InterfaceRenderer.renderObjectValue(value); + } else { + displayValue = Utils.sanitizeHTML(String(value)); + } + return ` <div class="detail-row"> <span class="detail-label">${abbrLabel}:</span> - <span class="detail-value ${valueClass}">${Utils.sanitizeHTML(value)}</span> + <span class="detail-value ${valueClass}">${displayValue}</span> </div> `; } /** + * Render object value for display + * @static + * @param {Object} obj - Object to render + * @returns {string} HTML string + */ + static renderObjectValue(obj) { + if (obj === null || obj === undefined) return ""; + + // Handle array of objects + if (Array.isArray(obj)) { + return obj + .map((item) => InterfaceRenderer.renderObjectValue(item)) + .join(", "); + } + + // Handle plain object + if (typeof obj === "object") { + // Check if it's an IP address object + if (obj.Address && Array.isArray(obj.Address)) { + return Utils.ipFromArray(obj); + } + + // Check if it's a simple key-value object we can stringify + try { + const simpleObj = {}; + for (const [key, value] of Object.entries(obj)) { + if ( + value !== null && + value !== undefined && + typeof value !== "object" + ) { + simpleObj[key] = value; + } + } + if (Object.keys(simpleObj).length > 0) { + return Utils.sanitizeHTML(JSON.stringify(simpleObj)); + } + } catch (e) { + // Fall through to default handling + } + + return Utils.sanitizeHTML(String(obj)); + } + + return Utils.sanitizeHTML(String(obj)); + } + + /** * Render address list * @static * @param {Array} addresses - Array of addresses @@ -162,14 +225,15 @@ class InterfaceRenderer { static renderAddressList(addresses) { if (!addresses?.length) return ""; - return addresses + const addressItems = addresses .map((addr) => { const ip = Utils.ipFromArray(addr); - return ip - ? `<div class="address-item">${Utils.sanitizeHTML(ip)}</div>` - : ""; + return ip ? Utils.sanitizeHTML(ip) : ""; }) - .join(""); + .filter((ip) => ip) + .join(", "); + + return addressItems || ""; } /** @@ -181,14 +245,47 @@ class InterfaceRenderer { static renderDNSServerList(dnsServers) { if (!dnsServers?.length) return ""; - return dnsServers + const dnsItems = dnsServers .map((dns) => { const server = Utils.ipFromArray(dns.Address ?? dns); - return server - ? `<div class="dns-item">${Utils.sanitizeHTML(server)}</div>` - : ""; + return server ? Utils.sanitizeHTML(server) : ""; }) - .join(""); + .filter((server) => server) + .join(", "); + + return dnsItems || ""; + } + + /** + * Render NTP server list + * @static + * @param {Array} ntpServers - Array of NTP servers + * @returns {string} Formatted NTP servers + */ + static renderNTPServerList(ntpServers) { + if (!ntpServers?.length) return ""; + + const ntpItems = ntpServers + .map((ntp) => { + if (typeof ntp === "string") { + return Utils.sanitizeHTML(ntp); + } else if (ntp && typeof ntp === "object") { + // Handle NTP server object + if (ntp.Address && Array.isArray(ntp.Address)) { + return Utils.ipFromArray(ntp); + } else if (ntp.Server) { + return Utils.sanitizeHTML(ntp.Server); + } else { + // Try to extract any stringifiable value + return InterfaceRenderer.renderObjectValue(ntp); + } + } + return ""; + }) + .filter((server) => server) + .join(", "); + + return ntpItems || ""; } /** @@ -200,13 +297,28 @@ class InterfaceRenderer { static renderDHCPLeases(leases) { if (!leases?.length) return ""; - return leases + const leaseItems = leases .map((lease) => { - const ip = lease.IP ?? lease; - const to = lease.To ?? lease.MAC ?? ""; - return `<div class="lease-item">${Utils.sanitizeHTML(ip)} (to ${Utils.sanitizeHTML(to)})</div>`; + if (typeof lease === "string") { + return Utils.sanitizeHTML(lease); + } else if (lease && typeof lease === "object") { + const ip = lease.IP ?? lease.Address ?? lease; + const to = lease.To ?? lease.MAC ?? lease.ClientIdentifier ?? ""; + + if (ip && to) { + return `${Utils.sanitizeHTML(String(ip))} (to ${Utils.sanitizeHTML(String(to))})`; + } else if (ip) { + return Utils.sanitizeHTML(String(ip)); + } else { + return InterfaceRenderer.renderObjectValue(lease); + } + } + return ""; }) - .join(""); + .filter((lease) => lease) + .join(", "); + + return leaseItems || ""; } } |
