devParentNodeMac chips in devices list

This commit is contained in:
jokob-sk
2025-08-05 20:54:28 +10:00
parent f25c012fbe
commit 101189ae7c
4 changed files with 113 additions and 72 deletions
+18 -1
View File
@@ -1489,7 +1489,7 @@ input[readonly] {
} }
#tableDevicesBox td svg, #tableDevicesBox td i{ #tableDevicesBox td svg, #tableDevicesBox td i{
height: 1.5em !important; height: 1em !important;
} }
#TileCards .tile .inner #TileCards .tile .inner
@@ -1649,6 +1649,23 @@ input[readonly] {
pointer-events: none; pointer-events: none;
} }
.custom-badge a
{
color: #fff !important;
font-size: 14px;
}
.custom-badge
{
border: 1px solid #aaa;
border-radius: 4px;
border-style: solid;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px;
font-size: 14px;
display: inline-block;
}
#deviceDetailsEdit .form-control #deviceDetailsEdit .form-control
{ {
min-height: 42px; min-height: 42px;
+52 -30
View File
@@ -503,36 +503,36 @@ function collectFilters() {
function mapColumnIndexToFieldName(index, tableColumnVisible) { function mapColumnIndexToFieldName(index, tableColumnVisible) {
// the order is important, don't change it! // the order is important, don't change it!
const columnNames = [ const columnNames = [
"devName", "devName", // 0
"devOwner", "devOwner", // 1
"devType", "devType", // 2
"devIcon", "devIcon", // 3
"devFavorite", "devFavorite", // 4
"devGroup", "devGroup", // 5
"devFirstConnection", "devFirstConnection", // 6
"devLastConnection", "devLastConnection", // 7
"devLastIP", "devLastIP", // 8
"devIsRandomMac", // resolved on the fly "devIsRandomMac", // 9 resolved on the fly
"devStatus", // resolved on the fly "devStatus", // 10 resolved on the fly
"devMac", "devMac", // 11
"devIpLong", //formatIPlong(device.devLastIP) || "", // IP orderable "devIpLong", // 12 formatIPlong(device.devLastIP) || "", // IP orderable
"rowid", "rowid", // 13
"devParentMAC", "devParentMAC", // 14
"devParentChildrenCount", // resolved on the fly "devParentChildrenCount", // 15 resolved on the fly
"devLocation", "devLocation", // 16
"devVendor", "devVendor", // 17
"devParentPort", "devParentPort", // 18
"devGUID", "devGUID", // 19
"devSyncHubNode", "devSyncHubNode", // 20
"devSite", "devSite", // 21
"devSSID", "devSSID", // 22
"devSourcePlugin", "devSourcePlugin", // 23
"devPresentLastScan", "devPresentLastScan", // 24
"devAlertDown", "devAlertDown", // 25
"devCustomProps", "devCustomProps", // 26
"devFQDN", "devFQDN", // 27
"devParentRelType", "devParentRelType", // 28
"devReqNicsOnline" "devReqNicsOnline" // 29
]; ];
// console.log("OrderBy: " + columnNames[tableColumnOrder[index]]); // console.log("OrderBy: " + columnNames[tableColumnOrder[index]]);
@@ -899,6 +899,28 @@ function initializeDatatable (status) {
} }
} }, } },
// Parent Mac
{targets: [mapIndx(14)],
'createdCell': function (td, cellData, rowData, row, col) {
if (!cellData) {
$(td).html('');
return;
}
const data = {
id: cellData, // MAC address
text: cellData // Optional display text (you could use a name or something else)
};
spanWrap = $(`<span class="custom-badge text-white"></span>`)
$(td).html(spanWrap);
const chipHtml = renderDeviceLink(data, spanWrap, true); // pass the td as container
$(spanWrap).append(chipHtml);
}
},
// Status color // Status color
{targets: [mapIndx(10)], {targets: [mapIndx(10)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
+43 -39
View File
@@ -715,45 +715,7 @@ function initSelect2() {
{ {
var selectEl = $(this).select2({ var selectEl = $(this).select2({
templateSelection: function (data, container) { templateSelection: function (data, container) {
if (!data.id) return data.text; // default for placeholder etc. return $(renderDeviceLink(data, container));
const device = getDevDataByMac(data.id);
const badge = getStatusBadgeParts(
device.devPresentLastScan,
device.devAlertDown,
device.devMac
)
$(container).addClass(badge.cssClass);
// Custom HTML
const html = $(`
<a href="${badge.url}" target="_blank">
<span class="custom-chip hover-node-info"
data-name="${device.devName}"
data-ip="${device.devLastIP}"
data-mac="${device.devMac}"
data-vendor="${device.devVendor}"
data-type="${device.devType}"
data-lastseen="${device.devLastConnection}"
data-firstseen="${device.devFirstConnection}"
data-relationship="${device.devParentRelType}"
data-status="${device.devStatus}"
data-present="${device.devPresentLastScan}"
data-alert="${device.devAlertDown}"
data-icon="${device.devIcon}"
>
<span class="iconPreview">${atob(device.devIcon)}</span>
${data.text}
<span>
(${badge.iconHtml})
</span
</span>
</a>
`);
return html;
}, },
escapeMarkup: function (m) { escapeMarkup: function (m) {
return m; // Allow HTML return m; // Allow HTML
@@ -817,6 +779,48 @@ function initSelect2() {
} }
} }
// ------------------------------------------
// Render a device link with hover-over functionality
function renderDeviceLink(data, container, useName=false) {
if (!data.id) return data.text; // default placeholder etc.
const device = getDevDataByMac(data.id);
const badge = getStatusBadgeParts(
device.devPresentLastScan,
device.devAlertDown,
device.devMac
);
$(container).addClass(badge.cssClass);
return `
<a href="${badge.url}" target="_blank">
<span class="custom-chip hover-node-info"
data-name="${device.devName}"
data-ip="${device.devLastIP}"
data-mac="${device.devMac}"
data-vendor="${device.devVendor}"
data-type="${device.devType}"
data-lastseen="${device.devLastConnection}"
data-firstseen="${device.devFirstConnection}"
data-relationship="${device.devParentRelType}"
data-status="${device.devStatus}"
data-present="${device.devPresentLastScan}"
data-alert="${device.devAlertDown}"
data-icon="${device.devIcon}"
>
<span class="iconPreview">${atob(device.devIcon)}</span>
${useName ? device.devName : data.text}
<span>
(${badge.iconHtml})
</span>
</span>
</a>
`;
}
// ------------------------------------------ // ------------------------------------------
// Display device info on hover (attach only once) // Display device info on hover (attach only once)
function initHoverNodeInfo() { function initHoverNodeInfo() {
-2
View File
@@ -264,8 +264,6 @@ function fetchUsedIps(callback) {
function renderAvailableIpsTable(allIps, usedIps) { function renderAvailableIpsTable(allIps, usedIps) {
const availableIps = allIps.filter(row => !usedIps.includes(row.ip)); const availableIps = allIps.filter(row => !usedIps.includes(row.ip));
console.log(allIps);
console.log(usedIps);
console.log(availableIps); console.log(availableIps);
$('#availableIpsTable').DataTable({ $('#availableIpsTable').DataTable({