mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
refactor, tab async loading on focus
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
<span class="helpIcon">
|
||||||
|
<a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/WORKFLOWS_DEBUGGING.md">
|
||||||
|
<i class="fa fa-circle-question"></i>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
<section class="content">
|
<section class="content">
|
||||||
<div class="nav-tabs-custom app-event-content" style="margin-bottom: 0px;">
|
<div class="nav-tabs-custom app-event-content" style="margin-bottom: 0px;">
|
||||||
<ul id="tabs-location" class="nav nav-tabs col-sm-2 hidden">
|
<ul id="tabs-location" class="nav nav-tabs col-sm-2 hidden">
|
||||||
|
|||||||
@@ -2090,36 +2090,45 @@ input[readonly] {
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Spin
|
Spin
|
||||||
----------------------------------------------------------------------------- */
|
----------------------------------------------------------------------------- */
|
||||||
|
#loadingSpinner {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1000;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease-in-out;
|
||||||
|
pointer-events: none;
|
||||||
|
display: block;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loadingSpinner.visible {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.pa_semitransparent-panel {
|
.pa_semitransparent-panel {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%; /*calc (100% -40px);*/
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
opacity: 0.8;
|
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
z-index: 800;
|
opacity: 0.8;
|
||||||
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pa_spinner {
|
.pa_spinner {
|
||||||
position: fixed;
|
position: absolute;
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: 100px;
|
top: 100px;
|
||||||
margin-left: auto;
|
left: 50%;
|
||||||
margin-right: auto;
|
transform: translateX(-50%);
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
z-index: 801;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#loadingSpinner
|
|
||||||
{
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Multi-edit adjustements */
|
/* Multi-edit adjustements */
|
||||||
.box-header
|
.box-header
|
||||||
|
|||||||
@@ -10,6 +10,16 @@
|
|||||||
*
|
*
|
||||||
* Additional fixes For Pi.Alert UI by leiweibau */
|
* Additional fixes For Pi.Alert UI by leiweibau */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--color-aqua: #00c0ef;
|
||||||
|
--color-lightblue: #3c8dbc;
|
||||||
|
--color-blue: #0060df;
|
||||||
|
--color-green: #00a65a;
|
||||||
|
--color-yellow: #f39c12;
|
||||||
|
--color-red: #dd4b39;
|
||||||
|
--color-gray: #8c8c8c;
|
||||||
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--datatable-bgcolor: rgba(64, 76, 88, 0.8);
|
--datatable-bgcolor: rgba(64, 76, 88, 0.8);
|
||||||
}
|
}
|
||||||
@@ -770,4 +780,9 @@ input[type="password"]::-webkit-caps-lock-indicator {
|
|||||||
.thresholdFormControl
|
.thresholdFormControl
|
||||||
{
|
{
|
||||||
color:#000;
|
color:#000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover
|
||||||
|
{
|
||||||
|
color: var(--color-gray);
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,16 @@
|
|||||||
* Additional fixes For Pi.Alert UI by leiweibau */
|
* Additional fixes For Pi.Alert UI by leiweibau */
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--color-aqua: #00c0ef;
|
||||||
|
--color-lightblue: #3c8dbc;
|
||||||
|
--color-blue: #0060df;
|
||||||
|
--color-green: #00a65a;
|
||||||
|
--color-yellow: #f39c12;
|
||||||
|
--color-red: #dd4b39;
|
||||||
|
--color-gray: #8c8c8c;
|
||||||
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--datatable-bgcolor: rgba(64, 76, 88, 0.8);
|
--datatable-bgcolor: rgba(64, 76, 88, 0.8);
|
||||||
@@ -781,3 +791,7 @@
|
|||||||
color:#000;
|
color:#000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn:hover
|
||||||
|
{
|
||||||
|
color: var(--color-gray);
|
||||||
|
}
|
||||||
@@ -16,8 +16,9 @@
|
|||||||
require 'php/templates/header.php';
|
require 'php/templates/header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
showSpinner();
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- Page ------------------------------------------------------------------ -->
|
<!-- Page ------------------------------------------------------------------ -->
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
@@ -125,15 +126,11 @@
|
|||||||
<div class="tab-content" style="min-height: 430px;">
|
<div class="tab-content" style="min-height: 430px;">
|
||||||
|
|
||||||
<!-- tab page 1 ------------------------------------------------------------ -->
|
<!-- tab page 1 ------------------------------------------------------------ -->
|
||||||
<!--
|
|
||||||
<div class="tab-pane fade in active" id="panDetails">
|
|
||||||
-->
|
|
||||||
<div class="tab-pane fade" id="panDetails">
|
|
||||||
|
|
||||||
|
<div class="tab-pane fade" id="panDetails">
|
||||||
<?php
|
<?php
|
||||||
require 'deviceDetailsEdit.php';
|
require 'deviceDetailsEdit.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- tab page 2 ------------------------------------------------------------ -->
|
<!-- tab page 2 ------------------------------------------------------------ -->
|
||||||
@@ -141,51 +138,38 @@
|
|||||||
<?php
|
<?php
|
||||||
require 'deviceDetailsSessions.php';
|
require 'deviceDetailsSessions.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- tab page "Tools" ------------------------------------------------------------ -->
|
<!-- tab page "Tools" ------------------------------------------------------------ -->
|
||||||
|
|
||||||
<div class="tab-pane fade" id="panTools">
|
<div class="tab-pane fade" id="panTools">
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
require 'deviceDetailsTools.php';
|
require 'deviceDetailsTools.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- tab page 3 ------------------------------------------------------------ -->
|
<!-- tab page 3 ------------------------------------------------------------ -->
|
||||||
<div class="tab-pane fade table-responsive" id="panPresence">
|
<div class="tab-pane fade table-responsive" id="panPresence">
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// Include the other page
|
// Include the other page
|
||||||
include 'deviceDetailsPresence.php';
|
include 'deviceDetailsPresence.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- tab page 4 ------------------------------------------------------------ -->
|
<!-- tab page 4 ------------------------------------------------------------ -->
|
||||||
<div class="tab-pane fade table-responsive" id="panEvents">
|
<div class="tab-pane fade table-responsive" id="panEvents">
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// Include the other page
|
// Include the other page
|
||||||
include 'deviceDetailsEvents.php';
|
include 'deviceDetailsEvents.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- tab page 7 ------------------------------------------------------------ -->
|
<!-- tab page 7 ------------------------------------------------------------ -->
|
||||||
<div class="tab-pane fade table-responsive" id="panPlugins">
|
<div class="tab-pane fade table-responsive" id="panPlugins">
|
||||||
|
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// Include the other page
|
// Include the other page
|
||||||
include 'pluginsCore.php';
|
include 'pluginsCore.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -273,7 +257,7 @@ function main () {
|
|||||||
period = '1 day';
|
period = '1 day';
|
||||||
sessionsRows = 50;
|
sessionsRows = 50;
|
||||||
eventsRows = 50;
|
eventsRows = 50;
|
||||||
$('#chkHideConnectionEvents')[0].checked = eval(eventsHide == 'true');
|
// $('#chkHideConnectionEvents')[0].checked = eval(eventsHide == 'true');
|
||||||
|
|
||||||
// Initialize components with parameters
|
// Initialize components with parameters
|
||||||
|
|
||||||
@@ -282,26 +266,7 @@ function main () {
|
|||||||
$( document ).ready(function() {
|
$( document ).ready(function() {
|
||||||
initializeTabs();
|
initializeTabs();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // Events tab toggle conenction events
|
|
||||||
// $('input').on('ifToggled', function(event){
|
|
||||||
// // Hide / Show Events
|
|
||||||
// if (event.currentTarget.id == 'chkHideConnectionEvents') {
|
|
||||||
// getDeviceEvents();
|
|
||||||
// } else {
|
|
||||||
// // Activate save & restore
|
|
||||||
// // activateSaveRestoreData();
|
|
||||||
|
|
||||||
// // Ask skip notifications
|
|
||||||
// // if (event.currentTarget.id == 'chkArchived' ) {
|
|
||||||
// // askSkipNotifications();
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -328,6 +293,48 @@ function recordSwitch(direction) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// Handle previous/next arrows/chevrons
|
||||||
|
function updateChevrons(currentMac) {
|
||||||
|
const devicesList = getDevicesList();
|
||||||
|
|
||||||
|
// Find the index of the device by MAC
|
||||||
|
pos = devicesList.findIndex(item => item.devMac == currentMac);
|
||||||
|
|
||||||
|
// If device not found, optionally add it or handle error
|
||||||
|
if (pos === -1) {
|
||||||
|
// If you want to add a placeholder or handle missing device:
|
||||||
|
// devicesList.push({ mac: currentMac, name: 'Unknown', type: 'Unknown' });
|
||||||
|
// pos = devicesList.length - 1;
|
||||||
|
|
||||||
|
// Or just return early if device not found
|
||||||
|
console.warn('Device with MAC not found:', currentMac);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the record number display
|
||||||
|
$('#txtRecord').html((pos + 1) + ' / ' + devicesList.length);
|
||||||
|
|
||||||
|
// Enable/disable previous button
|
||||||
|
if (pos <= 0) {
|
||||||
|
$('#btnPrevious').attr('disabled', '');
|
||||||
|
$('#btnPrevious').addClass('text-gray50');
|
||||||
|
} else {
|
||||||
|
$('#btnPrevious').removeAttr('disabled');
|
||||||
|
$('#btnPrevious').removeClass('text-gray50');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable/disable next button
|
||||||
|
if (pos >= devicesList.length - 1) {
|
||||||
|
$('#btnNext').attr('disabled', '');
|
||||||
|
$('#btnNext').addClass('text-gray50');
|
||||||
|
} else {
|
||||||
|
$('#btnNext').removeAttr('disabled');
|
||||||
|
$('#btnNext').removeClass('text-gray50');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
function performSwitch(direction)
|
function performSwitch(direction)
|
||||||
@@ -338,7 +345,9 @@ function performSwitch(direction)
|
|||||||
|
|
||||||
// Update the global position in the devices list variable 'pos'
|
// Update the global position in the devices list variable 'pos'
|
||||||
if (direction === "next") {
|
if (direction === "next") {
|
||||||
if (pos < devicesList.length - 1) {
|
console.log("direction" + direction);
|
||||||
|
|
||||||
|
if (pos < devicesList.length) {
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
} else if (direction === "prev") {
|
} else if (direction === "prev") {
|
||||||
@@ -358,15 +367,12 @@ function performSwitch(direction)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Activate save & restore on any value change
|
// Activate save & restore on any value change
|
||||||
$(document).on('input', 'input:text', function() {
|
$(document).on('input', 'input:text', function() {
|
||||||
settingsChanged();
|
settingsChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
function initializeTabs () {
|
function initializeTabs () {
|
||||||
@@ -380,8 +386,6 @@ function initializeTabs () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$('.nav-tabs a[id='+ selectedTab +']').tab('show');
|
$('.nav-tabs a[id='+ selectedTab +']').tab('show');
|
||||||
// $('.nav-tabs a[id='+ selectedTab +']').parent().click();
|
|
||||||
// $('.nav-tabs a[id="tabPlugins"]').tab('show');
|
|
||||||
|
|
||||||
// When changed save new current tab
|
// When changed save new current tab
|
||||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||||
@@ -391,11 +395,6 @@ function initializeTabs () {
|
|||||||
// events on tab change
|
// events on tab change
|
||||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||||
var target = $(e.target).attr("href") // activated tab
|
var target = $(e.target).attr("href") // activated tab
|
||||||
|
|
||||||
// if(target == "#panTools")
|
|
||||||
// {
|
|
||||||
// // loadTools();
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,22 +481,41 @@ async function renderSmallBoxes() {
|
|||||||
console.error('Error in renderSmallBoxes:', error);
|
console.error('Error in renderSmallBoxes:', error);
|
||||||
} finally {
|
} finally {
|
||||||
// Hide loading dialog
|
// Hide loading dialog
|
||||||
hideSpinner();
|
// hideSpinner();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateDevicePageName(mac) {
|
||||||
|
|
||||||
|
name = getDevDataByMac(mac, "devName")
|
||||||
|
owner = getDevDataByMac(mac, "devOwner")
|
||||||
|
|
||||||
|
// Page title - Name
|
||||||
|
if (mac == "new") {
|
||||||
|
$('#pageTitle').html(`<i title="${getString("Gen_create_new_device")}" class="fa fa-square-plus"></i> ` + getString("Gen_create_new_device"));
|
||||||
|
$('#devicePageInfoPlc .inner').html(`<i class="fa fa-circle-info"></i> ` + getString("Gen_create_new_device_info"));
|
||||||
|
$('#devicePageInfoPlc').show();
|
||||||
|
} else if (owner == null || owner == '' ||
|
||||||
|
(name.toString()).indexOf(owner) != -1) {
|
||||||
|
$('#pageTitle').html(name);
|
||||||
|
$('#devicePageInfoPlc').hide();
|
||||||
|
} else {
|
||||||
|
$('#pageTitle').html(name + ' (' + owner + ')');
|
||||||
|
$('#devicePageInfoPlc').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
window.onload = function async()
|
window.onload = function async()
|
||||||
{
|
{
|
||||||
initializeTabs();
|
initializeTabs();
|
||||||
|
updateChevrons(mac);
|
||||||
|
updateDevicePageName(mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Get plugin and settings data from API endpoints
|
// Get plugin and settings data from API endpoints
|
||||||
function getDeviceData(readAllData){
|
function getDeviceData(){
|
||||||
|
|
||||||
mac = getMac()
|
mac = getMac()
|
||||||
|
|
||||||
@@ -53,13 +53,13 @@
|
|||||||
|
|
||||||
var deviceData = JSON.parse(data);
|
var deviceData = JSON.parse(data);
|
||||||
|
|
||||||
// Deactivate next previous buttons
|
// // Deactivate next previous buttons
|
||||||
if (readAllData) {
|
// if (readAllData) {
|
||||||
$('#btnPrevious').attr ('disabled','');
|
// $('#btnPrevious').attr ('disabled','');
|
||||||
$('#btnPrevious').addClass ('text-gray50');
|
// $('#btnPrevious').addClass ('text-gray50');
|
||||||
$('#btnNext').attr ('disabled','');
|
// $('#btnNext').attr ('disabled','');
|
||||||
$('#btnNext').addClass ('text-gray50');
|
// $('#btnNext').addClass ('text-gray50');
|
||||||
}
|
// }
|
||||||
|
|
||||||
// some race condition, need to implement delay
|
// some race condition, need to implement delay
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -255,30 +255,13 @@
|
|||||||
updateAllIconPreviews();
|
updateAllIconPreviews();
|
||||||
|
|
||||||
// update readonly fields
|
// update readonly fields
|
||||||
handleReadOnly(settingsData, disabledFields);
|
handleReadOnly(settingsData, disabledFields);
|
||||||
|
|
||||||
// Page title - Name
|
|
||||||
if (mac == "new") {
|
|
||||||
$('#pageTitle').html(`<i title="${getString("Gen_create_new_device")}" class="fa fa-square-plus"></i> ` + getString("Gen_create_new_device"));
|
|
||||||
$('#devicePageInfoPlc .inner').html(`<i class="fa fa-circle-info"></i> ` + getString("Gen_create_new_device_info"));
|
|
||||||
$('#devicePageInfoPlc').show();
|
|
||||||
} else if (deviceData['devOwner'] == null || deviceData['devOwner'] == '' ||
|
|
||||||
(deviceData['devName'].toString()).indexOf(deviceData['devOwner']) != -1) {
|
|
||||||
$('#pageTitle').html(deviceData['devName']);
|
|
||||||
$('#devicePageInfoPlc').hide();
|
|
||||||
} else {
|
|
||||||
$('#pageTitle').html(deviceData['devName'] + ' (' + deviceData['devOwner'] + ')');
|
|
||||||
$('#devicePageInfoPlc').hide();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// console.log(relevantSettings)
|
// console.log(relevantSettings)
|
||||||
|
|
||||||
generateSimpleForm(relevantSettings);
|
generateSimpleForm(relevantSettings);
|
||||||
|
|
||||||
// <> chevrons
|
|
||||||
updateChevrons(deviceData)
|
|
||||||
|
|
||||||
toggleNetworkConfiguration(mac == 'Internet')
|
toggleNetworkConfiguration(mac == 'Internet')
|
||||||
|
|
||||||
initSelect2();
|
initSelect2();
|
||||||
@@ -294,46 +277,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------
|
|
||||||
// Handle previous/next arrows/chevrons
|
|
||||||
function updateChevrons(deviceData) {
|
|
||||||
|
|
||||||
devicesList = getDevicesList();
|
|
||||||
|
|
||||||
// console.log(devicesList);
|
|
||||||
|
|
||||||
// Check if device is part of the devicesList
|
|
||||||
pos = devicesList.findIndex(item => item.rowid == deviceData['rowid']);
|
|
||||||
|
|
||||||
// console.log(pos);
|
|
||||||
|
|
||||||
if (pos == -1) {
|
|
||||||
devicesList.push({"rowid" : deviceData['rowid'], "mac" : deviceData['devMac'], "name": deviceData['devName'], "type": deviceData['devType']});
|
|
||||||
pos=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record number
|
|
||||||
$('#txtRecord').html (pos+1 +' / '+ devicesList.length);
|
|
||||||
|
|
||||||
// Deactivate previous button
|
|
||||||
if (pos <= 0) {
|
|
||||||
$('#btnPrevious').attr ('disabled','');
|
|
||||||
$('#btnPrevious').addClass ('text-gray50');
|
|
||||||
} else {
|
|
||||||
$('#btnPrevious').removeAttr ('disabled');
|
|
||||||
$('#btnPrevious').removeClass ('text-gray50');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deactivate next button
|
|
||||||
if (pos >= (devicesList.length-1)) {
|
|
||||||
$('#btnNext').attr ('disabled','');
|
|
||||||
$('#btnNext').addClass ('text-gray50');
|
|
||||||
} else {
|
|
||||||
$('#btnNext').removeAttr ('disabled');
|
|
||||||
$('#btnNext').removeClass ('text-gray50');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// Handle the read-only fields
|
// Handle the read-only fields
|
||||||
function handleReadOnly(settingsData, disabledFields) {
|
function handleReadOnly(settingsData, disabledFields) {
|
||||||
@@ -451,9 +394,47 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------
|
||||||
|
// INIT with polling for panel element visibility
|
||||||
|
// -----------------------------------------------
|
||||||
|
|
||||||
|
var deviceDetailsPageInitialized = false;
|
||||||
|
|
||||||
|
function initdeviceDetailsPage()
|
||||||
|
{
|
||||||
|
// Only proceed if .plugin-content is visible
|
||||||
|
if (!$('#panDetails:visible').length) {
|
||||||
|
return; // exit early if nothing is visible
|
||||||
|
}
|
||||||
|
|
||||||
|
// init page once
|
||||||
|
if (deviceDetailsPageInitialized) return; // ENSURE ONCE
|
||||||
|
deviceDetailsPageInitialized = true;
|
||||||
|
|
||||||
|
showSpinner();
|
||||||
|
|
||||||
|
getDeviceData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Recurring function to monitor the URL and reinitialize if needed
|
||||||
|
function deviceDetailsPageUpdater() {
|
||||||
|
initdeviceDetailsPage();
|
||||||
|
|
||||||
|
// Run updater again after delay
|
||||||
|
setTimeout(deviceDetailsPageUpdater, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if visible, load immediately, if not start updater
|
||||||
|
if (!$('#panDetails:visible').length) {
|
||||||
|
deviceDetailsPageUpdater();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getDeviceData();
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------- INIT ------------------------
|
|
||||||
getDeviceData(true);
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -29,10 +29,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
var eventsRows = 10;
|
|
||||||
var eventsHide = true;
|
|
||||||
var parEventsRows = 'Front_Details_Events_Rows';
|
|
||||||
var parEventsHide = 'Front_Details_Events_Hide';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -41,6 +38,8 @@ function loadEventsData() {
|
|||||||
const hideConnections = $('#chkHideConnectionEvents')[0].checked;
|
const hideConnections = $('#chkHideConnectionEvents')[0].checked;
|
||||||
const hideConnectionsStr = hideConnections ? 'true' : 'false';
|
const hideConnectionsStr = hideConnections ? 'true' : 'false';
|
||||||
|
|
||||||
|
mac = getMac()
|
||||||
|
|
||||||
const rawSql = `
|
const rawSql = `
|
||||||
SELECT eve_DateTime, eve_EventType, eve_IP, eve_AdditionalInfo
|
SELECT eve_DateTime, eve_EventType, eve_IP, eve_AdditionalInfo
|
||||||
FROM Events
|
FROM Events
|
||||||
@@ -56,8 +55,6 @@ function loadEventsData() {
|
|||||||
// Manually load the data first
|
// Manually load the data first
|
||||||
$.get(apiUrl, function (data) {
|
$.get(apiUrl, function (data) {
|
||||||
const parsed = JSON.parse(data);
|
const parsed = JSON.parse(data);
|
||||||
|
|
||||||
console.log(parsed);
|
|
||||||
|
|
||||||
const rows = parsed.map(row => {
|
const rows = parsed.map(row => {
|
||||||
const rawDate = row.eve_DateTime;
|
const rawDate = row.eve_DateTime;
|
||||||
@@ -70,62 +67,94 @@ function loadEventsData() {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(rows);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Fill the table manually
|
// Fill the table manually
|
||||||
const table = $('#tableEvents').DataTable();
|
const table = $('#tableEvents').DataTable();
|
||||||
table.clear();
|
table.clear();
|
||||||
table.rows.add(rows); // assuming each row is an array
|
table.rows.add(rows); // assuming each row is an array
|
||||||
table.draw();
|
table.draw();
|
||||||
|
|
||||||
|
hideSpinner();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializeSessionsDatatable () {
|
function initializeEventsDatatable (eventsRows) {
|
||||||
|
|
||||||
|
if ($.fn.dataTable.isDataTable('#tableEvents')) {
|
||||||
|
$('#tableEvents').DataTable().clear().destroy();
|
||||||
|
}
|
||||||
|
|
||||||
// Events datatable
|
|
||||||
$('#tableEvents').DataTable({
|
$('#tableEvents').DataTable({
|
||||||
'paging' : true,
|
'paging' : true,
|
||||||
'lengthChange': true,
|
'lengthChange': true,
|
||||||
'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'All']],
|
'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'All']],
|
||||||
'searching' : true,
|
'searching' : true,
|
||||||
'ordering' : true,
|
'ordering' : true,
|
||||||
'info' : true,
|
'info' : true,
|
||||||
'autoWidth' : false,
|
'autoWidth' : false,
|
||||||
'order' : [[0,'desc']],
|
'order' : [[0,'desc']],
|
||||||
|
'pageLength' : eventsRows,
|
||||||
|
|
||||||
// Parameters
|
'columnDefs' : [
|
||||||
'pageLength' : eventsRows,
|
{
|
||||||
|
targets: [0],
|
||||||
'columnDefs' : [
|
'createdCell': function (td, cellData, rowData, row, col) {
|
||||||
// Replace HTML codes
|
$(td).html(translateHTMLcodes(localizeTimestamp(cellData)));
|
||||||
{targets: [0],
|
}
|
||||||
'createdCell': function (td, cellData, rowData, row, col) {
|
}
|
||||||
$(td).html (translateHTMLcodes (localizeTimestamp(cellData)));
|
],
|
||||||
} }
|
|
||||||
],
|
|
||||||
|
|
||||||
// Processing
|
|
||||||
'processing' : true,
|
|
||||||
'language' : {
|
|
||||||
processing: '<table><td width="130px" align="middle"><?= lang("DevDetail_Loading");?></td>'+
|
|
||||||
'<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw">'+
|
|
||||||
'</td></table>',
|
|
||||||
emptyTable: 'No data',
|
|
||||||
"lengthMenu": "<?= lang('Events_Tablelenght');?>",
|
|
||||||
"search": "<?= lang('Events_Searchbox');?>: ",
|
|
||||||
"paginate": {
|
|
||||||
"next": "<?= lang('Events_Table_nav_next');?>",
|
|
||||||
"previous": "<?= lang('Events_Table_nav_prev');?>"
|
|
||||||
},
|
|
||||||
"info": "<?= lang('Events_Table_info');?>",
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
'processing' : true,
|
||||||
|
'language' : {
|
||||||
|
processing: '<table><td width="130px" align="middle"><?= lang("DevDetail_Loading");?></td>'+
|
||||||
|
'<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></i></td></table>',
|
||||||
|
emptyTable: 'No data',
|
||||||
|
"lengthMenu": "<?= lang('Events_Tablelenght');?>",
|
||||||
|
"search": "<?= lang('Events_Searchbox');?>: ",
|
||||||
|
"paginate": {
|
||||||
|
"next": "<?= lang('Events_Table_nav_next');?>",
|
||||||
|
"previous": "<?= lang('Events_Table_nav_prev');?>"
|
||||||
|
},
|
||||||
|
"info": "<?= lang('Events_Table_info');?>",
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeSessionsDatatable();
|
// -----------------------------------------------
|
||||||
loadEventsData();
|
// INIT with polling for panel element visibility
|
||||||
|
// -----------------------------------------------
|
||||||
|
|
||||||
|
var eventsPageInitialized = false;
|
||||||
|
|
||||||
|
function initDeviceEventsPage()
|
||||||
|
{
|
||||||
|
// Only proceed if .plugin-content is visible
|
||||||
|
if (!$('#panEvents:visible').length) {
|
||||||
|
return; // exit early if nothing is visible
|
||||||
|
}
|
||||||
|
|
||||||
|
// init page once
|
||||||
|
if (eventsPageInitialized) return; // ENSURE ONCE
|
||||||
|
eventsPageInitialized = true;
|
||||||
|
|
||||||
|
showSpinner();
|
||||||
|
|
||||||
|
var eventsRows = 10;
|
||||||
|
var eventsHide = true;
|
||||||
|
|
||||||
|
initializeEventsDatatable(eventsRows);
|
||||||
|
loadEventsData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Recurring function to monitor the URL and reinitialize if needed
|
||||||
|
function deviceEventsPageUpdater() {
|
||||||
|
initDeviceEventsPage();
|
||||||
|
|
||||||
|
// Run updater again after delay
|
||||||
|
setTimeout(deviceEventsPageUpdater, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceEventsPageUpdater();
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -23,8 +23,6 @@
|
|||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
initializeCalendar();
|
|
||||||
loadPresenceData();
|
|
||||||
|
|
||||||
// Force re-render calendar on tab change
|
// Force re-render calendar on tab change
|
||||||
// (bugfix for render error at left panel)
|
// (bugfix for render error at left panel)
|
||||||
@@ -234,6 +232,37 @@ function initializeCalendar() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------
|
||||||
|
// INIT with polling for panel element visibility
|
||||||
|
// -----------------------------------------------
|
||||||
|
|
||||||
|
var presencePageInitialized = false;
|
||||||
|
|
||||||
|
function initDevicePresencePage() {
|
||||||
|
// Only proceed if the Presence tab is visible
|
||||||
|
if (!$('#panPresence:visible').length) {
|
||||||
|
return; // Exit early if nothing is visible
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure initialization only happens once
|
||||||
|
if (presencePageInitialized) return;
|
||||||
|
presencePageInitialized = true;
|
||||||
|
|
||||||
|
showSpinner();
|
||||||
|
|
||||||
|
initializeCalendar();
|
||||||
|
loadPresenceData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recurring check to initialize when visible
|
||||||
|
function devicePresencePageUpdater() {
|
||||||
|
initDevicePresencePage();
|
||||||
|
|
||||||
|
setTimeout(devicePresencePageUpdater, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
devicePresencePageUpdater();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -24,77 +24,126 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
var parSessionsRows = 'Front_Details_Sessions_Rows';
|
|
||||||
|
|
||||||
|
function initializeSessionsDatatable (sessionsRows) {
|
||||||
|
// Sessions datatable
|
||||||
|
$('#tableSessions').DataTable({
|
||||||
|
'paging' : true,
|
||||||
|
'lengthChange': true,
|
||||||
|
'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'All']],
|
||||||
|
'searching' : true,
|
||||||
|
'ordering' : true,
|
||||||
|
'info' : true,
|
||||||
|
'autoWidth' : false,
|
||||||
|
'order' : [[0,'desc'], [1,'desc']],
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
'pageLength' : sessionsRows,
|
||||||
|
|
||||||
|
'columnDefs' : [
|
||||||
|
{visible: false, targets: [0]},
|
||||||
|
|
||||||
|
// Replace HTML codes
|
||||||
|
{targets: [3,5],
|
||||||
|
'createdCell': function (td, cellData, rowData, row, col) {
|
||||||
|
$(td).html (translateHTMLcodes (cellData));
|
||||||
|
} },
|
||||||
|
// Date
|
||||||
|
{targets: [1,2],
|
||||||
|
"createdCell": function (td, cellData, rowData, row, col) {
|
||||||
|
// console.log(cellData);
|
||||||
|
|
||||||
|
if (!cellData.includes("missing event") && !cellData.includes("..."))
|
||||||
|
{
|
||||||
|
if (cellData.includes("+")) { // Check if timezone offset is present
|
||||||
|
cellData = cellData.split('+')[0]; // Remove timezone offset
|
||||||
|
}
|
||||||
|
// console.log(cellData);
|
||||||
|
result = localizeTimestamp(cellData);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
result = translateHTMLcodes(cellData)
|
||||||
|
}
|
||||||
|
|
||||||
|
$(td).html (result);
|
||||||
|
} }
|
||||||
|
],
|
||||||
|
|
||||||
|
// Processing
|
||||||
|
'processing' : true,
|
||||||
|
'language' : {
|
||||||
|
processing: '<table><td width="130px" align="middle"><?= lang("DevDetail_Loading");?></td>'+
|
||||||
|
'<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw">'+
|
||||||
|
'</td></table>',
|
||||||
|
emptyTable: 'No data',
|
||||||
|
"lengthMenu": "<?= lang('Events_Tablelenght');?>",
|
||||||
|
"search": "<?= lang('Events_Searchbox');?>: ",
|
||||||
|
"paginate": {
|
||||||
|
"next": "<?= lang('Events_Table_nav_next');?>",
|
||||||
|
"previous": "<?= lang('Events_Table_nav_prev');?>"
|
||||||
|
},
|
||||||
|
"info": "<?= lang('Events_Table_info');?>",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------
|
||||||
|
// INIT with polling for panel element visibility
|
||||||
|
// -----------------------------------------------
|
||||||
|
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
// Init datatable
|
||||||
|
function loadSessionsData(period){
|
||||||
|
const table = $('#tableSessions').DataTable();
|
||||||
|
|
||||||
|
showSpinner();
|
||||||
|
|
||||||
|
// table.clear().draw(); // Clear existing data before reloading
|
||||||
|
|
||||||
|
table.ajax
|
||||||
|
.url('php/server/events.php?action=getDeviceSessions&mac=' + getMac() + '&period=' + period)
|
||||||
|
.load(function () {
|
||||||
|
hideSpinner();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var sessionsPageInitialized = false;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
// Main init function
|
||||||
|
function initDeviceSessionsPage()
|
||||||
|
{
|
||||||
|
// Only proceed if .plugin-content is visible
|
||||||
|
if (!$('#panSessions:visible').length) {
|
||||||
|
return; // exit early if nothing is visible
|
||||||
|
}
|
||||||
|
|
||||||
|
// init page once
|
||||||
|
if (sessionsPageInitialized) return;
|
||||||
|
sessionsPageInitialized = true;
|
||||||
|
|
||||||
|
showSpinner();
|
||||||
|
|
||||||
var sessionsRows = 10;
|
var sessionsRows = 10;
|
||||||
var period = '1 month';
|
var period = '1 month';
|
||||||
|
|
||||||
function initializeSessionsDatatable () {
|
initializeSessionsDatatable(sessionsRows);
|
||||||
// Sessions datatable
|
loadSessionsData(period);
|
||||||
$('#tableSessions').DataTable({
|
}
|
||||||
'paging' : true,
|
|
||||||
'lengthChange': true,
|
|
||||||
'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'All']],
|
|
||||||
'searching' : true,
|
|
||||||
'ordering' : true,
|
|
||||||
'info' : true,
|
|
||||||
'autoWidth' : false,
|
|
||||||
'order' : [[0,'desc'], [1,'desc']],
|
|
||||||
|
|
||||||
// Parameters
|
// -----------------------------------------------------------------------------
|
||||||
'pageLength' : sessionsRows,
|
// Recurring function to monitor the URL and reinitialize if needed
|
||||||
|
function deviceSessionsPageUpdater() {
|
||||||
|
initDeviceSessionsPage();
|
||||||
|
|
||||||
'columnDefs' : [
|
// Run updater again after delay
|
||||||
{visible: false, targets: [0]},
|
setTimeout(deviceSessionsPageUpdater, 200);
|
||||||
|
}
|
||||||
|
|
||||||
// Replace HTML codes
|
// start updater
|
||||||
{targets: [3,5],
|
deviceSessionsPageUpdater();
|
||||||
'createdCell': function (td, cellData, rowData, row, col) {
|
|
||||||
$(td).html (translateHTMLcodes (cellData));
|
|
||||||
} },
|
|
||||||
// Date
|
|
||||||
{targets: [1,2],
|
|
||||||
"createdCell": function (td, cellData, rowData, row, col) {
|
|
||||||
// console.log(cellData);
|
|
||||||
|
|
||||||
if (!cellData.includes("missing event") && !cellData.includes("..."))
|
|
||||||
{
|
|
||||||
if (cellData.includes("+")) { // Check if timezone offset is present
|
|
||||||
cellData = cellData.split('+')[0]; // Remove timezone offset
|
|
||||||
}
|
|
||||||
// console.log(cellData);
|
|
||||||
result = localizeTimestamp(cellData);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
result = translateHTMLcodes(cellData)
|
|
||||||
}
|
|
||||||
|
|
||||||
$(td).html (result);
|
|
||||||
} }
|
|
||||||
],
|
|
||||||
|
|
||||||
// Processing
|
|
||||||
'processing' : true,
|
|
||||||
'language' : {
|
|
||||||
processing: '<table><td width="130px" align="middle"><?= lang("DevDetail_Loading");?></td>'+
|
|
||||||
'<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw">'+
|
|
||||||
'</td></table>',
|
|
||||||
emptyTable: 'No data',
|
|
||||||
"lengthMenu": "<?= lang('Events_Tablelenght');?>",
|
|
||||||
"search": "<?= lang('Events_Searchbox');?>: ",
|
|
||||||
"paginate": {
|
|
||||||
"next": "<?= lang('Events_Table_nav_next');?>",
|
|
||||||
"previous": "<?= lang('Events_Table_nav_prev');?>"
|
|
||||||
},
|
|
||||||
"info": "<?= lang('Events_Table_info');?>",
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadSessionsData(){
|
|
||||||
$('#tableSessions').DataTable().ajax.url('php/server/events.php?action=getDeviceSessions&mac=' + getMac() +'&period='+ period).load();
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeSessionsDatatable();
|
|
||||||
loadSessionsData();
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -1047,40 +1047,24 @@ function multiEditDevices()
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Function collects shown devices from the DataTable
|
// Function collects shown devices from the DataTable
|
||||||
function getMacsOfShownDevices() {
|
function getMacsOfShownDevices() {
|
||||||
rows = $('#tableDevices')[0].rows;
|
var table = $('#tableDevices').DataTable();
|
||||||
macs = [];
|
|
||||||
|
|
||||||
// var devicesDataTableData = $('#tableDevices').dataTable().fnGetData();
|
var macs = [];
|
||||||
var devicesDataTableData = $('#tableDevices').DataTable().rows({ selected: false, page: 'current' }).data().toArray();
|
|
||||||
|
|
||||||
console.log(devicesDataTableData);
|
// Get all row indexes on current page, in display order
|
||||||
|
var allIndexes = table.rows({ page: 'current' }).indexes();
|
||||||
|
|
||||||
var selectedDevices = [];
|
allIndexes.each(function(idx) {
|
||||||
|
var rowData = table.row(idx).data();
|
||||||
// first row is the heading, skip
|
if (rowData) {
|
||||||
for (var i = 1; i < rows.length; i++) {
|
macs.push(rowData[mapIndx(11)]); // mapIndx(11) == MAC column
|
||||||
var rowIndex = rows[i]._DT_RowIndex;
|
|
||||||
|
|
||||||
// Ensure the rowIndex is valid and within bounds of devicesDataTableData
|
|
||||||
if (rowIndex >= 0 && rowIndex < devicesDataTableData.length) {
|
|
||||||
selectedDevices.push(devicesDataTableData[rowIndex]);
|
|
||||||
} else {
|
|
||||||
console.log(`Invalid rowIndex: ${rowIndex} at row ${i}`);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
for (var j = 0; j < selectedDevices.length; j++) {
|
|
||||||
// Ensure that selectedDevices[j] is not undefined
|
|
||||||
if (selectedDevices[j]) {
|
|
||||||
macs.push(selectedDevices[j][mapIndx(11)]); // mapIndx(11) == MAC
|
|
||||||
} else {
|
|
||||||
console.log(`selectedDevices[${j}] is undefined`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return macs;
|
return macs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Handle custom actions/properties on a device
|
// Handle custom actions/properties on a device
|
||||||
function renderCustomProps(custProps, mac) {
|
function renderCustomProps(custProps, mac) {
|
||||||
|
|||||||
@@ -1109,46 +1109,52 @@ function getGuid() {
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Loading Spinner overlay
|
// Loading Spinner overlay
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
spinnerHtml = `
|
|
||||||
<!-- spinner -->
|
|
||||||
<div id="loadingSpinner" style="display: block">
|
|
||||||
<div class="pa_semitransparent-panel"></div>
|
|
||||||
<div class="panel panel-default pa_spinner">
|
|
||||||
<table>
|
|
||||||
<td width="130px" align="middle">_text_</td>
|
|
||||||
<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
|
|
||||||
function showSpinner(stringKey='Loading')
|
let spinnerTimeout = null;
|
||||||
{
|
let animationTime = 300
|
||||||
|
|
||||||
if(stringKey == "")
|
function showSpinner(stringKey = 'Loading') {
|
||||||
{
|
const text = isEmpty(stringKey) ? "Loading" : getString(stringKey || "Loading");
|
||||||
text = ''
|
const spinner = $("#loadingSpinner");
|
||||||
} else
|
|
||||||
{
|
if (spinner.length && spinner.is(':visible')) {
|
||||||
text = getString(stringKey)
|
clearTimeout(spinnerTimeout);
|
||||||
}
|
|
||||||
|
console.log(spinner);
|
||||||
|
|
||||||
text = isEmpty(text) ? "Loading" : text;
|
$("#loadingSpinnerText").text(text);
|
||||||
|
spinner.addClass("visible");
|
||||||
|
|
||||||
if($("#loadingSpinner").length)
|
spinner.fadeIn(animationTime);
|
||||||
{
|
} else {
|
||||||
$("#loadingSpinner").show();
|
$("#loadingSpinnerText").text(text);
|
||||||
}
|
|
||||||
else{
|
requestAnimationFrame(() => {
|
||||||
$(".wrapper").append(spinnerHtml.replace('_text_',text))
|
spinner.addClass("visible");
|
||||||
|
spinner.fadeIn(animationTime);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
function hideSpinner()
|
function hideSpinner() {
|
||||||
{
|
clearTimeout(spinnerTimeout);
|
||||||
$("#loadingSpinner").hide()
|
|
||||||
|
const spinner = $("#loadingSpinner");
|
||||||
|
|
||||||
|
if (spinner.length) {
|
||||||
|
spinner.removeClass("visible");
|
||||||
|
spinner.fadeOut(animationTime);
|
||||||
|
|
||||||
|
spinnerTimeout = setTimeout(() => {
|
||||||
|
spinner.removeClass("visible");
|
||||||
|
spinner.fadeOut(animationTime); // optional remove or hide again
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// Calls a backend function to add a front-end event to an execution queue
|
// Calls a backend function to add a front-end event to an execution queue
|
||||||
|
|||||||
@@ -136,7 +136,21 @@
|
|||||||
<!-- ----------------------------------------------------------------------- -->
|
<!-- ----------------------------------------------------------------------- -->
|
||||||
<!-- Layout Boxed Yellow -->
|
<!-- Layout Boxed Yellow -->
|
||||||
|
|
||||||
|
<!-- spinner -->
|
||||||
|
|
||||||
|
|
||||||
<body class="hold-transition fixed <?php echo $pia_skin_selected;?> theme-<?php echo $UI_THEME;?> sidebar-mini" onLoad="update_servertime();" >
|
<body class="hold-transition fixed <?php echo $pia_skin_selected;?> theme-<?php echo $UI_THEME;?> sidebar-mini" onLoad="update_servertime();" >
|
||||||
|
|
||||||
|
<div id="loadingSpinner">
|
||||||
|
<div class="pa_semitransparent-panel"></div>
|
||||||
|
<div class="panel panel-default pa_spinner">
|
||||||
|
<table>
|
||||||
|
<td id="loadingSpinnerText" width="130px" ></td>
|
||||||
|
<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Site wrapper -->
|
<!-- Site wrapper -->
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"About_Exit": "Sign out",
|
"About_Exit": "Sign out",
|
||||||
"About_Title": "Network security scanner & notification framework",
|
"About_Title": "Network security scanner & notification framework",
|
||||||
"AppEvents_AppEventProcessed": "Processed",
|
"AppEvents_AppEventProcessed": "Processed",
|
||||||
"AppEvents_DateTimeCreated": "Discovered On",
|
"AppEvents_DateTimeCreated": "Logged",
|
||||||
"AppEvents_Extra": "Extra",
|
"AppEvents_Extra": "Extra",
|
||||||
"AppEvents_GUID": "Application Event GUID",
|
"AppEvents_GUID": "Application Event GUID",
|
||||||
"AppEvents_Helper1": "Helper 1",
|
"AppEvents_Helper1": "Helper 1",
|
||||||
|
|||||||
@@ -49,10 +49,19 @@ function initMacFilter() {
|
|||||||
return mac;
|
return mac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------
|
||||||
|
// INIT with polling for panel element visibility
|
||||||
|
// -----------------------------------------------
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Initializes the fields if the MAC in the URL is different or not yet set
|
// Initializes the fields if the MAC in the URL is different or not yet set
|
||||||
function initFields() {
|
function initFields() {
|
||||||
|
|
||||||
|
// Only proceed if .plugin-content is visible
|
||||||
|
if (!$('.plugin-content:visible').length) {
|
||||||
|
return; // exit early if nothing is visible
|
||||||
|
}
|
||||||
|
|
||||||
// Get current value from the readonly text field
|
// Get current value from the readonly text field
|
||||||
const currentVal = initMacFilter();
|
const currentVal = initMacFilter();
|
||||||
|
|
||||||
@@ -74,15 +83,6 @@ function initFields() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// Recurring function to monitor the URL and reinitialize if needed
|
|
||||||
function updater() {
|
|
||||||
initFields();
|
|
||||||
|
|
||||||
// Run updater again after 500 milliseconds
|
|
||||||
setTimeout(updater, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Get form control according to the column definition from config.json > database_column_definitions
|
// Get form control according to the column definition from config.json > database_column_definitions
|
||||||
function getFormControl(dbColumnDef, value, index) {
|
function getFormControl(dbColumnDef, value, index) {
|
||||||
@@ -285,11 +285,9 @@ function getData(){
|
|||||||
pluginHistory = res["data"];
|
pluginHistory = res["data"];
|
||||||
|
|
||||||
generateTabs()
|
generateTabs()
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,15 +299,24 @@ function generateTabs() {
|
|||||||
// Sort pluginDefinitions by unique_prefix alphabetically
|
// Sort pluginDefinitions by unique_prefix alphabetically
|
||||||
pluginDefinitions.sort((a, b) => a.unique_prefix.localeCompare(b.unique_prefix));
|
pluginDefinitions.sort((a, b) => a.unique_prefix.localeCompare(b.unique_prefix));
|
||||||
|
|
||||||
|
assignActive = true;
|
||||||
|
|
||||||
// Iterate over the sorted pluginDefinitions to create tab headers and content
|
// Iterate over the sorted pluginDefinitions to create tab headers and content
|
||||||
pluginDefinitions.forEach(pluginObj => {
|
pluginDefinitions.forEach(pluginObj => {
|
||||||
if (pluginObj.show_ui) {
|
if (pluginObj.show_ui) {
|
||||||
stats = createTabContent(pluginObj); // Create the content for each tab
|
stats = createTabContent(pluginObj, assignActive); // Create the content for each tab
|
||||||
createTabHeader(pluginObj, stats); // Create the header for each tab
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
hideSpinner()
|
if(stats.objectDataCount > 0)
|
||||||
|
{
|
||||||
|
createTabHeader(pluginObj, stats, assignActive); // Create the header for each tab
|
||||||
|
assignActive = false; // only mark first with content active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
hideSpinner()
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetTabs() {
|
function resetTabs() {
|
||||||
@@ -318,27 +325,30 @@ function resetTabs() {
|
|||||||
$('#tabs-content-location').empty();
|
$('#tabs-content-location').empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTabHeader(pluginObj, stats) {
|
// ---------------------------------------------------------------
|
||||||
|
// left headers
|
||||||
|
function createTabHeader(pluginObj, stats, assignActive) {
|
||||||
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
|
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
|
||||||
|
|
||||||
// Determine the active class for the first tab
|
// Determine the active class for the first tab
|
||||||
const activeClass = pluginDefinitions.indexOf(pluginObj) === 0 ? 'active' : '';
|
assignActive ? activeClass = "active" : activeClass = "";
|
||||||
|
|
||||||
if(stats.objectDataCount > 0)
|
// Append the tab header to the tabs location
|
||||||
{
|
$('#tabs-location').append(`
|
||||||
// Append the tab header to the tabs location
|
<li class="left-nav ${activeClass} ">
|
||||||
$('#tabs-location').append(`
|
<a class="col-sm-12 textOverflow" href="#${prefix}" data-plugin-prefix="${prefix}" id="${prefix}_id" data-toggle="tab">
|
||||||
<li class="left-nav ${activeClass} ">
|
${getString(`${prefix}_icon`)} ${getString(`${prefix}_display_name`)}
|
||||||
<a class="col-sm-12 textOverflow" href="#${prefix}" data-plugin-prefix="${prefix}" id="${prefix}_id" data-toggle="tab">
|
|
||||||
${getString(`${prefix}_icon`)} ${getString(`${prefix}_display_name`)}
|
</a>
|
||||||
|
${stats.objectDataCount > 0 ? `<div class="pluginBadgeWrap"><span title="" class="badge pluginBadge" >${stats.objectDataCount}</span></div>` : ""}
|
||||||
</a>
|
</li>
|
||||||
${stats.objectDataCount > 0 ? `<div class="pluginBadgeWrap"><span title="" class="badge pluginBadge" >${stats.objectDataCount}</span></div>` : ""}
|
`);
|
||||||
</li>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTabContent(pluginObj) {
|
// ---------------------------------------------------------------
|
||||||
|
// Content of selected plugin (header)
|
||||||
|
function createTabContent(pluginObj, assignActive) {
|
||||||
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
|
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
|
||||||
const colDefinitions = getColumnDefinitions(pluginObj); // Get column definitions for DataTables
|
const colDefinitions = getColumnDefinitions(pluginObj); // Get column definitions for DataTables
|
||||||
|
|
||||||
@@ -349,7 +359,7 @@ function createTabContent(pluginObj) {
|
|||||||
|
|
||||||
// Append the content structure for the plugin's tab to the content location
|
// Append the content structure for the plugin's tab to the content location
|
||||||
$('#tabs-content-location').append(`
|
$('#tabs-content-location').append(`
|
||||||
<div id="${prefix}" class="tab-pane ${pluginDefinitions.indexOf(pluginObj) === 0 ? 'active' : ''}">
|
<div id="${prefix}" class="tab-pane ${objectData.length > 0 && assignActive? 'active' : ''}">
|
||||||
${generateTabNavigation(prefix, objectData.length, eventData.length, historyData.length)} <!-- Create tab navigation -->
|
${generateTabNavigation(prefix, objectData.length, eventData.length, historyData.length)} <!-- Create tab navigation -->
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
${generateDataTable(prefix, 'Objects', objectData, colDefinitions)}
|
${generateDataTable(prefix, 'Objects', objectData, colDefinitions)}
|
||||||
@@ -435,7 +445,7 @@ function generateDataTable(prefix, tableType, data, colDefinitions) {
|
|||||||
</table>
|
</table>
|
||||||
<div class="plugin-obj-purge">
|
<div class="plugin-obj-purge">
|
||||||
<button class="btn btn-primary" onclick="purgeAll('${prefix}', 'Plugins_${tableType}' )"><?= lang('Plugins_DeleteAll');?></button>
|
<button class="btn btn-primary" onclick="purgeAll('${prefix}', 'Plugins_${tableType}' )"><?= lang('Plugins_DeleteAll');?></button>
|
||||||
${tableType !== 'Events' ? `<button class="btn btn-danger" onclick="deleteListed('${prefix}', 'Plugins_${tableType}' )"><?= lang('Plugins_Obj_DeleteListed');?></button>` : ''}
|
${tableType !== 'Events' ? `<button class="btn btn-primary" onclick="deleteListed('${prefix}', 'Plugins_${tableType}' )"><?= lang('Plugins_Obj_DeleteListed');?></button>` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -583,14 +593,22 @@ function deleteListedExecute() {
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Main sequence
|
// Main sequence
|
||||||
|
|
||||||
// show spinning icon
|
// -----------------------------------------------------------------------------
|
||||||
showSpinner()
|
// Recurring function to monitor the URL and reinitialize if needed
|
||||||
// Start updater on page load
|
function updater() {
|
||||||
$(document).ready(function () {
|
initFields();
|
||||||
setTimeout(() => {
|
|
||||||
updater();
|
// Run updater again after delay
|
||||||
}, 100);
|
setTimeout(updater, 200);
|
||||||
|
}
|
||||||
});
|
|
||||||
|
// if visible, load immediately, if not start updater
|
||||||
|
if (!$('.plugin-content:visible').length) {
|
||||||
|
updater();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initFields();
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user