mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-04-15 22:51:37 -07:00
nnetwork and link tweaks
This commit is contained in:
+47
-4
@@ -12,6 +12,7 @@
|
|||||||
----------------------------------------------------------------------------- */
|
----------------------------------------------------------------------------- */
|
||||||
:root {
|
:root {
|
||||||
--color-aqua: #00c0ef;
|
--color-aqua: #00c0ef;
|
||||||
|
--color-lightblue: #3c8dbc;
|
||||||
--color-blue: #0060df;
|
--color-blue: #0060df;
|
||||||
--color-green: #00a65a;
|
--color-green: #00a65a;
|
||||||
--color-yellow: #f39c12;
|
--color-yellow: #f39c12;
|
||||||
@@ -29,6 +30,45 @@ h5
|
|||||||
font-size: medium;
|
font-size: medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a[target="_blank"] {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block; /* Needed for positioning */
|
||||||
|
padding-right: 0.6em; /* Space for the icon */
|
||||||
|
}
|
||||||
|
|
||||||
|
a[target="_blank"]::after {
|
||||||
|
content: '↗';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
font-size: 0.75em;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2 .hover-node-info::after {
|
||||||
|
padding-left: 1px ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .node-standard-device .netNodeText::after
|
||||||
|
{
|
||||||
|
right: -7px;
|
||||||
|
top: 1px;
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* .select2-container--default .select2-selection--multiple .select2-selection__choice
|
||||||
|
{
|
||||||
|
padding-right: 15px !important;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.hoverHighlight
|
||||||
|
{
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
.hoverHighlight:hover
|
||||||
|
{
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Helper Classes
|
Helper Classes
|
||||||
----------------------------------------------------------------------------- */
|
----------------------------------------------------------------------------- */
|
||||||
@@ -49,6 +89,7 @@ h5
|
|||||||
float: inline-end;
|
float: inline-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Text Classes
|
Text Classes
|
||||||
----------------------------------------------------------------------------- */
|
----------------------------------------------------------------------------- */
|
||||||
@@ -480,7 +521,7 @@ body
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bottom-border-primary {
|
.bottom-border-primary {
|
||||||
border-bottom-color: #3c8dbc;
|
border-bottom-color: var(--color-lightblue);
|
||||||
border-bottom-style: solid;
|
border-bottom-style: solid;
|
||||||
border-bottom-width: 3px
|
border-bottom-width: 3px
|
||||||
}
|
}
|
||||||
@@ -1666,7 +1707,7 @@ input[readonly] {
|
|||||||
#toggleFilters
|
#toggleFilters
|
||||||
{
|
{
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: fixed;
|
||||||
padding-left: 32px;
|
padding-left: 32px;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
@@ -1813,8 +1854,8 @@ input[readonly] {
|
|||||||
#networkTree .highlightedNode
|
#networkTree .highlightedNode
|
||||||
{
|
{
|
||||||
/* border: solid; */
|
/* border: solid; */
|
||||||
border-color:#3c8dbc;
|
border-color:var(--color-lightblue);
|
||||||
box-shadow: #3c8dbc 0px 0px 20px;
|
box-shadow: var(--color-lightblue) 0px 0px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#networkTree .netStatus-Off-line i,
|
#networkTree .netStatus-Off-line i,
|
||||||
@@ -1843,6 +1884,8 @@ input[readonly] {
|
|||||||
.networkTable
|
.networkTable
|
||||||
{
|
{
|
||||||
padding-bottom: 1px;
|
padding-bottom: 1px;
|
||||||
|
z-index: 3;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.networkNodeTabHeaders .icon i
|
.networkNodeTabHeaders .icon i
|
||||||
|
|||||||
@@ -651,8 +651,14 @@
|
|||||||
border-color: #888888;
|
border-color: #888888;
|
||||||
}
|
}
|
||||||
.table-hover tbody tr:hover td, .table-hover tbody tr:hover th {
|
.table-hover tbody tr:hover td, .table-hover tbody tr:hover th {
|
||||||
background-color: rgb(189,192,198);
|
background-color: var(--datatable-bgcolor);
|
||||||
color: #444;
|
color: var(--fbc-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.dataTable tbody tr.selected, table.dataTable tbody tr .selected
|
||||||
|
{
|
||||||
|
background-color: var(--datatable-bgcolor);
|
||||||
|
color: var(--fbc-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
.db_info_table_cell:nth-child(1) {background: #272c30}
|
.db_info_table_cell:nth-child(1) {background: #272c30}
|
||||||
|
|||||||
+5
-5
@@ -780,7 +780,9 @@ function initializeDatatable (status) {
|
|||||||
|
|
||||||
// console.log(cellData)
|
// console.log(cellData)
|
||||||
$(td).html (
|
$(td).html (
|
||||||
`<b class="anonymizeDev hover-node-info"
|
`<b class="anonymizeDev "
|
||||||
|
>
|
||||||
|
<a href="deviceDetails.php?mac=${rowData[mapIndx(11)]}" class="hover-node-info"
|
||||||
data-name="${cellData}"
|
data-name="${cellData}"
|
||||||
data-ip="${rowData[mapIndx(8)]}"
|
data-ip="${rowData[mapIndx(8)]}"
|
||||||
data-mac="${rowData[mapIndx(11)]}"
|
data-mac="${rowData[mapIndx(11)]}"
|
||||||
@@ -792,9 +794,7 @@ function initializeDatatable (status) {
|
|||||||
data-status="${rowData[mapIndx(10)]}"
|
data-status="${rowData[mapIndx(10)]}"
|
||||||
data-present="${rowData[mapIndx(24)]}"
|
data-present="${rowData[mapIndx(24)]}"
|
||||||
data-alert="${rowData[mapIndx(25)]}"
|
data-alert="${rowData[mapIndx(25)]}"
|
||||||
data-icon="${rowData[mapIndx(3)]}"
|
data-icon="${rowData[mapIndx(3)]}">
|
||||||
>
|
|
||||||
<a href="deviceDetails.php?mac=${rowData[mapIndx(11)]}" class="">
|
|
||||||
${cellData}
|
${cellData}
|
||||||
</a>
|
</a>
|
||||||
</b>`
|
</b>`
|
||||||
@@ -845,7 +845,7 @@ function initializeDatatable (status) {
|
|||||||
<a href="http://${cellData}" class="pointer" target="_blank">
|
<a href="http://${cellData}" class="pointer" target="_blank">
|
||||||
${cellData}
|
${cellData}
|
||||||
</a>
|
</a>
|
||||||
<span class="alignRight">
|
<span class="alignRight lockIcon">
|
||||||
<a href="https://${cellData}" class="pointer" target="_blank">
|
<a href="https://${cellData}" class="pointer" target="_blank">
|
||||||
<i class="fa fa-lock "></i>
|
<i class="fa fa-lock "></i>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -28,9 +28,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-1">
|
<div class="col-md-1 hoverHighlight">
|
||||||
<i class="fa-solid fa-circle-check" onclick="markAllSelected()" title="<?= lang('Gen_Add_All');?>"></i>
|
<i class="fa-solid fa-circle-check hoverHighlight pointer" onclick="markAllSelected()" title="<?= lang('Gen_Add_All');?>"></i>
|
||||||
<i class="fa-solid fa-circle-xmark" onclick="markAllNotSelected()" title="<?= lang('Gen_Remove_All');?>"></i>
|
<i class="fa-solid fa-circle-xmark hoverHighlight pointer" onclick="markAllNotSelected()" title="<?= lang('Gen_Remove_All');?>"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+82
-38
@@ -170,9 +170,9 @@
|
|||||||
<h5><i class="fa fa-server"></i> ${getString('Network_Node')}</h5>
|
<h5><i class="fa fa-server"></i> ${getString('Network_Node')}</h5>
|
||||||
|
|
||||||
<div class="mb-3 row">
|
<div class="mb-3 row">
|
||||||
<label class="col-sm-3 col-form-label fw-bold">${getString('Network_Node')}</label>
|
<label class="col-sm-3 col-form-label fw-bold">${getString('DevDetail_Tab_Details')}</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<a href="./deviceDetails.php?mac=${node.node_mac}" class="anonymize">${node.node_name}</a>
|
<a href="./deviceDetails.php?mac=${node.node_mac}" target="_blank" class="anonymize">${node.node_name}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@
|
|||||||
<label class="col-sm-3 col-form-label fw-bold">${getString('Network_Parent')}</label>
|
<label class="col-sm-3 col-form-label fw-bold">${getString('Network_Parent')}</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
${isRootNode ? '' : `<a class="anonymize" href="#">`}
|
${isRootNode ? '' : `<a class="anonymize" href="#">`}
|
||||||
<span my-data-mac="${node.parent_mac}" data-mytreemacmain="${node.parent_mac}" onclick="handleNodeClick(this)">
|
<span my-data-mac="${node.parent_mac}" data-mac="${node.parent_mac}" onclick="handleNodeClick(this)">
|
||||||
${isRootNode ? getString('Network_Root') : getNameByMacAddress(node.parent_mac)}
|
${isRootNode ? getString('Network_Root') : getNameByMacAddress(node.parent_mac)}
|
||||||
</span>
|
</span>
|
||||||
${isRootNode ? '' : `</a>`}
|
${isRootNode ? '' : `</a>`}
|
||||||
@@ -208,7 +208,7 @@
|
|||||||
${getString('Network_Connected')}
|
${getString('Network_Connected')}
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
<div id="leafs_${id}"></div>
|
<div id="leafs_${id}" class="table-responsive"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -239,6 +239,30 @@
|
|||||||
const $table = $(`#${tableId}`);
|
const $table = $(`#${tableId}`);
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
|
{
|
||||||
|
title: assignMode ? getString('Network_ManageAssign') : getString('Network_ManageUnassign'),
|
||||||
|
data: 'devMac',
|
||||||
|
orderable: false,
|
||||||
|
width: '5%',
|
||||||
|
render: function (mac) {
|
||||||
|
const label = assignMode ? 'assign' : 'unassign';
|
||||||
|
const btnClass = assignMode ? 'btn-primary' : 'btn-primary bg-red';
|
||||||
|
const btnText = assignMode ? getString('Network_ManageAssign') : getString('Network_ManageUnassign');
|
||||||
|
return `<button class="btn ${btnClass} btn-sm" data-myleafmac="${mac}" onclick="updateLeaf('${mac}','${label}')">
|
||||||
|
${btnText}
|
||||||
|
</button>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: getString('Device_TableHead_Name'),
|
||||||
|
data: 'devName',
|
||||||
|
width: '15%',
|
||||||
|
render: function (name, type, device) {
|
||||||
|
return `<a href="./deviceDetails.php?mac=${device.devMac}" target="_blank">
|
||||||
|
<b class="anonymize">${name || '-'}</b>
|
||||||
|
</a>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: getString('Network_Table_State'),
|
title: getString('Network_Table_State'),
|
||||||
data: 'devStatus',
|
data: 'devStatus',
|
||||||
@@ -252,16 +276,6 @@
|
|||||||
return `<a href="${badge.url}" class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.status}</a>`;
|
return `<a href="${badge.url}" class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.status}</a>`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: getString('Device_TableHead_Name'),
|
|
||||||
data: 'devName',
|
|
||||||
width: '15%',
|
|
||||||
render: function (name, type, device) {
|
|
||||||
return `<a href="./deviceDetails.php?mac=${device.devMac}">
|
|
||||||
<b class="anonymize">${name || '-'}</b>
|
|
||||||
</a>`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: 'MAC',
|
title: 'MAC',
|
||||||
data: 'devMac',
|
data: 'devMac',
|
||||||
@@ -277,20 +291,6 @@
|
|||||||
title: getString('Device_TableHead_Vendor'),
|
title: getString('Device_TableHead_Vendor'),
|
||||||
data: 'devVendor',
|
data: 'devVendor',
|
||||||
width: '20%'
|
width: '20%'
|
||||||
},
|
|
||||||
{
|
|
||||||
title: assignMode ? getString('Network_ManageAssign') : getString('Network_ManageUnassign'),
|
|
||||||
data: 'devMac',
|
|
||||||
orderable: false,
|
|
||||||
width: '5%',
|
|
||||||
render: function (mac) {
|
|
||||||
const label = assignMode ? 'assign' : 'unassign';
|
|
||||||
const btnClass = assignMode ? 'btn-primary' : 'btn-primary bg-red';
|
|
||||||
const btnText = assignMode ? getString('Network_ManageAssign') : getString('Network_ManageUnassign');
|
|
||||||
return `<button class="btn ${btnClass} btn-sm" data-myleafmac="${mac}" onclick="updateLeaf('${mac}','${label}')">
|
|
||||||
${btnText}
|
|
||||||
</button>`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
|
|
||||||
@@ -302,7 +302,10 @@
|
|||||||
order: assignMode ? [[2, 'asc']] : [],
|
order: assignMode ? [[2, 'asc']] : [],
|
||||||
responsive: true,
|
responsive: true,
|
||||||
autoWidth: false,
|
autoWidth: false,
|
||||||
searching: true
|
searching: true,
|
||||||
|
createdRow: function (row, data) {
|
||||||
|
$(row).attr('data-mac', data.devMac);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($.fn.DataTable.isDataTable($table)) {
|
if ($.fn.DataTable.isDataTable($table)) {
|
||||||
@@ -325,7 +328,7 @@
|
|||||||
|
|
||||||
const wrapperHtml = `
|
const wrapperHtml = `
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div id="unassignedDevices" class="box box-aqua box-body">
|
<div id="unassignedDevices" class="box box-aqua box-body table-responsive">
|
||||||
<section>
|
<section>
|
||||||
<h5><i class="fa-solid fa-plug-circle-xmark"></i> ${getString('Network_UnassignedDevices')}</h5>
|
<h5><i class="fa-solid fa-plug-circle-xmark"></i> ${getString('Network_UnassignedDevices')}</h5>
|
||||||
<table id="unassignedDevicesTable" class="table table-striped" width="100%"></table>
|
<table id="unassignedDevicesTable" class="table table-striped" width="100%"></table>
|
||||||
@@ -589,23 +592,63 @@ function attachTreeEvents()
|
|||||||
// Handle network node click - select correct tab in the bottom table
|
// Handle network node click - select correct tab in the bottom table
|
||||||
function handleNodeClick(el)
|
function handleNodeClick(el)
|
||||||
{
|
{
|
||||||
const targetTabMAC = $(el).attr("data-mytreemacmain");
|
|
||||||
|
|
||||||
// handle network node
|
isNetworkDevice = $(el).data("devisnetworknodedynamic") == 1;
|
||||||
|
targetTabMAC = ""
|
||||||
|
thisDevMac= $(el).data("mac");
|
||||||
|
|
||||||
|
if (isNetworkDevice == false)
|
||||||
|
{
|
||||||
|
targetTabMAC = $(el).data("parentmac");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
targetTabMAC = thisDevMac;
|
||||||
|
}
|
||||||
|
|
||||||
var targetTab = $(`a[data-mytabmac="${targetTabMAC}"]`);
|
var targetTab = $(`a[data-mytabmac="${targetTabMAC}"]`);
|
||||||
|
|
||||||
if (targetTab.length) {
|
if (targetTab.length) {
|
||||||
// Simulate a click event on the target tab
|
// Simulate a click event on the target tab
|
||||||
targetTab.click();
|
targetTab.click();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNetworkDevice) {
|
||||||
// Smooth scroll to the tab content
|
// Smooth scroll to the tab content
|
||||||
$('html, body').animate({
|
$('html, body').animate({
|
||||||
scrollTop: targetTab.offset().top - 50
|
scrollTop: targetTab.offset().top - 50
|
||||||
}, 500); // Adjust the duration as needed
|
}, 500); // Adjust the duration as needed
|
||||||
} else
|
} else {
|
||||||
{
|
$("tr.selected").removeClass("selected");
|
||||||
// handle regular device - open in new tab
|
$(`tr[data-mac="${thisDevMac}"]`).addClass("selected");
|
||||||
goToDevice($(el).data("mac"), true)
|
|
||||||
|
const tableId = "table_leafs_" + targetTabMAC.replace(/:/g, '_');
|
||||||
|
const $table = $(`#${tableId}`).DataTable();
|
||||||
|
|
||||||
|
// Find the row index (in the full data set) that matches
|
||||||
|
const rowIndex = $table
|
||||||
|
.rows()
|
||||||
|
.eq(0)
|
||||||
|
.filter(function(idx) {
|
||||||
|
return $table.row(idx).node().getAttribute("data-mac") === thisDevMac;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (rowIndex.length > 0) {
|
||||||
|
// Change to the page where this row is
|
||||||
|
$table.page(Math.floor(rowIndex[0] / $table.page.len())).draw(false);
|
||||||
|
|
||||||
|
// Delay needed so the row is in the DOM after page draw
|
||||||
|
setTimeout(() => {
|
||||||
|
const rowNode = $table.row(rowIndex[0]).node();
|
||||||
|
$(rowNode).addClass("selected");
|
||||||
|
|
||||||
|
// Smooth scroll to the row
|
||||||
|
$('html, body').animate({
|
||||||
|
scrollTop: $(rowNode).offset().top - 50
|
||||||
|
}, 500);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,7 +755,8 @@ function initTree(myHierarchy)
|
|||||||
class="node-inner hover-node-info box pointer ${highlightedCss} ${cssNodeType}"
|
class="node-inner hover-node-info box pointer ${highlightedCss} ${cssNodeType}"
|
||||||
style="height:${nodeHeightPx}px;font-size:${nodeHeightPx-5}px;"
|
style="height:${nodeHeightPx}px;font-size:${nodeHeightPx-5}px;"
|
||||||
onclick="handleNodeClick(this)"
|
onclick="handleNodeClick(this)"
|
||||||
data-mytreemacmain="${nodeData.data.mac}"
|
data-mac="${nodeData.data.mac}"
|
||||||
|
data-parentMac="${nodeData.data.parentMac}"
|
||||||
data-name="${nodeData.data.name}"
|
data-name="${nodeData.data.name}"
|
||||||
data-ip="${nodeData.data.ip}"
|
data-ip="${nodeData.data.ip}"
|
||||||
data-mac="${nodeData.data.mac}"
|
data-mac="${nodeData.data.mac}"
|
||||||
@@ -818,7 +862,7 @@ function initSelectedNodeHighlighting()
|
|||||||
$(selNode).attr('class', $(selNode).attr('class').replace('highlightedNode'))
|
$(selNode).attr('class', $(selNode).attr('class').replace('highlightedNode'))
|
||||||
}
|
}
|
||||||
|
|
||||||
newSelNode = $("#networkTree div[data-mytreemacmain='"+currentNodeMac+"']")[0]
|
newSelNode = $("#networkTree div[data-mac='"+currentNodeMac+"']")[0]
|
||||||
|
|
||||||
console.log(newSelNode)
|
console.log(newSelNode)
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
"DevDetail_Network_Node_hover": "Select the parent network device the current device is connected to, to populate the Network tree.",
|
"DevDetail_Network_Node_hover": "Select the parent network device the current device is connected to, to populate the Network tree.",
|
||||||
"DevDetail_Network_Port_hover": "The port this device is connected to on the parent network device. If left empty a wifi icon is displayed in the Network tree.",
|
"DevDetail_Network_Port_hover": "The port this device is connected to on the parent network device. If left empty a wifi icon is displayed in the Network tree.",
|
||||||
"DevDetail_Nmap_Scans": "Manual Nmap Scans",
|
"DevDetail_Nmap_Scans": "Manual Nmap Scans",
|
||||||
"DevDetail_Nmap_Scans_desc": "Here you can execute manual NMAP scans. You can also schedule regular automatic NMAP scans via the Services & Ports (NMAP) plugin. Head to <a href='/settings.php' target='_blank'>Settings</a> to find out more",
|
"DevDetail_Nmap_Scans_desc": "Here you can execute manual NMAP scans. You can also schedule regular automatic NMAP scans via the Services & Ports (NMAP) plugin. Head to <a href=\"/settings.php\" target=\"_blank\">Settings</a> to find out more",
|
||||||
"DevDetail_Nmap_buttonDefault": "Default Scan",
|
"DevDetail_Nmap_buttonDefault": "Default Scan",
|
||||||
"DevDetail_Nmap_buttonDefault_text": "Default Scan: Nmap scans the top 1,000 ports for each scan protocol requested. This catches roughly 93% of the TCP ports and 49% of the UDP ports. (about 5 seconds)",
|
"DevDetail_Nmap_buttonDefault_text": "Default Scan: Nmap scans the top 1,000 ports for each scan protocol requested. This catches roughly 93% of the TCP ports and 49% of the UDP ports. (about 5 seconds)",
|
||||||
"DevDetail_Nmap_buttonDetail": "Detailed Scan",
|
"DevDetail_Nmap_buttonDetail": "Detailed Scan",
|
||||||
|
|||||||
Regular → Executable
Reference in New Issue
Block a user