mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-04-05 01:31:49 -07:00
Refactor network tree data structure and improve device status handling
- Updated the network tree data structure to use consistent naming conventions for device properties (e.g., devName, devMac). - Enhanced the initTree function to utilize the new property names and improved the rendering of device nodes. - Refactored the getStatusBadgeParts function to include additional parameters for archived and new device statuses. - Introduced convenience functions (badgeFromDevice and badgeFromDataAttrs) to streamline badge generation from device objects and data attributes. - Updated various language files to include new status labels and ensure consistency across translations. - Modified the renderSmallBox function to allow for custom icon HTML, improving flexibility in UI components.
This commit is contained in:
@@ -75,8 +75,17 @@ const GRAPHQL_EXTRA_FIELDS = [
|
||||
"devLastNotification",
|
||||
"devIsNew",
|
||||
"devIsArchived",
|
||||
"devIsSleeping",
|
||||
];
|
||||
|
||||
// Row positions for extra (non-display) fields.
|
||||
// In dataSrc, extra fields are appended AFTER the display columns in each row,
|
||||
// so their position = DEVICE_COLUMN_FIELDS.length + their index in GRAPHQL_EXTRA_FIELDS.
|
||||
// Use COL_EXTRA.fieldName to access them in createdCell rowData.
|
||||
const COL_EXTRA = Object.fromEntries(
|
||||
GRAPHQL_EXTRA_FIELDS.map((name, i) => [name, DEVICE_COLUMN_FIELDS.length + i])
|
||||
);
|
||||
|
||||
// Maps Device_TableHead_* language keys to their GraphQL/DB field names.
|
||||
// Used by getColumnNameFromLangString() in ui_components.js and by
|
||||
// column filter logic in devices.php.
|
||||
|
||||
@@ -16,15 +16,16 @@ function loadNetworkNodes() {
|
||||
// PC (leaf) <------- leafs are not included in this SQL query
|
||||
const rawSql = `
|
||||
SELECT
|
||||
parent.devName AS node_name,
|
||||
LOWER(parent.devMac) AS node_mac,
|
||||
parent.devPresentLastScan AS online,
|
||||
parent.devType AS node_type,
|
||||
LOWER(parent.devParentMAC) AS parent_mac,
|
||||
parent.devIcon AS node_icon,
|
||||
parent.devAlertDown AS node_alert,
|
||||
parent.devFlapping AS node_flapping,
|
||||
parent.devIsSleeping AS node_sleeping,
|
||||
parent.devName,
|
||||
LOWER(parent.devMac) AS devMac,
|
||||
parent.devPresentLastScan,
|
||||
parent.devType,
|
||||
LOWER(parent.devParentMAC) AS devParentMAC,
|
||||
parent.devIcon,
|
||||
parent.devAlertDown,
|
||||
parent.devFlapping,
|
||||
parent.devIsSleeping,
|
||||
parent.devIsNew,
|
||||
COUNT(child.devMac) AS node_ports_count
|
||||
FROM DevicesView AS parent
|
||||
LEFT JOIN DevicesView AS child
|
||||
@@ -35,7 +36,7 @@ function loadNetworkNodes() {
|
||||
WHERE parent.devType IN (${networkDeviceTypes})
|
||||
AND parent.devIsArchived = 0
|
||||
GROUP BY parent.devMac, parent.devName, parent.devPresentLastScan,
|
||||
parent.devType, parent.devParentMAC, parent.devIcon, parent.devAlertDown, parent.devFlapping, parent.devIsSleeping
|
||||
parent.devType, parent.devParentMAC, parent.devIcon, parent.devAlertDown, parent.devFlapping, parent.devIsSleeping, parent.devIsNew
|
||||
ORDER BY parent.devName;
|
||||
`;
|
||||
|
||||
@@ -142,15 +143,8 @@ function loadDeviceTable({ sql, containerSelector, tableId, wrapperHtml = null,
|
||||
data: 'devStatus',
|
||||
width: '15%',
|
||||
render: function (_, type, device) {
|
||||
const badge = getStatusBadgeParts(
|
||||
device.devPresentLastScan,
|
||||
device.devAlertDown,
|
||||
device.devFlapping,
|
||||
device.devMac,
|
||||
device.devStatus,
|
||||
device.devIsSleeping || 0
|
||||
);
|
||||
return `<a href="${badge.url}" class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.text}</a>`;
|
||||
const badge = badgeFromDevice(device);
|
||||
return `<a href="${badge.url}" class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.label}</a>`;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -206,7 +200,7 @@ function loadDeviceTable({ sql, containerSelector, tableId, wrapperHtml = null,
|
||||
*/
|
||||
function loadUnassignedDevices() {
|
||||
const sql = `
|
||||
SELECT devMac, devPresentLastScan, devName, devLastIP, devVendor, devAlertDown, devParentPort, devFlapping, devIsSleeping, devStatus
|
||||
SELECT devMac, devPresentLastScan, devName, devLastIP, devVendor, devAlertDown, devParentPort, devFlapping, devIsSleeping, devIsNew, devStatus
|
||||
FROM DevicesView
|
||||
WHERE (devParentMAC IS NULL OR devParentMAC IN ("", " ", "undefined", "null"))
|
||||
AND LOWER(devMac) NOT LIKE "%internet%"
|
||||
@@ -241,7 +235,7 @@ function loadConnectedDevices(node_mac) {
|
||||
const normalized_mac = node_mac.toLowerCase();
|
||||
|
||||
const sql = `
|
||||
SELECT devName, devMac, devLastIP, devVendor, devPresentLastScan, devAlertDown, devParentPort, devVlan, devFlapping, devIsSleeping,
|
||||
SELECT devName, devMac, devLastIP, devVendor, devPresentLastScan, devAlertDown, devParentPort, devVlan, devFlapping, devIsSleeping, devIsNew, devIsArchived,
|
||||
CASE
|
||||
WHEN devIsNew = 1 THEN 'New'
|
||||
WHEN devPresentLastScan = 1 THEN 'On-line'
|
||||
|
||||
@@ -8,19 +8,19 @@
|
||||
function renderNetworkTabs(nodes) {
|
||||
let html = '';
|
||||
nodes.forEach((node, i) => {
|
||||
const iconClass = node.online == 1 ? "text-green" :
|
||||
(node.node_sleeping == 1 ? "text-aqua" :
|
||||
(node.node_alert == 1 ? "text-red" : "text-gray50"));
|
||||
const iconClass = node.devPresentLastScan == 1 ? "text-green" :
|
||||
(node.devIsSleeping == 1 ? "text-aqua" :
|
||||
(node.devAlertDown == 1 ? "text-red" : "text-gray50"));
|
||||
|
||||
const portLabel = node.node_ports_count ? ` (${node.node_ports_count})` : '';
|
||||
const icon = atob(node.node_icon);
|
||||
const id = node.node_mac.replace(/:/g, '_');
|
||||
const icon = atob(node.devIcon);
|
||||
const id = node.devMac.replace(/:/g, '_');
|
||||
|
||||
html += `
|
||||
<li class="networkNodeTabHeaders ${i === 0 ? 'active' : ''}">
|
||||
<a href="#${id}" data-mytabmac="${node.node_mac}" id="${id}_id" data-toggle="tab" title="${node.node_name}">
|
||||
<a href="#${id}" data-mytabmac="${node.devMac}" id="${id}_id" data-toggle="tab" title="${node.devName}">
|
||||
<div class="icon ${iconClass}">${icon}</div>
|
||||
<span class="node-name">${node.node_name}</span>${portLabel}
|
||||
<span class="node-name">${node.devName}</span>${portLabel}
|
||||
</a>
|
||||
</li>`;
|
||||
});
|
||||
@@ -50,21 +50,14 @@ function renderNetworkTabContent(nodes) {
|
||||
$('.tab-content').empty();
|
||||
|
||||
nodes.forEach((node, i) => {
|
||||
const id = node.node_mac.replace(/:/g, '_').toLowerCase();
|
||||
const id = node.devMac.replace(/:/g, '_').toLowerCase();
|
||||
|
||||
const badge = getStatusBadgeParts(
|
||||
node.online,
|
||||
node.node_alert,
|
||||
node.node_flapping,
|
||||
node.node_mac,
|
||||
'',
|
||||
node.node_sleeping || 0
|
||||
);
|
||||
const badge = badgeFromDevice(node);
|
||||
|
||||
const badgeHtml = `<a href="${badge.url}" class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.status}</a>`;
|
||||
const parentId = node.parent_mac.replace(/:/g, '_');
|
||||
const badgeHtml = `<a href="${badge.url}" class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.label}</a>`;
|
||||
const parentId = node.devParentMAC.replace(/:/g, '_');
|
||||
|
||||
isRootNode = node.parent_mac == "";
|
||||
isRootNode = node.devParentMAC == "";
|
||||
|
||||
const paneHtml = `
|
||||
<div class="tab-pane box box-aqua box-body ${i === 0 ? 'active' : ''}" id="${id}">
|
||||
@@ -73,18 +66,18 @@ function renderNetworkTabContent(nodes) {
|
||||
<div class="mb-3 row">
|
||||
<label class="col-sm-3 col-form-label fw-bold">${getString('DevDetail_Tab_Details')}</label>
|
||||
<div class="col-sm-9">
|
||||
<a href="./deviceDetails.php?mac=${node.node_mac}" target="_blank" class="anonymize">${node.node_name}</a>
|
||||
<a href="./deviceDetails.php?mac=${node.devMac}" target="_blank" class="anonymize">${node.devName}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label class="col-sm-3 col-form-label fw-bold">MAC</label>
|
||||
<div class="col-sm-9 anonymize">${node.node_mac}</div>
|
||||
<div class="col-sm-9 anonymize">${node.devMac}</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label class="col-sm-3 col-form-label fw-bold">${getString('Device_TableHead_Type')}</label>
|
||||
<div class="col-sm-9">${node.node_type}</div>
|
||||
<div class="col-sm-9">${node.devType}</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
@@ -96,8 +89,8 @@ function renderNetworkTabContent(nodes) {
|
||||
<label class="col-sm-3 col-form-label fw-bold">${getString('Network_Parent')}</label>
|
||||
<div class="col-sm-9">
|
||||
${isRootNode ? '' : `<a class="anonymize" href="#">`}
|
||||
<span my-data-mac="${node.parent_mac}" data-mac="${node.parent_mac}" data-devIsNetworkNodeDynamic="1" onclick="handleNodeClick(this)">
|
||||
${isRootNode ? getString('Network_Root') : getDevDataByMac(node.parent_mac, "devName")}
|
||||
<span my-data-mac="${node.devParentMAC}" data-mac="${node.devParentMAC}" data-devIsNetworkNodeDynamic="1" onclick="handleNodeClick(this)">
|
||||
${isRootNode ? getString('Network_Root') : getDevDataByMac(node.devParentMAC, "devName")}
|
||||
</span>
|
||||
${isRootNode ? '' : `</a>`}
|
||||
</div>
|
||||
@@ -115,7 +108,7 @@ function renderNetworkTabContent(nodes) {
|
||||
`;
|
||||
|
||||
$('.tab-content').append(paneHtml);
|
||||
loadConnectedDevices(node.node_mac);
|
||||
loadConnectedDevices(node.devMac);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -57,26 +57,28 @@ function getChildren(node, list, path, visited = [])
|
||||
// console.log(node);
|
||||
|
||||
return {
|
||||
name: node.devName,
|
||||
devName: node.devName,
|
||||
path: path,
|
||||
mac: node.devMac,
|
||||
port: node.devParentPort,
|
||||
devMac: node.devMac,
|
||||
devParentPort: node.devParentPort,
|
||||
id: node.devMac,
|
||||
parentMac: node.devParentMAC,
|
||||
icon: node.devIcon,
|
||||
type: node.devType,
|
||||
devParentMAC: node.devParentMAC,
|
||||
devIcon: node.devIcon,
|
||||
devType: node.devType,
|
||||
devIsNetworkNodeDynamic: node.devIsNetworkNodeDynamic,
|
||||
vendor: node.devVendor,
|
||||
lastseen: node.devLastConnection,
|
||||
firstseen: node.devFirstConnection,
|
||||
ip: node.devLastIP,
|
||||
status: node.devStatus,
|
||||
presentLastScan: node.devPresentLastScan,
|
||||
flapping: node.devFlapping,
|
||||
alertDown: node.devAlertDown,
|
||||
sleeping: node.devIsSleeping || 0,
|
||||
devVendor: node.devVendor,
|
||||
devLastConnection: node.devLastConnection,
|
||||
devFirstConnection: node.devFirstConnection,
|
||||
devLastIP: node.devLastIP,
|
||||
devStatus: node.devStatus,
|
||||
devPresentLastScan: node.devPresentLastScan,
|
||||
devFlapping: node.devFlapping,
|
||||
devAlertDown: node.devAlertDown,
|
||||
devIsSleeping: node.devIsSleeping || 0,
|
||||
devIsArchived: node.devIsArchived || 0,
|
||||
devIsNew: node.devIsNew || 0,
|
||||
hasChildren: children.length > 0 || hiddenMacs.includes(node.devMac),
|
||||
relType: node.devParentRelType,
|
||||
devParentRelType: node.devParentRelType,
|
||||
devVlan: node.devVlan,
|
||||
devSSID: node.devSSID,
|
||||
hiddenChildren: hiddenMacs.includes(node.devMac),
|
||||
@@ -227,16 +229,16 @@ function initTree(myHierarchy)
|
||||
htmlId: "networkTree",
|
||||
renderNode: nodeData => {
|
||||
|
||||
(!emptyArr.includes(nodeData.data.port )) ? port = nodeData.data.port : port = "";
|
||||
(!emptyArr.includes(nodeData.data.devParentPort)) ? port = nodeData.data.devParentPort : port = "";
|
||||
|
||||
(port == "" || port == 0 || port == 'None' ) ? portBckgIcon = `<i class="fa fa-wifi"></i>` : portBckgIcon = `<i class="fa fa-ethernet"></i>`;
|
||||
|
||||
portHtml = (port == "" || port == 0 || port == 'None' ) ? "   " : port;
|
||||
|
||||
// Build HTML for individual nodes in the network diagram
|
||||
deviceIcon = (!emptyArr.includes(nodeData.data.icon )) ?
|
||||
deviceIcon = (!emptyArr.includes(nodeData.data.devIcon)) ?
|
||||
`<div class="netIcon">
|
||||
${atob(nodeData.data.icon)}
|
||||
${atob(nodeData.data.devIcon)}
|
||||
</div>` : "";
|
||||
devicePort = `<div class="netPort"
|
||||
style="width:${emSize}em;height:${emSize}em">
|
||||
@@ -253,13 +255,13 @@ function initTree(myHierarchy)
|
||||
`<div class="netCollapse"
|
||||
style="font-size:${nodeHeightPx/2}px;top:${Math.floor(nodeHeightPx / 4)}px"
|
||||
data-mytreepath="${nodeData.data.path}"
|
||||
data-mytreemac="${nodeData.data.mac}">
|
||||
data-mytreemac="${nodeData.data.devMac}">
|
||||
<i class="fa fa-${collapseExpandIcon} pointer"></i>
|
||||
</div>` : "";
|
||||
|
||||
selectedNodeMac = $(".nav-tabs-custom .active a").attr('data-mytabmac')
|
||||
|
||||
highlightedCss = nodeData.data.mac == selectedNodeMac ?
|
||||
highlightedCss = nodeData.data.devMac == selectedNodeMac ?
|
||||
" highlightedNode " : "";
|
||||
cssNodeType = nodeData.data.devIsNetworkNodeDynamic ?
|
||||
" node-network-device " : " node-standard-device ";
|
||||
@@ -268,40 +270,35 @@ function initTree(myHierarchy)
|
||||
<i class="fa-solid fa-hard-drive"></i>
|
||||
</span>` : "";
|
||||
|
||||
const badgeConf = getStatusBadgeParts(
|
||||
nodeData.data.presentLastScan,
|
||||
nodeData.data.alertDown,
|
||||
nodeData.data.flapping,
|
||||
nodeData.data.mac,
|
||||
'',
|
||||
nodeData.data.sleeping || 0
|
||||
);
|
||||
const badgeConf = badgeFromDevice(nodeData.data);
|
||||
|
||||
return result = `<div
|
||||
class="node-inner hover-node-info box pointer ${highlightedCss} ${cssNodeType}"
|
||||
style="height:${nodeHeightPx}px;font-size:${nodeHeightPx-5}px;"
|
||||
onclick="handleNodeClick(this)"
|
||||
data-mac="${nodeData.data.mac}"
|
||||
data-parentMac="${nodeData.data.parentMac}"
|
||||
data-name="${nodeData.data.name}"
|
||||
data-ip="${nodeData.data.ip}"
|
||||
data-mac="${nodeData.data.mac}"
|
||||
data-vendor="${nodeData.data.vendor}"
|
||||
data-type="${nodeData.data.type}"
|
||||
data-mac="${nodeData.data.devMac}"
|
||||
data-parentMac="${nodeData.data.devParentMAC}"
|
||||
data-name="${nodeData.data.devName}"
|
||||
data-ip="${nodeData.data.devLastIP}"
|
||||
data-mac="${nodeData.data.devMac}"
|
||||
data-vendor="${nodeData.data.devVendor}"
|
||||
data-type="${nodeData.data.devType}"
|
||||
data-devIsNetworkNodeDynamic="${nodeData.data.devIsNetworkNodeDynamic}"
|
||||
data-lastseen="${nodeData.data.lastseen}"
|
||||
data-firstseen="${nodeData.data.firstseen}"
|
||||
data-relationship="${nodeData.data.relType}"
|
||||
data-flapping="${nodeData.data.flapping}"
|
||||
data-sleeping="${nodeData.data.sleeping || 0}"
|
||||
data-status="${nodeData.data.status}"
|
||||
data-present="${nodeData.data.presentLastScan}"
|
||||
data-alert="${nodeData.data.alertDown}"
|
||||
data-icon="${nodeData.data.icon}"
|
||||
data-lastseen="${nodeData.data.devLastConnection}"
|
||||
data-firstseen="${nodeData.data.devFirstConnection}"
|
||||
data-relationship="${nodeData.data.devParentRelType}"
|
||||
data-flapping="${nodeData.data.devFlapping}"
|
||||
data-sleeping="${nodeData.data.devIsSleeping || 0}"
|
||||
data-archived="${nodeData.data.devIsArchived || 0}"
|
||||
data-isnew="${nodeData.data.devIsNew || 0}"
|
||||
data-status="${nodeData.data.devStatus}"
|
||||
data-present="${nodeData.data.devPresentLastScan}"
|
||||
data-alertdown="${nodeData.data.devAlertDown}"
|
||||
data-icon="${nodeData.data.devIcon}"
|
||||
>
|
||||
<div class="netNodeText">
|
||||
<strong><span>${devicePort} <span class="${badgeConf.cssText}">${deviceIcon}</span></span>
|
||||
<span class="spanNetworkTree anonymizeDev" style="width:${nodeWidthPx-50}px">${nodeData.data.name}</span>
|
||||
<span class="spanNetworkTree anonymizeDev" style="width:${nodeWidthPx-50}px">${nodeData.data.devName}</span>
|
||||
${networkHardwareIcon}
|
||||
</strong>
|
||||
</div>
|
||||
@@ -318,7 +315,7 @@ function initTree(myHierarchy)
|
||||
hasPan: true,
|
||||
marginLeft: '10',
|
||||
marginRight: '10',
|
||||
idKey: "mac",
|
||||
idKey: "devMac",
|
||||
hasFlatData: false,
|
||||
relationnalField: "children",
|
||||
linkLabel: {
|
||||
@@ -339,7 +336,7 @@ function initTree(myHierarchy)
|
||||
},
|
||||
linkWidth: (nodeData) => 2,
|
||||
linkColor: (nodeData) => {
|
||||
relConf = getRelationshipConf(nodeData.data.relType)
|
||||
relConf = getRelationshipConf(nodeData.data.devParentRelType)
|
||||
return relConf.color;
|
||||
}
|
||||
// onNodeClick: (nodeData) => handleNodeClick(nodeData),
|
||||
|
||||
@@ -738,37 +738,54 @@ function getColumnNameFromLangString(headStringKey) {
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Generating the device status chip
|
||||
function getStatusBadgeParts(devPresentLastScan, devAlertDown, devFlapping, devMac, statusText = '', devIsSleeping = 0) {
|
||||
let css = 'bg-gray text-white statusUnknown';
|
||||
let icon = '<i class="fa-solid fa-question"></i>';
|
||||
let status = 'unknown';
|
||||
function getStatusBadgeParts(devPresentLastScan, devAlertDown, devFlapping, devMac, statusText = '', devIsSleeping = 0, devIsArchived = 0, devIsNew = 0) {
|
||||
let css = 'bg-gray text-white statusUnknown';
|
||||
let icon = '<i class="fa-solid fa-question"></i>';
|
||||
let status = 'unknown';
|
||||
let cssText = '';
|
||||
let label = getString('Gen_Offline');
|
||||
|
||||
if (devPresentLastScan == 1 && devFlapping == 0) {
|
||||
css = 'bg-green text-white statusOnline';
|
||||
css = 'bg-green text-white statusOnline';
|
||||
cssText = 'text-green';
|
||||
icon = '<i class="fa-solid fa-plug"></i>';
|
||||
status = 'online';
|
||||
icon = '<i class="fa-solid fa-plug"></i>';
|
||||
status = 'online';
|
||||
label = getString('Gen_Online');
|
||||
} else if (devPresentLastScan == 1 && devFlapping == 1) {
|
||||
css = 'bg-yellow text-white statusFlapping';
|
||||
css = 'bg-yellow text-white statusFlapping';
|
||||
cssText = 'text-yellow';
|
||||
icon = '<i class="fa-solid fa-plug-circle-exclamation"></i>';
|
||||
status = 'online';
|
||||
icon = '<i class="fa-solid fa-plug-circle-exclamation"></i>';
|
||||
status = 'flapping';
|
||||
label = getString('Gen_Flapping');
|
||||
} else if (devIsSleeping == 1) {
|
||||
css = 'bg-aqua text-white statusSleeping';
|
||||
css = 'bg-aqua text-white statusSleeping';
|
||||
cssText = 'text-aqua';
|
||||
icon = '<i class="fa-solid fa-moon"></i>';
|
||||
status = 'sleeping';
|
||||
} else if (devAlertDown == 1) {
|
||||
css = 'bg-red text-white statusDown';
|
||||
cssText = 'text-red';
|
||||
icon = '<i class="fa-solid fa-triangle-exclamation"></i>';
|
||||
status = 'down';
|
||||
} else if (devPresentLastScan != 1) {
|
||||
css = 'bg-gray text-white statusOffline';
|
||||
icon = '<i class="fa-solid fa-moon"></i>';
|
||||
status = 'sleeping';
|
||||
label = getString('Gen_Sleeping');
|
||||
} else if (devIsArchived == 1) {
|
||||
css = 'bg-gray text-white statusArchived';
|
||||
cssText = 'text-gray50';
|
||||
icon = '<i class="fa-solid fa-xmark"></i>';
|
||||
status = 'offline';
|
||||
icon = '<i class="fa-solid fa-box-archive"></i>';
|
||||
status = 'archived';
|
||||
label = getString('Gen_Archived');
|
||||
} else if (devAlertDown == 1) {
|
||||
css = 'bg-red text-white statusDown';
|
||||
cssText = 'text-red';
|
||||
icon = '<i class="fa-solid fa-triangle-exclamation"></i>';
|
||||
status = 'down';
|
||||
label = getString('Gen_Down');
|
||||
} else if (devPresentLastScan != 1) {
|
||||
css = 'bg-gray text-white statusOffline';
|
||||
cssText = 'text-gray50';
|
||||
icon = '<i class="fa-solid fa-xmark"></i>';
|
||||
status = 'offline';
|
||||
label = getString('Gen_Offline');
|
||||
}
|
||||
|
||||
// New devices keep the online/offline color & icon but show "New" as label
|
||||
if (devIsNew == 1) {
|
||||
label = getString('Gen_New');
|
||||
}
|
||||
|
||||
const cleanedText = statusText.replace(/-/g, '');
|
||||
@@ -776,15 +793,36 @@ function getStatusBadgeParts(devPresentLastScan, devAlertDown, devFlapping, devM
|
||||
|
||||
return {
|
||||
cssClass: css,
|
||||
cssText: cssText,
|
||||
cssText: cssText,
|
||||
iconHtml: icon,
|
||||
mac: devMac,
|
||||
text: cleanedText,
|
||||
status: status,
|
||||
url: url
|
||||
mac: devMac,
|
||||
text: cleanedText,
|
||||
status: status,
|
||||
label: label,
|
||||
url: url
|
||||
};
|
||||
}
|
||||
|
||||
// Convenience wrappers — call getStatusBadgeParts with the right fields
|
||||
// for each object shape used across the codebase.
|
||||
|
||||
// Any object with devXxx field names (API response, cache, SQL DevicesView row,
|
||||
// network-api nodes, network-tree nodeData.data objects)
|
||||
function badgeFromDevice(d) {
|
||||
return getStatusBadgeParts(
|
||||
d.devPresentLastScan, d.devAlertDown, d.devFlapping, d.devMac,
|
||||
'', d.devIsSleeping || 0, d.devIsArchived || 0, d.devIsNew || 0
|
||||
);
|
||||
}
|
||||
|
||||
// hover-box: reads status fields from jQuery data-* attributes on an element
|
||||
function badgeFromDataAttrs($el) {
|
||||
return getStatusBadgeParts(
|
||||
$el.data('present'), $el.data('alertdown'), $el.data('flapping') || 0, $el.data('mac'),
|
||||
'', $el.data('sleeping') || 0, $el.data('archived') || 0, $el.data('isnew') || 0
|
||||
);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Getting the color and css class for device relationships
|
||||
function getRelationshipConf(relType) {
|
||||
@@ -930,14 +968,7 @@ function renderDeviceLink(data, container, useName = false) {
|
||||
}
|
||||
|
||||
// Build and return badge parts
|
||||
const badge = getStatusBadgeParts(
|
||||
device.devPresentLastScan,
|
||||
device.devAlertDown,
|
||||
device.devFlapping,
|
||||
device.devMac,
|
||||
'',
|
||||
device.devIsSleeping || 0
|
||||
);
|
||||
const badge = badgeFromDevice(device);
|
||||
|
||||
// badge class and hover-info class to container
|
||||
$(container)
|
||||
@@ -954,8 +985,10 @@ function renderDeviceLink(data, container, useName = false) {
|
||||
'data-status': device.devStatus,
|
||||
'data-flapping': device.devFlapping,
|
||||
'data-present': device.devPresentLastScan,
|
||||
'data-alert': device.devAlertDown,
|
||||
'data-alertdown': device.devAlertDown,
|
||||
'data-sleeping': device.devIsSleeping || 0,
|
||||
'data-archived': device.devIsArchived || 0,
|
||||
'data-isnew': device.devIsNew || 0,
|
||||
'data-icon': device.devIcon
|
||||
});
|
||||
|
||||
@@ -1024,10 +1057,8 @@ function initHoverNodeInfo() {
|
||||
const lastseen = $el.data('lastseen') || 'Unknown';
|
||||
const firstseen = $el.data('firstseen') || 'Unknown';
|
||||
const relationship = $el.data('relationship') || 'Unknown';
|
||||
const flapping = $el.data('flapping') || 0;
|
||||
const sleeping = $el.data('sleeping') || 0;
|
||||
const badge = getStatusBadgeParts( $el.data('present'), $el.data('alert'), flapping, $el.data('mac'), '', sleeping)
|
||||
const status =`<span class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.status}</span>`
|
||||
const badge = badgeFromDataAttrs($el);
|
||||
const status =`<span class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.label}</span>`
|
||||
|
||||
const html = `
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user